12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
20 #define NUM_THREADS 10
22 static int setup_echo_srv_tcp_ipv4(void **state)
24 torture_setup_echo_srv_tcp_ipv4(state);
29 static int teardown(void **state)
31 torture_teardown_echo_srv(state);
36 static void *thread_worker1(void *arg)
38 struct torture_address addr = {
39 .sa_socklen = sizeof(struct sockaddr_storage),
41 char send_buf[64] = {0};
42 char recv_buf[64] = {0};
48 (void) arg; /* unused */
50 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
51 assert_int_not_equal(s, -1);
53 addr.sa.in.sin_family = AF_INET;
54 addr.sa.in.sin_port = htons(torture_server_port());
56 rc = inet_pton(AF_INET,
57 torture_server_address(AF_INET),
58 &addr.sa.in.sin_addr);
59 assert_int_equal(rc, 1);
61 rc = connect(s, &addr.sa.s, addr.sa_socklen);
62 assert_return_code(rc, errno);
64 for (i = 0; i < 10; i++) {
65 struct torture_address reply_addr = {
66 .sa_socklen = sizeof(struct sockaddr_storage),
68 struct msghdr s_msg = {
71 struct msghdr r_msg = {
77 snprintf(send_buf, sizeof(send_buf), "packet.%d", i);
79 /* This should be ignored */
80 rc = inet_pton(AF_INET,
82 &addr.sa.in.sin_addr);
83 assert_int_equal(rc, 1);
85 s_msg.msg_name = &addr.sa.s;
86 s_msg.msg_namelen = addr.sa_socklen;
88 s_iov.iov_base = send_buf;
89 s_iov.iov_len = sizeof(send_buf);
91 s_msg.msg_iov = &s_iov;
94 ret = sendmsg(s, &s_msg, 0);
95 assert_int_not_equal(ret, -1);
97 r_msg.msg_name = &reply_addr.sa.s;
98 r_msg.msg_namelen = reply_addr.sa_socklen;
100 r_iov.iov_base = recv_buf;
101 r_iov.iov_len = sizeof(recv_buf);
103 r_msg.msg_iov = &r_iov;
104 r_msg.msg_iovlen = 1;
106 ret = recvmsg(s, &r_msg, 0);
107 assert_int_not_equal(ret, -1);
109 assert_int_equal(r_msg.msg_namelen, 0);
111 assert_memory_equal(send_buf, recv_buf, sizeof(send_buf));
118 static void *thread_worker2(void *arg)
120 struct torture_address send_addr = {
121 .sa_socklen = sizeof(struct sockaddr_storage),
123 struct msghdr s_msg = {
126 struct msghdr r_msg = {
130 char payload[] = "PACKET";
135 (void)arg; /* unused */
137 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
138 assert_int_not_equal(s, -1);
140 send_addr.sa.in.sin_family = AF_INET;
141 send_addr.sa.in.sin_port = htons(torture_server_port());
143 rc = inet_pton(AF_INET,
144 torture_server_address(AF_INET),
145 &send_addr.sa.in.sin_addr);
146 assert_int_equal(rc, 1);
148 rc = connect(s, &send_addr.sa.s, send_addr.sa_socklen);
149 assert_return_code(rc, errno);
151 /* msg_name = NULL */
153 iov.iov_base = (void *)payload;
154 iov.iov_len = sizeof(payload);
156 s_msg.msg_iov = &iov;
157 s_msg.msg_iovlen = 1;
159 ret = sendmsg(s, &s_msg, 0);
160 assert_int_not_equal(ret, -1);
162 /* msg_name = NULL */
164 memset(payload, 0, sizeof(payload));
166 r_msg.msg_iov = &iov;
167 r_msg.msg_iovlen = 1;
169 ret = recvmsg(s, &r_msg, 0);
170 assert_int_not_equal(ret, -1);
172 assert_int_equal(r_msg.msg_namelen, 0);
173 assert_null(r_msg.msg_name);
179 static void test_sendmsg_recvmsg_ipv4(void **state)
181 pthread_attr_t pthread_custom_attr;
182 pthread_t threads[NUM_THREADS];
185 (void) state; /* unused */
187 pthread_attr_init(&pthread_custom_attr);
189 for (i = 0; i < NUM_THREADS; i++) {
190 pthread_create(&threads[i],
191 &pthread_custom_attr,
196 for (i = 0; i < NUM_THREADS; i++) {
197 pthread_join(threads[i], NULL);
200 pthread_attr_destroy(&pthread_custom_attr);
203 static void test_sendmsg_recvmsg_ipv4_null(void **state)
205 pthread_attr_t pthread_custom_attr;
206 pthread_t threads[NUM_THREADS];
209 (void) state; /* unused */
211 pthread_attr_init(&pthread_custom_attr);
213 for (i = 0; i < NUM_THREADS; i++) {
214 pthread_create(&threads[i],
215 &pthread_custom_attr,
220 for (i = 0; i < NUM_THREADS; i++) {
221 pthread_join(threads[i], NULL);
224 pthread_attr_destroy(&pthread_custom_attr);
231 const struct CMUnitTest sendmsg_tests[] = {
232 cmocka_unit_test_setup_teardown(test_sendmsg_recvmsg_ipv4,
233 setup_echo_srv_tcp_ipv4,
235 cmocka_unit_test_setup_teardown(test_sendmsg_recvmsg_ipv4_null,
236 setup_echo_srv_tcp_ipv4,
240 rc = cmocka_run_group_tests(sendmsg_tests, NULL, NULL);