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