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