Skip to content

Commit

Permalink
zdtm: Add tests for C/R UDP socket's queues
Browse files Browse the repository at this point in the history
Signed-off-by: Bui Quang Minh <[email protected]>
  • Loading branch information
minhbq-99 committed Aug 11, 2021
1 parent d87b8ac commit 92258cf
Show file tree
Hide file tree
Showing 8 changed files with 378 additions and 77 deletions.
24 changes: 24 additions & 0 deletions criu/cr-check.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <termios.h>
#include <sys/mman.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <sys/prctl.h>
#include <sched.h>
#include <sys/mount.h>
Expand Down Expand Up @@ -1362,6 +1363,27 @@ static int check_ns_pid(void)
return 0;
}

static int check_udp_repair(void)
{
int sk, val;

sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sk < 0) {
pr_perror("Can't create UDP socket");
return -1;
}

val = 1;
if (setsockopt(sk, SOL_UDP, UDP_REPAIR, &val, sizeof(val))) {
pr_perror("Can't turn UDP_REPAIR on");
close(sk);
return -1;
}

close(sk);
return 0;
}

static int (*chk_feature)(void);

/*
Expand Down Expand Up @@ -1487,6 +1509,7 @@ int cr_check(void)
if (opts.check_experimental_features) {
ret |= check_autofs();
ret |= check_compat_cr();
ret |= check_udp_repair();
}

pr_msg("%s\n", ret ? CHECK_MAYBE : CHECK_GOOD);
Expand Down Expand Up @@ -1590,6 +1613,7 @@ static struct feature_list feature_list[] = {
{ "pidfd_store", check_pidfd_store },
{ "ns_pid", check_ns_pid },
{ "apparmor_stacking", check_apparmor_stacking },
{ "udp_repair", check_udp_repair },
{ NULL, NULL },
};

Expand Down
3 changes: 2 additions & 1 deletion test/zdtm/static/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ TST_NOFILE := \
socket_listen4v6 \
socket_udp \
socket_udp-broadcast \
socket_udp-corked \
socket_udp_repair \
socket6_udp \
socket6_udp_repair \
socket_udp_shutdown \
sk-freebind \
sk-freebind-false \
Expand Down
175 changes: 175 additions & 0 deletions test/zdtm/static/socket6_udp_repair.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netinet/udp.h>

#include "zdtmtst.h"

const char *test_doc = "Test for C/R UDP socket's queue\n";
const char *test_author = "Bui Quang Minh <[email protected]>\n";

/* Description:
* Checkpoint/restore a corked UDP socket with 2 packets in send queue
* and 2 packets in recv queue
*/

#define PORT 3000

#define MSG1_1 "msg1_1"
#define MSG1_2 "msg1_2"
#define MSG2 "msg2"
#define MSG3 "msg_3"

int main(int argc, char **argv)
{
int ret, sk1, sk2, sk3, aux;
struct sockaddr_in6 addr1, addr2, addr3, addr;
unsigned int addr_len;
char recv_buffer[256], buffer[256];

test_init(argc, argv);

sk1 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sk1 < 0) {
pr_perror("Can't create socket");
return 1;
}

sk2 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sk2 < 0) {
pr_perror("Can't create socket");
return 1;
}

sk3 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sk3 < 0) {
pr_perror("Can't create socket");
return 1;
}

memset(&addr1, 0, sizeof(addr1));
addr1.sin6_family = AF_INET6;
addr1.sin6_port = htons(PORT);
inet_pton(AF_INET6, "::1", &addr1.sin6_addr);
ret = bind(sk1, (struct sockaddr *)&addr1, sizeof(addr1));
if (ret < 0) {
pr_perror("Can't bind socket");
return 1;
}

memset(&addr2, 0, sizeof(addr2));
addr2.sin6_family = AF_INET6;
addr2.sin6_port = htons(PORT + 1);
inet_pton(AF_INET6, "::1", &addr2.sin6_addr);
ret = bind(sk2, (struct sockaddr *)&addr2, sizeof(addr2));
if (ret < 0) {
pr_perror("Can't bind socket");
return 1;
}

memset(&addr3, 0, sizeof(addr3));
addr3.sin6_family = AF_INET6;
addr3.sin6_port = htons(PORT + 2);
inet_pton(AF_INET6, "::1", &addr3.sin6_addr);
ret = bind(sk3, (struct sockaddr *)&addr3, sizeof(addr3));
if (ret < 0) {
pr_perror("Can't bind socket");
return 1;
}

ret = sendto(sk2, MSG2, sizeof(MSG2), 0, (struct sockaddr *)&addr1, sizeof(addr1));
if (ret < 0) {
pr_perror("Can't send");
return 1;
}

ret = sendto(sk3, MSG3, sizeof(MSG3), 0, (struct sockaddr *)&addr1, sizeof(addr1));
if (ret < 0) {
pr_perror("Can't send");
return 1;
}

aux = 1;
if (setsockopt(sk1, SOL_UDP, UDP_CORK, &aux, sizeof(aux))) {
pr_perror("Can't set UDP_CORK");
return 1;
}

ret = sendto(sk1, MSG1_1, sizeof(MSG1_1), 0, (struct sockaddr *)&addr3, sizeof(addr3));
if (ret < 0) {
pr_perror("Can't send");
return 1;
}

ret = sendto(sk1, MSG1_2, sizeof(MSG1_2), 0, (struct sockaddr *)&addr3, sizeof(addr3));
if (ret < 0) {
pr_perror("Can't send");
return 1;
}

close(sk2);

test_daemon();
test_waitsig();

aux = 0;
if (setsockopt(sk1, SOL_UDP, UDP_CORK, &aux, sizeof(aux))) {
fail("Can't unset UDP_CORK");
return 1;
}

addr_len = sizeof(addr);
ret = recvfrom(sk3, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr *)&addr, &addr_len);
if (ret < 0) {
fail("Can't receive corked packet");
return 1;
}

memcpy(buffer, MSG1_1, sizeof(MSG1_1));
memcpy(buffer + sizeof(MSG1_1), MSG1_2, sizeof(MSG1_2));
if (ret != sizeof(MSG1_1) + sizeof(MSG1_2) || memcmp(recv_buffer, buffer, ret)) {
fail("Message 1 mismatch");
return 1;
}

if (addr_len != sizeof(struct sockaddr_in6) || memcmp(&addr1, &addr, addr_len)) {
fail("Wrong peer");
return 1;
}

ret = recvfrom(sk1, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr *)&addr, &addr_len);
if (ret < 0) {
fail("Can't receive MSG2");
return 1;
}

if (ret != sizeof(MSG2) || memcmp(recv_buffer, MSG2, sizeof(MSG2))) {
fail("Message 2 mismatch");
return 1;
}

if (addr_len != sizeof(struct sockaddr_in6) || memcmp(&addr2, &addr, addr_len)) {
fail("Wrong peer");
return 1;
}

ret = recvfrom(sk1, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr *)&addr, &addr_len);
if (ret < 0) {
fail("Can't receive MSG3");
return 1;
}

if (ret != sizeof(MSG3) || memcmp(recv_buffer, MSG3, sizeof(MSG3))) {
fail("Message 3 mismatch");
return 1;
}

if (addr_len != sizeof(struct sockaddr_in6) || memcmp(&addr3, &addr, addr_len)) {
fail("Wrong peer");
return 1;
}

pass();

return 0;
}
1 change: 1 addition & 0 deletions test/zdtm/static/socket6_udp_repair.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{'flags': 'suid', 'feature': 'udp_repair'}
75 changes: 0 additions & 75 deletions test/zdtm/static/socket_udp-corked.c

This file was deleted.

1 change: 0 additions & 1 deletion test/zdtm/static/socket_udp-corked.desc

This file was deleted.

Loading

0 comments on commit 92258cf

Please sign in to comment.