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