udp.but 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  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 - notably \e{all} of
  25. the code for the various back ends - are platform-generic. We want
  26. 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. Also, in particular, we disapprove of
  142. \cw{//} comments, at least for the moment. (Perhaps once C99 becomes
  143. genuinely widespread we might be more lenient.)
  144. The one exception: a port to a new platform may use languages other
  145. than C if they are necessary to code on that platform. If your
  146. favourite PDA has a GUI with a C++ API, then there's no way you can
  147. do a port of PuTTY without using C++, so go ahead and use it. But
  148. keep the C++ restricted to that platform's subdirectory; if your
  149. changes force the Unix or Windows ports to be compiled as C++, they
  150. will be unacceptable to us.
  151. \H{udp-security} Security-conscious coding
  152. PuTTY is a network application and a security application. Assume
  153. your code will end up being fed deliberately malicious data by
  154. attackers, and try to code in a way that makes it unlikely to be a
  155. security risk.
  156. In particular, try not to use fixed-size buffers for variable-size
  157. data such as strings received from the network (or even the user).
  158. We provide functions such as \cw{dupcat} and \cw{dupprintf}, which
  159. dynamically allocate buffers of the right size for the string they
  160. construct. Use these wherever possible.
  161. \H{udp-multi-compiler} Independence of specific compiler
  162. Windows PuTTY can currently be compiled with any of three Windows
  163. compilers: MS Visual C, the Cygwin / \cw{mingw32} GNU tools, and
  164. \cw{clang} (in MS compatibility mode).
  165. This is a really useful property of PuTTY, because it means people
  166. who want to contribute to the coding don't depend on having a
  167. specific compiler; so they don't have to fork out money for MSVC if
  168. they don't already have it, but on the other hand if they \e{do}
  169. have it they also don't have to spend effort installing \cw{gcc}
  170. alongside it. They can use whichever compiler they happen to have
  171. available, or install whichever is cheapest and easiest if they
  172. don't have one.
  173. Therefore, we don't want PuTTY to start depending on which compiler
  174. you're using. Using GNU extensions to the C language, for example,
  175. would ruin this useful property (not that anyone's ever tried it!);
  176. and more realistically, depending on an MS-specific library function
  177. supplied by the MSVC C library (\cw{_snprintf}, for example) is a
  178. mistake, because that function won't be available under the other
  179. compilers. Any function supplied in an official Windows DLL as part
  180. of the Windows API is fine, and anything defined in the C library
  181. standard is also fine, because those should be available
  182. irrespective of compilation environment. But things in between,
  183. available as non-standard library and language extensions in only
  184. one compiler, are disallowed.
  185. (\cw{_snprintf} in particular should be unnecessary, since we
  186. provide \cw{dupprintf}; see \k{udp-security}.)
  187. Compiler independence should apply on all platforms, of course, not
  188. just on Windows.
  189. \H{udp-small} Small code size
  190. PuTTY is tiny, compared to many other Windows applications. And it's
  191. easy to install: it depends on no DLLs, no other applications, no
  192. service packs or system upgrades. It's just one executable. You
  193. install that executable wherever you want to, and run it.
  194. We want to keep both these properties - the small size, and the ease
  195. of installation - if at all possible. So code contributions that
  196. depend critically on external DLLs, or that add a huge amount to the
  197. code size for a feature which is only useful to a small minority of
  198. users, are likely to be thrown out immediately.
  199. We do vaguely intend to introduce a DLL plugin interface for PuTTY,
  200. whereby seriously large extra features can be implemented in plugin
  201. modules. The important thing, though, is that those DLLs will be
  202. \e{optional}; if PuTTY can't find them on startup, it should run
  203. perfectly happily and just won't provide those particular features.
  204. A full installation of PuTTY might one day contain ten or twenty
  205. little DLL plugins, which would cut down a little on the ease of
  206. installation - but if you really needed ease of installation you
  207. \e{could} still just install the one PuTTY binary, or just the DLLs
  208. you really needed, and it would still work fine.
  209. Depending on \e{external} DLLs is something we'd like to avoid if at
  210. all possible (though for some purposes, such as complex SSH
  211. authentication mechanisms, it may be unavoidable). If it can't be
  212. avoided, the important thing is to follow the same principle of
  213. graceful degradation: if a DLL can't be found, then PuTTY should run
  214. happily and just not supply the feature that depended on it.
  215. \H{udp-single-threaded} Single-threaded code
  216. PuTTY and its supporting tools, or at least the vast majority of
  217. them, run in only one OS thread.
  218. This means that if you're devising some piece of internal mechanism,
  219. there's no need to use locks to make sure it doesn't get called by
  220. two threads at once. The only way code can be called re-entrantly is
  221. by recursion.
  222. That said, most of Windows PuTTY's network handling is triggered off
  223. Windows messages requested by \cw{WSAAsyncSelect()}, so if you call
  224. \cw{MessageBox()} deep within some network event handling code you
  225. should be aware that you might be re-entered if a network event
  226. comes in and is passed on to our window procedure by the
  227. \cw{MessageBox()} message loop.
  228. Also, the front ends (in particular Windows Plink) can use multiple
  229. threads if they like. However, Windows Plink keeps \e{very} tight
  230. control of its auxiliary threads, and uses them pretty much
  231. exclusively as a form of \cw{select()}. Pretty much all the code
  232. outside \cw{windows/winplink.c} is \e{only} ever called from the one
  233. primary thread; the others just loop round blocking on file handles
  234. and send messages to the main thread when some real work needs
  235. doing. This is not considered a portability hazard because that bit
  236. of \cw{windows/winplink.c} will need rewriting on other platforms in
  237. any case.
  238. One important consequence of this: PuTTY has only one thread in
  239. which to do everything. That \q{everything} may include managing
  240. more than one login session (\k{udp-globals}), managing multiple
  241. data channels within an SSH session, responding to GUI events even
  242. when nothing is happening on the network, and responding to network
  243. requests from the server (such as repeat key exchange) even when the
  244. program is dealing with complex user interaction such as the
  245. re-configuration dialog box. This means that \e{almost none} of the
  246. PuTTY code can safely block.
  247. \H{udp-keystrokes} Keystrokes sent to the server wherever possible
  248. In almost all cases, PuTTY sends keystrokes to the server. Even
  249. weird keystrokes that you think should be hot keys controlling
  250. PuTTY. Even Alt-F4 or Alt-Space, for example. If a keystroke has a
  251. well-defined escape sequence that it could usefully be sending to
  252. the server, then it should do so, or at the very least it should be
  253. configurably able to do so.
  254. To unconditionally turn a key combination into a hot key to control
  255. PuTTY is almost always a design error. If a hot key is really truly
  256. required, then try to find a key combination for it which \e{isn't}
  257. already used in existing PuTTYs (either it sends nothing to the
  258. server, or it sends the same thing as some other combination). Even
  259. then, be prepared for the possibility that one day that key
  260. combination might end up being needed to send something to the
  261. server - so make sure that there's an alternative way to invoke
  262. whatever PuTTY feature it controls.
  263. \H{udp-640x480} 640\u00D7{x}480 friendliness in configuration panels
  264. There's a reason we have lots of tiny configuration panels instead
  265. of a few huge ones, and that reason is that not everyone has a
  266. 1600\u00D7{x}1200 desktop. 640\u00D7{x}480 is still a viable
  267. resolution for running Windows (and indeed it's still the default if
  268. you start up in safe mode), so it's still a resolution we care
  269. about.
  270. Accordingly, the PuTTY configuration box, and the PuTTYgen control
  271. window, are deliberately kept just small enough to fit comfortably
  272. on a 640\u00D7{x}480 display. If you're adding controls to either of
  273. these boxes and you find yourself wanting to increase the size of
  274. the whole box, \e{don't}. Split it into more panels instead.
  275. \H{udp-makefiles-auto} Automatically generated \cw{Makefile}s
  276. PuTTY is intended to compile on multiple platforms, and with
  277. multiple compilers. It would be horrifying to try to maintain a
  278. single \cw{Makefile} which handled all possible situations, and just
  279. as painful to try to directly maintain a set of matching
  280. \cw{Makefile}s for each different compilation environment.
  281. Therefore, we have moved the problem up by one level. In the PuTTY
  282. source archive is a file called \c{Recipe}, which lists which source
  283. files combine to produce which binaries; and there is also a script
  284. called \cw{mkfiles.pl}, which reads \c{Recipe} and writes out the
  285. real \cw{Makefile}s. (The script also reads all the source files and
  286. analyses their dependencies on header files, so we get an extra
  287. benefit from doing it this way, which is that we can supply correct
  288. dependency information even in environments where it's difficult to
  289. set up an automated \c{make depend} phase.)
  290. You should \e{never} edit any of the PuTTY \cw{Makefile}s directly.
  291. They are not stored in our source repository at all. They are
  292. automatically generated by \cw{mkfiles.pl} from the file \c{Recipe}.
  293. If you need to add a new object file to a particular binary, the
  294. right thing to do is to edit \c{Recipe} and re-run \cw{mkfiles.pl}.
  295. This will cause the new object file to be added in every tool that
  296. requires it, on every platform where it matters, in every
  297. \cw{Makefile} to which it is relevant, \e{and} to get all the
  298. dependency data right.
  299. If you send us a patch that modifies one of the \cw{Makefile}s, you
  300. just waste our time, because we will have to convert it into a
  301. change to \c{Recipe}. If you send us a patch that modifies \e{all}
  302. of the \cw{Makefile}s, you will have wasted a lot of \e{your} time
  303. as well!
  304. (There is a comment at the top of every \cw{Makefile} in the PuTTY
  305. source archive saying this, but many people don't seem to read it,
  306. so it's worth repeating here.)
  307. \H{udp-ssh-coroutines} Coroutines in the SSH code
  308. Large parts of the code in the various SSH modules (in fact most of
  309. the protocol layers) are structured using a set of macros that
  310. implement (something close to) Donald Knuth's \q{coroutines} concept
  311. in C.
  312. Essentially, the purpose of these macros are to arrange that a
  313. function can call \cw{crReturn()} to return to its caller, and the
  314. next time it is called control will resume from just after that
  315. \cw{crReturn} statement.
  316. This means that any local (automatic) variables declared in such a
  317. function will be corrupted every time you call \cw{crReturn}. If you
  318. need a variable to persist for longer than that, you \e{must} make it
  319. a field in some appropriate structure containing the persistent state
  320. of the coroutine \dash typically the main state structure for an SSH
  321. protocol layer.
  322. See
  323. \W{https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}\c{https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}
  324. for a more in-depth discussion of what these macros are for and how
  325. they work.
  326. Another caveat: most of these coroutines are not \e{guaranteed} to run
  327. to completion, because the SSH connection (or whatever) that they're
  328. part of might be interrupted at any time by an unexpected network
  329. event or user action. So whenever a coroutine-managed variable refers
  330. to a resource that needs releasing, you should also ensure that the
  331. cleanup function for its containing state structure can reliably
  332. release it even if the coroutine is aborted at an arbitrary point.
  333. For example, if an SSH packet protocol layer has to have a field that
  334. sometimes points to a piece of allocated memory, then you should
  335. ensure that when you free that memory you reset the pointer field to
  336. \cw{NULL}. Then, no matter when the protocol layer's cleanup function
  337. is called, it can reliably free the memory if there is any, and not
  338. crash if there isn't.
  339. \H{udp-traits} Explicit vtable structures to implement traits
  340. A lot of PuTTY's code is written in a style that looks structurally
  341. rather like an object-oriented language, in spite of PuTTY being a
  342. pure C program.
  343. For example, there's a single data type called \cw{ssh_hash}, which is
  344. an abstraction of a secure hash function, and a bunch of functions
  345. called things like \cw{ssh_hash_}\e{foo} that do things with those
  346. data types. But in fact, PuTTY supports many different hash functions,
  347. and each one has to provide its own implementation of those functions.
  348. In C++ terms, this is rather like having a single abstract base class,
  349. and multiple concrete subclasses of it, each of which fills in all the
  350. pure virtual methods in a way that's compatible with the data fields
  351. of the subclass. The implementation is more or less the same, as well:
  352. in C, we do explicitly in the source code what the C++ compiler will
  353. be doing behind the scenes at compile time.
  354. But perhaps a closer analogy in functional terms is the Rust concept
  355. of a \q{trait}, or the Java idea of an \q{interface}. C++ supports a
  356. multi-level hierarchy of inheritance, whereas PuTTY's system \dash
  357. like traits or interfaces \dash has only two levels, one describing a
  358. generic object of a type (e.g. a hash function) and another describing
  359. a specific implementation of that type (e.g. SHA-256).
  360. The PuTTY code base has a standard idiom for doing this in C, as
  361. follows.
  362. Firstly, we define two \cw{struct} types for our trait. One of them
  363. describes a particular \e{kind} of implementation of that trait, and
  364. it's full of (mostly) function pointers. The other describes a
  365. specific \e{instance} of an implementation of that trait, and it will
  366. contain a pointer to a \cw{const} instance of the first type. For
  367. example:
  368. \c typedef struct MyAbstraction MyAbstraction;
  369. \c typedef struct MyAbstractionVtable MyAbstractionVtable;
  370. \c
  371. \c struct MyAbstractionVtable {
  372. \c MyAbstraction *(*new)(const MyAbstractionVtable *vt);
  373. \c void (*free)(MyAbstraction *);
  374. \c void (*modify)(MyAbstraction *, unsigned some_parameter);
  375. \c unsigned (*query)(MyAbstraction *, unsigned some_parameter);
  376. \c };
  377. \c
  378. \c struct MyAbstraction {
  379. \c const MyAbstractionVtable *vt;
  380. \c };
  381. Here, we imagine that \cw{MyAbstraction} might be some kind of object
  382. that contains mutable state. The associated vtable structure shows
  383. what operations you can perform on a \cw{MyAbstraction}: you can
  384. create one (dynamically allocated), free one you already have, or call
  385. the example methods \q{modify} (to change the state of the object in
  386. some way) and \q{query} (to return some value derived from the
  387. object's current state).
  388. (In most cases, the vtable structure has a name ending in \cq{vtable}.
  389. But for historical reasons a lot of the crypto primitives that use
  390. this scheme \dash ciphers, hash functions, public key methods and so
  391. on \dash instead have names ending in \cq{alg}, on the basis that the
  392. primitives they implement are often referred to as \q{encryption
  393. algorithms}, \q{hash algorithms} and so forth.)
  394. Now, to define a concrete instance of this trait, you'd define a
  395. \cw{struct} that contains a \cw{MyAbstraction} field, plus any other
  396. data it might need:
  397. \c struct MyImplementation {
  398. \c unsigned internal_data[16];
  399. \c SomeOtherType *dynamic_subthing;
  400. \c
  401. \c MyAbstraction myabs;
  402. \c };
  403. Next, you'd implement all the necessary methods for that
  404. implementation of the trait, in this kind of style:
  405. \c static MyAbstraction *myimpl_new(const MyAbstractionVtable *vt)
  406. \c {
  407. \c MyImplementation *impl = snew(MyImplementation);
  408. \c memset(impl, 0, sizeof(*impl));
  409. \c impl->dynamic_subthing = allocate_some_other_type();
  410. \c impl->myabs.vt = vt;
  411. \c return &impl->myabs;
  412. \c }
  413. \c
  414. \c static void myimpl_free(MyAbstraction *myabs)
  415. \c {
  416. \c MyImplementation *impl = container_of(myabs, MyImplementation, myabs);
  417. \c free_other_type(impl->dynamic_subthing);
  418. \c sfree(impl);
  419. \c }
  420. \c
  421. \c static void myimpl_modify(MyAbstraction *myabs, unsigned param)
  422. \c {
  423. \c MyImplementation *impl = container_of(myabs, MyImplementation, myabs);
  424. \c impl->internal_data[param] += do_something_with(impl->dynamic_subthing);
  425. \c }
  426. \c
  427. \c static unsigned myimpl_query(MyAbstraction *myabs, unsigned param)
  428. \c {
  429. \c MyImplementation *impl = container_of(myabs, MyImplementation, myabs);
  430. \c return impl->internal_data[param];
  431. \c }
  432. Having defined those methods, now we can define a \cw{const} instance
  433. of the vtable structure containing pointers to them:
  434. \c const MyAbstractionVtable MyImplementation_vt = {
  435. \c .new = myimpl_new,
  436. \c .free = myimpl_free,
  437. \c .modify = myimpl_modify,
  438. \c .query = myimpl_query,
  439. \c };
  440. \e{In principle}, this is all you need. Client code can construct a
  441. new instance of a particular implementation of \cw{MyAbstraction} by
  442. digging out the \cw{new} method from the vtable and calling it (with
  443. the vtable itself as a parameter), which returns a \cw{MyAbstraction
  444. *} pointer that identifies a newly created instance, in which the
  445. \cw{vt} field will contain a pointer to the same vtable structure you
  446. passed in. And once you have an instance object, say \cw{MyAbstraction
  447. *myabs}, you can dig out one of the other method pointers from the
  448. vtable it points to, and call that, passing the object itself as a
  449. parameter.
  450. But in fact, we don't do that, because it looks pretty ugly at all the
  451. call sites. Instead, what we generally do in this code base is to
  452. write a set of \cw{static inline} wrapper functions in the same header
  453. file that defined the \cw{MyAbstraction} structure types, like this:
  454. \c static MyAbstraction *myabs_new(const MyAbstractionVtable *vt)
  455. \c { return vt->new(vt); }
  456. \c static void myabs_free(MyAbstraction *myabs)
  457. \c { myabs->vt->free(myabs); }
  458. \c static void myimpl_modify(MyAbstraction *myabs, unsigned param)
  459. \c { myabs->vt->modify(myabs, param); }
  460. \c static unsigned myimpl_query(MyAbstraction *myabs, unsigned param)
  461. \c { return myabs->vt->query(myabs, param); }
  462. And now call sites can use those reasonably clean-looking wrapper
  463. functions, and shouldn't ever have to directly refer to the \cw{vt}
  464. field inside any \cw{myabs} object they're holding. For example, you
  465. might write something like this:
  466. \c MyAbstraction *myabs = myabs_new(&MyImplementation_vtable);
  467. \c myabs_update(myabs, 10);
  468. \c unsigned output = myabs_query(myabs, 2);
  469. \c myabs_free(myabs);
  470. and then all this code can use a different implementation of the same
  471. abstraction by just changing which vtable pointer it passed in in the
  472. first line.
  473. Some things to note about this system:
  474. \b The implementation instance type (here \cq{MyImplementation}
  475. contains the abstraction type (\cq{MyAbstraction}) as one of its
  476. fields. But that field is not necessarily at the start of the
  477. structure. So you can't just \e{cast} pointers back and forth between
  478. the two types. Instead:
  479. \lcont{
  480. \b You \q{up-cast} from implementation to abstraction by taking the
  481. address of the \cw{MyAbstraction} field. You can see the example
  482. \cw{new} method above doing this, returning \cw{&impl->myabs}. All
  483. \cw{new} methods do this on return.
  484. \b Going in the other direction, each method that was passed a generic
  485. \cw{MyAbstraction *myabs} parameter has to recover a pointer to the
  486. specific implementation type \cw{MyImplementation *impl}. The idiom
  487. for doing that is to use the \cq{container_of} macro, also seen in the
  488. Linux kernel code. Generally, \cw{container_of(p, Type, field)} says:
  489. \q{I'm confident that the pointer value \cq{p} is pointing to the
  490. field called \cq{field} within a larger \cw{struct} of type \cw{Type}.
  491. Please return me the pointer to the containing structure.} So in this
  492. case, we take the \cq{myabs} pointer passed to the function, and
  493. \q{down-cast} it into a pointer to the larger and more specific
  494. structure type \cw{MyImplementation}, by adjusting the pointer value
  495. based on the offset within that structure of the field called
  496. \cq{myabs}.
  497. This system is flexible enough to permit \q{multiple inheritance}, or
  498. rather, multiple \e{implementation}: having one object type implement
  499. more than one trait. For example, the \cw{Proxy} type implements both
  500. the \cw{Socket} trait and the \cw{Plug} trait that connects to it,
  501. because it has to act as an adapter between another instance of each
  502. of those types.
  503. It's also perfectly possible to have the same object implement the
  504. \e{same} trait in two different ways. At the time of writing this I
  505. can't think of any case where we actually do this, but a theoretical
  506. example might be if you needed to support a trait like \cw{Comparable}
  507. in two ways that sorted by different criteria. There would be no
  508. difficulty doing this in the PuTTY system: simply have your
  509. implementation \cw{struct} contain two (or more) fields of the same
  510. abstraction type. The fields will have different names, which makes it
  511. easy to explicitly specify which one you're returning a pointer to
  512. during up-casting, or which one you're down-casting from using
  513. \cw{container_of}. And then both sets of implementation methods can
  514. recover a pointer to the same containing structure.
  515. }
  516. \b Unlike in C++, all objects in PuTTY that use this system are
  517. dynamically allocated. The \q{constructor} functions (whether they're
  518. virtualised across the whole abstraction or specific to each
  519. implementation) always allocate memory and return a pointer to it. The
  520. \q{free} method (our analogue of a destructor) always expects the
  521. input pointer to be dynamically allocated, and frees it. As a result,
  522. client code doesn't need to know how large the implementing object
  523. type is, because it will never need to allocate it (on the stack or
  524. anywhere else).
  525. \b Unlike in C++, the abstraction's \q{vtable} structure does not only
  526. hold methods that you can call on an instance object. It can also
  527. hold several other kinds of thing:
  528. \lcont{
  529. \b Methods that you can call \e{without} an instance object, given
  530. only the vtable structure identifying a particular implementation of
  531. the trait. You might think of these as \q{static methods}, as in C++,
  532. except that they're \e{virtual} \dash the same code can call the
  533. static method of a different \q{class} given a different vtable
  534. pointer. So they're more like \q{virtual static methods}, which is a
  535. concept C++ doesn't have. An example is the \cw{pubkey_bits} method in
  536. \cw{ssh_keyalg}.
  537. \b The most important case of a \q{virtual static method} is the
  538. \cw{new} method that allocates and returns a new object. You can think
  539. of it as a \q{virtual constructor} \dash another concept C++ doesn't
  540. have. (However, not all types need one of these: see below.)
  541. \b The vtable can also contain constant data relevant to the class as
  542. a whole \dash \q{virtual constant data}. For example, a cryptographic
  543. hash function will contain an integer field giving the length of the
  544. output hash, and most crypto primitives will contain a string field
  545. giving the identifier used in the SSH protocol that describes that
  546. primitive.
  547. The effect of all of this is that you can make other pieces of code
  548. able to use any instance of one of these types, by passing it an
  549. actual vtable as a parameter. For example, the \cw{hash_simple}
  550. function takes an \cw{ssh_hashalg} vtable pointer specifying any hash
  551. algorithm you like, and internally, it creates an object of that type,
  552. uses it, and frees it. In C++, you'd probably do this using a
  553. template, which would mean you had multiple specialisations of
  554. \cw{hash_simple} \dash and then it would be much more difficult to
  555. decide \e{at run time} which one you needed to use. Here,
  556. \cw{hash_simple} is still just one function, and you can decide as
  557. late as you like which vtable to pass to it.
  558. }
  559. \b The abstract \e{instance} structure can also contain publicly
  560. visible data fields (this time, usually treated as mutable) which are
  561. common to all implementations of the trait. For example,
  562. \cw{BinaryPacketProtocol} has lots of these.
  563. \b Not all abstractions of this kind want virtual constructors. It
  564. depends on how different the implementations are.
  565. \lcont{
  566. With a crypto primitive like a hash algorithm, the constructor call
  567. looks the same for every implementing type, so it makes sense to have
  568. a standardised virtual constructor in the vtable and a
  569. \cw{ssh_hash_new} wrapper function which can make an instance of
  570. whatever vtable you pass it. And then you make all the vtable objects
  571. themselves globally visible throughout the source code, so that any
  572. module can call (for example) \cw{ssh_hash_new(&ssh_sha256)}.
  573. But with other kinds of object, the constructor for each implementing
  574. type has to take a different set of parameters. For example,
  575. implementations of \cw{Socket} are not generally interchangeable at
  576. construction time, because constructing different kinds of socket
  577. require totally different kinds of address parameter. In that
  578. situation, it makes more sense to keep the vtable structure itself
  579. private to the implementing source file, and instead, publish an
  580. ordinary constructing function that allocates and returns an instance
  581. of that particular subtype, taking whatever parameters are appropriate
  582. to that subtype.
  583. }
  584. \b If you do have virtual constructors, you can choose whether they
  585. take a vtable pointer as a parameter (as shown above), or an
  586. \e{existing} instance object. In the latter case, they can refer to
  587. the object itself as well as the vtable. For example, you could have a
  588. trait come with a virtual constructor called \q{clone}, meaning
  589. \q{Make a copy of this object, no matter which implementation it is.}
  590. \b Sometimes, a single vtable structure type can be shared between two
  591. completely different object types, and contain all the methods for
  592. both. For example, \cw{ssh_compression_alg} contains methods to
  593. create, use and free \cw{ssh_compressor} and \cw{ssh_decompressor}
  594. objects, which are not interchangeable \dash but putting their methods
  595. in the same vtable means that it's easy to create a matching pair of
  596. objects that are compatible with each other.
  597. \b Passing the vtable itself as an argument to the \cw{new} method is
  598. not compulsory: if a given \cw{new} implementation is only used by a
  599. single vtable, then that function can simply hard-code the vtable
  600. pointer that it writes into the object it constructs. But passing the
  601. vtable is more flexible, because it allows a single constructor
  602. function to be shared between multiple slightly different object
  603. types. For example, SHA-384 and SHA-512 share the same \cw{new} method
  604. and the same implementation data type, because they're very nearly the
  605. same hash algorithm \dash but a couple of the other methods in their
  606. vtables are different, because the \q{reset} function has to set up
  607. the initial algorithm state differently, and the \q{digest} method has
  608. to write out a different amount of data.
  609. \lcont{
  610. One practical advantage of having the \cw{myabs_}\e{foo} family of
  611. inline wrapper functions in the header file is that if you change your
  612. mind later about whether the vtable needs to be passed to \cw{new},
  613. you only have to update the \cw{myabs_new} wrapper, and then the
  614. existing call sites won't need changing.
  615. }
  616. \b Another piece of \q{stunt object orientation} made possible by this
  617. scheme is that you can write two vtables that both use the same
  618. structure layout for the implementation object, and have an object
  619. \e{transform from one to the other} part way through its lifetime, by
  620. overwriting its own vtable pointer field. For example, the
  621. \cw{sesschan} type that handles the server side of an SSH terminal
  622. session will sometimes transform in mid-lifetime into an SCP or SFTP
  623. file-transfer channel in this way, at the point where the client sends
  624. an \cq{exec} or \cq{subsystem} request that indicates that that's what
  625. it wants to do with the channel.
  626. \lcont{
  627. This concept would be difficult to arrange in C++. In Rust, it
  628. wouldn't even \e{make sense}, because in Rust, objects implementing a
  629. trait don't even contain a vtable pointer at all \dash instead, the
  630. \q{trait object} type (identifying a specific instance of some
  631. implementation of a given trait) consists of a pair of pointers, one
  632. to the object itself and one to the vtable. In that model, the only
  633. way you could make an existing object turn into a different trait
  634. would be to know where all the pointers to it were stored elsewhere in
  635. the program, and persuade all their owners to rewrite them.
  636. }
  637. \b Another stunt you can do is to have a vtable that doesn't have a
  638. corresponding implementation structure at all, because the only
  639. methods implemented in it are the constructors, and they always end up
  640. returning an implementation of some other vtable. For example, some of
  641. PuTTY's crypto primitives have a hardware-accelerated version and a
  642. pure software version, and decide at run time which one to use (based
  643. on whether the CPU they're running on supports the necessary
  644. acceleration instructions). So, for example, there are vtables for
  645. \cw{ssh_sha256_sw} and \cw{ssh_sha256_hw}, each of which has its own
  646. data layout and its own implementations of all the methods; and then
  647. there's a top-level vtable \cw{ssh_sha256}, which only provides the
  648. \q{new} method, and implements it by calling the \q{new} method on one
  649. or other of the subtypes depending on what it finds out about the
  650. machine it's running on. That top-level selector vtable is nearly
  651. always the one used by client code. (Except for the test suite, which
  652. has to instantiate both of the subtypes in order to make sure they
  653. both pass the tests.)
  654. \lcont{
  655. As a result, the top-level selector vtable \cw{ssh_sha256} doesn't
  656. need to implement any method that takes an \cw{ssh_cipher *}
  657. parameter, because no \cw{ssh_cipher} object is ever constructed whose
  658. \cw{vt} field points to \cw{&ssh_sha256}: they all point to one of the
  659. other two full implementation vtables.
  660. }
  661. \H{udp-compile-once} Single compilation of each source file
  662. The PuTTY build system for any given platform works on the following
  663. very simple model:
  664. \b Each source file is compiled precisely once, to produce a single
  665. object file.
  666. \b Each binary is created by linking together some combination of
  667. those object files.
  668. Therefore, if you need to introduce functionality to a particular
  669. module which is only available in some of the tool binaries (for
  670. example, a cryptographic proxy authentication mechanism which needs
  671. to be left out of PuTTYtel to maintain its usability in
  672. crypto-hostile jurisdictions), the \e{wrong} way to do it is by
  673. adding \cw{#ifdef}s in (say) \cw{proxy.c}. This would require
  674. separate compilation of \cw{proxy.c} for PuTTY and PuTTYtel, which
  675. means that the entire \cw{Makefile}-generation architecture (see
  676. \k{udp-makefiles-auto}) would have to be significantly redesigned.
  677. Unless you are prepared to do that redesign yourself, \e{and}
  678. guarantee that it will still port to any future platforms we might
  679. decide to run on, you should not attempt this!
  680. The \e{right} way to introduce a feature like this is to put the new
  681. code in a separate source file, and (if necessary) introduce a
  682. second new source file defining the same set of functions, but
  683. defining them as stubs which don't provide the feature. Then the
  684. module whose behaviour needs to vary (\cw{proxy.c} in this example)
  685. can call the functions defined in these two modules, and it will
  686. either provide the new feature or not provide it according to which
  687. of your new modules it is linked with.
  688. Of course, object files are never shared \e{between} platforms; so
  689. it is allowable to use \cw{#ifdef} to select between platforms. This
  690. happens in \cw{puttyps.h} (choosing which of the platform-specific
  691. include files to use), and also in \cw{misc.c} (the Windows-specific
  692. \q{Minefield} memory diagnostic system). It should be used
  693. sparingly, though, if at all.
  694. \H{udp-perfection} Do as we say, not as we do
  695. The current PuTTY code probably does not conform strictly to \e{all}
  696. of the principles listed above. There may be the occasional
  697. SSH-specific piece of code in what should be a backend-independent
  698. module, or the occasional dependence on a non-standard X library
  699. function under Unix.
  700. This should not be taken as a licence to go ahead and violate the
  701. rules. Where we violate them ourselves, we're not happy about it,
  702. and we would welcome patches that fix any existing problems. Please
  703. try to help us make our code better, not worse!