1*10465441SEvalZero #include "test_sockets.h"
2*10465441SEvalZero
3*10465441SEvalZero #include "lwip/mem.h"
4*10465441SEvalZero #include "lwip/opt.h"
5*10465441SEvalZero #include "lwip/sockets.h"
6*10465441SEvalZero #include "lwip/priv/sockets_priv.h"
7*10465441SEvalZero #include "lwip/stats.h"
8*10465441SEvalZero
9*10465441SEvalZero #include "lwip/tcpip.h"
10*10465441SEvalZero #include "lwip/priv/tcp_priv.h"
11*10465441SEvalZero #include "lwip/api.h"
12*10465441SEvalZero
13*10465441SEvalZero
14*10465441SEvalZero static int
test_sockets_get_used_count(void)15*10465441SEvalZero test_sockets_get_used_count(void)
16*10465441SEvalZero {
17*10465441SEvalZero int used = 0;
18*10465441SEvalZero int i;
19*10465441SEvalZero
20*10465441SEvalZero for (i = 0; i < NUM_SOCKETS; i++) {
21*10465441SEvalZero struct lwip_sock* s = lwip_socket_dbg_get_socket(i);
22*10465441SEvalZero if (s != NULL) {
23*10465441SEvalZero if (s->fd_used) {
24*10465441SEvalZero used++;
25*10465441SEvalZero }
26*10465441SEvalZero }
27*10465441SEvalZero }
28*10465441SEvalZero return used;
29*10465441SEvalZero }
30*10465441SEvalZero
31*10465441SEvalZero
32*10465441SEvalZero /* Setups/teardown functions */
33*10465441SEvalZero
34*10465441SEvalZero static void
sockets_setup(void)35*10465441SEvalZero sockets_setup(void)
36*10465441SEvalZero {
37*10465441SEvalZero /* expect full free heap */
38*10465441SEvalZero lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
39*10465441SEvalZero }
40*10465441SEvalZero
41*10465441SEvalZero static void
sockets_teardown(void)42*10465441SEvalZero sockets_teardown(void)
43*10465441SEvalZero {
44*10465441SEvalZero fail_unless(test_sockets_get_used_count() == 0);
45*10465441SEvalZero /* poll until all memory is released... */
46*10465441SEvalZero tcpip_thread_poll_one();
47*10465441SEvalZero while (tcp_tw_pcbs) {
48*10465441SEvalZero tcp_abort(tcp_tw_pcbs);
49*10465441SEvalZero tcpip_thread_poll_one();
50*10465441SEvalZero }
51*10465441SEvalZero tcpip_thread_poll_one();
52*10465441SEvalZero /* ensure full free heap */
53*10465441SEvalZero lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
54*10465441SEvalZero }
55*10465441SEvalZero
56*10465441SEvalZero #ifndef NUM_SOCKETS
57*10465441SEvalZero #define NUM_SOCKETS MEMP_NUM_NETCONN
58*10465441SEvalZero #endif
59*10465441SEvalZero
60*10465441SEvalZero #if LWIP_SOCKET
61*10465441SEvalZero static int
test_sockets_alloc_socket_nonblocking(int domain,int type)62*10465441SEvalZero test_sockets_alloc_socket_nonblocking(int domain, int type)
63*10465441SEvalZero {
64*10465441SEvalZero int s = lwip_socket(domain, type, 0);
65*10465441SEvalZero if (s >= 0) {
66*10465441SEvalZero int ret = lwip_fcntl(s, F_SETFL, O_NONBLOCK);
67*10465441SEvalZero fail_unless(ret == 0);
68*10465441SEvalZero }
69*10465441SEvalZero return s;
70*10465441SEvalZero }
71*10465441SEvalZero
72*10465441SEvalZero /* Verify basic sockets functionality
73*10465441SEvalZero */
START_TEST(test_sockets_basics)74*10465441SEvalZero START_TEST(test_sockets_basics)
75*10465441SEvalZero {
76*10465441SEvalZero int s, i, ret;
77*10465441SEvalZero int s2[NUM_SOCKETS];
78*10465441SEvalZero LWIP_UNUSED_ARG(_i);
79*10465441SEvalZero
80*10465441SEvalZero s = lwip_socket(AF_INET, SOCK_STREAM, 0);
81*10465441SEvalZero fail_unless(s >= 0);
82*10465441SEvalZero lwip_close(s);
83*10465441SEvalZero
84*10465441SEvalZero for (i = 0; i < NUM_SOCKETS; i++) {
85*10465441SEvalZero s2[i] = lwip_socket(AF_INET, SOCK_STREAM, 0);
86*10465441SEvalZero fail_unless(s2[i] >= 0);
87*10465441SEvalZero }
88*10465441SEvalZero
89*10465441SEvalZero /* all sockets used, now it should fail */
90*10465441SEvalZero s = lwip_socket(AF_INET, SOCK_STREAM, 0);
91*10465441SEvalZero fail_unless(s == -1);
92*10465441SEvalZero /* close one socket */
93*10465441SEvalZero ret = lwip_close(s2[0]);
94*10465441SEvalZero fail_unless(ret == 0);
95*10465441SEvalZero /* now it should succeed */
96*10465441SEvalZero s2[0] = lwip_socket(AF_INET, SOCK_STREAM, 0);
97*10465441SEvalZero fail_unless(s2[0] >= 0);
98*10465441SEvalZero
99*10465441SEvalZero /* close all sockets */
100*10465441SEvalZero for (i = 0; i < NUM_SOCKETS; i++) {
101*10465441SEvalZero ret = lwip_close(s2[i]);
102*10465441SEvalZero fail_unless(ret == 0);
103*10465441SEvalZero }
104*10465441SEvalZero }
105*10465441SEvalZero END_TEST
106*10465441SEvalZero
test_sockets_allfunctions_basic_domain(int domain)107*10465441SEvalZero static void test_sockets_allfunctions_basic_domain(int domain)
108*10465441SEvalZero {
109*10465441SEvalZero int s, s2, s3, ret;
110*10465441SEvalZero struct sockaddr_storage addr, addr2;
111*10465441SEvalZero socklen_t addrlen, addr2len;
112*10465441SEvalZero char buf[4];
113*10465441SEvalZero /* listen socket */
114*10465441SEvalZero s = lwip_socket(domain, SOCK_STREAM, 0);
115*10465441SEvalZero fail_unless(s >= 0);
116*10465441SEvalZero
117*10465441SEvalZero ret = lwip_listen(s, 0);
118*10465441SEvalZero fail_unless(ret == 0);
119*10465441SEvalZero
120*10465441SEvalZero addrlen = sizeof(addr);
121*10465441SEvalZero ret = lwip_getsockname(s, (struct sockaddr*)&addr, &addrlen);
122*10465441SEvalZero fail_unless(ret == 0);
123*10465441SEvalZero
124*10465441SEvalZero s2 = test_sockets_alloc_socket_nonblocking(domain, SOCK_STREAM);
125*10465441SEvalZero fail_unless(s2 >= 0);
126*10465441SEvalZero /* nonblocking connect s2 to s (but use loopback address) */
127*10465441SEvalZero if (domain == AF_INET) {
128*10465441SEvalZero #if LWIP_IPV4
129*10465441SEvalZero struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
130*10465441SEvalZero addr4->sin_addr.s_addr = PP_HTONL(INADDR_LOOPBACK);
131*10465441SEvalZero #endif
132*10465441SEvalZero } else {
133*10465441SEvalZero #if LWIP_IPV6
134*10465441SEvalZero struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
135*10465441SEvalZero struct in6_addr lo6 = IN6ADDR_LOOPBACK_INIT;
136*10465441SEvalZero addr6->sin6_addr = lo6;
137*10465441SEvalZero #endif
138*10465441SEvalZero }
139*10465441SEvalZero ret = lwip_connect(s2, (struct sockaddr*)&addr, addrlen);
140*10465441SEvalZero fail_unless(ret == -1);
141*10465441SEvalZero fail_unless(errno == EINPROGRESS);
142*10465441SEvalZero ret = lwip_connect(s2, (struct sockaddr*)&addr, addrlen);
143*10465441SEvalZero fail_unless(ret == -1);
144*10465441SEvalZero fail_unless(errno == EALREADY);
145*10465441SEvalZero
146*10465441SEvalZero while(tcpip_thread_poll_one());
147*10465441SEvalZero
148*10465441SEvalZero s3 = lwip_accept(s, (struct sockaddr*)&addr2, &addr2len);
149*10465441SEvalZero fail_unless(s3 >= 0);
150*10465441SEvalZero
151*10465441SEvalZero ret = lwip_connect(s2, (struct sockaddr*)&addr, addrlen);
152*10465441SEvalZero fail_unless(ret == -1);
153*10465441SEvalZero fail_unless(errno == EISCONN);
154*10465441SEvalZero
155*10465441SEvalZero /* write from server to client */
156*10465441SEvalZero ret = write(s3, "test", 4);
157*10465441SEvalZero fail_unless(ret == 4);
158*10465441SEvalZero
159*10465441SEvalZero ret = lwip_shutdown(s3, SHUT_WR);
160*10465441SEvalZero fail_unless(ret == 0);
161*10465441SEvalZero
162*10465441SEvalZero while(tcpip_thread_poll_one());
163*10465441SEvalZero
164*10465441SEvalZero ret = lwip_recv(s2, buf, 3, MSG_PEEK);
165*10465441SEvalZero fail_unless(ret == 3);
166*10465441SEvalZero
167*10465441SEvalZero ret = lwip_recv(s2, buf, 3, MSG_PEEK);
168*10465441SEvalZero fail_unless(ret == 3);
169*10465441SEvalZero
170*10465441SEvalZero ret = lwip_read(s2, buf, 4);
171*10465441SEvalZero fail_unless(ret == 4);
172*10465441SEvalZero
173*10465441SEvalZero ret = lwip_read(s2, buf, 1);
174*10465441SEvalZero fail_unless(ret == 0);
175*10465441SEvalZero
176*10465441SEvalZero ret = lwip_read(s2, buf, 1);
177*10465441SEvalZero fail_unless(ret == -1);
178*10465441SEvalZero
179*10465441SEvalZero ret = lwip_write(s2, "foo", 3);
180*10465441SEvalZero fail_unless(ret == 3);
181*10465441SEvalZero
182*10465441SEvalZero ret = lwip_close(s2);
183*10465441SEvalZero fail_unless(ret == 0);
184*10465441SEvalZero
185*10465441SEvalZero while(tcpip_thread_poll_one());
186*10465441SEvalZero
187*10465441SEvalZero /* read one byte more than available to check handling FIN */
188*10465441SEvalZero ret = lwip_read(s3, buf, 4);
189*10465441SEvalZero fail_unless(ret == 3);
190*10465441SEvalZero
191*10465441SEvalZero ret = lwip_read(s3, buf, 1);
192*10465441SEvalZero fail_unless(ret == 0);
193*10465441SEvalZero
194*10465441SEvalZero ret = lwip_read(s3, buf, 1);
195*10465441SEvalZero fail_unless(ret == -1);
196*10465441SEvalZero
197*10465441SEvalZero while(tcpip_thread_poll_one());
198*10465441SEvalZero
199*10465441SEvalZero ret = lwip_close(s);
200*10465441SEvalZero fail_unless(ret == 0);
201*10465441SEvalZero ret = lwip_close(s3);
202*10465441SEvalZero fail_unless(ret == 0);
203*10465441SEvalZero }
204*10465441SEvalZero
205*10465441SEvalZero /* Try to step through all sockets functions once...
206*10465441SEvalZero */
START_TEST(test_sockets_allfunctions_basic)207*10465441SEvalZero START_TEST(test_sockets_allfunctions_basic)
208*10465441SEvalZero {
209*10465441SEvalZero LWIP_UNUSED_ARG(_i);
210*10465441SEvalZero #if LWIP_IPV4
211*10465441SEvalZero test_sockets_allfunctions_basic_domain(AF_INET);
212*10465441SEvalZero #endif
213*10465441SEvalZero #if LWIP_IPV6
214*10465441SEvalZero test_sockets_allfunctions_basic_domain(AF_INET6);
215*10465441SEvalZero #endif
216*10465441SEvalZero }
217*10465441SEvalZero END_TEST
218*10465441SEvalZero
test_sockets_init_loopback_addr(int domain,struct sockaddr_storage * addr_st,socklen_t * sz)219*10465441SEvalZero static void test_sockets_init_loopback_addr(int domain, struct sockaddr_storage *addr_st, socklen_t *sz)
220*10465441SEvalZero {
221*10465441SEvalZero memset(addr_st, 0, sizeof(*addr_st));
222*10465441SEvalZero switch(domain) {
223*10465441SEvalZero #if LWIP_IPV6
224*10465441SEvalZero case AF_INET6: {
225*10465441SEvalZero struct sockaddr_in6 *addr = (struct sockaddr_in6*)addr_st;
226*10465441SEvalZero struct in6_addr lo6 = IN6ADDR_LOOPBACK_INIT;
227*10465441SEvalZero addr->sin6_family = AF_INET6;
228*10465441SEvalZero addr->sin6_port = 0; /* use ephemeral port */
229*10465441SEvalZero addr->sin6_addr = lo6;
230*10465441SEvalZero *sz = sizeof(*addr);
231*10465441SEvalZero }
232*10465441SEvalZero break;
233*10465441SEvalZero #endif /* LWIP_IPV6 */
234*10465441SEvalZero #if LWIP_IPV4
235*10465441SEvalZero case AF_INET: {
236*10465441SEvalZero struct sockaddr_in *addr = (struct sockaddr_in*)addr_st;
237*10465441SEvalZero addr->sin_family = AF_INET;
238*10465441SEvalZero addr->sin_port = 0; /* use ephemeral port */
239*10465441SEvalZero addr->sin_addr.s_addr = PP_HTONL(INADDR_LOOPBACK);
240*10465441SEvalZero *sz = sizeof(*addr);
241*10465441SEvalZero }
242*10465441SEvalZero break;
243*10465441SEvalZero #endif /* LWIP_IPV4 */
244*10465441SEvalZero default:
245*10465441SEvalZero *sz = 0;
246*10465441SEvalZero fail();
247*10465441SEvalZero break;
248*10465441SEvalZero }
249*10465441SEvalZero }
250*10465441SEvalZero
test_sockets_msgapi_update_iovs(struct msghdr * msg,size_t bytes)251*10465441SEvalZero static void test_sockets_msgapi_update_iovs(struct msghdr *msg, size_t bytes)
252*10465441SEvalZero {
253*10465441SEvalZero int i;
254*10465441SEvalZero
255*10465441SEvalZero /* note: this modifies the underyling iov_base and iov_len for a partial
256*10465441SEvalZero read for an individual vector. This updates the msg->msg_iov pointer
257*10465441SEvalZero to skip fully consumed vecotrs */
258*10465441SEvalZero
259*10465441SEvalZero /* process fully consumed vectors */
260*10465441SEvalZero for (i = 0; i < msg->msg_iovlen; i++) {
261*10465441SEvalZero if (msg->msg_iov[i].iov_len <= bytes) {
262*10465441SEvalZero /* reduce bytes by amount of this vector */
263*10465441SEvalZero bytes -= msg->msg_iov[i].iov_len;
264*10465441SEvalZero } else {
265*10465441SEvalZero break; /* iov not fully consumed */
266*10465441SEvalZero }
267*10465441SEvalZero }
268*10465441SEvalZero
269*10465441SEvalZero /* slide down over fully consumed vectors */
270*10465441SEvalZero msg->msg_iov = &msg->msg_iov[i];
271*10465441SEvalZero msg->msg_iovlen -= i;
272*10465441SEvalZero
273*10465441SEvalZero /* update new first vector with any remaining amount */
274*10465441SEvalZero msg->msg_iov[0].iov_base = ((u8_t *)msg->msg_iov[0].iov_base + bytes);
275*10465441SEvalZero msg->msg_iov[0].iov_len -= bytes;
276*10465441SEvalZero }
277*10465441SEvalZero
test_sockets_msgapi_tcp(int domain)278*10465441SEvalZero static void test_sockets_msgapi_tcp(int domain)
279*10465441SEvalZero {
280*10465441SEvalZero #define BUF_SZ (TCP_SND_BUF/4)
281*10465441SEvalZero #define TOTAL_DATA_SZ (BUF_SZ*8) /* ~(TCP_SND_BUF*2) that accounts for integer rounding */
282*10465441SEvalZero #define NEED_TRAILER (BUF_SZ % 4 != 0)
283*10465441SEvalZero int listnr, s1, s2, i, ret, opt;
284*10465441SEvalZero int bytes_written, bytes_read;
285*10465441SEvalZero struct sockaddr_storage addr_storage;
286*10465441SEvalZero socklen_t addr_size;
287*10465441SEvalZero struct iovec siovs[8];
288*10465441SEvalZero struct msghdr smsg;
289*10465441SEvalZero u8_t * snd_buf;
290*10465441SEvalZero struct iovec riovs[5];
291*10465441SEvalZero struct iovec riovs_tmp[5];
292*10465441SEvalZero struct msghdr rmsg;
293*10465441SEvalZero u8_t * rcv_buf;
294*10465441SEvalZero int rcv_off;
295*10465441SEvalZero int rcv_trailer = 0;
296*10465441SEvalZero u8_t val;
297*10465441SEvalZero
298*10465441SEvalZero test_sockets_init_loopback_addr(domain, &addr_storage, &addr_size);
299*10465441SEvalZero
300*10465441SEvalZero listnr = test_sockets_alloc_socket_nonblocking(domain, SOCK_STREAM);
301*10465441SEvalZero fail_unless(listnr >= 0);
302*10465441SEvalZero s1 = test_sockets_alloc_socket_nonblocking(domain, SOCK_STREAM);
303*10465441SEvalZero fail_unless(s1 >= 0);
304*10465441SEvalZero
305*10465441SEvalZero /* setup a listener socket on loopback with ephemeral port */
306*10465441SEvalZero ret = lwip_bind(listnr, (struct sockaddr*)&addr_storage, addr_size);
307*10465441SEvalZero fail_unless(ret == 0);
308*10465441SEvalZero ret = lwip_listen(listnr, 0);
309*10465441SEvalZero fail_unless(ret == 0);
310*10465441SEvalZero
311*10465441SEvalZero /* update address with ephemeral port */
312*10465441SEvalZero ret = lwip_getsockname(listnr, (struct sockaddr*)&addr_storage, &addr_size);
313*10465441SEvalZero fail_unless(ret == 0);
314*10465441SEvalZero
315*10465441SEvalZero /* connect, won't complete until we accept it */
316*10465441SEvalZero ret = lwip_connect(s1, (struct sockaddr*)&addr_storage, addr_size);
317*10465441SEvalZero fail_unless(ret == -1);
318*10465441SEvalZero fail_unless(errno == EINPROGRESS);
319*10465441SEvalZero
320*10465441SEvalZero while (tcpip_thread_poll_one());
321*10465441SEvalZero
322*10465441SEvalZero /* accept, creating the other side of the connection */
323*10465441SEvalZero s2 = lwip_accept(listnr, NULL, NULL);
324*10465441SEvalZero fail_unless(s2 >= 0);
325*10465441SEvalZero
326*10465441SEvalZero /* double check s1 is connected */
327*10465441SEvalZero ret = lwip_connect(s1, (struct sockaddr*)&addr_storage, addr_size);
328*10465441SEvalZero fail_unless(ret == -1);
329*10465441SEvalZero fail_unless(errno == EISCONN);
330*10465441SEvalZero
331*10465441SEvalZero /* set s2 to non-blocking, not inherited from listener */
332*10465441SEvalZero opt = lwip_fcntl(s2, F_GETFL, 0);
333*10465441SEvalZero fail_unless(opt == 6);
334*10465441SEvalZero opt = O_NONBLOCK;
335*10465441SEvalZero ret = lwip_fcntl(s2, F_SETFL, opt);
336*10465441SEvalZero fail_unless(ret == 0);
337*10465441SEvalZero
338*10465441SEvalZero /* we are done with listener, close it */
339*10465441SEvalZero ret = lwip_close(listnr);
340*10465441SEvalZero fail_unless(ret == 0);
341*10465441SEvalZero
342*10465441SEvalZero /* allocate a buffer for a stream of incrementing hex (0x00..0xFF) which we will use
343*10465441SEvalZero to create an input vector set that is larger than the TCP's send buffer. This will
344*10465441SEvalZero force execution of the partial IO vector send case */
345*10465441SEvalZero snd_buf = (u8_t*)mem_malloc(BUF_SZ);
346*10465441SEvalZero val = 0x00;
347*10465441SEvalZero fail_unless(snd_buf != NULL);
348*10465441SEvalZero for (i = 0; i < BUF_SZ; i++,val++) {
349*10465441SEvalZero snd_buf[i] = val;
350*10465441SEvalZero }
351*10465441SEvalZero
352*10465441SEvalZero /* send the buffer 8 times in one message, equating to TOTAL_DATA_SZ */
353*10465441SEvalZero for (i = 0; i < 8; i++) {
354*10465441SEvalZero siovs[i].iov_base = snd_buf;
355*10465441SEvalZero siovs[i].iov_len = BUF_SZ;
356*10465441SEvalZero }
357*10465441SEvalZero
358*10465441SEvalZero /* allocate a receive buffer, same size as snd_buf for easy verification */
359*10465441SEvalZero rcv_buf = (u8_t*)mem_calloc(1, BUF_SZ);
360*10465441SEvalZero fail_unless(rcv_buf != NULL);
361*10465441SEvalZero /* split across iovs */
362*10465441SEvalZero for (i = 0; i < 4; i++) {
363*10465441SEvalZero riovs[i].iov_base = &rcv_buf[i*(BUF_SZ/4)];
364*10465441SEvalZero riovs[i].iov_len = BUF_SZ/4;
365*10465441SEvalZero }
366*10465441SEvalZero /* handling trailing bytes if buffer doesn't evenly divide by 4 */
367*10465441SEvalZero #if NEED_TRAILER
368*10465441SEvalZero if ((BUF_SZ % 4) != 0) {
369*10465441SEvalZero riovs[5].iov_base = &rcv_buf[4*(BUF_SZ/4)];
370*10465441SEvalZero riovs[5].iov_len = BUF_SZ - (4*(BUF_SZ/4));
371*10465441SEvalZero rcv_trailer = 1;
372*10465441SEvalZero }
373*10465441SEvalZero #endif /* NEED_TRAILER */
374*10465441SEvalZero
375*10465441SEvalZero /* we use a copy of riovs since we'll be modifying base and len during
376*10465441SEvalZero receiving. This gives us an easy way to reset the iovs for next recvmsg */
377*10465441SEvalZero memcpy(riovs_tmp, riovs, sizeof(riovs));
378*10465441SEvalZero
379*10465441SEvalZero memset(&smsg, 0, sizeof(smsg));
380*10465441SEvalZero smsg.msg_iov = siovs;
381*10465441SEvalZero smsg.msg_iovlen = 8;
382*10465441SEvalZero
383*10465441SEvalZero memset(&rmsg, 0, sizeof(rmsg));
384*10465441SEvalZero rmsg.msg_iov = riovs_tmp;
385*10465441SEvalZero rmsg.msg_iovlen = (rcv_trailer ? 5 : 4);
386*10465441SEvalZero
387*10465441SEvalZero bytes_written = 0;
388*10465441SEvalZero bytes_read = 0;
389*10465441SEvalZero rcv_off = 0;
390*10465441SEvalZero
391*10465441SEvalZero while (bytes_written < TOTAL_DATA_SZ && (bytes_read < TOTAL_DATA_SZ)) {
392*10465441SEvalZero /* send data */
393*10465441SEvalZero if (bytes_written < TOTAL_DATA_SZ) {
394*10465441SEvalZero ret = lwip_sendmsg(s1, &smsg, 0);
395*10465441SEvalZero /* note: since we always receive after sending, there will be open
396*10465441SEvalZero space in the send buffer */
397*10465441SEvalZero fail_unless(ret > 0);
398*10465441SEvalZero
399*10465441SEvalZero bytes_written += ret;
400*10465441SEvalZero if (bytes_written < TOTAL_DATA_SZ) {
401*10465441SEvalZero test_sockets_msgapi_update_iovs(&smsg, (size_t)ret);
402*10465441SEvalZero }
403*10465441SEvalZero }
404*10465441SEvalZero
405*10465441SEvalZero while (tcpip_thread_poll_one());
406*10465441SEvalZero
407*10465441SEvalZero /* receive and verify data */
408*10465441SEvalZero do {
409*10465441SEvalZero if (bytes_read < TOTAL_DATA_SZ) {
410*10465441SEvalZero ret = lwip_recvmsg(s2, &rmsg, 0);
411*10465441SEvalZero fail_unless(ret > 0 || (ret == -1 && errno == EWOULDBLOCK));
412*10465441SEvalZero
413*10465441SEvalZero if (ret > 0) {
414*10465441SEvalZero rcv_off += ret;
415*10465441SEvalZero /* we have received a full buffer */
416*10465441SEvalZero if (rcv_off == BUF_SZ) {
417*10465441SEvalZero /* note: since iovs are just pointers, compare underlying buf */
418*10465441SEvalZero fail_unless(!memcmp(snd_buf, rcv_buf, BUF_SZ));
419*10465441SEvalZero bytes_read += BUF_SZ;
420*10465441SEvalZero /* reset receive state for next buffer */
421*10465441SEvalZero rcv_off = 0;
422*10465441SEvalZero memset(rcv_buf, 0, BUF_SZ);
423*10465441SEvalZero memcpy(riovs_tmp, riovs, sizeof(riovs));
424*10465441SEvalZero rmsg.msg_iov = riovs_tmp;
425*10465441SEvalZero rmsg.msg_iovlen = (rcv_trailer ? 5 : 4);
426*10465441SEvalZero } else { /* partial read */
427*10465441SEvalZero test_sockets_msgapi_update_iovs(&rmsg, (size_t)ret);
428*10465441SEvalZero }
429*10465441SEvalZero }
430*10465441SEvalZero } else {
431*10465441SEvalZero break;
432*10465441SEvalZero }
433*10465441SEvalZero } while(ret > 0);
434*10465441SEvalZero }
435*10465441SEvalZero
436*10465441SEvalZero ret = lwip_close(s1);
437*10465441SEvalZero fail_unless(ret == 0);
438*10465441SEvalZero ret = lwip_close(s2);
439*10465441SEvalZero fail_unless(ret == 0);
440*10465441SEvalZero mem_free(snd_buf);
441*10465441SEvalZero mem_free(rcv_buf);
442*10465441SEvalZero }
443*10465441SEvalZero
test_sockets_msgapi_udp_send_recv_loop(int s,struct msghdr * smsg,struct msghdr * rmsg)444*10465441SEvalZero static void test_sockets_msgapi_udp_send_recv_loop(int s, struct msghdr *smsg, struct msghdr *rmsg)
445*10465441SEvalZero {
446*10465441SEvalZero int i, ret;
447*10465441SEvalZero
448*10465441SEvalZero /* send/receive our datagram of IO vectors 10 times */
449*10465441SEvalZero for (i = 0; i < 10; i++) {
450*10465441SEvalZero ret = lwip_sendmsg(s, smsg, 0);
451*10465441SEvalZero fail_unless(ret == 4);
452*10465441SEvalZero
453*10465441SEvalZero while (tcpip_thread_poll_one());
454*10465441SEvalZero
455*10465441SEvalZero /* receive the datagram split across 4 buffers */
456*10465441SEvalZero ret = lwip_recvmsg(s, rmsg, 0);
457*10465441SEvalZero fail_unless(ret == 4);
458*10465441SEvalZero
459*10465441SEvalZero /* verify data */
460*10465441SEvalZero fail_unless(*((u8_t*)rmsg->msg_iov[0].iov_base) == 0xDE);
461*10465441SEvalZero fail_unless(*((u8_t*)rmsg->msg_iov[1].iov_base) == 0xAD);
462*10465441SEvalZero fail_unless(*((u8_t*)rmsg->msg_iov[2].iov_base) == 0xBE);
463*10465441SEvalZero fail_unless(*((u8_t*)rmsg->msg_iov[3].iov_base) == 0xEF);
464*10465441SEvalZero
465*10465441SEvalZero /* clear rcv_buf to ensure no data is being skipped */
466*10465441SEvalZero *((u8_t*)rmsg->msg_iov[0].iov_base) = 0x00;
467*10465441SEvalZero *((u8_t*)rmsg->msg_iov[1].iov_base) = 0x00;
468*10465441SEvalZero *((u8_t*)rmsg->msg_iov[2].iov_base) = 0x00;
469*10465441SEvalZero *((u8_t*)rmsg->msg_iov[3].iov_base) = 0x00;
470*10465441SEvalZero }
471*10465441SEvalZero }
472*10465441SEvalZero
test_sockets_msgapi_udp(int domain)473*10465441SEvalZero static void test_sockets_msgapi_udp(int domain)
474*10465441SEvalZero {
475*10465441SEvalZero int s, i, ret;
476*10465441SEvalZero struct sockaddr_storage addr_storage;
477*10465441SEvalZero socklen_t addr_size;
478*10465441SEvalZero struct iovec riovs[4];
479*10465441SEvalZero struct msghdr rmsg;
480*10465441SEvalZero u8_t rcv_buf[4];
481*10465441SEvalZero struct iovec siovs[4];
482*10465441SEvalZero struct msghdr smsg;
483*10465441SEvalZero u8_t snd_buf[4] = {0xDE, 0xAD, 0xBE, 0xEF};
484*10465441SEvalZero
485*10465441SEvalZero /* initialize IO vectors with data */
486*10465441SEvalZero for (i = 0; i < 4; i++) {
487*10465441SEvalZero siovs[i].iov_base = &snd_buf[i];
488*10465441SEvalZero siovs[i].iov_len = sizeof(u8_t);
489*10465441SEvalZero riovs[i].iov_base = &rcv_buf[i];
490*10465441SEvalZero riovs[i].iov_len = sizeof(u8_t);
491*10465441SEvalZero }
492*10465441SEvalZero
493*10465441SEvalZero test_sockets_init_loopback_addr(domain, &addr_storage, &addr_size);
494*10465441SEvalZero
495*10465441SEvalZero s = test_sockets_alloc_socket_nonblocking(domain, SOCK_DGRAM);
496*10465441SEvalZero fail_unless(s >= 0);
497*10465441SEvalZero
498*10465441SEvalZero ret = lwip_bind(s, (struct sockaddr*)&addr_storage, addr_size);
499*10465441SEvalZero fail_unless(ret == 0);
500*10465441SEvalZero
501*10465441SEvalZero /* Update addr with epehermal port */
502*10465441SEvalZero ret = lwip_getsockname(s, (struct sockaddr*)&addr_storage, &addr_size);
503*10465441SEvalZero fail_unless(ret == 0);
504*10465441SEvalZero switch(domain) {
505*10465441SEvalZero #if LWIP_IPV6
506*10465441SEvalZero case AF_INET6:
507*10465441SEvalZero fail_unless(addr_size == sizeof(struct sockaddr_in6));
508*10465441SEvalZero break;
509*10465441SEvalZero #endif /* LWIP_IPV6 */
510*10465441SEvalZero #if LWIP_IPV4
511*10465441SEvalZero case AF_INET:
512*10465441SEvalZero fail_unless(addr_size == sizeof(struct sockaddr_in));
513*10465441SEvalZero break;
514*10465441SEvalZero #endif /* LWIP_IPV6 */
515*10465441SEvalZero default:
516*10465441SEvalZero fail();
517*10465441SEvalZero break;
518*10465441SEvalZero }
519*10465441SEvalZero
520*10465441SEvalZero /* send and receive the datagram in 4 pieces */
521*10465441SEvalZero memset(&smsg, 0, sizeof(smsg));
522*10465441SEvalZero smsg.msg_iov = siovs;
523*10465441SEvalZero smsg.msg_iovlen = 4;
524*10465441SEvalZero memset(&rmsg, 0, sizeof(rmsg));
525*10465441SEvalZero rmsg.msg_iov = riovs;
526*10465441SEvalZero rmsg.msg_iovlen = 4;
527*10465441SEvalZero
528*10465441SEvalZero /* perform a sendmsg with remote host (self) */
529*10465441SEvalZero smsg.msg_name = &addr_storage;
530*10465441SEvalZero smsg.msg_namelen = addr_size;
531*10465441SEvalZero
532*10465441SEvalZero test_sockets_msgapi_udp_send_recv_loop(s, &smsg, &rmsg);
533*10465441SEvalZero
534*10465441SEvalZero /* Connect to self, allowing us to not pass message name */
535*10465441SEvalZero ret = lwip_connect(s, (struct sockaddr*)&addr_storage, addr_size);
536*10465441SEvalZero fail_unless(ret == 0);
537*10465441SEvalZero
538*10465441SEvalZero smsg.msg_name = NULL;
539*10465441SEvalZero smsg.msg_namelen = 0;
540*10465441SEvalZero
541*10465441SEvalZero test_sockets_msgapi_udp_send_recv_loop(s, &smsg, &rmsg);
542*10465441SEvalZero
543*10465441SEvalZero ret = lwip_close(s);
544*10465441SEvalZero fail_unless(ret == 0);
545*10465441SEvalZero }
546*10465441SEvalZero
547*10465441SEvalZero #if LWIP_IPV4
test_sockets_msgapi_cmsg(int domain)548*10465441SEvalZero static void test_sockets_msgapi_cmsg(int domain)
549*10465441SEvalZero {
550*10465441SEvalZero int s, ret, enable;
551*10465441SEvalZero struct sockaddr_storage addr_storage;
552*10465441SEvalZero socklen_t addr_size;
553*10465441SEvalZero struct iovec iov;
554*10465441SEvalZero struct msghdr msg;
555*10465441SEvalZero struct cmsghdr *cmsg;
556*10465441SEvalZero struct in_pktinfo *pktinfo;
557*10465441SEvalZero u8_t rcv_buf[4];
558*10465441SEvalZero u8_t snd_buf[4] = {0xDE, 0xAD, 0xBE, 0xEF};
559*10465441SEvalZero u8_t cmsg_buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
560*10465441SEvalZero
561*10465441SEvalZero test_sockets_init_loopback_addr(domain, &addr_storage, &addr_size);
562*10465441SEvalZero
563*10465441SEvalZero s = test_sockets_alloc_socket_nonblocking(domain, SOCK_DGRAM);
564*10465441SEvalZero fail_unless(s >= 0);
565*10465441SEvalZero
566*10465441SEvalZero ret = lwip_bind(s, (struct sockaddr*)&addr_storage, addr_size);
567*10465441SEvalZero fail_unless(ret == 0);
568*10465441SEvalZero
569*10465441SEvalZero /* Update addr with epehermal port */
570*10465441SEvalZero ret = lwip_getsockname(s, (struct sockaddr*)&addr_storage, &addr_size);
571*10465441SEvalZero fail_unless(ret == 0);
572*10465441SEvalZero
573*10465441SEvalZero enable = 1;
574*10465441SEvalZero ret = lwip_setsockopt(s, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable));
575*10465441SEvalZero fail_unless(ret == 0);
576*10465441SEvalZero
577*10465441SEvalZero /* Receive full message, including control message */
578*10465441SEvalZero iov.iov_base = rcv_buf;
579*10465441SEvalZero iov.iov_len = sizeof(rcv_buf);
580*10465441SEvalZero msg.msg_control = cmsg_buf;
581*10465441SEvalZero msg.msg_controllen = sizeof(cmsg_buf);
582*10465441SEvalZero msg.msg_flags = 0;
583*10465441SEvalZero msg.msg_iov = &iov;
584*10465441SEvalZero msg.msg_iovlen = 1;
585*10465441SEvalZero msg.msg_name = NULL;
586*10465441SEvalZero msg.msg_namelen = 0;
587*10465441SEvalZero
588*10465441SEvalZero memset(rcv_buf, 0, sizeof(rcv_buf));
589*10465441SEvalZero ret = lwip_sendto(s, snd_buf, sizeof(snd_buf), 0, (struct sockaddr*)&addr_storage, addr_size);
590*10465441SEvalZero fail_unless(ret == sizeof(snd_buf));
591*10465441SEvalZero
592*10465441SEvalZero tcpip_thread_poll_one();
593*10465441SEvalZero
594*10465441SEvalZero ret = lwip_recvmsg(s, &msg, 0);
595*10465441SEvalZero fail_unless(ret == sizeof(rcv_buf));
596*10465441SEvalZero fail_unless(!memcmp(rcv_buf, snd_buf, sizeof(rcv_buf)));
597*10465441SEvalZero
598*10465441SEvalZero /* Verify message header */
599*10465441SEvalZero cmsg = CMSG_FIRSTHDR(&msg);
600*10465441SEvalZero fail_unless(cmsg != NULL);
601*10465441SEvalZero fail_unless(cmsg->cmsg_len > 0);
602*10465441SEvalZero fail_unless(cmsg->cmsg_level == IPPROTO_IP);
603*10465441SEvalZero fail_unless(cmsg->cmsg_type == IP_PKTINFO);
604*10465441SEvalZero
605*10465441SEvalZero /* Verify message data */
606*10465441SEvalZero pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
607*10465441SEvalZero /* We only have loopback interface enabled */
608*10465441SEvalZero fail_unless(pktinfo->ipi_ifindex == 1);
609*10465441SEvalZero fail_unless(pktinfo->ipi_addr.s_addr == PP_HTONL(INADDR_LOOPBACK));
610*10465441SEvalZero
611*10465441SEvalZero /* Verify there are no additional messages */
612*10465441SEvalZero cmsg = CMSG_NXTHDR(&msg, cmsg);
613*10465441SEvalZero fail_unless(cmsg == NULL);
614*10465441SEvalZero
615*10465441SEvalZero /* Send datagram again, testing truncation */
616*10465441SEvalZero memset(rcv_buf, 0, sizeof(rcv_buf));
617*10465441SEvalZero ret = lwip_sendto(s, snd_buf, sizeof(snd_buf), 0, (struct sockaddr*)&addr_storage, addr_size);
618*10465441SEvalZero fail_unless(ret == sizeof(snd_buf));
619*10465441SEvalZero
620*10465441SEvalZero tcpip_thread_poll_one();
621*10465441SEvalZero
622*10465441SEvalZero msg.msg_controllen = 1;
623*10465441SEvalZero msg.msg_flags = 0;
624*10465441SEvalZero ret = lwip_recvmsg(s, &msg, 0);
625*10465441SEvalZero fail_unless(ret == sizeof(rcv_buf));
626*10465441SEvalZero fail_unless(!memcmp(rcv_buf, snd_buf, sizeof(rcv_buf)));
627*10465441SEvalZero /* Ensure truncation was returned */
628*10465441SEvalZero fail_unless(msg.msg_flags & MSG_CTRUNC);
629*10465441SEvalZero /* Ensure no control messages were returned */
630*10465441SEvalZero fail_unless(msg.msg_controllen == 0);
631*10465441SEvalZero
632*10465441SEvalZero ret = lwip_close(s);
633*10465441SEvalZero fail_unless(ret == 0);
634*10465441SEvalZero }
635*10465441SEvalZero #endif /* LWIP_IPV4 */
636*10465441SEvalZero
START_TEST(test_sockets_msgapis)637*10465441SEvalZero START_TEST(test_sockets_msgapis)
638*10465441SEvalZero {
639*10465441SEvalZero LWIP_UNUSED_ARG(_i);
640*10465441SEvalZero #if LWIP_IPV4
641*10465441SEvalZero test_sockets_msgapi_udp(AF_INET);
642*10465441SEvalZero test_sockets_msgapi_tcp(AF_INET);
643*10465441SEvalZero test_sockets_msgapi_cmsg(AF_INET);
644*10465441SEvalZero #endif
645*10465441SEvalZero #if LWIP_IPV6
646*10465441SEvalZero test_sockets_msgapi_udp(AF_INET6);
647*10465441SEvalZero test_sockets_msgapi_tcp(AF_INET6);
648*10465441SEvalZero #endif
649*10465441SEvalZero }
650*10465441SEvalZero END_TEST
651*10465441SEvalZero
START_TEST(test_sockets_select)652*10465441SEvalZero START_TEST(test_sockets_select)
653*10465441SEvalZero {
654*10465441SEvalZero #if LWIP_SOCKET_SELECT
655*10465441SEvalZero int s;
656*10465441SEvalZero int ret;
657*10465441SEvalZero fd_set readset;
658*10465441SEvalZero fd_set writeset;
659*10465441SEvalZero fd_set errset;
660*10465441SEvalZero struct timeval tv;
661*10465441SEvalZero
662*10465441SEvalZero fail_unless(test_sockets_get_used_count() == 0);
663*10465441SEvalZero
664*10465441SEvalZero s = lwip_socket(AF_INET, SOCK_STREAM, 0);
665*10465441SEvalZero fail_unless(s >= 0);
666*10465441SEvalZero fail_unless(test_sockets_get_used_count() == 0);
667*10465441SEvalZero
668*10465441SEvalZero FD_ZERO(&readset);
669*10465441SEvalZero FD_SET(s, &readset);
670*10465441SEvalZero FD_ZERO(&writeset);
671*10465441SEvalZero FD_SET(s, &writeset);
672*10465441SEvalZero FD_ZERO(&errset);
673*10465441SEvalZero FD_SET(s, &errset);
674*10465441SEvalZero
675*10465441SEvalZero tv.tv_sec = tv.tv_usec = 0;
676*10465441SEvalZero ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv);
677*10465441SEvalZero fail_unless(ret == 0);
678*10465441SEvalZero fail_unless(test_sockets_get_used_count() == 0);
679*10465441SEvalZero
680*10465441SEvalZero ret = lwip_close(s);
681*10465441SEvalZero fail_unless(ret == 0);
682*10465441SEvalZero
683*10465441SEvalZero #endif
684*10465441SEvalZero LWIP_UNUSED_ARG(_i);
685*10465441SEvalZero }
686*10465441SEvalZero END_TEST
687*10465441SEvalZero
START_TEST(test_sockets_recv_after_rst)688*10465441SEvalZero START_TEST(test_sockets_recv_after_rst)
689*10465441SEvalZero {
690*10465441SEvalZero int sl, sact;
691*10465441SEvalZero int spass = -1;
692*10465441SEvalZero int ret;
693*10465441SEvalZero struct sockaddr_in sa_listen;
694*10465441SEvalZero const u16_t port = 1234;
695*10465441SEvalZero int arg;
696*10465441SEvalZero const char txbuf[] = "something";
697*10465441SEvalZero char rxbuf[16];
698*10465441SEvalZero struct lwip_sock *sact_sock;
699*10465441SEvalZero int err;
700*10465441SEvalZero LWIP_UNUSED_ARG(_i);
701*10465441SEvalZero
702*10465441SEvalZero fail_unless(test_sockets_get_used_count() == 0);
703*10465441SEvalZero
704*10465441SEvalZero memset(&sa_listen, 0, sizeof(sa_listen));
705*10465441SEvalZero sa_listen.sin_family = AF_INET;
706*10465441SEvalZero sa_listen.sin_port = PP_HTONS(port);
707*10465441SEvalZero sa_listen.sin_addr.s_addr = PP_HTONL(INADDR_LOOPBACK);
708*10465441SEvalZero
709*10465441SEvalZero /* set up the listener */
710*10465441SEvalZero sl = lwip_socket(AF_INET, SOCK_STREAM, 0);
711*10465441SEvalZero fail_unless(sl >= 0);
712*10465441SEvalZero fail_unless(test_sockets_get_used_count() == 0);
713*10465441SEvalZero
714*10465441SEvalZero ret = lwip_bind(sl, (struct sockaddr *)&sa_listen, sizeof(sa_listen));
715*10465441SEvalZero fail_unless(ret == 0);
716*10465441SEvalZero ret = lwip_listen(sl, 0);
717*10465441SEvalZero fail_unless(ret == 0);
718*10465441SEvalZero
719*10465441SEvalZero /* set up the client */
720*10465441SEvalZero sact = lwip_socket(AF_INET, SOCK_STREAM, 0);
721*10465441SEvalZero fail_unless(sact >= 0);
722*10465441SEvalZero fail_unless(test_sockets_get_used_count() == 0);
723*10465441SEvalZero /* set the client to nonblocking to simplify this test */
724*10465441SEvalZero arg = 1;
725*10465441SEvalZero ret = lwip_ioctl(sact, FIONBIO, &arg);
726*10465441SEvalZero fail_unless(ret == 0);
727*10465441SEvalZero /* connect */
728*10465441SEvalZero do {
729*10465441SEvalZero ret = lwip_connect(sact, (struct sockaddr *)&sa_listen, sizeof(sa_listen));
730*10465441SEvalZero err = errno;
731*10465441SEvalZero fail_unless((ret == 0) || (ret == -1));
732*10465441SEvalZero if (ret != 0) {
733*10465441SEvalZero if (err == EISCONN) {
734*10465441SEvalZero /* Although this is not valid, use EISCONN as an indicator for successful connection.
735*10465441SEvalZero This marks us as "connect phase is done". On error, we would either have a different
736*10465441SEvalZero errno code or "send" fails later... -> good enough for this test. */
737*10465441SEvalZero ret = 0;
738*10465441SEvalZero } else {
739*10465441SEvalZero fail_unless(err == EINPROGRESS);
740*10465441SEvalZero if (err != EINPROGRESS) {
741*10465441SEvalZero goto cleanup;
742*10465441SEvalZero }
743*10465441SEvalZero /* we're in progress: little side check: test for EALREADY */
744*10465441SEvalZero ret = lwip_connect(sact, (struct sockaddr *)&sa_listen, sizeof(sa_listen));
745*10465441SEvalZero err = errno;
746*10465441SEvalZero fail_unless(ret == -1);
747*10465441SEvalZero fail_unless(err == EALREADY);
748*10465441SEvalZero if ((ret != -1) || (err != EALREADY)) {
749*10465441SEvalZero goto cleanup;
750*10465441SEvalZero }
751*10465441SEvalZero }
752*10465441SEvalZero tcpip_thread_poll_one();
753*10465441SEvalZero tcpip_thread_poll_one();
754*10465441SEvalZero tcpip_thread_poll_one();
755*10465441SEvalZero tcpip_thread_poll_one();
756*10465441SEvalZero }
757*10465441SEvalZero } while (ret != 0);
758*10465441SEvalZero fail_unless(ret == 0);
759*10465441SEvalZero
760*10465441SEvalZero /* accept the server connection part */
761*10465441SEvalZero spass = lwip_accept(sl, NULL, NULL);
762*10465441SEvalZero fail_unless(spass >= 0);
763*10465441SEvalZero
764*10465441SEvalZero /* write data from client */
765*10465441SEvalZero ret = lwip_send(sact, txbuf, sizeof(txbuf), 0);
766*10465441SEvalZero fail_unless(ret == sizeof(txbuf));
767*10465441SEvalZero
768*10465441SEvalZero tcpip_thread_poll_one();
769*10465441SEvalZero tcpip_thread_poll_one();
770*10465441SEvalZero
771*10465441SEvalZero /* issue RST (This is a HACK, don't try this in your own app!) */
772*10465441SEvalZero sact_sock = lwip_socket_dbg_get_socket(sact);
773*10465441SEvalZero fail_unless(sact_sock != NULL);
774*10465441SEvalZero if (sact_sock != NULL) {
775*10465441SEvalZero struct netconn *sact_conn = sact_sock->conn;
776*10465441SEvalZero fail_unless(sact_conn != NULL);
777*10465441SEvalZero if (sact_conn != NULL) {
778*10465441SEvalZero struct tcp_pcb *pcb = sact_conn->pcb.tcp;
779*10465441SEvalZero fail_unless(pcb != NULL);
780*10465441SEvalZero if (pcb != NULL) {
781*10465441SEvalZero tcp_rst(pcb, pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
782*10465441SEvalZero pcb->local_port, pcb->remote_port);
783*10465441SEvalZero }
784*10465441SEvalZero }
785*10465441SEvalZero }
786*10465441SEvalZero tcpip_thread_poll_one();
787*10465441SEvalZero tcpip_thread_poll_one();
788*10465441SEvalZero
789*10465441SEvalZero /* expect to receive data first */
790*10465441SEvalZero ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
791*10465441SEvalZero fail_unless(ret > 0);
792*10465441SEvalZero tcpip_thread_poll_one();
793*10465441SEvalZero tcpip_thread_poll_one();
794*10465441SEvalZero
795*10465441SEvalZero /* expect to receive RST indication */
796*10465441SEvalZero ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
797*10465441SEvalZero fail_unless(ret == -1);
798*10465441SEvalZero err = errno;
799*10465441SEvalZero fail_unless(err == ECONNRESET);
800*10465441SEvalZero tcpip_thread_poll_one();
801*10465441SEvalZero tcpip_thread_poll_one();
802*10465441SEvalZero
803*10465441SEvalZero /* expect to receive ENOTCONN indication */
804*10465441SEvalZero ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
805*10465441SEvalZero fail_unless(ret == -1);
806*10465441SEvalZero err = errno;
807*10465441SEvalZero fail_unless(err == ENOTCONN);
808*10465441SEvalZero tcpip_thread_poll_one();
809*10465441SEvalZero tcpip_thread_poll_one();
810*10465441SEvalZero
811*10465441SEvalZero /* expect to receive ENOTCONN indication */
812*10465441SEvalZero ret = lwip_recv(spass, rxbuf, sizeof(rxbuf), 0);
813*10465441SEvalZero fail_unless(ret == -1);
814*10465441SEvalZero err = errno;
815*10465441SEvalZero fail_unless(err == ENOTCONN);
816*10465441SEvalZero tcpip_thread_poll_one();
817*10465441SEvalZero tcpip_thread_poll_one();
818*10465441SEvalZero
819*10465441SEvalZero cleanup:
820*10465441SEvalZero ret = lwip_close(sl);
821*10465441SEvalZero fail_unless(ret == 0);
822*10465441SEvalZero ret = lwip_close(sact);
823*10465441SEvalZero fail_unless(ret == 0);
824*10465441SEvalZero if (spass >= 0) {
825*10465441SEvalZero ret = lwip_close(spass);
826*10465441SEvalZero fail_unless(ret == 0);
827*10465441SEvalZero }
828*10465441SEvalZero }
829*10465441SEvalZero END_TEST
830*10465441SEvalZero
831*10465441SEvalZero /** Create the suite including all tests for this module */
832*10465441SEvalZero Suite *
sockets_suite(void)833*10465441SEvalZero sockets_suite(void)
834*10465441SEvalZero {
835*10465441SEvalZero testfunc tests[] = {
836*10465441SEvalZero TESTFUNC(test_sockets_basics),
837*10465441SEvalZero TESTFUNC(test_sockets_allfunctions_basic),
838*10465441SEvalZero TESTFUNC(test_sockets_msgapis),
839*10465441SEvalZero TESTFUNC(test_sockets_select),
840*10465441SEvalZero TESTFUNC(test_sockets_recv_after_rst),
841*10465441SEvalZero };
842*10465441SEvalZero return create_suite("SOCKETS", tests, sizeof(tests)/sizeof(testfunc), sockets_setup, sockets_teardown);
843*10465441SEvalZero }
844*10465441SEvalZero
845*10465441SEvalZero #else /* LWIP_SOCKET */
846*10465441SEvalZero
847*10465441SEvalZero Suite *
sockets_suite(void)848*10465441SEvalZero sockets_suite(void)
849*10465441SEvalZero {
850*10465441SEvalZero return create_suite("SOCKETS", NULL, 0, NULL, NULL);
851*10465441SEvalZero }
852*10465441SEvalZero #endif /* LWIP_SOCKET */
853