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