mmlib/mmat: replace some variables by literal constants
[mmondor.git] / mmsoftware / mmlib / mmserver2.3
1 .\" $Id: mmserver2.3,v 1.18 2007/12/05 23:47:56 mmondor Exp $
2 .\"
3 .\" Copyright (C) 2004, Matthew Mondor
4 .\" All rights reserved.
5 .\"
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
8 .\" are met:
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\"    notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\"    notice, this list of conditions and the following disclaimer in the
13 .\"    documentation and/or other materials provided with the distribution.
14 .\" 3. All advertising materials mentioning features or use of this software
15 .\"    must display the following acknowledgement:
16 .\"      This product includes software developed by Matthew Mondor.
17 .\" 4. The name of Matthew Mondor may not be used to endorse or promote
18 .\"    products derived from this software without specific prior written
19 .\"    permission.
20 .\" 5. Redistribution of source code may not be released under the terms of
21 .\"    any GNU Public License derivate.
22 .\"
23 .\" THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
24 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 .\" IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 .\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 .\"
34 .Dd March 21, 2004
35 .Dt MMSERVER2 3
36 .Os mmsoftware
37 .Sh NAME
38 .Nm mmserver2
39 .Nd Library implementing the basis for internet protocol servers
40 .Sh SYNOPSIS
41 .Fd #include <sys/types.h>
42 .Fd #include <mmtypes.h>
43 .Fd #include <mmserver2.h>
44 .Ft void
45 .Fn server_init "void"
46 .Ft void *
47 .Fn server_shmem_malloc "size_t size"
48 .Ft int
49 .Fn server_rwlocks_init "const char *path" "int num" "const char *user" \
50 "const char *group" "mode_t mode" 
51 .Ft int
52 .Fn server_rwlock_ctl "int id" "int op"
53 .Ft int
54 .Fn server_socket_bind "struct server_socket_config *config"
55 .Ft int
56 .Fn server_start "struct server_config *config"
57 .Ft int
58 .Fn server_exit "void"
59 .Ft int
60 .Fn server_recycle "bool interrupt"
61 .Ft void
62 .Fn server_close "void"
63 .Ft unsigned int
64 .Fn server_alarm "unsigned int seconds"
65 .Ft int
66 .Fn server_execve "const char *path" "char *const argv[]" "char *const envp[]"
67 .Ft const char *
68 .Fn SERVER_REASON_STRING "int reason"
69 .Ft socklen_t
70 .Fn SERVER_SOCKADDR_SOCKLEN "struct server_sockaddr *addr"
71 .Ft int *
72 .Fn SERVER_SOCKADDR_PORT "struct server_sockaddr *addr"
73 .Ft sa_family_t *
74 .Fn SERVER_SOCKADDR_FAMILY "struct server_sockaddr *addr"
75 .Ft void *
76 .Fn SERVER_SOCKADDR_ADDRESS "struct server_sockaddr *addr"
77 .Ft struct sockaddr *
78 .Fn SERVER_SOCKADDR "struct server_sockaddr *addr"
79 .Sh DESCRIPTION
80 The
81 .Nm
82 library greatly simplifies the task of writing internet protocol server daemons
83 which can optionally support both IPv4 and IPv6 TCP and UDP, as well as
84 AF_LOCAL SOCK_STREAM and SOCK_DGRAM sockets. The system internally manages a
85 pool of children processes which it uses to dispatch client requests to. This
86 pool will grow and shrink as needed to efficiently serve a high number of high
87 frequency client requests. This prevents the need from using
88 .Xr fork 2
89 to dispatch every request or to have to start a thread using
90 .Xr pthread_create 3
91 for each of them. Every process in the pool has the ability to
92 .Xr recvfrom 2
93 or
94 .Xr accept 2
95 itself, so that filedescriptor passing over AF_LOCAL sockets is unnecessary
96 to dispatch requests to children processes. A lock is used to properly
97 distribute the incomming requests among all children processes evenly,
98 although this optional feature can be disabled on systems which have no
99 problems with multiple processes and concurrent usage of
100 .Xr accept 2
101 or
102 .Xr recvfrom 2
103 and where distribution of incomming requests is adequate among them.
104 A bottleneck can then be avoided.
105 .Pp
106 The system provides alot of per-socket configuration options for a high
107 flexibility. It also internally comports an address to hostname resolution
108 cache for efficiency which is automatically used whenever resolving is
109 enabled for wanted sockets. Some care also was taken so that processes may
110 concurrently call
111 .Xr getnameinfo 3
112 at the same time, preventing hostname resolution from being a bottleneck.
113 Because a process is considered to be in busy state when this happens,
114 other processes will be launched as necessary to cope with the concurrency.
115 The reason for calling this library
116 .Nm
117 is that the author already had implemented
118 .Xr mmserver 3
119 which used GNU
120 .Xr Pth
121 threads and was used to write
122 .Xr mmftpd 8
123 and
124 .Xr mmmail 8 .
125 This early implementation only supported AF_INET family with SOCK_STREAM type,
126 and required a new thread to be launched to serve every new connection.
127 .Pp
128 We also provide means to execute application-specific function hooks at
129 multiple points such as when launching or killing a children process in
130 the pool, at the occurance of particular signals, etc. Also provided is
131 a system for easy inter-process synchronization which can be used to
132 access either shared memory or shared resources, with a minimal amount of
133 code lines.
134 .Pp
135 Support is also provided for AF_LOCAL/AF_UNIX SOCK_DGRAM and SOCK_STREAM
136 sockets. It is allowed for the same application to have multiple sockets
137 of multiple types, of multiple address families.
138 .Pp
139 This library is particularly made for BSD systems (the author mostly
140 runs NetBSD) but should work on Linux without modifications (which implements
141 alot of BSD APIs including 4.2BSD sockets API, 4.2BSD
142 .Xr flock 2
143 and 4.4BSD
144 .Xr mmap 2
145 with MAP_ANON). It may also well work on a number of different Unix variants
146 but the author did not specifically try.
147 .Pp
148 An effort was made to make this library as efficient as possible while still
149 providing both a clean API and address-based limits functionality. To achieve
150 this, memory pools of fixed sized objects are used for various objects which
151 need to be allocated and freed in critical sections. The hash table lookups
152 number of buckets is also set high enough as to cause the less nodes to be
153 shared on a bucket, for faster lookups.
154 .Xr mmpool 3
155 and
156 .Xr mmhash 3
157 are used for this.
158 Moreover, cache lookup and update operations are avoided for sockets which
159 do not need per-address limits nor hostname resolution, for maximum
160 performance.
161 .Pp
162 Support is also provided for applications which need to execute the
163 .Xr execve 2
164 system call, causing the process which serves the client to
165 .Xr exit 3
166 or
167 .Xr _exit 2 .
168 Of course, the performance of such an application cannot reach that of one
169 which can serve multiple requests per children process of the pool, since
170 exiting after serving a single connection, the process must be restarted.
171 However, the advantage of a pool of processes still allows such applications
172 to benefit from a higher performance than simply using
173 .Xr fork 2
174 linearily per new client connection. The performance gains will be observed
175 when sudden bursts of client requests occur frequently, and of course by the
176 fact that not all clients requests may cause execution of another program
177 to override the process, for instance clients which fail authentication or
178 exceed limits can cause the process to serve multiple connections without
179 restarting.
180 .Pp
181 Reasons which were taken into consideration when deciding to use
182 processes instead of threads for this second implementation were the following:
183 .Bl -enum -offset left
184 .It
185 Although POSIX defined a definite API for threads (pthreads), the author's
186 experience using them on a variety of Unix-like systems proven that there were
187 significant implementation-specific issues which often had to be dealt with
188 depending on the system. Some systems even use non-preemptive implementations.
189 .It
190 There is a rather large number of non-reentrant (thread unfriendly) functions
191 in most C libraries. In fact, several POSIX standard functions are not thread
192 safe.
193 .It
194 The security model of process-based systems is generally higher than that of
195 thread-based ones. Because threads inherently share memory within the whole
196 process, it is generally very easy to render a minor discovered vulnerability
197 of the system into a much more destructive exploit. Moreover, the process
198 based model allows application authors to implement fancy tricks as privilege
199 separation, still avoiding most of the application from running as the
200 superuser even if part of it needs to. A thread model does not permit such
201 flexibility (of course, we cannot assume to run on an implementation internally
202 using processes corresponding to each thread as in the 1:1 models when
203 programming applications using POSIX threads).
204 .It
205 The cost of using
206 .Xr fork 2
207 has greatly decreased in modern operating systems, using COW (Copy On Write)
208 pages implementations. And because we are managing a pool of processes,
209 this problem is solved.
210 .It
211 The popular
212 .Xr OpenSSL 3
213 library distributed with BSD systems, and available as a package on most other
214 systems, generally performs much better when using a process per client. This
215 library is especially useful in the implementation of HTTPS servers for
216 instance, but also useful for many other network protocols.
217 .It
218 Systems on which the C library is bogus and comports memory leaks can benefit
219 from a system which causes client serving processes to recycle themselves after
220 a set number of client requests have been served.
221 .It
222 The popular free
223 .Xr MySQL 8
224 database server also has issues when some of it's features are used on
225 thread-based servers, such as table locking. Having one persistent connection
226 to the MySQL server per process in the pool resolves any such problems easily.
227 A client being blocked in a
228 .Xr libmysqlclient 3
229 function call will only affect it's own process without interefering with other
230 clients. This is only one of many examples when working with popular third
231 party applications and libraries.
232 .It
233 A thread cannot reliably use
234 .Xr fork 2 ,
235 .Xr flock 2 ,
236 .Xr system 3 ,
237 .Xr popen 3
238 or
239 .Xr execve 2 .
240 A process has no problem if the need to use such functions arise.
241 .It
242 Even the standard stdio library cannot be used properly within a thread without
243 worrying about thread concurrency issues. They were made with the assumption
244 of a nonthreaded process in mind. This is also true of most I/O related
245 unix functions. Weither a particular system causes a thread-safe version
246 of these functions to be linked in with the application which uses threads
247 or not is an assumption one cannot make reliably. With
248 .Xr mmserver 3 ,
249 .Xr mmftpd 8
250 and
251 .Xr mmmail 8
252 needed to use the
253 .Xr mmfd 3
254 library for buffered streams (which also provides bandwidth shaping).
255 .It
256 Finally, a system using multiple processes is always able to take advantage of
257 the Operating System and hardware Symetric Multi Processor features where
258 available. This is not always the case with threads, as it greatly depends on
259 the implementation internals.
260 .El
261 .Pp
262 .Ss STRUCTURES
263 These structures are defined in
264 .Aq Pa mmserver2.h
265 and are part of the API. The internal functions used by the library code
266 are not included and hidden for convenience
267 (no user serviceable parts inside :)
268 We here describe the structures
269 along with each of their fields definitions:
270 .Bl -tag -width indent -offset left
271 .It Nm struct server_socket_config
272 It is recommended to use
273 .Xr memset 3
274 to first zero this structure before setting it's parameters. It is then passed
275 to the
276 .Fn server_socket_bind
277 function, which internally makes it's own copy so that it does not matter if
278 it resides on the stack. It is best to set all of the fields to valid values,
279 explicitely.
280 .Bl -tag -width indent -offset left
281 .It int family;
282 The address family type of this socket, AF_INET, AF_INET6 or AF_LOCAL,
283 respectively.
284 .It int type;
285 The socket type, SOCK_STREAM or SOCK_DGRAM, respectively. For AF_INET and
286 AF_INET6 family sockets, SOCK_STREAM corresponds to TCP and SOCK_DGRAM to UDP.
287 .It int port;
288 The port number this socket should listen on, in host byte order. Should be
289 0 for AF_LOCAL sockets.
290 .It int backlog;
291 For SOCK_STREAM sockets only, this specifies the backlog parameters passed
292 to the
293 .Xr listen 2
294 syscall. This is closely related to the
295 .Nm children_maximum
296 field of the
297 .Nm struct server_config ,
298 as the connections which cannot immediately be dispatched to
299 processes will be queued by the backlog. Should be 0 for SOCK_DGRAM sockets.
300 .It bool create_stream;
301 For SOCK_STREAM sockets only, tells the system that a stdio FILE * stream
302 should be provided to the client request handler function, for convenience.
303 An advantage of this is that buffering can easily be used without additionnal
304 functions, but a known disadvantage is that stdio does not handle input
305 timeouts. Although SIGPIPE will internally be handled by the system, it
306 is advised to specify a SIGALRM handler in
307 .Nm struct server_config
308 and to use
309 .Fn server_alarm
310 to implement input timeout functionality.
311 .It bool address_resolve;
312 This should be FALSE for AF_LOCAL sockets. If TRUE, specifies that the system
313 should attempt to resolve client addresses to hostnames. This hostname will
314 be passed along to the handler functions. Note that for efficiency, an
315 internal cache is used to resolve hostnames which recently have been resolved
316 using the DNS system. This means that this functionality can even be used with
317 SOCK_DGRAM UDP sockets without too much slow down. Of course, it is always
318 more efficient to not resolve addresses, but it can be necessary for some
319 applications like for SMTP mail servers.
320 .It bool address_rate_limits;
321 Specifies if client IP address based request rate limits should be
322 enabled for this server socket (TRUE or FALSE). Should always be FALSE for
323 AF_LOCAL sockets.
324 .Nm address_cache_rate_limit
325 should be 0 if FALSE is specified. However,
326 .Nm address_cache_rate_period
327 will still be used for hostname cacheing.
328 .It bool address_concurrency_limits;
329 If client IP address based concurrency limits should be enabled for
330 this server socket (TRUE or FALSE). Should always be FALSE for AF_LOCAL
331 sockets.
332 .Nm address_cache_concurrency_limit
333 should be 0 if FALSE is specified.
334 .It uint32_t address_cache_size;
335 Specifies the maximum number of unique addresses which can be stored into
336 the rate limit sanity checking cache. This means that this socket can serve
337 at most this number of concurrently different addresses at once. It therefore
338 should generally be high enough. Should be 0 if
339 .Nm address_resolve ,
340 .Nm address_rate_limits
341 and
342 .Nm address_concurrency_limits
343 are all FALSE. Will be used otherwise.
344 .It uint32_t address_cache_rate_limit;
345 The maximum number of requests which each IP address can perform within
346 .Nm address_cache_rate_period
347 seconds. Exceeding requests are delegated to the reject handler (if any)
348 rather than to the request handler. Should be 0 if
349 .Nm address_rate_limits
350 is FALSE.
351 .It uint32_t address_cache_rate_period;
352 The number of seconds in which a maximum of
353 .Nm address_cache_rate_limit
354 requests are allowed from each IP address. Setting a low value here will
355 be less efficient but will also permit the address cache size to be smaller.
356 These values should be chosen with care depending on the particular
357 application. Note that even if rate limits are disabled specifying FALSE to
358 .Nm address_cache_rate_limit ,
359 this period is used to control the automatic expiration of hostname cache
360 entries, if resolving is enabled. What happens is that the system makes sure
361 that no more current requests being served exist for an address when this
362 number of seconds elapses. If there are, the system again waits this number
363 of seconds and so on. If there are no requests this address cache node can
364 be freed, and the reference counter of the corresponding hostname cache node
365 decreased. If the reference count becomes zero for the hostname node, it
366 can be freed. This value should be 0 if
367 .Nm address_cache_size
368 is 0.
369 .It uint32_t address_cache_concurrency_limit;
370 The maximum number of concurrent requests which each IP address is allowed
371 to perform at once. Exceeding requests are sent to the reject handler rather
372 than to the request handler. Should be 0 if
373 .Nm address_cache_concurrency_limits
374 is FALSE.
375 .It size_t packet_size;
376 For SOCK_DGRAM sokets only, specifies the maximum expected size of the
377 intitial client request packet. When the client request is received
378 this first packet is buffered and passed to the request handler function.
379 Although it would have been possible to internally use the MSG_PEEK flag
380 to
381 .Xr recvfrom 2
382 and let the request handlers unqueue the first packet themselves from the
383 socket, this would have resulted in concurrency issues among the multiple
384 processes of the pool.
385 .It char bind_address[100];
386 The address to
387 .Xr bind 2
388 this listening socket to.
389 This can be "0.0.0.0" in the case of AF_INET to allow requests on all
390 interfaces from all IP addresses, "::" for AF_INET6 to also allow requests
391 on all interfaces from all IPv6 addresses. For AF_LOCAL, this should be a
392 fullpath to a file socket. Of course, the format of this address
393 should correspond to the chosen
394 .Nm family
395 field.
396 .It char socket_user[32];
397 For AF_LOCAL family sockets only, if non-empty, this defines the unix user
398 which should be set as the AF_LOCAL socket file owner using
399 .Xr lchown 2 .
400 Has to be empty for other socket families.
401 .It char socket_group[32];
402 For AF_LOCAL family sockets only, if non-empty, this defines the unix group
403 which should be set as the AF_LOCAL socket file group using
404 .Xr lchown 2 .
405 Has to be empty for other socket families.
406 .It mode_t socket_mode;
407 For AF_LOCAL family sockets only, specifies the mode of the file to be set
408 using
409 .Xr lchmod 2
410 on the AF_LOCAL socket file. Note that any executable or suid/sgid bits will
411 automatically be stripped from this mask if present. Is ignored for other
412 socket families.
413 .It int (*setsockopts)(int);
414 After creating this socket using
415 .Xr socket 2 ,
416 but before calling
417 .Xr bind 2 ,
418 this optional function, if not NULL, is allowed to be called to set wanted
419 application-specific socket options, for instance using
420 .Xr setsockopt 2 .
421 This function should return 0 on success, or -1 on failure. The
422 .Fa int
423 parameter passed to it consists of the filedescriptor of the socket to affect.
424 .It void (*request_handler)(struct server_request *);
425 This function pointer is required and tells which application-specific function
426 to call to serve an incomming client request on this socket. A pointer
427 to a
428 .Nm struct server_request
429 is provided which allows the handler function to obtain needed information
430 about the client as well as application-specific user data associated with
431 this socket. Because SOCK_DGRAM sockets are by definition connectionless,
432 note that the initial request packet is then buffered and stored for the
433 request and reject handlers, as well as the original server socket. It
434 becomes the responsibility of the application to use
435 .Xr bind 2
436 and/or
437 .Xr connect 2
438 if it needs to use
439 .Xr recv 2 ,
440 .Xr send 2 ,
441 .Xr read 2
442 and
443 .Xr write 2
444 for communication with the client rather than
445 .Xr recvfrom 2
446 and
447 .Xr sendto 2 .
448 The initial request packet which is buffered for the handler should first
449 be processed before attempting to receive again. Although it would have
450 been possible for the underlaying system to use the MSG_PEEK flag
451 to
452 .Xr recvfrom 2 ,
453 if the request handler would not have unqueued the packet fast enough
454 there could be concurrency issues where other processes would also be
455 dispatched the same request. This is avoided by simply unqueing the request
456 packet and providing it to the request handlers. Be sure to read in detail
457 the informations provided on the
458 .Nm struct server_request
459 structure later on.
460 .It void (*reject_handler)(struct server_request *, int);
461 Called instead of the request handler function when the client address exceeds
462 it's request limits. Apart from the usual structure passed to this function,
463 the
464 .Fa int
465 parameter will represent the rejection reason:
466 .Bl -tag -width indent -offset left
467 .It REASON_CACHE_SIZE
468 The address cache size for this socket was exceeded; This address will be
469 allowed to perform requests whenever room exists to do it.
470 .It REASON_CONCURRENCY
471 The address exceeded the concurrent allowed number of simultaneous requests
472 it can perform. It currently has other existing requests which are ongoing
473 fine.
474 .It REASON_RATE
475 The address exceeded the allowed rate at which it can perform independent
476 requests. It will be allowed again whenever the limit counter expires for
477 a new period.
478 .El
479 .Pp
480 Because AF_LOCAL sockets have no address-based limits, this function will
481 never be called for them, and therefore should be NULL.
482 .It void (*request_interrupt_hook)(struct server_request *);
483 Called whenever a currently being served request is interrupted via a call
484 to
485 .Fn server_recycle
486 with the
487 .Fa interrupt
488 flag turned on, causing current requests to be interrupted. This handler
489 should perform any wanted application or protocol-specific task like sending
490 a protocol-friendly close message. The normal client closing procedure will
491 then be performed. Note that this also will be called if set, in the case where
492 .Nm exit_interrupt_requests
493 of
494 .Nm struct server_config
495 is TRUE when SIGTERM is received, causing the process to exit.
496 .It void (*request_close_hook)(struct server_request *);
497 Allows the application to set a custom function to be called whenever the
498 server disconnects a client (or terminates serving one). Because it is
499 possible for this event to happen as the result of an internal SIGPIPE
500 signal resulting from a client disconnection or socket error, it may be
501 important to release some resources which have been allocated by the
502 request handler function and must not remain dangling.
503 .It void *user_data;
504 Optional user data, that is, application-specific data associated with this
505 particular socket which is to be passed to the request handlers. This can
506 be useful for instance for an HTTP server to distinguish HTTP sockets from
507 HTTPS ones, or any other wanted functionality. Set to NULL if no such data
508 is wanted.
509 .El
510 .It Nm struct server_config
511 It is recommended to use
512 .Xr memset 3
513 to zero out this structure before filling it with the wanted parameters.
514 This structure can then be passed to the
515 .Fn server_start
516 function. An internal copy of it will be made so that it does not matter
517 if the supplied structure resides on the stack. It is best to set all of the
518 fields to valid values, explicitely.
519 .Bl -tag -width indent -offset left
520 .It char proc_title[32];
521 Especially useful with BSD systems
522 .Xr setproctitle 3
523 fonctionality. This allows to append a custom prefix to the titles set for
524 the processes. This is useful if for instance multiple configurations exist
525 for a single program and thus several copies are running and should easily
526 be distinguished. The
527 .Xr mmspawnd 8
528 program uses this feature. Can be set to an empty string if no prefix is
529 needed.
530 .It char locks_path[256];
531 Should be set to the full path, including a filename, which will be used
532 to create all internal lock files to be used internally for shared resources
533 synchronization. The lock files will be created with this name plus a unique
534 suffix.
535 .It char locks_user[32];
536 Specifies the user which should be set as the owner of the created lock
537 files, or an empty string to leave the default owner (usually the current user
538 ID of the process).
539 .It char locks_group[32];
540 Specifies the group to be set as the group of the created lock files, or
541 an empty string to leave the default creation group.
542 .It mode_t locks_mode;
543 The file creation mode to be applied to the newly created lock files.
544 These permissions should be set with care so that the files generally cannot
545 be accessed by other applications or users, but that they be accessed at
546 least for read access by children processes of the application, so that
547 the lock files may be reopened by each process (a requirement for
548 .Xr flock 2 ) .
549 A popular value for this is 0600.
550 .It char null_path[256];
551 Specifies the full path to the
552 .Xr null 4
553 device, to redirect stdin, stdout and stderr at initialization when detaching
554 from the tty.
555 .It char pid_path[256];
556 The full path to the filename used to store the process ID (pid_t) of the
557 parent process. This will be used by other software to know which pid to
558 signal using SIGTERM or SIGHUP afterwards.
559 .It uint32_t children_initial;
560 The number of children processes to initially startup at application launch.
561 This number will usually consist of
562 .Nm children_minspare
563 but it can be set higher if it is known that high load is immediately expected.
564 .It uint32_t children_minspare;
565 Specifies the minimum number of spare processes (ready, unclobbered processes)
566 which should be available to answer extraneous imminent client requests.
567 Every second, the system verifies if this number is met and if not, new
568 children processes are started in the pool to meet the requirement.
569 In the case of an HTTP server, this for instance allows to make sure that
570 there be enough processes to answer requests from browsers which perform
571 multiple simultaneous requests to load images of a page (like Netscape).
572 .It uint32_t children_maxspare;
573 The maximum unused children processes in the pool that may exist. This permits
574 to shrink the pool of processes when it is known that we are wasting resources
575 with too many of them. The system maintains an average of unused processes
576 number so that it may only shrink the pool when it establishes that the current
577 load allows it. It would be unefficient to shrink this pool too fast in the
578 case of bursts of many client requests followed by short moments of inactivity
579 when other bursts are known to occur soon. The system avoids this.
580 .It uint32_t children_maximum;
581 The maximum number of total processes (busy or not) in the pool. Note that
582 this should be high enough to handle the maximum expected loads. Because
583 each process can only handle one particular request at a time, this represents
584 the total maximum request concurrency. Although this does not mean that clients
585 are inherently blocked out if this number is reached and all the processes
586 are busy (it also depends on the backlog set for each listening socket), it
587 is a possible event. In the case of AF_INET or AF_INET6 SOCK_DGRAM sockets,
588 because of the unreliable nature of UDP, packets may be lost if this value is
589 too low (I.E. there are many more clients than number of processes).
590 .It uint32_t children_average_seconds;
591 We previously described the way in which we shrink the size of the pool as
592 needed maintaining an average count of ready processes in
593 .Nm children_maxspare .
594 This value specifies the number of seconds over which this average is
595 calculated before deciding to shrink the pool. A number of 300 seconds
596 will cause the pool to only be shrinked if it is known that too many processes
597 were ideling for nothing during 5 minutes.
598 .It uint32_t children_maxrequests;
599 Specifies the maximum number of consecutive client requests which each children
600 process may serve before recycling. Recycling causes the process to exit and
601 to be immediately replaced by another new process. This can be especially
602 useful in the cases where memory leaks are observed into the system libraries
603 and the processes tend to grow overtime. This limit should be rather high
604 for performance considerations. 1000 or more is generally a good value.
605 Although this feature cannot be disabled, it is allowed to set a very high
606 value (uint32_t)-1 if wanted.
607 .It bool serialization_lock;
608 If TRUE, a synchronization lock will be used to more evenly distribute requests
609 among the chilren processes in the pool. This also may be required on some
610 systems for proper function. If FALSE, a bottleneck can be avoided, allowing
611 requests to simultaneously be dispatched among all processes of the pool, which
612 will be sleeping in
613 .Xr poll 2
614 rather than
615 .Xr flock 2
616 or
617 .Xr poll 2 .
618 At least on NetBSD, disabling the lock does not seem to generally cause
619 problems, but it does in the case where the processes are swapped out. It then
620 seems that some processes will wait on the "netconn" channel (in
621 .Xr accept 2 )
622 rather than at
623 .Xr poll 2
624 on the "select" channel. Using a serialization lock fixes this issue.
625 .It bool exit_interrupt_requests;
626 Tells weither or not requests currently being processed should be interrupted
627 whenever the parent process is to exit (generally as the result of reception
628 of SIGTERM signal). Note that the request interrupt handler hook (
629 .Nm request_interrupt_hook
630 of
631 .Nm struct server_socket_config )
632 will be called if set whenever an active request is to be cancelled before
633 the process exits. This usually can be set to TRUE in most circumstances.
634 However, some services may require this to be FALSE (I.E. a remote
635 administration service where the link must remain up even when ordering a
636 full server restart, where SIGHUP is not enough). If FALSE, the children
637 processes will die whenever they finish serving the current request, if any.
638 .It bool children_setsid;
639 If TRUE, specifies that each children process in the pool should have their own
640 process group ID using
641 .Xr setsid 2 ,
642 instead of sharing the master parent's process group. This is generally set to
643 FALSE for most setups.
644 .It bool using_execve;
645 If the application needs to use the
646 .Xr execve 2
647 system call to serve a client, this should be set to TRUE. This enables a
648 special hash table to map children process IDs with their status structure
649 in shared memory, so that when the client serving process exits the parent
650 be notified that it may be recycled immediately. Note that such an application
651 must always call
652 .Xr _exit 2
653 if
654 .Xr execve 2
655 ever returns (it normally will not return, however). For other applications,
656 should be set to FALSE to avoid the need to maintain such a lookup table for
657 better efficiency. The
658 .Fn server_execve
659 function should be used instead of
660 .Xr execve 2 ,
661 which will internally
662 .Xr _exit 2
663 if necessary. Note that enabling this option also causes the close-on-exec flag
664 to be applied to the filedescriptors which should not be available during the
665 execution of the program used to serve the client, using
666 .Xr fcntl 2 .
667 .It int (*parent_init_hook)(void);
668 Optional application-specific function to be called at parent master process
669 initialization after it detaches from the tty and becomes a daemon, before
670 launching any children processes. Can be NULL if no such function is wanted.
671 Such a function may alter privileges of the process or perform other wanted
672 initialization. The function should return 0 on sucess or -1 on error,
673 optionally setting errno. If this function fails when the parent process calls
674 it, the server will exit after logging the error via
675 .Xr syslog 3 .
676 This function is called after binding all listening sockets.
677 .It void (*parent_exit_hook)(void);
678 Optional application-specific function to be called before the parent master
679 process exits, or NULL. This may be useful to clean up resources allocated
680 by the
681 .Nm parent_init_hook
682 custom function.
683 .It void (*parent_sighup_hook)(void);
684 Can be NULL if no such function is wanted. Optional application-specific
685 function to be called in the parent process context upon reception of the
686 SIGHUP signal. This function can potentially perform some configuration files
687 reload and such. It is also responsible for calling the
688 .Fn server_recycle
689 function as needed.
690 .It void (*parent_timer_hook)(void);
691 If not NULL, specifies a function which is to be called every
692 .Nm parent_timer_seconds
693 number of seconds. This function should return rather fast. This may be useful
694 when another process than the children ones need to perform some work at
695 regular intervals. A timer of at least 1 seconds must be used if a pointer is
696 set here. If the application requires more fancy things, and cannot be
697 satisfied by such a function hook which needs to return quite fast, it is
698 recommended to launch an application-specific process which can serve better
699 the tasks at hand. This can be done through
700 .Nm parent_init_hook .
701 .It uint32_t parent_timer_seconds;
702 If
703 .Nm parent_timer_hook
704 is set a pointer, this must hold a value larger than 0, specifying the interval
705 timer in seconds for the hook function to be called.
706 .It int (*child_init_hook)(void);
707 Optional application-specific function to be called by each new child process
708 started in the pool, or NULL. This function can perfom tasks such as alter
709 the privileges of the process, attaching to any process-specific persistent
710 devices, pre-creation of process-specific client sockets, etc. Note that in the
711 case of an application using
712 .Nm using_execve
713 support and setting up persistent sockets it may be wanted to also use
714 .Xr fcntl 2
715 on the filedescriptors to set the close-on-exec flag.
716 .It void (*child_exit_hook)(void);
717 Optional application-specific function to be called by each child process
718 before they exit, or NULL. Can be used to detach from process-specific
719 persistent devices for instance.
720 .It void (*child_sigalrm_hook)(void);
721 Optional application-specific function to be called upon reception of the
722 SIGALRM signal by the child processes. This is mostly useful to use in
723 conjunction with the
724 .Fn server_alarm
725 function while serving a client request in the handler function. This system
726 can also be used with
727 .Xr mmalarm 3
728 if needed. A system using the FILE * stdio stream to serve a SOCK_STREAM client
729 connection will generally at least need to use this system to observe
730 input timeouts.
731 .El
732 .It Nm struct server_request
733 A pointer to such a structure is passed to client request handler functions.
734 Be sure to read the details of each field, as well as the corresponding
735 address manipulation macros described later on, plus the documentation of
736 the handler functions.
737 .Bl -tag -width indent -offset left
738 .It int client_socket;
739 For SOCK_STREAM sockets, the socket of the connected client. For
740 SOCK_DGRAM sockets, will be set to the same descriptor as for the
741 .Nm server_socket
742 field.
743 Do not close this filedescriptor yourself, the library always takes care of it.
744 .It int server_socket;
745 The filedescriptor of the listening server.
746 Note that this filedescriptor should not be modified (I.E.) do never use
747 .Xr close 2 ,
748 .Xr connect 2
749 or
750 .Xr bind 2
751 on this filedescriptor. It is however possible to use
752 .Xr dup 2 .
753 This is provided because for some SOCK_DGRAM applications it is convenient.
754 Use this descriptor with care, as it is possible to mess up the server if it
755 is modified.
756 .It int server_socket_type;
757 SOCK_STREAM or SOCK_DGRAM, respectively.
758 .It int server_socket_family;
759 AF_INET, AF_INET6 or AF_LOCAL, respectively.
760 .It int client_port;
761 In the case of AF_LOCAL sockets, will always be 0. Otherwise, will be set to
762 the originator client request port, in host byte order.
763 .It int server_socket_port;
764 For AF_LOCAL sockets, always 0. Otherwise, the port number corresponding to
765 the socket on which this request was received, in host byte order.
766 .It FILE *client_stream;
767 In the case of SOCK_STREAM sockets with the
768 .Nm create_stream
769 parameter set to TRUE, this consists of the stdio line-buffered FILE stream
770 which can be used to communicate with the connected client, taking some care
771 about input timeouts.
772 .It const struct server_sockaddr *server_socket_address;
773 The address on which this server socket was bound to. See the macros provided
774 to work with this address later on.
775 .It const struct server_sockaddr *client_address;
776 The address of the client issueing the request. See the macros provided
777 to work with this address later on.
778 .It const char *server_socket_address_name;
779 The ASCII C string representation of the address on which this server socket
780 was bound to.
781 .It const char *client_address_name;
782 The ASCII C string representation of the address of the client isseuing the
783 request. In the case of AF_LOCAL sockets, will be NULL.
784 .It const char *client_address_hostname;
785 If address to hostname resolution was enabled for this socket, consists of the
786 ASCII hostname C string. NULL otherwise.
787 .It void *socket_user_data;
788 The pointer supplied at the
789 .Nm user_data
790 parameter for this server socket. May be used for any application-specific
791 data.
792 .It uint32_t client_address_concurrency;
793 The number of concurrent simultaneous requests from this client address.
794 Always 0 in the case of AF_LOCAL sockets or for ones which do not have any
795 address based limits enabled nor hostname resolution.
796 .It const void *packet_data;
797 For SOCK_DGRAM sockets only, a pointer to the first received packet from
798 the client. This packet should be processed by the request handler first
799 before reading other packets from the client or replying to the request.
800 .It size_t packet_size;
801 For SOCK_DGRAM sockets only, the size of the above received
802 .Nm packet_data
803 in bytes.
804 .El
805 .It Nm struct server_sockaddr
806 This structure is generally not needed by SOCK_STREAM using this library,
807 unless address specific limits and hostname resolution are disabled, in which
808 case it may be useful, the address ASCII C string not being automatically
809 supplied to the request handlers in this case. It also is useful to
810 SOCK_DGRAM sockets. It is provided as an address-family independent
811 alternative to the sockaddr structure, including the family type, and a
812 pointer to this structure is provided to the client request handler functions
813 for convenience. An application may optionally use it. See later on the
814 utility macros which are provided to manipulate this structure easily.
815 .El
816 .Ss FUNCTIONS
817 .Bl -tag -width indent -offset left
818 .It void Fn server_init "void"
819 Must be called before any other function of this library can be called.
820 Otherwise other functions will error, setting errno to EPERM.
821 .It void * Fn server_shmem_malloc "size_t size"
822 Allows the application to optionally allocate blocks of shared memory which
823 shall be available to all processes.
824 .Fa size
825 specifies the size of the block of memory to allocate.
826 Returned is the address of the new shared memory block, or NULL.
827 Can be called multiple times, but must be called before
828 .Fn server_start .
829 The application will need to ensure proper synchronization among the
830 concurrent processes itself, using
831 .Fn server_rwlock_ctl
832 as needed to access these shared resources. There are no provided functions
833 to free or resize these memory blocks until the application terminates.
834 If dynamic allocation of shared memory objects is needed, it is recommended
835 to use the
836 .Xr mmpool 3
837 library in conjunction with this function, and to ensure to create the
838 pool to not dynamically be resized, with a fixed number of maximum objects.
839 .It int Fn server_rwlocks_init "const char *path" "int num" \
840 "const char *user" "const char *group" "mode_t mode"
841 Must be called before
842 .Fn server_start .
843 Allows the application to allocate
844 .Fa num
845 number of read-write locks which may be used for synchronization of shared
846 resources among concurrent processes.
847 .Fa path
848 specifies the full path of a filename to be used to serve as a template to
849 create the internal lock files.
850 .Fa user
851 consists of the user which should be set as the lock files owner, or an empty
852 string to keep the default creation owner.
853 .Fa group
854 similarily consists of the group which should be set for the files, or an empty
855 string for the default group.
856 .Fa mode
857 specifies the permissions mode which should be set to the lock files.
858 Note that these permissions should be set properly in order for children
859 processes to be able to reopen the files in read mode (a requirement for
860 .Xr flock 2 ) .
861 Returns 0 on success or -1 on error. Can only be called once, the required
862 number of locks should be specified for the whole application.
863 .It int Fn server_rwlock_ctl "int id" "int op"
864 Can only be called after
865 .Fn server_start .
866 Allows to obtain or release an advisory lock on one of the previously
867 created locks by
868 .Fn server_rwlocks_init .
869 When in blocking mode, this function internally ensures to restart
870 upon signal events. It is possible to upgrade a shared read-access lock
871 to an exclusive write-access lock or to downgrade an exclusive lock
872 to a shared one by calling this function again with the new wanted lock
873 type. However, it is not guarenteed that another process will not be able
874 to obtain the lock in between the status change.
875 .Fa id
876 specifies the lock ID number to operate on, 0 being the first lock.
877 .Fa op
878 tells which type of operation should be performed on the lock, using
879 bitmasks which can be ORed:
880 .Bl -tag -width indent -offset left
881 .It SHL_READ
882 Obtain a shared read access lock on the object.
883 .It SHL_WRITE
884 Obtain an exclusive read-write access lock on the object.
885 .It SHL_FREE
886 Release any currently held lock by this process from the object.
887 .It SHL_TRY
888 In the case of SHL_READ or SHL_WRITE, specifies that the process should
889 not block if the lock cannot immediately be obtained, but that the function
890 should instead return -1 with errno set to EAGAIN.
891 .El
892 .Pp
893 This function returns 0 on success, or -1 on error. Unlike
894 .Xr flock 2 ,
895 will internally restart upon EINTR events when SHL_TRY is not used.
896 This means that -1 will never be returned with EINTR from this function.
897 .It int Fn server_socket_bind "struct server_socket_config *config"
898 Allows to register a server socket to listen on. Can only be called
899 before
900 .Fn server_start .
901 .Fa config
902 supplies a pointer to the socket-specific configuration. The description of
903 the parameters are described in the
904 .Nm struct server_socket_config
905 section. Note that the supplied configuration structure will be copied
906 internally such that it does not matter if it resides on the stack.
907 This functon returns -1 on error (in which case it releases any resources
908 it internally allocated meanwhile and can be called again), or 0 on success.
909 Can be called as many times as necessary to register all wanted sockets.
910 Sockets of multiple address famillies and types may be registered.
911 .It int Fn server_start "struct server_config *config"
912 Actually launches the whole system. The current process will exit if this
913 function succeeds, with the server detached from any tty and transformed into
914 a daemon. The children process pool will be created and the system becomes
915 ready to accept client requests.
916 .Fa config
917 supplies the configuration structure, which is described in
918 the
919 .Nm struct server_config
920 section.
921 Returns -1 on error, in which case an attempt is made to release the
922 internally allocated resources while not unregistering the sockets.
923 In normal operation, however, the application generally exits if this fails.
924 .It int Fn server_exit "void"
925 Can only be called after
926 .Fn server_start .
927 Allows the application to properly exit. Can be called either by the parent
928 process (via a handler or hook) or by any child process. Note that it is
929 an error for an application to use the
930 .Xr exit 3
931 or
932 .Xr _exit 2
933 function calls after
934 .Fn server_start
935 success. In case of applications using
936 .Xr execve 2 ,
937 the
938 .Fn server_execve
939 wrapper function should be used instead, which will internally
940 .Xr _exit 2
941 if necessary.
942 .It int Fn server_recycle "bool interrupt"
943 Can only be called after
944 .Fn server_start .
945 Provided so that the application can register a SIGHUP handler function
946 .Nm parent_sighup_hook
947 in
948 .Nm struct server_config
949 and then call this function whenever it finishes it's wanted tasks, such as
950 re-reading a configuration file. Because this is done into the parent process,
951 and that the new changes can only be seen by newly started children processes,
952 they must be recycled. The way in which this is done can be specified via the
953 .Fa interrupt
954 parameter. TRUE means that it should interrupt any currently being served
955 requests (which can cause the
956 .Nm request_interrupt_hook
957 function, if any, to be called to allow the application to send an
958 application-specific protocol-friendly message to the clients upon closing).
959 FALSE means that current clients should not be dropped but that each process
960 should recycle whenever it can (as soon as it finishes serving the current
961 request).
962 .It void Fn server_close "void"
963 Can only be called by the children processes after
964 .Fn server_start .
965 Although the client connection (for SOCK_STREAM sockets) is automatically
966 closed as needed when the request handler function returns, it is possible to
967 explicitely end the request calling this function. This function never
968 returns, the process immediately becomes ready to serve another request.
969 If any
970 .Nm request_close_hook
971 function was provided, it also will automatically be called, either after
972 normal request termination or forced termination triggered by this function.
973 Note that it is an error to call the
974 .Xr exit 3
975 or
976 .Xr _exit 2
977 functions after
978 .Fn server_start
979 success. In the case where an application uses
980 .Xr execve 2 ,
981 with
982 .Nm using_execve
983 set to TRUE, the
984 .Fn server_execve
985 function should be used.
986 .It unsigned int Fn server_alarm "unsigned int seconds"
987 An
988 .Xr alarm 3
989 clone which internally uses
990 .Xr setitimer 2 .
991 Can only be called after
992 .Fn server_start .
993 Utility function which can be used to implement input timeouts into
994 child processes request handlers. Can also of course be used in conjunction
995 with the
996 .Xr mmalarm 3
997 timers multiplexer if wanted. Unlike
998 .Xr alarm 3 ,
999 always returns 0.
1000 .It int Fn server_execve "const char *path" "char *const argv[]" \
1001 "char *const envp[]"
1002 consists of an
1003 .Xr execve 2
1004 replacement which application programs should call instead, in conjunction
1005 with the
1006 .Nm using_execve
1007 flag of
1008 .Nm struct server_config
1009 set to TRUE. This function can only return if
1010 .Fn server_start
1011 was not yet successfully called or if
1012 .Nm using_execve
1013 is FALSE, or if not called by a child process currently serving a SOCK_STREAM
1014 connection (-1 with EPERM). Otherwise, it will internally call
1015 .Xr _exit 2
1016 itself in case of a failure when invoking
1017 .Xr execve 2 .
1018 It however will log an error if returning from
1019 .Xr execve 2 ,
1020 since it is expected to be an application bug. See the
1021 .Xr execve 2
1022 manual page for more details about calling semantics.
1023 This function also automatically links the client socket filedescriptor
1024 to the stdin and stdout streams of the process, as well as restoring
1025 signal behavior to the default action. Moreover, shared memory will be
1026 freed before launching the program, and unwanted filedescriptors closed
1027 because of the close-on-exec flag set with
1028 .Xr fcntl 2
1029 when creating the sockets. An application using
1030 .Nm
1031 should most definitely use this function instead of
1032 .Xr execve 2 .
1033 .El
1034 .Ss MACROS
1035 .Bl -tag -width indent -offset left
1036 .It const char * Fn SERVER_REASON_STRING "int reason"
1037 Utility macro to map a rejected reason number to a printable string. Useful
1038 to use within the
1039 .Nm reject_handler
1040 function.
1041 .El
1042 .Pp
1043 The following macros are especially useful to work with the family independent
1044 .Nm struct server_sockaddr
1045 structure, for AF_INET, AF_INET6 and AF_LOCAL:
1046 .Bl -tag -width indent -offset left
1047 .It socklen_t Fn SERVER_SOCKADDR_SOCKLEN "struct server_sockaddr *addr"
1048 Useful to determine the length of the family-specific internal sockaddr_*
1049 structure for the family-independent
1050 .Nm struct server_sockaddr
1051 .Fa addr
1052 pointer.
1053 .It int * Fn SERVER_SOCKADDR_PORT "struct server_sockaddr *addr"
1054 Returns a pointer to the port associated with the address of the specified
1055 .Nm struct server_sockaddr
1056 .Fa addr
1057 pointer. This port is always in network byte order, so the
1058 .Xr htons 3
1059 function should be used to set it, and the
1060 .Xr ntohs 3
1061 function to query it.
1062 Returns NULL if the address corresponds to the AF_LOCAL family.
1063 .It sa_family_t * Fn SERVER_SOCKADDR_FAMILY "struct server_socaddr *addr"
1064 Returns the sa_family_t pointer to the address family identifyer (AF_INET,
1065 AF_INET6, AF_LOCAL) for the specified
1066 .Nm struct server_sockaddr
1067 .Fa addr
1068 pointer.
1069 .It void * Fn SERVER_SOCKADDR_ADDRESS "struct server_sockaddr *addr"
1070 Returns the family-specific IP address of the specified
1071 .Fa addr .
1072 This is especially useful when using the
1073 .Xr inet_ntop 3
1074 and
1075 .Xr inet_pton 3
1076 functions, for instance, which can be provided the addr->family field for
1077 their address family argument, and a pointer provided by this macro for
1078 the address argument.
1079 .It struct sockaddr * Fn SERVER_SOCKADDR "struct server_sockaddr *addr"
1080 Utility macro to return the family-independent
1081 .Nm struct sockaddr
1082 pointer of the specified
1083 .Nm struct server_sockaddr
1084 .Fa addr
1085 pointer. To avoid having to use &addr->u.sockaddr.
1086 .El
1087 .Sh RETURN VALUES
1088 .Bl -tag -width indent -offset indent
1089 .It Xo
1090 .Fn server_init ,
1091 .Fn server_close
1092 .Xc
1093 return nothing.
1094 .It Fn server_shmem_malloc
1095 returns a pointer on success, or NULL on error.
1096 .It Xo
1097 .Fn server_rwlocks_init ,
1098 .Fn server_rwlock_ctl ,
1099 .Fn server_socket_bind ,
1100 .Fn server_start ,
1101 .Fn server_exit ,
1102 .Fn server_recycle ,
1103 .Xc
1104 return 0 on success, or -1 on error, in which case errno is set.
1105 .It Fn server_alarm
1106 returns 0 on success, or (unsigned int)-1 on error.
1107 .It Fn server_execve
1108 returns -1 on error, but normally never returns.
1109 .El
1110 .Sh ERRORS
1111 The errno global variable can be set to the following when a function
1112 returns -1 for error:
1113 .Bl -tag -width Er
1114 .It Bq Er EPERM
1115 The library does not allow this function to be called in this order.
1116 This may be caused by a failure to call
1117 .Fn server_init 
1118 or in a function which should be called before or after
1119 .Fn server_start .
1120 Another possibility is
1121 .Fn server_execve
1122 being called when
1123 .Nm using_execve
1124 is FALSE and/or the child process is not currently serving a SOCK_STREAM
1125 connected client.
1126 .It Bq Er EINVAL
1127 An invalid parameter was supplied, either in a configuration structure
1128 or as parameters to the function.
1129 .It Bq Er EAGAIN
1130 (only for
1131 .Fn server_rwlock_ctl ) ,
1132 SHL_TRY was used and the lock could not immediately be obtained.
1133 .It Bq Er ENOMEM
1134 There was a failure to allocate the necessary memory.
1135 .El
1136 .Pp
1137 Other errno codes may be set and then are the result of internal errors
1138 when calling the C library functions or kernel syscalls, such as
1139 .Xr open 2 ,
1140 .Xr mmap 2 ,
1141 etc.
1142 .Sh SEE ALSO
1143 .Xr inet 4 ,
1144 .Xr inet6 4 ,
1145 .Xr ip 4 ,
1146 .Xr ip6 4 ,
1147 .Xr unix 4 ,
1148 .Xr mmap 2 ,
1149 .Xr flock 2 ,
1150 .Xr socket 2 ,
1151 .Xr bind 2 ,
1152 .Xr connect 2 ,
1153 .Xr recvfrom 2 ,
1154 .Xr sendto 2 ,
1155 .Xr recv 2 ,
1156 .Xr send 2 ,
1157 .Xr read 2 ,
1158 .Xr write 2 ,
1159 .Xr lchown 2 ,
1160 .Xr lchmod 2 ,
1161 .Xr setsid 2 ,
1162 .Xr fcntl 2 ,
1163 .Xr execve 2 ,
1164 .Xr _exit 2 ,
1165 .Xr getnameinfo 3 ,
1166 .Xr inet_ntop 3 ,
1167 .Xr inet_pton 3 ,
1168 .Xr htons 3 ,
1169 .Xr ntohs 3 ,
1170 .Xr exit 3 ,
1171 .Xr mmserver 3 ,
1172 .Xr mmalarm 3 ,
1173 .Xr mmpool 3 ,
1174 .Xr mmhash 3 ,
1175 .Xr mmlist 3 ,
1176 .Xr mmheap 3 ,
1177 .Xr mmlimitrate 3 .
1178 .Sh HISTORY
1179 .Nm
1180 was written by Matthew Mondor, to use on NetBSD 1.6.2 in March 2004 and
1181 was released under a BSD-style license.
1182 .Sh AUTHORS
1183 .Nm
1184 as well as this documentation were
1185 written by Matthew Mondor and are
1186 Copyright (c) 2004-2006, Matthew Mondor, All rights reserved.
1187 .Sh BUGS
1188 Please report any bug to mmondor@accela.net