1 /* Establishing and handling network connections.
2 Copyright (C) 1995, 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Wget.
6 GNU Wget is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 GNU Wget is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Wget; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include <sys/types.h>
32 # include <sys/socket.h>
34 # include <netinet/in.h>
36 # include <arpa/inet.h>
45 #endif /* HAVE_STRING_H */
46 #ifdef HAVE_SYS_SELECT_H
47 # include <sys/select.h>
48 #endif /* HAVE_SYS_SELECT_H */
50 /* To implement connect with timeout, we need signal and either
51 sigsetjmp or sigblock. */
52 #undef UNIX_CONNECT_TIMEOUT
59 /* If sigsetjmp is a macro, configure won't pick it up. */
61 # define HAVE_SIGSETJMP
64 # ifdef HAVE_SIGSETJMP
65 # define UNIX_CONNECT_TIMEOUT
68 # define UNIX_CONNECT_TIMEOUT
80 /* Variables shared by bindport and acceptport: */
81 static int msock = -1;
82 static struct sockaddr *addr;
84 static ip_address bind_address;
85 static int bind_address_resolved;
88 resolve_bind_address (void)
90 struct address_list *al;
92 if (bind_address_resolved || opt.bind_address == NULL)
96 al = lookup_host (opt.bind_address, 1);
99 logprintf (LOG_NOTQUIET,
100 _("Unable to convert `%s' to a bind address. Reverting to ANY.\n"),
105 address_list_copy_one (al, 0, &bind_address);
106 address_list_release (al);
107 bind_address_resolved = 1;
110 #ifndef UNIX_CONNECT_TIMEOUT
112 connect_with_timeout (int fd, const struct sockaddr *addr, int addrlen,
115 return connect (fd, addr, addrlen);
117 #else /* UNIX_CONNECT_TIMEOUT */
118 /* Implementation of connect with timeout. */
120 #ifdef HAVE_SIGSETJMP
121 #define SETJMP(env) sigsetjmp (env, 1)
123 static sigjmp_buf abort_connect_env;
126 abort_connect (int ignored)
128 siglongjmp (abort_connect_env, -1);
130 #else /* not HAVE_SIGSETJMP */
131 #define SETJMP(env) setjmp (env)
133 static jmp_buf abort_connect_env;
136 abort_connect (int ignored)
138 /* We don't have siglongjmp to preserve the set of blocked signals;
139 if we longjumped out of the handler at this point, SIGALRM would
140 remain blocked. We must unblock it manually. */
141 int mask = siggetmask ();
142 mask &= ~sigmask(SIGALRM);
145 /* Now it's safe to longjump. */
146 longjmp (abort_connect_env, -1);
148 #endif /* not HAVE_SIGSETJMP */
150 /* Like connect, but specifies a timeout. If connecting takes longer
151 than TIMEOUT seconds, -1 is returned and errno is set to
155 connect_with_timeout (int fd, const struct sockaddr *addr, int addrlen,
158 int result, saved_errno;
161 return connect (fd, addr, addrlen);
163 signal (SIGALRM, abort_connect);
164 if (SETJMP (abort_connect_env) != 0)
166 /* Longjumped out of connect with a timeout. */
167 signal (SIGALRM, SIG_DFL);
173 result = connect (fd, addr, addrlen);
175 saved_errno = errno; /* In case alarm() or signal() change
178 signal (SIGALRM, SIG_DFL);
183 #endif /* UNIX_CONNECT_TIMEOUT */
185 /* A kludge, but still better than passing the host name all the way
186 to connect_to_one. */
187 static const char *connection_host_name;
190 set_connection_host_name (const char *host)
193 assert (connection_host_name == NULL);
195 assert (connection_host_name != NULL);
197 connection_host_name = host;
200 /* Connect to a remote host whose address has been resolved. */
202 connect_to_one (ip_address *addr, unsigned short port, int silent)
205 int sock, save_errno;
207 /* Set port and protocol */
208 wget_sockaddr_set_address (&sa, ip_default_family, port, addr);
212 char *pretty_addr = pretty_print_address (addr);
213 if (connection_host_name
214 && 0 != strcmp (connection_host_name, pretty_addr))
215 logprintf (LOG_VERBOSE, _("Connecting to %s[%s]:%hu... "),
216 connection_host_name, pretty_addr, port);
218 logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "),
222 /* Make an internet socket, stream type. */
223 sock = socket (ip_default_family, SOCK_STREAM, 0);
227 resolve_bind_address ();
228 if (bind_address_resolved)
230 /* Bind the client side to the requested address. */
232 wget_sockaddr_set_address (&bsa, ip_default_family, 0, &bind_address);
233 if (bind (sock, &bsa.sa, sockaddr_len ()))
241 /* Connect the socket to the remote host. */
242 if (connect_with_timeout (sock, &sa.sa, sockaddr_len (), opt.timeout) < 0)
254 logprintf (LOG_VERBOSE, _("connected.\n"));
255 DEBUGP (("Created socket %d.\n", sock));
261 logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
268 /* Connect to a remote host whose address has been resolved. */
270 connect_to_many (struct address_list *al, unsigned short port, int silent)
274 address_list_get_bounds (al, &start, &end);
275 for (i = start; i < end; i++)
279 address_list_copy_one (al, i, &addr);
281 sock = connect_to_one (&addr, port, silent);
286 address_list_set_faulty (al, i);
288 /* The attempt to connect has failed. Continue with the loop
289 and try next address. */
296 test_socket_open (int sock)
302 /* Check if we still have a valid (non-EOF) connection. From Andrew
303 * Maholski's code in the Unix Socket FAQ. */
305 FD_ZERO (&check_set);
306 FD_SET (sock, &check_set);
308 /* Wait one microsecond */
312 /* If we get a timeout, then that means still connected */
313 if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
315 /* Connection is valid (not EOF), so continue */
321 /* Without select, it's hard to know for sure. */
326 /* Bind the local port PORT. This does all the necessary work, which
327 is creating a socket, setting SO_REUSEADDR option on it, then
328 calling bind() and listen(). If *PORT is 0, a random port is
329 chosen by the system, and its value is stored to *PORT. The
330 internal variable MPORT is set to the value of the ensuing master
331 socket. Call acceptport() to block for and accept a connection. */
333 bindport (unsigned short *port, int family)
337 memset (&srv, 0, sizeof (wget_sockaddr));
341 if ((msock = socket (family, SOCK_STREAM, 0)) < 0)
343 if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
344 (char *)&optval, sizeof (optval)) < 0)
347 resolve_bind_address ();
348 wget_sockaddr_set_address (&srv, ip_default_family, htons (*port),
349 bind_address_resolved ? &bind_address : NULL);
350 if (bind (msock, &srv.sa, sockaddr_len ()) < 0)
356 DEBUGP (("Master socket fd %d bound.\n", msock));
359 /* #### addrlen should be a 32-bit type, which int is not
360 guaranteed to be. Oh, and don't try to make it a size_t,
361 because that can be 64-bit. */
362 int sa_len = sockaddr_len ();
363 if (getsockname (msock, &srv.sa, &sa_len) < 0)
369 *port = wget_sockaddr_get_port (&srv);
370 DEBUGP (("using port %i.\n", *port));
372 if (listen (msock, 1) < 0)
382 /* Wait for file descriptor FD to be readable, MAXTIME being the
383 timeout in seconds. If WRITEP is non-zero, checks for FD being
386 Returns 1 if FD is accessible, 0 for timeout and -1 for error in
389 select_fd (int fd, int maxtime, int writep)
391 fd_set fds, exceptfds;
392 struct timeval timeout;
396 FD_ZERO (&exceptfds);
397 FD_SET (fd, &exceptfds);
398 timeout.tv_sec = maxtime;
400 /* HPUX reportedly warns here. What is the correct incantation? */
401 return select (fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,
402 &exceptfds, &timeout);
404 #endif /* HAVE_SELECT */
406 /* Call accept() on MSOCK and store the result to *SOCK. This assumes
407 that bindport() has been used to initialize MSOCK to a correct
408 value. It blocks the caller until a connection is established. If
409 no connection is established for OPT.TIMEOUT seconds, the function
410 exits with an error status. */
412 acceptport (int *sock)
414 int addrlen = sockaddr_len ();
417 if (select_fd (msock, opt.timeout, 0) <= 0)
420 if ((*sock = accept (msock, addr, &addrlen)) < 0)
422 DEBUGP (("Created socket fd %d.\n", *sock));
426 /* Close SOCK, as well as the most recently remembered MSOCK, created
427 via bindport(). If SOCK is -1, close MSOCK only. */
431 /*shutdown (sock, 2);*/
439 /* Return the local IP address associated with the connection on FD. */
442 conaddr (int fd, ip_address *ip)
446 /* see bindport() for discussion of using `int' here. */
447 int addrlen = sizeof (mysrv);
449 if (getsockname (fd, &mysrv.sa, (int *)&addrlen) < 0)
452 switch (mysrv.sa.sa_family)
456 memcpy (ip, &mysrv.sin6.sin6_addr, 16);
460 map_ipv4_to_ip ((ip4_address *)&mysrv.sin.sin_addr, ip);
468 /* Read at most LEN bytes from FD, storing them to BUF. This is
469 virtually the same as read(), but takes care of EINTR braindamage
470 and uses select() to timeout the stale connections (a connection is
471 stale if more than OPT.TIMEOUT time is spent in select() or
474 iread (int fd, char *buf, int len)
485 res = select_fd (fd, opt.timeout, 0);
487 while (res == -1 && errno == EINTR);
490 /* Set errno to ETIMEDOUT on timeout. */
492 /* #### Potentially evil! */
498 res = READ (fd, buf, len);
500 while (res == -1 && errno == EINTR);
505 /* Write LEN bytes from BUF to FD. This is similar to iread(), but
506 doesn't bother with select(). Unlike iread(), it makes sure that
507 all of BUF is actually written to FD, so callers needn't bother
508 with checking that the return value equals to LEN. Instead, you
509 should simply check for -1. */
511 iwrite (int fd, char *buf, int len)
515 /* `write' may write less than LEN bytes, thus the outward loop
516 keeps trying it until all was written, or an error occurred. The
517 inner loop is reserved for the usual EINTR f*kage, and the
518 innermost loop deals with the same during select(). */
528 res = select_fd (fd, opt.timeout, 1);
530 while (res == -1 && errno == EINTR);
533 /* Set errno to ETIMEDOUT on timeout. */
535 /* #### Potentially evil! */
541 res = WRITE (fd, buf, len);
543 while (res == -1 && errno == EINTR);