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