udp.but 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. \# This file is so named for tradition's sake: it contains what we
  2. \# always used to refer to, before they were written down, as
  3. \# PuTTY's `unwritten design principles'. It has nothing to do with
  4. \# the User Datagram Protocol.
  5. \A{udp} PuTTY hacking guide
  6. This appendix lists a selection of the design principles applying to
  7. the PuTTY source code. If you are planning to send code
  8. contributions, you should read this first.
  9. \H{udp-portability} Cross-OS portability
  10. Despite Windows being its main area of fame, PuTTY is no longer a
  11. Windows-only application suite. It has a working Unix port; a Mac
  12. port is in progress; more ports may or may not happen at a later
  13. date.
  14. Therefore, embedding Windows-specific code in core modules such as
  15. \cw{ssh.c} is not acceptable. We went to great lengths to \e{remove}
  16. all the Windows-specific stuff from our core modules, and to shift
  17. it out into Windows-specific modules. Adding large amounts of
  18. Windows-specific stuff in parts of the code that should be portable
  19. is almost guaranteed to make us reject a contribution.
  20. The PuTTY source base is divided into platform-specific modules and
  21. platform-generic modules. The Unix-specific modules are all in the
  22. \c{unix} subdirectory; the Windows-specific modules are in the
  23. \c{windows} subdirectory.
  24. All the modules in the main source directory and other
  25. subdirectories - notably \e{all} of the code for the various back
  26. ends - are platform-generic. We want to keep them that way.
  27. This also means you should stick to the C semantics guaranteed by the
  28. C standard: try not to make assumptions about the precise size of
  29. basic types such as \c{int} and \c{long int}; don't use pointer casts
  30. to do endianness-dependent operations, and so on.
  31. (Even \e{within} a platform front end you should still be careful of
  32. some of these portability issues. The Windows front end compiles on
  33. both 32- and 64-bit x86 and also Arm.)
  34. Our current choice of C standards version is \e{mostly} C99. With a
  35. couple of exceptions, you can assume that C99 features are available
  36. (in particular \cw{<stdint.h>}, \cw{<stdbool.h>} and \c{inline}), but
  37. you shouldn't use things that are new in C11 (such as \cw{<uchar.h>}
  38. or \cw{_Generic}).
  39. The exceptions to that rule are due to the need for Visual Studio
  40. compatibility:
  41. \b Don't use variable-length arrays. Visual Studio doesn't support
  42. them even now that it's adopted the rest of C99. We use \cw{-Wvla}
  43. when building with gcc and clang, to make it easier to avoid
  44. accidentally breaking that rule.
  45. \b For historical reasons, we still build with one older VS version
  46. which lacks \cw{<inttypes.h>}. So that file is included centrally in
  47. \c{defs.h}, and has a set of workaround definitions for the
  48. \cw{PRIx64}-type macros we use. If you need to use another one of
  49. those macros, you need to add a workaround definition in \c{defs.h},
  50. and don't casually re-include \cw{<inttypes.h>} anywhere else in the
  51. source file.
  52. Here are a few portability assumptions that we \e{do} currently allow
  53. (because we'd already have to thoroughly vet the existing code if they
  54. ever needed to change, and it doesn't seem worth doing that unless we
  55. really have to):
  56. \b You can assume \c{int} is \e{at least} 32 bits wide. (We've never
  57. tried to port PuTTY to a platform with 16-bit \cw{int}, and it doesn't
  58. look likely to be necessary in future.)
  59. \b Similarly, you can assume \c{char} is exactly 8 bits. (Exceptions
  60. to that are even less likely to be relevant to us than short
  61. \cw{int}.)
  62. \b You can assume that using \c{memset} to write zero bytes over a
  63. whole structure will have the effect of setting all its pointer fields
  64. to \cw{NULL}. (The standard itself guarantees this for \e{integer}
  65. fields, but not for pointers.)
  66. \b You can assume that \c{time_t} has POSIX semantics, i.e. that it
  67. represents an integer number of non-leap seconds since 1970-01-01
  68. 00:00:00 UTC. (Times in this format are used in X authorisation, but
  69. we could work around that by carefully distinguishing local \c{time_t}
  70. from time values used in the wire protocol; but these semantics of
  71. \c{time_t} are also baked into the shared library API used by the
  72. GSSAPI authentication code, which would be much harder to change.)
  73. \b You can assume that the execution character encoding is a superset
  74. of the printable characters of ASCII. (In particular, it's fine to do
  75. arithmetic on a \c{char} value representing a Latin alphabetic
  76. character, without bothering to allow for EBCDIC or other
  77. non-consecutive encodings of the alphabet.)
  78. On the other hand, here are some particular things \e{not} to assume:
  79. \b Don't assume anything about the \e{signedness} of \c{char}. In
  80. particular, you \e{must} cast \c{char} values to \c{unsigned char}
  81. before passing them to any \cw{<ctype.h>} function (because those
  82. expect a non-negative character value, or \cw{EOF}). If you need a
  83. particular signedness, explicitly specify \c{signed char} or
  84. \c{unsigned char}, or use C99 \cw{int8_t} or \cw{uint8_t}.
  85. \b From past experience with MacOS, we're still a bit nervous about
  86. \cw{'\\n'} and \cw{'\\r'} potentially having unusual meanings on a
  87. given platform. So it's fine to say \c{\\n} in a string you're passing
  88. to \c{printf}, but in any context where those characters appear in a
  89. standardised wire protocol or a binary file format, they should be
  90. spelled \cw{'\\012'} and \cw{'\\015'} respectively.
  91. \H{udp-multi-backend} Multiple backends treated equally
  92. PuTTY is not an SSH client with some other stuff tacked on the side.
  93. PuTTY is a generic, multiple-backend, remote VT-terminal client
  94. which happens to support one backend which is larger, more popular
  95. and more useful than the rest. Any extra feature which can possibly
  96. be general across all backends should be so: localising features
  97. unnecessarily into the SSH back end is a design error. (For example,
  98. we had several code submissions for proxy support which worked by
  99. hacking \cw{ssh.c}. Clearly this is completely wrong: the
  100. \cw{network.h} abstraction is the place to put it, so that it will
  101. apply to all back ends equally, and indeed we eventually put it
  102. there after another contributor sent a better patch.)
  103. The rest of PuTTY should try to avoid knowing anything about
  104. specific back ends if at all possible. To support a feature which is
  105. only available in one network protocol, for example, the back end
  106. interface should be extended in a general manner such that \e{any}
  107. back end which is able to provide that feature can do so. If it so
  108. happens that only one back end actually does, that's just the way it
  109. is, but it shouldn't be relied upon by any code.
  110. \H{udp-globals} Multiple sessions per process on some platforms
  111. Some ports of PuTTY - notably the in-progress Mac port - are
  112. constrained by the operating system to run as a single process
  113. potentially managing multiple sessions.
  114. Therefore, the platform-independent parts of PuTTY never use global
  115. variables to store per-session data. The global variables that do
  116. exist are tolerated because they are not specific to a particular
  117. login session. The random number state in \cw{sshrand.c}, the timer
  118. list in \cw{timing.c} and the queue of top-level callbacks in
  119. \cw{callback.c} serve all sessions equally. But most data is specific
  120. to a particular network session, and is therefore stored in
  121. dynamically allocated data structures, and pointers to these
  122. structures are passed around between functions.
  123. Platform-specific code can reverse this decision if it likes. The
  124. Windows code, for historical reasons, stores most of its data as
  125. global variables. That's OK, because \e{on Windows} we know there is
  126. only one session per PuTTY process, so it's safe to do that. But
  127. changes to the platform-independent code should avoid introducing
  128. global variables, unless they are genuinely cross-session.
  129. \H{udp-pure-c} C, not C++
  130. PuTTY is written entirely in C, not in C++.
  131. We have made \e{some} effort to make it easy to compile our code
  132. using a C++ compiler: notably, our \c{snew}, \c{snewn} and
  133. \c{sresize} macros explicitly cast the return values of \cw{malloc}
  134. and \cw{realloc} to the target type. (This has type checking
  135. advantages even in C: it means you never accidentally allocate the
  136. wrong size piece of memory for the pointer type you're assigning it
  137. to. C++ friendliness is really a side benefit.)
  138. We want PuTTY to continue being pure C, at least in the
  139. platform-independent parts and the currently existing ports. Patches
  140. which switch the Makefiles to compile it as C++ and start using
  141. classes will not be accepted.
  142. The one exception: a port to a new platform may use languages other
  143. than C if they are necessary to code on that platform. If your
  144. favourite PDA has a GUI with a C++ API, then there's no way you can
  145. do a port of PuTTY without using C++, so go ahead and use it. But
  146. keep the C++ restricted to that platform's subdirectory; if your
  147. changes force the Unix or Windows ports to be compiled as C++, they
  148. will be unacceptable to us.
  149. \H{udp-security} Security-conscious coding
  150. PuTTY is a network application and a security application. Assume
  151. your code will end up being fed deliberately malicious data by
  152. attackers, and try to code in a way that makes it unlikely to be a
  153. security risk.
  154. In particular, try not to use fixed-size buffers for variable-size
  155. data such as strings received from the network (or even the user).
  156. We provide functions such as \cw{dupcat} and \cw{dupprintf}, which
  157. dynamically allocate buffers of the right size for the string they
  158. construct. Use these wherever possible.
  159. \H{udp-multi-compiler} Independence of specific compiler
  160. Windows PuTTY can currently be compiled with any of three Windows
  161. compilers: MS Visual C, the Cygwin / \cw{mingw32} GNU tools, and
  162. \cw{clang} (in MS compatibility mode).
  163. This is a really useful property of PuTTY, because it means people
  164. who want to contribute to the coding don't depend on having a
  165. specific compiler; so they don't have to fork out money for MSVC if
  166. they don't already have it, but on the other hand if they \e{do}
  167. have it they also don't have to spend effort installing \cw{gcc}
  168. alongside it. They can use whichever compiler they happen to have
  169. available, or install whichever is cheapest and easiest if they
  170. don't have one.
  171. Therefore, we don't want PuTTY to start depending on which compiler
  172. you're using. Using GNU extensions to the C language, for example,
  173. would ruin this useful property (not that anyone's ever tried it!);
  174. and more realistically, depending on an MS-specific library function
  175. supplied by the MSVC C library (\cw{_snprintf}, for example) is a
  176. mistake, because that function won't be available under the other
  177. compilers. Any function supplied in an official Windows DLL as part
  178. of the Windows API is fine, and anything defined in the C library
  179. standard is also fine, because those should be available
  180. irrespective of compilation environment. But things in between,
  181. available as non-standard library and language extensions in only
  182. one compiler, are disallowed.
  183. (\cw{_snprintf} in particular should be unnecessary, since we
  184. provide \cw{dupprintf}; see \k{udp-security}.)
  185. Compiler independence should apply on all platforms, of course, not
  186. just on Windows.
  187. \H{udp-small} Small code size
  188. PuTTY is tiny, compared to many other Windows applications. And it's
  189. easy to install: it depends on no DLLs, no other applications, no
  190. service packs or system upgrades. It's just one executable. You
  191. install that executable wherever you want to, and run it.
  192. We want to keep both these properties - the small size, and the ease
  193. of installation - if at all possible. So code contributions that
  194. depend critically on external DLLs, or that add a huge amount to the
  195. code size for a feature which is only useful to a small minority of
  196. users, are likely to be thrown out immediately.
  197. We do vaguely intend to introduce a DLL plugin interface for PuTTY,
  198. whereby seriously large extra features can be implemented in plugin
  199. modules. The important thing, though, is that those DLLs will be
  200. \e{optional}; if PuTTY can't find them on startup, it should run
  201. perfectly happily and just won't provide those particular features.
  202. A full installation of PuTTY might one day contain ten or twenty
  203. little DLL plugins, which would cut down a little on the ease of
  204. installation - but if you really needed ease of installation you
  205. \e{could} still just install the one PuTTY binary, or just the DLLs
  206. you really needed, and it would still work fine.
  207. Depending on \e{external} DLLs is something we'd like to avoid if at
  208. all possible (though for some purposes, such as complex SSH
  209. authentication mechanisms, it may be unavoidable). If it can't be
  210. avoided, the important thing is to follow the same principle of
  211. graceful degradation: if a DLL can't be found, then PuTTY should run
  212. happily and just not supply the feature that depended on it.
  213. \H{udp-single-threaded} Single-threaded code
  214. PuTTY and its supporting tools, or at least the vast majority of
  215. them, run in only one OS thread.
  216. This means that if you're devising some piece of internal mechanism,
  217. there's no need to use locks to make sure it doesn't get called by
  218. two threads at once. The only way code can be called re-entrantly is
  219. by recursion.
  220. That said, most of Windows PuTTY's network handling is triggered off
  221. Windows messages requested by \cw{WSAAsyncSelect()}, so if you call
  222. \cw{MessageBox()} deep within some network event handling code you
  223. should be aware that you might be re-entered if a network event
  224. comes in and is passed on to our window procedure by the
  225. \cw{MessageBox()} message loop.
  226. Also, the front ends can use multiple threads if they like. For
  227. example, the Windows front-end code spawns subthreads to deal with
  228. bidirectional blocking I/O on non-network streams such as Windows
  229. pipes. However, it keeps tight control of its auxiliary threads, and
  230. uses them only for that one purpose, as a form of \cw{select()}.
  231. Pretty much all the code outside \cw{windows/handle-io.c} is \e{only}
  232. ever called from the one primary thread; the others just loop round
  233. blocking on file handles, and signal the main thread (via Windows
  234. event objects) when some real work needs doing. This is not considered
  235. a portability hazard because that code is already Windows-specific and
  236. needs rewriting on other platforms.
  237. One important consequence of this: PuTTY has only one thread in
  238. which to do everything. That \q{everything} may include managing
  239. more than one login session (\k{udp-globals}), managing multiple
  240. data channels within an SSH session, responding to GUI events even
  241. when nothing is happening on the network, and responding to network
  242. requests from the server (such as repeat key exchange) even when the
  243. program is dealing with complex user interaction such as the
  244. re-configuration dialog box. This means that \e{almost none} of the
  245. PuTTY code can safely block.
  246. \H{udp-keystrokes} Keystrokes sent to the server wherever possible
  247. In almost all cases, PuTTY sends keystrokes to the server. Even
  248. weird keystrokes that you think should be hot keys controlling
  249. PuTTY. Even Alt-F4 or Alt-Space, for example. If a keystroke has a
  250. well-defined escape sequence that it could usefully be sending to
  251. the server, then it should do so, or at the very least it should be
  252. configurably able to do so.
  253. To unconditionally turn a key combination into a hot key to control
  254. PuTTY is almost always a design error. If a hot key is really truly
  255. required, then try to find a key combination for it which \e{isn't}
  256. already used in existing PuTTYs (either it sends nothing to the
  257. server, or it sends the same thing as some other combination). Even
  258. then, be prepared for the possibility that one day that key
  259. combination might end up being needed to send something to the
  260. server - so make sure that there's an alternative way to invoke
  261. whatever PuTTY feature it controls.
  262. \H{udp-640x480} 640\u00D7{x}480 friendliness in configuration panels
  263. There's a reason we have lots of tiny configuration panels instead
  264. of a few huge ones, and that reason is that not everyone has a
  265. 1600\u00D7{x}1200 desktop. 640\u00D7{x}480 is still a viable
  266. resolution for running Windows (and indeed it's still the default if
  267. you start up in safe mode), so it's still a resolution we care
  268. about.
  269. Accordingly, the PuTTY configuration box, and the PuTTYgen control
  270. window, are deliberately kept just small enough to fit comfortably
  271. on a 640\u00D7{x}480 display. If you're adding controls to either of
  272. these boxes and you find yourself wanting to increase the size of
  273. the whole box, \e{don't}. Split it into more panels instead.
  274. \H{udp-ssh-coroutines} Coroutines in protocol code
  275. Large parts of the code in modules implementing wire protocols
  276. (mainly SSH) are structured using a set of macros that implement
  277. (something close to) Donald Knuth's \q{coroutines} concept in C.
  278. Essentially, the purpose of these macros are to arrange that a
  279. function can call \cw{crReturn()} to return to its caller, and the
  280. next time it is called control will resume from just after that
  281. \cw{crReturn} statement.
  282. This means that any local (automatic) variables declared in such a
  283. function will be corrupted every time you call \cw{crReturn}. If you
  284. need a variable to persist for longer than that, you \e{must} make it
  285. a field in some appropriate structure containing the persistent state
  286. of the coroutine \dash typically the main state structure for a
  287. protocol layer.
  288. See
  289. \W{https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}\c{https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}
  290. for a more in-depth discussion of what these macros are for and how
  291. they work.
  292. Another caveat: most of these coroutines are not \e{guaranteed} to run
  293. to completion, because the SSH connection (or whatever) that they're
  294. part of might be interrupted at any time by an unexpected network
  295. event or user action. So whenever a coroutine-managed variable refers
  296. to a resource that needs releasing, you should also ensure that the
  297. cleanup function for its containing state structure can reliably
  298. release it even if the coroutine is aborted at an arbitrary point.
  299. For example, if an SSH packet protocol layer has to have a field that
  300. sometimes points to a piece of allocated memory, then you should
  301. ensure that when you free that memory you reset the pointer field to
  302. \cw{NULL}. Then, no matter when the protocol layer's cleanup function
  303. is called, it can reliably free the memory if there is any, and not
  304. crash if there isn't.
  305. \H{udp-traits} Explicit vtable structures to implement traits
  306. A lot of PuTTY's code is written in a style that looks structurally
  307. rather like an object-oriented language, in spite of PuTTY being a
  308. pure C program.
  309. For example, there's a single data type called \cw{ssh_hash}, which is
  310. an abstraction of a secure hash function, and a bunch of functions
  311. called things like \cw{ssh_hash_}\e{foo} that do things with those
  312. data types. But in fact, PuTTY supports many different hash functions,
  313. and each one has to provide its own implementation of those functions.
  314. In C++ terms, this is rather like having a single abstract base class,
  315. and multiple concrete subclasses of it, each of which fills in all the
  316. pure virtual methods in a way that's compatible with the data fields
  317. of the subclass. The implementation is more or less the same, as well:
  318. in C, we do explicitly in the source code what the C++ compiler will
  319. be doing behind the scenes at compile time.
  320. But perhaps a closer analogy in functional terms is the Rust concept
  321. of a \q{trait}, or the Java idea of an \q{interface}. C++ supports a
  322. multi-level hierarchy of inheritance, whereas PuTTY's system \dash
  323. like traits or interfaces \dash has only two levels, one describing a
  324. generic object of a type (e.g. a hash function) and another describing
  325. a specific implementation of that type (e.g. SHA-256).
  326. The PuTTY code base has a standard idiom for doing this in C, as
  327. follows.
  328. Firstly, we define two \cw{struct} types for our trait. One of them
  329. describes a particular \e{kind} of implementation of that trait, and
  330. it's full of (mostly) function pointers. The other describes a
  331. specific \e{instance} of an implementation of that trait, and it will
  332. contain a pointer to a \cw{const} instance of the first type. For
  333. example:
  334. \c typedef struct MyAbstraction MyAbstraction;
  335. \c typedef struct MyAbstractionVtable MyAbstractionVtable;
  336. \c
  337. \c struct MyAbstractionVtable {
  338. \c MyAbstraction *(*new)(const MyAbstractionVtable *vt);
  339. \c void (*free)(MyAbstraction *);
  340. \c void (*modify)(MyAbstraction *, unsigned some_parameter);
  341. \c unsigned (*query)(MyAbstraction *, unsigned some_parameter);
  342. \c };
  343. \c
  344. \c struct MyAbstraction {
  345. \c const MyAbstractionVtable *vt;
  346. \c };
  347. Here, we imagine that \cw{MyAbstraction} might be some kind of object
  348. that contains mutable state. The associated vtable structure shows
  349. what operations you can perform on a \cw{MyAbstraction}: you can
  350. create one (dynamically allocated), free one you already have, or call
  351. the example methods \q{modify} (to change the state of the object in
  352. some way) and \q{query} (to return some value derived from the
  353. object's current state).
  354. (In most cases, the vtable structure has a name ending in \cq{vtable}.
  355. But for historical reasons a lot of the crypto primitives that use
  356. this scheme \dash ciphers, hash functions, public key methods and so
  357. on \dash instead have names ending in \cq{alg}, on the basis that the
  358. primitives they implement are often referred to as \q{encryption
  359. algorithms}, \q{hash algorithms} and so forth.)
  360. Now, to define a concrete instance of this trait, you'd define a
  361. \cw{struct} that contains a \cw{MyAbstraction} field, plus any other
  362. data it might need:
  363. \c struct MyImplementation {
  364. \c unsigned internal_data[16];
  365. \c SomeOtherType *dynamic_subthing;
  366. \c
  367. \c MyAbstraction myabs;
  368. \c };
  369. Next, you'd implement all the necessary methods for that
  370. implementation of the trait, in this kind of style:
  371. \c static MyAbstraction *myimpl_new(const MyAbstractionVtable *vt)
  372. \c {
  373. \c MyImplementation *impl = snew(MyImplementation);
  374. \c memset(impl, 0, sizeof(*impl));
  375. \c impl->dynamic_subthing = allocate_some_other_type();
  376. \c impl->myabs.vt = vt;
  377. \c return &impl->myabs;
  378. \c }
  379. \c
  380. \c static void myimpl_free(MyAbstraction *myabs)
  381. \c {
  382. \c MyImplementation *impl = container_of(myabs, MyImplementation, myabs);
  383. \c free_other_type(impl->dynamic_subthing);
  384. \c sfree(impl);
  385. \c }
  386. \c
  387. \c static void myimpl_modify(MyAbstraction *myabs, unsigned param)
  388. \c {
  389. \c MyImplementation *impl = container_of(myabs, MyImplementation, myabs);
  390. \c impl->internal_data[param] += do_something_with(impl->dynamic_subthing);
  391. \c }
  392. \c
  393. \c static unsigned myimpl_query(MyAbstraction *myabs, unsigned param)
  394. \c {
  395. \c MyImplementation *impl = container_of(myabs, MyImplementation, myabs);
  396. \c return impl->internal_data[param];
  397. \c }
  398. Having defined those methods, now we can define a \cw{const} instance
  399. of the vtable structure containing pointers to them:
  400. \c const MyAbstractionVtable MyImplementation_vt = {
  401. \c .new = myimpl_new,
  402. \c .free = myimpl_free,
  403. \c .modify = myimpl_modify,
  404. \c .query = myimpl_query,
  405. \c };
  406. \e{In principle}, this is all you need. Client code can construct a
  407. new instance of a particular implementation of \cw{MyAbstraction} by
  408. digging out the \cw{new} method from the vtable and calling it (with
  409. the vtable itself as a parameter), which returns a \cw{MyAbstraction
  410. *} pointer that identifies a newly created instance, in which the
  411. \cw{vt} field will contain a pointer to the same vtable structure you
  412. passed in. And once you have an instance object, say \cw{MyAbstraction
  413. *myabs}, you can dig out one of the other method pointers from the
  414. vtable it points to, and call that, passing the object itself as a
  415. parameter.
  416. But in fact, we don't do that, because it looks pretty ugly at all the
  417. call sites. Instead, what we generally do in this code base is to
  418. write a set of \cw{static inline} wrapper functions in the same header
  419. file that defined the \cw{MyAbstraction} structure types, like this:
  420. \c static inline MyAbstraction *myabs_new(const MyAbstractionVtable *vt)
  421. \c { return vt->new(vt); }
  422. \c static inline void myabs_free(MyAbstraction *myabs)
  423. \c { myabs->vt->free(myabs); }
  424. \c static inline void myimpl_modify(MyAbstraction *myabs, unsigned param)
  425. \c { myabs->vt->modify(myabs, param); }
  426. \c static inline unsigned myimpl_query(MyAbstraction *myabs, unsigned param)
  427. \c { return myabs->vt->query(myabs, param); }
  428. And now call sites can use those reasonably clean-looking wrapper
  429. functions, and shouldn't ever have to directly refer to the \cw{vt}
  430. field inside any \cw{myabs} object they're holding. For example, you
  431. might write something like this:
  432. \c MyAbstraction *myabs = myabs_new(&MyImplementation_vtable);
  433. \c myabs_update(myabs, 10);
  434. \c unsigned output = myabs_query(myabs, 2);
  435. \c myabs_free(myabs);
  436. and then all this code can use a different implementation of the same
  437. abstraction by just changing which vtable pointer it passed in in the
  438. first line.
  439. Some things to note about this system:
  440. \b The implementation instance type (here \cq{MyImplementation}
  441. contains the abstraction type (\cq{MyAbstraction}) as one of its
  442. fields. But that field is not necessarily at the start of the
  443. structure. So you can't just \e{cast} pointers back and forth between
  444. the two types. Instead:
  445. \lcont{
  446. \b You \q{up-cast} from implementation to abstraction by taking the
  447. address of the \cw{MyAbstraction} field. You can see the example
  448. \cw{new} method above doing this, returning \cw{&impl->myabs}. All
  449. \cw{new} methods do this on return.
  450. \b Going in the other direction, each method that was passed a generic
  451. \cw{MyAbstraction *myabs} parameter has to recover a pointer to the
  452. specific implementation type \cw{MyImplementation *impl}. The idiom
  453. for doing that is to use the \cq{container_of} macro, also seen in the
  454. Linux kernel code. Generally, \cw{container_of(p, Type, field)} says:
  455. \q{I'm confident that the pointer value \cq{p} is pointing to the
  456. field called \cq{field} within a larger \cw{struct} of type \cw{Type}.
  457. Please return me the pointer to the containing structure.} So in this
  458. case, we take the \cq{myabs} pointer passed to the function, and
  459. \q{down-cast} it into a pointer to the larger and more specific
  460. structure type \cw{MyImplementation}, by adjusting the pointer value
  461. based on the offset within that structure of the field called
  462. \cq{myabs}.
  463. This system is flexible enough to permit \q{multiple inheritance}, or
  464. rather, multiple \e{implementation}: having one object type implement
  465. more than one trait. For example, the \cw{ProxySocket} type implements
  466. both the \cw{Socket} trait and the \cw{Plug} trait that connects to it,
  467. because it has to act as an adapter between another instance of each
  468. of those types.
  469. It's also perfectly possible to have the same object implement the
  470. \e{same} trait in two different ways. At the time of writing this I
  471. can't think of any case where we actually do this, but a theoretical
  472. example might be if you needed to support a trait like \cw{Comparable}
  473. in two ways that sorted by different criteria. There would be no
  474. difficulty doing this in the PuTTY system: simply have your
  475. implementation \cw{struct} contain two (or more) fields of the same
  476. abstraction type. The fields will have different names, which makes it
  477. easy to explicitly specify which one you're returning a pointer to
  478. during up-casting, or which one you're down-casting from using
  479. \cw{container_of}. And then both sets of implementation methods can
  480. recover a pointer to the same containing structure.
  481. }
  482. \b Unlike in C++, all objects in PuTTY that use this system are
  483. dynamically allocated. The \q{constructor} functions (whether they're
  484. virtualised across the whole abstraction or specific to each
  485. implementation) always allocate memory and return a pointer to it. The
  486. \q{free} method (our analogue of a destructor) always expects the
  487. input pointer to be dynamically allocated, and frees it. As a result,
  488. client code doesn't need to know how large the implementing object
  489. type is, because it will never need to allocate it (on the stack or
  490. anywhere else).
  491. \b Unlike in C++, the abstraction's \q{vtable} structure does not only
  492. hold methods that you can call on an instance object. It can also
  493. hold several other kinds of thing:
  494. \lcont{
  495. \b Methods that you can call \e{without} an instance object, given
  496. only the vtable structure identifying a particular implementation of
  497. the trait. You might think of these as \q{static methods}, as in C++,
  498. except that they're \e{virtual} \dash the same code can call the
  499. static method of a different \q{class} given a different vtable
  500. pointer. So they're more like \q{virtual static methods}, which is a
  501. concept C++ doesn't have. An example is the \cw{pubkey_bits} method in
  502. \cw{ssh_keyalg}.
  503. \b The most important case of a \q{virtual static method} is the
  504. \cw{new} method that allocates and returns a new object. You can think
  505. of it as a \q{virtual constructor} \dash another concept C++ doesn't
  506. have. (However, not all types need one of these: see below.)
  507. \b The vtable can also contain constant data relevant to the class as
  508. a whole \dash \q{virtual constant data}. For example, a cryptographic
  509. hash function will contain an integer field giving the length of the
  510. output hash, and most crypto primitives will contain a string field
  511. giving the identifier used in the SSH protocol that describes that
  512. primitive.
  513. The effect of all of this is that you can make other pieces of code
  514. able to use any instance of one of these types, by passing it an
  515. actual vtable as a parameter. For example, the \cw{hash_simple}
  516. function takes an \cw{ssh_hashalg} vtable pointer specifying any hash
  517. algorithm you like, and internally, it creates an object of that type,
  518. uses it, and frees it. In C++, you'd probably do this using a
  519. template, which would mean you had multiple specialisations of
  520. \cw{hash_simple} \dash and then it would be much more difficult to
  521. decide \e{at run time} which one you needed to use. Here,
  522. \cw{hash_simple} is still just one function, and you can decide as
  523. late as you like which vtable to pass to it.
  524. }
  525. \b The abstract \e{instance} structure can also contain publicly
  526. visible data fields (this time, usually treated as mutable) which are
  527. common to all implementations of the trait. For example,
  528. \cw{BinaryPacketProtocol} has lots of these.
  529. \b Not all abstractions of this kind want virtual constructors. It
  530. depends on how different the implementations are.
  531. \lcont{
  532. With a crypto primitive like a hash algorithm, the constructor call
  533. looks the same for every implementing type, so it makes sense to have
  534. a standardised virtual constructor in the vtable and a
  535. \cw{ssh_hash_new} wrapper function which can make an instance of
  536. whatever vtable you pass it. And then you make all the vtable objects
  537. themselves globally visible throughout the source code, so that any
  538. module can call (for example) \cw{ssh_hash_new(&ssh_sha256)}.
  539. But with other kinds of object, the constructor for each implementing
  540. type has to take a different set of parameters. For example,
  541. implementations of \cw{Socket} are not generally interchangeable at
  542. construction time, because constructing different kinds of socket
  543. require totally different kinds of address parameter. In that
  544. situation, it makes more sense to keep the vtable structure itself
  545. private to the implementing source file, and instead, publish an
  546. ordinary constructing function that allocates and returns an instance
  547. of that particular subtype, taking whatever parameters are appropriate
  548. to that subtype.
  549. }
  550. \b If you do have virtual constructors, you can choose whether they
  551. take a vtable pointer as a parameter (as shown above), or an
  552. \e{existing} instance object. In the latter case, they can refer to
  553. the object itself as well as the vtable. For example, you could have a
  554. trait come with a virtual constructor called \q{clone}, meaning
  555. \q{Make a copy of this object, no matter which implementation it is.}
  556. \b Sometimes, a single vtable structure type can be shared between two
  557. completely different object types, and contain all the methods for
  558. both. For example, \cw{ssh_compression_alg} contains methods to
  559. create, use and free \cw{ssh_compressor} and \cw{ssh_decompressor}
  560. objects, which are not interchangeable \dash but putting their methods
  561. in the same vtable means that it's easy to create a matching pair of
  562. objects that are compatible with each other.
  563. \b Passing the vtable itself as an argument to the \cw{new} method is
  564. not compulsory: if a given \cw{new} implementation is only used by a
  565. single vtable, then that function can simply hard-code the vtable
  566. pointer that it writes into the object it constructs. But passing the
  567. vtable is more flexible, because it allows a single constructor
  568. function to be shared between multiple slightly different object
  569. types. For example, SHA-384 and SHA-512 share the same \cw{new} method
  570. and the same implementation data type, because they're very nearly the
  571. same hash algorithm \dash but a couple of the other methods in their
  572. vtables are different, because the \q{reset} function has to set up
  573. the initial algorithm state differently, and the \q{digest} method has
  574. to write out a different amount of data.
  575. \lcont{
  576. One practical advantage of having the \cw{myabs_}\e{foo} family of
  577. inline wrapper functions in the header file is that if you change your
  578. mind later about whether the vtable needs to be passed to \cw{new},
  579. you only have to update the \cw{myabs_new} wrapper, and then the
  580. existing call sites won't need changing.
  581. }
  582. \b Another piece of \q{stunt object orientation} made possible by this
  583. scheme is that you can write two vtables that both use the same
  584. structure layout for the implementation object, and have an object
  585. \e{transform from one to the other} part way through its lifetime, by
  586. overwriting its own vtable pointer field. For example, the
  587. \cw{sesschan} type that handles the server side of an SSH terminal
  588. session will sometimes transform in mid-lifetime into an SCP or SFTP
  589. file-transfer channel in this way, at the point where the client sends
  590. an \cq{exec} or \cq{subsystem} request that indicates that that's what
  591. it wants to do with the channel.
  592. \lcont{
  593. This concept would be difficult to arrange in C++. In Rust, it
  594. wouldn't even \e{make sense}, because in Rust, objects implementing a
  595. trait don't even contain a vtable pointer at all \dash instead, the
  596. \q{trait object} type (identifying a specific instance of some
  597. implementation of a given trait) consists of a pair of pointers, one
  598. to the object itself and one to the vtable. In that model, the only
  599. way you could make an existing object turn into a different trait
  600. would be to know where all the pointers to it were stored elsewhere in
  601. the program, and persuade all their owners to rewrite them.
  602. }
  603. \b Another stunt you can do is to have a vtable that doesn't have a
  604. corresponding implementation structure at all, because the only
  605. methods implemented in it are the constructors, and they always end up
  606. returning an implementation of some other vtable. For example, some of
  607. PuTTY's crypto primitives have a hardware-accelerated version and a
  608. pure software version, and decide at run time which one to use (based
  609. on whether the CPU they're running on supports the necessary
  610. acceleration instructions). So, for example, there are vtables for
  611. \cw{ssh_sha256_sw} and \cw{ssh_sha256_hw}, each of which has its own
  612. data layout and its own implementations of all the methods; and then
  613. there's a top-level vtable \cw{ssh_sha256}, which only provides the
  614. \q{new} method, and implements it by calling the \q{new} method on one
  615. or other of the subtypes depending on what it finds out about the
  616. machine it's running on. That top-level selector vtable is nearly
  617. always the one used by client code. (Except for the test suite, which
  618. has to instantiate both of the subtypes in order to make sure they
  619. both pass the tests.)
  620. \lcont{
  621. As a result, the top-level selector vtable \cw{ssh_sha256} doesn't
  622. need to implement any method that takes an \cw{ssh_cipher *}
  623. parameter, because no \cw{ssh_cipher} object is ever constructed whose
  624. \cw{vt} field points to \cw{&ssh_sha256}: they all point to one of the
  625. other two full implementation vtables.
  626. }
  627. \H{udp-perfection} Do as we say, not as we do
  628. The current PuTTY code probably does not conform strictly to \e{all}
  629. of the principles listed above. There may be the occasional
  630. SSH-specific piece of code in what should be a backend-independent
  631. module, or the occasional dependence on a non-standard X library
  632. function under Unix.
  633. This should not be taken as a licence to go ahead and violate the
  634. rules. Where we violate them ourselves, we're not happy about it,
  635. and we would welcome patches that fix any existing problems. Please
  636. try to help us make our code better, not worse!