From: Geliang Tang <tanggeliang@kylinos.cn>
Introduces large data transfer tests (1-17 MB) to validate MPTCP socket
options under high-volume conditions, including proper EOF handling,
preparing for TCP_INQ support in subsequent patches.
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
.../selftests/net/mptcp/mptcp_sockopt.c | 90 ++++++++++++++++++-
1 file changed, 88 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
index 675ed2dcee9f..fc65157a41ee 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c
@@ -620,10 +620,12 @@ static void connect_one_server(int fd, int unixfd)
/* un-block server */
ret = read(unixfd, buf2, 4);
assert(ret == 4);
- close(unixfd);
assert(strncmp(buf2, "xmit", 4) == 0);
+ ret = write(unixfd, &len, sizeof(len));
+ assert(ret == (ssize_t)sizeof(len));
+
ret = write(fd, buf, len);
if (ret < 0)
die_perror("write");
@@ -659,14 +661,51 @@ static void connect_one_server(int fd, int unixfd)
total += 1; /* sequence advances due to FIN */
assert(s.mptcpi_rcv_delta ? s.mptcpi_rcv_delta == (uint64_t)total : true);
+
+ ret = read(unixfd, buf2, 4);
+ assert(strncmp(buf2, "huge", 4) == 0);
+
+ total = rand() % (16 * 1024 * 1024);
+ total += (1 * 1024 * 1024);
+
+ ret = write(unixfd, &total, sizeof(total));
+ assert(ret == (ssize_t)sizeof(total));
+
+ while (total > 0) {
+ if (total > sizeof(buf))
+ len = sizeof(buf);
+ else
+ len = total;
+
+ ret = write(fd, buf, len);
+ if (ret < 0)
+ die_perror("write");
+ total -= ret;
+
+ /* we don't have to care about buf content, only
+ * number of total bytes sent
+ */
+ }
+
+ ret = read(unixfd, buf2, 4);
+ assert(ret == 4);
+ assert(strncmp(buf2, "shut", 4) == 0);
+
+ ret = write(fd, buf, 1);
+ assert(ret == 1);
close(fd);
+ ret = write(unixfd, "closed", 6);
+ assert(ret == 6);
+
+ close(unixfd);
}
static void process_one_client(int fd, int unixfd)
{
- ssize_t ret, ret2, ret3;
+ ssize_t ret, ret2, ret3, tot;
char msg_buf[4096];
struct so_state s;
+ size_t expect_len;
char buf[4096];
struct iovec iov = {
.iov_base = buf,
@@ -678,6 +717,7 @@ static void process_one_client(int fd, int unixfd)
.msg_control = msg_buf,
.msg_controllen = sizeof(msg_buf),
};
+ char tmp[16];
memset(&s, 0, sizeof(s));
do_getsockopts(&s, fd, 0, 0);
@@ -685,6 +725,12 @@ static void process_one_client(int fd, int unixfd)
ret = write(unixfd, "xmit", 4);
assert(ret == 4);
+ ret = read(unixfd, &expect_len, sizeof(expect_len));
+ assert(ret == (ssize_t)sizeof(expect_len));
+
+ if (expect_len > sizeof(buf))
+ xerror("expect len %zu exceeds buffer size", expect_len);
+
/* read one byte, expect cmsg to return expected - 1 */
ret = recvmsg(fd, &msg, 0);
if (ret < 0)
@@ -703,6 +749,9 @@ static void process_one_client(int fd, int unixfd)
if (s.tcpi_rcv_delta)
assert(s.tcpi_rcv_delta == (uint64_t)ret);
+ /* should have gotten exact remainder of all pending data */
+ assert(ret == (ssize_t)expect_len - 1);
+
ret2 = write(fd, buf, ret);
if (ret2 < 0)
die_perror("write");
@@ -727,6 +776,43 @@ static void process_one_client(int fd, int unixfd)
s.last_sample.mptcpi_bytes_acked - ret2);
}
+ /* request a large swath of data. */
+ ret = write(unixfd, "huge", 4);
+ assert(ret == 4);
+
+ ret = read(unixfd, &expect_len, sizeof(expect_len));
+ assert(ret == (ssize_t)sizeof(expect_len));
+
+ /* peer should send us a few mb of data */
+ if (expect_len <= sizeof(buf))
+ xerror("expect len %zu too small\n", expect_len);
+
+ tot = 0;
+ do {
+ iov.iov_len = sizeof(buf);
+ ret = recvmsg(fd, &msg, 0);
+ if (ret < 0)
+ die_perror("recvmsg");
+
+ tot += ret;
+ } while ((size_t)tot < expect_len);
+
+ ret = write(unixfd, "shut", 4);
+ assert(ret == 4);
+
+ /* wait for hangup. Should have received one more byte of data. */
+ ret = read(unixfd, tmp, sizeof(tmp));
+ assert(ret == 6);
+ assert(strncmp(tmp, "closed", 6) == 0);
+
+ sleep(1);
+
+ iov.iov_len = 1;
+ ret = recvmsg(fd, &msg, 0);
+ if (ret < 0)
+ die_perror("recvmsg");
+ assert(ret == 1);
+
/* wait for hangup */
iov.iov_len = 1;
ret3 = recvmsg(fd, &msg, 0);
--
2.48.1