[LTP] [PATCH v2 1/5] netstress: add basic support for DCCP & SCTP
Alexey Kodanev
alexey.kodanev@oracle.com
Thu Mar 23 17:12:33 CET 2017
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
---
v2: add SCTP protocol and use '-T' option instead of -U and -D
testcases/network/netstress/netstress.c | 123 ++++++++++++++++++++++++++-----
1 files changed, 103 insertions(+), 20 deletions(-)
diff --git a/testcases/network/netstress/netstress.c b/testcases/network/netstress/netstress.c
index 8184716..e0babdf 100644
--- a/testcases/network/netstress/netstress.c
+++ b/testcases/network/netstress/netstress.c
@@ -38,6 +38,19 @@
static const int max_msg_len = (1 << 16) - 1;
+#ifndef SOCK_DCCP
+#define SOCK_DCCP 6
+#endif
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33
+#endif
+#ifndef SOL_DCCP
+#define SOL_DCCP 269
+#endif
+#ifndef DCCP_SOCKOPT_SERVICE
+#define DCCP_SOCKOPT_SERVICE 2
+#endif
+
/* TCP server requiers */
#ifndef TCP_FASTOPEN
#define TCP_FASTOPEN 23
@@ -92,7 +105,21 @@ static int clients_num;
static char *tcp_port = "61000";
static char *server_addr = "localhost";
static int busy_poll = -1;
-static char *use_udp;
+
+enum {
+ TYPE_TCP = 0,
+ TYPE_UDP,
+ TYPE_DCCP,
+ TYPE_SCTP
+};
+static uint proto_type;
+static char *type;
+static int sock_type = SOCK_STREAM;
+static int protocol;
+static int family = AF_INET6;
+
+static uint32_t service_code = 0xffff;
+
/* server socket */
static int sfd;
@@ -129,6 +156,11 @@ static void init_socket_opts(int sd)
SAFE_SETSOCKOPT(sd, SOL_SOCKET, SO_BUSY_POLL,
&busy_poll, sizeof(busy_poll));
}
+
+ if (proto_type == TYPE_DCCP) {
+ SAFE_SETSOCKOPT(sd, SOL_DCCP, DCCP_SOCKOPT_SERVICE,
+ &service_code, sizeof(uint32_t));
+ }
}
static void do_cleanup(void)
@@ -226,8 +258,7 @@ static int client_recv(int *fd, char *buf)
static int client_connect_send(const char *msg, int size)
{
- int cfd = SAFE_SOCKET(remote_addrinfo->ai_family,
- remote_addrinfo->ai_socktype, 0);
+ int cfd = SAFE_SOCKET(family, sock_type, protocol);
init_socket_opts(cfd);
@@ -264,7 +295,7 @@ void *client_fn(LTP_ATTRIBUTE_UNUSED void *arg)
}
for (i = 1; i < client_max_requests; ++i) {
- if (use_udp)
+ if (proto_type == TYPE_UDP)
goto send;
if (cfd == -1) {
@@ -355,7 +386,7 @@ static void client_init(void)
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = (use_udp) ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_socktype = sock_type;
hints.ai_flags = 0;
hints.ai_protocol = 0;
@@ -368,6 +399,8 @@ static void client_init(void)
tst_res(TINFO, "Running the test over IPv%s",
(remote_addrinfo->ai_family == AF_INET6) ? "6" : "4");
+ family = remote_addrinfo->ai_family;
+
clock_gettime(CLOCK_MONOTONIC_RAW, &tv_client_start);
int i;
for (i = 0; i < clients_num; ++i)
@@ -482,13 +515,23 @@ void *server_fn(void *cfd)
* It will tell client that server is going
* to close this connection.
*/
- if (!use_udp && ++num_requests >= server_max_requests)
+ if (sock_type == SOCK_STREAM &&
+ ++num_requests >= server_max_requests)
send_msg[0] = start_fin_byte;
- SAFE_SENDTO(1, client_fd, send_msg, send_msg_size, MSG_NOSIGNAL,
- (struct sockaddr *)&remote_addr, remote_addr_len);
+ switch (proto_type) {
+ case TYPE_SCTP:
+ SAFE_SEND(1, client_fd, send_msg, send_msg_size,
+ MSG_NOSIGNAL);
+ break;
+ default:
+ SAFE_SENDTO(1, client_fd, send_msg, send_msg_size,
+ MSG_NOSIGNAL, (struct sockaddr *)&remote_addr,
+ remote_addr_len);
+ }
- if (!use_udp && num_requests >= server_max_requests) {
+ if (sock_type == SOCK_STREAM &&
+ num_requests >= server_max_requests) {
/* max reqs, close socket */
shutdown(client_fd, SHUT_WR);
break;
@@ -514,9 +557,10 @@ static pthread_t server_thread_add(intptr_t client_fd)
static void server_init(void)
{
struct addrinfo hints;
+
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
- hints.ai_socktype = (use_udp) ? SOCK_DGRAM : SOCK_STREAM;
+ hints.ai_socktype = sock_type;
hints.ai_flags = AI_PASSIVE;
int err = getaddrinfo(NULL, tcp_port, &hints, &local_addrinfo);
@@ -528,7 +572,7 @@ static void server_init(void)
tst_brk(TBROK, "failed to get the address");
/* IPv6 socket is also able to access IPv4 protocol stack */
- sfd = SAFE_SOCKET(AF_INET6, local_addrinfo->ai_socktype, 0);
+ sfd = SAFE_SOCKET(family, sock_type, protocol);
const int flag = 1;
SAFE_SETSOCKOPT(sfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
@@ -537,7 +581,7 @@ static void server_init(void)
freeaddrinfo(local_addrinfo);
- if (use_udp)
+ if (proto_type == TYPE_UDP)
return;
init_socket_opts(sfd);
@@ -656,6 +700,18 @@ static void check_tw_reuse(void)
tst_res(TINFO, "set '%s' to '1'", tcp_tw_reuse);
}
+static void set_protocol_type(void)
+{
+ if (!type || !strcmp(type, "tcp"))
+ proto_type = TYPE_TCP;
+ else if (!strcmp(type, "udp"))
+ proto_type = TYPE_UDP;
+ else if (!strcmp(type, "dccp"))
+ proto_type = TYPE_DCCP;
+ else if (!strcmp(type, "sctp"))
+ proto_type = TYPE_SCTP;
+}
+
static void setup(void)
{
if (tst_parse_int(aarg, &clients_num, 1, INT_MAX))
@@ -687,6 +743,8 @@ static void setup(void)
if (busy_poll >= 0 && tst_kvercmp(3, 11, 0) < 0)
tst_brk(TCONF, "Test must be run with kernel 3.11 or newer");
+ set_protocol_type();
+
if (client_mode) {
tst_res(TINFO, "connection: addr '%s', port '%s'",
server_addr, tcp_port);
@@ -703,21 +761,46 @@ static void setup(void)
tst_res(TINFO, "max requests '%d'",
server_max_requests);
net.init = server_init;
- net.run = (use_udp) ? server_run_udp : server_run;
- net.cleanup = (use_udp) ? NULL : server_cleanup;
+ switch (proto_type) {
+ case TYPE_TCP:
+ case TYPE_DCCP:
+ case TYPE_SCTP:
+ net.run = server_run;
+ net.cleanup = server_cleanup;
+ break;
+ case TYPE_UDP:
+ net.run = server_run_udp;
+ net.cleanup = NULL;
+ break;
+ }
}
remote_addr_len = sizeof(struct sockaddr_storage);
- if (use_udp) {
- tst_res(TINFO, "using UDP");
- fastopen_api = NULL;
- } else {
+ switch (proto_type) {
+ case TYPE_TCP:
tst_res(TINFO, "TCP %s is using %s TCP API.",
(client_mode) ? "client" : "server",
(fastopen_api) ? "Fastopen" : "old");
-
check_tfo_value();
+ break;
+ case TYPE_UDP:
+ tst_res(TINFO, "using UDP");
+ fastopen_api = NULL;
+ sock_type = SOCK_DGRAM;
+ break;
+ case TYPE_DCCP:
+ tst_res(TINFO, "DCCP %s", (client_mode) ? "client" : "server");
+ fastopen_api = NULL;
+ sock_type = SOCK_DCCP;
+ protocol = IPPROTO_DCCP;
+ service_code = htonl(service_code);
+ break;
+ case TYPE_SCTP:
+ tst_res(TINFO, "SCTP %s", (client_mode) ? "client" : "server");
+ fastopen_api = NULL;
+ protocol = IPPROTO_SCTP;
+ break;
}
net.init();
@@ -735,7 +818,7 @@ static struct tst_option options[] = {
{"g:", &tcp_port, "-g x x - server port"},
{"b:", &barg, "-b x x - low latency busy poll timeout"},
- {"U", &use_udp, "-U Use UDP\n"},
+ {"T:", &type, "-T x tcp (default), udp, dccp, sctp\n"},
{"H:", &server_addr, "Client:\n-H x Server name or IP address"},
{"l", &client_mode, "-l Become client, default is server"},
--
1.7.1
More information about the ltp
mailing list