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