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