#else // _WIN32 || _WIN64
#include <endian.h>
+#include <errno.h>
#include <byteswap.h>
#include <netdb.h>
#include <sys/types.h>
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)
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));
}
}
+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;
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);
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");
/* Connect all */
if (server)
- ret = conn_server();
+ ret = conn_server(ia_attr.ia_address_ptr);
else
ret = conn_client();
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;
&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++) {