cmake: Define large file support for tests
[socket_wrapper.git] / tests / test_echo_tcp_sendmsg_recvmsg.c
1 #include <stdarg.h>
2 #include <stddef.h>
3 #include <setjmp.h>
4 #include <cmocka.h>
5
6 #include "config.h"
7 #include "torture.h"
8
9 #include <errno.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <unistd.h>
17
18 static int setup_echo_srv_tcp_ipv4(void **state)
19 {
20         torture_setup_echo_srv_tcp_ipv4(state);
21
22         return 0;
23 }
24
25 #ifdef HAVE_IPV6
26 static int setup_echo_srv_tcp_ipv6(void **state)
27 {
28         torture_setup_echo_srv_tcp_ipv6(state);
29
30         return 0;
31 }
32 #endif
33
34 static int teardown(void **state)
35 {
36         torture_teardown_echo_srv(state);
37
38         return 0;
39 }
40
41 static void test_sendmsg_recvmsg_ipv4(void **state)
42 {
43         struct torture_address addr = {
44                 .sa_socklen = sizeof(struct sockaddr_storage),
45         };
46         char send_buf[64] = {0};
47         char recv_buf[64] = {0};
48         ssize_t ret;
49         int rc;
50         int i;
51         int s;
52
53         (void) state; /* unused */
54
55         s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
56         assert_int_not_equal(s, -1);
57
58         addr.sa.in.sin_family = AF_INET;
59         addr.sa.in.sin_port = htons(torture_server_port());
60
61         rc = inet_pton(AF_INET,
62                        torture_server_address(AF_INET),
63                        &addr.sa.in.sin_addr);
64         assert_int_equal(rc, 1);
65
66         rc = connect(s, &addr.sa.s, addr.sa_socklen);
67         assert_return_code(rc, errno);
68
69         for (i = 0; i < 10; i++) {
70                 struct torture_address reply_addr = {
71                         .sa_socklen = sizeof(struct sockaddr_storage),
72                 };
73                 struct msghdr s_msg = {
74                         .msg_namelen = 0,
75                 };
76                 struct msghdr r_msg = {
77                         .msg_namelen = 0,
78                 };
79                 struct iovec s_iov;
80                 struct iovec r_iov;
81
82                 snprintf(send_buf, sizeof(send_buf), "packet.%d", i);
83
84                 /* This should be ignored */
85                 rc = inet_pton(AF_INET,
86                                "127.0.0.1",
87                                &addr.sa.in.sin_addr);
88                 assert_int_equal(rc, 1);
89
90                 s_msg.msg_name = &addr.sa.s;
91                 s_msg.msg_namelen = addr.sa_socklen;
92
93                 s_iov.iov_base = send_buf;
94                 s_iov.iov_len = sizeof(send_buf);
95
96                 s_msg.msg_iov = &s_iov;
97                 s_msg.msg_iovlen = 1;
98
99                 ret = sendmsg(s, &s_msg, 0);
100                 assert_int_not_equal(ret, -1);
101
102                 r_msg.msg_name = &reply_addr.sa.s;
103                 r_msg.msg_namelen = reply_addr.sa_socklen;
104
105                 r_iov.iov_base = recv_buf;
106                 r_iov.iov_len = sizeof(recv_buf);
107
108                 r_msg.msg_iov = &r_iov;
109                 r_msg.msg_iovlen = 1;
110
111                 ret = recvmsg(s, &r_msg, 0);
112                 assert_int_not_equal(ret, -1);
113
114                 assert_int_equal(r_msg.msg_namelen, 0);
115
116                 assert_memory_equal(send_buf, recv_buf, sizeof(send_buf));
117         }
118
119         close(s);
120 }
121
122 #ifdef HAVE_IPV6
123 static void test_sendmsg_recvmsg_ipv6(void **state)
124 {
125         struct torture_address addr = {
126                 .sa_socklen = sizeof(struct sockaddr_storage),
127         };
128         char send_buf[64] = {0};
129         char recv_buf[64] = {0};
130         ssize_t ret;
131         int rc;
132         int i;
133         int s;
134
135         (void) state; /* unused */
136
137         s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
138         assert_int_not_equal(s, -1);
139
140         addr.sa.in.sin_family = AF_INET6;
141         addr.sa.in.sin_port = htons(torture_server_port());
142
143         rc = inet_pton(AF_INET6,
144                        torture_server_address(AF_INET6),
145                        &addr.sa.in6.sin6_addr);
146         assert_int_equal(rc, 1);
147
148         rc = connect(s, &addr.sa.s, addr.sa_socklen);
149         assert_return_code(rc, errno);
150
151         for (i = 0; i < 10; i++) {
152                 struct torture_address reply_addr = {
153                         .sa_socklen = sizeof(struct sockaddr_in),
154                 };
155                 struct msghdr s_msg = {
156                         .msg_namelen = 0,
157                 };
158                 struct msghdr r_msg = {
159                         .msg_namelen = 0,
160                 };
161                 struct iovec s_iov;
162                 struct iovec r_iov;
163
164                 snprintf(send_buf, sizeof(send_buf), "packet.%d", i);
165
166                 s_iov.iov_base = send_buf;
167                 s_iov.iov_len = sizeof(send_buf);
168
169                 s_msg.msg_iov = &s_iov;
170                 s_msg.msg_iovlen = 1;
171
172                 ret = sendmsg(s, &s_msg, 0);
173                 assert_int_not_equal(ret, -1);
174
175                 r_msg.msg_name = &reply_addr.sa.s;
176                 r_msg.msg_namelen = reply_addr.sa_socklen;
177
178                 r_iov.iov_base = recv_buf;
179                 r_iov.iov_len = sizeof(recv_buf);
180
181                 r_msg.msg_iov = &r_iov;
182                 r_msg.msg_iovlen = 1;
183
184                 ret = recvmsg(s, &r_msg, 0);
185                 assert_int_not_equal(ret, -1);
186
187                 assert_int_equal(r_msg.msg_namelen, 0);
188
189                 assert_memory_equal(send_buf, recv_buf, sizeof(send_buf));
190         }
191
192         close(s);
193 }
194 #endif
195
196 static void test_sendmsg_recvmsg_ipv4_null(void **state)
197 {
198         struct torture_address send_addr = {
199                 .sa_socklen = sizeof(struct sockaddr_storage),
200         };
201         struct msghdr s_msg = {
202                 .msg_namelen = 0,
203         };
204         struct msghdr r_msg = {
205                 .msg_namelen = 0,
206         };
207         struct iovec iov;
208         char payload[] = "PACKET";
209         ssize_t ret;
210         int rc;
211         int s;
212
213         (void)state; /* unused */
214
215         s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
216         assert_int_not_equal(s, -1);
217
218         send_addr.sa.in.sin_family = AF_INET;
219         send_addr.sa.in.sin_port = htons(torture_server_port());
220
221         rc = inet_pton(AF_INET,
222                        torture_server_address(AF_INET),
223                        &send_addr.sa.in.sin_addr);
224         assert_int_equal(rc, 1);
225
226         rc = connect(s, &send_addr.sa.s, send_addr.sa_socklen);
227         assert_return_code(rc, errno);
228
229         /* msg_name = NULL */
230
231         iov.iov_base = (void *)payload;
232         iov.iov_len = sizeof(payload);
233
234         s_msg.msg_iov = &iov;
235         s_msg.msg_iovlen = 1;
236
237         ret = sendmsg(s, &s_msg, 0);
238         assert_int_not_equal(ret, -1);
239
240         /* msg_name = NULL */
241
242         memset(payload, 0, sizeof(payload));
243
244         r_msg.msg_iov = &iov;
245         r_msg.msg_iovlen = 1;
246
247         ret = recvmsg(s, &r_msg, 0);
248         assert_int_not_equal(ret, -1);
249
250         assert_int_equal(r_msg.msg_namelen, 0);
251         assert_null(r_msg.msg_name);
252
253         close(s);
254 }
255
256 int main(void) {
257         int rc;
258
259         const struct CMUnitTest sendmsg_tests[] = {
260                 cmocka_unit_test_setup_teardown(test_sendmsg_recvmsg_ipv4,
261                                                 setup_echo_srv_tcp_ipv4,
262                                                 teardown),
263                 cmocka_unit_test_setup_teardown(test_sendmsg_recvmsg_ipv4_null,
264                                                 setup_echo_srv_tcp_ipv4,
265                                                 teardown),
266 #ifdef HAVE_IPV6
267                 cmocka_unit_test_setup_teardown(test_sendmsg_recvmsg_ipv6,
268                                                 setup_echo_srv_tcp_ipv6,
269                                                 teardown),
270 #endif
271         };
272
273         rc = cmocka_run_group_tests(sendmsg_tests, NULL, NULL);
274
275         return rc;
276 }