xref: /illumos-gate/usr/src/man/man4p/tcp.4p (revision 1edba515)
1.\"
2.\" This file and its contents are supplied under the terms of the
3.\" Common Development and Distribution License ("CDDL"), version 1.0.
4.\" You may only use this file in accordance with the terms of version
5.\" 1.0 of the CDDL.
6.\"
7.\" A full copy of the text of the CDDL should have accompanied this
8.\" source.  A copy of the CDDL is also available via the Internet at
9.\" http://www.illumos.org/license/CDDL.
10.\"
11.\"
12.\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved.
13.\" Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
14.\" Copyright 2019 Joyent, Inc.
15.\" Copyright 2024 Oxide Computer Company
16.\" Copyright 1989 AT&T
17.\"
18.Dd April 17, 2024
19.Dt TCP 4P
20.Os
21.Sh NAME
22.Nm tcp ,
23.Nm TCP
24.Nd Internet Transmission Control Protocol
25.Sh SYNOPSIS
26.In sys/socket.h
27.In netinet/in.h
28.In netinet/tcp.h
29.Bd -literal
30s = socket(AF_INET, SOCK_STREAM, 0);
31s = socket(AF_INET6, SOCK_STREAM, 0);
32t = t_open("/dev/tcp", O_RDWR);
33t = t_open("/dev/tcp6", O_RDWR);
34.Ed
35.Sh DESCRIPTION
36TCP is the virtual circuit protocol of the Internet protocol family.
37It provides reliable, flow-controlled, in-order, two-way transmission of data.
38It is a byte-stream protocol layered above the Internet Protocol
39.Pq Sy IP ,
40or the Internet Protocol Version 6
41.Pq Sy IPv6 ,
42the Internet protocol family's
43internetwork datagram delivery protocol.
44.Pp
45Programs can access TCP using the socket interface as a
46.Dv SOCK_STREAM
47socket type, or using the Transport Level Interface
48.Pq Sy TLI
49where it supports the connection-oriented
50.Pq Dv BT_COTS_ORD
51service type.
52.Pp
53A checksum over all data helps TCP provide reliable communication.
54Using a window-based flow control mechanism that makes use of positive
55acknowledgements, sequence numbers, and a retransmission strategy, TCP can
56usually recover when datagrams are damaged, delayed, duplicated or delivered
57out of order by the underlying medium.
58.Pp
59TCP provides several socket options, defined in
60.In netinet/tcp.h
61and described throughout this document,
62which may be set using
63.Xr setsockopt 3SOCKET
64and read using
65.Xr getsockopt 3SOCKET .
66The
67.Fa level
68argument for these calls is the protocol number for TCP, available from
69.Xr getprotobyname 3SOCKET .
70IP level options may also be used with TCP.
71See
72.Xr ip 4P
73and
74.Xr ip6 4P .
75.Ss "Listening And Connecting"
76TCP uses IP's host-level addressing and adds its own per-host
77collection of
78.Dq port addresses .
79The endpoints of a TCP connection are
80identified by the combination of an IPv4 or IPv6 address and a TCP
81port number.
82Although other protocols, such as the User Datagram Protocol
83.Pq Sy UDP ,
84may use the same host and port address format, the port space of these
85protocols is distinct.
86See
87.Xr inet 4P
88and
89.Xr inet6 4P
90for details on
91the common aspects of addressing in the Internet protocol family.
92.Pp
93Sockets utilizing TCP are either
94.Dq active
95or
96.Dq passive .
97Active sockets
98initiate connections to passive sockets.
99Passive sockets must have their local IPv4 or IPv6 address and TCP port number
100bound with the
101.Xr bind 3SOCKET
102system call after the socket is created.
103If an active socket has not been bound by the time
104.Xr connect 3SOCKET
105is called, then the operating system will choose a local address and port for
106the application.
107By default, TCP sockets are active.
108A passive socket is created by calling the
109.Xr listen 3SOCKET
110system call after binding, which establishes a queueing parameter for the
111passive socket.
112Connections to the passive socket can then be received using the
113.Xr accept 3SOCKET
114system call.
115Active sockets use the
116.Xr connect 3SOCKET
117call after binding to initiate connections.
118.Pp
119If incoming connection requests include an IP source route option, then the
120reverse source route will be used when responding.
121.Pp
122By using the special value
123.Dv INADDR_ANY
124with IPv4, or the unspecified
125address
126.Pq all zeroes
127with IPv6, the local IP address can be left unspecified in the
128.Fn bind
129call by either active or passive TCP
130sockets.
131This feature is usually used if the local address is either unknown or
132irrelevant.
133If left unspecified, the local IP address will be bound at connection time to
134the address of the network interface used to service the connection.
135For passive sockets, this is the destination address used by the connecting
136peer.
137For active sockets, this is usually an address on the same subnet as the
138destination or default gateway address, although the rules can be more complex.
139See
140.Sy "Source Address Selection"
141in
142.Xr inet6 4P
143for a detailed discussion of how this works in IPv6.
144.Pp
145Note that no two TCP sockets can be bound to the same port unless the bound IP
146addresses are different.
147IPv4
148.Dv INADDR_ANY
149and IPv6 unspecified addresses compare as equal to any IPv4 or IPv6 address.
150For example, if a socket is bound to
151.Dv INADDR_ANY
152or the unspecified address and port
153.Em N ,
154no other socket can bind to port
155.Em N ,
156regardless of the binding address.
157This special consideration of
158.Dv INADDR_ANY
159and the unspecified address can be changed using the socket option
160.Dv SO_REUSEADDR .
161If
162.Dv SO_REUSEADDR
163is set on a socket doing a bind, IPv4
164.Dv INADDR_ANY
165and the IPv6 unspecified address do not compare as equal to any IP address.
166This means that as long as the two sockets are not both bound to
167.Dv INADDR_ANY ,
168the unspecified address, or the same IP address, then the two sockets can be
169bound to the same port.
170.Pp
171If an application does not want to allow another socket using the
172.Dv SO_REUSEADDR
173option to bind to a port its socket is bound to, the
174application can set the socket-level
175.Pq Dv SOL_SOCKET
176option
177.Dv SO_EXCLBIND
178on a socket.
179The
180option values of 0 and 1 mean enabling and disabling the option respectively.
181Once this option is enabled on a socket, no other socket can be bound to the
182same port.
183.Ss "Sending And Receiving Data"
184Once a connection has been established, data can be exchanged using the
185.Xr read 2
186and
187.Xr write 2
188system calls.
189If, after sending data, the local TCP receives no acknowledgements from its
190peer for a period of time
191.Pq for example, if the remote machine crashes ,
192the connection is closed and an error is returned.
193.Pp
194When a peer is sending data, it will only send up to the advertised
195.Dq receive window ,
196which is determined by how much more data the recipient can fit in its buffer.
197Applications can use the socket-level option
198.Dv SO_RCVBUF
199to increase or decrease the receive buffer size.
200Similarly, the socket-level option
201.Dv SO_SNDBUF
202can be used to allow TCP to buffer more unacknowledged and unsent data locally.
203.Pp
204Under most circumstances, TCP will send data when it is written by the
205application.
206When outstanding data has not yet been acknowledged, though, TCP will gather
207small amounts of output to be sent as a single packet once an acknowledgement
208has been received.
209Usually referred to as Nagle's Algorithm
210.Pq RFC 896 ,
211this behavior helps prevent flooding the network with many small packets.
212.Pp
213However, for some highly interactive clients
214.Po
215such as remote shells or windowing systems that send a stream of keypresses or
216mouse events
217.Pc ,
218this
219batching may cause significant delays.
220To disable this behavior, TCP provides a boolean socket option,
221.Dv TCP_NODELAY .
222.Pp
223Conversely, for other applications, it may be desirable for TCP not to send out
224any data until a full TCP segment can be sent.
225To enable this behavior, an application can use the TCP-level socket option
226.Dv TCP_CORK .
227When set to a non-zero value, TCP will only send out a full TCP segment.
228When
229.Dv TCP_CORK
230is set to zero after it has been enabled, all currently buffered data is sent
231out
232.Po
233as permitted by the peer's receive window and the current congestion window
234.Pc .
235.Pp
236Still other latency-sensitive applications rely on receiving a quick
237notification that their packets have been successfully received.
238To satisfy the requirements of those applications, setting the
239.Dv TCP_QUICKACK
240option to a non-zero value will instruct the TCP stack to send an acknowledgment
241immediately upon receipt of a packet, rather than waiting to acknowledge
242multiple packets at once.
243.Pp
244TCP provides an urgent data mechanism, which may be invoked using the
245out-of-band provisions of
246.Xr send 3SOCKET .
247The caller may mark one byte as
248.Dq urgent
249with the
250.Dv MSG_OOB
251flag to
252.Xr send 3SOCKET .
253This sets an
254.Dq urgent pointer
255pointing to this byte in the TCP stream.
256The receiver on the other side of the stream is notified of the urgent data by a
257.Dv SIGURG
258signal.
259The
260.Dv SIOCATMARK
261.Xr ioctl 2
262request returns a value indicating whether the stream is at the urgent mark.
263Because the system never returns data across the urgent mark in a single
264.Xr read 2
265call, it is possible to
266advance to the urgent data in a simple loop which reads data, testing the
267socket with the
268.Dv SIOCATMARK
269.Fn ioctl
270request, until it reaches the mark.
271.Pp
272The
273.Dv TCP_MD5SIG
274option controls the use of MD5 digests
275.Pq as defined by RFC 2385
276on the specified socket.
277The option value is specified as an
278.Vt int .
279When enabled
280.Pq non-zero ,
281outgoing packets have a digest added to the included TCP options and digests in
282incoming packets are verified.
283Incoming packets without a digest, or without a correct digest value, are
284silently dropped.
285In order to use this function, TCPSIG security associations
286.Pq one for each direction
287must also be configured in the system security association database
288.Pq SADB
289using
290.Xr tcpkey 8 .
291If no matching security association
292.Pq SA
293is found for traffic on a socket configured with the
294.Dv TCP_MD5SIG
295option, no outgoing segments are sent, and all inbound segments are dropped.
296In particular, the SA must be present prior to the socket being used in a
297call to
298.Xr connect 3SOCKET
299or
300.Xr accept 3SOCKET .
301Once the option is enabled and an SA is bound to a connection, it will be
302cached and used for all subsequent segments; it cannot be changed mid-stream.
303An SA which is in use can be deleted using
304.Xr tcpkey 8
305and will not be used for any new connections, but existing connections continue
306to use their cached copy.
307.Ss "Congestion Control"
308TCP follows the congestion control algorithm described in RFC 2581, and
309also supports the initial congestion window
310.Pq cwnd
311changes in RFC 3390.
312The initial cwnd calculation can be overridden by the socket option
313.Dv TCP_INIT_CWND .
314An application can use this option to set the initial cwnd to a
315specified number of TCP segments.
316This applies to the cases when the connection
317first starts and restarts after an idle period.
318The process must have the
319.Dv PRIV_SYS_NET_CONFIG
320privilege if it wants to specify a number greater than that
321calculated by RFC 3390.
322.Pp
323The operating system also provides alternative algorithms that may be more
324appropriate for your application, including the CUBIC congestion control
325algorithm described in RFC 8312.
326These can be configured system-wide using
327.Xr ipadm 8 ,
328or on a per-connection basis with the TCP-level socket option
329.Dv TCP_CONGESTION ,
330whose argument is the name of the algorithm to use
331.Pq for example Dq cubic .
332If the requested algorithm does not exist, then
333.Fn setsockopt
334will fail, and
335.Va errno
336will be set to
337.Er ENOENT .
338.Ss "TCP Keep-Alive"
339Since TCP determines whether a remote peer is no longer reachable by timing out
340waiting for acknowledgements, a host that never sends any new data may never
341notice a peer that has gone away.
342While consumers can avoid this problem by sending their own periodic heartbeat
343messages
344.Pq Transport Layer Security does this, for example,
345TCP describes an optional keep-alive mechanism in RFC 1122.
346Applications can enable it using the socket-level option
347.Dv SO_KEEPALIVE .
348When enabled, the first keep-alive probe is sent out after a TCP connection is
349idle for two hours.
350If the peer does not respond to the probe within eight minutes, the TCP
351connection is aborted.
352An application can alter the probe behavior using the following TCP-level
353socket options:
354.Bl -tag -offset indent -width 16m
355.It Dv TCP_KEEPALIVE_THRESHOLD
356Determines the interval for sending the first probe.
357The option value is specified as an unsigned integer in milliseconds.
358The system default is controlled by the TCP
359.Nm ndd
360parameter
361.Cm tcp_keepalive_interval .
362The minimum value is ten seconds.
363The maximum is ten days, while the default is two hours.
364.It Dv TCP_KEEPALIVE_ABORT_THRESHOLD
365If TCP does not receive a response to the probe, then this option determines
366how long to wait before aborting a TCP connection.
367The option value is an unsigned integer in milliseconds.
368The value zero indicates that TCP should never time
369out and abort the connection when probing.
370The system default is controlled by the TCP
371.Nm ndd
372parameter
373.Sy tcp_keepalive_abort_interval .
374The default is eight minutes.
375.It Dv TCP_KEEPIDLE
376This option, like
377.Dv TCP_KEEPALIVE_THRESHOLD ,
378determines the interval for sending the first probe, except that
379the option value is an unsigned integer in
380.Sy seconds .
381It is provided primarily for compatibility with other Unix flavors.
382.It Dv TCP_KEEPCNT
383This option specifies the number of keep-alive probes that should be sent
384without any response from the peer before aborting the connection.
385.It Dv TCP_KEEPINTVL
386This option specifies the interval in seconds between successive,
387unacknowledged keep-alive probes.
388.El
389.Ss "Additional Configuration"
390illumos supports TCP Extensions for High Performance
391.Pq RFC 7323
392which includes the window scale and timestamp options, and Protection Against
393Wrap Around Sequence Numbers
394.Pq Sy PAWS .
395Note that if timestamps are negotiated on
396a connection, received segments without timestamps on that connection are
397silently dropped per the suggestion in the RFC. illumos also supports Selective
398Acknowledgment
399.Pq Sy SACK
400capabilities
401.Pq RFC 2018
402and Explicit Congestion Notification
403.Pq Sy ECN
404mechanism
405.Pq RFC 3168 .
406.Pp
407Turn on the window scale option in one of the following ways:
408.Bl -bullet -offset indent -width 4m
409.It
410An application can set
411.Dv SO_SNDBUF
412or
413.Dv SO_RCVBUF
414size in the
415.Fn setsockopt
416option to be larger than 64K.
417This must be done
418.Em before
419the program calls
420.Fn listen
421or
422.Fn connect ,
423because the window scale
424option is negotiated when the connection is established.
425Once the connection
426has been made, it is too late to increase the send or receive window beyond the
427default TCP limit of 64K.
428.It
429For all applications, use
430.Xr ndd 8
431to modify the configuration parameter
432.Cm tcp_wscale_always .
433If
434.Cm tcp_wscale_always
435is set to
436.Sy 1 ,
437the
438window scale option will always be set when connecting to a remote system.
439If
440.Cm tcp_wscale_always
441is
442.Sy 0 ,
443the window scale option will be set only if
444the user has requested a send or receive window larger than 64K.
445The default value of
446.Cm tcp_wscale_always
447is
448.Sy 1 .
449.It
450Regardless of the value of
451.Cm tcp_wscale_always ,
452the window scale option
453will always be included in a connect acknowledgement if the connecting system
454has used the option.
455.El
456.Pp
457Turn on SACK capabilities in the following way:
458.Bl -bullet -offset indent -width 4m
459.It
460Use
461.Nm ndd
462to modify the configuration parameter
463.Cm tcp_sack_permitted .
464If
465.Cm tcp_sack_permitted
466is set to
467.Sy 0 ,
468TCP will not accept SACK or send out SACK information.
469If
470.Cm tcp_sack_permitted
471is
472set to
473.Sy 1 ,
474TCP will not initiate a connection with SACK permitted option in the
475.Sy SYN
476segment, but will respond with SACK permitted option in the
477.Sy SYN|ACK
478segment if an incoming connection request has the SACK permitted option.
479This means that TCP will only accept SACK information if the other side of the
480connection also accepts SACK information.
481If
482.Cm tcp_sack_permitted
483is set to
484.Sy 2 ,
485it will both initiate and accept connections with SACK information.
486The default for
487.Cm tcp_sack_permitted
488is
489.Sy 2
490.Pq active enabled .
491.El
492.Pp
493Turn on the TCP ECN mechanism in the following way:
494.Bl -bullet -offset indent -width 4m
495.It
496Use
497.Nm ndd
498to modify the configuration parameter
499.Cm tcp_ecn_permitted .
500If
501.Cm tcp_ecn_permitted
502is set to
503.Sy 0 ,
504then TCP will not negotiate with a peer that supports ECN mechanism.
505If
506.Cm tcp_ecn_permitted
507is set to
508.Sy 1
509when initiating a connection, TCP will not tell a peer that it supports
510.Sy ECN
511mechanism.
512However, it will tell a peer that it supports
513.Sy ECN
514mechanism when accepting a new incoming connection request if the peer
515indicates that it supports
516.Sy ECN
517mechanism in the
518.Sy SYN
519segment.
520If
521.Cm tcp_ecn_permitted
522is set to 2, in addition to negotiating with a peer on
523.Sy ECN
524mechanism when accepting connections, TCP will indicate in the outgoing
525.Sy SYN
526segment that it supports
527.Sy ECN
528mechanism when TCP makes active outgoing connections.
529The default for
530.Cm tcp_ecn_permitted
531is 1.
532.El
533.Pp
534Turn on the timestamp option in the following way:
535.Bl -bullet -offset indent -width 4m
536.It
537Use
538.Nm ndd
539to modify the configuration parameter
540.Cm tcp_tstamp_always .
541If
542.Cm tcp_tstamp_always
543is
544.Sy 1 ,
545the timestamp option will always be set
546when connecting to a remote machine.
547If
548.Cm tcp_tstamp_always
549is
550.Sy 0 ,
551the timestamp option will not be set when connecting to a remote system.
552The
553default for
554.Cm tcp_tstamp_always
555is
556.Sy 0 .
557.It
558Regardless of the value of
559.Cm tcp_tstamp_always ,
560the timestamp option will
561always be included in a connect acknowledgement
562.Pq and all succeeding packets
563if the connecting system has used the timestamp option.
564.El
565.Pp
566Use the following procedure to turn on the timestamp option only when the
567window scale option is in effect:
568.Bl -bullet -offset indent -width 4m
569.It
570Use
571.Nm ndd
572to modify the configuration parameter
573.Cm tcp_tstamp_if_wscale .
574Setting
575.Cm tcp_tstamp_if_wscale
576to
577.Sy 1
578will cause the timestamp option
579to be set when connecting to a remote system, if the window scale option has
580been set.
581If
582.Cm tcp_tstamp_if_wscale
583is
584.Sy 0 ,
585the timestamp option will
586not be set when connecting to a remote system.
587The default for
588.Cm tcp_tstamp_if_wscale
589is
590.Sy 1 .
591.El
592.Pp
593Protection Against Wrap Around Sequence Numbers
594.Pq Sy PAWS
595is always used when the
596timestamp option is set.
597.Pp
598The operating system also supports multiple methods of generating initial sequence numbers.
599One of these methods is the improved technique suggested in RFC 1948.
600We
601.Em HIGHLY
602recommend that you set sequence number generation parameters as
603close to boot time as possible.
604This prevents sequence number problems on
605connections that use the same connection-ID as ones that used a different
606sequence number generation.
607The
608.Sy svc:/network/initial:default
609service configures the initial sequence number generation.
610The service reads the value contained in the configuration file
611.Pa /etc/default/inetinit
612to determine which method to use.
613.Pp
614The
615.Pa /etc/default/inetinit
616file is an unstable interface, and may change in future releases.
617.Sh EXAMPLES
618.Ss Example 1: Connecting to a server
619.Bd -literal
620$ gcc -std=c99 -Wall -lsocket -o client client.c
621$ cat client.c
622#include <sys/socket.h>
623#include <netinet/in.h>
624#include <netinet/tcp.h>
625#include <netdb.h>
626#include <stdio.h>
627#include <string.h>
628#include <unistd.h>
629
630int
631main(int argc, char *argv[])
632{
633	struct addrinfo hints, *gair, *p;
634	int fd, rv, rlen;
635	char buf[1024];
636	int y = 1;
637
638	if (argc != 3) {
639		fprintf(stderr, "%s <host> <port>\en", argv[0]);
640		return (1);
641	}
642
643	memset(&hints, 0, sizeof (hints));
644	hints.ai_family = PF_UNSPEC;
645	hints.ai_socktype = SOCK_STREAM;
646
647	if ((rv = getaddrinfo(argv[1], argv[2], &hints, &gair)) != 0) {
648		fprintf(stderr, "getaddrinfo() failed: %s\en",
649		    gai_strerror(rv));
650		return (1);
651	}
652
653	for (p = gair; p != NULL; p = p->ai_next) {
654		if ((fd = socket(
655		    p->ai_family,
656		    p->ai_socktype,
657		    p->ai_protocol)) == -1) {
658			perror("socket() failed");
659			continue;
660		}
661
662		if (connect(fd, p->ai_addr, p->ai_addrlen) == -1) {
663			close(fd);
664			perror("connect() failed");
665			continue;
666		}
667
668		break;
669	}
670
671	if (p == NULL) {
672		fprintf(stderr, "failed to connect to server\en");
673		return (1);
674	}
675
676	freeaddrinfo(gair);
677
678	if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &y,
679	    sizeof (y)) == -1) {
680		perror("setsockopt(SO_KEEPALIVE) failed");
681		return (1);
682	}
683
684	while ((rlen = read(fd, buf, sizeof (buf))) > 0) {
685		fwrite(buf, rlen, 1, stdout);
686	}
687
688	if (rlen == -1) {
689		perror("read() failed");
690	}
691
692	fflush(stdout);
693
694	if (close(fd) == -1) {
695		perror("close() failed");
696	}
697
698	return (0);
699}
700$ ./client 127.0.0.1 8080
701hello
702$ ./client ::1 8080
703hello
704.Ed
705.Ss Example 2: Accepting client connections
706.Bd -literal
707$ gcc -std=c99 -Wall -lsocket -o server server.c
708$ cat server.c
709#include <sys/socket.h>
710#include <netinet/in.h>
711#include <netinet/tcp.h>
712#include <netdb.h>
713#include <stdio.h>
714#include <string.h>
715#include <unistd.h>
716#include <arpa/inet.h>
717
718void
719logmsg(struct sockaddr *s, int bytes)
720{
721	char dq[INET6_ADDRSTRLEN];
722
723	switch (s->sa_family) {
724	case AF_INET: {
725		struct sockaddr_in *s4 = (struct sockaddr_in *)s;
726		inet_ntop(AF_INET, &s4->sin_addr, dq, sizeof (dq));
727		fprintf(stdout, "sent %d bytes to %s:%d\en",
728		    bytes, dq, ntohs(s4->sin_port));
729		break;
730	}
731	case AF_INET6: {
732		struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)s;
733		inet_ntop(AF_INET6, &s6->sin6_addr, dq, sizeof (dq));
734		fprintf(stdout, "sent %d bytes to [%s]:%d\en",
735		    bytes, dq, ntohs(s6->sin6_port));
736		break;
737	}
738	default:
739		fprintf(stdout, "sent %d bytes to unknown client\en",
740		    bytes);
741		break;
742	}
743}
744
745int
746main(int argc, char *argv[])
747{
748	struct addrinfo hints, *gair, *p;
749	int sfd, cfd;
750	int slen, wlen, rv;
751
752	if (argc != 3) {
753		fprintf(stderr, "%s <port> <message>\en", argv[0]);
754		return (1);
755	}
756
757	slen = strlen(argv[2]);
758
759	memset(&hints, 0, sizeof (hints));
760	hints.ai_family = PF_UNSPEC;
761	hints.ai_socktype = SOCK_STREAM;
762	hints.ai_flags = AI_PASSIVE;
763
764	if ((rv = getaddrinfo(NULL, argv[1], &hints, &gair)) != 0) {
765		fprintf(stderr, "getaddrinfo() failed: %s\en",
766		    gai_strerror(rv));
767		return (1);
768	}
769
770	for (p = gair; p != NULL; p = p->ai_next) {
771		if ((sfd = socket(
772		    p->ai_family,
773		    p->ai_socktype,
774		    p->ai_protocol)) == -1) {
775			perror("socket() failed");
776			continue;
777		}
778
779		if (bind(sfd, p->ai_addr, p->ai_addrlen) == -1) {
780			close(sfd);
781			perror("bind() failed");
782			continue;
783		}
784
785		break;
786	}
787
788	if (p == NULL) {
789		fprintf(stderr, "server failed to bind()\en");
790		return (1);
791	}
792
793	freeaddrinfo(gair);
794
795	if (listen(sfd, 1024) != 0) {
796		perror("listen() failed");
797		return (1);
798	}
799
800	fprintf(stdout, "waiting for clients...\en");
801
802	for (int times = 0; times < 5; times++) {
803		struct sockaddr_storage stor;
804		socklen_t alen = sizeof (stor);
805		struct sockaddr *addr = (struct sockaddr *)&stor;
806
807		if ((cfd = accept(sfd, addr, &alen)) == -1) {
808			perror("accept() failed");
809			continue;
810		}
811
812		wlen = 0;
813
814		do {
815			wlen += write(cfd, argv[2] + wlen, slen - wlen);
816		} while (wlen < slen);
817
818		logmsg(addr, wlen);
819
820		if (close(cfd) == -1) {
821			perror("close(cfd) failed");
822		}
823	}
824
825	if (close(sfd) == -1) {
826		perror("close(sfd) failed");
827	}
828
829	fprintf(stdout, "finished.\en");
830
831	return (0);
832}
833$ ./server 8080 $'hello\en'
834waiting for clients...
835sent 6 bytes to [::ffff:127.0.0.1]:59059
836sent 6 bytes to [::ffff:127.0.0.1]:47448
837sent 6 bytes to [::ffff:127.0.0.1]:54949
838sent 6 bytes to [::ffff:127.0.0.1]:55186
839sent 6 bytes to [::1]:62256
840finished.
841.Ed
842.Sh DIAGNOSTICS
843A socket operation may fail if:
844.Bl -tag -offset indent -width 16m
845.It Er EISCONN
846A
847.Fn connect
848operation was attempted on a socket on which a
849.Fn connect
850operation had already been performed.
851.It Er ETIMEDOUT
852A connection was dropped due to excessive retransmissions.
853.It Er ECONNRESET
854The remote peer forced the connection to be closed (usually because the remote
855machine has lost state information about the connection due to a crash).
856.It Er ECONNREFUSED
857The remote peer actively refused connection establishment (usually because no
858process is listening to the port).
859.It Er EADDRINUSE
860A
861.Fn bind
862operation was attempted on a socket with a network address/port pair that has
863already been bound to another socket.
864.It Er EADDRNOTAVAIL
865A
866.Fn bind
867operation was attempted on a socket with a network address for which no network
868interface exists.
869.It Er EACCES
870A
871.Fn bind
872operation was attempted with a
873.Dq reserved
874port number and the effective user ID of the process was not the privileged
875user.
876.It Er ENOBUFS
877The system ran out of memory for internal data structures.
878.El
879.Sh SEE ALSO
880.Xr svcs 1 ,
881.Xr ioctl 2 ,
882.Xr read 2 ,
883.Xr write 2 ,
884.Xr accept 3SOCKET ,
885.Xr bind 3SOCKET ,
886.Xr connect 3SOCKET ,
887.Xr getprotobyname 3SOCKET ,
888.Xr getsockopt 3SOCKET ,
889.Xr listen 3SOCKET ,
890.Xr send 3SOCKET ,
891.Xr inet 4P ,
892.Xr inet6 4P ,
893.Xr ip 4P ,
894.Xr ip6 4P ,
895.Xr smf 7 ,
896.Xr ndd 8 ,
897.Xr svcadm 8 ,
898.Xr tcpkey 8
899.Rs
900.%A "K. Ramakrishnan"
901.%A "S. Floyd"
902.%A "D. Black"
903.%T "The Addition of Explicit Congestion Notification (ECN) to IP"
904.%R "RFC 3168"
905.%D "September 2001"
906.Re
907.Rs
908.%A "M. Mathias"
909.%A "J. Mahdavi"
910.%A "S. Ford"
911.%A "A. Romanow"
912.%T "TCP Selective Acknowledgement Options"
913.%R "RFC 2018"
914.%D "October 1996"
915.Re
916.Rs
917.%A "S. Bellovin"
918.%T "Defending Against Sequence Number Attacks"
919.%R "RFC 1948"
920.%D "May 1996"
921.Re
922.Rs
923.%A "D. Borman"
924.%A "B. Braden"
925.%A "V. Jacobson"
926.%A "R. Scheffenegger, Ed."
927.%T "TCP Extensions for High Performance"
928.%R "RFC 7323"
929.%D "September 2014"
930.Re
931.Rs
932.%A "Jon Postel"
933.%T "Transmission Control Protocol - DARPA Internet Program Protocol Specification"
934.%R "RFC 793"
935.%C "Network Information Center, SRI International, Menlo Park, CA."
936.%D "September 1981"
937.Re
938.Rs
939.%A "A. Heffernan"
940.%T "Protection of BGP Sessions via the TCP MD5 Signature Option"
941.%R "RFC 2385"
942.%D "August 1998"
943.Re
944.Sh NOTES
945The
946.Sy tcp
947service is managed by the service management facility,
948.Xr smf 7 ,
949under the service identifier
950.Sy svc:/network/initial:default .
951.Pp
952Administrative actions on this service, such as enabling, disabling, or
953requesting restart, can be performed using
954.Xr svcadm 8 .
955The service's
956status can be queried using the
957.Xr svcs 1
958command.
959