]> sjero.net Git - wget/blob - src/connect.c
[svn] Enabled separation of different timeout values.
[wget] / src / connect.c
1 /* Establishing and handling network connections.
2    Copyright (C) 1995, 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
3
4 This file is part of GNU Wget.
5
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.
10
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.
15
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.
19
20 In addition, as a special exception, the Free Software Foundation
21 gives permission to link the code of its release of Wget with the
22 OpenSSL project's "OpenSSL" library (or with modified versions of it
23 that use the same license as the "OpenSSL" library), and distribute
24 the linked executables.  You must obey the GNU General Public License
25 in all respects for all of the code used other than "OpenSSL".  If you
26 modify this file, you may extend this exception to your version of the
27 file, but you are not obligated to do so.  If you do not wish to do
28 so, delete this exception statement from your version.  */
29
30 #include <config.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/types.h>
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif
38 #include <assert.h>
39
40 #ifdef WINDOWS
41 # include <winsock.h>
42 #else
43 # include <sys/socket.h>
44 # include <netdb.h>
45 # include <netinet/in.h>
46 #ifndef __BEOS__
47 # include <arpa/inet.h>
48 #endif
49 #endif /* WINDOWS */
50
51 #include <errno.h>
52 #ifdef HAVE_STRING_H
53 # include <string.h>
54 #else
55 # include <strings.h>
56 #endif /* HAVE_STRING_H */
57 #ifdef HAVE_SYS_SELECT_H
58 # include <sys/select.h>
59 #endif /* HAVE_SYS_SELECT_H */
60
61 #include "wget.h"
62 #include "utils.h"
63 #include "host.h"
64 #include "connect.h"
65
66 #ifndef errno
67 extern int errno;
68 #endif
69
70 /* Variables shared by bindport and acceptport: */
71 static int msock = -1;
72 static struct sockaddr *addr;
73
74 static ip_address bind_address;
75 static int bind_address_resolved;
76
77 static void
78 resolve_bind_address (void)
79 {
80   struct address_list *al;
81
82   if (bind_address_resolved || opt.bind_address == NULL)
83     /* Nothing to do. */
84     return;
85
86   al = lookup_host (opt.bind_address, 1);
87   if (!al)
88     {
89       logprintf (LOG_NOTQUIET,
90                  _("Unable to convert `%s' to a bind address.  Reverting to ANY.\n"),
91                  opt.bind_address);
92       return;
93     }
94
95   address_list_copy_one (al, 0, &bind_address);
96   address_list_release (al);
97   bind_address_resolved = 1;
98 }
99 \f
100 struct cwt_context {
101   int fd;
102   const struct sockaddr *addr;
103   int addrlen;
104   int result;
105 };
106
107 static void
108 connect_with_timeout_callback (void *arg)
109 {
110   struct cwt_context *ctx = (struct cwt_context *)arg;
111   ctx->result = connect (ctx->fd, ctx->addr, ctx->addrlen);
112 }
113
114 /* Like connect, but specifies a timeout.  If connecting takes longer
115    than TIMEOUT seconds, -1 is returned and errno is set to
116    ETIMEDOUT.  */
117
118 static int
119 connect_with_timeout (int fd, const struct sockaddr *addr, int addrlen,
120                       double timeout)
121 {
122   struct cwt_context ctx;
123   ctx.fd = fd;
124   ctx.addr = addr;
125   ctx.addrlen = addrlen;
126
127   if (run_with_timeout (timeout, connect_with_timeout_callback, &ctx))
128     {
129       errno = ETIMEDOUT;
130       return -1;
131     }
132   if (ctx.result == -1 && errno == EINTR)
133     errno = ETIMEDOUT;
134   return ctx.result;
135 }
136 \f
137 /* A kludge, but still better than passing the host name all the way
138    to connect_to_one.  */
139 static const char *connection_host_name;
140
141 void
142 set_connection_host_name (const char *host)
143 {
144   if (host)
145     assert (connection_host_name == NULL);
146   else
147     assert (connection_host_name != NULL);
148
149   connection_host_name = host;
150 }
151
152 /* Connect to a remote host whose address has been resolved. */
153 int
154 connect_to_one (ip_address *addr, unsigned short port, int silent)
155 {
156   wget_sockaddr sa;
157   int sock, save_errno;
158
159   /* Set port and protocol */
160   wget_sockaddr_set_address (&sa, ip_default_family, port, addr);
161
162   if (!silent)
163     {
164       char *pretty_addr = pretty_print_address (addr);
165       if (connection_host_name
166           && 0 != strcmp (connection_host_name, pretty_addr))
167         logprintf (LOG_VERBOSE, _("Connecting to %s[%s]:%hu... "),
168                    connection_host_name, pretty_addr, port);
169       else
170         logprintf (LOG_VERBOSE, _("Connecting to %s:%hu... "),
171                    pretty_addr, port);
172     }
173
174   /* Make an internet socket, stream type.  */
175   sock = socket (ip_default_family, SOCK_STREAM, 0);
176   if (sock < 0)
177     goto out;
178
179 #ifdef SO_RCVBUF
180   /* For very small rate limits, set the buffer size (and hence,
181      hopefully, the size of the kernel window) to the size of the
182      limit.  */
183   if (opt.limit_rate && opt.limit_rate < 8192)
184     {
185       int bufsize = opt.limit_rate;
186       if (bufsize < 512)
187         bufsize = 512;
188       setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
189                   (char *)&bufsize, sizeof (bufsize));
190     }
191 #endif
192
193   resolve_bind_address ();
194   if (bind_address_resolved)
195     {
196       /* Bind the client side to the requested address. */
197       wget_sockaddr bsa;
198       wget_sockaddr_set_address (&bsa, ip_default_family, 0, &bind_address);
199       if (bind (sock, &bsa.sa, sockaddr_len ()))
200         {
201           close (sock);
202           sock = -1;
203           goto out;
204         }
205     }
206
207   /* Connect the socket to the remote host.  */
208   if (connect_with_timeout (sock, &sa.sa, sockaddr_len (),
209                             opt.connect_timeout) < 0)
210     {
211       close (sock);
212       sock = -1;
213       goto out;
214     }
215
216  out:
217   if (sock >= 0)
218     {
219       /* Success. */
220       if (!silent)
221         logprintf (LOG_VERBOSE, _("connected.\n"));
222       DEBUGP (("Created socket %d.\n", sock));
223     }
224   else
225     {
226       save_errno = errno;
227       if (!silent)
228         logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
229       errno = save_errno;
230     }
231
232   return sock;
233 }
234
235 /* Connect to a remote host whose address has been resolved. */
236 int
237 connect_to_many (struct address_list *al, unsigned short port, int silent)
238 {
239   int i, start, end;
240
241   address_list_get_bounds (al, &start, &end);
242   for (i = start; i < end; i++)
243     {
244       ip_address addr;
245       int sock;
246       address_list_copy_one (al, i, &addr);
247
248       sock = connect_to_one (&addr, port, silent);
249       if (sock >= 0)
250         /* Success. */
251         return sock;
252
253       address_list_set_faulty (al, i);
254
255       /* The attempt to connect has failed.  Continue with the loop
256          and try next address. */
257     }
258
259   return -1;
260 }
261
262 int
263 test_socket_open (int sock)
264 {
265 #ifdef HAVE_SELECT
266   fd_set check_set;
267   struct timeval to;
268
269   /* Check if we still have a valid (non-EOF) connection.  From Andrew
270    * Maholski's code in the Unix Socket FAQ.  */
271
272   FD_ZERO (&check_set);
273   FD_SET (sock, &check_set);
274
275   /* Wait one microsecond */
276   to.tv_sec = 0;
277   to.tv_usec = 1;
278
279   /* If we get a timeout, then that means still connected */
280   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
281     {
282       /* Connection is valid (not EOF), so continue */
283       return 1;
284     }
285   else
286     return 0;
287 #else
288   /* Without select, it's hard to know for sure. */
289   return 1;
290 #endif
291 }
292
293 /* Bind the local port PORT.  This does all the necessary work, which
294    is creating a socket, setting SO_REUSEADDR option on it, then
295    calling bind() and listen().  If *PORT is 0, a random port is
296    chosen by the system, and its value is stored to *PORT.  The
297    internal variable MPORT is set to the value of the ensuing master
298    socket.  Call acceptport() to block for and accept a connection.  */
299 uerr_t
300 bindport (unsigned short *port, int family)
301 {
302   int optval = 1;
303   wget_sockaddr srv;
304   memset (&srv, 0, sizeof (wget_sockaddr));
305
306   msock = -1;
307
308   if ((msock = socket (family, SOCK_STREAM, 0)) < 0)
309     return CONSOCKERR;
310
311 #ifdef SO_REUSEADDR
312   if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
313                   (char *)&optval, sizeof (optval)) < 0)
314     return CONSOCKERR;
315 #endif
316
317   resolve_bind_address ();
318   wget_sockaddr_set_address (&srv, ip_default_family, htons (*port),
319                              bind_address_resolved ? &bind_address : NULL);
320   if (bind (msock, &srv.sa, sockaddr_len ()) < 0)
321     {
322       CLOSE (msock);
323       msock = -1;
324       return BINDERR;
325     }
326   DEBUGP (("Master socket fd %d bound.\n", msock));
327   if (!*port)
328     {
329       /* #### addrlen should be a 32-bit type, which int is not
330          guaranteed to be.  Oh, and don't try to make it a size_t,
331          because that can be 64-bit.  */
332       int sa_len = sockaddr_len ();
333       if (getsockname (msock, &srv.sa, &sa_len) < 0)
334         {
335           CLOSE (msock);
336           msock = -1;
337           return CONPORTERR;
338         }
339       *port = wget_sockaddr_get_port (&srv);
340       DEBUGP (("using port %i.\n", *port));
341     }
342   if (listen (msock, 1) < 0)
343     {
344       CLOSE (msock);
345       msock = -1;
346       return LISTENERR;
347     }
348   return BINDOK;
349 }
350
351 #ifdef HAVE_SELECT
352 /* Wait for file descriptor FD to be available, timing out after
353    MAXTIME seconds.  "Available" means readable if writep is 0,
354    writeable otherwise.
355
356    Returns 1 if FD is available, 0 for timeout and -1 for error.  */
357
358 int
359 select_fd (int fd, double maxtime, int writep)
360 {
361   fd_set fds;
362   fd_set *rd = NULL, *wrt = NULL;
363   struct timeval tmout;
364   int result;
365
366   FD_ZERO (&fds);
367   FD_SET (fd, &fds);
368   *(writep ? &wrt : &rd) = &fds;
369
370   tmout.tv_sec = (long)maxtime;
371   tmout.tv_usec = 1000000L * (maxtime - (long)maxtime);
372
373   do
374     result = select (fd + 1, rd, wrt, NULL, &tmout);
375   while (result < 0 && errno == EINTR);
376
377   /* When we've timed out, set errno to ETIMEDOUT for the convenience
378      of the caller. */
379   if (result == 0)
380     errno = ETIMEDOUT;
381
382   return result;
383 }
384 #endif /* HAVE_SELECT */
385
386 /* Call accept() on MSOCK and store the result to *SOCK.  This assumes
387    that bindport() has been used to initialize MSOCK to a correct
388    value.  It blocks the caller until a connection is established.  If
389    no connection is established for OPT.CONNECT_TIMEOUT seconds, the
390    function exits with an error status.  */
391 uerr_t
392 acceptport (int *sock)
393 {
394   int addrlen = sockaddr_len ();
395
396 #ifdef HAVE_SELECT
397   if (select_fd (msock, opt.connect_timeout, 0) <= 0)
398     return ACCEPTERR;
399 #endif
400   if ((*sock = accept (msock, addr, &addrlen)) < 0)
401     return ACCEPTERR;
402   DEBUGP (("Created socket fd %d.\n", *sock));
403   return ACCEPTOK;
404 }
405
406 /* Close SOCK, as well as the most recently remembered MSOCK, created
407    via bindport().  If SOCK is -1, close MSOCK only.  */
408 void
409 closeport (int sock)
410 {
411   /*shutdown (sock, 2);*/
412   if (sock != -1)
413     CLOSE (sock);
414   if (msock != -1)
415     CLOSE (msock);
416   msock = -1;
417 }
418
419 /* Return the local IP address associated with the connection on FD.  */
420
421 int
422 conaddr (int fd, ip_address *ip)
423 {
424   wget_sockaddr mysrv;
425
426   /* see bindport() for discussion of using `int' here. */
427   int addrlen = sizeof (mysrv); 
428
429   if (getsockname (fd, &mysrv.sa, (int *)&addrlen) < 0)
430     return 0;
431
432   switch (mysrv.sa.sa_family)
433     {
434 #ifdef ENABLE_IPV6
435     case AF_INET6:
436       memcpy (ip, &mysrv.sin6.sin6_addr, 16);
437       return 1;
438 #endif
439     case AF_INET:
440       map_ipv4_to_ip ((ip4_address *)&mysrv.sin.sin_addr, ip);
441       return 1;
442     default:
443       abort ();
444     }
445   return 0;
446 }
447
448 /* Read at most LEN bytes from FD, storing them to BUF.  This is
449    virtually the same as read(), but takes care of EINTR braindamage
450    and uses select() to timeout the stale connections (a connection is
451    stale if more than OPT.READ_TIMEOUT time is spent in select() or
452    read()).  */
453
454 int
455 iread (int fd, char *buf, int len)
456 {
457   int res;
458
459 #ifdef HAVE_SELECT
460   if (opt.read_timeout)
461     if (select_fd (fd, opt.read_timeout, 0) <= 0)
462       return -1;
463 #endif
464   do
465     res = READ (fd, buf, len);
466   while (res == -1 && errno == EINTR);
467
468   return res;
469 }
470
471 /* Write LEN bytes from BUF to FD.  This is similar to iread(), but
472    unlike iread(), it makes sure that all of BUF is actually written
473    to FD, so callers needn't bother with checking that the return
474    value equals to LEN.  Instead, you should simply check for -1.  */
475
476 int
477 iwrite (int fd, char *buf, int len)
478 {
479   int res = 0;
480
481   /* `write' may write less than LEN bytes, thus the outward loop
482      keeps trying it until all was written, or an error occurred.  The
483      inner loop is reserved for the usual EINTR f*kage, and the
484      innermost loop deals with the same during select().  */
485   while (len > 0)
486     {
487 #ifdef HAVE_SELECT
488       if (opt.read_timeout)
489         if (select_fd (fd, opt.read_timeout, 1) <= 0)
490           return -1;
491 #endif
492       do
493         res = WRITE (fd, buf, len);
494       while (res == -1 && errno == EINTR);
495       if (res <= 0)
496         break;
497       buf += res;
498       len -= res;
499     }
500   return res;
501 }