IPv6 patches
authorZdeněk Salvet <salvet@ics.muni.cz>
Thu, 18 Mar 2010 10:17:08 +0000 (10:17 +0000)
committerZdeněk Salvet <salvet@ics.muni.cz>
Thu, 18 Mar 2010 10:17:08 +0000 (10:17 +0000)
org.glite.lb.client/src/connection.c
org.glite.lb.client/src/notification.c
org.glite.lb.logger/src/logd.c
org.glite.lb.logger/src/logd_proto.c
org.glite.lb.server/src/bkserverd.c
org.glite.lbjp-common.server-bones/src/srvbones.c
org.glite.security.gss/test/test_gss.cpp

index 3bc75f1..ea73bb6 100644 (file)
@@ -688,7 +688,7 @@ int edg_wll_accept(edg_wll_Context ctx, int fd)
        time_t lifetime = 0;
        struct stat statinfo;
        int acquire_cred = 0;
-        struct sockaddr_in     a;
+        struct sockaddr_storage        a;
         socklen_t              alen;
        edg_wll_GssStatus       gss_code;
 
index 7ffe4a4..18395ab 100644 (file)
@@ -96,26 +96,53 @@ static void get_name_and_port(const char *address, char **name, int *port)
 
 static int my_bind(edg_wll_Context ctx, const char *name, int port, int *fd)
 {
-       struct  sockaddr_in     a;
-       socklen_t               alen = sizeof(a);
-       int                     sock;
-               
-       sock = socket(PF_INET,SOCK_STREAM,0);
-       if (sock<0) 
-               return  edg_wll_SetError(ctx, errno, "socket() failed");
+       int             sock;
+       int             ret;
+       struct addrinfo *ai;
+       struct addrinfo hints;
+       char            *portstr = NULL;
+
+       asprintf(&portstr, "%d", port);
+       if (portstr == NULL) {
+               return edg_wll_SetError(ctx, ENOMEM, "my_bind(): ENOMEM converting port number");
+       }
+
+       memset (&hints, '\0', sizeof (hints));
+       hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE | AI_ADDRCONFIG;
+       hints.ai_socktype = SOCK_STREAM;
 
-       a.sin_family = AF_INET;
-       a.sin_port = htons(port);
-       a.sin_addr.s_addr = name? inet_addr(name): htonl(INADDR_ANY);
+       ret = getaddrinfo (name, portstr, &hints, &ai);
+       free(portstr);
+       if (ret != 0) {
+               return edg_wll_SetError(ctx, EADDRNOTAVAIL, gai_strerror(ret));
+       }
+       if (ai == NULL) {
+               return edg_wll_SetError(ctx, EADDRNOTAVAIL, "no result from getaddrinfo");
+       }
+
+       sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+       if (sock == -1) { 
+               freeaddrinfo(ai);
+               return  edg_wll_SetError(ctx, errno, "socket() failed");
+       }
 
 //     setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-       if (bind(sock,(struct sockaddr *)&a,alen))
-               return  edg_wll_SetError(ctx, errno, "bind() failed");
+       ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
+       if (ret == -1) { 
+               edg_wll_SetError(ctx, errno, "bind() failed");
+               close(sock); 
+               freeaddrinfo(ai);
+               return edg_wll_Error(ctx, NULL, NULL);
+       }
+       freeaddrinfo(ai);
+
+       ret = listen(sock, CON_QUEUE);
+       if (ret == -1) { 
+               edg_wll_SetError(ctx, errno, "listen() failed");
+               close(sock); 
+               return edg_wll_Error(ctx, NULL, NULL);
+       }
 
-       
-       if (listen(sock,CON_QUEUE)) 
-               return edg_wll_SetError(ctx, errno, "listen() failed");
-       
        *fd = sock;
        
        return edg_wll_Error(ctx,NULL,NULL);
@@ -150,33 +177,45 @@ static int get_client_address(
                char **address) 
        
 {
-       struct  sockaddr_in     a;
+       struct  sockaddr_storage        a;
        socklen_t               alen = sizeof(a);
-       struct hostent          *he;
+       int                     e;
        char                    *name = NULL;
        int                     port = 0;
+       struct addrinfo *ai;
+       struct addrinfo hints;
+       char            hostnum[64], hostnum1[64], portnum[16];
        
+       memset (&hints, '\0', sizeof (hints));
+       hints.ai_flags = AI_ADDRCONFIG;
+       hints.ai_socktype = SOCK_STREAM;
        
        if (address_override) {
-               struct in_addr in;
                
                get_name_and_port(address_override, &name, &port);
                
-               if ( (he = gethostbyname((const char *) name)) == NULL) {
-                       edg_wll_SetError(ctx, errno, "gethostbyname() failed");
+               e = getaddrinfo((const char *) name, NULL, &hints, & ai);
+               if (e) {
+                       edg_wll_SetError(ctx, EADDRNOTAVAIL, "getaddrinfo() failed");
                        goto err;
                }
-               
+
                free(name);
                
-               memmove(&in.s_addr, he->h_addr_list[0], sizeof(in.s_addr));
-               name = strdup(inet_ntoa(in));
-       
-               if ( (he = gethostbyname((const char *) name)) == NULL) {
-                       edg_wll_SetError(ctx, errno, "gethostbyname() failed");
+               e = getnameinfo ((struct sockaddr *) ai->ai_addr, ai->ai_addrlen,
+                       hostnum, sizeof(hostnum), NULL, 0, NI_NUMERICHOST );
+               if (e) {
+                       edg_wll_SetError(ctx, EADDRNOTAVAIL, "getnameinfo() failed");
+                       goto err;
+               }
+               freeadrinfo(ai);
+
+               e = getaddrinfo((const char *) hostnum, NULL, &hints, & ai);
+               if (e) {
+                       edg_wll_SetError(ctx, EADDRNOTAVAIL, "getaddrinfo() failed");
                        goto err;
                }
-       
+
                /* Test whether open sockket represents the same address as address_override
                 * if not, close ctx->notifSock and bind to new socket corresponding to 
                 * address_override
@@ -185,7 +224,19 @@ static int get_client_address(
                        if (getsockname(ctx->notifSock, (struct sockaddr *) &a, &alen)) 
                                return edg_wll_SetError(ctx, errno, "getsockname() failed");
                        
-                       if ( (strcmp(inet_ntoa(a.sin_addr), name)) || (ntohs(a.sin_port) != port) ) {
+                       e = getnameinfo ((struct sockaddr *) &a, alen,
+                               NULL, 0, portnum, sizeof(portnum), NI_NUMERICSERV );
+                       if (e) {
+                               edg_wll_SetError(ctx, EADDRNOTAVAIL, "getnameinfo() failed");
+                               goto err;
+                       }
+                       e = getnameinfo ((struct sockaddr *) &a, alen,
+                               hostnum1, sizeof(hostnum1), NULL, 0, NI_NUMERICHOST );
+                       if (e) {
+                               edg_wll_SetError(ctx, EADDRNOTAVAIL, "getnameinfo() failed");
+                               goto err;
+                       }
+                       if ( (strcmp(hostnum1, hostnum)) || (atoi(portnum) != port) ) {
                                
                                if (close(ctx->notifSock)) {
                                        edg_wll_SetError(ctx, errno, "close() failed");
@@ -217,10 +268,13 @@ static int get_client_address(
                if (getsockname(fd == -1 ? ctx->notifSock : fd,(struct sockaddr *)  &a, &alen)) 
                        return edg_wll_SetError(ctx, errno, "getsockname() failed");
 
-               if (a.sin_addr.s_addr == INADDR_ANY)
-                       asprintf(address,"0.0.0.0:%d", ntohs(a.sin_port));
-               else
-                       asprintf(address,"%s:%d", inet_ntoa(a.sin_addr), ntohs(a.sin_port));
+               e = getnameinfo ((struct sockaddr *) &a, alen,
+                       hostnum, sizeof(hostnum), portnum, sizeof(portnum), NI_NUMERICSERV );
+               if (e) {
+                       edg_wll_SetError(ctx, EADDRNOTAVAIL, "getnameinfo() failed");
+                       goto err;
+               }
+               asprintf(address,"%s:%s", hostnum, portnum);
        }
 
 err:
index 3f3993e..003783e 100644 (file)
@@ -32,6 +32,7 @@ limitations under the License.
 #include <getopt.h>
 #include <assert.h>
 #include <errno.h>
+#include <netdb.h>
 
 #if defined(FREEBSD) || defined(__FreeBSD__)
 #define TCP_CORK TCP_NOPUSH
@@ -203,8 +204,9 @@ doit(int socket, edg_wll_GssCred cred_handle, char *file_name_prefix, int noipc,
     edg_wll_GssStatus  gss_stat;
     edg_wll_GssPrincipal client = NULL;
     fd_set fdset;
-    struct sockaddr_in peer;
+    struct sockaddr_storage    peer;
     socklen_t  alen = sizeof peer;
+    char       peerhost[64], peerserv[16];
 
     ret = count = 0;
     FD_ZERO(&fdset);
@@ -215,6 +217,13 @@ doit(int socket, edg_wll_GssCred cred_handle, char *file_name_prefix, int noipc,
     getpeername(socket,(struct sockaddr *) &peer,&alen);
     glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Accepting connection (remaining timeout %d.%06d sec)\n",
                (int)timeout.tv_sec, (int) timeout.tv_usec);
+    
+    ret = getnameinfo ((struct sockaddr *) &peer, alen, 
+               peerhost, sizeof(peerhost), peerserv, sizeof(peerserv), NI_NUMERICHOST | NI_NUMERICSERV);
+    if (ret) {
+       glite_common_log(LOG_CATEGORY_ACCESS, LOG_PRIORITY_WARN, "getnameinfo: %s", gai_strerror (ret));
+       strcpy(peerhost, "unknown"); strcpy(peerserv, "unknown"); 
+    }
 
 /* XXX: ugly workaround, we may detect false expired certificated
  * probably due to bug in Globus GSS/SSL. */
@@ -224,20 +233,20 @@ doit(int socket, edg_wll_GssCred cred_handle, char *file_name_prefix, int noipc,
        glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_DEBUG,"timeout after gss_accept is %d.%06d sec\n",
                (int)timeout.tv_sec, (int) timeout.tv_usec);
        if ( ret == EDG_WLL_GSS_ERROR_TIMEOUT ) {
-               glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: Client authentication failed - timeout reached, closing.\n",inet_ntoa(peer.sin_addr));
+               glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: Client authentication failed - timeout reached, closing.\n",peerhost);
        } else if (ret == EDG_WLL_GSS_ERROR_GSS) {
                char *gss_err;
 
                edg_wll_gss_get_error(&gss_stat, "Client authentication failed", &gss_err);
                if (strstr(gss_err,_EXPIRED_CERTIFICATE_MESSAGE)) {
-                       glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: false expired certificate: %s\n",inet_ntoa(peer.sin_addr),gss_err);
+                       glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: false expired certificate: %s\n",peerhost,gss_err);
                        free(gss_err);
                        return -1;
                }
-               glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: GSS error: %s, closing.\n",inet_ntoa(peer.sin_addr),gss_err);
+               glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: GSS error: %s, closing.\n",peerhost,gss_err);
                free(gss_err);
        } else {
-               glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: Client authentication failed, closing.\n",inet_ntoa(peer.sin_addr));
+               glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"%s: Client authentication failed, closing.\n",peerhost);
        }
        return 1;
     }
@@ -248,7 +257,7 @@ doit(int socket, edg_wll_GssCred cred_handle, char *file_name_prefix, int noipc,
     if (ret) {
         char *gss_err;
         edg_wll_gss_get_error(&gss_stat, "Cannot read client identification", &gss_err);
-        glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN, "%s: %s\n", inet_ntoa(peer.sin_addr),gss_err);
+        glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN, "%s: %s\n", peerhost,gss_err);
         free(gss_err);
     }
 
@@ -339,7 +348,7 @@ int main(int argc, char *argv[])
 
    int listener_fd;
    int client_fd;
-   struct sockaddr_in client_addr;
+   struct sockaddr_storage client_addr;
    int client_addr_len;
 
    time_t      cert_mtime = 0, key_mtime = 0;
index 83b90bb..8a2adfb 100644 (file)
@@ -29,6 +29,7 @@ limitations under the License.
 #include <fcntl.h>
 #include <stdarg.h>
 #include <errno.h>
+#include <netdb.h>
 
 #include "glite/lbu/escape.h"
 #include "glite/lbu/log.h"
@@ -257,27 +258,47 @@ int do_listen(int port)
 {
        int                ret;
        int                sock;
-       struct sockaddr_in my_addr;
+       struct addrinfo *ai;
+       struct addrinfo hints;
+       char            *portstr = NULL;
+
+       asprintf(&portstr, "%d", port);
+       if (portstr == NULL) {
+               glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"do_listen(): ENOMEM converting port number\n");
+               return -1;
+       }
+
+       memset (&hints, '\0', sizeof (hints));
+       hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE | AI_ADDRCONFIG;
+       hints.ai_socktype = SOCK_STREAM;
 
-       memset(&my_addr, 0, sizeof(my_addr));
-       my_addr.sin_family = AF_INET;
-       my_addr.sin_addr.s_addr = INADDR_ANY;
-       my_addr.sin_port = htons(port);
+       ret = getaddrinfo (NULL, portstr, &hints, &ai);
+       if (ret != 0) {
+               glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: %s", gai_strerror (ret));
+               return -1;
+       }
+       if (ai == NULL) {
+               glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: no return");
+               return -1;
+       }
 
-       sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+       sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
        if (sock == -1) { 
                glite_common_log_SYS_ERROR("socket"); 
                glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_ERROR,"do_listen(): error creating socket\n");
+               freeaddrinfo(ai);
                return -1; 
        }
 
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-       ret = bind(sock, (struct sockaddr *)&my_addr, sizeof(my_addr));
+       ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
        if (ret == -1) { 
                glite_common_log_SYS_ERROR("bind"); 
                glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_ERROR,"do_listen(): error binding socket\n");
+               freeaddrinfo(ai);
                return -1; 
        }
+       freeaddrinfo(ai);
 
        ret = listen(sock, 5);
        if (ret == -1) { 
index 3e805d0..9fa2faa 100644 (file)
@@ -303,8 +303,8 @@ static void usage(char *me)
 
 static int wait_for_open(edg_wll_Context,const char *);
 static int decrement_timeout(struct timeval *, struct timeval, struct timeval);
+static int asyn_gethostbyaddr(char **, char **, const struct sockaddr *, int, struct timeval *, int );
 static int add_root(edg_wll_Context, char *);
-static int asyn_gethostbyaddr(char **, const char *, int, int, struct timeval *);
 static int parse_limits(char *, int *, int *, int *);
 static int check_mkdir(const char *);
 
@@ -390,7 +390,10 @@ struct clnt_data_t {
 int main(int argc, char *argv[])
 {
        int                     i;
-       struct sockaddr_in      a;
+       struct addrinfo *ai;
+       struct addrinfo hints;
+       char *portstr = NULL;
+       int     gaie;
        int                                     opt, pidfile_forced = 0;
        char                            pidfile[PATH_MAX] = EDG_BKSERVERD_PIDFILE,
                                           *name;
@@ -602,62 +605,98 @@ int main(int argc, char *argv[])
 
                glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_INFO, "Server address: %s:%d", fake_host, fake_port);
        }
+
+       memset (&hints, '\0', sizeof (hints));
+       hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE | AI_ADDRCONFIG;
+       hints.ai_socktype = SOCK_STREAM;
+
        if ((mode & SERVICE_SERVER)) {
-               service_table[SRV_SERVE].conn = socket(PF_INET, SOCK_STREAM, 0);
+               gaie = getaddrinfo (NULL, port, &hints, &ai);
+               if (gaie != 0) {
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: %s", gai_strerror (gaie));
+                       return 1;
+               }
+               if (ai == NULL) {
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: no return");
+                       return 1;
+               }
+               service_table[SRV_SERVE].conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                if ( service_table[SRV_SERVE].conn < 0 ) { 
                        glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "socket()");
+                       freeaddrinfo(ai);
                        return 1; 
                }
-               a.sin_family = AF_INET;
-               a.sin_port = htons(atoi(port));
-               a.sin_addr.s_addr = INADDR_ANY;
                setsockopt(service_table[SRV_SERVE].conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-               if ( bind(service_table[SRV_SERVE].conn, (struct sockaddr *) &a, sizeof(a)) )
+               if ( bind(service_table[SRV_SERVE].conn, ai->ai_addr, ai->ai_addrlen) )
                { 
-                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%d)",atoi(port));
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%s)", port);
+                       freeaddrinfo(ai);
                        return 1;
                }
+               freeaddrinfo(ai);
                if ( listen(service_table[SRV_SERVE].conn, CON_QUEUE) ) { 
                        glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "listen()");
                        return 1; 
                }
 
-               service_table[SRV_STORE].conn = socket(PF_INET, SOCK_STREAM, 0);
-               if ( service_table[SRV_STORE].conn < 0) { 
+               asprintf(&portstr, "%d", atoi(port)+1);
+               gaie = getaddrinfo (NULL, portstr, &hints, &ai);
+               if (gaie != 0) {
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: %s", gai_strerror (gaie));
+                       return 1;
+               }
+               if (ai == NULL) {
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: no return");
+                       return 1;
+               }
+               service_table[SRV_STORE].conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+               if ( service_table[SRV_STORE].conn < 0 ) { 
+                       freeaddrinfo(ai);
                        glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "socket()");
                        return 1; 
                }
-               a.sin_family = AF_INET;
-               a.sin_port = htons(atoi(port)+1);
-               a.sin_addr.s_addr = INADDR_ANY;
                setsockopt(service_table[SRV_STORE].conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-               if ( bind(service_table[SRV_STORE].conn, (struct sockaddr *) &a, sizeof(a)))
-               {
-                        glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%d)", atoi(port)+1);
+               if ( bind(service_table[SRV_STORE].conn, ai->ai_addr, ai->ai_addrlen) )
+               { 
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%s)", portstr);
+                       freeaddrinfo(ai);
                        return 1;
                }
+               freeaddrinfo(ai);
                if ( listen(service_table[SRV_STORE].conn, CON_QUEUE) ) { 
-                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "listen()"); 
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "listen()");
                        return 1; 
                }
+               free(portstr); portstr = NULL;
 
 #ifdef GLITE_LB_SERVER_WITH_WS
-               service_table[SRV_WS].conn = socket(PF_INET, SOCK_STREAM, 0);
-               if ( service_table[SRV_WS].conn < 0) { 
+               gaie = getaddrinfo (NULL, ws_port, &hints, &ai);
+               if (gaie != 0) {
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: %s", gai_strerror (gaie));
+                       return 1;
+               }
+               if (ai == NULL) {
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "getaddrinfo: no return");
+                       return 1;
+               }
+               service_table[SRV_WS].conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+               if ( service_table[SRV_WS].conn < 0 ) { 
                        glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "socket()");
+                       freeaddrinfo(ai);
                        return 1; 
                }
-               a.sin_family = AF_INET;
-               a.sin_port = htons(atoi(ws_port));
-               a.sin_addr.s_addr = INADDR_ANY;
                setsockopt(service_table[SRV_WS].conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-               if ( bind(service_table[SRV_WS].conn, (struct sockaddr *) &a, sizeof(a)))
-               {
-                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%d)", atoi(ws_port));
+               if ( bind(service_table[SRV_WS].conn, ai->ai_addr, ai->ai_addrlen) )
+               { 
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "bind(%s)",ws_port);
+                       freeaddrinfo(ai);
                        return 1;
                }
-               if ( listen(service_table[SRV_WS].conn, CON_QUEUE) ) { perror("listen()"); return 1; }
-
+               freeaddrinfo(ai);
+               if ( listen(service_table[SRV_WS].conn, CON_QUEUE) ) { 
+                       glite_common_log(LOG_CATEGORY_CONTROL, LOG_PRIORITY_FATAL, "listen()");
+                       return 1; 
+               }
 #endif /* GLITE_LB_SERVER_WITH_WS */
 
                if (!server_cert || !server_key)
@@ -978,10 +1017,12 @@ int bk_handle_connection(int conn, struct timeval *timeout, void *data)
        edg_wll_GssStatus       gss_code;
        struct timeval          dns_to = {DNS_TIMEOUT, 0},
                                                conn_start, now;
-       struct sockaddr_in      a;
+       struct sockaddr_storage a;
        socklen_t                                       alen;
-       char                       *server_name = NULL,
-                                          *name = NULL;
+       char                    *server_name = NULL,
+                               *port =NULL,
+                               *name_num = NULL,
+                               *name = NULL;
        int                                     h_errno, ret;
 
 
@@ -1047,10 +1088,6 @@ int bk_handle_connection(int conn, struct timeval *timeout, void *data)
        
        edg_wll_initConnections();
 
-       alen = sizeof(a);
-       getpeername(conn, (struct sockaddr *)&a, &alen);
-       ctx->connections->serverConnection->peerName = strdup(inet_ntoa(a.sin_addr));
-       ctx->connections->serverConnection->peerPort = ntohs(a.sin_port);
        ctx->count_statistics = count_statistics;
 
        ctx->serverIdentity = strdup(server_subject);
@@ -1059,25 +1096,31 @@ int bk_handle_connection(int conn, struct timeval *timeout, void *data)
 
        gettimeofday(&conn_start, 0);
 
-       h_errno = asyn_gethostbyaddr(&name, (char *)&a.sin_addr.s_addr,sizeof(a.sin_addr.s_addr), AF_INET, &dns_to);
+       alen = sizeof(a);
+       getpeername(conn, (struct sockaddr *)&a, &alen);
+       h_errno = asyn_gethostbyaddr(&name_num, &port, (struct sockaddr *)&a, alen, &dns_to, 1);
+       ctx->connections->serverConnection->peerPort = atoi(port);
+       h_errno = asyn_gethostbyaddr(&name, NULL, (struct sockaddr *)&a, alen, &dns_to, 0);
        switch ( h_errno )
        {
        case NETDB_SUCCESS:
                if (name) 
-                       glite_common_log(LOG_CATEGORY_LB_SERVER_REQUEST, LOG_PRIORITY_INFO, "[%d] connection from %s:%d (%s)", getpid(), inet_ntoa(a.sin_addr), ntohs(a.sin_port), name); 
+                       glite_common_log(LOG_CATEGORY_LB_SERVER_REQUEST, LOG_PRIORITY_INFO, "[%d] connection from %s:%s (%s)", getpid(), name_num, port, name); 
                free(ctx->connections->serverConnection->peerName);
                ctx->connections->serverConnection->peerName = name;
                name = NULL;
                break;
 
        default:
-               glite_common_log(LOG_CATEGORY_LB_SERVER_REQUEST, LOG_PRIORITY_DEBUG, "gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
-               glite_common_log(LOG_CATEGORY_LB_SERVER_REQUEST, LOG_PRIORITY_INFO,"[%d] connection from %s:%d", getpid(), inet_ntoa(a.sin_addr), ntohs(a.sin_port));
+               glite_common_log(LOG_CATEGORY_LB_SERVER_REQUEST, LOG_PRIORITY_DEBUG, "gethostbyaddr(%s): %s", name_num, hstrerror(h_errno));
+               glite_common_log(LOG_CATEGORY_LB_SERVER_REQUEST, LOG_PRIORITY_INFO,"[%d] connection from %s:%s", getpid(), name_num, port);
                free(ctx->connections->serverConnection->peerName);
-               ctx->connections->serverConnection->peerName = strdup(inet_ntoa(a.sin_addr));
+               ctx->connections->serverConnection->peerName = strdup(name_num);
                break;
        }
        
+       free(port);
+
        gettimeofday(&now, 0);
        if ( decrement_timeout(timeout, conn_start, now) )
        {
@@ -1099,9 +1142,9 @@ int bk_handle_connection(int conn, struct timeval *timeout, void *data)
        
                dns_to.tv_sec = DNS_TIMEOUT;
                dns_to.tv_usec = 0;
-               h_errno = asyn_gethostbyaddr(&name,
-                                               (char *) &a.sin_addr.s_addr,sizeof(a.sin_addr.s_addr),
-                                               AF_INET,&dns_to);
+               h_errno = asyn_gethostbyaddr(&name, &port,
+                                               (struct sockaddr *) &a, alen,
+                                               &dns_to, 0);
 
                switch ( h_errno )
                {
@@ -1118,12 +1161,13 @@ int bk_handle_connection(int conn, struct timeval *timeout, void *data)
                        break;
 
                default:
-                               glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_ERROR, "gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
+                               glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_ERROR, "gethostbyaddr(%s): %s", name_num, hstrerror(h_errno));
                        if ( server_name != NULL )
                                ctx->srvName = strdup(server_name);
                        break;
                }
-               ctx->srvPort = ntohs(a.sin_port);
+               ctx->srvPort = atoi(port);
+               free(port); port = NULL;
        }
 
 /* XXX: ugly workaround, we may detect false expired certificated
@@ -1712,24 +1756,22 @@ static void free_hostent(struct hostent *h){
 }
 
 struct asyn_result {
-       struct hostent *ent;
+       char            *host;
+       char            *service;
        int             err;
 };
 
-/* ares callback handler for ares_gethostbyaddr()       */
-#if ARES_VERSION >= 0x010500
-static void callback_handler(void *arg, int status, int timeouts, struct hostent *h)
-#else
-static void callback_handler(void *arg, int status, struct hostent *h)
-#endif
+/* ares callback handler for ares_getnameinfo() */
+void callback_handler(void *arg, int status, char *node, char *service)
 {
        struct asyn_result *arp = (struct asyn_result *) arg;
 
        switch (status) {
           case ARES_SUCCESS:
-               if (h && h->h_name) {
-                       arp->ent->h_name = strdup(h->h_name);           
-                       if (arp->ent->h_name == NULL) {
+               if (node||service) {
+                       if (node) arp->host = strdup(node);             
+                       if (service) arp->service = strdup(service);            
+                       if (arp->host == NULL && arp->service == NULL) {
                                arp->err = NETDB_INTERNAL;
                        } else {
                                arp->err = NETDB_SUCCESS;
@@ -1753,7 +1795,7 @@ static void callback_handler(void *arg, int status, struct hostent *h)
        }
 }
 
-static int asyn_gethostbyaddr(char **name, const char *addr,int len, int type, struct timeval *timeout)
+static int asyn_gethostbyaddr(char **name, char **service, const struct sockaddr *addr, int len, struct timeval *timeout, int numeric)
 {
        struct asyn_result ar;
        ares_channel channel;
@@ -1761,18 +1803,19 @@ static int asyn_gethostbyaddr(char **name, const char *addr,int len, int type, s
        fd_set readers, writers;
        struct timeval tv, *tvp;
        struct timeval start_time,check_time;
-
+       int     flags = 0;
 
 /* start timer */
         gettimeofday(&start_time,0);
 
 /* ares init */
         if ( ares_init(&channel) != ARES_SUCCESS ) return(NETDB_INTERNAL);
-       ar.ent = (struct hostent *) malloc (sizeof(*ar.ent));
-       memset((void *) ar.ent, 0, sizeof(*ar.ent));
+       memset((void *) &ar, 0, sizeof(ar));
 
 /* query DNS server asynchronously */
-       ares_gethostbyaddr(channel, addr, len, type, callback_handler, (void *) &ar);
+       if (name) flags |= ARES_NI_LOOKUPHOST | ( numeric? ARES_NI_NUMERICHOST : 0);
+       if (service) flags |= ARES_NI_LOOKUPSERVICE | ( numeric? ARES_NI_NUMERICSERV : 0);
+       ares_getnameinfo(channel, addr, len, flags, (ares_nameinfo_callback)callback_handler, (void *) &ar);
 
 /* wait for result */
         while (1) {
@@ -1785,7 +1828,6 @@ static int asyn_gethostbyaddr(char **name, const char *addr,int len, int type, s
                 gettimeofday(&check_time,0);
                if (decrement_timeout(timeout, start_time, check_time)) {
                        ares_destroy(channel);
-                       free_hostent(ar.ent);
                        return(TRY_AGAIN);
                }
                start_time = check_time;
@@ -1795,7 +1837,6 @@ static int asyn_gethostbyaddr(char **name, const char *addr,int len, int type, s
                 switch ( select(nfds, &readers, &writers, NULL, tvp) ) {
                        case -1: if (errno != EINTR) {
                                        ares_destroy(channel);
-                                       free_hostent(ar.ent);
                                        return NETDB_INTERNAL;
                                 } else
                                        continue;
@@ -1812,8 +1853,8 @@ static int asyn_gethostbyaddr(char **name, const char *addr,int len, int type, s
        ares_destroy(channel);
                
        if (ar.err == NETDB_SUCCESS) {
-               *name = strdup(ar.ent->h_name); 
-               free_hostent(ar.ent); 
+               if (name) *name = ar.host;
+               if (service) *service = ar.service;
        }
        return (ar.err);
 }
index 92b7ef3..e73f97d 100644 (file)
@@ -332,10 +332,10 @@ int glite_srvbones_daemonize(const char *servername, const char *custom_pidfile,
 
 static int dispatchit(int sock_slave, int sock, int sidx)
 {
-       struct sockaddr_in      a;
-       unsigned char      *pom;
-       int                                     conn,
-                                               alen, ret;
+       struct sockaddr_storage a;
+       char                    peerhost[64], peerserv[16];
+       int                     conn, ret;
+       socklen_t               alen;
 
 
        alen = sizeof(a);
@@ -361,20 +361,25 @@ static int dispatchit(int sock_slave, int sock, int sidx)
        }
 
        getpeername(conn, (struct sockaddr *)&a, &alen);
-       pom = (char *) &a.sin_addr.s_addr;
-       if (a.sin_family  == PF_LOCAL) {
+       if (a.ss_family  == PF_LOCAL) {
                glite_common_log(set_log_category,
                         LOG_PRIORITY_DEBUG, 
                        "[master] %s connection from local socket", 
                        services[sidx].id ? services[sidx].id : "");
        }
        else {
+               ret = getnameinfo ((struct sockaddr *) &a, alen,
+                       peerhost, sizeof(peerhost), peerserv, sizeof(peerserv), NI_NUMERICHOST | NI_NUMERICSERV);
+               if (ret) {
+                       glite_common_log(set_log_category, LOG_PRIORITY_WARN, "getnameinfo: %s", gai_strerror (ret));
+                               strcpy(peerhost, "unknown"); strcpy(peerserv, "unknown");
+               }
+
                glite_common_log(set_log_category, 
                          LOG_PRIORITY_DEBUG,
-                       "[master] %s connection from %d.%d.%d.%d:%d",
+                       "[master] %s connection from %s:%s",
                         services[sidx].id ? services[sidx].id : "",
-                        (int)pom[0], (int)pom[1], (int)pom[2], (int)pom[3],
-                        ntohs(a.sin_port));
+                        peerhost, peerserv);
        }
 
        ret = 0;
index 60c8169..90ec6d3 100644 (file)
@@ -63,7 +63,7 @@ private:
 void GSSTest::replier() {
        edg_wll_GssConnection   conn;
        edg_wll_GssStatus       stat;
-       struct sockaddr_in      a;
+       struct sockaddr_storage a;
        socklen_t               alen = sizeof(a);
        int                     s, len;
        char                    buf[8*BUFSIZ];
@@ -87,11 +87,15 @@ void GSSTest::replier() {
 void GSSTest::setUp(void) {
        pid_t pid;
        edg_wll_GssStatus stat;
-       struct sockaddr_in      a;
+       struct sockaddr_storage a;
        socklen_t               alen = sizeof(a);
        char *                  cred_file = NULL;
        char *                  key_file = NULL;
        char *                  to = getenv("GSS_TEST_TIMEOUT");
+       struct addrinfo *ai;
+       struct addrinfo hints;
+       char            servname[16];
+
 
        timeout.tv_sec = to ? atoi(to) : 10 ;
        timeout.tv_usec = 0;
@@ -103,24 +107,28 @@ void GSSTest::setUp(void) {
        if (edg_wll_gss_acquire_cred_gsi(cred_file, key_file, &my_cred, &stat))
                CPPUNIT_ASSERT_MESSAGE("gss_acquire_cred", 0);
        
-        sock = socket(PF_INET,SOCK_STREAM,0);
-       CPPUNIT_ASSERT_MESSAGE("socket()", sock >= 0);
+       memset (&hints, '\0', sizeof (hints));
+       hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE | AI_ADDRCONFIG;
+       hints.ai_socktype = SOCK_STREAM;
 
-       memset(&a, 0, sizeof a);
-        a.sin_family = AF_INET;
-        a.sin_port = 0;
-        a.sin_addr.s_addr = INADDR_ANY;
+       ret = getaddrinfo (NULL, port, &hints, &ai);
+       CPPUNIT_ASSERT_MESSAGE("getaddrinfo()", ret == 0 && ai != NULL);
 
-        if (bind(sock,(struct sockaddr *) &a,sizeof(a))) {
-               CPPUNIT_ASSERT_MESSAGE("bind()", 0);
-        }
+       sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+       CPPUNIT_ASSERT_MESSAGE("socket()", sock >= 0);
 
-        if (listen(sock,1)) {
-               CPPUNIT_ASSERT_MESSAGE("listen()", 0);
-       }
+       ret = bind(sock, ai->ai_addr, ai->ai_addrlen);
+       CPPUNIT_ASSERT_MESSAGE("bind()", ret == 0);
+
+       ret = listen(sock, 1);
+       CPPUNIT_ASSERT_MESSAGE("listen()", ret == 0);
 
        getsockname(sock,(struct sockaddr *) &a,&alen);
-       port = ntohs(a.sin_port);
+       ret = getnameinfo ((struct sockaddr *) &a, alen,
+                NULL, 0, servname, sizeof(servname), NI_NUMERICSERV);
+        CPPUNIT_ASSERT_MESSAGE("getnameinfo()", ret == 0);
+
+       port = atoi(servname);
 
        if ( !(pid = fork()) ) replier();
        else close(sock);