Skip to content

Commit c706363

Browse files
AnandBibhutihestela
authored andcommitted
Support for IPv6 address format in qperf tests (#13)
* Code changes to include support for IPv6 address * Revert "Code changes to include support for IPv6 address" This reverts commit b4182bc. * qperf should accept both IPv4 and IPv6 addresses for test execution. These code changes are done to include support for IPv6 address. Reviewed-by: Ka-Cheong Poon <[email protected]>
1 parent 414e261 commit c706363

File tree

3 files changed

+59
-23
lines changed

3 files changed

+59
-23
lines changed

src/qperf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
*/
6363
#define VER_MAJ 0 /* Major version */
6464
#define VER_MIN 4 /* Minor version */
65-
#define VER_INC 10 /* Incremental version */
65+
#define VER_INC 11 /* Incremental version */
6666
#define LISTENQ 5 /* Size of listen queue */
6767
#define BUFSIZE 1024 /* Size of buffers */
6868

@@ -1418,7 +1418,7 @@ server_listen(void)
14181418
AI *ai;
14191419
AI hints ={
14201420
.ai_flags = AI_PASSIVE | AI_NUMERICSERV,
1421-
.ai_family = AF_UNSPEC,
1421+
.ai_family = AF_INET6,
14221422
.ai_socktype = SOCK_STREAM
14231423
};
14241424
AI *ailist = getaddrinfo_port(0, ListenPort, &hints);
@@ -1450,7 +1450,7 @@ static int
14501450
server_recv_request(void)
14511451
{
14521452
socklen_t clientLen;
1453-
struct sockaddr_in clientAddr;
1453+
SS clientAddr;
14541454

14551455
clientLen = sizeof(clientAddr);
14561456
RemoteFD = accept(ListenFD, (struct sockaddr *)&clientAddr, &clientLen);

src/rds.c

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@
4343
#include <unistd.h>
4444
#include <arpa/inet.h>
4545
#include <netinet/in.h>
46+
#include <stdbool.h>
4647
#include "qperf.h"
4748

48-
4949
/*
5050
* Parameters.
5151
*/
@@ -107,7 +107,7 @@ static void rds_makeaddr(SS *addr, socklen_t *len, char *host, int port);
107107
static void set_parameters(long msgSize);
108108
static void server_get_hosts(char *lhost, char *rhost);
109109
static void set_socket_buffer_size(int fd);
110-
110+
static inline bool ipv6_addr_v4mapped(const struct in6_addr *a);
111111

112112
/*
113113
* Static variables.
@@ -314,6 +314,15 @@ init(void)
314314
}
315315

316316

317+
/*
318+
* Check if it is IPv4-mapped IPv6 address
319+
*/
320+
static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
321+
{
322+
return (a->s6_addr32[0] | a->s6_addr32[1] |
323+
(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0;
324+
}
325+
317326
/*
318327
* Have an exchange with the client over TCP/IP and get the IP of our local
319328
* host.
@@ -323,34 +332,42 @@ server_get_hosts(char *lhost, char *rhost)
323332
{
324333
int fd, lfd;
325334
uint32_t port;
326-
struct sockaddr_in laddr, raddr;
327335
socklen_t rlen;
336+
struct sockaddr_in6 v6addr;
337+
struct sockaddr_in v4addr;
338+
SA *raddr;
328339

329-
lfd = socket(AF_INET, SOCK_STREAM, 0);
340+
lfd = socket(AF_INET6, SOCK_STREAM, 0);
330341
if (lfd < 0)
331342
error(SYS, "socket failed");
332343
setsockopt_one(lfd, SO_REUSEADDR);
333-
334-
memset(&laddr, 0, sizeof(laddr));
335-
laddr.sin_family = AF_INET;
336-
laddr.sin_addr.s_addr = INADDR_ANY;
337-
laddr.sin_port = htons(0);
338-
if (bind(lfd, (SA *)&laddr, sizeof(laddr)) < 0)
339-
error(SYS, "bind INET failed");
344+
memset(&v6addr, 0, sizeof(v6addr));
345+
v6addr.sin6_family = AF_INET6;
346+
if (bind(lfd, (SA *)&v6addr, sizeof(v6addr)) < 0)
347+
error(SYS, "bind INET6 failed");
340348

341349
port = get_socket_port(lfd);
342350
encode_uint32(&port, port);
343-
send_mesg(&port, sizeof(port), "TCP IPv4 server port");
344-
351+
send_mesg(&port, sizeof(port), "TCP server port");
345352
if (listen(lfd, 1) < 0)
346353
error(SYS, "listen failed");
347354

348-
rlen = sizeof(raddr);
349-
fd = accept(lfd, (SA *)&raddr, &rlen);
355+
rlen = sizeof(v6addr);
356+
fd = accept(lfd, (SA *)&v6addr, &rlen);
350357
if (fd < 0)
351358
error(SYS, "accept failed");
352359
close(lfd);
353-
get_socket_ip((SA *)&raddr, rlen, rhost, NI_MAXHOST);
360+
361+
if (ipv6_addr_v4mapped(&v6addr.sin6_addr)) {
362+
v4addr.sin_family = AF_INET;
363+
v4addr.sin_addr.s_addr = v6addr.sin6_addr.s6_addr32[3];
364+
v4addr.sin_port = v6addr.sin6_port;
365+
raddr = (SA *)&v4addr;
366+
rlen = sizeof(v4addr);
367+
} else {
368+
raddr = (SA *)&v6addr;
369+
}
370+
get_socket_ip(raddr, rlen, rhost, NI_MAXHOST);
354371
send_mesg(rhost, NI_MAXHOST, "client IP");
355372
recv_mesg(lhost, NI_MAXHOST, "server IP");
356373
close(fd);
@@ -410,13 +427,30 @@ rds_socket(char *host, int port)
410427
static void
411428
rds_makeaddr(SS *addr, socklen_t *len, char *host, int port)
412429
{
430+
int stat;
431+
struct addrinfo *ailist;
413432
struct sockaddr_in *sap = (struct sockaddr_in *)addr;
433+
struct sockaddr_in6 *sap6 = (struct sockaddr_in6 *)addr;
414434

435+
stat = getaddrinfo(host, NULL, NULL, &ailist);
436+
if (stat != 0)
437+
error(0, "getaddrinfo failed: %s", gai_strerror(stat));
438+
switch (ailist->ai_family) {
439+
case AF_INET:
415440
memset(sap, 0, sizeof(*sap));
416-
sap->sin_family = AF_INET;
417-
inet_pton(AF_INET, host, &sap->sin_addr.s_addr);
441+
memcpy(addr, ailist->ai_addr, ailist->ai_addrlen);
418442
sap->sin_port = htons(port);
419443
*len = sizeof(struct sockaddr_in);
444+
break;
445+
case AF_INET6:
446+
memset(sap6, 0, sizeof(*sap6));
447+
memcpy(sap6, ailist->ai_addr, ailist->ai_addrlen);
448+
sap6->sin6_port = htons(port);
449+
*len = sizeof(struct sockaddr_in6);
450+
break;
451+
default:
452+
error(0, "Unsupported Address family");
453+
}
420454
}
421455

422456

@@ -431,7 +465,7 @@ connect_tcp(char *server, char *port, SS *addr, socklen_t *len, int *fd)
431465
struct addrinfo *aip, *ailist;
432466
struct addrinfo hints ={
433467
.ai_flags = AI_NUMERICSERV,
434-
.ai_family = AF_INET,
468+
.ai_family = AF_UNSPEC,
435469
.ai_socktype = SOCK_STREAM
436470
};
437471

src/socket.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,8 +699,10 @@ getaddrinfo_kind(int serverflag, KIND kind, int port)
699699
.ai_socktype = SOCK_STREAM
700700
};
701701

702-
if (serverflag)
702+
if (serverflag){
703703
hints.ai_flags |= AI_PASSIVE;
704+
hints.ai_family = AF_INET6;
705+
}
704706
if (kind == K_UDP)
705707
hints.ai_socktype = SOCK_DGRAM;
706708

0 commit comments

Comments
 (0)