1 /* This NetX test concentrates on the basic BSD TCP blocking operation. */
2 /* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */
3
4 #include "tx_api.h"
5 #include "nx_api.h"
6 #if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4)
7 #include "nx_icmpv6.h"
8 #include "nxd_bsd.h"
9 #define DEMO_STACK_SIZE 4096
10
11
12 /* Define the ThreadX and NetX object control blocks... */
13
14 static TX_THREAD ntest_0;
15 static TX_THREAD ntest_1;
16
17 static NX_PACKET_POOL pool_0;
18 static NX_IP ip_0;
19 static NX_IP ip_1;
20 static NX_TCP_SOCKET server_socket;
21 static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)];
22 static TX_SEMAPHORE sema_0;
23 static TX_SEMAPHORE sema_1;
24 #define BSD_THREAD_PRIORITY 2
25 #define NUM_CLIENTS 10
26 /* Define the counters used in the test application... */
27
28 static ULONG error_counter;
29 static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4];
30
31 /* Define thread prototypes. */
32
33 static void ntest_0_entry(ULONG thread_input);
34 static void ntest_1_entry(ULONG thread_input);
35 extern void test_control_return(UINT status);
36 extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
37 static void validate_bsd_structure(void);
38 extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS];
39 #ifdef FEATURE_NX_IPV6
40 static NXD_ADDRESS ipv6_address_ip0;
41 static NXD_ADDRESS ipv6_address_ip1;
42 #endif
43 static char *send_buffer = "Hello World";
44 static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"};
45 static char *response[4] = {"Response1", "Response2", "Response3", "Response4"};
46 static void validate_bsd_structure(void);
47 #ifdef __PRODUCT_NETXDUO__
48 static char large_msg[1000];
49 #endif
50 /* Define what the initial system looks like. */
51
52 #ifdef CTEST
test_application_define(void * first_unused_memory)53 VOID test_application_define(void *first_unused_memory)
54 #else
55 void netx_bsd_tcp_basic_blocking_test_application_define(void *first_unused_memory)
56 #endif
57 {
58
59 CHAR *pointer;
60 UINT status;
61
62
63 /* Setup the working pointer. */
64 pointer = (CHAR *) first_unused_memory;
65
66 error_counter = 0;
67
68 /* Create the main thread. */
69 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
70 pointer, DEMO_STACK_SIZE,
71 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
72
73 pointer = pointer + DEMO_STACK_SIZE;
74
75 /* Create the main thread. */
76 tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
77 pointer, DEMO_STACK_SIZE,
78 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
79
80 pointer = pointer + DEMO_STACK_SIZE;
81
82
83 /* Initialize the NetX system. */
84 nx_system_initialize();
85
86 /* Create a packet pool. */
87 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area));
88
89
90 if (status)
91 error_counter++;
92
93 /* Create an IP instance. */
94 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
95 pointer, 2048, 1);
96 pointer = pointer + 2048;
97
98 /* Create another IP instance. */
99 status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
100 pointer, 2048, 1);
101 pointer = pointer + 2048;
102 if (status)
103 error_counter++;
104
105 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
106 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
107 pointer = pointer + 1024;
108 if (status)
109 error_counter++;
110
111 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
112 status = nx_arp_enable(&ip_1, (void *) pointer, 1024);
113 pointer = pointer + 1024;
114 if (status)
115 error_counter++;
116
117 /* Enable TCP processing for both IP instances. */
118 status = nx_tcp_enable(&ip_0);
119 status += nx_tcp_enable(&ip_1);
120
121 /* Enable BSD */
122 status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY);
123
124 /* Check TCP enable status. */
125 if (status)
126 error_counter++;
127
128 status = tx_semaphore_create(&sema_0, "SEMA 0", 0);
129 status += tx_semaphore_create(&sema_1, "SEMA 1", 0);
130 if(status)
131 error_counter++;
132 }
133 typedef struct client_info_struct
134 {
135 int sockfd;
136 int message_id;
137 } client_info;
138
139 static client_info client_data[NUM_CLIENTS];
140 static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)];
141 static TX_THREAD helper_thread[NUM_CLIENTS];
142 #ifdef FEATURE_NX_IPV6
143 static ULONG stack_space6[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)];
144 static TX_THREAD helper_thread6[NUM_CLIENTS];
145 #endif
bsd_server_helper_thread_entry(ULONG thread_input)146 static VOID bsd_server_helper_thread_entry(ULONG thread_input)
147 {
148 int ret;
149 int sockfd, message_id;
150 char buf[30];
151 int sockaddr_len;
152 fd_set read_fds, write_fds, except_fds;
153 struct timeval wait_time;
154 #ifdef FEATURE_NX_IPV6
155 struct sockaddr_in6 remote_address;
156 #else
157 struct sockaddr_in remote_address;
158 #endif
159
160 sockfd = client_data[thread_input].sockfd;
161 message_id = client_data[thread_input].message_id;
162 /* Receive data from the client. */
163 if(message_id == 2)
164 {
165 #ifdef FEATURE_NX_IPV6
166 sockaddr_len = sizeof(struct sockaddr_in6);
167 #else
168 sockaddr_len = sizeof(struct sockaddr_in);
169 #endif
170 ret = recvfrom(sockfd, (char*)buf, sizeof(buf), 0, (struct sockaddr*)&remote_address, &sockaddr_len);
171
172 if(ret < 0)
173 error_counter++;
174 if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET)
175 {
176 if(sockaddr_len != sizeof(struct sockaddr_in))
177 error_counter++;
178 if(((struct sockaddr_in*)&remote_address) -> sin_family != AF_INET)
179 error_counter++;
180 if(((struct sockaddr_in*)&remote_address) -> sin_addr.s_addr != htonl(0x01020305))
181 error_counter++;
182 }
183 #ifdef FEATURE_NX_IPV6
184 else if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET6)
185 {
186 if(sockaddr_len != sizeof(struct sockaddr_in6))
187 error_counter++;
188 if((remote_address.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
189 (remote_address.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
190 (remote_address.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
191 (remote_address.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
192 error_counter++;
193 }
194 #endif
195 }
196 else
197 {
198
199 /* Peek message test. */
200 ret = recv(sockfd, buf, sizeof(buf), MSG_PEEK);
201
202 /* Validate the data. */
203 if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret))
204 error_counter++;
205
206 ret = recv(sockfd, buf, sizeof(buf), 0);
207 }
208 if(ret <= 0)
209 error_counter++;
210
211 /* Validate the data. */
212 if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret))
213 error_counter++;
214
215 /* Invoke recvfrom with MSG_DONTWAIT flag. */
216 ret = recvfrom(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&remote_address, &sockaddr_len);
217 if(ret >= 0)
218 error_counter++;
219 else if((errno != EWOULDBLOCK) || (errno != EAGAIN))
220 error_counter++;
221
222 /* Invoke recv with MSG_DONTWAIT flag. */
223 ret = recv(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT);
224 if(ret >= 0)
225 error_counter++;
226 else if((errno != EWOULDBLOCK) || (errno != EAGAIN))
227 error_counter++;
228
229 /* Send a response back. */
230 ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0);
231 if(ret != (int)strlen(response[message_id & 3]))
232 error_counter++;
233
234 tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE);
235
236 #ifdef __PRODUCT_NETXDUO__
237 /* Invoke send with MSG_DONTWAIT flag. The message is larger than tx_window. Partial data should be sent. */
238 ret = send(sockfd, large_msg, sizeof(large_msg), MSG_DONTWAIT);
239 if (ret <= 0)
240 error_counter++;
241 #endif
242
243 FD_ZERO(&read_fds);
244 FD_ZERO(&write_fds);
245 FD_ZERO(&except_fds);
246 FD_SET(sockfd, &read_fds);
247 FD_SET(sockfd, &write_fds);
248 FD_SET(sockfd, &except_fds);
249
250 ret = soc_close(sockfd);
251 if(ret < 0)
252 error_counter++;
253
254 wait_time.tv_sec = 1;
255 wait_time.tv_usec = 0;
256 select(sockfd + 1, &read_fds, &write_fds, &except_fds, &wait_time);
257 if((FD_ISSET(sockfd, &read_fds) && FD_ISSET(sockfd, &write_fds) && FD_ISSET(sockfd, &except_fds)) == 0)
258 error_counter++;
259
260 tx_semaphore_put(&sema_0);
261 return;
262 }
263
264
test_tcp_client4(void)265 static void test_tcp_client4(void)
266 {
267 int sockfd;
268 struct sockaddr_in remote_addr, local_addr;
269 #ifdef FEATURE_NX_IPV6
270 struct sockaddr_in6 local_addr6;
271 int port;
272 int sockfd1;
273 #endif
274 int bytes_sent;
275 int ret;
276 char buf;
277
278 sockfd = socket(AF_INET, SOCK_STREAM, 0);
279 if(sockfd < 0)
280 error_counter++;
281
282 local_addr.sin_family = AF_INET;
283 local_addr.sin_port = INADDR_ANY;
284 local_addr.sin_addr.s_addr = INADDR_ANY;
285
286 ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr));
287 if(ret < 0)
288 error_counter++;
289
290 remote_addr.sin_family = AF_INET;
291 remote_addr.sin_port = htons(12);
292 remote_addr.sin_addr.s_addr = htonl(0x01020305);
293
294 if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0)
295 error_counter++;
296
297 bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0);
298
299 if(bytes_sent != (int)strlen(send_buffer))
300 error_counter++;
301
302 #ifdef FEATURE_NX_IPV6
303 /* Get the port bind to any. */
304 port = nx_bsd_socket_array[sockfd - NX_BSD_SOCKFD_START].nx_bsd_socket_tcp_socket -> nx_tcp_socket_port;
305
306 sockfd1 = socket(AF_INET6, SOCK_STREAM, 0);
307 if(sockfd1 < 0)
308 error_counter++;
309
310 memset(&local_addr6, 0, sizeof(local_addr6));
311 local_addr6.sin6_family = AF_INET6;
312 local_addr6.sin6_port = htons(port);
313
314 /* Bind to the same port. */
315 ret = bind(sockfd1, (struct sockaddr*)&local_addr6, sizeof(local_addr6));
316 if(ret < 0)
317 error_counter++;
318
319 ret = soc_close(sockfd1);
320 if(ret < 0)
321 error_counter++;
322 #endif
323
324 /* Call recv before peer orderly shutdown. */
325 ret = recv(sockfd, &buf, 1, 0);
326 if (ret != 0)
327 error_counter++;
328
329 /* Make sure the other side gets the message. */
330 tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
331
332 /* Call recv after peer orderly shutdown. */
333 ret = recv(sockfd, &buf, 1, 0);
334 if (ret != 0)
335 error_counter++;
336
337 ret = soc_close(sockfd);
338 if(ret < 0)
339 error_counter++;
340
341 }
342
test_tcp_server4(void)343 static void test_tcp_server4(void)
344 {
345 int sockfd;
346 struct sockaddr_in remote_addr, local_addr;
347 int address_length;
348 int ret;
349 int newsock;
350 int i;
351 UINT status;
352
353
354 sockfd = socket(AF_INET, SOCK_STREAM, 0);
355 if(sockfd < 0)
356 error_counter++;
357
358 local_addr.sin_family = AF_INET;
359 local_addr.sin_port = htons(12345);
360 local_addr.sin_addr.s_addr = INADDR_ANY;
361
362 ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr));
363 if(ret < 0)
364 error_counter++;
365
366 ret = listen(sockfd, 5);
367 if(ret < 0)
368 error_counter++;
369
370 /* 3 iterations. */
371 for(i = 0; i < NUM_CLIENTS; i++)
372 {
373 address_length = sizeof(remote_addr);
374
375 newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length);
376
377 if(newsock <= 0)
378 error_counter++;
379 else if(address_length != sizeof(remote_addr))
380 error_counter++;
381 else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305)))
382 error_counter++;
383
384 address_length = sizeof(local_addr);
385 ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length);
386 if(ret < 0)
387 error_counter++;
388 else if(address_length != sizeof(local_addr))
389 error_counter++;
390 else if(local_addr.sin_family != AF_INET)
391 error_counter++;
392 else if(local_addr.sin_port != htons(12345))
393 error_counter++;
394 else if(local_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 4)))
395 error_counter++;
396
397 address_length = sizeof(remote_addr);
398 ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length);
399 if(ret < 0)
400 error_counter++;
401 else if(address_length != sizeof(remote_addr))
402 error_counter++;
403 else if(remote_addr.sin_family != AF_INET)
404 error_counter++;
405 else if(remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5)))
406 error_counter++;
407
408
409 /* Set the client data */
410 client_data[i].sockfd = newsock;
411 client_data[i].message_id = i;
412
413 /* Create a helper thread to handle the new socket. */
414 status = tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry,
415 i, stack_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
416 if(status != TX_SUCCESS)
417 error_counter++;
418
419 tx_thread_relinquish();
420 }
421
422 /* Close downt he socket. */
423 ret = soc_close(sockfd);
424 if(ret < 0)
425 error_counter++;
426
427 for(i = 0; i < NUM_CLIENTS; i++)
428 {
429
430 /* Wakeup server thread. */
431 tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
432 }
433 }
434
435
436 #ifdef FEATURE_NX_IPV6
test_tcp_client6(void)437 static void test_tcp_client6(void)
438 {
439 int sockfd;
440 struct sockaddr_in6 remote_addr;
441 int bytes_sent;
442 int ret;
443
444 sockfd = socket(AF_INET6, SOCK_STREAM, 0);
445 if(sockfd < 0)
446 error_counter++;
447
448
449 remote_addr.sin6_family = AF_INET6;
450 remote_addr.sin6_port = htons(12);
451 remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]);
452 remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]);
453 remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]);
454 remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]);
455
456 if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0)
457 error_counter++;
458
459 bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0);
460
461 if(bytes_sent != (INT)strlen(send_buffer))
462 error_counter++;
463
464 /* Make sure the other side gets the message. */
465 tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
466
467 ret = soc_close(sockfd);
468 if(ret < 0)
469 error_counter++;
470
471 }
472
test_tcp_server6(void)473 static void test_tcp_server6(void)
474 {
475 int sockfd;
476 struct sockaddr_in6 remote_addr, local_addr;
477 int address_length;
478 int ret;
479 int newsock;
480 int i;
481 UINT status;
482
483 sockfd = socket(AF_INET6, SOCK_STREAM, 0);
484 if(sockfd < 0)
485 error_counter++;
486
487 memset(&local_addr, 0, sizeof(local_addr));
488 local_addr.sin6_family = AF_INET6;
489 local_addr.sin6_port = htons(12346);
490
491
492 ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr));
493 if(ret < 0)
494 error_counter++;
495
496 ret = listen(sockfd, 5);
497 if(ret < 0)
498 error_counter++;
499
500 /* 3 iterations. */
501 for(i = 0; i < NUM_CLIENTS; i++)
502 {
503 address_length = sizeof(remote_addr);
504
505 newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length);
506
507 if(newsock <= 0)
508 error_counter++;
509
510 if(address_length != sizeof(struct sockaddr_in6))
511 error_counter++;
512
513 if((remote_addr.sin6_family != AF_INET6) ||
514 (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
515 (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
516 (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
517 (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
518 error_counter++;
519
520 address_length = sizeof(local_addr);
521 ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length);
522 if(ret < 0)
523 error_counter++;
524 else if(address_length != sizeof(local_addr))
525 error_counter++;
526 else if(local_addr.sin6_family != AF_INET6)
527 error_counter++;
528 else if(local_addr.sin6_port != htons(12346))
529 error_counter++;
530 else if((local_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip0.nxd_ip_address.v6[0])) ||
531 (local_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip0.nxd_ip_address.v6[1])) ||
532 (local_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip0.nxd_ip_address.v6[2])) ||
533 (local_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip0.nxd_ip_address.v6[3])))
534 error_counter++;
535
536 address_length = sizeof(remote_addr);
537 ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length);
538 if(ret < 0)
539 error_counter++;
540 else if(address_length != sizeof(remote_addr))
541 error_counter++;
542 else if(remote_addr.sin6_family != AF_INET6)
543 error_counter++;
544 else if((remote_addr.sin6_family != AF_INET6) ||
545 (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
546 (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
547 (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
548 (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
549 error_counter++;
550
551
552
553 /* Set the client data */
554 client_data[i].sockfd = newsock;
555 client_data[i].message_id = i;
556
557 /* Create a helper thread to handle the new socket. */
558 status = tx_thread_create(&helper_thread6[i], "helper thread", bsd_server_helper_thread_entry,
559 i, stack_space6[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
560 if(status)
561 error_counter++;
562
563 tx_thread_relinquish();
564 }
565
566 /* Close downt he socket. */
567 ret = soc_close(sockfd);
568 if(ret < 0)
569 error_counter++;
570
571 for(i = 0; i < NUM_CLIENTS; i++)
572 {
573
574 /* Wakeup server thread. */
575 tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
576 }
577 }
578
579 #endif
580
close_before_accept_test()581 static void close_before_accept_test()
582 {
583 int server_fd, client_fd;
584 int ret;
585 struct sockaddr_in remote_addr, local_addr;
586
587 /* Setup server socket. */
588 server_fd = socket(AF_INET, SOCK_STREAM, 0);
589 if(server_fd < 0)
590 error_counter++;
591
592 local_addr.sin_family = AF_INET;
593 local_addr.sin_port = htons(12345);
594 local_addr.sin_addr.s_addr = INADDR_ANY;
595
596 ret = bind(server_fd, (struct sockaddr*)&local_addr, sizeof(local_addr));
597 if(ret < 0)
598 error_counter++;
599
600 ret = listen(server_fd, 5);
601 if(ret < 0)
602 error_counter++;
603
604 /* Setup client socket. */
605 client_fd = socket(AF_INET, SOCK_STREAM, 0);
606 if(client_fd < 0)
607 error_counter++;
608
609 remote_addr.sin_family = AF_INET;
610 remote_addr.sin_port = htons(12345);
611 remote_addr.sin_addr.s_addr = htonl(0x01020304);
612
613 if(connect(client_fd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0)
614 error_counter++;
615
616 /* Close before calling accept. */
617 soc_close(server_fd);
618 soc_close(client_fd);
619 }
620
621
622 /* Define the test threads. */
ntest_0_entry(ULONG thread_input)623 static void ntest_0_entry(ULONG thread_input)
624 {
625 int sockfd;
626 struct sockaddr_in remote_addr;
627 #ifdef FEATURE_NX_IPV6
628 char mac_ip0[6];
629 char mac_ip1[6];
630 UINT status;
631 #endif
632 int ret;
633
634
635 printf("NetX Test: Basic BSD TCP Basic Blocking Test.............");
636
637 /* Check for earlier error. */
638 if (error_counter)
639 {
640
641 printf("ERROR!\n");
642 test_control_return(1);
643 }
644 #ifdef FEATURE_NX_IPV6
645 /* First set up IPv6 addresses. */
646 ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6;
647 ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000;
648 ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000;
649 ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff;
650 ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456;
651
652 ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6;
653 ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000;
654 ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000;
655 ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff;
656 ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457;
657
658 status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL);
659 status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL);
660
661 status += nxd_ipv6_enable(&ip_0);
662 status += nxd_ipv6_enable(&ip_1);
663
664 mac_ip0[0] = (CHAR)(ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8);
665 mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
666 mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
667 mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
668 mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
669 mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff;
670
671 mac_ip1[0] = (CHAR)(ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8);
672 mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
673 mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
674 mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
675 mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
676 mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff;
677
678 status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1);
679 status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0);
680
681 if(status)
682 error_counter++;
683 #endif
684
685 close_before_accept_test();
686
687 tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
688 test_tcp_client4();
689
690 tx_semaphore_put(&sema_1);
691 test_tcp_server4();
692
693 #ifdef FEATURE_NX_IPV6
694 tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
695 test_tcp_client6();
696
697 tx_semaphore_put(&sema_1);
698 test_tcp_server6();
699 #endif
700
701 tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
702 /* Now open another socket and attempt to connect to the correct remote
703 host but an unexpected port so we expect an unsuccessful connections. */
704 sockfd = socket(AF_INET, SOCK_STREAM, 0);
705 if(sockfd < 0)
706 error_counter++;
707
708 remote_addr.sin_family = AF_INET;
709 remote_addr.sin_port = htons(13);
710 remote_addr.sin_addr.s_addr = htonl(0x01020305);
711
712 if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0)
713 error_counter++;
714 if(errno != ECONNREFUSED)
715 error_counter++;
716
717 ret = soc_close(sockfd);
718 if(ret < 0)
719 error_counter++;
720
721 /* Now open another socket and attempt to connect to the an incorrect
722 remote host so we expect an unsuccessful connections. */
723 sockfd = socket(AF_INET, SOCK_STREAM, 0);
724 if(sockfd < 0)
725 error_counter++;
726
727
728 remote_addr.sin_family = AF_INET;
729 remote_addr.sin_port = htons(13);
730 remote_addr.sin_addr.s_addr = htonl(0x01020306);
731
732 if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0)
733 error_counter++;
734
735 if(errno != ETIMEDOUT)
736 error_counter++;
737 ret = soc_close(sockfd);
738 if(ret < 0)
739 error_counter++;
740
741 /* After the previous failed connection, make sure we can still open a socket. */
742 sockfd = socket(AF_INET, SOCK_STREAM, 0);
743 if(sockfd < 0)
744 error_counter++;
745
746 ret = soc_close(sockfd);
747 if(ret < 0)
748 error_counter++;
749
750 validate_bsd_structure();
751
752 if(error_counter)
753 printf("ERROR!\n");
754 else
755 printf("SUCCESS!\n");
756
757 if(error_counter)
758 test_control_return(1);
759
760 test_control_return(0);
761 }
762
763 static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS];
multiple_client4(void)764 static void multiple_client4(void)
765 {
766
767 int i;
768 UINT status = NX_SUCCESS;
769 NX_PACKET *packet_ptr;
770 for(i = 0; i < NUM_CLIENTS; i++)
771 {
772 status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket",
773 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
774 NX_NULL, NX_NULL);
775 status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0);
776 }
777 if(status != NX_SUCCESS)
778 error_counter++;
779
780 status = NX_SUCCESS;
781 for(i = 0; i < NUM_CLIENTS; i++)
782 {
783 status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE);
784
785 }
786 if(status != NX_SUCCESS)
787 error_counter++;
788
789 status = NX_SUCCESS;
790
791 /* Send messages to each server */
792 for(i = 0; i < NUM_CLIENTS; i++)
793 {
794 status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT);
795 status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]),
796 &pool_0, NX_NO_WAIT);
797 status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE);
798
799 }
800
801 if(status != NX_SUCCESS)
802 error_counter++;
803
804 status = NX_SUCCESS;
805 /* Receive 3 messages. */
806
807 for(i = 0; i < NUM_CLIENTS; i++)
808 {
809 status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE);
810 if(status != NX_SUCCESS)
811 {
812 error_counter++;
813 continue;
814 }
815
816 /* Validate the received data. */
817 else if(packet_ptr -> nx_packet_length != strlen(response[i & 3]))
818 error_counter++;
819 else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length))
820 error_counter++;
821 nx_packet_release(packet_ptr);
822 }
823
824 for(i = 0; i < NUM_CLIENTS; i++)
825 {
826
827 /* Wakeup server thread. */
828 tx_semaphore_put(&sema_1);
829 }
830
831 /* Shutdown the socket. */
832 for(i = 0; i < NUM_CLIENTS; i++)
833 {
834
835 status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE);
836 if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED)
837 status = 0;
838
839 if(tcp_sockets[i].nx_tcp_socket_bound_next)
840 status += nx_tcp_client_socket_unbind(&tcp_sockets[i]);
841
842
843 status += nx_tcp_socket_delete(&tcp_sockets[i]);
844
845 if(status != NX_SUCCESS)
846 error_counter++;
847 }
848
849
850 }
851
852
853 #ifdef FEATURE_NX_IPV6
multiple_client6(void)854 static void multiple_client6(void)
855 {
856
857 int i;
858 UINT status = NX_SUCCESS;
859 NX_PACKET *packet_ptr;
860 for(i = 0; i < NUM_CLIENTS; i++)
861 {
862 status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket",
863 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
864 NX_NULL, NX_NULL);
865 status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0);
866 }
867 if(status != NX_SUCCESS)
868 error_counter++;
869
870 status = NX_SUCCESS;
871 for(i = 0; i < NUM_CLIENTS; i++)
872 {
873 status += nxd_tcp_client_socket_connect(&tcp_sockets[i], &ipv6_address_ip0, 12346, NX_IP_PERIODIC_RATE);
874 }
875 if(status != NX_SUCCESS)
876 error_counter++;
877
878 status = NX_SUCCESS;
879
880 /* Send messages to each server */
881 for(i = 0; i < NUM_CLIENTS; i++)
882 {
883 status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT);
884 status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]),
885 &pool_0, NX_NO_WAIT);
886 status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE);
887
888 }
889
890 if(status != NX_SUCCESS)
891 error_counter++;
892
893 status = NX_SUCCESS;
894 /* Receive 3 messages. */
895
896 for(i = 0; i < NUM_CLIENTS; i++)
897 {
898 status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE);
899 if(status != NX_SUCCESS)
900 {
901 error_counter++;
902 continue;
903 }
904
905 /* Validate the received data. */
906 else if(packet_ptr -> nx_packet_length != strlen(response[i & 3]))
907 error_counter++;
908 else if(strncmp((char *)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length))
909 error_counter++;
910 nx_packet_release(packet_ptr);
911 }
912
913 for(i = 0; i < NUM_CLIENTS; i++)
914 {
915
916 /* Wakeup server thread. */
917 tx_semaphore_put(&sema_1);
918 }
919
920 /* Shutdown the socket. */
921 for(i = 0; i < NUM_CLIENTS; i++)
922 {
923
924 nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE);
925
926 if(tcp_sockets[i].nx_tcp_socket_bound_next)
927 status = nx_tcp_client_socket_unbind(&tcp_sockets[i]);
928 status += nx_tcp_socket_delete(&tcp_sockets[i]);
929
930 if(status != NX_SUCCESS)
931 error_counter++;
932 }
933
934 }
935 #endif
936
netx_tcp_server(void)937 static void netx_tcp_server(void)
938 {
939 NX_PACKET *packet_ptr;
940 UINT status;
941 /* Create a socket. */
942 status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket",
943 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
944 NX_NULL, NX_NULL);
945
946 /* Check for error. */
947 if (status)
948 error_counter++;
949
950 /* Setup this thread to listen. */
951 status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL);
952
953 /* Check for error. */
954 if (status)
955 error_counter++;
956
957 /* Accept a client socket connection. */
958 status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE);
959
960 /* Check for error. */
961 if (status)
962 error_counter++;
963
964 /* Receive a TCP message from the socket. */
965 status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE);
966
967 /* Check for error. */
968 if ((status) || (packet_ptr -> nx_packet_length != strlen(send_buffer)))
969 error_counter++;
970 else
971 {
972 if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer)))
973 error_counter++;
974
975 nx_packet_release(packet_ptr);
976 }
977
978 tx_semaphore_put(&sema_0);
979
980 /* Disconnect the server socket. */
981 status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE);
982
983 /* Check for error. */
984 if (status)
985 error_counter++;
986
987 /* Unaccept the server socket. */
988 status = nx_tcp_server_socket_unaccept(&server_socket);
989
990 /* Check for error. */
991 if (status)
992 error_counter++;
993
994 /* Setup server socket for listening again. */
995 status = nx_tcp_server_socket_unlisten(&ip_1, 12);
996
997 /* Check for error. */
998 if (status)
999 error_counter++;
1000
1001 nx_tcp_socket_delete(&server_socket);
1002 }
1003
ntest_1_entry(ULONG thread_input)1004 static void ntest_1_entry(ULONG thread_input)
1005 {
1006
1007 UINT status;
1008 ULONG actual_status;
1009
1010
1011
1012 /* Ensure the IP instance has been initialized. */
1013 status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE);
1014
1015 /* Check status... */
1016 if (status != NX_SUCCESS)
1017 {
1018
1019 printf("ERROR!\n");
1020 test_control_return(3);
1021 }
1022
1023 tx_semaphore_put(&sema_0);
1024
1025 netx_tcp_server();
1026
1027 /* Server run first. */
1028 tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE);
1029
1030 /* Simulate a multiple client conneting to the same server. */
1031 multiple_client4();
1032
1033 #ifdef FEATURE_NX_IPV6
1034 tx_semaphore_put(&sema_0);
1035 netx_tcp_server();
1036
1037 tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE);
1038 multiple_client6();
1039 #endif
1040
1041 /* Client finished. */
1042 tx_semaphore_put(&sema_0);
1043 }
1044
1045
1046 extern TX_BLOCK_POOL nx_bsd_socket_block_pool;
validate_bsd_structure(void)1047 static void validate_bsd_structure(void)
1048 {
1049 int i;
1050 /* Make sure every BSD socket should be free by now. */
1051
1052 for(i = 0; i < NX_BSD_MAX_SOCKETS; i++)
1053 {
1054 if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE)
1055 {
1056 error_counter++;
1057 }
1058
1059 if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket ||
1060 nx_bsd_socket_array[i].nx_bsd_socket_udp_socket)
1061 {
1062 error_counter++;
1063 }
1064 }
1065
1066 /* Make sure all the NX SOCKET control blocks are released. */
1067 if(nx_bsd_socket_block_pool.tx_block_pool_available !=
1068 nx_bsd_socket_block_pool.tx_block_pool_total)
1069 {
1070 error_counter++;
1071 }
1072
1073 /* Make sure all the sockets are released */
1074 if(ip_0.nx_ip_tcp_created_sockets_ptr ||
1075 ip_0.nx_ip_udp_created_sockets_ptr)
1076 {
1077 error_counter++;
1078 return;
1079 }
1080 }
1081
1082 #else
1083 extern void test_control_return(UINT status);
1084
1085 #ifdef CTEST
test_application_define(void * first_unused_memory)1086 VOID test_application_define(void *first_unused_memory)
1087 #else
1088 void netx_bsd_tcp_basic_blocking_test_application_define(void *first_unused_memory)
1089 #endif
1090 {
1091
1092 /* Print out test information banner. */
1093 printf("NetX Test: Basic BSD TCP Basic Blocking Test.............N/A\n");
1094
1095 test_control_return(3);
1096 }
1097 #endif
1098