]> sjero.net Git - wget/blob - src/connect.c
[svn] Set IPV6_V6ONLY socket option when -6 switch is used.
[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 (err == ECONNREFUSED && !opt.retry_connrefused)
601     return 0;
602
603   return 1;
604 }
605
606 #ifdef ENABLE_IPV6
607 # ifndef HAVE_GETADDRINFO_AI_ADDRCONFIG
608
609 /* Return non-zero if the INET6 socket family is supported on the
610    system.
611
612    This doesn't guarantee that we're able to connect to IPv6 hosts,
613    but it's better than nothing.  It is only used on systems where
614    getaddrinfo doesn't support AI_ADDRCONFIG.  (See lookup_host.)  */
615
616 int
617 socket_has_inet6 (void)
618 {
619   static int supported = -1;
620   if (supported == -1)
621     {
622       int sock = socket (AF_INET6, SOCK_STREAM, 0);
623       if (sock < 0)
624         supported = 0;
625       else
626         {
627           fd_close (sock);
628           supported = 1;
629         }
630     }
631   return supported;
632 }
633
634 # endif/* not HAVE_GETADDRINFO_AI_ADDRCONFIG */
635 #endif /* ENABLE_IPV6 */
636
637 /* Wait for a single descriptor to become available, timing out after
638    MAXTIME seconds.  Returns 1 if FD is available, 0 for timeout and
639    -1 for error.  The argument WAIT_FOR can be a combination of
640    WAIT_FOR_READ and WAIT_FOR_WRITE.
641
642    This is a mere convenience wrapper around the select call, and
643    should be taken as such (for example, it doesn't implement Wget's
644    0-timeout-means-no-timeout semantics.)  */
645
646 int
647 select_fd (int fd, double maxtime, int wait_for)
648 {
649 #ifdef HAVE_SELECT
650   fd_set fdset;
651   fd_set *rd = NULL, *wr = NULL;
652   struct timeval tmout;
653   int result;
654
655   FD_ZERO (&fdset);
656   FD_SET (fd, &fdset);
657   if (wait_for & WAIT_FOR_READ)
658     rd = &fdset;
659   if (wait_for & WAIT_FOR_WRITE)
660     wr = &fdset;
661
662   tmout.tv_sec = (long) maxtime;
663   tmout.tv_usec = 1000000 * (maxtime - (long) maxtime);
664
665   do
666     result = select (fd + 1, rd, wr, NULL, &tmout);
667   while (result < 0 && errno == EINTR);
668
669   return result;
670
671 #else  /* not HAVE_SELECT */
672
673   /* If select() unavailable, just return 1.  In most usages in Wget,
674      this is the appropriate response -- "if we can't poll, go ahead
675      with the blocking operation".  If a specific part of code needs
676      different behavior, it can use #ifdef HAVE_SELECT to test whether
677      polling really occurs.  */
678   return 1;
679
680 #endif /* not HAVE_SELECT */
681 }
682
683 int
684 test_socket_open (int sock)
685 {
686 #ifdef HAVE_SELECT
687   fd_set check_set;
688   struct timeval to;
689
690   /* Check if we still have a valid (non-EOF) connection.  From Andrew
691    * Maholski's code in the Unix Socket FAQ.  */
692
693   FD_ZERO (&check_set);
694   FD_SET (sock, &check_set);
695
696   /* Wait one microsecond */
697   to.tv_sec = 0;
698   to.tv_usec = 1;
699
700   /* If we get a timeout, then that means still connected */
701   if (select (sock + 1, &check_set, NULL, NULL, &to) == 0)
702     {
703       /* Connection is valid (not EOF), so continue */
704       return 1;
705     }
706   else
707     return 0;
708 #else
709   /* Without select, it's hard to know for sure. */
710   return 1;
711 #endif
712 }
713 \f
714 /* Basic socket operations, mostly EINTR wrappers.  */
715
716 #ifdef WINDOWS
717 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
718 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
719 # define close(fd) closesocket (fd)
720 #endif
721
722 #ifdef __BEOS__
723 # define read(fd, buf, cnt) recv (fd, buf, cnt, 0)
724 # define write(fd, buf, cnt) send (fd, buf, cnt, 0)
725 #endif
726
727 static int
728 sock_read (int fd, char *buf, int bufsize)
729 {
730   int res;
731   do
732     res = read (fd, buf, bufsize);
733   while (res == -1 && errno == EINTR);
734   return res;
735 }
736
737 static int
738 sock_write (int fd, char *buf, int bufsize)
739 {
740   int res;
741   do
742     res = write (fd, buf, bufsize);
743   while (res == -1 && errno == EINTR);
744   return res;
745 }
746
747 static int
748 sock_poll (int fd, double timeout, int wait_for)
749 {
750   return select_fd (fd, timeout, wait_for);
751 }
752
753 static int
754 sock_peek (int fd, char *buf, int bufsize)
755 {
756   int res;
757   do
758     res = recv (fd, buf, bufsize, MSG_PEEK);
759   while (res == -1 && errno == EINTR);
760   return res;
761 }
762
763 static void
764 sock_close (int fd)
765 {
766   close (fd);
767   DEBUGP (("Closed fd %d\n", fd));
768 }
769 #undef read
770 #undef write
771 #undef close
772 \f
773 /* Reading and writing from the network.  We build around the socket
774    (file descriptor) API, but support "extended" operations for things
775    that are not mere file descriptors under the hood, such as SSL
776    sockets.
777
778    That way the user code can call fd_read(fd, ...) and we'll run read
779    or SSL_read or whatever is necessary.  */
780
781 static struct hash_table *transport_map;
782 static int transport_map_modified_tick;
783
784 struct transport_info {
785   fd_reader_t reader;
786   fd_writer_t writer;
787   fd_poller_t poller;
788   fd_peeker_t peeker;
789   fd_closer_t closer;
790   void *ctx;
791 };
792
793 /* Register the transport layer operations that will be used when
794    reading, writing, and polling FD.
795
796    This should be used for transport layers like SSL that piggyback on
797    sockets.  FD should otherwise be a real socket, on which you can
798    call getpeername, etc.  */
799
800 void
801 fd_register_transport (int fd, fd_reader_t reader, fd_writer_t writer,
802                        fd_poller_t poller, fd_peeker_t peeker,
803                        fd_closer_t closer, void *ctx)
804 {
805   struct transport_info *info;
806
807   /* The file descriptor must be non-negative to be registered.
808      Negative values are ignored by fd_close(), and -1 cannot be used as
809      hash key.  */
810   assert (fd >= 0);
811
812   info = xnew (struct transport_info);
813   info->reader = reader;
814   info->writer = writer;
815   info->poller = poller;
816   info->peeker = peeker;
817   info->closer = closer;
818   info->ctx = ctx;
819   if (!transport_map)
820     transport_map = hash_table_new (0, NULL, NULL);
821   hash_table_put (transport_map, (void *) fd, info);
822   ++transport_map_modified_tick;
823 }
824
825 /* When fd_read/fd_write are called multiple times in a loop, they should
826    remember the INFO pointer instead of fetching it every time.  It is
827    not enough to compare FD to LAST_FD because FD might have been
828    closed and reopened.  modified_tick ensures that changes to
829    transport_map will not be unnoticed.
830
831    This is a macro because we want the static storage variables to be
832    per-function.  */
833
834 #define LAZY_RETRIEVE_INFO(info) do {                                   \
835   static struct transport_info *last_info;                              \
836   static int last_fd = -1, last_tick;                                   \
837   if (!transport_map)                                                   \
838     info = NULL;                                                        \
839   else if (last_fd == fd && last_tick == transport_map_modified_tick)   \
840     info = last_info;                                                   \
841   else                                                                  \
842     {                                                                   \
843       info = hash_table_get (transport_map, (void *) fd);               \
844       last_fd = fd;                                                     \
845       last_info = info;                                                 \
846       last_tick = transport_map_modified_tick;                          \
847     }                                                                   \
848 } while (0)
849
850 static int
851 poll_internal (int fd, struct transport_info *info, int wf, double timeout)
852 {
853   if (timeout == -1)
854     timeout = opt.read_timeout;
855   if (timeout)
856     {
857       int test;
858       if (info && info->poller)
859         test = info->poller (fd, timeout, wf, info->ctx);
860       else
861         test = sock_poll (fd, timeout, wf);
862       if (test == 0)
863         errno = ETIMEDOUT;
864       if (test <= 0)
865         return 0;
866     }
867   return 1;
868 }
869
870 /* Read no more than BUFSIZE bytes of data from FD, storing them to
871    BUF.  If TIMEOUT is non-zero, the operation aborts if no data is
872    received after that many seconds.  If TIMEOUT is -1, the value of
873    opt.timeout is used for TIMEOUT.  */
874
875 int
876 fd_read (int fd, char *buf, int bufsize, double timeout)
877 {
878   struct transport_info *info;
879   LAZY_RETRIEVE_INFO (info);
880   if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
881     return -1;
882   if (info && info->reader)
883     return info->reader (fd, buf, bufsize, info->ctx);
884   else
885     return sock_read (fd, buf, bufsize);
886 }
887
888 /* Like fd_read, except it provides a "preview" of the data that will
889    be read by subsequent calls to fd_read.  Specifically, it copies no
890    more than BUFSIZE bytes of the currently available data to BUF and
891    returns the number of bytes copied.  Return values and timeout
892    semantics are the same as those of fd_read.
893
894    CAVEAT: Do not assume that the first subsequent call to fd_read
895    will retrieve the same amount of data.  Reading can return more or
896    less data, depending on the TCP implementation and other
897    circumstances.  However, barring an error, it can be expected that
898    all the peeked data will eventually be read by fd_read.  */
899
900 int
901 fd_peek (int fd, char *buf, int bufsize, double timeout)
902 {
903   struct transport_info *info;
904   LAZY_RETRIEVE_INFO (info);
905   if (!poll_internal (fd, info, WAIT_FOR_READ, timeout))
906     return -1;
907   if (info && info->peeker)
908     return info->peeker (fd, buf, bufsize, info->ctx);
909   else
910     return sock_peek (fd, buf, bufsize);
911 }
912
913 /* Write the entire contents of BUF to FD.  If TIMEOUT is non-zero,
914    the operation aborts if no data is received after that many
915    seconds.  If TIMEOUT is -1, the value of opt.timeout is used for
916    TIMEOUT.  */
917
918 int
919 fd_write (int fd, char *buf, int bufsize, double timeout)
920 {
921   int res;
922   struct transport_info *info;
923   LAZY_RETRIEVE_INFO (info);
924
925   /* `write' may write less than LEN bytes, thus the loop keeps trying
926      it until all was written, or an error occurred.  */
927   res = 0;
928   while (bufsize > 0)
929     {
930       if (!poll_internal (fd, info, WAIT_FOR_WRITE, timeout))
931         return -1;
932       if (info && info->writer)
933         res = info->writer (fd, buf, bufsize, info->ctx);
934       else
935         res = sock_write (fd, buf, bufsize);
936       if (res <= 0)
937         break;
938       buf += res;
939       bufsize -= res;
940     }
941   return res;
942 }
943
944 /* Close the file descriptor FD.  */
945
946 void
947 fd_close (int fd)
948 {
949   struct transport_info *info;
950   if (fd < 0)
951     return;
952
953   /* Don't use LAZY_RETRIEVE_INFO because fd_close() is only called once
954      per socket, so that particular optimization wouldn't work.  */
955   info = NULL;
956   if (transport_map)
957     info = hash_table_get (transport_map, (void *) fd);
958
959   if (info && info->closer)
960     info->closer (fd, info->ctx);
961   else
962     sock_close (fd);
963
964   if (info)
965     {
966       hash_table_remove (transport_map, (void *) fd);
967       xfree (info);
968       ++transport_map_modified_tick;
969     }
970 }