add Berkeley specific copyright notice
[unix-history] / usr / src / share / doc / psd / 21.ipc / 5.t
CommitLineData
d60e8dff
MK
1.\" Copyright (c) 1986 Regents of the University of California.
2.\" All rights reserved. The Berkeley software License Agreement
3.\" specifies the terms and conditions for redistribution.
4.\"
f41f0747 5.\" @(#)5.t 1.5 (Berkeley) %G%
d60e8dff 6.\"
6d89475b 7.\".ds RH "Advanced Topics
200989e9
MK
8.bp
9.nr H1 5
10.nr H2 0
200989e9
MK
11.LG
12.B
13.ce
145. ADVANCED TOPICS
15.sp 2
16.R
17.NL
18.PP
19A number of facilities have yet to be discussed. For most users
d60e8dff 20of the IPC the mechanisms already
200989e9 21described will suffice in constructing distributed
d60e8dff 22applications. However, others will find the need to utilize some
200989e9
MK
23of the features which we consider in this section.
24.NH 2
25Out of band data
26.PP
27The stream socket abstraction includes the notion of \*(lqout
28of band\*(rq data. Out of band data is a logically independent
29transmission channel associated with each pair of connected
30stream sockets. Out of band data is delivered to the user
6d89475b
MK
31independently of normal data.
32The abstraction defines that the out of band data facilities
200989e9
MK
33must support the reliable delivery of at least one
34out of band message at a time. This message may contain at least one
35byte of data, and at least one message may be pending delivery
36to the user at any one time. For communications protocols which
37support only in-band signaling (i.e. the urgent data is
6d89475b 38delivered in sequence with the normal data), the system normally extracts
200989e9
MK
39the data from the normal data stream and stores it separately.
40This allows users to choose between receiving the urgent data
41in order and receiving it out of sequence without having to
6d89475b 42buffer all the intervening data. It is possible
d60e8dff 43to ``peek'' (via MSG_PEEK) at out of band data.
6d89475b
MK
44If the socket has a process group, a SIGURG signal is generated
45when the protocol is notified of its existence.
46A process can set the process group
47or process id to be informed by the SIGURG signal via the
48appropriate \fIfcntl\fP call, as described below for
49SIGIO.
50If multiple sockets may have out of band data awaiting
51delivery, a \fIselect\fP call for exceptional conditions
52may be used to determine those sockets with such data pending.
53Neither the signal nor the select indicate the actual arrival
54of the out-of-band data, but only notification that it is pending.
55.PP
56In addition to the information passed, a logical mark is placed in
57the data stream to indicate the point at which the out
58of band data was sent. The remote login and remote shell
59applications use this facility to propagate signals between
60client and server processes. When a signal
61flushs any pending output from the remote process(es), all
62data up to the mark in the data stream is discarded.
200989e9 63.PP
d60e8dff 64To send an out of band message the MSG_OOB flag is supplied to
200989e9 65a \fIsend\fP or \fIsendto\fP calls,
d60e8dff 66while to receive out of band data MSG_OOB should be indicated
200989e9
MK
67when performing a \fIrecvfrom\fP or \fIrecv\fP call.
68To find out if the read pointer is currently pointing at
69the mark in the data stream, the SIOCATMARK ioctl is provided:
70.DS
71ioctl(s, SIOCATMARK, &yes);
72.DE
73If \fIyes\fP is a 1 on return, the next read will return data
74after the mark. Otherwise (assuming out of band data has arrived),
75the next read will provide data sent by the client prior
76to transmission of the out of band signal. The routine used
77in the remote login process to flush output on receipt of an
78interrupt or quit signal is shown in Figure 5.
6d89475b
MK
79It reads the normal data up to the mark (to discard it),
80then reads the out-of-band byte.
200989e9
MK
81.KF
82.DS
d60e8dff
MK
83#include <sys/ioctl.h>
84#include <sys/file.h>
85 ...
200989e9
MK
86oob()
87{
f41f0747
MK
88 int out = FWRITE, mark;
89 char waste[BUFSIZ];
200989e9 90
d60e8dff 91 /* flush local terminal output */
200989e9
MK
92 ioctl(1, TIOCFLUSH, (char *)&out);
93 for (;;) {
94 if (ioctl(rem, SIOCATMARK, &mark) < 0) {
95 perror("ioctl");
96 break;
97 }
98 if (mark)
99 break;
100 (void) read(rem, waste, sizeof (waste));
101 }
d60e8dff
MK
102 if (recv(rem, &mark, 1, MSG_OOB) < 0) {
103 perror("recv");
104 ...
105 }
200989e9
MK
106 ...
107}
108.DE
109.ce
6d89475b 110Figure 5. Flushing terminal I/O on receipt of out of band data.
200989e9
MK
111.sp
112.KE
6d89475b
MK
113.PP
114A process may also read or peek at the out-of-band data
115without first reading up to the mark.
116This is more difficult when the underlying protocol delivers
117the urgent data in-band with the normal data, and only sends
118notification of its presence ahead of time (e.g., the TCP protocol
119used to implement streams in the Internet domain).
120With such protocols, the out-of-band byte may not yet have arrived
121when a \fIrecv\fP is done with the MSG_OOB flag.
122In that case, the call will return an error of EWOULDBLOCK.
123Worse, there may be enough in-band data in the input buffer
124that normal flow control prevents the peer from sending the urgent data
125until the buffer is cleared.
126The process must then read enough of the queued data
127that the urgent data may be delivered.
128.PP
129Certain programs that use multiple bytes of urgent data and must
130handle multiple urgent signals (e.g., \fItelnet\fP\|(1C))
131need to retain the position of urgent data within the stream.
132This treatment is available as a socket-level option, SO_OOBINLINE;
133see \fIsetsockopt\fP\|(2) for usage.
134With this option, the position of urgent data (the \*(lqmark\*(rq)
135is retained, but the urgent data immediately follows the mark
136within the normal data stream returned without the MSG_OOB flag.
137Reception of multiple urgent indications causes the mark to move,
138but no out-of-band data are lost.
200989e9 139.NH 2
6d89475b
MK
140Non-Blocking Sockets
141.PP
142It is occasionally convenient to make use of sockets
143which do not block; that is, I/O requests which
144cannot complete immediately and
145would therefore cause the process to be suspended awaiting completion are
146not executed, and an error code is returned.
147Once a socket has been created via
148the \fIsocket\fP call, it may be marked as non-blocking
149by \fIfcntl\fP as follows:
150.DS
151#include <fcntl.h>
152 ...
153int s;
154 ...
155s = socket(AF_INET, SOCK_STREAM, 0);
156 ...
157if (fcntl(s, F_SETFL, FNDELAY) < 0)
158 perror("fcntl F_SETFL, FNDELAY");
159 exit(1);
160}
161 ...
162.DE
163.PP
164When performing non-blocking I/O on sockets, one must be
165careful to check for the error EWOULDBLOCK (stored in the
166global variable \fIerrno\fP), which occurs when
167an operation would normally block, but the socket it
168was performed on is marked as non-blocking.
169In particular, \fIaccept\fP, \fIconnect\fP, \fIsend\fP, \fIrecv\fP,
170\fIread\fP, and \fIwrite\fP can
171all return EWOULDBLOCK, and processes should be prepared
172to deal with such return codes.
173If an operation such as a \fIsend\fP cannot be done in its entirety,
174but partial writes are sensible (for example, when using a stream socket),
175the data that can be sent immediately will be processed,
176and the return value will indicate the amount actually sent.
177.NH 2
178Interrupt driven socket I/O
d60e8dff
MK
179.PP
180The SIGIO signal allows a process to be notified
181via a signal when a socket (or more generally, a file
182descriptor) has data waiting to be read. Use of
183the SIGIO facility requires three steps: First,
184the process must set up a SIGIO signal handler
6d89475b 185by use of the \fIsignal\fP or \fIsigvec\fP calls. Second,
d60e8dff
MK
186it must set the process id or process group id which is to receive
187notification of pending input to its own process id,
188or the process group id of its process group (note that
189the default process group of a socket is group zero).
6d89475b
MK
190This is accomplished by use of an \fIfcntl\fP call.
191Third, it must enable asynchronous notification of pending I/O requests
d60e8dff
MK
192with another \fIfcntl\fP call. Sample code to
193allow a given process to receive information on
6d89475b
MK
194pending I/O requests as they occur for a socket \fIs\fP
195is given in Figure 6. With the addition of a handler for SIGURG,
196this code can also be used to prepare for receipt of SIGURG signals.
d60e8dff
MK
197.KF
198.DS
199#include <fcntl.h>
200 ...
201int io_handler();
202 ...
203signal(SIGIO, io_handler);
204
205/* Set the process receiving SIGIO/SIGURG signals to us */
206
207if (fcntl(s, F_SETOWN, getpid()) < 0) {
208 perror("fcntl F_SETOWN");
209 exit(1);
210}
211
6d89475b 212/* Allow receipt of asynchronous I/O signals */
d60e8dff
MK
213
214if (fcntl(s, F_SETFL, FASYNC) < 0) {
215 perror("fcntl F_SETFL, FASYNC");
216 exit(1);
217}
218.DE
219.ce
6d89475b 220Figure 6. Use of asynchronous notification of I/O requests.
d60e8dff
MK
221.sp
222.KE
223.NH 2
200989e9
MK
224Signals and process groups
225.PP
226Due to the existence of the SIGURG and SIGIO signals each socket has an
d60e8dff
MK
227associated process number, just as is done for terminals.
228This value is initialized to zero,
229but may be redefined at a later time with the F_SETOWN
230\fIfcntl\fP, such as was done in the code above for SIGIO.
231To set the socket's process id for signals, positive arguments
232should be given to the \fIfcntl\fP call. To set the socket's
233process group for signals, negative arguments should be
234passed to \fIfcntl\fP. Note that the process number indicates
235either the associated process id or the associated process
236group; it is impossible to specify both at the same time.
237A similar \fIfcntl\fP, F_GETOWN, is available for determining the
238current process number of a socket.
239.PP
6d89475b 240Another signal which is useful when constructing server processes
d60e8dff 241is SIGCHLD. This signal is delivered to a process when any
6d89475b
MK
242child processes have changed state. Normally servers use
243the signal to \*(lqreap\*(rq child processes that have exited
244without explicitly awaiting their termination
245or periodic polling for exit status.
d60e8dff
MK
246For example, the remote login server loop shown in Figure 2
247may be augmented as shown in Figure 7.
248.KF
200989e9 249.DS
d60e8dff
MK
250int reaper();
251 ...
252signal(SIGCHLD, reaper);
253listen(f, 5);
254for (;;) {
255 int g, len = sizeof (from);
256
257 g = accept(f, (struct sockaddr *)&from, &len,);
258 if (g < 0) {
259 if (errno != EINTR)
260 syslog(LOG_ERR, "rlogind: accept: %m");
261 continue;
262 }
263 ...
264}
265 ...
266#include <wait.h>
267reaper()
268{
269 union wait status;
270
271 while (wait3(&status, WNOHANG, 0) > 0)
272 ;
273}
200989e9 274.DE
d60e8dff
MK
275.sp
276.ce
277Figure 7. Use of the SIGCHLD signal.
278.sp
279.KE
280.PP
281If the parent server process fails to reap its children,
282a large number of \*(lqzombie\*(rq processes may be created.
200989e9
MK
283.NH 2
284Pseudo terminals
285.PP
286Many programs will not function properly without a terminal
6d89475b
MK
287for standard input and output. Since sockets do not provide
288the semantics of terminals,
200989e9 289it is often necessary to have a process communicating over
6d89475b 290the network do so through a \fIpseudo-terminal\fP. A pseudo-
200989e9
MK
291terminal is actually a pair of devices, master and slave,
292which allow a process to serve as an active agent in communication
293between processes and users. Data written on the slave side
6d89475b
MK
294of a pseudo-terminal is supplied as input to a process reading
295from the master side, while data written on the master side are
296processed as terminal input for the slave.
297In this way, the process manipulating
298the master side of the pseudo-terminal has control over the
299information read and written on the slave side
300as if it were manipulating the keyboard and reading the screen
301on a real terminal.
d60e8dff 302The purpose of this abstraction is to
6d89475b
MK
303preserve terminal semantics over a network connection\(em
304that is, the slave side appears as a normal terminal to
d60e8dff
MK
305any process reading from or writing to it.
306.PP
307For example, the remote
6d89475b 308login server uses pseudo-terminals for remote login sessions.
200989e9 309A user logging in to a machine across the network is provided
6d89475b 310a shell with a slave pseudo-terminal as standard input, output,
200989e9
MK
311and error. The server process then handles the communication
312between the programs invoked by the remote shell and the user's
6d89475b
MK
313local client process.
314When a user sends a character that generates an interrupt
315on the remote machine that flushes terminal output,
316the pseudo-terminal generates a control message for the server process.
317The server then sends an out of band message
318to the client process to signal a flush of data at the real terminal
319and on the intervening data buffered in the network.
d60e8dff 320.PP
6d89475b 321Under 4.3BSD, the name of the slave side of a pseudo-terminal is of the form
d60e8dff 322\fI/dev/ttyxy\fP, where \fIx\fP is a single letter
6d89475b
MK
323starting at `p' and continuing to `t'.
324\fIy\fP is a hexadecimal digit (i.e., a single
d60e8dff 325character in the range 0 through 9 or `a' through `f').
6d89475b
MK
326The master side of a pseudo-terminal is \fI/dev/ptyxy\fP,
327where \fIx\fP and \fIy\fP correspond to the
328slave side of the pseudo-terminal.
d60e8dff
MK
329.PP
330In general, the method of obtaining a pair of master and
6d89475b
MK
331slave pseudo-terminals is to
332find a pseudo-terminal which
333is not currently in use.
334The master half of a pseudo-terminal is a single-open device;
335thus, each master may be opened in turn until an open succeeds.
336The slave side of the pseudo-terminal is then opened,
337and is set to the proper terminal modes if necessary.
d60e8dff 338The process then \fIfork\fPs; the child closes
6d89475b 339the master side of the pseudo-terminal, and \fIexec\fPs the
d60e8dff 340appropriate program. Meanwhile, the parent closes the
6d89475b 341slave side of the pseudo-terminal and begins reading and
d60e8dff 342writing from the master side. Sample code making use of
6d89475b 343pseudo-terminals is given in Figure 8; this code assumes
d60e8dff
MK
344that a connection on a socket \fIs\fP exists, connected
345to a peer who wants a service of some kind, and that the
6d89475b 346process has disassociated itself from any previous controlling terminal.
d60e8dff
MK
347.KF
348.DS
349gotpty = 0;
350for (c = 'p'; !gotpty && c <= 's'; c++) {
351 line = "/dev/ptyXX";
352 line[sizeof("/dev/pty")-1] = c;
353 line[sizeof("/dev/ptyp")-1] = '0';
354 if (stat(line, &statbuf) < 0)
355 break;
356 for (i = 0; i < 16; i++) {
357 line[sizeof("/dev/ptyp")-1] = "0123456789abcdef"[i];
358 master = open(line, O_RDWR);
359 if (master > 0) {
360 gotpty = 1;
361 break;
362 }
363 }
364}
365if (!gotpty) {
366 syslog(LOG_ERR, "All network ports in use");
367 exit(1);
368}
369
370line[sizeof("/dev/")-1] = 't';
371slave = open(line, O_RDWR); /* \fIslave\fP is now slave side */
372if (slave < 0) {
373 syslog(LOG_ERR, "Cannot open slave pty %s", line);
374 exit(1);
375}
376
377ioctl(slave, TIOCGETP, &b); /* Set slave tty modes */
378b.sg_flags = CRMOD|XTABS|ANYP;
379ioctl(slave, TIOCSETP, &b);
380
381i = fork();
382if (i < 0) {
383 syslog(LOG_ERR, "fork: %m");
384 exit(1);
385} else if (i) { /* Parent */
386 close(slave);
387 ...
388} else { /* Child */
389 (void) close(s);
390 (void) close(master);
391 dup2(slave, 0);
392 dup2(slave, 1);
393 dup2(slave, 2);
394 if (slave > 2)
395 (void) close(slave);
396 ...
397}
398.DE
399.ce
400Figure 8. Creation and use of a pseudo terminal
401.sp
402.KE
200989e9 403.NH 2
d60e8dff 404Selecting specific protocols
200989e9 405.PP
d60e8dff
MK
406If the third argument to the \fIsocket\fP call is 0,
407\fIsocket\fP will select a default protocol to use with
6d89475b
MK
408the returned socket of the type requested.
409The default protocol is usually correct, and alternate choices are not
410usually available.
411However, when using ``raw'' sockets to communicate directly with
412lower-level protocols or hardware interfaces,
413the protocol argument may be important for setting up demultiplexing.
414For example, raw sockets in the Internet family may be used to implement
415a new protocol above IP, and the socket will receive packets
416only for the protocol specified.
417To obtain a particular protocol one determines the protocol number
d60e8dff 418as defined within the communication domain. For the Internet
6d89475b 419domain one may use one of the library routines
d60e8dff
MK
420discussed in section 3, such as \fIgetprotobyname\fP:
421.DS
422#include <sys/types.h>
423#include <sys/socket.h>
424#include <netinet/in.h>
425#include <netdb.h>
426 ...
427pp = getprotobyname("newtcp");
428s = socket(AF_INET, SOCK_STREAM, pp->p_proto);
429.DE
430This would result in a socket \fIs\fP using a stream
431based connection, but with protocol type of ``newtcp''
432instead of the default ``tcp.''
433.PP
434In the NS domain, the available socket protocols are defined in
435<\fInetns/ns.h\fP>. To create a raw socket for Xerox Error Protocol
436messages, one might use:
437.DS
438#include <sys/types.h>
439#include <sys/socket.h>
440#include <netns/ns.h>
441 ...
442s = socket(AF_NS, SOCK_RAW, NSPROTO_ERROR);
443.DE
444.NH 2
445Address binding
446.PP
447As was mentioned in section 2,
448binding addresses to sockets in the Internet and NS domains can be
449fairly complex. As a brief reminder, these associations
450are composed of local and foreign
200989e9 451addresses, and local and foreign ports. Port numbers are
d60e8dff
MK
452allocated out of separate spaces, one for each system and one
453for each domain on that system.
454Through the \fIbind\fP system call, a
455process may specify half of an association, the
456<local address, local port> part, while the
457\fIconnect\fP
458and \fIaccept\fP
459primitives are used to complete a socket's association by
460specifying the <foreign address, foreign port> part.
200989e9 461Since the association is created in two steps the association
d60e8dff 462uniqueness requirement indicated previously could be violated unless
200989e9
MK
463care is taken. Further, it is unrealistic to expect user
464programs to always know proper values to use for the local address
465and local port since a host may reside on multiple networks and
466the set of allocated port numbers is not directly accessible
467to a user.
468.PP
d60e8dff 469To simplify local address binding in the Internet domain the notion of a
200989e9
MK
470\*(lqwildcard\*(rq address has been provided. When an address
471is specified as INADDR_ANY (a manifest constant defined in
472<netinet/in.h>), the system interprets the address as
473\*(lqany valid address\*(rq. For example, to bind a specific
474port number to a socket, but leave the local address unspecified,
475the following code might be used:
476.DS
477#include <sys/types.h>
478#include <netinet/in.h>
479 ...
480struct sockaddr_in sin;
481 ...
482s = socket(AF_INET, SOCK_STREAM, 0);
483sin.sin_family = AF_INET;
d60e8dff
MK
484sin.sin_addr.s_addr = htonl(INADDR_ANY);
485sin.sin_port = htons(MYPORT);
486bind(s, (struct sockaddr *) &sin, sizeof (sin));
200989e9
MK
487.DE
488Sockets with wildcarded local addresses may receive messages
6d89475b 489directed to the specified port number, and sent to any
d60e8dff 490of the possible addresses assigned to a host. For example,
6d89475b
MK
491if a host has addresses 128.32.0.4 and 10.0.0.78, and a socket is bound as
492above, the process will be
493able to accept connection requests which are addressed to
494128.32.0.4 or 10.0.0.78.
d60e8dff
MK
495If a server process wished to only allow hosts on a
496given network connect to it, it would bind
6d89475b 497the address of the host on the appropriate network.
200989e9
MK
498.PP
499In a similar fashion, a local port may be left unspecified
500(specified as zero), in which case the system will select an
d60e8dff
MK
501appropriate port number for it. This shortcut will work
502both in the Internet and NS domains. For example, to
503bind a specific local address to a socket, but to leave the
504local port number unspecified:
200989e9 505.DS
d60e8dff
MK
506hp = gethostbyname(hostname);
507if (hp == NULL) {
508 ...
509}
510bcopy(hp->h_addr, (char *) sin.sin_addr, hp->h_length);
511sin.sin_port = htons(0);
512bind(s, (struct sockaddr *) &sin, sizeof (sin));
200989e9 513.DE
d60e8dff
MK
514The system selects the local port number based on two criteria.
515The first is that on 4BSD systems,
6d89475b 516Internet ports below IPPORT_RESERVED (1024) (for the Xerox domain,
d60e8dff 5170 through 3000) are reserved
6d89475b
MK
518for privileged users (i.e., the super user);
519Internet ports above IPPORT_USERRESERVED (50000) are reserved
520for non-privileged servers. The second is
200989e9 521that the port number is not currently bound to some other
d60e8dff
MK
522socket. In order to find a free Internet port number in the privileged
523range the \fIrresvport\fP library routine may be used as follows
524to return a stream socket in with a privileged port number:
200989e9 525.DS
d60e8dff
MK
526int lport = IPPORT_RESERVED \- 1;
527int s;
528...
529s = rresvport(&lport);
530if (s < 0) {
531 if (errno == EAGAIN)
532 fprintf(stderr, "socket: all ports in use\en");
533 else
534 perror("rresvport: socket");
535 ...
200989e9
MK
536}
537.DE
538The restriction on allocating ports was done to allow processes
539executing in a \*(lqsecure\*(rq environment to perform authentication
d60e8dff
MK
540based on the originating address and port number. For example,
541the \fIrlogin\fP(1) command allows users to log in across a network
542without being asked for a password, if two conditions hold:
543First, the name of the system the user
544is logging in from is in the file
545\fI/etc/hosts.equiv\fP on the system he is logging
546in to (or the system name and the user name are in
547the user's \fI.rhosts\fP file in the user's home
548directory), and second, that the user's rlogin
6d89475b
MK
549process is coming from a privileged port on the machine from which he is
550logging. The port number and network address of the
551machine from which the user is logging in can be determined either
552by the \fIfrom\fP result of the \fIaccept\fP call, or
d60e8dff 553from the \fIgetpeername\fP call.
200989e9
MK
554.PP
555In certain cases the algorithm used by the system in selecting
6d89475b
MK
556port numbers is unsuitable for an application. This is because
557associations are created in a two step process. For example,
200989e9
MK
558the Internet file transfer protocol, FTP, specifies that data
559connections must always originate from the same local port. However,
560duplicate associations are avoided by connecting to different foreign
561ports. In this situation the system would disallow binding the
562same local address and port number to a socket if a previous data
6d89475b
MK
563connection's socket still existed. To override the default port
564selection algorithm, an option call must be performed prior
200989e9
MK
565to address binding:
566.DS
d60e8dff
MK
567 ...
568int on = 1;
569 ...
570setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
571bind(s, (struct sockaddr *) &sin, sizeof (sin));
200989e9
MK
572.DE
573With the above call, local addresses may be bound which
574are already in use. This does not violate the uniqueness
575requirement as the system still checks at connect time to
576be sure any other sockets with the same local address and
6d89475b
MK
577port do not have the same foreign address and port.
578If the association already exists, the error EADDRINUSE is returned.
200989e9 579.NH 2
6d89475b 580Broadcasting and determining network configuration
200989e9 581.PP
6d89475b
MK
582By using a datagram socket, it is possible to send broadcast
583packets on many networks supported by the system.
584The network itself must support broadcast; the system
585provides no simulation of broadcast in software.
586Broadcast messages can place a high load on a network since they force
200989e9 587every host on the network to service them. Consequently,
d60e8dff
MK
588the ability to send broadcast packets has been limited
589to sockets which are explicitly marked as allowing broadcasting.
6d89475b
MK
590Broadcast is typically used for one of two reasons:
591it is desired to find a resource on a local network without prior
592knowledge of its address,
593or important functions such as routing require that information
594be sent to all accessible neighbors.
200989e9 595.PP
d60e8dff 596To send a broadcast message, a datagram socket
200989e9
MK
597should be created:
598.DS
599s = socket(AF_INET, SOCK_DGRAM, 0);
600.DE
d60e8dff
MK
601or
602.DS
603s = socket(AF_NS, SOCK_DGRAM, 0);
604.DE
605The socket is marked as allowing broadcasting,
606.DS
607int on = 1;
608
609setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on));
610.DE
200989e9
MK
611and at least a port number should be bound to the socket:
612.DS
613sin.sin_family = AF_INET;
d60e8dff
MK
614sin.sin_addr.s_addr = htonl(INADDR_ANY);
615sin.sin_port = htons(MYPORT);
616bind(s, (struct sockaddr *) &sin, sizeof (sin));
617.DE
618or, for the NS domain,
619.DS
620sns.sns_family = AF_NS;
621netnum = htonl(net);
622sns.sns_addr.x_net = *(union ns_net *) &netnum; /* insert net number */
623sns.sns_addr.x_port = htons(MYPORT);
624bind(s, (struct sockaddr *) &sns, sizeof (sns));
625.DE
626The destination address of the message to be broadcast
6d89475b
MK
627depends on the network(s) on which the message is to be broadcast.
628The Internet domain supports a shorthand notation for broadcast
629on the local network, the address INADDR_BROADCAST (defined in
630<\fInetinet/in.h\fP>.
631To determine the list of addresses for all reachable neighbors
632requires knowledge of the networks to which the host is connected.
633Since this information should
634be obtained in a host-independent fashion and may be impossible
635to derive, 4.3BSD provides a method of
d60e8dff
MK
636retrieving this information from the system data structures.
637The SIOCGIFCONF \fIioctl\fP call returns the interface
638configuration of a host in the form of a
639single \fIifconf\fP structure; this structure contains
640a ``data area'' which is made up of an array of
641of \fIifreq\fP structures, one for each network interface
642to which the host is connected.
643These structures are defined in
644\fI<net/if.h>\fP as follows:
645.DS
646.if t .ta .5i 1.0i 1.5i 3.5i
647.if n .ta .7i 1.4i 2.1i 3.4i
648struct ifconf {
649 int ifc_len; /* size of associated buffer */
650 union {
651 caddr_t ifcu_buf;
652 struct ifreq *ifcu_req;
653 } ifc_ifcu;
654};
655
656#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
657#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
658
659#define IFNAMSIZ 16
660
661struct ifreq {
662 char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
663 union {
664 struct sockaddr ifru_addr;
665 struct sockaddr ifru_dstaddr;
666 struct sockaddr ifru_broadaddr;
667 short ifru_flags;
668 caddr_t ifru_data;
669 } ifr_ifru;
670};
671
672.if t .ta \w' #define'u +\w' ifr_broadaddr'u +\w' ifr_ifru.ifru_broadaddr'u
673#define ifr_addr ifr_ifru.ifru_addr /* address */
674#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
675#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
676#define ifr_flags ifr_ifru.ifru_flags /* flags */
677#define ifr_data ifr_ifru.ifru_data /* for use by interface */
678.DE
679The actual call which obtains the
680interface configuration is
681.DS
682struct ifconf ifc;
683char buf[BUFSIZ];
684
685ifc.ifc_len = sizeof (buf);
686ifc.ifc_buf = buf;
687if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
688 ...
689}
200989e9 690.DE
d60e8dff
MK
691After this call \fIbuf\fP will contain one \fIifreq\fP structure for
692each network to which the host is connected, and
693\fIifc.ifc_len\fP will have been modified to reflect the number
694of bytes used by the \fIifreq\fP structures.
695.PP
696For each structure
697there exists a set of ``interface flags'' which tell
698whether the network corresponding to that interface is
699up or down, point to point or broadcast, etc. The
700SIOCGIFFLAGS \fIioctl\fP retrieves these
701flags for an interface specified by an \fIifreq\fP
702structure as follows:
200989e9 703.DS
d60e8dff
MK
704struct ifreq *ifr;
705
706ifr = ifc.ifc_req;
707
708for (n = ifc.ifc_len / sizeof (struct ifreq); --n >= 0; ifr++) {
709 /*
710 * We must be careful that we don't use an interface
6d89475b 711 * devoted to an address family other than those intended;
d60e8dff
MK
712 * if we were interested in NS interfaces, the
713 * AF_INET would be AF_NS.
714 */
715 if (ifr->ifr_addr.sa_family != AF_INET)
716 continue;
717 if (ioctl(s, SIOCGIFFLAGS, (char *) ifr) < 0) {
718 ...
719 }
6d89475b
MK
720 /*
721 * Skip boring cases.
722 */
723 if ((ifr->ifr_flags & IFF_UP) == 0 ||
724 (ifr->ifr_flags & IFF_LOOPBACK) ||
d60e8dff
MK
725 (ifr->ifr_flags & (IFF_BROADCAST | IFF_POINTTOPOINT)) == 0)
726 continue;
200989e9 727.DE
d60e8dff
MK
728.PP
729Once the flags have been obtained, the broadcast address
730must be obtained. In the case of broadcast networks this is
731done via the SIOCGIFBRDADDR \fIioctl\fP, while for point-to-point networks
732the address of the destination host is obtained with SIOCGIFDSTADDR.
733.DS
734struct sockaddr dst;
735
736if (ifr->ifr_flags & IFF_POINTTOPOINT) {
737 if (ioctl(s, SIOCGIFDSTADDR, (char *) ifr) < 0) {
738 ...
739 }
740 bcopy((char *) ifr->ifr_dstaddr, (char *) &dst, sizeof (ifr->ifr_dstaddr));
741} else if (ifr->ifr_flags & IFF_BROADCAST) {
742 if (ioctl(s, SIOCGIFBRDADDR, (char *) ifr) < 0) {
743 ...
744 }
745 bcopy((char *) ifr->ifr_broadaddr, (char *) &dst, sizeof (ifr->ifr_broadaddr));
746}
747.DE
748.PP
749After the appropriate \fIioctl\fP's have obtained the broadcast
750or destination address (now in \fIdst\fP), the \fIsendto\fP call may be
751used:
200989e9 752.DS
d60e8dff
MK
753 sendto(s, buf, buflen, 0, (struct sockaddr *)&dst, sizeof (dst));
754}
200989e9 755.DE
d60e8dff 756In the above loop one \fIsendto\fP occurs for every
6d89475b 757interface to which the host is connected that supports the notion of
d60e8dff
MK
758broadcast or point-to-point addressing.
759If a process only wished to send broadcast
760messages on a given network, code similar to that outlined above
761would be used, but the loop would need to find the
762correct destination address.
200989e9
MK
763.PP
764Received broadcast messages contain the senders address
d60e8dff
MK
765and port, as datagram sockets are bound before
766a message is allowed to go out.
200989e9 767.NH 2
d60e8dff 768Socket Options
200989e9 769.PP
d60e8dff
MK
770It is possible to set and get a number of options on sockets
771via the \fIsetsockopt\fP and \fIgetsockopt\fP system calls.
772These options include such things as marking a socket for
773broadcasting, not to route, to linger on close, etc.
774The general forms of the calls are:
200989e9 775.DS
d60e8dff
MK
776setsockopt(s, level, optname, optval, optlen);
777.DE
778and
779.DS
780getsockopt(s, level, optname, optval, optlen);
781.DE
782.PP
783The parameters to the calls are as follows: \fIs\fP
784is the socket on which the option is to be applied.
785\fILevel\fP specifies the protocol layer on which the
786option is to be applied; in most cases this is
787the ``socket level'', indicated by the symbolic constant
788SOL_SOCKET, defined in \fI<sys/socket.h>.\fP
789The actual option is specified in \fIoptname\fP, and is
790a symbolic constant also defined in \fI<sys/socket.h>\fP.
791\fIOptval\fP and \fIOptlen\fP point to the value of the
792option (in most cases, whether the option is to be turned
793on or off), and the length of the value of the option,
794respectively.
795For \fIgetsockopt\fP, \fIoptlen\fP is
796a value-result parameter, initially set to the size of
797the storage area pointed to by \fIoptval\fP, and modified
798upon return to indicate the actual amount of storage used.
799.PP
800An example should help clarify things. It is sometimes
801useful to determine the type (e.g., stream, datagram, etc.)
802of an existing socket; programs
803under \fIinetd\fP (described below) may need to perform this
804task. This can be accomplished as follows via the
805SO_TYPE socket option and the \fIgetsockopt\fP call:
806.DS
807#include <sys/types.h>
808#include <sys/socket.h>
200989e9 809
d60e8dff
MK
810int type, size;
811
812size = sizeof (int);
813
814if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &type, &size) < 0) {
200989e9
MK
815 ...
816}
d60e8dff
MK
817.DE
818After the \fIgetsockopt\fP call, \fItype\fP will be set
819to the value of the socket type, as defined in
820\fI<sys/socket.h>\fP. If, for example, the socket were
821a datagram socket, \fItype\fP would have the value
822corresponding to SOCK_DGRAM.
823.NH 2
824NS Packet Sequences
825.PP
826The semantics of NS connections demand that
827the user both be able to look inside the network header associated
828with any incoming packet and be able to specify what should go
3c0dec46
MK
829in certain fields of an outgoing packet.
830Using different calls to \fIsetsockopt\fP, it is possible
831to indicate whether prototype headers will be associated by
832the user with each outgoing packet (SO_HEADERS_ON_OUTPUT),
833to indicate whether the headers received by the system should be
834delivered to the user (SO_HEADERS_ON_INPUT), or to indicate
835default information that should be associated with all
836outgoing packets on a given socket (SO_DEFAULT_HEADERS).
d60e8dff
MK
837.PP
838The contents of a SPP header (minus the IDP header) are:
839.DS
840.if t .ta \w" #define"u +\w" u_short"u +2.0i
841struct sphdr {
842 u_char sp_cc; /* connection control */
843#define SP_SP 0x80 /* system packet */
844#define SP_SA 0x40 /* send acknowledgement */
845#define SP_OB 0x20 /* attention (out of band data) */
846#define SP_EM 0x10 /* end of message */
847 u_char sp_dt; /* datastream type */
848 u_short sp_sid; /* source connection identifier */
849 u_short sp_did; /* destination connection identifier */
850 u_short sp_seq; /* sequence number */
851 u_short sp_ack; /* acknowledge number */
852 u_short sp_alo; /* allocation number */
853};
854.DE
855Here, the items of interest are the \fIdatastream type\fP and
856the \fIconnection control\fP fields. The semantics of the
857datastream type are defined by the application(s) in question;
858the value of this field is, by default, zero, but it can be
859used to indicate things such as Xerox's Bulk Data Transfer
860Protocol (in which case it is set to one). The connection control
3c0dec46 861field is a mask of the flags defined just below it. The user may
d60e8dff
MK
862set or clear the end-of-message bit to indicate
863that a given message is the last of a given substream type,
864or may set/clear the attention bit as an alternate way to
865indicate that a packet should be sent out-of-band.
3c0dec46
MK
866As an example, to associate prototype headers with outgoing
867SPP packets, consider:
d60e8dff
MK
868.DS
869#include <sys/types.h>
870#include <sys/socket.h>
871#include <netns/ns.h>
872#include <netns/sp.h>
200989e9 873 ...
d60e8dff
MK
874struct sockaddr_ns sns, to;
875int s, on = 1;
876struct databuf {
877 struct sphdr proto_spp; /* prototype header */
878 char buf[534]; /* max. possible data by Xerox std. */
879} buf;
880 ...
881s = socket(AF_NS, SOCK_SEQPACKET, 0);
882 ...
883bind(s, (struct sockaddr *) &sns, sizeof (sns));
884setsockopt(s, NSPROTO_SPP, SO_HEADERS_ON_OUTPUT, &on, sizeof(on));
885 ...
886buf.proto_spp.sp_dt = 1; /* bulk data */
887buf.proto_spp.sp_cc = SP_EM; /* end-of-message */
888strcpy(buf.buf, "hello world\en");
889sendto(s, (char *) &buf, sizeof(struct sphdr) + strlen("hello world\en"),
890 (struct sockaddr *) &to, sizeof(to));
891 ...
892.DE
893Note that one must be careful when writing headers; if the prototype
894header is not written with the data with which it is to be associated,
895the kernel will treat the first few bytes of the data as the
896header, with unpredictable results.
897To turn off the above association, and to indicate that packet
898headers received by the system should be passed up to the user,
899one might use:
900.DS
901#include <sys/types.h>
902#include <sys/socket.h>
903#include <netns/ns.h>
904#include <netns/sp.h>
905 ...
906struct sockaddr sns;
907int s, on = 1, off = 0;
908 ...
909s = socket(AF_NS, SOCK_SEQPACKET, 0);
910 ...
911bind(s, (struct sockaddr *) &sns, sizeof (sns));
912setsockopt(s, NSPROTO_SPP, SO_HEADERS_ON_OUTPUT, &off, sizeof(off));
913setsockopt(s, NSPROTO_SPP, SO_HEADERS_ON_INPUT, &on, sizeof(on));
914 ...
915.DE
3c0dec46
MK
916.PP
917Output is handled somewhat differently in the IDP world.
918The header of an IDP-level packet looks like:
919.DS
920.if t .ta \w'struct 'u +\w" struct ns_addr"u +2.0i
921struct idp {
922 u_short idp_sum; /* Checksum */
923 u_short idp_len; /* Length, in bytes, including header */
924 u_char idp_tc; /* Transport Control (i.e., hop count) */
925 u_char idp_pt; /* Packet Type (i.e., level 2 protocol) */
926 struct ns_addr idp_dna; /* Destination Network Address */
927 struct ns_addr idp_sna; /* Source Network Address */
928};
929.DE
930The primary field of interest in an IDP header is the \fIpacket type\fP
931field. The standard values for this field are (as defined
932in <\fInetns/ns.h\fP>):
933.DS
934.if t .ta \w" #define"u +\w" NSPROTO_ERROR"u +1.0i
935#define NSPROTO_RI 1 /* Routing Information */
936#define NSPROTO_ECHO 2 /* Echo Protocol */
937#define NSPROTO_ERROR 3 /* Error Protocol */
938#define NSPROTO_PE 4 /* Packet Exchange */
939#define NSPROTO_SPP 5 /* Sequenced Packet */
940.DE
941For SPP connections, the contents of this field are
942automatically set to NSPROTO_SPP; for IDP packets,
943this value defaults to zero, which means ``unknown''.
944.PP
945Setting the value of that field with SO_DEFAULT_HEADERS is
946easy:
d60e8dff
MK
947.DS
948#include <sys/types.h>
949#include <sys/socket.h>
950#include <netns/ns.h>
951#include <netns/idp.h>
952 ...
953struct sockaddr sns;
954struct idp proto_idp; /* prototype header */
955int s, on = 1;
956 ...
957s = socket(AF_NS, SOCK_DGRAM, 0);
958 ...
959bind(s, (struct sockaddr *) &sns, sizeof (sns));
960proto_idp.idp_pt = NSPROTO_PE; /* packet exchange */
961setsockopt(s, NSPROTO_IDP, SO_DEFAULT_HEADERS, (char *) &proto_idp,
962 sizeof(proto_idp));
963 ...
964.DE
3c0dec46
MK
965.PP
966Using SO_HEADERS_ON_OUTPUT is somewhat more difficult. When
967SO_HEADERS_ON_OUTPUT is turned on for an IDP socket, the socket
968becomes (for all intents and purposes) a raw socket. In this
969case, all the fields of the prototype header (except the
970length and checksum fields, which are computed by the kernel)
971must be filled in correctly in order for the socket to send and
972receive data in a sensible manner. To be more specific, the
973source address must be set to that of the host sending the
974data; the destination address must be set to that of the
975host for whom the data is intended; the packet type must be
976set to whatever value is desired; and the hopcount must be
977set to some reasonable value (almost always zero). It should
978also be noted that simply sending data using \fIwrite\fP
979will not work unless a \fIconnect\fP or \fIsendto\fP call
980is used, in spite of the fact that it is the destination
981address in the prototype header that is used, not the one
982given in either of those calls. For almost
983all IDP applications , using SO_DEFAULT_HEADERS is easier and
984more desirable than writing headers.
d60e8dff
MK
985.NH 2
986Three-way Handshake
987.PP
988The semantics of SPP connections indicates that a three-way
989handshake, involving changes in the datastream type, should \(em
990but is not absolutely required to \(em take place before a SPP
991connection is closed. Almost all SPP connections are
992``well-behaved'' in this manner; when communicating with
993any process, it is best to assume that the three-way handshake
994is required unless it is known for certain that it is not
995required. In a three-way close, the closing process
996indicates that it wishes to close the connection by sending
997a zero-length packet with end-of-message set and with
998datastream type 254. The other side of the connection
999indicates that it is OK to close by sending a zero-length
1000packet with end-of-message set and datastream type 255. Finally,
1001the closing process replies with a zero-length packet with
1002substream type 255; at this point, the connection is considered
1003closed. The following code fragments are simplified examples
1004of how one might handle this three-way handshake at the user
1005level; in the future, support for this type of close will
1006probably be provided as part of the C library or as part of
1007the kernel. The first code fragment below illustrates how a process
1008might handle three-way handshake if it sees that the process it
1009is communicating with wants to close the connection:
1010.DS
1011#include <sys/types.h>
1012#include <sys/socket.h>
1013#include <netns/ns.h>
1014#include <netns/sp.h>
1015 ...
1016#ifndef SPPSST_END
1017#define SPPSST_END 254
1018#define SPPSST_ENDREPLY 255
1019#endif
1020struct sphdr proto_sp;
1021int s;
1022 ...
1023read(s, buf, BUFSIZE);
1024if (((struct sphdr *)buf)->sp_dt == SPPSST_END) {
1025 /*
1026 * SPPSST_END indicates that the other side wants to
1027 * close.
1028 */
1029 proto_sp.sp_dt = SPPSST_ENDREPLY;
1030 proto_sp.sp_cc = SP_EM;
1031 setsockopt(s, NSPROTO_SPP, SO_DEFAULT_HEADERS, (char *)&proto_sp,
1032 sizeof(proto_sp));
1033 write(s, buf, 0);
1034 /*
1035 * Write a zero-length packet with datastream type = SPPSST_ENDREPLY
1036 * to indicate that the close is OK with us. The packet that we
1037 * don't see (because we don't look for it) is another packet
1038 * from the other side of the connection, with SPPSST_ENDREPLY
1039 * on it it, too. Once that packet is sent, the connection is
1040 * considered closed; note that we really ought to retransmit
1041 * the close for some time if we do not get a reply.
1042 */
1043 close(s);
1044}
1045 ...
1046.DE
1047To indicate to another process that we would like to close the
1048connection, the following code would suffice:
1049.DS
1050#include <sys/types.h>
1051#include <sys/socket.h>
1052#include <netns/ns.h>
1053#include <netns/sp.h>
1054 ...
1055#ifndef SPPSST_END
1056#define SPPSST_END 254
1057#define SPPSST_ENDREPLY 255
1058#endif
1059struct sphdr proto_sp;
1060int s;
1061 ...
1062proto_sp.sp_dt = SPPSST_END;
1063proto_sp.sp_cc = SP_EM;
1064setsockopt(s, NSPROTO_SPP, SO_DEFAULT_HEADERS, (char *)&proto_sp,
1065 sizeof(proto_sp));
1066write(s, buf, 0); /* send the end request */
1067proto_sp.sp_dt = SPPSST_ENDREPLY;
1068setsockopt(s, NSPROTO_SPP, SO_DEFAULT_HEADERS, (char *)&proto_sp,
1069 sizeof(proto_sp));
1070/*
1071 * We assume (perhaps unwisely)
1072 * that the other side will send the
1073 * ENDREPLY, so we'll just send our final ENDREPLY
1074 * as if we'd seen theirs already.
1075 */
1076write(s, buf, 0);
1077close(s);
1078 ...
1079.DE
1080.NH 2
1081Packet Exchange
1082.PP
1083The Xerox standard protocols include a protocol that is both
1084reliable and datagram-oriented. This protocol is known as
1085Packet Exchange (PEX or PE) and, like SPP, is layered on top
1086of IDP. PEX is important for a number of things: Courier
1087remote procedure calls may be expedited through the use
1088of PEX, and many Xerox servers are located by doing a PEX
1089``BroadcastForServers'' operation. Although there is no
1090implementation of PEX in the kernel,
1091it may be simulated at the user level with some clever coding
1092and the use of one peculiar \fIgetsockopt\fP. A PEX packet
1093looks like:
1094.DS
1095.if t .ta \w'struct 'u +\w" struct idp"u +2.0i
1096/*
1097 * The packet-exchange header shown here is not defined
1098 * as part of any of the system include files.
1099 */
1100struct pex {
1101 struct idp p_idp; /* idp header */
1102 u_short ph_id[2]; /* unique transaction ID for pex */
1103 u_short ph_client; /* client type field for pex */
1104};
1105.DE
1106The \fIph_id\fP field is used to hold a ``unique id'' that
1107is used in duplicate suppression; the \fIph_client\fP
1108field indicates the PEX client type (similar to the packet
1109type field in the IDP header). PEX reliability stems from the
1110fact that it is an idempotent (``I send a packet to you, you
1111send a packet to me'') protocol. Processes on each side of
1112the connection may use the unique id to determine if they have
1113seen a given packet before (the unique id field differs on each
1114packet sent) so that duplicates may be detected, and to indicate
1115which message a given packet is in response to. If a packet with
1116a given unique id is sent and no response is received in a given
1117amount of time, the packet is retransmitted until it is decided
1118that no response will ever be received. To simulate PEX, one
1119must be able to generate unique ids -- something that is hard to
1120do at the user level with any real guarantee that the id is really
1121unique. Therefore, a means (via \fIgetsockopt\fP) has been provided
1122for getting unique ids from the kernel. The following code fragment
1123indicates how to get a unique id:
1124.DS
1125long uniqueid;
1126int s, idsize = sizeof(uniqueid);
1127 ...
1128s = socket(AF_NS, SOCK_DGRAM, 0);
1129 ...
1130/* get id from the kernel -- only on IDP sockets */
1131getsockopt(s, NSPROTO_PE, SO_SEQNO, (char *)&uniqueid, &idsize);
1132 ...
1133.DE
1134The retransmission and duplicate suppression code required to
1135simulate PEX fully is left as an exercise for the reader.
1136.NH 2
d60e8dff
MK
1137Inetd
1138.PP
1139One of the daemons provided with 4.3BSD is \fIinetd\fP, the
1140so called ``internet super-server.'' \fIInetd\fP is invoked at boot
1141time, and determines from the file \fI/etc/inetd.conf\fP the
1142servers for which it is to listen. Once this information has been
1143read and a pristine environment created, \fIinetd\fP proceeds
1144to create one socket for each service it is to listen for,
1145binding the appropriate port number to each socket.
1146.PP
1147\fIInetd\fP then performs a \fIselect\fP on all these
1148sockets for read availability, waiting for somebody wishing
1149a connection to the service corresponding to
1150that socket. \fIInetd\fP then performs an \fIaccept\fP on
1151the socket in question, \fIfork\fPs, \fIdup\fPs the new
1152socket to file descriptors 0 and 1 (stdin and
1153stdout), closes other open file
1154descriptors, and \fIexec\fPs the appropriate server.
1155.PP
1156Servers making use of \fIinetd\fP are considerably simplified,
1157as \fIinetd\fP takes care of the majority of the IPC work
1158required in establishing a connection. The server invoked
1159by \fIinetd\fP expects the socket connected to its client
1160on file descriptors 0 and 1, and may immediately perform
1161any operations such as \fIread\fP, \fIwrite\fP, \fIsend\fP,
1162or \fIrecv\fP. Indeed, servers may use
6d89475b 1163buffered I/O as provided by the ``stdio'' conventions, as
d60e8dff
MK
1164long as as they remember to use \fIfflush\fP when appropriate.
1165.PP
1166One call which may be of interest to individuals writing
1167servers under \fIinetd\fP is the \fIgetpeername\fP call,
1168which returns the address of the peer (process) connected
1169on the other end of the socket. For example, to log the
1170Internet address in ``dot notation'' (e.g., ``128.32.0.4'')
1171of a client connected to a server under
1172\fIinetd\fP, the following code might be used:
1173.DS
1174struct sockaddr_in name;
1175int namelen = sizeof (name);
1176 ...
1177if (getpeername(0, (struct sockaddr *)&name, &namelen) < 0) {
1178 syslog(LOG_ERR, "getpeername: %m");
1179 exit(1);
1180} else
1181 syslog(LOG_INFO, "Connection from %s", inet_ntoa(name.sin_addr));
1182 ...
1183.DE
1184While the \fIgetpeername\fP call is especially useful when
1185writing programs to run with \fIinetd\fP, it can be used
6d89475b
MK
1186under other circumstances. Be warned, however, that \fIgetpeername\fP will
1187fail on UNIX domain sockets.