Imported Upstream version 2.5.2p1
[debian/amanda] / common-src / dgram.c
index a4c4ba378f773ae129e6a40525091e8fd8980aeb..e6d267bb99f45bb646aa4503c3c2fd908dea2dc2 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /* 
- * $Id: dgram.c,v 1.32.2.4 2006/10/16 18:23:53 martinea Exp $
+ * $Id: dgram.c,v 1.32 2006/07/05 19:54:20 martinea Exp $
  *
  * library routines to marshall/send, recv/unmarshall UDP packets
  */
@@ -33,6 +33,7 @@
 #include "arglist.h"
 #include "dgram.h"
 #include "util.h"
+#include "conffile.h"
 
 void
 dgram_socket(
@@ -51,34 +52,36 @@ dgram_socket(
 int
 dgram_bind(
     dgram_t *  dgram,
+    sa_family_t family,
     in_port_t *        portp)
 {
     int s, retries;
     socklen_t len;
-    struct sockaddr_in name;
+    struct sockaddr_storage name;
     int save_errno;
+    int *portrange;
 
+    portrange = getconf_intrange(CNF_RESERVED_UDP_PORT);
     *portp = (in_port_t)0;
-    if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+    if((s = socket(family, SOCK_DGRAM, 0)) == -1) {
        save_errno = errno;
        dbprintf(("%s: dgram_bind: socket() failed: %s\n",
-                 debug_prefix(NULL),
+                 debug_prefix_time(NULL),
                  strerror(save_errno)));
        errno = save_errno;
        return -1;
     }
     if(s < 0 || s >= (int)FD_SETSIZE) {
        dbprintf(("%s: dgram_bind: socket out of range: %d\n",
-                 debug_prefix(NULL),
+                 debug_prefix_time(NULL),
                  s));
        aclose(s);
        errno = EMFILE;                         /* out of range */
        return -1;
     }
 
-    memset(&name, 0, SIZEOF(name));
-    name.sin_family = (sa_family_t)AF_INET;
-    name.sin_addr.s_addr = INADDR_ANY;
+    SS_INIT(&name, family);
+    SS_SET_INADDR_ANY(&name);
 
     /*
      * If a port range was specified, we try to get a port in that
@@ -92,38 +95,24 @@ dgram_bind(
      * is within the range it requires.
      */
     for (retries = 0; ; retries++) {
-#ifdef UDPPORTRANGE
-       if (bind_portrange(s, &name, UDPPORTRANGE, "udp") == 0)
-           goto out;
-       dbprintf(("%s: dgram_bind: Could to bind to port in range: %d - %d.\n",
-                 debug_prefix(NULL), UDPPORTRANGE));
-#endif
-
-       if (bind_portrange(s, &name, (in_port_t)512,
-               (in_port_t)(IPPORT_RESERVED - 1), "udp") == 0)
-           goto out;
-       dbprintf(("%s: dgram_bind: Could to bind to port in range: 512 - %d.\n",
-                 debug_prefix(NULL), IPPORT_RESERVED - 1));
-
-       name.sin_port = INADDR_ANY;
-       if (bind(s, (struct sockaddr *)&name, (socklen_t)sizeof(name)) == 0)
+       if (bind_portrange(s, &name, portrange[0], portrange[1], "udp") == 0)
            goto out;
-       dbprintf(("%s: dgram_bind: Could to bind to any port: %s\n",
-                 debug_prefix(NULL), strerror(errno)));
-
+       dbprintf(("%s: dgram_bind: Could not bind to port in range: %d - %d.\n",
+                 debug_prefix_time(NULL), portrange[0], portrange[1]));
        if (retries >= BIND_CYCLE_RETRIES) {
-           dbprintf(("%s: dgram_bind: Giving up...\n", debug_prefix(NULL)));
+           dbprintf(("%s: dgram_bind: Giving up...\n",
+                     debug_prefix_time(NULL)));
            break;
        }
 
        dbprintf(("%s: dgram_bind: Retrying entire range after 10 second delay.\n",
-                 debug_prefix(NULL)));
+                 debug_prefix_time(NULL)));
        sleep(15);
     }
 
     save_errno = errno;
-    dbprintf(("%s: dgram_bind: bind(INADDR_ANY) failed: %s\n",
-                 debug_prefix(NULL),
+    dbprintf(("%s: dgram_bind: bind(in6addr_any) failed: %s\n",
+                 debug_prefix_time(NULL),
                  strerror(save_errno)));
     aclose(s);
     errno = save_errno;
@@ -136,31 +125,28 @@ out:
     if(getsockname(s, (struct sockaddr *)&name, &len) == -1) {
        save_errno = errno;
        dbprintf(("%s: dgram_bind: getsockname() failed: %s\n",
-                 debug_prefix(NULL),
+                 debug_prefix_time(NULL),
                  strerror(save_errno)));
        errno = save_errno;
        aclose(s);
        return -1;
     }
-    *portp = (in_port_t)ntohs(name.sin_port);
+    *portp = SS_GET_PORT(&name);
     dgram->socket = s;
 
-    dbprintf(("%s: dgram_bind: socket bound to %s.%d\n",
-             debug_prefix_time(NULL),
-             inet_ntoa(name.sin_addr),
-             *portp));
+    dbprintf(("%s: dgram_bind: socket %d bound to %s\n",
+             debug_prefix_time(NULL), dgram->socket, str_sockaddr(&name)));
     return 0;
 }
 
 
 int
 dgram_send_addr(
-    struct sockaddr_in addr,
+    struct sockaddr_storage    *addr,
     dgram_t *          dgram)
 {
     int s, rc;
     int socket_opened;
-    struct sockaddr_in addr_save;
     int save_errno;
     int max_wait;
     int wait_count;
@@ -170,18 +156,18 @@ dgram_send_addr(
 #endif
 
     dbprintf(("%s: dgram_send_addr(addr=%p, dgram=%p)\n",
-                       debug_prefix(NULL), &addr, dgram));
-    dump_sockaddr(&addr);
+             debug_prefix_time(NULL), addr, dgram));
+    dump_sockaddr(addr);
     dbprintf(("%s: dgram_send_addr: %p->socket = %d\n",
-                       debug_prefix(NULL), dgram, dgram->socket));
+             debug_prefix_time(NULL), dgram, dgram->socket));
     if(dgram->socket != -1) {
        s = dgram->socket;
        socket_opened = 0;
     } else {
-       if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+       if((s = socket(addr->ss_family, SOCK_DGRAM, 0)) == -1) {
            save_errno = errno;
            dbprintf(("%s: dgram_send_addr: socket() failed: %s\n",
-                     debug_prefix(NULL),
+                     debug_prefix_time(NULL),
                      strerror(save_errno)));
            errno = save_errno;
            return -1;
@@ -192,16 +178,15 @@ dgram_send_addr(
                (void *)&on, (socklen_t)sizeof(on));
        if (r < 0) {
            dbprintf(("%s: dgram_send_addr: setsockopt(SO_REUSEADDR) failed: %s\n",
-                         debug_prefix(NULL),
-                         strerror(errno)));
+                     debug_prefix_time(NULL),
+                     strerror(errno)));
        }
 #endif
     }
 
-    memcpy(&addr_save, &addr, SIZEOF(addr));
     if(s < 0 || s >= FD_SETSIZE) {
        dbprintf(("%s: dgram_send_addr: socket out of range: %d\n",
-                 debug_prefix(NULL),
+                 debug_prefix_time(NULL),
                  s));
        errno = EMFILE;                         /* out of range */
        rc = -1;
@@ -213,15 +198,14 @@ dgram_send_addr(
                 dgram->data,
                 dgram->len,
                 0, 
-                (struct sockaddr *)&addr,
-                (int)sizeof(struct sockaddr_in)) == -1) {
+                (struct sockaddr *)addr,
+                SS_LEN(addr)) == -1) {
 #ifdef ECONNREFUSED
            if(errno == ECONNREFUSED && wait_count++ < max_wait) {
                sleep(5);
-               dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after ECONNREFUSED\n",
+               dbprintf(("%s: dgram_send_addr: sendto(%s): retry %d after ECONNREFUSED\n",
                      debug_prefix_time(NULL),
-                     inet_ntoa(addr_save.sin_addr),
-                     (in_port_t)ntohs(addr.sin_port),
+                     str_sockaddr(addr),
                      wait_count));
                continue;
            }
@@ -229,19 +213,17 @@ dgram_send_addr(
 #ifdef EAGAIN
            if(errno == EAGAIN && wait_count++ < max_wait) {
                sleep(5);
-               dbprintf(("%s: dgram_send_addr: sendto(%s.%hu): retry %d after EAGAIN\n",
+               dbprintf(("%s: dgram_send_addr: sendto(%s): retry %d after EAGAIN\n",
                      debug_prefix_time(NULL),
-                     inet_ntoa(addr_save.sin_addr),
-                     (in_port_t)ntohs(addr.sin_port),
+                     str_sockaddr(addr),
                      wait_count));
                continue;
            }
 #endif
            save_errno = errno;
-           dbprintf(("%s: dgram_send_addr: sendto(%s.%d) failed: %s \n",
+           dbprintf(("%s: dgram_send_addr: sendto(%s) failed: %s \n",
                  debug_prefix_time(NULL),
-                 inet_ntoa(addr_save.sin_addr),
-                 (int) ntohs(addr.sin_port),
+                 str_sockaddr(addr),
                  strerror(save_errno)));
            errno = save_errno;
            rc = -1;
@@ -252,10 +234,9 @@ dgram_send_addr(
     if(socket_opened) {
        save_errno = errno;
        if(close(s) == -1) {
-           dbprintf(("%s: dgram_send_addr: close(%s.%d): failed: %s\n",
-                     debug_prefix(NULL),
-                     inet_ntoa(addr_save.sin_addr),
-                     (int) ntohs(addr.sin_port),
+           dbprintf(("%s: dgram_send_addr: close(%s): failed: %s\n",
+                     debug_prefix_time(NULL),
+                     str_sockaddr(addr),
                      strerror(errno)));
            /*
             * Calling function should not care that the close failed.
@@ -269,37 +250,11 @@ dgram_send_addr(
 }
 
 
-int
-dgram_send(
-    char *     hostname,
-    in_port_t  port,
-    dgram_t *  dgram)
-{
-    struct sockaddr_in name;
-    struct hostent *hp;
-    int save_errno;
-
-    if((hp = gethostbyname(hostname)) == 0) {
-       save_errno = errno;
-       dbprintf(("%s: dgram_send: gethostbyname(%s) failed\n",
-                 debug_prefix_time(NULL),
-                 hostname));
-       errno = save_errno;
-       return -1;
-    }
-    memcpy(&name.sin_addr, hp->h_addr, (size_t)hp->h_length);
-    name.sin_family = (sa_family_t)AF_INET;
-    name.sin_port = (in_port_t)htons(port);
-
-    return dgram_send_addr(name, dgram);
-}
-
-
 ssize_t
 dgram_recv(
     dgram_t *          dgram,
     int                        timeout,
-    struct sockaddr_in *fromaddr)
+    struct sockaddr_storage *fromaddr)
 {
     SELECT_ARG_TYPE ready;
     struct timeval to;
@@ -350,13 +305,13 @@ dgram_recv(
        return nfound;
     }
 
-    addrlen = (socklen_t)sizeof(struct sockaddr_in);
+    addrlen = (socklen_t)sizeof(struct sockaddr_storage);
     size = recvfrom(sock, dgram->data, (size_t)MAX_DGRAM, 0,
                    (struct sockaddr *)fromaddr, &addrlen);
     if(size == -1) {
        save_errno = errno;
        dbprintf(("%s: dgram_recv: recvfrom() failed: %s\n",
-                 debug_prefix(NULL),
+                 debug_prefix_time(NULL),
                  strerror(save_errno)));
        errno = save_errno;
        return -1;