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