MPTFO tests: these are examples of initiator (sendto) and listener,
probably are going to be integrated to the mptcp_connect.* selftests
Signed-off-by: Dmytro Shytyi <dmytro@shytyi.net>
---
tools/testing/selftests/net/mptcp/mptfo.sh | 13 +++
.../selftests/net/mptcp/mptfo_initiator.c | 41 ++++++++
.../selftests/net/mptcp/mptfo_listener.c | 98 +++++++++++++++++++
3 files changed, 152 insertions(+)
create mode 100644 tools/testing/selftests/net/mptcp/mptfo.sh
create mode 100644 tools/testing/selftests/net/mptcp/mptfo_initiator.c
create mode 100644 tools/testing/selftests/net/mptcp/mptfo_listener.c
diff --git a/tools/testing/selftests/net/mptcp/mptfo.sh b/tools/testing/selftests/net/mptcp/mptfo.sh
new file mode 100644
index 000000000000..9ed0cb281094
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptfo.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+#This is an example of environmen that was used to generate wireshark
+sudo ip netns add server
+sudo ip netns add client
+sudo ip link add veth0 type veth peer name veth1
+sudo ip link set veth1 netns server
+sudo ip link set veth0 netns client
+sudo ip netns exec client ip a a 10.10.0.1/24 dev veth0
+sudo ip netns exec server ip a a 10.10.0.2/24 dev veth1
+sudo ip netns exec client ip link set dev veth0 up
+sudo ip netns exec server ip link set dev veth1 up
+sudo ip netns exec server bash -c "echo 2 > /proc/sys/net/ipv4/tcp_fastopen"
+sudo ip netns exec client bash -c "echo 1 > /proc/sys/net/ipv4/tcp_fastopen"
diff --git a/tools/testing/selftests/net/mptcp/mptfo_initiator.c b/tools/testing/selftests/net/mptcp/mptfo_initiator.c
new file mode 100644
index 000000000000..e23b88693fb0
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptfo_initiator.c
@@ -0,0 +1,41 @@
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <netinet/tcp.h>
+#include <string.h>
+#include <signal.h>
+
+#define SERVER_PORT 7003
+
+int main(int argc, char *argv[])
+{
+ unsigned char valsyn[3] = "abc";
+ struct sockaddr_in daddr;
+ char *valend = "fff";
+ char *val1 = "zz1";
+ char *val2 = "zz2";
+ char *val3 = "zz3";
+ int sock_fd = -1;
+ int ret;
+
+ memset(&daddr, 0, sizeof(daddr));
+ inet_pton(AF_INET, "10.10.0.2", &daddr.sin_addr);
+ daddr.sin_family = AF_INET;
+ daddr.sin_port = htons(SERVER_PORT);
+
+ sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
+
+ ret = sendto(sock_fd, valsyn, 3, MSG_FASTOPEN, (struct sockaddr *) &daddr, sizeof(daddr));
+ ret = write(sock_fd, val1, 3);
+ ret = write(sock_fd, val2, 3);
+ ret = write(sock_fd, val2, 3);
+ ret = write(sock_fd, val2, 3);
+ ret = write(sock_fd, val3, 3);
+ ret = write(sock_fd, valend, 3);
+
+ close(sock_fd);
+ return EXIT_SUCCESS;
+}
diff --git a/tools/testing/selftests/net/mptcp/mptfo_listener.c b/tools/testing/selftests/net/mptcp/mptfo_listener.c
new file mode 100644
index 000000000000..7e3de8d1d08c
--- /dev/null
+++ b/tools/testing/selftests/net/mptcp/mptfo_listener.c
@@ -0,0 +1,98 @@
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <linux/in.h>
+#include <netinet/tcp.h>
+
+#define CLIENT_QUEUE_LEN 10
+#define SERVER_PORT 7003
+
+int main(void)
+{
+ int listen_sock_fd = -1, client_sock_fd = -1;
+ char str_addr[INET6_ADDRSTRLEN];
+ struct sockaddr_in server_addr;
+ int ret, flag;
+ int qlen = 5;
+ char ch;
+
+ server_addr.sin_family = AF_INET;
+ inet_pton(AF_INET, "10.10.0.2", &server_addr.sin_addr);
+ server_addr.sin_port = htons(SERVER_PORT);
+
+ /* Create socket for listening (client requests) */
+ listen_sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP);
+ if (listen_sock_fd == -1) {
+ perror("socket()server");
+ return EXIT_FAILURE;
+ }
+
+ /* Set socket to reuse address */
+ flag = 1;
+ ret = setsockopt(listen_sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
+ if (ret == -1) {
+ perror("setsockopt()");
+ return EXIT_FAILURE;
+ }
+
+ ret = setsockopt(listen_sock_fd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
+ if (ret == -1) {
+ perror("setsockopt()TCP_FASTOPEN");
+ return EXIT_FAILURE;
+ }
+
+ /* Bind address and socket together */
+ ret = bind(listen_sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
+ if (ret == -1) {
+ perror("bind()");
+ close(listen_sock_fd);
+ return EXIT_FAILURE;
+ }
+
+ /* Create listening queue (client requests) */
+ ret = listen(listen_sock_fd, CLIENT_QUEUE_LEN);
+ if (ret == -1) {
+ perror("listen()");
+ close(listen_sock_fd);
+ return EXIT_FAILURE;
+ }
+ perror("Server listening");
+ while (1) {
+ /* Do TCP handshake with client */
+ client_sock_fd = accept(listen_sock_fd,
+ NULL,
+ 0);
+ if (client_sock_fd == -1) {
+ perror("accept()");
+ close(listen_sock_fd);
+ return EXIT_FAILURE;
+ } else {
+ perror("ACCEPT_SUCCESS");
+ }
+
+ char rb[1024];
+
+ while (1) {
+ ret = read(client_sock_fd, rb, 3);
+
+ if (ret == -1) {
+ perror("SERVVERread()");
+ close(client_sock_fd);
+ break;
+ } else {
+ fprintf(stderr, "received %c%c%c from client", rb[0], rb[1], rb[2]);
+ }
+ if (rb[0] == 'f' && rb[1] == 'f' && rb[2] == 'f') {
+ close(client_sock_fd);
+ break;
+ }
+
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
--
2.25.1