udp.but 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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 Mac-specific modules are in the \c{mac}
  23. subdirectory; the Windows-specific modules are in the \c{windows}
  24. subdirectory.
  25. All the modules in the main source directory - notably \e{all} of
  26. the code for the various back ends - are platform-generic. We want
  27. to keep them that way.
  28. This also means you should stick to what you are guaranteed by
  29. ANSI/ISO C (that is, the original C89/C90 standard, not C99). Try
  30. not to make assumptions about the precise size of basic types such
  31. as \c{int} and \c{long int}; don't use pointer casts to do
  32. endianness-dependent operations, and so on.
  33. (There are one or two aspects of ANSI C portability which we
  34. \e{don't} care about. In particular, we expect PuTTY to be compiled
  35. on 32-bit architectures \e{or bigger}; so it's safe to assume that
  36. \c{int} is at least 32 bits wide, not just the 16 you are guaranteed
  37. by ANSI C. Similarly, we assume that the execution character
  38. encoding is a superset of the printable characters of ASCII, though
  39. we don't assume the numeric values of control characters,
  40. particularly \cw{'\\n'} and \cw{'\\r'}. Also, the X forwarding code
  41. assumes that \c{time_t} has the Unix format and semantics, i.e. an
  42. integer giving the number of seconds since 1970.)
  43. \H{udp-multi-backend} Multiple backends treated equally
  44. PuTTY is not an SSH client with some other stuff tacked on the side.
  45. PuTTY is a generic, multiple-backend, remote VT-terminal client
  46. which happens to support one backend which is larger, more popular
  47. and more useful than the rest. Any extra feature which can possibly
  48. be general across all backends should be so: localising features
  49. unnecessarily into the SSH back end is a design error. (For example,
  50. we had several code submissions for proxy support which worked by
  51. hacking \cw{ssh.c}. Clearly this is completely wrong: the
  52. \cw{network.h} abstraction is the place to put it, so that it will
  53. apply to all back ends equally, and indeed we eventually put it
  54. there after another contributor sent a better patch.)
  55. The rest of PuTTY should try to avoid knowing anything about
  56. specific back ends if at all possible. To support a feature which is
  57. only available in one network protocol, for example, the back end
  58. interface should be extended in a general manner such that \e{any}
  59. back end which is able to provide that feature can do so. If it so
  60. happens that only one back end actually does, that's just the way it
  61. is, but it shouldn't be relied upon by any code.
  62. \H{udp-globals} Multiple sessions per process on some platforms
  63. Some ports of PuTTY - notably the in-progress Mac port - are
  64. constrained by the operating system to run as a single process
  65. potentially managing multiple sessions.
  66. Therefore, the platform-independent parts of PuTTY never use global
  67. variables to store per-session data. The global variables that do
  68. exist are tolerated because they are not specific to a particular
  69. login session: \c{flags} defines properties that are expected to
  70. apply equally to \e{all} the sessions run by a single PuTTY process,
  71. the random number state in \cw{sshrand.c} and the timer list in
  72. \cw{timing.c} serve all sessions equally, and so on. But most data
  73. is specific to a particular network session, and is therefore stored
  74. in dynamically allocated data structures, and pointers to these
  75. structures are passed around between functions.
  76. Platform-specific code can reverse this decision if it likes. The
  77. Windows code, for historical reasons, stores most of its data as
  78. global variables. That's OK, because \e{on Windows} we know there is
  79. only one session per PuTTY process, so it's safe to do that. But
  80. changes to the platform-independent code should avoid introducing
  81. global variables, unless they are genuinely cross-session.
  82. \H{udp-pure-c} C, not C++
  83. PuTTY is written entirely in C, not in C++.
  84. We have made \e{some} effort to make it easy to compile our code
  85. using a C++ compiler: notably, our \c{snew}, \c{snewn} and
  86. \c{sresize} macros explicitly cast the return values of \cw{malloc}
  87. and \cw{realloc} to the target type. (This has type checking
  88. advantages even in C: it means you never accidentally allocate the
  89. wrong size piece of memory for the pointer type you're assigning it
  90. to. C++ friendliness is really a side benefit.)
  91. We want PuTTY to continue being pure C, at least in the
  92. platform-independent parts and the currently existing ports. Patches
  93. which switch the Makefiles to compile it as C++ and start using
  94. classes will not be accepted. Also, in particular, we disapprove of
  95. \cw{//} comments, at least for the moment. (Perhaps once C99 becomes
  96. genuinely widespread we might be more lenient.)
  97. The one exception: a port to a new platform may use languages other
  98. than C if they are necessary to code on that platform. If your
  99. favourite PDA has a GUI with a C++ API, then there's no way you can
  100. do a port of PuTTY without using C++, so go ahead and use it. But
  101. keep the C++ restricted to that platform's subdirectory; if your
  102. changes force the Unix or Windows ports to be compiled as C++, they
  103. will be unacceptable to us.
  104. \H{udp-security} Security-conscious coding
  105. PuTTY is a network application and a security application. Assume
  106. your code will end up being fed deliberately malicious data by
  107. attackers, and try to code in a way that makes it unlikely to be a
  108. security risk.
  109. In particular, try not to use fixed-size buffers for variable-size
  110. data such as strings received from the network (or even the user).
  111. We provide functions such as \cw{dupcat} and \cw{dupprintf}, which
  112. dynamically allocate buffers of the right size for the string they
  113. construct. Use these wherever possible.
  114. \H{udp-multi-compiler} Independence of specific compiler
  115. Windows PuTTY can currently be compiled with any of four Windows
  116. compilers: MS Visual C, Borland's freely downloadable C compiler,
  117. the Cygwin / \cw{mingw32} GNU tools, and \cw{lcc-win32}.
  118. This is a really useful property of PuTTY, because it means people
  119. who want to contribute to the coding don't depend on having a
  120. specific compiler; so they don't have to fork out money for MSVC if
  121. they don't already have it, but on the other hand if they \e{do}
  122. have it they also don't have to spend effort installing \cw{gcc}
  123. alongside it. They can use whichever compiler they happen to have
  124. available, or install whichever is cheapest and easiest if they
  125. don't have one.
  126. Therefore, we don't want PuTTY to start depending on which compiler
  127. you're using. Using GNU extensions to the C language, for example,
  128. would ruin this useful property (not that anyone's ever tried it!);
  129. and more realistically, depending on an MS-specific library function
  130. supplied by the MSVC C library (\cw{_snprintf}, for example) is a
  131. mistake, because that function won't be available under the other
  132. compilers. Any function supplied in an official Windows DLL as part
  133. of the Windows API is fine, and anything defined in the C library
  134. standard is also fine, because those should be available
  135. irrespective of compilation environment. But things in between,
  136. available as non-standard library and language extensions in only
  137. one compiler, are disallowed.
  138. (\cw{_snprintf} in particular should be unnecessary, since we
  139. provide \cw{dupprintf}; see \k{udp-security}.)
  140. Compiler independence should apply on all platforms, of course, not
  141. just on Windows.
  142. \H{udp-small} Small code size
  143. PuTTY is tiny, compared to many other Windows applications. And it's
  144. easy to install: it depends on no DLLs, no other applications, no
  145. service packs or system upgrades. It's just one executable. You
  146. install that executable wherever you want to, and run it.
  147. We want to keep both these properties - the small size, and the ease
  148. of installation - if at all possible. So code contributions that
  149. depend critically on external DLLs, or that add a huge amount to the
  150. code size for a feature which is only useful to a small minority of
  151. users, are likely to be thrown out immediately.
  152. We do vaguely intend to introduce a DLL plugin interface for PuTTY,
  153. whereby seriously large extra features can be implemented in plugin
  154. modules. The important thing, though, is that those DLLs will be
  155. \e{optional}; if PuTTY can't find them on startup, it should run
  156. perfectly happily and just won't provide those particular features.
  157. A full installation of PuTTY might one day contain ten or twenty
  158. little DLL plugins, which would cut down a little on the ease of
  159. installation - but if you really needed ease of installation you
  160. \e{could} still just install the one PuTTY binary, or just the DLLs
  161. you really needed, and it would still work fine.
  162. Depending on \e{external} DLLs is something we'd like to avoid if at
  163. all possible (though for some purposes, such as complex SSH
  164. authentication mechanisms, it may be unavoidable). If it can't be
  165. avoided, the important thing is to follow the same principle of
  166. graceful degradation: if a DLL can't be found, then PuTTY should run
  167. happily and just not supply the feature that depended on it.
  168. \H{udp-single-threaded} Single-threaded code
  169. PuTTY and its supporting tools, or at least the vast majority of
  170. them, run in only one OS thread.
  171. This means that if you're devising some piece of internal mechanism,
  172. there's no need to use locks to make sure it doesn't get called by
  173. two threads at once. The only way code can be called re-entrantly is
  174. by recursion.
  175. That said, most of Windows PuTTY's network handling is triggered off
  176. Windows messages requested by \cw{WSAAsyncSelect()}, so if you call
  177. \cw{MessageBox()} deep within some network event handling code you
  178. should be aware that you might be re-entered if a network event
  179. comes in and is passed on to our window procedure by the
  180. \cw{MessageBox()} message loop.
  181. Also, the front ends (in particular Windows Plink) can use multiple
  182. threads if they like. However, Windows Plink keeps \e{very} tight
  183. control of its auxiliary threads, and uses them pretty much
  184. exclusively as a form of \cw{select()}. Pretty much all the code
  185. outside \cw{windows/winplink.c} is \e{only} ever called from the one
  186. primary thread; the others just loop round blocking on file handles
  187. and send messages to the main thread when some real work needs
  188. doing. This is not considered a portability hazard because that bit
  189. of \cw{windows/winplink.c} will need rewriting on other platforms in
  190. any case.
  191. One important consequence of this: PuTTY has only one thread in
  192. which to do everything. That \q{everything} may include managing
  193. more than one login session (\k{udp-globals}), managing multiple
  194. data channels within an SSH session, responding to GUI events even
  195. when nothing is happening on the network, and responding to network
  196. requests from the server (such as repeat key exchange) even when the
  197. program is dealing with complex user interaction such as the
  198. re-configuration dialog box. This means that \e{almost none} of the
  199. PuTTY code can safely block.
  200. \H{udp-keystrokes} Keystrokes sent to the server wherever possible
  201. In almost all cases, PuTTY sends keystrokes to the server. Even
  202. weird keystrokes that you think should be hot keys controlling
  203. PuTTY. Even Alt-F4 or Alt-Space, for example. If a keystroke has a
  204. well-defined escape sequence that it could usefully be sending to
  205. the server, then it should do so, or at the very least it should be
  206. configurably able to do so.
  207. To unconditionally turn a key combination into a hot key to control
  208. PuTTY is almost always a design error. If a hot key is really truly
  209. required, then try to find a key combination for it which \e{isn't}
  210. already used in existing PuTTYs (either it sends nothing to the
  211. server, or it sends the same thing as some other combination). Even
  212. then, be prepared for the possibility that one day that key
  213. combination might end up being needed to send something to the
  214. server - so make sure that there's an alternative way to invoke
  215. whatever PuTTY feature it controls.
  216. \H{udp-640x480} 640\u00D7{x}480 friendliness in configuration panels
  217. There's a reason we have lots of tiny configuration panels instead
  218. of a few huge ones, and that reason is that not everyone has a
  219. 1600\u00D7{x}1200 desktop. 640\u00D7{x}480 is still a viable
  220. resolution for running Windows (and indeed it's still the default if
  221. you start up in safe mode), so it's still a resolution we care
  222. about.
  223. Accordingly, the PuTTY configuration box, and the PuTTYgen control
  224. window, are deliberately kept just small enough to fit comfortably
  225. on a 640\u00D7{x}480 display. If you're adding controls to either of
  226. these boxes and you find yourself wanting to increase the size of
  227. the whole box, \e{don't}. Split it into more panels instead.
  228. \H{udp-makefiles-auto} Automatically generated \cw{Makefile}s
  229. PuTTY is intended to compile on multiple platforms, and with
  230. multiple compilers. It would be horrifying to try to maintain a
  231. single \cw{Makefile} which handled all possible situations, and just
  232. as painful to try to directly maintain a set of matching
  233. \cw{Makefile}s for each different compilation environment.
  234. Therefore, we have moved the problem up by one level. In the PuTTY
  235. source archive is a file called \c{Recipe}, which lists which source
  236. files combine to produce which binaries; and there is also a script
  237. called \cw{mkfiles.pl}, which reads \c{Recipe} and writes out the
  238. real \cw{Makefile}s. (The script also reads all the source files and
  239. analyses their dependencies on header files, so we get an extra
  240. benefit from doing it this way, which is that we can supply correct
  241. dependency information even in environments where it's difficult to
  242. set up an automated \c{make depend} phase.)
  243. You should \e{never} edit any of the PuTTY \cw{Makefile}s directly.
  244. They are not stored in our source repository at all. They are
  245. automatically generated by \cw{mkfiles.pl} from the file \c{Recipe}.
  246. If you need to add a new object file to a particular binary, the
  247. right thing to do is to edit \c{Recipe} and re-run \cw{mkfiles.pl}.
  248. This will cause the new object file to be added in every tool that
  249. requires it, on every platform where it matters, in every
  250. \cw{Makefile} to which it is relevant, \e{and} to get all the
  251. dependency data right.
  252. If you send us a patch that modifies one of the \cw{Makefile}s, you
  253. just waste our time, because we will have to convert it into a
  254. change to \c{Recipe}. If you send us a patch that modifies \e{all}
  255. of the \cw{Makefile}s, you will have wasted a lot of \e{your} time
  256. as well!
  257. (There is a comment at the top of every \cw{Makefile} in the PuTTY
  258. source archive saying this, but many people don't seem to read it,
  259. so it's worth repeating here.)
  260. \H{udp-ssh-coroutines} Coroutines in \cw{ssh.c}
  261. Large parts of the code in \cw{ssh.c} are structured using a set of
  262. macros that implement (something close to) Donald Knuth's
  263. \q{coroutines} concept in C.
  264. Essentially, the purpose of these macros are to arrange that a
  265. function can call \cw{crReturn()} to return to its caller, and the
  266. next time it is called control will resume from just after that
  267. \cw{crReturn} statement.
  268. This means that any local (automatic) variables declared in such a
  269. function will be corrupted every time you call \cw{crReturn}. If you
  270. need a variable to persist for longer than that, you \e{must} make
  271. it a field in one of the persistent state structures: either the
  272. local state structures \c{s} or \c{st} in each function, or the
  273. backend-wide structure \c{ssh}.
  274. See
  275. \W{http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}\c{http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}
  276. for a more in-depth discussion of what these macros are for and how
  277. they work.
  278. \H{udp-compile-once} Single compilation of each source file
  279. The PuTTY build system for any given platform works on the following
  280. very simple model:
  281. \b Each source file is compiled precisely once, to produce a single
  282. object file.
  283. \b Each binary is created by linking together some combination of
  284. those object files.
  285. Therefore, if you need to introduce functionality to a particular
  286. module which is only available in some of the tool binaries (for
  287. example, a cryptographic proxy authentication mechanism which needs
  288. to be left out of PuTTYtel to maintain its usability in
  289. crypto-hostile jurisdictions), the \e{wrong} way to do it is by
  290. adding \cw{#ifdef}s in (say) \cw{proxy.c}. This would require
  291. separate compilation of \cw{proxy.c} for PuTTY and PuTTYtel, which
  292. means that the entire \cw{Makefile}-generation architecture (see
  293. \k{udp-makefiles-auto}) would have to be significantly redesigned.
  294. Unless you are prepared to do that redesign yourself, \e{and}
  295. guarantee that it will still port to any future platforms we might
  296. decide to run on, you should not attempt this!
  297. The \e{right} way to introduce a feature like this is to put the new
  298. code in a separate source file, and (if necessary) introduce a
  299. second new source file defining the same set of functions, but
  300. defining them as stubs which don't provide the feature. Then the
  301. module whose behaviour needs to vary (\cw{proxy.c} in this example)
  302. can call the functions defined in these two modules, and it will
  303. either provide the new feature or not provide it according to which
  304. of your new modules it is linked with.
  305. Of course, object files are never shared \e{between} platforms; so
  306. it is allowable to use \cw{#ifdef} to select between platforms. This
  307. happens in \cw{puttyps.h} (choosing which of the platform-specific
  308. include files to use), and also in \cw{misc.c} (the Windows-specific
  309. \q{Minefield} memory diagnostic system). It should be used
  310. sparingly, though, if at all.
  311. \H{udp-perfection} Do as we say, not as we do
  312. The current PuTTY code probably does not conform strictly to \e{all}
  313. of the principles listed above. There may be the occasional
  314. SSH-specific piece of code in what should be a backend-independent
  315. module, or the occasional dependence on a non-standard X library
  316. function under Unix.
  317. This should not be taken as a licence to go ahead and violate the
  318. rules. Where we violate them ourselves, we're not happy about it,
  319. and we would welcome patches that fix any existing problems. Please
  320. try to help us make our code better, not worse!