]> sjero.net Git - wget/blob - src/connect.c
[svn] Make setsockopt(SO_REUSEADDR) non-fatal if fails.
[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 #ifndef WINDOWS
41 # include <sys/socket.h>
42 # include <netdb.h>
43 # include <netinet/in.h>
44 # ifndef __BEOS__
45 #  include <arpa/inet.h>
46 # endif
47 #endif /* not WINDOWS */
48
49 #include <errno.h>
50 #ifdef HAVE_STRING_H
51 # include <string.h>
52 #else
53 # include <strings.h>
54 #endif /* HAVE_STRING_H */
55 #ifdef HAVE_SYS_SELECT_H
56 # include <sys/select.h>
57 #endif /* HAVE_SYS_SELECT_H */
58
59 #include "wget.h"
60 #include "utils.h"
61 #include "host.h"
62 #include "connect.h"
63
64 #ifndef errno
65 extern int errno;
66 #endif
67
68 \f
69 /* Fill SA as per the data in IP and PORT.  SA shoult point to struct
70    sockaddr_storage if ENABLE_IPV6 is defined, to struct sockaddr_in
71    otherwise.  */
72
73 static void
74 sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
75 {
76   switch (ip->type)
77     {
78     case IPV4_ADDRESS:
79       {
80         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
81         sin->sin_family = AF_INET;
82         sin->sin_port = htons (port);
83         sin->sin_addr = ADDRESS_IPV4_IN_ADDR (ip);
84         break;
85       }
86 #ifdef ENABLE_IPV6
87     case IPV6_ADDRESS:
88       {
89         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
90         sin6->sin6_family = AF_INET6;
91         sin6->sin6_port = htons (port);
92         sin6->sin6_addr = ADDRESS_IPV6_IN6_ADDR (ip);
93 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
94         sin6->sin6_scope_id = ADDRESS_IPV6_SCOPE (ip);
95 #endif
96         break;
97       }
98 #endif /* ENABLE_IPV6 */
99     default:
100       abort ();
101     }
102 }
103
104 /* Get the data of SA, specifically the IP address and the port.  If
105    you're not interested in one or the other information, pass NULL as
106    the pointer.  */
107
108 void
109 sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
110 {
111   switch (sa->sa_family)
112     {
113     case AF_INET:
114       {
115         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
116         if (ip)
117           {
118             ip->type = IPV4_ADDRESS;
119             ADDRESS_IPV4_IN_ADDR (ip) = sin->sin_addr;
120           }
121         if (port)
122           *port = ntohs (sin->sin_port);
123         break;
124       }
125 #ifdef ENABLE_IPV6
126     case AF_INET6:
127       {
128         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
129         if (ip)
130           {
131             ip->type = IPV6_ADDRESS;
132             ADDRESS_IPV6_IN6_ADDR (ip) = sin6->sin6_addr;
133 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
134             ADDRESS_IPV6_SCOPE (ip) = sin6->sin6_scope_id;
135 #endif
136           }
137         if (port)
138           *port = ntohs (sin6->sin6_port);
139         break;
140       }
141 #endif
142     default:
143       abort ();
144     }
145 }
146
147 /* Return the size of the sockaddr structure depending on its
148    family.  */
149
150 static socklen_t
151 sockaddr_size (const struct sockaddr *sa)
152 {
153   switch (sa->sa_family)
154     {
155     case AF_INET:
156       return sizeof (struct sockaddr_in);
157 #ifdef ENABLE_IPV6
158     case AF_INET6:
159       return sizeof (struct sockaddr_in6);
160 #endif
161     default:
162       abort ();
163       return 0;                 /* so the compiler shuts up. */
164     }
165 }
166 \f
167 static int
168 resolve_bind_address (const char *host, struct sockaddr *sa, int flags)
169 {
170   struct address_list *al;
171
172   /* #### Shouldn't we do this only once?  opt.bind_address won't
173      change during a Wget run!  */
174
175   al = lookup_host (host, flags | LH_SILENT | LH_PASSIVE);
176   if (al == NULL)
177     {
178       /* #### We should print the error message here. */
179       logprintf (LOG_NOTQUIET,
180                  _("%s: unable to resolve bind address `%s'; disabling bind.\n"),
181                  exec_name, opt.bind_address);
182       return 0;
183     }
184
185   /* Pick the first address in the list and use it as bind address.
186      Perhaps we should try multiple addresses, but I don't think
187      that's necessary in practice.  */
188   sockaddr_set_data (sa, address_list_address_at (al, 0), 0);
189   address_list_release (al);
190   return 1;
191 }
192 \f
193 struct cwt_context {
194   int fd;
195   const struct sockaddr *addr;
196   socklen_t addrlen;
197   int result;
198 };
199
200 static void
201 connect_with_timeout_callback (void *arg)
202 {
203   struct cwt_context *ctx = (struct cwt_context *)arg;
204   ctx->result = connect (ctx->fd, ctx->addr, ctx->addrlen);
205 }
206
207 /* Like connect, but specifies a timeout.  If connecting takes longer
208    than TIMEOUT seconds, -1 is returned and errno is set to
209    ETIMEDOUT.  */
210
211 static int
212 connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen,
213                       double timeout)
214 {
215   struct cwt_context ctx;
216   ctx.fd = fd;
217   ctx.addr = addr;
218   ctx.addrlen = addrlen;
219
220   if (run_with_timeout (timeout, connect_with_timeout_callback, &ctx))
221     {
222       errno = ETIMEDOUT;
223       return -1;
224     }
225   if (ctx.result == -1 && errno == EINTR)
226     errno = ETIMEDOUT;
227   return ctx.result;
228 }
229 \f
230 /* Connect to a remote endpoint whose IP address is known.  */
231
232 int
233 connect_to_ip (const ip_address *ip, int port, const char *print)
234 {
235   struct sockaddr_storage ss;
236   struct sockaddr *sa = (struct sockaddr *)&ss;
237   int sock = -1;
238
239   /* If PRINT is non-NULL, print the "Connecting to..." line, with
240      PRINT being the host name we're connecting to.  */
241   if (print)
242     {
243       const char *txt_addr = pretty_print_address (ip);
244       if (print && 0 != strcmp (print, txt_addr))
245         logprintf (LOG_VERBOSE,
246                    _("Connecting to %s|%s|:%d... "), print, txt_addr, port);
247       else
248         logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
249     }
250
251   /* Store the sockaddr info to SA.  */
252   sockaddr_set_data (sa, ip, port);
253
254   /* Create the socket of the family appropriate for the address.  */
255   sock = socket (sa->sa_family, SOCK_STREAM, 0);
256   if (sock < 0)
257     goto err;
258
259   /* For very small rate limits, set the buffer size (and hence,
260      hopefully, the kernel's TCP window size) to the per-second limit.
261      That way we should never have to sleep for more than 1s between
262      network reads.  */
263   if (opt.limit_rate && opt.limit_rate < 8192)
264     {
265       int bufsize = opt.limit_rate;
266       if (bufsize < 512)
267         bufsize = 512;          /* avoid pathologically small values */
268 #ifdef SO_RCVBUF
269       setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
270                   (void *)&bufsize, (socklen_t)sizeof (bufsize));
271 #endif
272       /* When we add limit_rate support for writing, which is useful
273          for POST, we should also set SO_SNDBUF here.  */
274     }
275
276   if (opt.bind_address)
277     {
278       /* Bind the client side of the socket to the requested
279          address.  */
280       struct sockaddr_storage bind_ss;
281       struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss;
282       if (resolve_bind_address (opt.bind_address, bind_sa, 0))
283         {
284           if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
285             goto err;
286         }
287     }
288
289   /* Connect the socket to the remote endpoint.  */
290   if (connect_with_timeout (sock, sa, sockaddr_size (sa),
291                             opt.connect_timeout) < 0)
292     goto err;
293
294   /* Success. */
295   assert (sock >= 0);
296   if (print)
297     logprintf (LOG_VERBOSE, _("connected.\n"));
298   DEBUGP (("Created socket %d.\n", sock));
299   return sock;
300
301  err:
302   {
303     /* Protect errno from possible modifications by close and
304        logprintf.  */
305     int save_errno = errno;
306     if (sock >= 0)
307       CLOSE (sock);
308     if (print)
309       logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
310     errno = save_errno;
311     return -1;
312   }
313 }
314
315 /* Connect to a remote endpoint specified by host name.  */
316
317 int
318 connect_to_host (const char *host, int port)
319 {
320   int i, start, end;
321   struct address_list *al;
322   int sock = -1;
323
324  again:
325   al = lookup_host (host, 0);
326   if (!al)
327     return E_HOST;
328
329   address_list_get_bounds (al, &start, &end);
330   for (i = start; i < end; i++)
331     {
332       const ip_address *ip = address_list_address_at (al, i);
333       sock = connect_to_ip (ip, port, host);
334       if (sock >= 0)
335         /* Success. */
336         break;
337
338       address_list_set_faulty (al, i);
339
340       /* The attempt to connect has failed.  Continue with the loop
341          and try next address. */
342     }
343   address_list_release (al);
344
345   if (sock < 0 && address_list_cached_p (al))
346     {
347       /* We were unable to connect to any address in a list we've
348          obtained from cache.  There is a possibility that the host is
349          under dynamic DNS and has changed its address.  Resolve it
350          again.  */
351       forget_host_lookup (host);
352       goto again;
353     }
354
355   return sock;
356 }
357
358 int
359 test_socket_open (int sock)
360 {
361 #ifdef HAVE_SELECT
362   fd_set check_set;
363   struct timeval to;
364
365   /* Check if we still have a valid (non-EOF) connection.  From Andrew
366    * Maholski's code in the Unix Socket FAQ.  */
367
368   FD_ZERO (&check_set);
369   FD_SET (sock, &check_set);
370
371   /* Wait one microsecond */
372   to.tv_sec = 0;
373   to.tv_usec = 1;
374
375   /* If we get a timeout, then that means still connected */
376   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
377     {
378       /* Connection is valid (not EOF), so continue */
379       return 1;
380     }
381   else
382     return 0;
383 #else
384   /* Without select, it's hard to know for sure. */
385   return 1;
386 #endif
387 }
388
389 /* Create a socket and bind it to PORT locally.  Calling accept() on
390    such a socket waits for and accepts incoming TCP connections.  The
391    resulting socket is stored to LOCAL_SOCK.  */
392
393 uerr_t
394 bindport (const ip_address *bind_address, int *port, int *local_sock)
395 {
396   int sock;
397   int family = AF_INET;
398   struct sockaddr_storage ss;
399   struct sockaddr *sa = (struct sockaddr *)&ss;
400   xzero (ss);
401
402   /* For setting options with setsockopt. */
403   int setopt_val = 1;
404   void *setopt_ptr = (void *)&setopt_val;
405   socklen_t setopt_size = sizeof (setopt_val);
406
407 #ifdef ENABLE_IPV6
408   if (bind_address->type == IPV6_ADDRESS) 
409     family = AF_INET6;
410 #endif
411
412   if ((sock = socket (family, SOCK_STREAM, 0)) < 0)
413     return CONSOCKERR;
414
415 #ifdef SO_REUSEADDR
416   setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size);
417 #endif
418
419 #ifdef ENABLE_IPV6
420 # ifdef HAVE_IPV6_V6ONLY
421   if (family == AF_INET6)
422     setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, setopt_ptr, setopt_size);
423 # endif
424 #endif
425
426   sockaddr_set_data (sa, bind_address, *port);
427   if (bind (sock, sa, sockaddr_size (sa)) < 0)
428     {
429       CLOSE (sock);
430       return BINDERR;
431     }
432   DEBUGP (("Local socket fd %d bound.\n", sock));
433   if (!*port)
434     {
435       socklen_t sa_len = sockaddr_size (sa);
436       if (getsockname (sock, sa, &sa_len) < 0)
437         {
438           CLOSE (sock);
439           return CONPORTERR;
440         }
441       sockaddr_get_data (sa, NULL, port);
442       DEBUGP (("binding to address %s using port %i.\n", 
443                pretty_print_address (bind_address), *port));
444     }
445   if (listen (sock, 1) < 0)
446     {
447       CLOSE (sock);
448       return LISTENERR;
449     }
450   *local_sock = sock;
451   return BINDOK;
452 }
453
454 #ifdef HAVE_SELECT
455 /* Wait for file descriptor FD to be readable or writable or both,
456    timing out after MAXTIME seconds.  Returns 1 if FD is available, 0
457    for timeout and -1 for error.  The argument WHAT can be a
458    combination of WAIT_READ and WAIT_WRITE.
459
460    This is a mere convenience wrapper around the select call, and
461    should be taken as such.  */
462
463 int
464 select_fd (int fd, double maxtime, int wait)
465 {
466   fd_set fdset;
467   fd_set *rd = NULL, *wr = NULL;
468   struct timeval tmout;
469   int result;
470
471   FD_ZERO (&fdset);
472   FD_SET (fd, &fdset);
473   if (wait & WAIT_READ)
474     rd = &fdset;
475   if (wait & WAIT_WRITE)
476     wr = &fdset;
477
478   tmout.tv_sec = (long)maxtime;
479   tmout.tv_usec = 1000000L * (maxtime - (long)maxtime);
480
481   do
482     result = select (fd + 1, rd, wr, NULL, &tmout);
483   while (result < 0 && errno == EINTR);
484
485   /* When we've timed out, set errno to ETIMEDOUT for the convenience
486      of the caller. */
487   if (result == 0)
488     errno = ETIMEDOUT;
489
490   return result;
491 }
492 #endif /* HAVE_SELECT */
493
494 /* Accept a connection on LOCAL_SOCK, and store the new socket to
495    *SOCK.  It blocks the caller until a connection is established.  If
496    no connection is established for opt.connect_timeout seconds, the
497    function exits with an error status.  */
498
499 uerr_t
500 acceptport (int local_sock, int *sock)
501 {
502   struct sockaddr_storage ss;
503   struct sockaddr *sa = (struct sockaddr *)&ss;
504   socklen_t addrlen = sizeof (ss);
505
506 #ifdef HAVE_SELECT
507   if (opt.connect_timeout)
508     if (select_fd (local_sock, opt.connect_timeout, WAIT_READ) <= 0)
509       return ACCEPTERR;
510 #endif
511   if ((*sock = accept (local_sock, sa, &addrlen)) < 0)
512     return ACCEPTERR;
513   DEBUGP (("Created socket fd %d.\n", *sock));
514   return ACCEPTOK;
515 }
516
517 /* Return the local IP address associated with the connection on FD.  */
518
519 int
520 conaddr (int fd, ip_address *ip)
521 {
522   struct sockaddr_storage storage;
523   struct sockaddr *sockaddr = (struct sockaddr *)&storage;
524   socklen_t addrlen = sizeof (storage);
525
526   if (getsockname (fd, sockaddr, &addrlen) < 0)
527     return 0;
528
529   switch (sockaddr->sa_family)
530     {
531 #ifdef ENABLE_IPV6
532     case AF_INET6:
533       {
534         struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
535         ip->type = IPV6_ADDRESS;
536         ADDRESS_IPV6_IN6_ADDR (ip) = sa6->sin6_addr;
537 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
538         ADDRESS_IPV6_SCOPE (ip) = sa6->sin6_scope_id;
539 #endif
540         DEBUGP (("conaddr is: %s\n", pretty_print_address (ip)));
541         return 1;
542       }
543 #endif
544     case AF_INET:
545       {
546         struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
547         ip->type = IPV4_ADDRESS;
548         ADDRESS_IPV4_IN_ADDR (ip) = sa->sin_addr;
549         DEBUGP (("conaddr is: %s\n", pretty_print_address (ip)));
550         return 1;
551       }
552     default:
553       abort ();
554     }
555
556   return 0;
557 }
558
559 /* Read at most LEN bytes from FD, storing them to BUF.  This is
560    virtually the same as read(), but takes care of EINTR braindamage
561    and uses select() to timeout the stale connections (a connection is
562    stale if more than OPT.READ_TIMEOUT time is spent in select() or
563    read()).  */
564
565 int
566 iread (int fd, char *buf, int len)
567 {
568   int res;
569
570 #ifdef HAVE_SELECT
571   if (opt.read_timeout)
572     if (select_fd (fd, opt.read_timeout, WAIT_READ) <= 0)
573       return -1;
574 #endif
575   do
576     res = READ (fd, buf, len);
577   while (res == -1 && errno == EINTR);
578
579   return res;
580 }
581
582 /* Write LEN bytes from BUF to FD.  This is similar to iread(), but
583    unlike iread(), it makes sure that all of BUF is actually written
584    to FD, so callers needn't bother with checking that the return
585    value equals to LEN.  Instead, you should simply check for -1.  */
586
587 int
588 iwrite (int fd, char *buf, int len)
589 {
590   int res = 0;
591
592   /* `write' may write less than LEN bytes, thus the outward loop
593      keeps trying it until all was written, or an error occurred.  The
594      inner loop is reserved for the usual EINTR f*kage, and the
595      innermost loop deals with the same during select().  */
596   while (len > 0)
597     {
598 #ifdef HAVE_SELECT
599       if (opt.read_timeout)
600         if (select_fd (fd, opt.read_timeout, WAIT_WRITE) <= 0)
601           return -1;
602 #endif
603       do
604         res = WRITE (fd, buf, len);
605       while (res == -1 && errno == EINTR);
606       if (res <= 0)
607         break;
608       buf += res;
609       len -= res;
610     }
611   return res;
612 }