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