]> sjero.net Git - wget/blob - src/connect.c
[svn] New mechanism for quoting file names.
[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                       int 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   resolve_bind_address ();
180   if (bind_address_resolved)
181     {
182       /* Bind the client side to the requested address. */
183       wget_sockaddr bsa;
184       wget_sockaddr_set_address (&bsa, ip_default_family, 0, &bind_address);
185       if (bind (sock, &bsa.sa, sockaddr_len ()))
186         {
187           close (sock);
188           sock = -1;
189           goto out;
190         }
191     }
192
193   /* Connect the socket to the remote host.  */
194   if (connect_with_timeout (sock, &sa.sa, sockaddr_len (), opt.timeout) < 0)
195     {
196       close (sock);
197       sock = -1;
198       goto out;
199     }
200
201  out:
202   if (sock >= 0)
203     {
204       /* Success. */
205       if (!silent)
206         logprintf (LOG_VERBOSE, _("connected.\n"));
207       DEBUGP (("Created socket %d.\n", sock));
208     }
209   else
210     {
211       save_errno = errno;
212       if (!silent)
213         logprintf (LOG_VERBOSE, "failed: %s.\n", strerror (errno));
214       errno = save_errno;
215     }
216
217   return sock;
218 }
219
220 /* Connect to a remote host whose address has been resolved. */
221 int
222 connect_to_many (struct address_list *al, unsigned short port, int silent)
223 {
224   int i, start, end;
225
226   address_list_get_bounds (al, &start, &end);
227   for (i = start; i < end; i++)
228     {
229       ip_address addr;
230       int sock;
231       address_list_copy_one (al, i, &addr);
232
233       sock = connect_to_one (&addr, port, silent);
234       if (sock >= 0)
235         /* Success. */
236         return sock;
237
238       address_list_set_faulty (al, i);
239
240       /* The attempt to connect has failed.  Continue with the loop
241          and try next address. */
242     }
243
244   return -1;
245 }
246
247 int
248 test_socket_open (int sock)
249 {
250 #ifdef HAVE_SELECT
251   fd_set check_set;
252   struct timeval to;
253
254   /* Check if we still have a valid (non-EOF) connection.  From Andrew
255    * Maholski's code in the Unix Socket FAQ.  */
256
257   FD_ZERO (&check_set);
258   FD_SET (sock, &check_set);
259
260   /* Wait one microsecond */
261   to.tv_sec = 0;
262   to.tv_usec = 1;
263
264   /* If we get a timeout, then that means still connected */
265   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
266     {
267       /* Connection is valid (not EOF), so continue */
268       return 1;
269     }
270   else
271     return 0;
272 #else
273   /* Without select, it's hard to know for sure. */
274   return 1;
275 #endif
276 }
277
278 /* Bind the local port PORT.  This does all the necessary work, which
279    is creating a socket, setting SO_REUSEADDR option on it, then
280    calling bind() and listen().  If *PORT is 0, a random port is
281    chosen by the system, and its value is stored to *PORT.  The
282    internal variable MPORT is set to the value of the ensuing master
283    socket.  Call acceptport() to block for and accept a connection.  */
284 uerr_t
285 bindport (unsigned short *port, int family)
286 {
287   int optval = 1;
288   wget_sockaddr srv;
289   memset (&srv, 0, sizeof (wget_sockaddr));
290
291   msock = -1;
292
293   if ((msock = socket (family, SOCK_STREAM, 0)) < 0)
294     return CONSOCKERR;
295   if (setsockopt (msock, SOL_SOCKET, SO_REUSEADDR,
296                   (char *)&optval, sizeof (optval)) < 0)
297     return CONSOCKERR;
298
299   resolve_bind_address ();
300   wget_sockaddr_set_address (&srv, ip_default_family, htons (*port),
301                              bind_address_resolved ? &bind_address : NULL);
302   if (bind (msock, &srv.sa, sockaddr_len ()) < 0)
303     {
304       CLOSE (msock);
305       msock = -1;
306       return BINDERR;
307     }
308   DEBUGP (("Master socket fd %d bound.\n", msock));
309   if (!*port)
310     {
311       /* #### addrlen should be a 32-bit type, which int is not
312          guaranteed to be.  Oh, and don't try to make it a size_t,
313          because that can be 64-bit.  */
314       int sa_len = sockaddr_len ();
315       if (getsockname (msock, &srv.sa, &sa_len) < 0)
316         {
317           CLOSE (msock);
318           msock = -1;
319           return CONPORTERR;
320         }
321       *port = wget_sockaddr_get_port (&srv);
322       DEBUGP (("using port %i.\n", *port));
323     }
324   if (listen (msock, 1) < 0)
325     {
326       CLOSE (msock);
327       msock = -1;
328       return LISTENERR;
329     }
330   return BINDOK;
331 }
332
333 #ifdef HAVE_SELECT
334 /* Wait for file descriptor FD to be available, timing out after
335    MAXTIME seconds.  "Available" means readable if writep is 0,
336    writeable otherwise.
337
338    Returns 1 if FD is available, 0 for timeout and -1 for error.  */
339
340 int
341 select_fd (int fd, int maxtime, int writep)
342 {
343   fd_set fds;
344   fd_set *rd = NULL, *wrt = NULL;
345   struct timeval tmout;
346   int result;
347
348   FD_ZERO (&fds);
349   FD_SET (fd, &fds);
350   *(writep ? &wrt : &rd) = &fds;
351
352   tmout.tv_sec = maxtime;
353   tmout.tv_usec = 0;
354
355   do
356     result = select (fd + 1, rd, wrt, NULL, &tmout);
357   while (result < 0 && errno == EINTR);
358
359   /* When we've timed out, set errno to ETIMEDOUT for the convenience
360      of the caller. */
361   if (result == 0)
362     errno = ETIMEDOUT;
363
364   return result;
365 }
366 #endif /* HAVE_SELECT */
367
368 /* Call accept() on MSOCK and store the result to *SOCK.  This assumes
369    that bindport() has been used to initialize MSOCK to a correct
370    value.  It blocks the caller until a connection is established.  If
371    no connection is established for OPT.TIMEOUT seconds, the function
372    exits with an error status.  */
373 uerr_t
374 acceptport (int *sock)
375 {
376   int addrlen = sockaddr_len ();
377
378 #ifdef HAVE_SELECT
379   if (select_fd (msock, opt.timeout, 0) <= 0)
380     return ACCEPTERR;
381 #endif
382   if ((*sock = accept (msock, addr, &addrlen)) < 0)
383     return ACCEPTERR;
384   DEBUGP (("Created socket fd %d.\n", *sock));
385   return ACCEPTOK;
386 }
387
388 /* Close SOCK, as well as the most recently remembered MSOCK, created
389    via bindport().  If SOCK is -1, close MSOCK only.  */
390 void
391 closeport (int sock)
392 {
393   /*shutdown (sock, 2);*/
394   if (sock != -1)
395     CLOSE (sock);
396   if (msock != -1)
397     CLOSE (msock);
398   msock = -1;
399 }
400
401 /* Return the local IP address associated with the connection on FD.  */
402
403 int
404 conaddr (int fd, ip_address *ip)
405 {
406   wget_sockaddr mysrv;
407
408   /* see bindport() for discussion of using `int' here. */
409   int addrlen = sizeof (mysrv); 
410
411   if (getsockname (fd, &mysrv.sa, (int *)&addrlen) < 0)
412     return 0;
413
414   switch (mysrv.sa.sa_family)
415     {
416 #ifdef ENABLE_IPV6
417     case AF_INET6:
418       memcpy (ip, &mysrv.sin6.sin6_addr, 16);
419       return 1;
420 #endif
421     case AF_INET:
422       map_ipv4_to_ip ((ip4_address *)&mysrv.sin.sin_addr, ip);
423       return 1;
424     default:
425       abort ();
426     }
427   return 0;
428 }
429
430 /* Read at most LEN bytes from FD, storing them to BUF.  This is
431    virtually the same as read(), but takes care of EINTR braindamage
432    and uses select() to timeout the stale connections (a connection is
433    stale if more than OPT.TIMEOUT time is spent in select() or
434    read()).  */
435
436 int
437 iread (int fd, char *buf, int len)
438 {
439   int res;
440
441 #ifdef HAVE_SELECT
442   if (opt.timeout)
443     if (select_fd (fd, opt.timeout, 0) <= 0)
444       return -1;
445 #endif
446   do
447     res = READ (fd, buf, len);
448   while (res == -1 && errno == EINTR);
449
450   return res;
451 }
452
453 /* Write LEN bytes from BUF to FD.  This is similar to iread(), but
454    unlike iread(), it makes sure that all of BUF is actually written
455    to FD, so callers needn't bother with checking that the return
456    value equals to LEN.  Instead, you should simply check for -1.  */
457
458 int
459 iwrite (int fd, char *buf, int len)
460 {
461   int res = 0;
462
463   /* `write' may write less than LEN bytes, thus the outward loop
464      keeps trying it until all was written, or an error occurred.  The
465      inner loop is reserved for the usual EINTR f*kage, and the
466      innermost loop deals with the same during select().  */
467   while (len > 0)
468     {
469 #ifdef HAVE_SELECT
470       if (opt.timeout)
471         if (select_fd (fd, opt.timeout, 1) <= 0)
472           return -1;
473 #endif
474       do
475         res = WRITE (fd, buf, len);
476       while (res == -1 && errno == EINTR);
477       if (res <= 0)
478         break;
479       buf += res;
480       len -= res;
481     }
482   return res;
483 }