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