]> git.pld-linux.org Git - packages/exim.git/commitdiff
- update exim-3_32-3
authorareq <areq@pld-linux.org>
Mon, 13 Aug 2001 21:57:39 +0000 (21:57 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    exim-ipv6.patch -> 1.2

exim-ipv6.patch

index c329dc27277b89318bcf26a037178560d0658d58..710e0cf5bde75677b6f1c9e378da1e603538d39f 100644 (file)
-diff -urN exim-3.32.org/src/daemon.c exim-3.32/src/daemon.c
---- exim-3.32.org/src/daemon.c Tue Aug  7 23:32:54 2001
-+++ exim-3.32/src/daemon.c     Tue Aug  7 23:31:08 2001
-@@ -698,18 +698,18 @@
-   else
-     {
-+    #if HAVE_IPV6
-     addresses = store_get(sizeof(ip_address_item));
-     addresses->next = NULL;
--    addresses->address[0] = 0;
-+    addresses->address[0] = ':';
-+    addresses->address[1] = 0;
-     listen_socket_count = 1;
-+    #endif /* HAVE_IPV6 */
--    #if HAVE_IPV6
-     addresses->next = store_get(sizeof(ip_address_item));
-     addresses->next->next = NULL;
--    addresses->next->address[0] = ':';
--    addresses->next->address[1] = 0;
-+    addresses->next->address[0] = 0;
-     listen_socket_count++;
--    #endif  /* HAVE_IPV6 */
-     }
-   /* Get a vector to remember all the sockets in */
-@@ -856,7 +856,11 @@
-   connections that is allowed. */
-   for (sk = 0; sk < listen_socket_count; sk++)
--    listen(listen_sockets[sk], smtp_connect_backlog);
-+    if (listen(listen_sockets[sk], smtp_connect_backlog) < 0)
-+      {
-+      close(listen_sockets[sk]);
-+      listen_socket_count--;
-+      }
-   }
- /* Set up the handler for SIGHUP, which causes a restart of the daemon. */
-
+diff -urN exim-3.32.org/src/daemon.c exim-3.32/src/daemon.c\r
+--- exim-3.32.org/src/daemon.c Mon Aug 13 20:01:02 2001\r
++++ exim-3.32/src/daemon.c     Mon Aug 13 20:01:27 2001\r
+@@ -689,26 +689,62 @@\r
+       listen_socket_count++;\r
+     }\r
\r
+-  /* Otherwise set up one address item with a null address, implying listening\r
+-  on all interfaces. In an IPv6 world, we set up a second address for listening\r
+-  on all IPv6 interfaces. Some IPv6 stacks will pick up incoming IPv4 calls on\r
+-  an IPv6 wildcard socket, but some won't (there are security issues). Using\r
+-  two sockets should work in all cases. We identify an IPv6 wildcard address by\r
+-  the string ":". */\r
++  /* Otherwise we set up things to listen on all interfaces. In an IPv4 world,\r
++  this is just a single, empty address. On systems with IPv6, several different\r
++  implementation approaches have been taken. This code is now supposed to work\r
++  with all of them. The point of difference is whether an IPv6 socket that is\r
++  listening on all interfaces will receive incoming IPv4 calls or not.\r
++\r
++  . On Solaris, an IPv6 socket will accept IPv4 calls, and give them as mapped\r
++    addresses. However, if an IPv4 socket is also listening on all interfaces,\r
++    calls are directed to the appropriate socket.\r
++\r
++  . On (some versions of) Linux, an IPv6 socket will accept IPv4 calls, and\r
++    give them as mapped addresses, but an attempt also to listen on an IPv4\r
++    socket on all interfaces causes an error.\r
++\r
++  . On OpenBSD, an IPv6 socket will not accept IPv4 calls. You have to set up\r
++    two sockets if you want to accept both kinds of call.\r
++\r
++  . FreeBSD is like OpenBSD, but it has the IPV6_V6ONLY socket option, which\r
++    can be turned off, to make it behave like the versions of Linux described\r
++    above.\r
++\r
++  . I heard a report that the USAGI IPv6 stack for Linux has implemented\r
++    IPV6_V6ONLY.\r
++\r
++  So, what we do is as follows:\r
++\r
++   (1) At this point we set up two addresses, one containing ":" to indicate\r
++   an IPv6 wildcard address, and an empty one to indicate an IPv4 wildcard\r
++   address.\r
++\r
++   (2) Later, when we create the IPv6 socket, we set IPV6_V6ONLY if that option\r
++   is defined.\r
++\r
++   (3) We listen on the v6 socket first. If that fails, there is a serious\r
++   error.\r
++\r
++   (4) We listen on the v4 socket second. If that fails with the error\r
++   EADDRINUSE, assume we are in the situation where just a single socket is\r
++   permitted, and ignore the error. */\r
\r
+   else\r
+     {\r
+     addresses = store_get(sizeof(ip_address_item));\r
+-    addresses->next = NULL;\r
+-    addresses->address[0] = 0;\r
+-    listen_socket_count = 1;\r
\r
+     #if HAVE_IPV6\r
+     addresses->next = store_get(sizeof(ip_address_item));\r
++    addresses->address[0] = ':';\r
++    addresses->address[1] = 0;\r
+     addresses->next->next = NULL;\r
+-    addresses->next->address[0] = ':';\r
+-    addresses->next->address[1] = 0;\r
+-    listen_socket_count++;\r
++    addresses->next->address[0] = 0;\r
++    listen_socket_count = 2;\r
++\r
++    #else\r
++    addresses->next = NULL;\r
++    addresses->address[0] = 0;\r
++    listen_socket_count = 1;\r
+     #endif  /* HAVE_IPV6 */\r
+     }\r
\r
+@@ -726,10 +762,12 @@\r
+   #endif\r
\r
+   /* For each IP address, create a socket and bind it to the appropriate\r
+-  port. Some IPv6 stacks can handle IPv4 addresses on IPv6 sockets using\r
+-  the mapping facilities. However, some don't do this because of security\r
+-  concerns. Therefore, we use IPv4 sockets for IPv4 addresses even in an\r
+-  IPv6 world. */\r
++  port. See comments above about IPv6 sockets that may or may not accept IPv4\r
++  calls when listening on all interfaces. We also have to cope with the case of\r
++  a system with IPv6 libraries, but no IPv6 support in the kernel. In this\r
++  case, we must ignore failure to create an IPv6 socket for wildcard listening.\r
++  The second socket (IPv4) should then get used instead - we have to shuffle\r
++  it down into first place. */\r
\r
+   for (ipa = addresses, sk = 0; sk < listen_socket_count; ipa = ipa->next, sk++)\r
+     {\r
+@@ -738,8 +776,37 @@\r
\r
+     listen_sockets[sk] = socket(af, SOCK_STREAM, 0);\r
+     if (listen_sockets[sk] < 0)\r
+-      log_write(0, LOG_PANIC_DIE, "IPv%c socket creation failed: %s",\r
+-        (af == AF_INET6)? '6' : '4', strerror(errno));\r
++      {\r
++      /* Just log failure for an IPv6 wildcard socket */\r
++\r
++      if (af == AF_INET6 && local_interfaces == NULL)\r
++        {\r
++        log_write(0, LOG_MAIN, "Failed to create IPv6 socket for wildcard "\r
++          "listening (%s): falling back to IPv4", strerror(errno));\r
++\r
++        addresses = addresses->next;   /* Chop IPv6 off the list */\r
++        sk--;                          /* Back up the count */\r
++        listen_socket_count--;         /* Reduce the total */\r
++        continue;                      /* With the IPv4 socket */\r
++        }\r
++\r
++      /* Not a failure to create an IPv6 socket for wildcard listening */\r
++\r
++      else\r
++        log_write(0, LOG_PANIC_DIE, "IPv%c socket creation failed: %s",\r
++          (af == AF_INET6)? '6' : '4', strerror(errno));\r
++      }\r
++\r
++    /* If this is an IPv6 wildcard socket, set IPV6_V6ONLY if that option is\r
++    available. */\r
++\r
++    #ifdef IPV6_V6ONLY\r
++    if (local_interfaces == NULL && af == AF_INET6 &&\r
++        setsockopt(listen_sockets[sk], SOL_SOCKET, IPV6_V6ONLY, (char *)(&on),\r
++          sizeof(on)) < 0)\r
++      log_write(0, LOG_PANIC_DIE, "setting IPV6_V6ONLY on socket failed: %s",\r
++        strerror(errno));\r
++    #endif  /* IPV6_V6ONLY */\r
\r
+     /* Set SO_REUSEADDR so that the daemon can be restarted while a connection\r
+     is being handled.  Without this, a connection will prevent reuse of the\r
+@@ -853,10 +920,35 @@\r
+     }\r
\r
+   /* Start listening on the bound sockets, establishing the maximum backlog of\r
+-  connections that is allowed. */\r
++  connections that is allowed. In an IPv6 environment, if listen() fails with\r
++  the error EADDRINUSE and we are doing wildcard listening and this is the\r
++  second (i.e last) socket, ignore the error on the grounds that we must be\r
++  in a system where the IPv6 socket accepts both kinds of call. */\r
\r
+   for (sk = 0; sk < listen_socket_count; sk++)\r
+-    listen(listen_sockets[sk], smtp_connect_backlog);\r
++    {\r
++    if (listen(listen_sockets[sk], smtp_connect_backlog) < 0)\r
++      {\r
++      if (errno == EADDRINUSE && local_interfaces == NULL && sk > 0)\r
++        {\r
++        DEBUG(9) debug_printf("wildcard IPv4 listen() failed after IPv6 "\r
++          "listen() success; EADDRINUSE ignored\n");\r
++        close(listen_sockets[sk]);\r
++        listen_socket_count--;       /* OK because we know we are in the */\r
++        break;                       /* last iteration of this loop */\r
++        }\r
++      else\r
++        {\r
++        int skf;\r
++        for (ipa = addresses, skf = 0; skf < sk; ipa = ipa->next, skf++);\r
++        log_write(0, LOG_PANIC_DIE, "listen() failed on interface %s: %s",\r
++          (ipa->address[0] == 0)? "(any IPv4)" :\r
++          (ipa->address[0] == ':' && ipa->address[1] == ':')? "(any IPv6)" :\r
++          ipa->address,\r
++          strerror(errno));\r
++        }\r
++      }\r
++    }\r
+   }\r
\r
+ /* Set up the handler for SIGHUP, which causes a restart of the daemon. */\r
This page took 0.064753 seconds and 4 git commands to generate.