1 .\"
   2 .\" The contents of this file are subject to the terms of the
   3 .\" Common Development and Distribution License (the "License").
   4 .\" You may not use this file except in compliance with the License.
   5 .\"
   6 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   7 .\" or http://www.opensolaris.org/os/licensing.
   8 .\" See the License for the specific language governing permissions
   9 .\" and limitations under the License.
  10 .\"
  11 .\" When distributing Covered Code, include this CDDL HEADER in each
  12 .\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  13 .\" If applicable, add the following below this CDDL HEADER, with the
  14 .\" fields enclosed by brackets "[]" replaced with your own identifying
  15 .\" information: Portions Copyright [yyyy] [name of copyright owner]
  16 .\"
  17 .\"
  18 .\" Copyright 1989 AT&T  All Rights Reserved
  19 .\" Copyright (C) 2005, Sun Microsystems, Inc. All Rights Reserved.
  20 .\" Copyright (c) 2014, Joyent, Inc.
  21 .\" Copyright 2018 Nexenta Systems, Inc.
  22 .\"
  23 .Dd August 2, 2018
  24 .Dt CONNECT 3C
  25 .Os
  26 .Sh NAME
  27 .Nm connect
  28 .Nd initiate a connection on a socket
  29 .Sh LIBRARY
  30 .Lb libc
  31 .Sh SYNOPSIS
  32 .In sys/types.h
  33 .In sys/socket.h
  34 .Ft int
  35 .Fo connect
  36 .Fa "int s"
  37 .Fa "const struct sockaddr *name"
  38 .Fa "socklen_t namelen"
  39 .Fc
  40 .Sh DESCRIPTION
  41 The parameter
  42 .Fa s
  43 is a socket.
  44 If it is of type
  45 .Dv SOCK_DGRAM ,
  46 .Fn connect
  47 specifies the peer with which the socket is to be associated.
  48 This address is the address to which datagrams are to be sent if a receiver is
  49 not explicitly designated.
  50 This address is the only address from which datagrams are to be received.
  51 If the socket
  52 .Fa s
  53 is of type
  54 .Dv SOCK_STREAM ,
  55 .Fn connect
  56 attempts to make a connection to another socket.
  57 The other socket is specified by
  58 .Fa name .
  59 .Fa name
  60 is an address in the communication space of the socket.
  61 Each communication space interprets the
  62 .Fa name
  63 parameter in its own way.
  64 If
  65 .Fa s
  66 is not bound, then
  67 .Fa s
  68 will be bound to an address selected by the underlying transport provider.
  69 Generally, stream sockets can successfully
  70 .Fn connect
  71 only once.
  72 Datagram sockets can use
  73 .Fn connect
  74 multiple times to change their association.
  75 Datagram sockets can dissolve the association by connecting to a null address.
  76 .Ss Non-blocking Sockets
  77 When a socket is created, it is by default a blocking socket.
  78 A socket may be configured to be non-blocking either at socket creation time or
  79 through the use of
  80 .Xr fcntl 2 .
  81 When a socket is set to be non-blocking, a call to
  82 .Fn connect
  83 initiates an asynchronous connection.
  84 If the connection cannot be completed without blocking, such as when making a
  85 TCP connection to a remote server, then  the connection attempt is made in the
  86 background and
  87 .Fn connect
  88 returns -1 and
  89 .Va errno
  90 is set to
  91 .Er EINPROGRESS .
  92 .Pp
  93 Applications can obtain the state of this connection attempt by polling the
  94 socket's file descriptor for
  95 .Dv POLLOUT .
  96 The event ports facility is the preferred means of polling on the file
  97 descriptor, see
  98 .Xr port_create 3C
  99 and
 100 .Xr port_get 3C
 101 for more information on event ports; however, applications may also use
 102 traditional portable routines like
 103 .Xr poll 2
 104 and
 105 .Xr select 3C .
 106 .Pp
 107 When an asynchronous connection has completed, the application must call
 108 .Xr getsockopt 3C
 109 using the macro
 110 .Dv SOL_SOCKET
 111 as the
 112 .Fa level
 113 argument and the macro
 114 .Dv SO_ERROR
 115 as the value of the
 116 .Fa option
 117 argument.
 118 If the value of the
 119 .Dv SO_ERROR
 120 socket option is zero, then the connect was successfully established.
 121 Otherwise, the connection could not be established and the value is the
 122 corresponding error code that would be commonly found in
 123 .Va errno .
 124 .Pp
 125 Even when a socket is in non-blocking mode, a call to
 126 .Fn connect
 127 may fail synchronously.
 128 If any error other than
 129 .Er EINPROGRESS
 130 or
 131 .Er EINTR
 132 occurs, then there is no need for the application to poll for asynchronous
 133 completion.
 134 Similarly, if a call to
 135 .Fn connect
 136 returns successfully, then the socket connection will be established and there
 137 is no need to poll for completion.
 138 .Sh RETURN VALUES
 139 If the connection or binding succeeds, 0 is returned.
 140 Otherwise, -1 is returned and sets
 141 .Va errno
 142 to indicate the error.
 143 .Sh EXAMPLES
 144 .Bl -tag -width Ds
 145 .It Sy Example 1 No Performing an asynchronous connection
 146 The following sample C program shows how to create and connect to a remote host
 147 using TCP.
 148 .Bd -literal
 149 #include <sys/types.h>
 150 #include <sys/socket.h>
 151 #include <netinet/in.h>
 152 #include <arpa/inet.h>
 153 #include <inttypes.h>
 154 #include <stdio.h>
 155 #include <strings.h>
 156 #include <stdlib.h>
 157 #include <errno.h>
 158 #include <port.h>
 159 #include <unistd.h>
 160 #include <assert.h>
 161 
 162 int
 163 main(int argc, char *argv[])
 164 {
 165         char *eptr;
 166         long port;
 167         int sock, ret, eport;
 168         struct sockaddr_in6 sin6;
 169 
 170         if (argc != 3) {
 171                 fprintf(stderr, "connect: <IP> <port>\\n");
 172                 return (1);
 173         }
 174 
 175         bzero(&sin6, sizeof (struct sockaddr_in6));
 176         sin6.sin6_family = AF_INET6;
 177 
 178         /*
 179          * Try to parse as an IPv6 address and then try v4.
 180          */
 181         ret = inet_pton(AF_INET6, argv[1], &sin6.sin6_addr);
 182         if (ret == -1) {
 183                 perror("inet_pton");
 184                 return (1);
 185         } else if (ret == 0) {
 186                 struct in_addr v4;
 187                 ret = inet_pton(AF_INET, argv[1], &v4);
 188                 if (ret == -1) {
 189                         perror("inet_pton");
 190                         return (1);
 191                 } else if (ret == 0) {
 192                         fprintf(stderr, "connect: %s is not a valid "
 193                             "IPv4 or IPv6 address\\n", argv[1]);
 194                         return (1);
 195                 }
 196                 /* N.B. Not a portable macro */
 197                 IN6_INADDR_TO_V4MAPPED(&v4, &sin6.sin6_addr);
 198         }
 199 
 200         errno = 0;
 201         port = strtol(argv[2], &eptr, 10);
 202         if (errno != 0 || *eptr != '\e0') {
 203                 fprintf(stderr, "failed to parse port %s\\n", argv[2]);
 204                 return (1);
 205         }
 206         if (port <= 0 || port > UINT16_MAX) {
 207                 fprintf(stderr, "invalid port: %ld\\n", port);
 208                 return (1);
 209         }
 210         sin6.sin6_port = htons(port);
 211 
 212         sock = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
 213         if (sock < 0) {
 214                 perror("socket");
 215                 return (1);
 216         }
 217 
 218         eport = port_create();
 219         if (eport < 0) {
 220                 perror("port_create");
 221                 (void) close(sock);
 222                 return (1);
 223         }
 224 
 225         ret = connect(sock, (struct sockaddr *)&sin6,
 226             sizeof (struct sockaddr_in6));
 227         if (ret != 0 && errno != EINPROGRESS && errno != EINTR) {
 228                 perror("connect");
 229                 (void) close(sock);
 230                 (void) close(eport);
 231                 return (1);
 232         }
 233 
 234         if (ret != 0) {
 235                 port_event_t pe;
 236                 int err;
 237                 socklen_t sz = sizeof (err);
 238                 if (port_associate(eport, PORT_SOURCE_FD, sock, POLLOUT,
 239                     NULL) != 0) {
 240                         perror("port_associate");
 241                         (void) close(sock);
 242                         (void) close(eport);
 243                         return (1);
 244                 }
 245                 if (port_get(eport, &pe, NULL) != 0) {
 246                         perror("port_get");
 247                         (void) close(sock);
 248                         (void) close(eport);
 249                         return (1);
 250                 }
 251                 assert(pe.portev_source == PORT_SOURCE_FD);
 252                 assert(pe.portev_object == (uintptr_t)sock);
 253                 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &sz) != 0) {
 254                         perror("getsockopt");
 255                         (void) close(sock);
 256                         (void) close(eport);
 257                         return (1);
 258                 }
 259                 if (err != 0) {
 260                         /* Asynch connect failed */
 261                         fprintf(stderr, "asnchronous connect: %s\\n",
 262                             strerror(err));
 263                         (void) close(sock);
 264                         (void) close(eport);
 265                         return (1);
 266                 }
 267         }
 268 
 269         /* Read and write to the socket and then clean up */
 270 
 271         return (0);
 272 }
 273 .Ed
 274 .El
 275 .Sh ERRORS
 276 The call fails if:
 277 .Bl -tag -width Er
 278 .It Bq Er EACCES
 279 Search permission is denied for a component of the path prefix of the pathname
 280 in
 281 .Fa name .
 282 .It Bq Er EADDRINUSE
 283 The address is already in use.
 284 .It Bq Er EADDRNOTAVAIL
 285 The specified address is not available on the remote machine.
 286 .It Bq Er EAFNOSUPPORT
 287 Addresses in the specified address family cannot be used with this socket.
 288 .It Bq Er EALREADY
 289 The socket is non-blocking,  and a previous connection attempt has not yet been
 290 completed.
 291 .It Bq Er EBADF
 292 .Fa s
 293 is not a valid descriptor.
 294 .It Bq Er ECONNREFUSED
 295 The attempt to connect was forcefully rejected.
 296 The calling program should
 297 .Xr close 2
 298 the socket descriptor, and issue another
 299 .Xr socket 3C
 300 call to obtain a new descriptor before attempting another
 301 .Fn connect
 302 call.
 303 .It Bq Er EINPROGRESS
 304 The socket is non-blocking, and the connection cannot be completed immediately.
 305 See the section on
 306 .Sx Non-blocking Sockets
 307 for more information.
 308 .It Bq Er EINTR
 309 The connection attempt was interrupted before any data arrived by the delivery
 310 of a signal.
 311 The connection, however, will be established asynchronously.
 312 .It Bq Er EINVAL
 313 .Fa namelen
 314 is not the size of a valid address for the specified address family.
 315 .It Bq Er EIO
 316 An I/O error occurred while reading from or writing to the file system.
 317 .It Bq Er EISCONN
 318 The socket is already connected.
 319 .It Bq Er ELOOP
 320 Too many symbolic links were encountered in translating the pathname in
 321 .Fa name .
 322 .It Bq Er ENETUNREACH
 323 The network is not reachable from this host.
 324 .It Bq Er EHOSTUNREACH
 325 The remote host is not reachable from this host.
 326 .It Bq Er ENOENT
 327 A component of the path prefix of the pathname in
 328 .Fa name
 329 does not exist.
 330 .Pp
 331 The socket referred to by the pathname in
 332 .Fa name
 333 does not exist.
 334 .It Bq Er ENOSR
 335 There were insufficient STREAMS resources available to complete the operation.
 336 .It Bq Er ENXIO
 337 The server exited before the connection was complete.
 338 .It Bq Er ETIMEDOUT
 339 Connection establishment timed out without establishing a connection.
 340 .It Bq Er EWOULDBLOCK
 341 The socket is marked as non-blocking, and the requested operation would block.
 342 .El
 343 .Pp
 344 The following errors are specific to connecting names in the UNIX domain.
 345 These errors might not apply in future versions of the UNIX IPC domain.
 346 .Bl -tag -width Er
 347 .It Bq Er ENOTDIR
 348 A component of the path prefix of the pathname in
 349 .Fa name
 350 is not a directory.
 351 .It Bq Er ENOTSOCK
 352 .Fa s
 353 is not a socket.
 354 .It Bq Er EPROTOTYPE
 355 The file that is referred to by
 356 .Fa name
 357 is a socket of a type other than type
 358 .Fa s .
 359 For example,
 360 .Fa s
 361 is a
 362 .Dv SOCK_DGRAM
 363 socket, while
 364 .Fa name
 365 refers to a
 366 .Dv SOCK_STREAM
 367 socket.
 368 .El
 369 .Sh MT-LEVEL
 370 .Sy Safe
 371 .Sh SEE ALSO
 372 .Xr close 2 ,
 373 .Xr accept 3C ,
 374 .Xr getsockname 3C ,
 375 .Xr select 3C ,
 376 .Xr sockaddr 3C ,
 377 .Xr socket 3C ,
 378 .Xr socket.h 3HEAD ,
 379 .Xr attributes 5