master
c 1,211 lines 31.1 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 socket.c
8
9 Abstract:
10
11 Linux socket client / server test.
12
13 --*/
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/un.h>
22 #include <pthread.h>
23 #include <netinet/in.h>
24 #include <netdb.h>
25 #include "lxtcommon.h"
26 #include "unittests.h"
27 #include "common.h"
28
29 #define LXT_NAME_CLIENT "SocketClient"
30 #define LXT_NAME_SERVER "SocketServer"
31
32 #define LXT_AF_UNIX_SOCKET_PATH "af_unix_socket"
33
34 #define FD_STDOUT 1
35 //
36 // Function declarations.
37 //
38
39 long long GetTickCount(void);
40
41 int SocketClientDgram(PLXT_ARGS Args);
42
43 int SocketClientSend(int NumConnectAndSends, int Family, int Type, int Protocol);
44
45 int SocketClientSendMultiple(PLXT_ARGS Args);
46
47 int SocketClientSendMultipleIpv6(PLXT_ARGS Args);
48
49 int SocketClientSendWithFlags(PLXT_ARGS Args);
50
51 int SocketClientUnix(PLXT_ARGS Args);
52
53 int SocketCreateAcceptedSockets(int Family, int Type, int Protocol);
54
55 int SocketCreateBoundSocket(int Family, int Type, int Protocol);
56
57 int SocketCreateConnectSocket(int Family, int Type, int Protocol);
58
59 int SocketGetSockName(PLXT_ARGS Args);
60
61 int SocketParseCommandLine(int Argc, char* Argv[], LXT_ARGS* Args);
62
63 int SocketServerAccept(int NumAccepts, int Family, int Type, int Protocol);
64
65 int SocketServerAcceptMultiple(PLXT_ARGS Args);
66
67 int SocketServerAcceptMultipleIpv6(PLXT_ARGS Args);
68
69 int SocketServerAcceptWithFlags(PLXT_ARGS Args);
70
71 int SocketServerDgram(PLXT_ARGS Args);
72
73 int SocketServerUnix(PLXT_ARGS Args);
74
75 int SocketServerPortZeroFromThread(PLXT_ARGS Args);
76
77 void* SocketServerPortZeroFromThreadWorker(void* Context);
78
79 //
80 // Global constants.
81 //
82
83 static const LXT_VARIATION g_LxtClientVariations[] = {
84 {"Socket Client - send multiple", SocketClientSendMultiple},
85 {"Socket Client - AF_UNIX", SocketClientUnix},
86 {"Socket Client - send multiple Ipv6", SocketClientSendMultipleIpv6},
87 {"Socket Client - send (MSG_WAITALL)", SocketClientSendWithFlags},
88 {"Socket Client - SOCK_DGRAM", SocketClientDgram},
89
90 //
91 // Variations that do not require a server.
92 //
93
94 {"Socket - getsockname", SocketGetSockName},
95 };
96
97 //
98 // N.B. Keep the number of variations up to date with
99 // LXT_SOCKET_NUM_SERVER_VARIATIONS in socket/common.h
100 //
101
102 static const LXT_VARIATION g_LxtServerVariations[] = {
103 {"Socket Server - accept multiple", SocketServerAcceptMultiple},
104 {"Socket Server - AF_UNIX", SocketServerUnix},
105 {"Socket Server - accept multiple Ipv6", SocketServerAcceptMultipleIpv6},
106 {"Socket Server - accept (MSG_WAITALL)", SocketServerAcceptWithFlags},
107 {"Socket Server - SOCK_DGRAM", SocketServerDgram},
108 {"Socket Server - port zero bind from thread", SocketServerPortZeroFromThread}};
109
110 //
111 // Function definitions.
112 //
113
114 long long GetTickCount(void)
115 {
116
117 struct timespec Now;
118
119 if (clock_gettime(CLOCK_MONOTONIC, &Now))
120 {
121 return 0;
122 }
123
124 return Now.tv_sec * 1000 + Now.tv_nsec / 1000000;
125 }
126
127 int SocketTestEntry(int Argc, char* Argv[])
128
129 /*++
130 --*/
131
132 {
133
134 LXT_ARGS Args;
135 int Result;
136
137 LxtCheckResult(SocketParseCommandLine(Argc, Argv, &Args))
138
139 ErrorExit : LxtUninitialize();
140 return !LXT_SUCCESS(Result);
141 }
142
143 int SocketClientDgram(PLXT_ARGS Args)
144 {
145
146 char ReceiveBuffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
147 int Result = LXT_RESULT_FAILURE;
148 char* SendBuffer;
149 struct sockaddr* ServerAddress = {0};
150 struct sockaddr_in ServerAddressIpv4 = {0};
151 struct sockaddr_in6 ServerAddressIpv6 = {0};
152 struct sockaddr_un ServerAddressUnix = {0};
153 int ServerAddressLength;
154 int Size;
155 int Socket = 0;
156
157 sleep(2);
158
159 Socket = socket(AF_INET6, SOCK_DGRAM, 0);
160 if (Socket < 0)
161 {
162 LxtLogError("socket(AF_INET6, SOCK_DGRAM, 0) - %s", strerror(errno));
163 goto ErrorExit;
164 }
165
166 ServerAddressIpv6.sin6_family = AF_INET6;
167 ServerAddressIpv6.sin6_addr = in6addr_loopback;
168 ServerAddressIpv6.sin6_port = htons(LXT_SOCKET_DEFAULT_PORT_IPV6);
169 ServerAddress = (struct sockaddr*)&ServerAddressIpv6;
170 ServerAddressLength = sizeof(ServerAddressIpv6);
171 SendBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
172
173 Size = sendto(Socket, SendBuffer, strlen(SendBuffer), 0, ServerAddress, ServerAddressLength);
174
175 if (Size < 0)
176 {
177 LxtLogError("sendto - %s", strerror(errno));
178 goto ErrorExit;
179 }
180
181 Size = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, ServerAddress, &ServerAddressLength);
182
183 if (Size < 0)
184 {
185 LxtLogError("recvfrom - %s", strerror(errno));
186 goto ErrorExit;
187 }
188
189 LxtLogInfo("Received from server: %s", ReceiveBuffer);
190
191 if (memcmp(SendBuffer, ReceiveBuffer, Size) != 0)
192 {
193 LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
194
195 goto ErrorExit;
196 }
197
198 Result = LXT_RESULT_SUCCESS;
199
200 ErrorExit:
201 if (Socket > 0)
202 {
203 if (close(Socket) != 0)
204 {
205 LxtLogError("close(%d) - %s", Socket, strerror(errno));
206 }
207 }
208
209 return Result;
210 }
211
212 int SocketClientSend(int NumConnectAndSends, int Family, int Type, int Protocol)
213
214 {
215
216 int Index;
217 char ReceiveBuffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
218 int Result = LXT_RESULT_FAILURE;
219 char* SendBuffer;
220 int Size;
221 int Socket = 0;
222
223 //
224 // Sleep to allow the server process to be listening.
225 //
226
227 sleep(2);
228 SendBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
229 for (Index = 0; Index < NumConnectAndSends; Index++)
230 {
231 Socket = SocketCreateConnectSocket(Family, Type, Protocol);
232 if (Socket <= 0)
233 {
234 LxtLogError("SocketCreateConnectSocket failed");
235 goto ErrorExit;
236 }
237
238 Size = send(Socket, SendBuffer, strlen(SendBuffer), 0);
239 if (Size < 0)
240 {
241 LxtLogError("send(%d, SendBuffer, strlen(SendBuffer), 0) - %s", Socket, strerror(errno));
242
243 goto ErrorExit;
244 }
245
246 memset(ReceiveBuffer, 0, sizeof(ReceiveBuffer));
247 Size = read(Socket, ReceiveBuffer, Size);
248 if (Size < 0)
249 {
250 LxtLogError("read(%d, ReceiveBuffer, sizeof(ReceiveBuffer) - %s", Socket, strerror(errno));
251
252 goto ErrorExit;
253 }
254
255 LxtLogInfo("Received from server: %s", ReceiveBuffer);
256
257 if (memcmp(SendBuffer, ReceiveBuffer, Size) != 0)
258 {
259 LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
260
261 goto ErrorExit;
262 }
263
264 if (close(Socket) != 0)
265 {
266 LxtLogError("close(%d) - %s", Socket, strerror(errno));
267 }
268
269 Socket = 0;
270 }
271
272 Result = LXT_RESULT_SUCCESS;
273
274 ErrorExit:
275 if (Socket > 0)
276 {
277 if (close(Socket) != 0)
278 {
279 LxtLogError("close(%d) - %s", Socket, strerror(errno));
280 }
281 }
282
283 return Result;
284 }
285
286 int SocketClientSendMultiple(PLXT_ARGS Args)
287
288 /*++
289 --*/
290
291 {
292
293 return SocketClientSend(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET, SOCK_STREAM, 0);
294 }
295
296 int SocketClientSendMultipleIpv6(PLXT_ARGS Args)
297
298 /*++
299 --*/
300
301 {
302
303 return SocketClientSend(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET6, SOCK_STREAM, 0);
304 }
305
306 int SocketClientSendWithFlags(PLXT_ARGS Args)
307 {
308 int FullMessageSize;
309 char* ReceiveBuffer;
310 int Result = LXT_RESULT_FAILURE;
311 char* SendBuffer;
312 int Size;
313 int Socket = 0;
314
315 //
316 // Sleep to allow the server process to be listening.
317 //
318
319 sleep(2);
320 SendBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
321 FullMessageSize = 2 * strlen(SendBuffer);
322 ReceiveBuffer = malloc(FullMessageSize);
323 if (ReceiveBuffer == NULL)
324 {
325 goto ErrorExit;
326 }
327
328 Socket = SocketCreateConnectSocket(AF_INET, SOCK_STREAM, 0);
329 if (Socket <= 0)
330 {
331 goto ErrorExit;
332 }
333
334 Size = send(Socket, SendBuffer, strlen(SendBuffer), 0);
335 if (Size < 0)
336 {
337 LxtLogError("send(%d, SendBuffer, strlen(SendBuffer), 0) - %s", Socket, strerror(errno));
338
339 goto ErrorExit;
340 }
341
342 //
343 // Sleep long enough that the second send won't be concatenated by WSK to
344 // test MSW_WAITALL code path.
345 //
346
347 sleep(1);
348 Size = send(Socket, SendBuffer, strlen(SendBuffer), 0);
349 if (Size < 0)
350 {
351 LxtLogError("send(%d, SendBuffer, strlen(SendBuffer), 0) - %s", Socket, strerror(errno));
352
353 goto ErrorExit;
354 }
355
356 memset(ReceiveBuffer, 0, FullMessageSize);
357 Size = recv(Socket, ReceiveBuffer, FullMessageSize, MSG_WAITALL);
358 if (Size < 0)
359 {
360 LxtLogError("read(%d, ReceiveBuffer, %d, MSG_WAITALL - %s", Socket, FullMessageSize, strerror(errno));
361
362 goto ErrorExit;
363 }
364
365 LxtLogInfo("Received from server: %s", ReceiveBuffer);
366
367 if (memcmp(SendBuffer, ReceiveBuffer, FullMessageSize / 2) != 0)
368 {
369 LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
370
371 goto ErrorExit;
372 }
373
374 if (memcmp(SendBuffer, ReceiveBuffer + FullMessageSize / 2, sizeof(SendBuffer)) != 0)
375 {
376
377 LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
378
379 goto ErrorExit;
380 }
381
382 Result = LXT_RESULT_SUCCESS;
383
384 ErrorExit:
385 if (Socket > 0)
386 {
387 if (close(Socket) != 0)
388 {
389 LxtLogError("close(%d) - %s", Socket, strerror(errno));
390 }
391 }
392
393 if (ReceiveBuffer != NULL)
394 {
395 free(ReceiveBuffer);
396 }
397
398 return Result;
399 }
400
401 int SocketClientUnix(PLXT_ARGS Args)
402 {
403
404 return SocketClientSend(1, AF_UNIX, SOCK_SEQPACKET, 0);
405 }
406
407 int SocketCreateAcceptedSocket(int Socket, int Family)
408 {
409
410 int AcceptedSocket = 0;
411 int Result = LXT_RESULT_FAILURE;
412 struct sockaddr* Address;
413 struct sockaddr_in AddressIpv4 = {0};
414 struct sockaddr_in6 AddressIpv6 = {0};
415 struct sockaddr_un AddressUnix = {0};
416 socklen_t AddressLength;
417
418 switch (Family)
419 {
420 case AF_INET:
421 Address = (struct sockaddr*)&AddressIpv4;
422 AddressLength = sizeof(AddressIpv4);
423 break;
424
425 case AF_INET6:
426 Address = (struct sockaddr*)&AddressIpv6;
427 AddressLength = sizeof(AddressIpv6);
428 break;
429
430 case AF_UNIX:
431 Address = (struct sockaddr*)&AddressUnix;
432 AddressLength = sizeof(AddressUnix);
433 break;
434
435 default:
436 LxtLogError("Unsupported Family %d", Family);
437 AcceptedSocket = 0;
438 goto ErrorExit;
439 }
440
441 AcceptedSocket = accept(Socket, Address, &AddressLength);
442
443 if (AcceptedSocket < 0)
444 {
445 LxtLogError("accept(%d, Address, &AddressLength) - %s", Socket, strerror(errno));
446
447 close(AcceptedSocket);
448 goto ErrorExit;
449 }
450
451 Result = AcceptedSocket;
452
453 ErrorExit:
454 return Result;
455 }
456
457 int SocketCreateBoundSocket(int Family, int Type, int Protocol)
458 {
459 int OptVal;
460 int Result = LXT_RESULT_FAILURE;
461 struct sockaddr* ServerAddress;
462 int ServerAddressSize;
463 struct sockaddr_in ServerAddressIpv4 = {0};
464 struct sockaddr_in6 ServerAddressIpv6 = {0};
465 struct sockaddr_un ServerAddressUnix = {0};
466 int Size;
467 int Socket = 0;
468
469 Socket = socket(Family, Type, Protocol);
470 if (Socket < 0)
471 {
472 LxtLogError("socket(%d, %d, %d) - %s", Family, Type, Protocol, strerror(errno));
473 goto ErrorExit;
474 }
475
476 //
477 // TODO: when setsockopt is implemented uncomment the below.
478 //
479 // OptVal = 1;
480 // if (setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, &OptVal, sizeof(OptVal)) < 0) {
481 // LxtLogError("setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, &OptVal, sizeof(OptVal)) - %s",
482 // Socket,
483 // strerror(errno));
484 // goto ErrorExit;
485 //}
486
487 switch (Family)
488 {
489 case AF_INET:
490 ServerAddressIpv4.sin_family = AF_INET;
491 ServerAddressIpv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
492 ServerAddressIpv4.sin_port = htons(LXT_SOCKET_DEFAULT_PORT);
493 ServerAddress = (struct sockaddr*)&ServerAddressIpv4;
494 ServerAddressSize = sizeof(ServerAddressIpv4);
495 break;
496
497 case AF_INET6:
498 ServerAddressIpv6.sin6_family = AF_INET6;
499 ServerAddressIpv6.sin6_addr = in6addr_loopback;
500 ServerAddressIpv6.sin6_port = htons(LXT_SOCKET_DEFAULT_PORT_IPV6);
501 ServerAddress = (struct sockaddr*)&ServerAddressIpv6;
502 ServerAddressSize = sizeof(ServerAddressIpv6);
503 break;
504
505 case AF_UNIX:
506 ServerAddressUnix.sun_family = AF_UNIX;
507 strcpy(ServerAddressUnix.sun_path, LXT_AF_UNIX_SOCKET_PATH);
508 ServerAddress = (struct sockaddr*)&ServerAddressUnix;
509 ServerAddressSize = sizeof(ServerAddressUnix);
510 // unlink(LXT_AF_UNIX_SOCKET_PATH); // TODO: when unlink is implemented uncomment this.
511 break;
512
513 default:
514 LxtLogError("Unsupported Family %d", Family);
515 close(Socket);
516 Socket = 0;
517 goto ErrorExit;
518 }
519
520 if (bind(Socket, ServerAddress, ServerAddressSize) < 0)
521 {
522 LxtLogError("bind(%d, ServerAddress, ServerAddressSize) - %s", Socket, strerror(errno));
523
524 close(Socket);
525 Socket = 0;
526 goto ErrorExit;
527 }
528
529 Result = Socket;
530
531 ErrorExit:
532 return Result;
533 }
534
535 int SocketCreateConnectSocket(int Family, int Type, int Protocol)
536 {
537
538 int Result = LXT_RESULT_FAILURE;
539 struct sockaddr* ServerAddress = NULL;
540 struct sockaddr_in ServerAddressIpv4 = {0};
541 struct sockaddr_in6 ServerAddressIpv6 = {0};
542 int ServerAddressSize;
543 struct sockaddr_un ServerAddressUnix = {0};
544 int Size;
545 int Socket = 0;
546
547 Socket = socket(Family, Type, Protocol);
548 if (Socket < 0)
549 {
550 LxtLogError("socket(%d, %d, %d) - %s", Family, Type, Protocol, strerror(errno));
551 goto ErrorExit;
552 }
553
554 switch (Family)
555 {
556 case AF_INET:
557 ServerAddressIpv4.sin_family = AF_INET;
558 ServerAddressIpv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
559 ServerAddressIpv4.sin_port = htons(LXT_SOCKET_DEFAULT_PORT);
560 ServerAddress = (struct sockaddr*)&ServerAddressIpv4;
561 ServerAddressSize = sizeof(ServerAddressIpv4);
562 break;
563
564 case AF_INET6:
565 ServerAddressIpv6.sin6_family = AF_INET6;
566 ServerAddressIpv6.sin6_addr = in6addr_loopback;
567 ServerAddressIpv6.sin6_port = htons(LXT_SOCKET_DEFAULT_PORT_IPV6);
568 ServerAddress = (struct sockaddr*)&ServerAddressIpv6;
569 ServerAddressSize = sizeof(ServerAddressIpv6);
570 break;
571
572 case AF_UNIX:
573 ServerAddressUnix.sun_family = AF_UNIX;
574 strcpy(ServerAddressUnix.sun_path, LXT_AF_UNIX_SOCKET_PATH);
575 ServerAddress = (struct sockaddr*)&ServerAddressUnix;
576 ServerAddressSize = sizeof(ServerAddressUnix);
577 break;
578
579 default:
580 LxtLogError("LxtSocketClientSend Unsupported Family %d", Family);
581 close(Socket);
582 Socket = 0;
583 goto ErrorExit;
584 }
585
586 if (connect(Socket, ServerAddress, ServerAddressSize) < 0)
587 {
588 LxtLogError("connect failed - %s", strerror(errno));
589 close(Socket);
590 Socket = 0;
591 goto ErrorExit;
592 }
593
594 Result = Socket;
595
596 ErrorExit:
597 return Result;
598 }
599
600 int SocketGetSockName(PLXT_ARGS Args)
601 {
602 union
603 {
604 struct in_addr Addr;
605 struct in6_addr AddrIpv6;
606 } Addr;
607 struct sockaddr_storage Address = {0};
608 int AddressFamilies[] = {AF_INET, AF_INET6};
609 int AddressFamily;
610 int AddressSize;
611 int Port;
612 int Result = LXT_RESULT_FAILURE;
613 int Socket = 0;
614 int Index;
615
616 for (Index = 0; Index < (int)LXT_COUNT_OF(AddressFamilies); Index++)
617 {
618 Socket = socket(AddressFamilies[Index], SOCK_STREAM, 0);
619 if (Socket < 0)
620 {
621 LxtLogError("socket(%d, SOCK_STREAM, 0) - %s", AddressFamilies[Index], strerror(errno));
622
623 goto ErrorExit;
624 }
625
626 switch (AddressFamilies[Index])
627 {
628 case AF_INET:
629 ((struct sockaddr_in*)&Address)->sin_family = AF_INET;
630 ((struct sockaddr_in*)&Address)->sin_port = htons(0);
631 ((struct sockaddr_in*)&Address)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
632 AddressSize = sizeof(struct sockaddr_in);
633 break;
634
635 case AF_INET6:
636 ((struct sockaddr_in6*)&Address)->sin6_family = AF_INET6;
637 ((struct sockaddr_in6*)&Address)->sin6_port = htons(0);
638 ((struct sockaddr_in6*)&Address)->sin6_addr = in6addr_loopback;
639 AddressSize = sizeof(struct sockaddr_in6);
640 break;
641
642 default:
643 LxtLogError("Unsupported Family %d", AddressFamilies[Index]);
644 goto ErrorExit;
645 }
646
647 if (bind(Socket, (struct sockaddr*)&Address, AddressSize) < 0)
648 {
649 LxtLogError("bind(%d, (struct sockaddr*)&Address, AddressSize) - %s", Socket, strerror(errno));
650
651 goto ErrorExit;
652 }
653
654 if (getsockname(Socket, (struct sockaddr*)&Address, &AddressSize) < 0)
655 {
656 LxtLogError("getsockname(%d, &Address, &AddressSize) - %s", Socket, strerror(errno));
657
658 goto ErrorExit;
659 }
660
661 memset(&Addr, 0, sizeof(Addr));
662 switch (AddressFamilies[Index])
663 {
664 case AF_INET:
665 AddressFamily = ((struct sockaddr_in*)&Address)->sin_family;
666 Port = ((struct sockaddr_in*)&Address)->sin_port;
667 memcpy(
668 (struct sockaddr_in*)&Addr,
669 &((struct sockaddr_in*)&Address)->sin_addr.s_addr,
670 sizeof(((struct sockaddr_in*)&Address)->sin_addr.s_addr));
671
672 break;
673
674 case AF_INET6:
675 AddressFamily = ((struct sockaddr_in6*)&Address)->sin6_family;
676 Port = ((struct sockaddr_in6*)&Address)->sin6_port;
677 memcpy(
678 (struct sockaddr_in6*)&Addr, &((struct sockaddr_in6*)&Address)->sin6_addr, sizeof(((struct sockaddr_in6*)&Address)->sin6_addr));
679
680 break;
681
682 default:
683 LxtLogError("Unsupported AddressFamily %d", AddressFamilies[Index]);
684 goto ErrorExit;
685 }
686
687 if (AddressFamily != AddressFamilies[Index])
688 {
689 LxtLogError("Socket %d is bound, address family %d should be %d", Socket, AddressFamily, AddressFamilies[Index], strerror(errno));
690
691 goto ErrorExit;
692 }
693
694 if (Port == 0)
695 {
696 LxtLogError("Socket %d is bound, port should be non-null", Socket, strerror(errno));
697
698 goto ErrorExit;
699 }
700
701 //
702 // Create the underlaying socket and query again, port should be the same.
703 //
704
705 if (listen(Socket, 32) < 0)
706 {
707 LxtLogError("listen(%d, 32) - %s", Socket, strerror(errno));
708 goto ErrorExit;
709 }
710
711 if (getsockname(Socket, (struct sockaddr*)&Address, &AddressSize) < 0)
712 {
713 LxtLogError("getsockname(%d, &Address, &AddressSize) - %s", Socket, strerror(errno));
714
715 goto ErrorExit;
716 }
717
718 switch (AddressFamilies[Index])
719 {
720 case AF_INET:
721 if (AddressFamily != ((struct sockaddr_in*)&Address)->sin_family)
722 {
723 LxtLogError("Socket %d is bound, address family %d should be %d", Socket, ((struct sockaddr_in*)&Address)->sin_family, AddressFamily, strerror(errno));
724
725 goto ErrorExit;
726 }
727
728 if (Port != ((struct sockaddr_in*)&Address)->sin_port)
729 {
730 LxtLogError("Socket %d should be bound to port %d", Socket, Port, strerror(errno));
731
732 goto ErrorExit;
733 }
734
735 if (memcmp(&Addr, &((struct sockaddr_in*)&Address)->sin_addr.s_addr, sizeof(((struct sockaddr_in*)&Address)->sin_addr.s_addr)) != 0)
736 {
737
738 LxtLogError("Socket %d addr should be localhost", Socket, strerror(errno));
739
740 goto ErrorExit;
741 }
742
743 break;
744
745 case AF_INET6:
746 if (AddressFamily != ((struct sockaddr_in6*)&Address)->sin6_family)
747 {
748 LxtLogError(
749 "Socket %d is bound, address family %d should be %d",
750 Socket,
751 ((struct sockaddr_in6*)&Address)->sin6_family,
752 AddressFamily,
753 strerror(errno));
754
755 goto ErrorExit;
756 }
757
758 if (Port != ((struct sockaddr_in6*)&Address)->sin6_port)
759 {
760 LxtLogError("Socket %d should be bound to port %d", Socket, Port, strerror(errno));
761
762 goto ErrorExit;
763 }
764
765 if (memcmp(&Addr, &((struct sockaddr_in6*)&Address)->sin6_addr, sizeof(((struct sockaddr_in6*)&Address)->sin6_addr)) != 0)
766 {
767
768 LxtLogError("Socket %d addr should be localhost", Socket, strerror(errno));
769
770 goto ErrorExit;
771 }
772 break;
773
774 default:
775 LxtLogError("Unsupported Family %d", AddressFamilies[Index]);
776 goto ErrorExit;
777 }
778
779 if (close(Socket) != 0)
780 {
781 LxtLogError("close(%d) - %s", Socket, strerror(errno));
782 }
783
784 Socket = 0;
785 }
786
787 Result = LXT_RESULT_SUCCESS;
788
789 ErrorExit:
790 if (Socket > 0)
791 {
792 if (close(Socket) != 0)
793 {
794 LxtLogError("close(%d) - %s", Socket, strerror(errno));
795 }
796 }
797
798 return Result;
799 }
800
801 int SocketParseCommandLine(int Argc, char* Argv[], LXT_ARGS* Args)
802
803 /*++
804 --*/
805
806 {
807
808 int ArgvIndex;
809 int Result;
810 int ValidArguments;
811
812 Result = LXT_RESULT_FAILURE;
813 ValidArguments = 0;
814
815 if (Argc < 2)
816 {
817 goto ErrorExit;
818 }
819
820 for (ArgvIndex = 1; ArgvIndex < Argc; ++ArgvIndex)
821 {
822 if (Argv[ArgvIndex][0] != '-')
823 {
824 printf("Unexpected character %s\n", Argv[ArgvIndex]);
825 goto ErrorExit;
826 }
827
828 switch (Argv[ArgvIndex][1])
829 {
830 case 'c':
831
832 //
833 // Run client variations.
834 //
835
836 ValidArguments = 1;
837 LxtCheckResult(LxtInitialize(Argc, Argv, Args, LXT_NAME_CLIENT));
838 LxtCheckResult(LxtRunVariations(Args, g_LxtClientVariations, LXT_COUNT_OF(g_LxtClientVariations)));
839 break;
840
841 case 's':
842
843 //
844 // Run server variations.
845 //
846
847 ValidArguments = 1;
848 LxtCheckResult(LxtInitialize(Argc, Argv, Args, LXT_NAME_SERVER));
849 LxtCheckResult(LxtRunVariations(Args, g_LxtServerVariations, LXT_COUNT_OF(g_LxtServerVariations)));
850 break;
851
852 case 'v':
853
854 //
855 // This was already taken care of by LxtInitialize.
856 //
857
858 ++ArgvIndex;
859
860 break;
861
862 default:
863 goto ErrorExit;
864 }
865 }
866
867 ErrorExit:
868 if (ValidArguments == 0)
869 {
870 printf("\nuse: socket <One of the below arguments>\n");
871 printf("\t-c : Run all client variations (server must already be running)\n");
872 printf("\t-s : Run all server variations\n");
873 }
874
875 return Result;
876 }
877
878 int SocketServerDgram(PLXT_ARGS Args)
879 {
880
881 char Buffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
882 struct sockaddr* FromAddress = {0};
883 struct sockaddr_in FromAddressIpv4 = {0};
884 struct sockaddr_in6 FromAddressIpv6 = {0};
885 struct sockaddr_un FromAddressUnix = {0};
886 int FromAddressLength;
887 int Result = LXT_RESULT_FAILURE;
888 int Size;
889 int Socket = 0;
890
891 Socket = SocketCreateBoundSocket(AF_INET6, SOCK_DGRAM, 0);
892 if (Socket < 0)
893 {
894 goto ErrorExit;
895 }
896
897 FromAddress = (struct sockaddr*)&FromAddressIpv6;
898 FromAddressLength = sizeof(FromAddressIpv6);
899
900 Size = recvfrom(Socket, Buffer, sizeof(Buffer), 0, FromAddress, &FromAddressLength);
901
902 if (Size < 0)
903 {
904 LxtLogError("recvfrom - %s", strerror(errno));
905 goto ErrorExit;
906 }
907
908 LxtLogInfo("Received : %s", Buffer);
909
910 Size = sendto(Socket, Buffer, Size, 0, FromAddress, FromAddressLength);
911
912 if (Size < 0)
913 {
914 LxtLogError("sendto - %s", strerror(errno));
915 goto ErrorExit;
916 }
917
918 Result = LXT_RESULT_SUCCESS;
919
920 ErrorExit:
921 if (Socket > 0)
922 {
923 if (close(Socket) != 0)
924 {
925 LxtLogError("close(%d) - %s", Socket, strerror(errno));
926 }
927 }
928
929 return Result;
930 }
931
932 int SocketServerAccept(int NumAccepts, int Family, int Type, int Protocol)
933
934 /*++
935 --*/
936
937 {
938
939 char Buffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
940 int ClientSockets[LXT_SOCKET_SERVER_MAX_BACKLOG_NUM] = {0};
941 int Index;
942 int Result = LXT_RESULT_FAILURE;
943 int Size;
944 int Socket = 0;
945
946 Socket = SocketCreateBoundSocket(Family, Type, Protocol);
947 if (Socket < 0)
948 {
949 goto ErrorExit;
950 }
951
952 if (listen(Socket, NumAccepts) < 0)
953 {
954 LxtLogError("listen(%d, %d) - %s", Socket, NumAccepts, strerror(errno));
955 goto ErrorExit;
956 }
957
958 for (Index = 0; Index < NumAccepts; Index++)
959 {
960 ClientSockets[Index] = SocketCreateAcceptedSocket(Socket, Family);
961 if (ClientSockets[Index] < 0)
962 {
963 goto ErrorExit;
964 }
965
966 memset(Buffer, 0, sizeof(Buffer));
967 Size = read(ClientSockets[Index], Buffer, sizeof(Buffer));
968
969 //
970 // TODO: might need to handle the case where the socket gets shut down
971 // without receiving any data as in the connect / close variation.
972 //
973
974 if (Size < 0)
975 {
976 LxtLogError("read(%d, Buffer, sizeof(Buffer)) - %s", ClientSockets[Index], strerror(errno));
977 goto ErrorExit;
978 }
979
980 LxtLogInfo("Received: %s", Buffer);
981
982 if (write(ClientSockets[Index], Buffer, Size) < 0)
983 {
984 LxtLogError("write(%d, Buffer, Size) - %s", ClientSockets[Index], strerror(errno));
985 goto ErrorExit;
986 }
987 }
988
989 Result = LXT_RESULT_SUCCESS;
990
991 ErrorExit:
992 for (Index = 0; Index < NumAccepts; Index++)
993 {
994 if (ClientSockets[Index] > 0)
995 {
996 if (close(ClientSockets[Index]) < 0)
997 {
998 LxtLogError("close(%d) - %s", ClientSockets[Index], strerror(errno));
999 }
1000 }
1001 }
1002
1003 if (Socket > 0)
1004 {
1005 if (close(Socket) != 0)
1006 {
1007 LxtLogError("close(%d) - %s", Socket, strerror(errno));
1008 }
1009 }
1010
1011 return Result;
1012 }
1013
1014 int SocketServerAcceptMultiple(PLXT_ARGS Args)
1015
1016 /*++
1017 --*/
1018
1019 {
1020
1021 return SocketServerAccept(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET, SOCK_STREAM, 0);
1022 }
1023
1024 int SocketServerAcceptMultipleIpv6(PLXT_ARGS Args)
1025
1026 /*++
1027 --*/
1028
1029 {
1030
1031 return SocketServerAccept(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET6, SOCK_STREAM, 0);
1032 }
1033
1034 int SocketServerAcceptWithFlags(PLXT_ARGS Args)
1035 {
1036 int AcceptedSocket = 0;
1037 int Index;
1038 char* ReceiveBuffer;
1039 int Result = LXT_RESULT_FAILURE;
1040 int Size;
1041 int FullMessageSize;
1042 int Socket = 0;
1043
1044 ReceiveBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
1045 FullMessageSize = 2 * strlen(ReceiveBuffer);
1046 ReceiveBuffer = malloc(FullMessageSize);
1047 if (ReceiveBuffer == NULL)
1048 {
1049 goto ErrorExit;
1050 }
1051
1052 Socket = SocketCreateBoundSocket(AF_INET, SOCK_STREAM, 0);
1053 if (Socket < 0)
1054 {
1055 goto ErrorExit;
1056 }
1057
1058 if (listen(Socket, 32) < 0)
1059 {
1060 LxtLogError("listen(%d, 32) - %s", Socket, strerror(errno));
1061 goto ErrorExit;
1062 }
1063
1064 AcceptedSocket = SocketCreateAcceptedSocket(Socket, AF_INET);
1065 memset(ReceiveBuffer, 0, sizeof(ReceiveBuffer));
1066 Size = recv(AcceptedSocket, ReceiveBuffer, FullMessageSize, MSG_WAITALL);
1067
1068 //
1069 // TODO: might need to handle the case where the socket gets shut down
1070 // without receiving any data as in the connect / close variation.
1071 //
1072
1073 if (Size < 0)
1074 {
1075 LxtLogError("recv(%d, Buffer, %d, MSG_WAITALL) - %s", AcceptedSocket, FullMessageSize, strerror(errno));
1076 goto ErrorExit;
1077 }
1078
1079 LxtLogInfo("Received: %s", ReceiveBuffer);
1080
1081 if (write(AcceptedSocket, ReceiveBuffer, Size) < 0)
1082 {
1083 LxtLogError("write(%d, Buffer, Size) - %s", AcceptedSocket, strerror(errno));
1084 goto ErrorExit;
1085 }
1086
1087 Result = LXT_RESULT_SUCCESS;
1088
1089 ErrorExit:
1090 if (AcceptedSocket > 0)
1091 {
1092 if (close(AcceptedSocket) < 0)
1093 {
1094 LxtLogError("close(%d) - %s", AcceptedSocket, strerror(errno));
1095 }
1096 }
1097
1098 if (Socket > 0)
1099 {
1100 if (close(Socket) != 0)
1101 {
1102 LxtLogError("close(%d) - %s", Socket, strerror(errno));
1103 }
1104 }
1105
1106 if (ReceiveBuffer != NULL)
1107 {
1108 free(ReceiveBuffer);
1109 }
1110
1111 return Result;
1112 }
1113
1114 int SocketServerUnix(PLXT_ARGS Args)
1115 {
1116
1117 return SocketServerAccept(1, AF_UNIX, SOCK_SEQPACKET, 0);
1118 }
1119
1120 int SocketServerPortZeroFromThread(PLXT_ARGS Args)
1121 {
1122 int Error;
1123 int Result = LXT_RESULT_FAILURE;
1124 int ThreadError = 0;
1125 pthread_t Thread;
1126
1127 Error = pthread_create(&Thread, NULL, SocketServerPortZeroFromThreadWorker, &ThreadError);
1128 if (Error != 0)
1129 {
1130 LxtLogError("pthread_create - %s", strerror(Error));
1131 goto ErrorExit;
1132 }
1133
1134 Error = pthread_join(Thread, NULL);
1135 if (Error != 0)
1136 {
1137 LxtLogError("pthread_join - %s", strerror(Error));
1138 goto ErrorExit;
1139 }
1140
1141 if (ThreadError != 0)
1142 {
1143 LxtLogError("Threaded port-zero server failed - %s", strerror(ThreadError));
1144 goto ErrorExit;
1145 }
1146
1147 Result = LXT_RESULT_SUCCESS;
1148
1149 ErrorExit:
1150 return Result;
1151 }
1152
1153 void* SocketServerPortZeroFromThreadWorker(void* Context)
1154 {
1155 int* ThreadError = Context;
1156 int AcceptedSocket = -1;
1157 struct sockaddr_in ServerAddress = {0};
1158 socklen_t ServerAddressLength = sizeof(ServerAddress);
1159 int ServerSocket = -1;
1160 int Error = 0;
1161
1162 ServerSocket = socket(AF_INET, SOCK_STREAM, 0);
1163 if (ServerSocket < 0)
1164 {
1165 Error = errno;
1166 goto ErrorExit;
1167 }
1168
1169 ServerAddress.sin_family = AF_INET;
1170 ServerAddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1171 if (bind(ServerSocket, (struct sockaddr*)&ServerAddress, sizeof(ServerAddress)) < 0)
1172 {
1173 Error = errno;
1174 goto ErrorExit;
1175 }
1176
1177 if (getsockname(ServerSocket, (struct sockaddr*)&ServerAddress, &ServerAddressLength) < 0)
1178 {
1179 Error = errno;
1180 goto ErrorExit;
1181 }
1182
1183 if (listen(ServerSocket, 1) < 0)
1184 {
1185 Error = errno;
1186 goto ErrorExit;
1187 }
1188
1189 printf("PORT_ZERO_THREAD_LISTENER_PORT=%u\n", ntohs(ServerAddress.sin_port));
1190 fflush(stdout);
1191
1192 AcceptedSocket = accept(ServerSocket, NULL, NULL);
1193 if (AcceptedSocket < 0)
1194 {
1195 Error = errno;
1196 }
1197
1198 ErrorExit:
1199 *ThreadError = Error;
1200 if (AcceptedSocket >= 0)
1201 {
1202 close(AcceptedSocket);
1203 }
1204
1205 if (ServerSocket >= 0)
1206 {
1207 close(ServerSocket);
1208 }
1209
1210 return NULL;
1211 }