10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
18 static int setup_echo_srv_tcp_ipv4(void **state)
20 torture_setup_echo_srv_tcp_ipv4(state);
26 static int setup_echo_srv_tcp_ipv6(void **state)
28 torture_setup_echo_srv_tcp_ipv6(state);
34 static int teardown(void **state)
36 torture_teardown_echo_srv(state);
41 static void test_sendmmsg_recvmmsg_ipv4_ignore(void **state)
43 struct torture_address addr = {
44 .sa_socklen = sizeof(struct sockaddr_storage),
47 struct torture_address reply_addr;
53 struct mmsghdr s_msgs[10] = {};
54 struct mmsghdr r_msgs[10] = {};
60 (void) state; /* unused */
62 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
63 assert_int_not_equal(s, -1);
65 addr.sa.in.sin_family = AF_INET;
66 addr.sa.in.sin_port = htons(torture_server_port());
68 rc = inet_pton(AF_INET,
69 torture_server_address(AF_INET),
70 &addr.sa.in.sin_addr);
71 assert_int_equal(rc, 1);
73 rc = connect(s, &addr.sa.s, addr.sa_socklen);
74 assert_return_code(rc, errno);
76 /* This should be ignored */
77 rc = inet_pton(AF_INET,
79 &addr.sa.in.sin_addr);
80 assert_int_equal(rc, 1);
82 for (i = 0; i < 10; i++) {
83 tmsgs[i].reply_addr = (struct torture_address){
84 .sa_socklen = sizeof(struct sockaddr_storage),
87 snprintf(tmsgs[i].send_buf, sizeof(tmsgs[i].send_buf), "packet.%d", i);
89 tmsgs[i].s_iov.iov_base = tmsgs[i].send_buf;
90 tmsgs[i].s_iov.iov_len = sizeof(tmsgs[i].send_buf);
92 s_msgs[i].msg_hdr.msg_name = &addr.sa.s;
93 s_msgs[i].msg_hdr.msg_namelen = addr.sa_socklen;
94 s_msgs[i].msg_hdr.msg_iov = &tmsgs[i].s_iov;
95 s_msgs[i].msg_hdr.msg_iovlen = 1;
97 tmsgs[i].r_iov.iov_base = tmsgs[i].recv_buf;
98 tmsgs[i].r_iov.iov_len = sizeof(tmsgs[i].recv_buf);
100 r_msgs[i].msg_hdr.msg_name = &tmsgs[i].reply_addr.sa.s;
101 r_msgs[i].msg_hdr.msg_namelen = tmsgs[i].reply_addr.sa_socklen;
102 r_msgs[i].msg_hdr.msg_iov = &tmsgs[i].r_iov;
103 r_msgs[i].msg_hdr.msg_iovlen = 1;
106 ret = sendmmsg(s, s_msgs, 10, 0);
107 assert_int_equal(ret, 10);
109 ret = recvmmsg(s, r_msgs, 10, 0, NULL);
110 assert_int_equal(ret, 10);
112 for (i = 0; i < 10; i++) {
113 assert_int_equal(r_msgs[i].msg_hdr.msg_namelen, 0);
114 assert_ptr_equal(r_msgs[i].msg_hdr.msg_name, &tmsgs[i].reply_addr.sa.s);
116 assert_int_equal(r_msgs[i].msg_len, tmsgs[i].s_iov.iov_len);
117 assert_memory_equal(tmsgs[i].send_buf, tmsgs[i].recv_buf, sizeof(tmsgs[i].send_buf));
121 assert_int_equal(rc, 0);
125 static void test_sendmmsg_recvmmsg_ipv6(void **state)
127 struct torture_address addr = {
128 .sa_socklen = sizeof(struct sockaddr_storage),
131 struct torture_address reply_addr;
137 struct mmsghdr s_msgs[10] = {};
138 struct mmsghdr r_msgs[10] = {};
144 (void) state; /* unused */
146 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
147 assert_int_not_equal(s, -1);
149 addr.sa.in.sin_family = AF_INET6;
150 addr.sa.in.sin_port = htons(torture_server_port());
152 rc = inet_pton(AF_INET6,
153 torture_server_address(AF_INET6),
154 &addr.sa.in6.sin6_addr);
155 assert_int_equal(rc, 1);
157 rc = connect(s, &addr.sa.s, addr.sa_socklen);
158 assert_return_code(rc, errno);
160 for (i = 0; i < 10; i++) {
161 tmsgs[i].reply_addr = (struct torture_address){
162 .sa_socklen = sizeof(struct sockaddr_storage),
165 snprintf(tmsgs[i].send_buf, sizeof(tmsgs[i].send_buf), "packet.%d", i);
167 tmsgs[i].s_iov.iov_base = tmsgs[i].send_buf;
168 tmsgs[i].s_iov.iov_len = sizeof(tmsgs[i].send_buf);
170 s_msgs[i].msg_hdr.msg_name = &addr.sa.s;
171 s_msgs[i].msg_hdr.msg_namelen = addr.sa_socklen;
172 s_msgs[i].msg_hdr.msg_iov = &tmsgs[i].s_iov;
173 s_msgs[i].msg_hdr.msg_iovlen = 1;
175 tmsgs[i].r_iov.iov_base = tmsgs[i].recv_buf;
176 tmsgs[i].r_iov.iov_len = sizeof(tmsgs[i].recv_buf);
178 r_msgs[i].msg_hdr.msg_name = &tmsgs[i].reply_addr.sa.s;
179 r_msgs[i].msg_hdr.msg_namelen = tmsgs[i].reply_addr.sa_socklen;
180 r_msgs[i].msg_hdr.msg_iov = &tmsgs[i].r_iov;
181 r_msgs[i].msg_hdr.msg_iovlen = 1;
184 ret = sendmmsg(s, s_msgs, 10, 0);
185 assert_int_equal(ret, 10);
187 ret = recvmmsg(s, r_msgs, 10, 0, NULL);
188 assert_int_equal(ret, 10);
190 for (i = 0; i < 10; i++) {
191 assert_int_equal(r_msgs[i].msg_hdr.msg_namelen, 0);
192 assert_ptr_equal(r_msgs[i].msg_hdr.msg_name, &tmsgs[i].reply_addr.sa.s);
194 assert_int_equal(r_msgs[i].msg_len, tmsgs[i].s_iov.iov_len);
195 assert_memory_equal(tmsgs[i].send_buf, tmsgs[i].recv_buf, sizeof(tmsgs[i].send_buf));
199 assert_int_equal(rc, 0);
203 static void test_sendmmsg_recvmmsg_ipv4_null(void **state)
205 struct torture_address addr = {
206 .sa_socklen = sizeof(struct sockaddr_storage),
209 struct torture_address reply_addr;
215 struct mmsghdr s_msgs[10] = {};
216 struct mmsghdr r_msgs[10] = {};
222 (void) state; /* unused */
224 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
225 assert_int_not_equal(s, -1);
227 addr.sa.in.sin_family = AF_INET;
228 addr.sa.in.sin_port = htons(torture_server_port());
230 rc = inet_pton(AF_INET,
231 torture_server_address(AF_INET),
232 &addr.sa.in.sin_addr);
233 assert_int_equal(rc, 1);
235 rc = connect(s, &addr.sa.s, addr.sa_socklen);
236 assert_return_code(rc, errno);
238 for (i = 0; i < 10; i++) {
239 tmsgs[i].reply_addr = (struct torture_address){
240 .sa_socklen = sizeof(struct sockaddr_storage),
243 snprintf(tmsgs[i].send_buf, sizeof(tmsgs[i].send_buf), "packet.%d", i);
245 tmsgs[i].s_iov.iov_base = tmsgs[i].send_buf;
246 tmsgs[i].s_iov.iov_len = sizeof(tmsgs[i].send_buf);
248 s_msgs[i].msg_hdr.msg_name = NULL;
249 s_msgs[i].msg_hdr.msg_namelen = 0;
250 s_msgs[i].msg_hdr.msg_iov = &tmsgs[i].s_iov;
251 s_msgs[i].msg_hdr.msg_iovlen = 1;
253 tmsgs[i].r_iov.iov_base = tmsgs[i].recv_buf;
254 tmsgs[i].r_iov.iov_len = sizeof(tmsgs[i].recv_buf);
256 r_msgs[i].msg_hdr.msg_name = NULL;
257 r_msgs[i].msg_hdr.msg_namelen = 0;
258 r_msgs[i].msg_hdr.msg_iov = &tmsgs[i].r_iov;
259 r_msgs[i].msg_hdr.msg_iovlen = 1;
262 ret = sendmmsg(s, s_msgs, 10, 0);
263 assert_int_equal(ret, 10);
265 ret = recvmmsg(s, r_msgs, 10, 0, NULL);
266 assert_int_equal(ret, 10);
268 for (i = 0; i < 10; i++) {
269 assert_int_equal(r_msgs[i].msg_hdr.msg_namelen, 0);
270 assert_null(r_msgs[i].msg_hdr.msg_name);
272 assert_int_equal(r_msgs[i].msg_len, tmsgs[i].s_iov.iov_len);
273 assert_memory_equal(tmsgs[i].send_buf, tmsgs[i].recv_buf, sizeof(tmsgs[i].send_buf));
277 assert_int_equal(rc, 0);
283 const struct CMUnitTest sendmsg_tests[] = {
284 cmocka_unit_test_setup_teardown(test_sendmmsg_recvmmsg_ipv4_ignore,
285 setup_echo_srv_tcp_ipv4,
287 cmocka_unit_test_setup_teardown(test_sendmmsg_recvmmsg_ipv4_null,
288 setup_echo_srv_tcp_ipv4,
291 cmocka_unit_test_setup_teardown(test_sendmmsg_recvmmsg_ipv6,
292 setup_echo_srv_tcp_ipv6,
297 rc = cmocka_run_group_tests(sendmsg_tests, NULL, NULL);