]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/dsi/dsi_tcp.c
Merge from branch-2-1
[netatalk.git] / libatalk / dsi / dsi_tcp.c
index 659ea7e561b3050a0dfe99a31f4d1ea0a6eee4f3..9c44116a8494944fa15a96346c4b31e02ab9d6de 100644 (file)
@@ -86,29 +86,10 @@ static void dsi_tcp_close(DSI *dsi)
     dsi->socket = -1;
 }
 
-static void dsi_tcp_timeout(DSI *dsi)
-{
-    struct timeval tv;
-    /* 2 seconds delay, most of the time it translates to 4 seconds:
-     * send/write returns first with whatever it has written and the
-     * second time it returns EAGAIN
-     */
-    tv.tv_sec = 2;
-    tv.tv_usec = 0;
-
-    /* Note: write isn't a restartable syscall if there's a timeout on the socket
-     * we have to test for EINTR
-     */
-    if (setsockopt(dsi->socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
-        LOG(log_error, logtype_default, "dsi_tcp_open: unable to set timeout %s", strerror(errno));
-        exit(EXITERR_CLNT);
-    }
-}
-
 /* alarm handler for tcp_open */
 static void timeout_handler(int sig _U_)
 {
-    LOG(log_error, logtype_default, "dsi_tcp_open: connection timed out");
+    LOG(log_error, logtype_dsi, "dsi_tcp_open: connection timed out");
     exit(EXITERR_CLNT);
 }
 
@@ -128,7 +109,7 @@ static int dsi_tcp_open(DSI *dsi)
         request_init(&req, RQ_DAEMON, dsi->program, RQ_FILE, dsi->socket, NULL);
         fromhost(&req);
         if (!hosts_access(&req)) {
-            LOG(deny_severity, logtype_default, "refused connect from %s", eval_client(&req));
+            LOG(deny_severity, logtype_dsi, "refused connect from %s", eval_client(&req));
             close(dsi->socket);
             errno = ECONNREFUSED;
             dsi->socket = -1;
@@ -160,7 +141,7 @@ static int dsi_tcp_open(DSI *dsi)
 
         if ((sigaction(SIGALRM, &newact, &oldact) < 0) ||
             (setitimer(ITIMER_REAL, &timer, NULL) < 0)) {
-            LOG(log_error, logtype_default, "dsi_tcp_open: %s", strerror(errno));
+            LOG(log_error, logtype_dsi, "dsi_tcp_open: %s", strerror(errno));
             exit(EXITERR_SYS);
         }
 #endif
@@ -176,7 +157,7 @@ static int dsi_tcp_open(DSI *dsi)
             exit(EXITERR_CLNT);
         }
         if (len < 2 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
-            LOG(log_error, logtype_default, "dsi_tcp_open: invalid header");
+            LOG(log_error, logtype_dsi, "dsi_tcp_open: invalid header");
             exit(EXITERR_CLNT);
         }
 
@@ -187,7 +168,7 @@ static int dsi_tcp_open(DSI *dsi)
             if (len > 0)
                 stored += len;
             else {
-                LOG(log_error, logtype_default, "dsi_tcp_open: stream_read: %s", strerror(errno));
+                LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
                 exit(EXITERR_CLNT);
             }
         }
@@ -211,7 +192,7 @@ static int dsi_tcp_open(DSI *dsi)
             if (len > 0)
                 stored += len;
             else {
-                LOG(log_error, logtype_default, "dsi_tcp_open: stream_read: %s", strerror(errno));
+                LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
                 exit(EXITERR_CLNT);
             }
         }
@@ -223,9 +204,7 @@ static int dsi_tcp_open(DSI *dsi)
         sigaction(SIGALRM, &oldact, NULL);
 #endif
 
-        dsi_tcp_timeout(dsi);
-
-        LOG(log_info, logtype_default, "AFP/TCP session from %s:%u",
+        LOG(log_info, logtype_dsi, "AFP/TCP session from %s:%u",
             getip_string((struct sockaddr *)&dsi->client),
             getip_port((struct sockaddr *)&dsi->client));
     }
@@ -274,11 +253,11 @@ static void guess_interface(DSI *dsi, const char *hostname, const char *port)
         sa->sin_port = htons(atoi(port));
         sa->sin_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
 
-        LOG(log_info, logtype_default, "dsi_tcp: '%s:%s' on interface '%s' will be used instead.",
+        LOG(log_info, logtype_dsi, "dsi_tcp: '%s:%s' on interface '%s' will be used instead.",
             getip_string((struct sockaddr *)&dsi->server), port, ifr.ifr_name);
         goto iflist_done;
     }
-    LOG(log_info, logtype_default, "dsi_tcp (Chooser will not select afp/tcp) "
+    LOG(log_info, logtype_dsi, "dsi_tcp (Chooser will not select afp/tcp) "
         "Check to make sure %s is in /etc/hosts and the correct domain is in "
         "/etc/resolv.conf: %s", hostname, strerror(errno));
 
@@ -304,16 +283,25 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
 
     /* Prepare hint for getaddrinfo */
     memset(&hints, 0, sizeof hints);
+#if !defined(FREEBSD)
     hints.ai_family = AF_UNSPEC;
+#endif
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_flags = AI_NUMERICSERV;
-    if ( ! address)
+
+    if ( ! address) {
         hints.ai_flags |= AI_PASSIVE;
-    else
+#if defined(FREEBSD)
+        hints.ai_family = AF_INET6;
+#endif
+    } else {
         hints.ai_flags |= AI_NUMERICHOST;
-
+#if defined(FREEBSD)
+        hints.ai_family = AF_UNSPEC;
+#endif
+    }
     if ((ret = getaddrinfo(address ? address : NULL, port ? port : "548", &hints, &servinfo)) != 0) {
-        LOG(log_error, logtype_default, "dsi_tcp_init: getaddrinfo: %s\n", gai_strerror(ret));
+        LOG(log_error, logtype_dsi, "dsi_tcp_init: getaddrinfo: %s\n", gai_strerror(ret));
         return 0;
     }
 
@@ -324,7 +312,7 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
         /* loop through all the results and bind to the first we can */
         for (p = servinfo; p != NULL; p = p->ai_next) {
             if ((dsi->serversock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
-                LOG(log_info, logtype_default, "dsi_tcp_init: socket: %s", strerror(errno));
+                LOG(log_info, logtype_dsi, "dsi_tcp_init: socket: %s", strerror(errno));
                 continue;
             }
 
@@ -337,6 +325,10 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
             flag = 1;
             setsockopt(dsi->serversock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
 #endif
+#if defined(FREEBSD) && defined(IPV6_BINDV6ONLY)
+            int on = 0;
+            setsockopt(dsi->serversock, IPPROTO_IPV6, IPV6_BINDV6ONLY, (char *)&on, sizeof (on));
+#endif
 
 #ifdef USE_TCP_NODELAY
 #ifndef SOL_TCP
@@ -348,13 +340,13 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
             
             if (bind(dsi->serversock, p->ai_addr, p->ai_addrlen) == -1) {
                 close(dsi->serversock);
-                LOG(log_info, logtype_default, "dsi_tcp_init: bind: %s\n", strerror(errno));
+                LOG(log_info, logtype_dsi, "dsi_tcp_init: bind: %s\n", strerror(errno));
                 continue;
             }
 
             if (listen(dsi->serversock, DSI_TCPMAXPEND) < 0) {
                 close(dsi->serversock);
-                LOG(log_info, logtype_default, "dsi_tcp_init: listen: %s\n", strerror(errno));
+                LOG(log_info, logtype_dsi, "dsi_tcp_init: listen: %s\n", strerror(errno));
                 continue;
             }
             
@@ -362,7 +354,7 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
         }
 
         if (p == NULL)  {
-            LOG(log_error, logtype_default, "dsi_tcp_init: no suitable network config for TCP socket");
+            LOG(log_error, logtype_dsi, "dsi_tcp_init: no suitable network config for TCP socket");
             freeaddrinfo(servinfo);
             return 0;
         }
@@ -389,7 +381,7 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
     hints.ai_socktype = SOCK_STREAM;
 
     if ((ret = getaddrinfo(hostname, port ? port : "548", &hints, &servinfo)) != 0) {
-        LOG(log_info, logtype_default, "dsi_tcp_init: getaddrinfo '%s': %s\n", hostname, gai_strerror(ret));
+        LOG(log_info, logtype_dsi, "dsi_tcp_init: getaddrinfo '%s': %s\n", hostname, gai_strerror(ret));
         goto interfaces;
     }
 
@@ -412,7 +404,7 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
         freeaddrinfo(servinfo);
         return 1;
     }
-    LOG(log_info, logtype_default, "dsi_tcp: hostname '%s' resolves to loopback address", hostname);
+    LOG(log_info, logtype_dsi, "dsi_tcp: hostname '%s' resolves to loopback address", hostname);
     freeaddrinfo(servinfo);
 
 interfaces: