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