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 May 2, 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 TCP options in their header, and 282digests in incoming packets are verified. 283In order to use this function, TCPSIG security associations 284.Pq one for each direction 285must also be configured in the system security association database 286.Pq SADB 287using 288.Xr tcpkey 8 . 289A listening socket with the option enabled accepts connections with digests 290only from sources for which a security association exists. 291Connections without digests are only accepted from sources for which no 292security association is set up. 293The resulting connected socket only has TCP_MD5SIG set if the connection is 294protected with MD5 signatures. 295If no matching security association 296.Pq SA 297is found for traffic on a socket configured with the 298.Dv TCP_MD5SIG 299option, no outgoing segments are sent, and all inbound segments are dropped. 300In particular, the SA must be present prior to the socket being used in a 301call to 302.Xr connect 3SOCKET 303or 304.Xr accept 3SOCKET . 305Once the option is enabled and an SA is bound to a connection, it will be 306cached and used for all subsequent segments; it cannot be changed mid-stream. 307An SA which is in use can be deleted using 308.Xr tcpkey 8 309and will not be used for any new connections, but existing connections continue 310to use their cached copy. 311.Ss "Congestion Control" 312TCP follows the congestion control algorithm described in RFC 2581, and 313also supports the initial congestion window 314.Pq cwnd 315changes in RFC 3390. 316The initial cwnd calculation can be overridden by the socket option 317.Dv TCP_INIT_CWND . 318An application can use this option to set the initial cwnd to a 319specified number of TCP segments. 320This applies to the cases when the connection 321first starts and restarts after an idle period. 322The process must have the 323.Dv PRIV_SYS_NET_CONFIG 324privilege if it wants to specify a number greater than that 325calculated by RFC 3390. 326.Pp 327The operating system also provides alternative algorithms that may be more 328appropriate for your application, including the CUBIC congestion control 329algorithm described in RFC 8312. 330These can be configured system-wide using 331.Xr ipadm 8 , 332or on a per-connection basis with the TCP-level socket option 333.Dv TCP_CONGESTION , 334whose argument is the name of the algorithm to use 335.Pq for example Dq cubic . 336If the requested algorithm does not exist, then 337.Fn setsockopt 338will fail, and 339.Va errno 340will be set to 341.Er ENOENT . 342.Ss "TCP Keep-Alive" 343Since TCP determines whether a remote peer is no longer reachable by timing out 344waiting for acknowledgements, a host that never sends any new data may never 345notice a peer that has gone away. 346While consumers can avoid this problem by sending their own periodic heartbeat 347messages 348.Pq Transport Layer Security does this, for example, 349TCP describes an optional keep-alive mechanism in RFC 1122. 350Applications can enable it using the socket-level option 351.Dv SO_KEEPALIVE . 352When enabled, the first keep-alive probe is sent out after a TCP connection is 353idle for two hours. 354If the peer does not respond to the probe within eight minutes, the TCP 355connection is aborted. 356An application can alter the probe behavior using the following TCP-level 357socket options: 358.Bl -tag -offset indent -width 16m 359.It Dv TCP_KEEPALIVE_THRESHOLD 360Determines the interval for sending the first probe. 361The option value is specified as an unsigned integer in milliseconds. 362The system default is controlled by the TCP 363.Nm ndd 364parameter 365.Cm tcp_keepalive_interval . 366The minimum value is ten seconds. 367The maximum is ten days, while the default is two hours. 368.It Dv TCP_KEEPALIVE_ABORT_THRESHOLD 369If TCP does not receive a response to the probe, then this option determines 370how long to wait before aborting a TCP connection. 371The option value is an unsigned integer in milliseconds. 372The value zero indicates that TCP should never time 373out and abort the connection when probing. 374The system default is controlled by the TCP 375.Nm ndd 376parameter 377.Sy tcp_keepalive_abort_interval . 378The default is eight minutes. 379.It Dv TCP_KEEPIDLE 380This option, like 381.Dv TCP_KEEPALIVE_THRESHOLD , 382determines the interval for sending the first probe, except that 383the option value is an unsigned integer in 384.Sy seconds . 385It is provided primarily for compatibility with other Unix flavors. 386.It Dv TCP_KEEPCNT 387This option specifies the number of keep-alive probes that should be sent 388without any response from the peer before aborting the connection. 389.It Dv TCP_KEEPINTVL 390This option specifies the interval in seconds between successive, 391unacknowledged keep-alive probes. 392.El 393.Ss "Additional Configuration" 394illumos supports TCP Extensions for High Performance 395.Pq RFC 7323 396which includes the window scale and timestamp options, and Protection Against 397Wrap Around Sequence Numbers 398.Pq Sy PAWS . 399Note that if timestamps are negotiated on 400a connection, received segments without timestamps on that connection are 401silently dropped per the suggestion in the RFC. illumos also supports Selective 402Acknowledgment 403.Pq Sy SACK 404capabilities 405.Pq RFC 2018 406and Explicit Congestion Notification 407.Pq Sy ECN 408mechanism 409.Pq RFC 3168 . 410.Pp 411Turn on the window scale option in one of the following ways: 412.Bl -bullet -offset indent -width 4m 413.It 414An application can set 415.Dv SO_SNDBUF 416or 417.Dv SO_RCVBUF 418size in the 419.Fn setsockopt 420option to be larger than 64K. 421This must be done 422.Em before 423the program calls 424.Fn listen 425or 426.Fn connect , 427because the window scale 428option is negotiated when the connection is established. 429Once the connection 430has been made, it is too late to increase the send or receive window beyond the 431default TCP limit of 64K. 432.It 433For all applications, use 434.Xr ndd 8 435to modify the configuration parameter 436.Cm tcp_wscale_always . 437If 438.Cm tcp_wscale_always 439is set to 440.Sy 1 , 441the 442window scale option will always be set when connecting to a remote system. 443If 444.Cm tcp_wscale_always 445is 446.Sy 0 , 447the window scale option will be set only if 448the user has requested a send or receive window larger than 64K. 449The default value of 450.Cm tcp_wscale_always 451is 452.Sy 1 . 453.It 454Regardless of the value of 455.Cm tcp_wscale_always , 456the window scale option 457will always be included in a connect acknowledgement if the connecting system 458has used the option. 459.El 460.Pp 461Turn on SACK capabilities in the following way: 462.Bl -bullet -offset indent -width 4m 463.It 464Use 465.Nm ndd 466to modify the configuration parameter 467.Cm tcp_sack_permitted . 468If 469.Cm tcp_sack_permitted 470is set to 471.Sy 0 , 472TCP will not accept SACK or send out SACK information. 473If 474.Cm tcp_sack_permitted 475is 476set to 477.Sy 1 , 478TCP will not initiate a connection with SACK permitted option in the 479.Sy SYN 480segment, but will respond with SACK permitted option in the 481.Sy SYN|ACK 482segment if an incoming connection request has the SACK permitted option. 483This means that TCP will only accept SACK information if the other side of the 484connection also accepts SACK information. 485If 486.Cm tcp_sack_permitted 487is set to 488.Sy 2 , 489it will both initiate and accept connections with SACK information. 490The default for 491.Cm tcp_sack_permitted 492is 493.Sy 2 494.Pq active enabled . 495.El 496.Pp 497Turn on the TCP ECN mechanism in the following way: 498.Bl -bullet -offset indent -width 4m 499.It 500Use 501.Nm ndd 502to modify the configuration parameter 503.Cm tcp_ecn_permitted . 504If 505.Cm tcp_ecn_permitted 506is set to 507.Sy 0 , 508then TCP will not negotiate with a peer that supports ECN mechanism. 509If 510.Cm tcp_ecn_permitted 511is set to 512.Sy 1 513when initiating a connection, TCP will not tell a peer that it supports 514.Sy ECN 515mechanism. 516However, it will tell a peer that it supports 517.Sy ECN 518mechanism when accepting a new incoming connection request if the peer 519indicates that it supports 520.Sy ECN 521mechanism in the 522.Sy SYN 523segment. 524If 525.Cm tcp_ecn_permitted 526is set to 2, in addition to negotiating with a peer on 527.Sy ECN 528mechanism when accepting connections, TCP will indicate in the outgoing 529.Sy SYN 530segment that it supports 531.Sy ECN 532mechanism when TCP makes active outgoing connections. 533The default for 534.Cm tcp_ecn_permitted 535is 1. 536.El 537.Pp 538Turn on the timestamp option in the following way: 539.Bl -bullet -offset indent -width 4m 540.It 541Use 542.Nm ndd 543to modify the configuration parameter 544.Cm tcp_tstamp_always . 545If 546.Cm tcp_tstamp_always 547is 548.Sy 1 , 549the timestamp option will always be set 550when connecting to a remote machine. 551If 552.Cm tcp_tstamp_always 553is 554.Sy 0 , 555the timestamp option will not be set when connecting to a remote system. 556The 557default for 558.Cm tcp_tstamp_always 559is 560.Sy 0 . 561.It 562Regardless of the value of 563.Cm tcp_tstamp_always , 564the timestamp option will 565always be included in a connect acknowledgement 566.Pq and all succeeding packets 567if the connecting system has used the timestamp option. 568.El 569.Pp 570Use the following procedure to turn on the timestamp option only when the 571window scale option is in effect: 572.Bl -bullet -offset indent -width 4m 573.It 574Use 575.Nm ndd 576to modify the configuration parameter 577.Cm tcp_tstamp_if_wscale . 578Setting 579.Cm tcp_tstamp_if_wscale 580to 581.Sy 1 582will cause the timestamp option 583to be set when connecting to a remote system, if the window scale option has 584been set. 585If 586.Cm tcp_tstamp_if_wscale 587is 588.Sy 0 , 589the timestamp option will 590not be set when connecting to a remote system. 591The default for 592.Cm tcp_tstamp_if_wscale 593is 594.Sy 1 . 595.El 596.Pp 597Protection Against Wrap Around Sequence Numbers 598.Pq Sy PAWS 599is always used when the 600timestamp option is set. 601.Pp 602The operating system also supports multiple methods of generating initial sequence numbers. 603One of these methods is the improved technique suggested in RFC 1948. 604We 605.Em HIGHLY 606recommend that you set sequence number generation parameters as 607close to boot time as possible. 608This prevents sequence number problems on 609connections that use the same connection-ID as ones that used a different 610sequence number generation. 611The 612.Sy svc:/network/initial:default 613service configures the initial sequence number generation. 614The service reads the value contained in the configuration file 615.Pa /etc/default/inetinit 616to determine which method to use. 617.Pp 618The 619.Pa /etc/default/inetinit 620file is an unstable interface, and may change in future releases. 621.Sh EXAMPLES 622.Ss Example 1: Connecting to a server 623.Bd -literal 624$ gcc -std=c99 -Wall -lsocket -o client client.c 625$ cat client.c 626#include <sys/socket.h> 627#include <netinet/in.h> 628#include <netinet/tcp.h> 629#include <netdb.h> 630#include <stdio.h> 631#include <string.h> 632#include <unistd.h> 633 634int 635main(int argc, char *argv[]) 636{ 637 struct addrinfo hints, *gair, *p; 638 int fd, rv, rlen; 639 char buf[1024]; 640 int y = 1; 641 642 if (argc != 3) { 643 fprintf(stderr, "%s <host> <port>\en", argv[0]); 644 return (1); 645 } 646 647 memset(&hints, 0, sizeof (hints)); 648 hints.ai_family = PF_UNSPEC; 649 hints.ai_socktype = SOCK_STREAM; 650 651 if ((rv = getaddrinfo(argv[1], argv[2], &hints, &gair)) != 0) { 652 fprintf(stderr, "getaddrinfo() failed: %s\en", 653 gai_strerror(rv)); 654 return (1); 655 } 656 657 for (p = gair; p != NULL; p = p->ai_next) { 658 if ((fd = socket( 659 p->ai_family, 660 p->ai_socktype, 661 p->ai_protocol)) == -1) { 662 perror("socket() failed"); 663 continue; 664 } 665 666 if (connect(fd, p->ai_addr, p->ai_addrlen) == -1) { 667 close(fd); 668 perror("connect() failed"); 669 continue; 670 } 671 672 break; 673 } 674 675 if (p == NULL) { 676 fprintf(stderr, "failed to connect to server\en"); 677 return (1); 678 } 679 680 freeaddrinfo(gair); 681 682 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &y, 683 sizeof (y)) == -1) { 684 perror("setsockopt(SO_KEEPALIVE) failed"); 685 return (1); 686 } 687 688 while ((rlen = read(fd, buf, sizeof (buf))) > 0) { 689 fwrite(buf, rlen, 1, stdout); 690 } 691 692 if (rlen == -1) { 693 perror("read() failed"); 694 } 695 696 fflush(stdout); 697 698 if (close(fd) == -1) { 699 perror("close() failed"); 700 } 701 702 return (0); 703} 704$ ./client 127.0.0.1 8080 705hello 706$ ./client ::1 8080 707hello 708.Ed 709.Ss Example 2: Accepting client connections 710.Bd -literal 711$ gcc -std=c99 -Wall -lsocket -o server server.c 712$ cat server.c 713#include <sys/socket.h> 714#include <netinet/in.h> 715#include <netinet/tcp.h> 716#include <netdb.h> 717#include <stdio.h> 718#include <string.h> 719#include <unistd.h> 720#include <arpa/inet.h> 721 722void 723logmsg(struct sockaddr *s, int bytes) 724{ 725 char dq[INET6_ADDRSTRLEN]; 726 727 switch (s->sa_family) { 728 case AF_INET: { 729 struct sockaddr_in *s4 = (struct sockaddr_in *)s; 730 inet_ntop(AF_INET, &s4->sin_addr, dq, sizeof (dq)); 731 fprintf(stdout, "sent %d bytes to %s:%d\en", 732 bytes, dq, ntohs(s4->sin_port)); 733 break; 734 } 735 case AF_INET6: { 736 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)s; 737 inet_ntop(AF_INET6, &s6->sin6_addr, dq, sizeof (dq)); 738 fprintf(stdout, "sent %d bytes to [%s]:%d\en", 739 bytes, dq, ntohs(s6->sin6_port)); 740 break; 741 } 742 default: 743 fprintf(stdout, "sent %d bytes to unknown client\en", 744 bytes); 745 break; 746 } 747} 748 749int 750main(int argc, char *argv[]) 751{ 752 struct addrinfo hints, *gair, *p; 753 int sfd, cfd; 754 int slen, wlen, rv; 755 756 if (argc != 3) { 757 fprintf(stderr, "%s <port> <message>\en", argv[0]); 758 return (1); 759 } 760 761 slen = strlen(argv[2]); 762 763 memset(&hints, 0, sizeof (hints)); 764 hints.ai_family = PF_UNSPEC; 765 hints.ai_socktype = SOCK_STREAM; 766 hints.ai_flags = AI_PASSIVE; 767 768 if ((rv = getaddrinfo(NULL, argv[1], &hints, &gair)) != 0) { 769 fprintf(stderr, "getaddrinfo() failed: %s\en", 770 gai_strerror(rv)); 771 return (1); 772 } 773 774 for (p = gair; p != NULL; p = p->ai_next) { 775 if ((sfd = socket( 776 p->ai_family, 777 p->ai_socktype, 778 p->ai_protocol)) == -1) { 779 perror("socket() failed"); 780 continue; 781 } 782 783 if (bind(sfd, p->ai_addr, p->ai_addrlen) == -1) { 784 close(sfd); 785 perror("bind() failed"); 786 continue; 787 } 788 789 break; 790 } 791 792 if (p == NULL) { 793 fprintf(stderr, "server failed to bind()\en"); 794 return (1); 795 } 796 797 freeaddrinfo(gair); 798 799 if (listen(sfd, 1024) != 0) { 800 perror("listen() failed"); 801 return (1); 802 } 803 804 fprintf(stdout, "waiting for clients...\en"); 805 806 for (int times = 0; times < 5; times++) { 807 struct sockaddr_storage stor; 808 socklen_t alen = sizeof (stor); 809 struct sockaddr *addr = (struct sockaddr *)&stor; 810 811 if ((cfd = accept(sfd, addr, &alen)) == -1) { 812 perror("accept() failed"); 813 continue; 814 } 815 816 wlen = 0; 817 818 do { 819 wlen += write(cfd, argv[2] + wlen, slen - wlen); 820 } while (wlen < slen); 821 822 logmsg(addr, wlen); 823 824 if (close(cfd) == -1) { 825 perror("close(cfd) failed"); 826 } 827 } 828 829 if (close(sfd) == -1) { 830 perror("close(sfd) failed"); 831 } 832 833 fprintf(stdout, "finished.\en"); 834 835 return (0); 836} 837$ ./server 8080 $'hello\en' 838waiting for clients... 839sent 6 bytes to [::ffff:127.0.0.1]:59059 840sent 6 bytes to [::ffff:127.0.0.1]:47448 841sent 6 bytes to [::ffff:127.0.0.1]:54949 842sent 6 bytes to [::ffff:127.0.0.1]:55186 843sent 6 bytes to [::1]:62256 844finished. 845.Ed 846.Sh DIAGNOSTICS 847A socket operation may fail if: 848.Bl -tag -offset indent -width 16m 849.It Er EISCONN 850A 851.Fn connect 852operation was attempted on a socket on which a 853.Fn connect 854operation had already been performed. 855.It Er ETIMEDOUT 856A connection was dropped due to excessive retransmissions. 857.It Er ECONNRESET 858The remote peer forced the connection to be closed (usually because the remote 859machine has lost state information about the connection due to a crash). 860.It Er ECONNREFUSED 861The remote peer actively refused connection establishment (usually because no 862process is listening to the port). 863.It Er EADDRINUSE 864A 865.Fn bind 866operation was attempted on a socket with a network address/port pair that has 867already been bound to another socket. 868.It Er EADDRNOTAVAIL 869A 870.Fn bind 871operation was attempted on a socket with a network address for which no network 872interface exists. 873.It Er EACCES 874A 875.Fn bind 876operation was attempted with a 877.Dq reserved 878port number and the effective user ID of the process was not the privileged 879user. 880.It Er ENOBUFS 881The system ran out of memory for internal data structures. 882.El 883.Sh SEE ALSO 884.Xr svcs 1 , 885.Xr ioctl 2 , 886.Xr read 2 , 887.Xr write 2 , 888.Xr accept 3SOCKET , 889.Xr bind 3SOCKET , 890.Xr connect 3SOCKET , 891.Xr getprotobyname 3SOCKET , 892.Xr getsockopt 3SOCKET , 893.Xr listen 3SOCKET , 894.Xr send 3SOCKET , 895.Xr inet 4P , 896.Xr inet6 4P , 897.Xr ip 4P , 898.Xr ip6 4P , 899.Xr smf 7 , 900.Xr ndd 8 , 901.Xr svcadm 8 , 902.Xr tcpkey 8 903.Rs 904.%A "K. Ramakrishnan" 905.%A "S. Floyd" 906.%A "D. Black" 907.%T "The Addition of Explicit Congestion Notification (ECN) to IP" 908.%R "RFC 3168" 909.%D "September 2001" 910.Re 911.Rs 912.%A "M. Mathias" 913.%A "J. Mahdavi" 914.%A "S. Ford" 915.%A "A. Romanow" 916.%T "TCP Selective Acknowledgement Options" 917.%R "RFC 2018" 918.%D "October 1996" 919.Re 920.Rs 921.%A "S. Bellovin" 922.%T "Defending Against Sequence Number Attacks" 923.%R "RFC 1948" 924.%D "May 1996" 925.Re 926.Rs 927.%A "D. Borman" 928.%A "B. Braden" 929.%A "V. Jacobson" 930.%A "R. Scheffenegger, Ed." 931.%T "TCP Extensions for High Performance" 932.%R "RFC 7323" 933.%D "September 2014" 934.Re 935.Rs 936.%A "Jon Postel" 937.%T "Transmission Control Protocol - DARPA Internet Program Protocol Specification" 938.%R "RFC 793" 939.%C "Network Information Center, SRI International, Menlo Park, CA." 940.%D "September 1981" 941.Re 942.Rs 943.%A "A. Heffernan" 944.%T "Protection of BGP Sessions via the TCP MD5 Signature Option" 945.%R "RFC 2385" 946.%D "August 1998" 947.Re 948.Sh NOTES 949The 950.Sy tcp 951service is managed by the service management facility, 952.Xr smf 7 , 953under the service identifier 954.Sy svc:/network/initial:default . 955.Pp 956Administrative actions on this service, such as enabling, disabling, or 957requesting restart, can be performed using 958.Xr svcadm 8 . 959The service's 960status can be queried using the 961.Xr svcs 1 962command. 963