]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/dsi/dsi_tcp.c
Merge master
[netatalk.git] / libatalk / dsi / dsi_tcp.c
index 74d92de1db91183e245a02ca857af8d7ebd4edb2..b87c253b9c4a0f7e09cac95470235f02e44ca203 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: dsi_tcp.c,v 1.25 2009-12-08 22:34:37 didg Exp $
- *
  * Copyright (c) 1997, 1998 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
  *
@@ -17,9 +15,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif /* HAVE_UNISTD_H */
 #include <errno.h>
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/socket.h>
-
-#ifdef HAVE_STDINT_H
 #include <stdint.h>
-#endif /* HAVE_STDINT_H */
 
 #include <sys/ioctl.h>
 #ifdef TRU64
@@ -58,7 +51,7 @@ int deny_severity = log_warning;
 #include <atalk/dsi.h>
 #include <atalk/compat.h>
 #include <atalk/util.h>
-#include <netatalk/endian.h>
+
 #include "dsi_private.h"
 
 #define min(a,b)  ((a) < (b) ? (a) : (b))
@@ -86,25 +79,6 @@ 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_dsi, "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_)
 {
@@ -146,6 +120,9 @@ static int dsi_tcp_open(DSI *dsi)
         u_int8_t block[DSI_BLOCKSIZ];
         size_t stored;
 
+        /* Immediateyl mark globally that we're a child now */
+        parent_or_child = 1;
+
         /* reset signals */
         server_reset_signal();
 
@@ -223,8 +200,6 @@ static int dsi_tcp_open(DSI *dsi)
         sigaction(SIGALRM, &oldact, NULL);
 #endif
 
-        dsi_tcp_timeout(dsi);
-
         LOG(log_info, logtype_dsi, "AFP/TCP session from %s:%u",
             getip_string((struct sockaddr *)&dsi->client),
             getip_port((struct sockaddr *)&dsi->client));
@@ -239,7 +214,7 @@ static int dsi_tcp_open(DSI *dsi)
 #define IFF_SLAVE 0
 #endif
 
-static void guess_interface(DSI *dsi, const char *hostname)
+static void guess_interface(DSI *dsi, const char *hostname, const char *port)
 {
     int fd;
     char **start, **list;
@@ -271,11 +246,11 @@ static void guess_interface(DSI *dsi, const char *hostname)
 
         memset(&dsi->server, 0, sizeof(struct sockaddr_storage));
         sa->sin_family = AF_INET;
-        sa->sin_port = htons(548);
+        sa->sin_port = htons(atoi(port));
         sa->sin_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
 
-        LOG(log_info, logtype_dsi, "dsi_tcp: '%s' on interface '%s' will be used instead.",
-                  getip_string((struct sockaddr *)&dsi->server), ifr.ifr_name);
+        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_dsi, "dsi_tcp (Chooser will not select afp/tcp) "
@@ -304,14 +279,23 @@ 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_dsi, "dsi_tcp_init: getaddrinfo: %s\n", gai_strerror(ret));
         return 0;
@@ -337,6 +321,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
@@ -416,7 +404,7 @@ int dsi_tcp_init(DSI *dsi, const char *hostname, const char *address,
     freeaddrinfo(servinfo);
 
 interfaces:
-    guess_interface(dsi, hostname);
+    guess_interface(dsi, hostname, port ? port : "548");
     return 1;
 }