]> sjero.net Git - wget/blob - src/connect.c
Merge SFLC licensing changes for OpenSSL with tip.
[wget] / src / connect.c
1 /* Establishing and handling network connections.
2    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3    2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4
5 This file is part of GNU Wget.
6
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a
24 modified version of that library), containing parts covered by the
25 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26 grants you additional permission to convey the resulting work.
27 Corresponding Source for a non-source form of such a combination
28 shall include the source code for the parts of OpenSSL used as well
29 as that of the covered work.  */
30
31 #include "wget.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #ifdef HAVE_UNISTD_H
36 # include <unistd.h>
37 #endif
38 #include <assert.h>
39
40 #ifndef WINDOWS
41 # include <sys/socket.h>
42 # include <netdb.h>
43 # include <netinet/in.h>
44 # ifndef __BEOS__
45 #  include <arpa/inet.h>
46 # endif
47 #endif /* not WINDOWS */
48
49 #include <errno.h>
50 #include <string.h>
51 #ifdef HAVE_SYS_SELECT_H
52 # include <sys/select.h>
53 #endif /* HAVE_SYS_SELECT_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     {
365       logprintf (LOG_NOTQUIET,
366                  _("%s: unable to resolve host address `%s'\n"),
367                  exec_name, host);
368       return E_HOST;
369     }
370
371   address_list_get_bounds (al, &start, &end);
372   for (i = start; i < end; i++)
373     {
374       const ip_address *ip = address_list_address_at (al, i);
375       sock = connect_to_ip (ip, port, host);
376       if (sock >= 0)
377         {
378           /* Success. */
379           address_list_set_connected (al);
380           address_list_release (al);
381           return sock;
382         }
383
384       /* The attempt to connect has failed.  Continue with the loop
385          and try next address. */
386
387       address_list_set_faulty (al, i);
388     }
389
390   /* Failed to connect to any of the addresses in AL. */
391
392   if (address_list_connected_p (al))
393     {
394       /* We connected to AL before, but cannot do so now.  That might
395          indicate that our DNS cache entry for HOST has expired.  */
396       address_list_release (al);
397       al = lookup_host (host, LH_REFRESH);
398       goto retry;
399     }
400   address_list_release (al);
401
402   return -1;
403 }
404 \f
405 /* Create a socket, bind it to local interface BIND_ADDRESS on port
406    *PORT, set up a listen backlog, and return the resulting socket, or
407    -1 in case of error.
408
409    BIND_ADDRESS is the address of the interface to bind to.  If it is
410    NULL, the socket is bound to the default address.  PORT should
411    point to the port number that will be used for the binding.  If
412    that number is 0, the system will choose a suitable port, and the
413    chosen value will be written to *PORT.
414
415    Calling accept() on such a socket waits for and accepts incoming
416    TCP connections.  */
417
418 int
419 bind_local (const ip_address *bind_address, int *port)
420 {
421   int sock;
422   struct sockaddr_storage ss;
423   struct sockaddr *sa = (struct sockaddr *)&ss;
424
425   /* For setting options with setsockopt. */
426   int setopt_val = 1;
427   void *setopt_ptr = (void *)&setopt_val;
428   socklen_t setopt_size = sizeof (setopt_val);
429
430   sock = socket (bind_address->family, SOCK_STREAM, 0);
431   if (sock < 0)
432     return -1;
433
434 #ifdef SO_REUSEADDR
435   setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, setopt_ptr, setopt_size);
436 #endif
437
438   xzero (ss);
439   sockaddr_set_data (sa, bind_address, *port);
440   if (bind (sock, sa, sockaddr_size (sa)) < 0)
441     {
442       fd_close (sock);
443       return -1;
444     }
445   DEBUGP (("Local socket fd %d bound.\n", sock));
446
447   /* If *PORT is 0, find out which port we've bound to.  */
448   if (*port == 0)
449     {
450       socklen_t addrlen = sockaddr_size (sa);
451       if (getsockname (sock, sa, &addrlen) < 0)
452         {
453           /* If we can't find out the socket's local address ("name"),
454              something is seriously wrong with the socket, and it's
455              unusable for us anyway because we must know the chosen
456              port.  */
457           fd_close (sock);
458           return -1;
459         }
460       sockaddr_get_data (sa, NULL, port);
461       DEBUGP (("binding to address %s using port %i.\n",
462                print_address (bind_address), *port));
463     }
464   if (listen (sock, 1) < 0)
465     {
466       fd_close (sock);
467       return -1;
468     }
469   return sock;
470 }
471
472 /* Like a call to accept(), but with the added check for timeout.
473
474    In other words, accept a client connection on LOCAL_SOCK, and
475    return the new socket used for communication with the client.
476    LOCAL_SOCK should have been bound, e.g. using bind_local().
477
478    The caller is blocked until a connection is established.  If no
479    connection is established for opt.connect_timeout seconds, the
480    function exits with an error status.  */
481
482 int
483 accept_connection (int local_sock)
484 {
485   int sock;
486
487   /* We don't need the values provided by accept, but accept
488      apparently requires them to be present.  */
489   struct sockaddr_storage ss;
490   struct sockaddr *sa = (struct sockaddr *)&ss;
491   socklen_t addrlen = sizeof (ss);
492
493   if (opt.connect_timeout)
494     {
495       int test = select_fd (local_sock, opt.connect_timeout, WAIT_FOR_READ);
496       if (test == 0)
497         errno = ETIMEDOUT;
498       if (test <= 0)
499         return -1;
500     }
501   sock = accept (local_sock, sa, &addrlen);
502   DEBUGP (("Accepted client at socket %d.\n", sock));
503   return sock;
504 }
505
506 /* Get the IP address associated with the connection on FD and store
507    it to IP.  Return true on success, false otherwise.
508
509    If ENDPOINT is ENDPOINT_LOCAL, it returns the address of the local
510    (client) side of the socket.  Else if ENDPOINT is ENDPOINT_PEER, it
511    returns the address of the remote (peer's) side of the socket.  */
512
513 bool
514 socket_ip_address (int sock, ip_address *ip, int endpoint)
515 {
516   struct sockaddr_storage storage;
517   struct sockaddr *sockaddr = (struct sockaddr *)&storage;
518   socklen_t addrlen = sizeof (storage);
519   int ret;
520
521   if (endpoint == ENDPOINT_LOCAL)
522     ret = getsockname (sock, sockaddr, &addrlen);
523   else if (endpoint == ENDPOINT_PEER)
524     ret = getpeername (sock, sockaddr, &addrlen);
525   else
526     abort ();
527   if (ret < 0)
528     return false;
529
530   ip->family = sockaddr->sa_family;
531   switch (sockaddr->sa_family)
532     {
533 #ifdef ENABLE_IPV6
534     case AF_INET6:
535       {
536         struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&storage;
537         ip->data.d6 = sa6->sin6_addr;
538 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
539         ip->ipv6_scope = sa6->sin6_scope_id;
540 #endif
541         DEBUGP (("conaddr is: %s\n", print_address (ip)));
542         return true;
543       }
544 #endif
545     case AF_INET:
546       {
547         struct sockaddr_in *sa = (struct sockaddr_in *)&storage;
548         ip->data.d4 = sa->sin_addr;
549         DEBUGP (("conaddr is: %s\n", print_address (ip)));
550         return true;
551       }
552     default:
553       abort ();
554     }
555 }
556
557 /* Return true if the error from the connect code can be considered
558    retryable.  Wget normally retries after errors, but the exception
559    are the "unsupported protocol" type errors (possible on IPv4/IPv6
560    dual family systems) and "connection refused".  */
561
562 bool
563 retryable_socket_connect_error (int err)
564 {
565   /* Have to guard against some of these values not being defined.
566      Cannot use a switch statement because some of the values might be
567      equal.  */
568   if (false
569 #ifdef EAFNOSUPPORT
570       || err == EAFNOSUPPORT
571 #endif
572 #ifdef EPFNOSUPPORT
573       || err == EPFNOSUPPORT
574 #endif
575 #ifdef ESOCKTNOSUPPORT          /* no, "sockt" is not a typo! */
576       || err == ESOCKTNOSUPPORT
577 #endif
578 #ifdef EPROTONOSUPPORT
579       || err == EPROTONOSUPPORT
580 #endif
581 #ifdef ENOPROTOOPT
582       || err == ENOPROTOOPT
583 #endif
584       /* Apparently, older versions of Linux and BSD used EINVAL
585          instead of EAFNOSUPPORT and such.  */
586       || err == EINVAL
587       )
588     return false;
589
590   if (!opt.retry_connrefused)
591     if (err == ECONNREFUSED
592 #ifdef ENETUNREACH
593         || err == ENETUNREACH   /* network is unreachable */
594 #endif
595 #ifdef EHOSTUNREACH
596         || err == EHOSTUNREACH  /* host is unreachable */
597 #endif
598         )
599       return false;
600
601   return true;
602 }
603
604 /* Wait for a single descriptor to become available, timing out after
605    MAXTIME seconds.  Returns 1 if FD is available, 0 for timeout and
606    -1 for error.  The argument WAIT_FOR can be a combination of
607    WAIT_FOR_READ and WAIT_FOR_WRITE.
608
609    This is a mere convenience wrapper around the select call, and
610    should be taken as such (for example, it doesn't implement Wget's
611    0-timeout-means-no-timeout semantics.)  */
612
613 int
614 select_fd (int fd, double maxtime, int wait_for)
615 {
616   fd_set fdset;
617   fd_set *rd = NULL, *wr = NULL;
618   struct timeval tmout;
619   int result;
620
621   FD_ZERO (&fdset);
622   FD_SET (fd, &fdset);
623   if (wait_for & WAIT_FOR_READ)
624     rd = &fdset;
625   if (wait_for & WAIT_FOR_WRITE)
626     wr = &fdset;
627
628   tmout.tv_sec = (long) maxtime;
629   tmout.tv_usec = 1000000 * (maxtime - (long) maxtime);
630
631   do
632     result = select (fd + 1, rd, wr, NULL, &tmout);
633   while (result < 0 && errno == EINTR);
634
635   return result;
636 }
637
638 /* Return true iff the connection to the remote site established
639    through SOCK is still open.
640
641    Specifically, this function returns true if SOCK is not ready for
642    reading.  This is because, when the connection closes, the socket
643    is ready for reading because EOF is about to be delivered.  A side
644    effect of this method is that sockets that have pending data are
645    considered non-open.  This is actually a good thing for callers of
646    this function, where such pending data can only be unwanted
647    leftover from a previous request.  */
648
649 bool
650 test_socket_open (int sock)
651 {
652   fd_set check_set;
653   struct timeval to;
654
655   /* Check if we still have a valid (non-EOF) connection.  From Andrew
656    * Maholski's code in the Unix Socket FAQ.  */
657
658   FD_ZERO (&check_set);
659   FD_SET (sock, &check_set);
660
661   /* Wait one microsecond */
662   to.tv_sec = 0;
663   to.tv_usec = 1;
664
665   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
666     /* We got a timeout, it means we're still connected. */
667     return true;
668   else
669     /* Read now would not wait, it means we have either pending data
670        or EOF/error. */
671     return false;
672 }
673 \f
674 /* Basic socket operations, mostly EINTR wrappers.  */
675
676 #if defined(WINDOWS) || defined(MSDOS)
677 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
678 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
679 # define close(fd) closesocket (fd)
680 #endif
681
682 #ifdef __BEOS__
683 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
684 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
685 #endif
686
687 static int
688 sock_read (int fd, char *buf, int bufsize)
689 {
690   int res;
691   do
692     res = read (fd, buf, bufsize);
693   while (res == -1 && errno == EINTR);
694   return res;
695 }
696
697 static int
698 sock_write (int fd, char *buf, int bufsize)
699 {
700   int res;
701   do
702     res = write (fd, buf, bufsize);
703   while (res == -1 && errno == EINTR);
704   return res;
705 }
706
707 static int
708 sock_poll (int fd, double timeout, int wait_for)
709 {
710   return select_fd (fd, timeout, wait_for);
711 }
712
713 static int
714 sock_peek (int fd, char *buf, int bufsize)
715 {
716   int res;
717   do
718     res = recv (fd, buf, bufsize, MSG_PEEK);
719   while (res == -1 && errno == EINTR);
720   return res;
721 }
722
723 static void
724 sock_close (int fd)
725 {
726   close (fd);
727   DEBUGP (("Closed fd %d\n", fd));
728 }
729 #undef read
730 #undef write
731 #undef close
732 \f
733 /* Reading and writing from the network.  We build around the socket
734    (file descriptor) API, but support "extended" operations for things
735    that are not mere file descriptors under the hood, such as SSL
736    sockets.
737
738    That way the user code can call fd_read(fd, ...) and we'll run read
739    or SSL_read or whatever is necessary.  */
740
741 static struct hash_table *transport_map;
742 static unsigned int transport_map_modified_tick;
743
744 struct transport_info {
745   struct transport_implementation *imp;
746   void *ctx;
747 };
748
749 /* Register the transport layer operations that will be used when
750    reading, writing, and polling FD.
751
752    This should be used for transport layers like SSL that piggyback on
753    sockets.  FD should otherwise be a real socket, on which you can
754    call getpeername, etc.  */
755
756 void
757 fd_register_transport (int fd, struct transport_implementation *imp, void *ctx)
758 {
759   struct transport_info *info;
760
761   /* The file descriptor must be non-negative to be registered.
762      Negative values are ignored by fd_close(), and -1 cannot be used as
763      hash key.  */
764   assert (fd >= 0);
765
766   info = xnew (struct transport_info);
767   info->imp = imp;
768   info->ctx = ctx;
769   if (!transport_map)
770     transport_map = hash_table_new (0, NULL, NULL);
771   hash_table_put (transport_map, (void *)(intptr_t) fd, info);
772   ++transport_map_modified_tick;
773 }
774
775 /* Return context of the transport registered with
776    fd_register_transport.  This assumes fd_register_transport was
777    previously called on FD.  */
778
779 void *
780 fd_transport_context (int fd)
781 {
782   struct transport_info *info = hash_table_get (transport_map, (void *)(intptr_t) fd);
783   return info->ctx;
784 }
785
786 /* When fd_read/fd_write are called multiple times in a loop, they should
787    remember the INFO pointer instead of fetching it every time.  It is
788    not enough to compare FD to LAST_FD because FD might have been
789    closed and reopened.  modified_tick ensures that changes to
790    transport_map will not be unnoticed.
791
792    This is a macro because we want the static storage variables to be
793    per-function.  */
794
795 #define LAZY_RETRIEVE_INFO(info) do {                                   \
796   static struct transport_info *last_info;                              \
797   static int last_fd = -1;                                              \
798   static unsigned int last_tick;                                        \
799   if (!transport_map)                                                   \
800     info = NULL;                                                        \
801   else if (last_fd == fd && last_tick == transport_map_modified_tick)   \
802     info = last_info;                                                   \
803   else                                                                  \
804     {                                                                   \
805       info = hash_table_get (transport_map, (void *)(intptr_t) fd);     \
806       last_fd = fd;                                                     \
807       last_info = info;                                                 \
808       last_tick = transport_map_modified_tick;                          \
809     }                                                                   \
810 } while (0)
811
812 static bool
813 poll_internal (int fd, struct transport_info *info, int wf, double timeout)
814 {
815   if (timeout == -1)
816     timeout = opt.read_timeout;
817   if (timeout)
818     {
819       int test;
820       if (info && info->imp->poller)
821         test = info->imp->poller (fd, timeout, wf, info->ctx);
822       else
823         test = sock_poll (fd, timeout, wf);
824       if (test == 0)
825         errno = ETIMEDOUT;
826       if (test <= 0)
827         return false;
828     }
829   return true;
830 }
831
832 /* Read no more than BUFSIZE bytes of data from FD, storing them to
833    BUF.  If TIMEOUT is non-zero, the operation aborts if no data is
834    received after that many seconds.  If TIMEOUT is -1, the value of
835    opt.timeout is used for TIMEOUT.  */
836
837 int
838 fd_read (int fd, char *buf, int bufsize, double timeout)
839 {
840   struct transport_info *info;
841   LAZY_RETRIEVE_INFO (info);
842   if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
843     return -1;
844   if (info && info->imp->reader)
845     return info->imp->reader (fd, buf, bufsize, info->ctx);
846   else
847     return sock_read (fd, buf, bufsize);
848 }
849
850 /* Like fd_read, except it provides a "preview" of the data that will
851    be read by subsequent calls to fd_read.  Specifically, it copies no
852    more than BUFSIZE bytes of the currently available data to BUF and
853    returns the number of bytes copied.  Return values and timeout
854    semantics are the same as those of fd_read.
855
856    CAVEAT: Do not assume that the first subsequent call to fd_read
857    will retrieve the same amount of data.  Reading can return more or
858    less data, depending on the TCP implementation and other
859    circumstances.  However, barring an error, it can be expected that
860    all the peeked data will eventually be read by fd_read.  */
861
862 int
863 fd_peek (int fd, char *buf, int bufsize, double timeout)
864 {
865   struct transport_info *info;
866   LAZY_RETRIEVE_INFO (info);
867   if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
868     return -1;
869   if (info && info->imp->peeker)
870     return info->imp->peeker (fd, buf, bufsize, info->ctx);
871   else
872     return sock_peek (fd, buf, bufsize);
873 }
874
875 /* Write the entire contents of BUF to FD.  If TIMEOUT is non-zero,
876    the operation aborts if no data is received after that many
877    seconds.  If TIMEOUT is -1, the value of opt.timeout is used for
878    TIMEOUT.  */
879
880 int
881 fd_write (int fd, char *buf, int bufsize, double timeout)
882 {
883   int res;
884   struct transport_info *info;
885   LAZY_RETRIEVE_INFO (info);
886
887   /* `write' may write less than LEN bytes, thus the loop keeps trying
888      it until all was written, or an error occurred.  */
889   res = 0;
890   while (bufsize > 0)
891     {
892       if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout))
893         return -1;
894       if (info && info->imp->writer)
895         res = info->imp->writer (fd, buf, bufsize, info->ctx);
896       else
897         res = sock_write (fd, buf, bufsize);
898       if (res <= 0)
899         break;
900       buf += res;
901       bufsize -= res;
902     }
903   return res;
904 }
905
906 /* Report the most recent error(s) on FD.  This should only be called
907    after fd_* functions, such as fd_read and fd_write, and only if
908    they return a negative result.  For errors coming from other calls
909    such as setsockopt or fopen, strerror should continue to be
910    used.
911
912    If the transport doesn't support error messages or doesn't supply
913    one, strerror(errno) is returned.  The returned error message
914    should not be used after fd_close has been called.  */
915
916 const char *
917 fd_errstr (int fd)
918 {
919   /* Don't bother with LAZY_RETRIEVE_INFO, as this will only be called
920      in case of error, never in a tight loop.  */
921   struct transport_info *info = NULL;
922   if (transport_map)
923     info = hash_table_get (transport_map, (void *)(intptr_t) fd);
924
925   if (info && info->imp->errstr)
926     {
927       const char *err = info->imp->errstr (fd, info->ctx);
928       if (err)
929         return err;
930       /* else, fall through and print the system error. */
931     }
932   return strerror (errno);
933 }
934
935 /* Close the file descriptor FD.  */
936
937 void
938 fd_close (int fd)
939 {
940   struct transport_info *info;
941   if (fd < 0)
942     return;
943
944   /* Don't use LAZY_RETRIEVE_INFO because fd_close() is only called once
945      per socket, so that particular optimization wouldn't work.  */
946   info = NULL;
947   if (transport_map)
948     info = hash_table_get (transport_map, (void *)(intptr_t) fd);
949
950   if (info && info->imp->closer)
951     info->imp->closer (fd, info->ctx);
952   else
953     sock_close (fd);
954
955   if (info)
956     {
957       hash_table_remove (transport_map, (void *)(intptr_t) fd);
958       xfree (info);
959       ++transport_map_modified_tick;
960     }
961 }