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