]> sjero.net Git - wget/blob - src/connect.c
[svn] Merge of fix for bugs 20341 and 20410.
[wget] / src / connect.c
1 /* Establishing and handling network connections.
2    Copyright (C) 1996-2006 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 3 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, see <http://www.gnu.org/licenses/>.
18
19 In addition, as a special exception, the Free Software Foundation
20 gives permission to link the code of its release of Wget with the
21 OpenSSL project's "OpenSSL" library (or with modified versions of it
22 that use the same license as the "OpenSSL" library), and distribute
23 the linked executables.  You must obey the GNU General Public License
24 in all respects for all of the code used other than "OpenSSL".  If you
25 modify this file, you may extend this exception to your version of the
26 file, but you are not obligated to do so.  If you do not wish to do
27 so, delete this exception statement from your version.  */
28
29 #include <config.h>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #ifdef HAVE_UNISTD_H
34 # include <unistd.h>
35 #endif
36 #include <assert.h>
37
38 #ifndef WINDOWS
39 # include <sys/socket.h>
40 # include <netdb.h>
41 # include <netinet/in.h>
42 # ifndef __BEOS__
43 #  include <arpa/inet.h>
44 # endif
45 #endif /* not WINDOWS */
46
47 #include <errno.h>
48 #include <string.h>
49 #ifdef HAVE_SYS_SELECT_H
50 # include <sys/select.h>
51 #endif /* HAVE_SYS_SELECT_H */
52
53 #include "wget.h"
54 #include "utils.h"
55 #include "host.h"
56 #include "connect.h"
57 #include "hash.h"
58
59 /* Define sockaddr_storage where unavailable (presumably on IPv4-only
60    hosts).  */
61
62 #ifndef ENABLE_IPV6
63 # ifndef HAVE_STRUCT_SOCKADDR_STORAGE
64 #  define sockaddr_storage sockaddr_in
65 # endif
66 #endif /* ENABLE_IPV6 */
67
68 /* Fill SA as per the data in IP and PORT.  SA shoult point to struct
69    sockaddr_storage if ENABLE_IPV6 is defined, to struct sockaddr_in
70    otherwise.  */
71
72 static void
73 sockaddr_set_data (struct sockaddr *sa, const ip_address *ip, int port)
74 {
75   switch (ip->family)
76     {
77     case AF_INET:
78       {
79         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
80         xzero (*sin);
81         sin->sin_family = AF_INET;
82         sin->sin_port = htons (port);
83         sin->sin_addr = ip->data.d4;
84         break;
85       }
86 #ifdef ENABLE_IPV6
87     case AF_INET6:
88       {
89         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
90         xzero (*sin6);
91         sin6->sin6_family = AF_INET6;
92         sin6->sin6_port = htons (port);
93         sin6->sin6_addr = ip->data.d6;
94 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
95         sin6->sin6_scope_id = ip->ipv6_scope;
96 #endif
97         break;
98       }
99 #endif /* ENABLE_IPV6 */
100     default:
101       abort ();
102     }
103 }
104
105 /* Get the data of SA, specifically the IP address and the port.  If
106    you're not interested in one or the other information, pass NULL as
107    the pointer.  */
108
109 static void
110 sockaddr_get_data (const struct sockaddr *sa, ip_address *ip, int *port)
111 {
112   switch (sa->sa_family)
113     {
114     case AF_INET:
115       {
116         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
117         if (ip)
118           {
119             ip->family = AF_INET;
120             ip->data.d4 = sin->sin_addr;
121           }
122         if (port)
123           *port = ntohs (sin->sin_port);
124         break;
125       }
126 #ifdef ENABLE_IPV6
127     case AF_INET6:
128       {
129         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
130         if (ip)
131           {
132             ip->family = AF_INET6;
133             ip->data.d6 = sin6->sin6_addr;
134 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
135             ip->ipv6_scope = sin6->sin6_scope_id;
136 #endif
137           }
138         if (port)
139           *port = ntohs (sin6->sin6_port);
140         break;
141       }
142 #endif
143     default:
144       abort ();
145     }
146 }
147
148 /* Return the size of the sockaddr structure depending on its
149    family.  */
150
151 static socklen_t
152 sockaddr_size (const struct sockaddr *sa)
153 {
154   switch (sa->sa_family)
155     {
156     case AF_INET:
157       return sizeof (struct sockaddr_in);
158 #ifdef ENABLE_IPV6
159     case AF_INET6:
160       return sizeof (struct sockaddr_in6);
161 #endif
162     default:
163       abort ();
164     }
165 }
166 \f
167 /* Resolve the bind address specified via --bind-address and store it
168    to SA.  The resolved value is stored in a static variable and
169    reused after the first invocation of this function.
170
171    Returns true on success, false on failure.  */
172
173 static bool
174 resolve_bind_address (struct sockaddr *sa)
175 {
176   struct address_list *al;
177
178   /* Make sure this is called only once.  opt.bind_address doesn't
179      change during a Wget run.  */
180   static bool called, should_bind;
181   static ip_address ip;
182   if (called)
183     {
184       if (should_bind)
185         sockaddr_set_data (sa, &ip, 0);
186       return should_bind;
187     }
188   called = true;
189
190   al = lookup_host (opt.bind_address, LH_BIND | LH_SILENT);
191   if (!al)
192     {
193       /* #### We should be able to print the error message here. */
194       logprintf (LOG_NOTQUIET,
195                  _("%s: unable to resolve bind address `%s'; disabling bind.\n"),
196                  exec_name, opt.bind_address);
197       should_bind = false;
198       return false;
199     }
200
201   /* Pick the first address in the list and use it as bind address.
202      Perhaps we should try multiple addresses in succession, but I
203      don't think that's necessary in practice.  */
204   ip = *address_list_address_at (al, 0);
205   address_list_release (al);
206
207   sockaddr_set_data (sa, &ip, 0);
208   should_bind = true;
209   return true;
210 }
211 \f
212 struct cwt_context {
213   int fd;
214   const struct sockaddr *addr;
215   socklen_t addrlen;
216   int result;
217 };
218
219 static void
220 connect_with_timeout_callback (void *arg)
221 {
222   struct cwt_context *ctx = (struct cwt_context *)arg;
223   ctx->result = connect (ctx->fd, ctx->addr, ctx->addrlen);
224 }
225
226 /* Like connect, but specifies a timeout.  If connecting takes longer
227    than TIMEOUT seconds, -1 is returned and errno is set to
228    ETIMEDOUT.  */
229
230 static int
231 connect_with_timeout (int fd, const struct sockaddr *addr, socklen_t addrlen,
232                       double timeout)
233 {
234   struct cwt_context ctx;
235   ctx.fd = fd;
236   ctx.addr = addr;
237   ctx.addrlen = addrlen;
238
239   if (run_with_timeout (timeout, connect_with_timeout_callback, &ctx))
240     {
241       errno = ETIMEDOUT;
242       return -1;
243     }
244   if (ctx.result == -1 && errno == EINTR)
245     errno = ETIMEDOUT;
246   return ctx.result;
247 }
248 \f
249 /* Connect via TCP to the specified address and port.
250
251    If PRINT is non-NULL, it is the host name to print that we're
252    connecting to.  */
253
254 int
255 connect_to_ip (const ip_address *ip, int port, const char *print)
256 {
257   struct sockaddr_storage ss;
258   struct sockaddr *sa = (struct sockaddr *)&ss;
259   int sock;
260
261   /* If PRINT is non-NULL, print the "Connecting to..." line, with
262      PRINT being the host name we're connecting to.  */
263   if (print)
264     {
265       const char *txt_addr = print_address (ip);
266       if (print && 0 != strcmp (print, txt_addr))
267         logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
268                    escnonprint (print), txt_addr, port);
269       else
270         logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
271     }
272
273   /* Store the sockaddr info to SA.  */
274   sockaddr_set_data (sa, ip, port);
275
276   /* Create the socket of the family appropriate for the address.  */
277   sock = socket (sa->sa_family, SOCK_STREAM, 0);
278   if (sock < 0)
279     goto err;
280
281 #if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY)
282   if (opt.ipv6_only) {
283     int on = 1;
284     /* In case of error, we will go on anyway... */
285     int err = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on));
286     IF_DEBUG
287       if (err < 0) 
288         DEBUGP (("Failed setting IPV6_V6ONLY: %s", strerror (errno)));
289   }
290 #endif
291
292   /* For very small rate limits, set the buffer size (and hence,
293      hopefully, the kernel's TCP window size) to the per-second limit.
294      That way we should never have to sleep for more than 1s between
295      network reads.  */
296   if (opt.limit_rate && opt.limit_rate < 8192)
297     {
298       int bufsize = opt.limit_rate;
299       if (bufsize < 512)
300         bufsize = 512;          /* avoid pathologically small values */
301 #ifdef SO_RCVBUF
302       setsockopt (sock, SOL_SOCKET, SO_RCVBUF,
303                   (void *)&bufsize, (socklen_t)sizeof (bufsize));
304 #endif
305       /* When we add limit_rate support for writing, which is useful
306          for POST, we should also set SO_SNDBUF here.  */
307     }
308
309   if (opt.bind_address)
310     {
311       /* Bind the client side of the socket to the requested
312          address.  */
313       struct sockaddr_storage bind_ss;
314       struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss;
315       if (resolve_bind_address (bind_sa))
316         {
317           if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
318             goto err;
319         }
320     }
321
322   /* Connect the socket to the remote endpoint.  */
323   if (connect_with_timeout (sock, sa, sockaddr_size (sa),
324                             opt.connect_timeout) < 0)
325     goto err;
326
327   /* Success. */
328   assert (sock >= 0);
329   if (print)
330     logprintf (LOG_VERBOSE, _("connected.\n"));
331   DEBUGP (("Created socket %d.\n", sock));
332   return sock;
333
334  err:
335   {
336     /* Protect errno from possible modifications by close and
337        logprintf.  */
338     int save_errno = errno;
339     if (sock >= 0)
340       fd_close (sock);
341     if (print)
342       logprintf (LOG_VERBOSE, _("failed: %s.\n"), strerror (errno));
343     errno = save_errno;
344     return -1;
345   }
346 }
347
348 /* Connect via TCP to a remote host on the specified port.
349
350    HOST is resolved as an Internet host name.  If HOST resolves to
351    more than one IP address, they are tried in the order returned by
352    DNS until connecting to one of them succeeds.  */
353
354 int
355 connect_to_host (const char *host, int port)
356 {
357   int i, start, end;
358   int sock;
359
360   struct address_list *al = lookup_host (host, 0);
361
362  retry:
363   if (!al)
364     return E_HOST;
365
366   address_list_get_bounds (al, &start, &end);
367   for (i = start; i < end; i++)
368     {
369       const ip_address *ip = address_list_address_at (al, i);
370       sock = connect_to_ip (ip, port, host);
371       if (sock >= 0)
372         {
373           /* Success. */
374           address_list_set_connected (al);
375           address_list_release (al);
376           return sock;
377         }
378
379       /* The attempt to connect has failed.  Continue with the loop
380          and try next address. */
381
382       address_list_set_faulty (al, i);
383     }
384
385   /* Failed to connect to any of the addresses in AL. */
386
387   if (address_list_connected_p (al))
388     {
389       /* We connected to AL before, but cannot do so now.  That might
390          indicate that our DNS cache entry for HOST has expired.  */
391       address_list_release (al);
392       al = lookup_host (host, LH_REFRESH);
393       goto retry;
394     }
395   address_list_release (al);
396
397   return -1;
398 }
399 \f
400 /* Create a socket, bind it to local interface BIND_ADDRESS on port
401    *PORT, set up a listen backlog, and return the resulting socket, or
402    -1 in case of error.
403
404    BIND_ADDRESS is the address of the interface to bind to.  If it is
405    NULL, the socket is bound to the default address.  PORT should
406    point to the port number that will be used for the binding.  If
407    that number is 0, the system will choose a suitable port, and the
408    chosen value will be written to *PORT.
409
410    Calling accept() on such a socket waits for and accepts incoming
411    TCP connections.  */
412
413 int
414 bind_local (const ip_address *bind_address, int *port)
415 {
416   int sock;
417   struct sockaddr_storage ss;
418   struct sockaddr *sa = (struct sockaddr *)&ss;
419
420   /* For setting options with setsockopt. */
421   int setopt_val = 1;
422   void *setopt_ptr = (void *)&setopt_val;
423   socklen_t setopt_size = sizeof (setopt_val);
424
425   sock = socket (bind_address->family, SOCK_STREAM, 0);
426   if (sock < 0)
427     return -1;
428
429 #ifdef SO_REUSEADDR
430   setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size);
431 #endif
432
433   xzero (ss);
434   sockaddr_set_data (sa, bind_address, *port);
435   if (bind (sock, sa, sockaddr_size (sa)) < 0)
436     {
437       fd_close (sock);
438       return -1;
439     }
440   DEBUGP (("Local socket fd %d bound.\n", sock));
441
442   /* If *PORT is 0, find out which port we've bound to.  */
443   if (*port == 0)
444     {
445       socklen_t addrlen = sockaddr_size (sa);
446       if (getsockname (sock, sa, &addrlen) < 0)
447         {
448           /* If we can't find out the socket's local address ("name"),
449              something is seriously wrong with the socket, and it's
450              unusable for us anyway because we must know the chosen
451              port.  */
452           fd_close (sock);
453           return -1;
454         }
455       sockaddr_get_data (sa, NULL, port);
456       DEBUGP (("binding to address %s using port %i.\n",
457                print_address (bind_address), *port));
458     }
459   if (listen (sock, 1) < 0)
460     {
461       fd_close (sock);
462       return -1;
463     }
464   return sock;
465 }
466
467 /* Like a call to accept(), but with the added check for timeout.
468
469    In other words, accept a client connection on LOCAL_SOCK, and
470    return the new socket used for communication with the client.
471    LOCAL_SOCK should have been bound, e.g. using bind_local().
472
473    The caller is blocked until a connection is established.  If no
474    connection is established for opt.connect_timeout seconds, the
475    function exits with an error status.  */
476
477 int
478 accept_connection (int local_sock)
479 {
480   int sock;
481
482   /* We don't need the values provided by accept, but accept
483      apparently requires them to be present.  */
484   struct sockaddr_storage ss;
485   struct sockaddr *sa = (struct sockaddr *)&ss;
486   socklen_t addrlen = sizeof (ss);
487
488   if (opt.connect_timeout)
489     {
490       int test = select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ);
491       if (test == 0)
492         errno = ETIMEDOUT;
493       if (test <= 0)
494         return -1;
495     }
496   sock = accept (local_sock, sa, &addrlen);
497   DEBUGP (("Accepted client at socket %d.\n", sock));
498   return sock;
499 }
500
501 /* Get the IP address associated with the connection on FD and store
502    it to IP.  Return true on success, false otherwise.
503
504    If ENDPOINT is ENDPOINT_LOCAL, it returns the address of the local
505    (client) side of the socket.  Else if ENDPOINT is ENDPOINT_PEER, it
506    returns the address of the remote (peer's) side of the socket.  */
507
508 bool
509 socket_ip_address (int sock, ip_address *ip, int endpoint)
510 {
511   struct sockaddr_storage storage;
512   struct sockaddr *sockaddr = (struct sockaddr *)&storage;
513   socklen_t addrlen = sizeof (storage);
514   int ret;
515
516   if (endpoint == ENDPOINT_LOCAL)
517     ret = getsockname (sock, sockaddr, &addrlen);
518   else if (endpoint == ENDPOINT_PEER)
519     ret = getpeername (sock, sockaddr, &addrlen);
520   else
521     abort ();
522   if (ret < 0)
523     return false;
524
525   ip->family = sockaddr->sa_family;
526   switch (sockaddr->sa_family)
527     {
528 #ifdef ENABLE_IPV6
529     case AF_INET6:
530       {
531         struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
532         ip->data.d6 = sa6->sin6_addr;
533 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
534         ip->ipv6_scope = sa6->sin6_scope_id;
535 #endif
536         DEBUGP (("conaddr is: %s\n", print_address (ip)));
537         return true;
538       }
539 #endif
540     case AF_INET:
541       {
542         struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
543         ip->data.d4 = sa->sin_addr;
544         DEBUGP (("conaddr is: %s\n", print_address (ip)));
545         return true;
546       }
547     default:
548       abort ();
549     }
550 }
551
552 /* Return true if the error from the connect code can be considered
553    retryable.  Wget normally retries after errors, but the exception
554    are the "unsupported protocol" type errors (possible on IPv4/IPv6
555    dual family systems) and "connection refused".  */
556
557 bool
558 retryable_socket_connect_error (int err)
559 {
560   /* Have to guard against some of these values not being defined.
561      Cannot use a switch statement because some of the values might be
562      equal.  */
563   if (false
564 #ifdef EAFNOSUPPORT
565       || err == EAFNOSUPPORT
566 #endif
567 #ifdef EPFNOSUPPORT
568       || err == EPFNOSUPPORT
569 #endif
570 #ifdef ESOCKTNOSUPPORT          /* no, "sockt" is not a typo! */
571       || err == ESOCKTNOSUPPORT
572 #endif
573 #ifdef EPROTONOSUPPORT
574       || err == EPROTONOSUPPORT
575 #endif
576 #ifdef ENOPROTOOPT
577       || err == ENOPROTOOPT
578 #endif
579       /* Apparently, older versions of Linux and BSD used EINVAL
580          instead of EAFNOSUPPORT and such.  */
581       || err == EINVAL
582       )
583     return false;
584
585   if (!opt.retry_connrefused)
586     if (err == ECONNREFUSED
587 #ifdef ENETUNREACH
588         || err == ENETUNREACH   /* network is unreachable */
589 #endif
590 #ifdef EHOSTUNREACH
591         || err == EHOSTUNREACH  /* host is unreachable */
592 #endif
593         )
594       return false;
595
596   return true;
597 }
598
599 /* Wait for a single descriptor to become available, timing out after
600    MAXTIME seconds.  Returns 1 if FD is available, 0 for timeout and
601    -1 for error.  The argument WAIT_FOR can be a combination of
602    WAIT_FOR_READ and WAIT_FOR_WRITE.
603
604    This is a mere convenience wrapper around the select call, and
605    should be taken as such (for example, it doesn't implement Wget's
606    0-timeout-means-no-timeout semantics.)  */
607
608 int
609 select_fd (int fd, double maxtime, int wait_for)
610 {
611   fd_set fdset;
612   fd_set *rd = NULL, *wr = NULL;
613   struct timeval tmout;
614   int result;
615
616   FD_ZERO (&fdset);
617   FD_SET (fd, &fdset);
618   if (wait_for & WAIT_FOR_READ)
619     rd = &fdset;
620   if (wait_for & WAIT_FOR_WRITE)
621     wr = &fdset;
622
623   tmout.tv_sec = (long) maxtime;
624   tmout.tv_usec = 1000000 * (maxtime - (long) maxtime);
625
626   do
627     result = select (fd + 1, rd, wr, NULL, &tmout);
628   while (result < 0 && errno == EINTR);
629
630   return result;
631 }
632
633 /* Return true iff the connection to the remote site established
634    through SOCK is still open.
635
636    Specifically, this function returns true if SOCK is not ready for
637    reading.  This is because, when the connection closes, the socket
638    is ready for reading because EOF is about to be delivered.  A side
639    effect of this method is that sockets that have pending data are
640    considered non-open.  This is actually a good thing for callers of
641    this function, where such pending data can only be unwanted
642    leftover from a previous request.  */
643
644 bool
645 test_socket_open (int sock)
646 {
647   fd_set check_set;
648   struct timeval to;
649
650   /* Check if we still have a valid (non-EOF) connection.  From Andrew
651    * Maholski's code in the Unix Socket FAQ.  */
652
653   FD_ZERO (&check_set);
654   FD_SET (sock, &check_set);
655
656   /* Wait one microsecond */
657   to.tv_sec = 0;
658   to.tv_usec = 1;
659
660   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
661     /* We got a timeout, it means we're still connected. */
662     return true;
663   else
664     /* Read now would not wait, it means we have either pending data
665        or EOF/error. */
666     return false;
667 }
668 \f
669 /* Basic socket operations, mostly EINTR wrappers.  */
670
671 #ifdef WINDOWS
672 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
673 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
674 # define close(fd) closesocket (fd)
675 #endif
676
677 #ifdef __BEOS__
678 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
679 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
680 #endif
681
682 static int
683 sock_read (int fd, char *buf, int bufsize)
684 {
685   int res;
686   do
687     res = read (fd, buf, bufsize);
688   while (res == -1 && errno == EINTR);
689   return res;
690 }
691
692 static int
693 sock_write (int fd, char *buf, int bufsize)
694 {
695   int res;
696   do
697     res = write (fd, buf, bufsize);
698   while (res == -1 && errno == EINTR);
699   return res;
700 }
701
702 static int
703 sock_poll (int fd, double timeout, int wait_for)
704 {
705   return select_fd (fd, timeout, wait_for);
706 }
707
708 static int
709 sock_peek (int fd, char *buf, int bufsize)
710 {
711   int res;
712   do
713     res = recv (fd, buf, bufsize, MSG_PEEK);
714   while (res == -1 && errno == EINTR);
715   return res;
716 }
717
718 static void
719 sock_close (int fd)
720 {
721   close (fd);
722   DEBUGP (("Closed fd %d\n", fd));
723 }
724 #undef read
725 #undef write
726 #undef close
727 \f
728 /* Reading and writing from the network.  We build around the socket
729    (file descriptor) API, but support "extended" operations for things
730    that are not mere file descriptors under the hood, such as SSL
731    sockets.
732
733    That way the user code can call fd_read(fd, ...) and we'll run read
734    or SSL_read or whatever is necessary.  */
735
736 static struct hash_table *transport_map;
737 static unsigned int transport_map_modified_tick;
738
739 struct transport_info {
740   struct transport_implementation *imp;
741   void *ctx;
742 };
743
744 /* Register the transport layer operations that will be used when
745    reading, writing, and polling FD.
746
747    This should be used for transport layers like SSL that piggyback on
748    sockets.  FD should otherwise be a real socket, on which you can
749    call getpeername, etc.  */
750
751 void
752 fd_register_transport (int fd, struct transport_implementation *imp, void *ctx)
753 {
754   struct transport_info *info;
755
756   /* The file descriptor must be non-negative to be registered.
757      Negative values are ignored by fd_close(), and -1 cannot be used as
758      hash key.  */
759   assert (fd >= 0);
760
761   info = xnew (struct transport_info);
762   info->imp = imp;
763   info->ctx = ctx;
764   if (!transport_map)
765     transport_map = hash_table_new (0, NULL, NULL);
766   hash_table_put (transport_map, (void *)(intptr_t) fd, info);
767   ++transport_map_modified_tick;
768 }
769
770 /* Return context of the transport registered with
771    fd_register_transport.  This assumes fd_register_transport was
772    previously called on FD.  */
773
774 void *
775 fd_transport_context (int fd)
776 {
777   struct transport_info *info = hash_table_get (transport_map, (void *)(intptr_t) fd);
778   return info->ctx;
779 }
780
781 /* When fd_read/fd_write are called multiple times in a loop, they should
782    remember the INFO pointer instead of fetching it every time.  It is
783    not enough to compare FD to LAST_FD because FD might have been
784    closed and reopened.  modified_tick ensures that changes to
785    transport_map will not be unnoticed.
786
787    This is a macro because we want the static storage variables to be
788    per-function.  */
789
790 #define LAZY_RETRIEVE_INFO(info) do {                                   \
791   static struct transport_info *last_info;                              \
792   static int last_fd = -1;                                              \
793   static unsigned int last_tick;                                        \
794   if (!transport_map)                                                   \
795     info = NULL;                                                        \
796   else if (last_fd == fd && last_tick == transport_map_modified_tick)   \
797     info = last_info;                                                   \
798   else                                                                  \
799     {                                                                   \
800       info = hash_table_get (transport_map, (void *)(intptr_t) fd);     \
801       last_fd = fd;                                                     \
802       last_info = info;                                                 \
803       last_tick = transport_map_modified_tick;                          \
804     }                                                                   \
805 } while (0)
806
807 static bool
808 poll_internal (int fd, struct transport_info *info, int wf, double timeout)
809 {
810   if (timeout == -1)
811     timeout = opt.read_timeout;
812   if (timeout)
813     {
814       int test;
815       if (info && info->imp->poller)
816         test = info->imp->poller (fd, timeout, wf, info->ctx);
817       else
818         test = sock_poll (fd, timeout, wf);
819       if (test == 0)
820         errno = ETIMEDOUT;
821       if (test <= 0)
822         return false;
823     }
824   return true;
825 }
826
827 /* Read no more than BUFSIZE bytes of data from FD, storing them to
828    BUF.  If TIMEOUT is non-zero, the operation aborts if no data is
829    received after that many seconds.  If TIMEOUT is -1, the value of
830    opt.timeout is used for TIMEOUT.  */
831
832 int
833 fd_read (int fd, char *buf, int bufsize, double timeout)
834 {
835   struct transport_info *info;
836   LAZY_RETRIEVE_INFO (info);
837   if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
838     return -1;
839   if (info && info->imp->reader)
840     return info->imp->reader (fd, buf, bufsize, info->ctx);
841   else
842     return sock_read (fd, buf, bufsize);
843 }
844
845 /* Like fd_read, except it provides a "preview" of the data that will
846    be read by subsequent calls to fd_read.  Specifically, it copies no
847    more than BUFSIZE bytes of the currently available data to BUF and
848    returns the number of bytes copied.  Return values and timeout
849    semantics are the same as those of fd_read.
850
851    CAVEAT: Do not assume that the first subsequent call to fd_read
852    will retrieve the same amount of data.  Reading can return more or
853    less data, depending on the TCP implementation and other
854    circumstances.  However, barring an error, it can be expected that
855    all the peeked data will eventually be read by fd_read.  */
856
857 int
858 fd_peek (int fd, char *buf, int bufsize, double timeout)
859 {
860   struct transport_info *info;
861   LAZY_RETRIEVE_INFO (info);
862   if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
863     return -1;
864   if (info && info->imp->peeker)
865     return info->imp->peeker (fd, buf, bufsize, info->ctx);
866   else
867     return sock_peek (fd, buf, bufsize);
868 }
869
870 /* Write the entire contents of BUF to FD.  If TIMEOUT is non-zero,
871    the operation aborts if no data is received after that many
872    seconds.  If TIMEOUT is -1, the value of opt.timeout is used for
873    TIMEOUT.  */
874
875 int
876 fd_write (int fd, char *buf, int bufsize, double timeout)
877 {
878   int res;
879   struct transport_info *info;
880   LAZY_RETRIEVE_INFO (info);
881
882   /* `write' may write less than LEN bytes, thus the loop keeps trying
883      it until all was written, or an error occurred.  */
884   res = 0;
885   while (bufsize > 0)
886     {
887       if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout))
888         return -1;
889       if (info && info->imp->writer)
890         res = info->imp->writer (fd, buf, bufsize, info->ctx);
891       else
892         res = sock_write (fd, buf, bufsize);
893       if (res <= 0)
894         break;
895       buf += res;
896       bufsize -= res;
897     }
898   return res;
899 }
900
901 /* Report the most recent error(s) on FD.  This should only be called
902    after fd_* functions, such as fd_read and fd_write, and only if
903    they return a negative result.  For errors coming from other calls
904    such as setsockopt or fopen, strerror should continue to be
905    used.
906
907    If the transport doesn't support error messages or doesn't supply
908    one, strerror(errno) is returned.  The returned error message
909    should not be used after fd_close has been called.  */
910
911 const char *
912 fd_errstr (int fd)
913 {
914   /* Don't bother with LAZY_RETRIEVE_INFO, as this will only be called
915      in case of error, never in a tight loop.  */
916   struct transport_info *info = NULL;
917   if (transport_map)
918     info = hash_table_get (transport_map, (void *)(intptr_t) fd);
919
920   if (info && info->imp->errstr)
921     {
922       const char *err = info->imp->errstr (fd, info->ctx);
923       if (err)
924         return err;
925       /* else, fall through and print the system error. */
926     }
927   return strerror (errno);
928 }
929
930 /* Close the file descriptor FD.  */
931
932 void
933 fd_close (int fd)
934 {
935   struct transport_info *info;
936   if (fd < 0)
937     return;
938
939   /* Don't use LAZY_RETRIEVE_INFO because fd_close() is only called once
940      per socket, so that particular optimization wouldn't work.  */
941   info = NULL;
942   if (transport_map)
943     info = hash_table_get (transport_map, (void *)(intptr_t) fd);
944
945   if (info && info->imp->closer)
946     info->imp->closer (fd, info->ctx);
947   else
948     sock_close (fd);
949
950   if (info)
951     {
952       hash_table_remove (transport_map, (void *)(intptr_t) fd);
953       xfree (info);
954       ++transport_map_modified_tick;
955     }
956 }