]> git.openfabrics.org - ~ardavis/dapl.git/commitdiff
dtestcm: exchange provider IA address info via sockets
authorArlin Davis <arlin.r.davis@intel.com>
Tue, 12 Apr 2016 20:58:34 +0000 (13:58 -0700)
committerArlin Davis <arlin.r.davis@intel.com>
Tue, 12 Apr 2016 20:58:34 +0000 (13:58 -0700)
Signed-off-by: Arlin Davis <arlin.r.davis@intel.com>
test/dtest/dtestcm.c

index 77f8e55edeaf01a71bd615a23bc2b31666e4cf52..93ea48c5dd27b81b3b147294ed6539eaf2959c7b 100644 (file)
@@ -65,6 +65,7 @@
 #else // _WIN32 || _WIN64
 
 #include <endian.h>
+#include <errno.h>
 #include <byteswap.h>
 #include <netdb.h>
 #include <sys/types.h>
@@ -168,11 +169,15 @@ const char *DT_EventToSTr(DAT_EVENT_NUMBER event_code);
 static void print_usage(void);
 static double get_time(void);
 static DAT_RETURN conn_client(void);
-static DAT_RETURN conn_server(void);
+static DAT_RETURN conn_server(struct sockaddr *ser_sa);
 static DAT_RETURN disconnect_eps(void);
 static DAT_RETURN create_events(void);
 static DAT_RETURN destroy_events(void);
 
+#define CONN_PORT 15828
+#define CONN_MSG_SIZE 128
+#define CONN_MSG_FMT "%04hx:%08x:%08x:%08x:%s"
+
 #define LOGPRINTF if (verbose) printf
 
 static void flush_evds(void)
@@ -195,11 +200,11 @@ static void print_ia_address(struct sockaddr *sa)
        switch(sa->sa_family) {
        case AF_INET:
                inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, str, INET6_ADDRSTRLEN);
-               printf("%d Local Address AF_INET - %s port %d\n", getpid(), str, SERVER_CONN_QUAL);
+               printf("%d Local IA Address - %s port %d\n", getpid(), str, SERVER_CONN_QUAL);
                break;
        case AF_INET6:
                inet_ntop(AF_INET6, &((struct sockaddr_in6 *)sa)->sin6_addr, str, INET6_ADDRSTRLEN);
-               printf("%d Local Address AF_INET6 - %s flowinfo(QPN)=0x%x, port(LID)=0x%x\n",
+               printf("%d Local IA Address - %s flowinfo(QPN)=0x%x, port(LID)=0x%x\n",
                        getpid(), str,
                        ntohl(((struct sockaddr_in6 *)sa)->sin6_flowinfo),
                        ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
@@ -209,6 +214,204 @@ static void print_ia_address(struct sockaddr *sa)
        }
 }
 
+static int conn_client_connect(const char *servername, int port)
+{
+
+       struct addrinfo *res, *t;
+       struct addrinfo hints = {
+               .ai_family   = AF_UNSPEC,
+               .ai_socktype = SOCK_STREAM
+       };
+       char *service;
+       int n;
+       int sockfd = -1;
+
+       if (asprintf(&service, "%d", port) < 0)
+               return -1;
+
+       n = getaddrinfo(servername, service, &hints, &res);
+
+       if (n < 0) {
+               fprintf(stderr, "%s for %s:%d\n",
+                       gai_strerror(n), servername, port);
+               return n;
+       }
+
+       for (t = res; t; t = t->ai_next) {
+               sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
+               if (sockfd >= 0) {
+                       if (!connect(sockfd, t->ai_addr, t->ai_addrlen))
+                               break;
+                       close(sockfd);
+                       sockfd = -1;
+               }
+       }
+
+       freeaddrinfo(res);
+
+       if (sockfd < 0) {
+               fprintf(stderr, "Couldn't connect to %s:%d, err = %s\n",
+                       servername, port, strerror(errno));
+               return sockfd;
+       }
+       return sockfd;
+}
+
+static int conn_server_connect(int port)
+{
+       struct addrinfo *res, *t;
+       struct addrinfo hints = {
+               .ai_flags    = AI_PASSIVE,
+               .ai_family   = AF_UNSPEC,
+               .ai_socktype = SOCK_STREAM
+       };
+       char *service;
+       int sockfd = -1, connfd;
+       int n;
+
+       if (asprintf(&service, "%d", port) < 0)
+               return -1;
+
+       n = getaddrinfo(NULL, service, &hints, &res);
+
+       if (n < 0) {
+               fprintf(stderr, "%s for port %d\n", gai_strerror(n), port);
+               return n;
+       }
+
+       for (t = res; t; t = t->ai_next) {
+               sockfd = socket(t->ai_family, t->ai_socktype, t->ai_protocol);
+               if (sockfd >= 0) {
+                       n = 1;
+
+                       setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n,
+                                  sizeof n);
+
+                       if (!bind(sockfd, t->ai_addr, t->ai_addrlen))
+                               break;
+
+                       close(sockfd);
+                       sockfd = -1;
+               }
+       }
+
+       freeaddrinfo(res);
+
+       if (sockfd < 0) {
+               fprintf(stderr, "Couldn't listen to port %d\n", port);
+               return sockfd;
+       }
+
+       listen(sockfd, 1);
+       connfd = accept(sockfd, NULL, 0);
+       if (connfd < 0) {
+               perror("server accept");
+               fprintf(stderr, "accept() failed\n");
+               close(sockfd);
+               return connfd;
+       }
+
+       close(sockfd);
+       return connfd;
+}
+
+static int get_server_params(void)
+{
+       int connfd, parsed;
+       char msg[CONN_MSG_SIZE];
+       in_port_t ser_lid = 0;
+       uint32_t ser_qpn = 0, ser_scope_id = 0, ser_sin_addr = 0;
+       struct in_addr sin_addr;        /* Internet address.  */
+
+       connfd = conn_client_connect(hostname, CONN_PORT);
+       if (connfd < 0) {
+               fprintf(stderr, "%d Could not connect to %s\n",
+                       getpid(), hostname);
+               return -1;
+       }
+
+       if (read(connfd, msg, sizeof msg) != sizeof msg) {
+               fprintf(stderr, "%d Couldn't read remote address\n", getpid());
+               return -1;
+       }
+
+       parsed = sscanf(msg, CONN_MSG_FMT, &ser_lid, &ser_qpn, &ser_scope_id,
+                       &ser_sin_addr, provider);
+
+       if (parsed != 5) {
+               fprintf(stderr, "%d Couldn't parse line <%.*s>\n",
+                       getpid(), (int)sizeof msg, msg);
+               return -1;
+       }
+
+       if (ser_sin_addr) {
+               sin_addr.s_addr = ser_sin_addr;
+               inet_ntop(AF_INET, &sin_addr, hostname, INET6_ADDRSTRLEN);
+               LOGPRINTF("%d remote data: provider %s hostname %s port %d\n",
+                         getpid(), provider, hostname, CONN_PORT);
+       } else if (ser_lid && ser_qpn) {
+               remote.sin6_family = AF_INET6;
+               remote.sin6_port = ser_lid;
+               remote.sin6_flowinfo = ser_qpn;
+               remote.sin6_scope_id = ntohl(ser_scope_id);
+               ucm = 1;
+               LOGPRINTF("%d remote data: provider %s Client QPN 0x%x,"
+                         " LID = 0x%x, scope_id 0x%x\n",
+                         getpid(), provider, ntohl(ser_qpn), ntohs(ser_lid),
+                         ntohl(ser_scope_id));
+       } else {
+               fprintf(stderr, "%d No valid data was received"
+                       " from the server\n",
+                       getpid());
+               return -1;
+       }
+
+       return 0;
+}
+
+static int send_server_params(struct sockaddr *ser_sa)
+{
+       in_port_t ser_lid = 0;
+       uint32_t ser_qpn = 0, scope_id = 0, ser_sin_addr = 0;
+       int connfd;
+       char msg[CONN_MSG_SIZE];
+
+       if (!ser_sa) {
+               printf("%d no address\n", getpid());
+               return -1;
+       }
+
+       if  (ser_sa->sa_family == AF_INET6) {
+               ser_qpn = ((struct sockaddr_in6 *)ser_sa)->sin6_flowinfo;
+               ser_lid = ((struct sockaddr_in6 *)ser_sa)->sin6_port;
+               scope_id = htonl(((struct sockaddr_in6 *)ser_sa)->sin6_scope_id);
+               LOGPRINTF("%d Server data to client: provider %s QPN 0x%x LID"
+                         " = 0x%x SCCOPE_ID 0x%x\n",
+                         getpid(), provider, ntohl(ser_qpn), ntohs(ser_lid),
+                         ntohl(scope_id));
+       } else if (ser_sa->sa_family == AF_INET) {
+               ser_sin_addr = ((struct sockaddr_in *)ser_sa)->sin_addr.s_addr;
+               LOGPRINTF("%d Server data to client: provider %s SIN_ADDR"
+                         " 0x%x\n",
+                         getpid(), provider, ser_sin_addr);
+       }
+
+       connfd = conn_server_connect(CONN_PORT);
+       if (connfd < 0) {
+               fprintf(stderr, "%d Failed to connect to client\n", getpid());
+               return -1;
+       }
+
+       sprintf(msg, CONN_MSG_FMT, ser_lid, ser_qpn, scope_id,
+               ser_sin_addr, provider);
+       if (write(connfd, msg, sizeof msg) != sizeof msg) {
+               fprintf(stderr, "%d Couldn't send data", getpid());
+               return -1;
+       }
+
+       return 0;
+}
+
 int main(int argc, char **argv)
 {
        int i, c, len;
@@ -253,20 +456,6 @@ int main(int argc, char **argv)
                case 'P':
                        strcpy(provider, optarg);
                        break;
-               case 'q':
-                       /* map UCM qpn into AF_INET6 sin6_flowinfo */
-                       remote.sin6_family = AF_INET6;
-                       remote.sin6_flowinfo = htonl(strtol(optarg,NULL,0));
-                       ucm = 1;
-                       server = 0;
-                       break;
-               case 'l':
-                       /* map UCM lid into AF_INET6 sin6_port */
-                       remote.sin6_family = AF_INET6;
-                       remote.sin6_port = htons(strtol(optarg,NULL,0));
-                       ucm = 1;
-                       server = 0;
-                       break;
                default:
                        print_usage();
                        exit(-12);
@@ -290,6 +479,10 @@ int main(int argc, char **argv)
        if (!server) {
                printf(" Running client on %s with %d %s connections\n", 
                        provider, connections, ud_test ? "UD" : "RC");
+               if (get_server_params()) {
+                       printf("%d Failed to get server params\n", getpid());
+                       exit(1);
+               }
        } else {
                printf(" Running server on %s with %d %s connections\n", 
                        provider, connections, ud_test ? "UD" : "RC");
@@ -427,7 +620,7 @@ int main(int argc, char **argv)
        
        /* Connect all */
        if (server)
-               ret = conn_server();
+               ret = conn_server(ia_attr.ia_address_ptr);
        else    
                ret = conn_client();
        
@@ -555,7 +748,7 @@ static double get_time(void)
        return ((double)tp.tv_sec + (double)tp.tv_usec * 1e-6);
 }
 
-static DAT_RETURN conn_server()
+static DAT_RETURN conn_server(struct sockaddr *ser_sa)
 {
        DAT_RETURN ret;
        DAT_EVENT event;
@@ -566,6 +759,14 @@ static DAT_RETURN conn_server()
                &event.event_data.cr_arrival_event_data;
        DAT_CR_PARAM cr_param = { 0 };
        
+       printf("%d Conn server waiting for client, port %d \n",
+               getpid(), CONN_PORT);
+       fflush(stdout);
+       if (send_server_params(ser_sa)) {
+               printf("%d Failed to send server params\n", getpid());
+               return -1;
+       }
+
        printf(" Accepting...\n");
        for (i = 0; i < connections; i++) {