]> sjero.net Git - wget/blob - src/connect.c
[svn] Use new macros xnew, xnew0, xnew_array, and xnew0_array in various places.
[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       logprintf (LOG_NOTQUIET,
179                  _("Unable to convert `%s' to a bind address.  Reverting to ANY.\n"),
180                  opt.bind_address);
181       return 0;
182     }
183
184   /* Pick the first address in the list and use it as bind address.
185      Perhaps we should try multiple addresses, but I don't think
186      that's necessary in practice.  */
187   sockaddr_set_data (sa, address_list_address_at (al, 0), 0);
188   address_list_release (al);
189   return 1;
190 }
191 \f
192 struct cwt_context {
193   int fd;
194   const struct sockaddr *addr;
195   socklen_t addrlen;
196   int result;
197 };
198
199 static void
200 connect_with_timeout_callback (void *arg)
201 {
202   struct cwt_context *ctx = (struct cwt_context *)arg;
203   ctx->result = connect (ctx->fd, ctx->addr, ctx->addrlen);
204 }
205
206 /* Like connect, but specifies a timeout.  If connecting takes longer
207    than TIMEOUT seconds, -1 is returned and errno is set to
208    ETIMEDOUT.  */
209
210 static int
211 connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen,
212                       double timeout)
213 {
214   struct cwt_context ctx;
215   ctx.fd = fd;
216   ctx.addr = addr;
217   ctx.addrlen = addrlen;
218
219   if (run_with_timeout (timeout, connect_with_timeout_callback, &ctx))
220     {
221       errno = ETIMEDOUT;
222       return -1;
223     }
224   if (ctx.result == -1 && errno == EINTR)
225     errno = ETIMEDOUT;
226   return ctx.result;
227 }
228 \f
229 /* Connect to a remote endpoint whose IP address is known.  */
230
231 int
232 connect_to_ip (const ip_address *ip, int port, const char *print)
233 {
234   struct sockaddr_storage ss;
235   struct sockaddr *sa = (struct sockaddr *)&ss;
236   int sock, save_errno;
237
238   /* If PRINT is non-NULL, print the "Connecting to..." line, with
239      PRINT being the host name we're connecting to.  */
240   if (print)
241     {
242       const char *txt_addr = pretty_print_address (ip);
243       if (print && 0 != strcmp (print, txt_addr))
244         logprintf (LOG_VERBOSE,
245                    _("Connecting to %s{%s}:%d... "), print, txt_addr, port);
246       else
247         logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
248     }
249
250   /* Store the sockaddr info to SA.  */
251   sockaddr_set_data (sa, ip, port);
252
253   /* Create the socket of the family appropriate for the address.  */
254   sock = socket (sa->sa_family, SOCK_STREAM, 0);
255   if (sock < 0)
256     goto out;
257
258   /* For very small rate limits, set the buffer size (and hence,
259      hopefully, the kernel's TCP window size) to the per-second limit.
260      That way we should never have to sleep for more than 1s between
261      network reads.  */
262   if (opt.limit_rate && opt.limit_rate < 8192)
263     {
264       int bufsize = opt.limit_rate;
265       if (bufsize < 512)
266         bufsize = 512;          /* avoid pathologically small values */
267 #ifdef SO_RCVBUF
268       setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
269                   (void *)&bufsize, (socklen_t)sizeof (bufsize));
270 #endif
271       /* When we add limit_rate support for writing, which is useful
272          for POST, we should also set SO_SNDBUF here.  */
273     }
274
275   if (opt.bind_address)
276     {
277       /* Bind the client side of the socket to the requested
278          address.  */
279       struct sockaddr_storage bind_ss;
280       struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss;
281       if (resolve_bind_address (opt.bind_address, bind_sa, 0))
282         {
283           if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
284             {
285               CLOSE (sock);
286               sock = -1;
287               goto out;
288             }
289         }
290     }
291
292   /* Connect the socket to the remote endpoint.  */
293   if (connect_with_timeout (sock, sa, sockaddr_size (sa),
294                             opt.connect_timeout) < 0)
295     {
296       CLOSE (sock);
297       sock = -1;
298       goto out;
299     }
300
301  out:
302   if (sock >= 0)
303     {
304       /* Success. */
305       if (print)
306         logprintf (LOG_VERBOSE, _("connected.\n"));
307       DEBUGP (("Created socket %d.\n", sock));
308     }
309   else
310     {
311       save_errno = errno;
312       if (print)
313         logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
314       errno = save_errno;
315     }
316
317   return sock;
318 }
319
320 /* Connect to a remote endpoint specified by host name.  */
321
322 int
323 connect_to_host (const char *host, int port)
324 {
325   int i, start, end;
326   struct address_list *al;
327   int sock = -1;
328
329  again:
330   al = lookup_host (host, 0);
331   if (!al)
332     return E_HOST;
333
334   address_list_get_bounds (al, &start, &end);
335   for (i = start; i < end; i++)
336     {
337       const ip_address *ip = address_list_address_at (al, i);
338       sock = connect_to_ip (ip, port, host);
339       if (sock >= 0)
340         /* Success. */
341         break;
342
343       address_list_set_faulty (al, i);
344
345       /* The attempt to connect has failed.  Continue with the loop
346          and try next address. */
347     }
348   address_list_release (al);
349
350   if (sock < 0 && address_list_cached_p (al))
351     {
352       /* We were unable to connect to any address in a list we've
353          obtained from cache.  There is a possibility that the host is
354          under dynamic DNS and has changed its address.  Resolve it
355          again.  */
356       forget_host_lookup (host);
357       goto again;
358     }
359
360   return sock;
361 }
362
363 int
364 test_socket_open (int sock)
365 {
366 #ifdef HAVE_SELECT
367   fd_set check_set;
368   struct timeval to;
369
370   /* Check if we still have a valid (non-EOF) connection.  From Andrew
371    * Maholski's code in the Unix Socket FAQ.  */
372
373   FD_ZERO (&check_set);
374   FD_SET (sock, &check_set);
375
376   /* Wait one microsecond */
377   to.tv_sec = 0;
378   to.tv_usec = 1;
379
380   /* If we get a timeout, then that means still connected */
381   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
382     {
383       /* Connection is valid (not EOF), so continue */
384       return 1;
385     }
386   else
387     return 0;
388 #else
389   /* Without select, it's hard to know for sure. */
390   return 1;
391 #endif
392 }
393
394 /* Create a socket and bind it to PORT locally.  Calling accept() on
395    such a socket waits for and accepts incoming TCP connections.  The
396    resulting socket is stored to LOCAL_SOCK.  */
397
398 uerr_t
399 bindport (const ip_address *bind_address, int *port, int *local_sock)
400 {
401   int msock;
402   int family = AF_INET;
403   int optval;
404   struct sockaddr_storage ss;
405   struct sockaddr *sa = (struct sockaddr *)&ss;
406   xzero (ss);
407
408 #ifdef ENABLE_IPV6
409   if (bind_address->type == IPV6_ADDRESS) 
410     family = AF_INET6;
411 #endif
412
413   if ((msock = socket (family, SOCK_STREAM, 0)) < 0)
414     return CONSOCKERR;
415
416 #ifdef SO_REUSEADDR
417   optval = 1;
418   if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
419                   (void *)&optval, (socklen_t)sizeof (optval)) < 0)
420     {
421       CLOSE (msock);
422       return CONSOCKERR;
423     }
424 #endif
425
426 #ifdef ENABLE_IPV6
427 # ifdef HAVE_IPV6_V6ONLY
428   if (family == AF_INET6)
429     {
430       optval = 1;
431       /* if setsockopt fails, go on anyway */
432       setsockopt (msock, IPPROTO_IPV6, IPV6_V6ONLY,
433                   (void *)&optval, (socklen_t)sizeof (optval));
434     }
435 # endif
436 #endif
437
438   sockaddr_set_data (sa, bind_address, *port);
439   if (bind (msock, sa, sockaddr_size (sa)) < 0)
440     {
441       CLOSE (msock);
442       return BINDERR;
443     }
444   DEBUGP (("Local socket fd %d bound.\n", msock));
445   if (!*port)
446     {
447       socklen_t sa_len = sockaddr_size (sa);
448       if (getsockname (msock, sa, &sa_len) < 0)
449         {
450           CLOSE (msock);
451           return CONPORTERR;
452         }
453       sockaddr_get_data (sa, NULL, port);
454       DEBUGP (("binding to address %s using port %i.\n", 
455                pretty_print_address (bind_address), *port));
456     }
457   if (listen (msock, 1) < 0)
458     {
459       CLOSE (msock);
460       return LISTENERR;
461     }
462   *local_sock = msock;
463   return BINDOK;
464 }
465
466 #ifdef HAVE_SELECT
467 /* Wait for file descriptor FD to be available, timing out after
468    MAXTIME seconds.  "Available" means readable if writep is 0,
469    writeable otherwise.
470
471    Returns 1 if FD is available, 0 for timeout and -1 for error.  */
472
473 int
474 select_fd (int fd, double maxtime, int writep)
475 {
476   fd_set fds;
477   fd_set *rd = NULL, *wrt = NULL;
478   struct timeval tmout;
479   int result;
480
481   FD_ZERO (&fds);
482   FD_SET (fd, &fds);
483   *(writep ? &wrt : &rd) = &fds;
484
485   tmout.tv_sec = (long)maxtime;
486   tmout.tv_usec = 1000000L * (maxtime - (long)maxtime);
487
488   do
489     result = select (fd + 1, rd, wrt, NULL, &tmout);
490   while (result < 0 && errno == EINTR);
491
492   /* When we've timed out, set errno to ETIMEDOUT for the convenience
493      of the caller. */
494   if (result == 0)
495     errno = ETIMEDOUT;
496
497   return result;
498 }
499 #endif /* HAVE_SELECT */
500
501 /* Accept a connection on LOCAL_SOCK, and store the new socket to
502    *SOCK.  It blocks the caller until a connection is established.  If
503    no connection is established for opt.connect_timeout seconds, the
504    function exits with an error status.  */
505
506 uerr_t
507 acceptport (int local_sock, int *sock)
508 {
509   struct sockaddr_storage ss;
510   struct sockaddr *sa = (struct sockaddr *)&ss;
511   socklen_t addrlen = sizeof (ss);
512
513 #ifdef HAVE_SELECT
514   if (select_fd (local_sock, opt.connect_timeout, 0) <= 0)
515     return ACCEPTERR;
516 #endif
517   if ((*sock = accept (local_sock, sa, &addrlen)) < 0)
518     return ACCEPTERR;
519   DEBUGP (("Created socket fd %d.\n", *sock));
520   return ACCEPTOK;
521 }
522
523 /* Return the local IP address associated with the connection on FD.  */
524
525 int
526 conaddr (int fd, ip_address *ip)
527 {
528   struct sockaddr_storage storage;
529   struct sockaddr *sockaddr = (struct sockaddr *)&storage;
530   socklen_t addrlen = sizeof (storage);
531
532   if (getsockname (fd, sockaddr, &addrlen) < 0)
533     return 0;
534
535   switch (sockaddr->sa_family)
536     {
537 #ifdef ENABLE_IPV6
538     case AF_INET6:
539       {
540         struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
541         ip->type = IPV6_ADDRESS;
542         ADDRESS_IPV6_IN6_ADDR (ip) = sa6->sin6_addr;
543 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
544         ADDRESS_IPV6_SCOPE (ip) = sa6->sin6_scope_id;
545 #endif
546         DEBUGP (("conaddr is: %s\n", pretty_print_address (ip)));
547         return 1;
548       }
549 #endif
550     case AF_INET:
551       {
552         struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
553         ip->type = IPV4_ADDRESS;
554         ADDRESS_IPV4_IN_ADDR (ip) = sa->sin_addr;
555         DEBUGP (("conaddr is: %s\n", pretty_print_address (ip)));
556         return 1;
557       }
558     default:
559       abort ();
560     }
561
562   return 0;
563 }
564
565 /* Read at most LEN bytes from FD, storing them to BUF.  This is
566    virtually the same as read(), but takes care of EINTR braindamage
567    and uses select() to timeout the stale connections (a connection is
568    stale if more than OPT.READ_TIMEOUT time is spent in select() or
569    read()).  */
570
571 int
572 iread (int fd, char *buf, int len)
573 {
574   int res;
575
576 #ifdef HAVE_SELECT
577   if (opt.read_timeout)
578     if (select_fd (fd, opt.read_timeout, 0) <= 0)
579       return -1;
580 #endif
581   do
582     res = READ (fd, buf, len);
583   while (res == -1 && errno == EINTR);
584
585   return res;
586 }
587
588 /* Write LEN bytes from BUF to FD.  This is similar to iread(), but
589    unlike iread(), it makes sure that all of BUF is actually written
590    to FD, so callers needn't bother with checking that the return
591    value equals to LEN.  Instead, you should simply check for -1.  */
592
593 int
594 iwrite (int fd, char *buf, int len)
595 {
596   int res = 0;
597
598   /* `write' may write less than LEN bytes, thus the outward loop
599      keeps trying it until all was written, or an error occurred.  The
600      inner loop is reserved for the usual EINTR f*kage, and the
601      innermost loop deals with the same during select().  */
602   while (len > 0)
603     {
604 #ifdef HAVE_SELECT
605       if (opt.read_timeout)
606         if (select_fd (fd, opt.read_timeout, 1) <= 0)
607           return -1;
608 #endif
609       do
610         res = WRITE (fd, buf, len);
611       while (res == -1 && errno == EINTR);
612       if (res <= 0)
613         break;
614       buf += res;
615       len -= res;
616     }
617   return res;
618 }