1 /*
2 ** Copyright 2009 The Android Open Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17 /** socket testing */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <sys/uio.h>
23 #include <unistd.h>
24
25 #include <pthread.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <sys/socket.h>
31 #include <sys/ioctl.h>
32 #include <sys/poll.h>
33 #include <sys/un.h>
34 #include <netinet/in.h>
35
36 #include <bluetooth/bluetooth.h>
37 #include <bluetooth/rfcomm.h>
38 #include <bluetooth/sco.h>
39 #include <bluetooth/l2cap.h>
40
41 #include "cutils/abort_socket.h"
42
43 enum sock_type {
44 UNIX = 0,
45 RFCOMM,
46 SCO,
47 L2CAP,
48 TCP,
49 };
50
51 struct thread_args {
52 int fd;
53 int type;
54 int delay;
55 };
56
57 struct sockaddr_un local_addr_un = {AF_UNIX, "/data/foo"};
58 struct sockaddr_rc local_addr_rc = {AF_BLUETOOTH, *BDADDR_ANY, 4};
59 struct sockaddr_sco local_addr_sco = {AF_BLUETOOTH, *BDADDR_LOCAL};
60 struct sockaddr_l2 local_addr_l2 = {AF_BLUETOOTH, htobs(0x1001), *BDADDR_ANY, 0};
61 struct sockaddr_in local_addr_in = {AF_INET, 9999, {0}, {0}};
62
63 struct sockaddr_un remote_addr_un ;
64 struct sockaddr_rc remote_addr_rc ;
65 struct sockaddr_sco remote_addr_sco ;
66 struct sockaddr_l2 remote_addr_l2 ;
67 struct sockaddr_in remote_addr_in ;
68
print_events(int events)69 static void print_events(int events) {
70 if (events & POLLIN) printf("POLLIN ");
71 if (events & POLLPRI) printf("POLLPRI ");
72 if (events & POLLOUT) printf("POLLOUT ");
73 if (events & POLLERR) printf("POLLERR ");
74 if (events & POLLHUP) printf("POLLHUP ");
75 if (events & POLLNVAL) printf("POLLNVAL ");
76 printf("\n");
77 }
78
print_fds(struct pollfd * ufds,nfds_t nfds)79 static void print_fds(struct pollfd *ufds, nfds_t nfds) {
80 unsigned int i;
81 for (i=0; i<nfds; i++)
82 printf("%d ", ufds[i].fd);
83 }
84
_socket(int type)85 static int _socket(int type) {
86 int ret;
87 int family = -1;
88 int typ = -1;
89 int protocol = -1;
90
91 switch (type) {
92 case UNIX:
93 family = PF_UNIX;
94 typ = SOCK_STREAM;
95 protocol = 0;
96 break;
97 case RFCOMM:
98 family = PF_BLUETOOTH;
99 typ = SOCK_STREAM;
100 protocol = BTPROTO_RFCOMM;
101 break;
102 case SCO:
103 family = PF_BLUETOOTH;
104 typ = SOCK_SEQPACKET;
105 protocol = BTPROTO_SCO;
106 break;
107 case L2CAP:
108 family = PF_BLUETOOTH;
109 typ = SOCK_SEQPACKET;
110 protocol = BTPROTO_L2CAP;
111 break;
112 case TCP:
113 family = PF_INET;
114 typ = SOCK_STREAM;
115 protocol = 0;
116 break;
117 }
118
119 printf("%d: socket()\n", gettid());
120 ret = socket(family, typ, protocol);
121 printf("%d: socket() = %d\n", gettid(), ret);
122 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
123
124 return ret;
125 }
126
_close(int fd,int type)127 static int _close(int fd, int type) {
128 int ret;
129
130 printf("%d: close(%d)\n", gettid(), fd);
131 ret = close(fd);
132 printf("%d: close(%d) = %d\n", gettid(), fd, ret);
133 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
134
135 return ret;
136 }
137
_bind(int fd,int type)138 static int _bind(int fd, int type) {
139 int len = 0;
140 int ret;
141 struct sockaddr *addr = NULL;
142
143 switch (type) {
144 case UNIX:
145 unlink(local_addr_un.sun_path);
146 addr = (struct sockaddr *) &local_addr_un;
147 len = sizeof(local_addr_un);
148 break;
149 case RFCOMM:
150 addr = (struct sockaddr *) &local_addr_rc;
151 len = sizeof(local_addr_rc);
152 break;
153 case SCO:
154 addr = (struct sockaddr *) &local_addr_sco;
155 len = sizeof(local_addr_sco);
156 break;
157 case L2CAP:
158 addr = (struct sockaddr *) &local_addr_l2;
159 len = sizeof(local_addr_l2);
160 break;
161 case TCP:
162 addr = (struct sockaddr *) &local_addr_in;
163 len = sizeof(local_addr_in);
164 break;
165 }
166
167 printf("%d: bind(%d)\n", gettid(), fd);
168 ret = bind(fd, addr, len);
169 printf("%d: bind(%d) = %d\n", gettid(), fd, ret);
170 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
171
172 return ret;
173 }
174
_listen(int fd,int type)175 static int _listen(int fd, int type) {
176 int ret;
177
178 printf("%d: listen(%d)\n", gettid(), fd);
179 ret = listen(fd, 1);
180 printf("%d: listen(%d) = %d\n", gettid(), fd, ret);
181 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
182
183 return ret;
184 }
185
_read(int fd)186 static int _read(int fd) {
187 int ret;
188 char buf;
189
190 printf("%d: read(%d)\n", gettid(), fd);
191 ret = read(fd, &buf, 1);
192 printf("%d: read(%d) = %d [%d]\n", gettid(), fd, ret, (int)buf);
193 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
194
195 return ret;
196 }
197
198
_accept(int fd,int type)199 static int _accept(int fd, int type) {
200 int ret;
201 int len;
202 struct sockaddr *addr = NULL;
203
204 switch (type) {
205 case UNIX:
206 addr = (struct sockaddr *) &remote_addr_un;
207 len = sizeof(remote_addr_un);
208 break;
209 case RFCOMM:
210 addr = (struct sockaddr *) &remote_addr_rc;
211 len = sizeof(remote_addr_rc);
212 break;
213 case SCO:
214 addr = (struct sockaddr *) &remote_addr_sco;
215 len = sizeof(remote_addr_sco);
216 break;
217 case L2CAP:
218 addr = (struct sockaddr *) &remote_addr_l2;
219 len = sizeof(remote_addr_l2);
220 break;
221 case TCP:
222 addr = (struct sockaddr *) &remote_addr_in;
223 len = sizeof(remote_addr_in);
224 break;
225 }
226
227 printf("%d: accept(%d)\n", gettid(), fd);
228 ret = accept(fd, addr, &len);
229 printf("%d: accept(%d) = %d\n", gettid(), fd, ret);
230 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
231 else {
232 printf("\tlen = %d\n", len);
233 }
234
235 return ret;
236 }
237
_connect(int fd,int type)238 static int _connect(int fd, int type) {
239 int ret;
240 int len = 0;
241 struct sockaddr *addr = NULL;
242
243 switch (type) {
244 case UNIX:
245 addr = (struct sockaddr *) &local_addr_un;
246 len = sizeof(local_addr_un);
247 break;
248 case RFCOMM:
249 addr = (struct sockaddr *) &local_addr_rc;
250 len = sizeof(local_addr_rc);
251 break;
252 case SCO:
253 addr = (struct sockaddr *) &local_addr_sco;
254 len = sizeof(local_addr_sco);
255 break;
256 case L2CAP:
257 addr = (struct sockaddr *) &local_addr_l2;
258 len = sizeof(local_addr_l2);
259 break;
260 case TCP:
261 addr = (struct sockaddr *) &local_addr_in;
262 len = sizeof(local_addr_in);
263 break;
264 }
265
266 printf("%d: connect(%d)\n", gettid(), fd);
267 ret = connect(fd, addr, len);
268 printf("%d: connect(%d) = %d\n", gettid(), fd, ret);
269 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
270
271 return ret;
272 }
273
_write(int fd,int type)274 static int _write(int fd, int type) {
275 int ret;
276 char buf = 69;
277
278 printf("%d: write(%d)\n", gettid(), fd);
279 ret = write(fd, &buf, 1);
280 printf("%d: write(%d) = %d\n", gettid(), fd, ret);
281 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
282
283 return ret;
284 }
285
_shutdown(int fd,int how)286 static int _shutdown(int fd, int how) {
287 int ret;
288
289 printf("%d: shutdown(%d)\n", gettid(), fd);
290 ret = shutdown(fd, how);
291 printf("%d: shutdown(%d) = %d\n", gettid(), fd, ret);
292 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
293
294 return ret;
295 }
296
_poll(struct pollfd * ufds,nfds_t nfds,int timeout)297 static int _poll(struct pollfd *ufds, nfds_t nfds, int timeout) {
298 int ret;
299 unsigned int i;
300
301 printf("%d: poll(", gettid());
302 print_fds(ufds, nfds);
303 printf(")\n");
304 ret = poll(ufds, nfds, timeout);
305 printf("%d: poll() = %d\n", gettid(), ret);
306 if (ret < 0) printf("\terr %d (%s)\n", errno, strerror(errno));
307 if (ret > 0) {
308 for (i=0; i<nfds; i++) {
309 if (ufds[i].revents) {
310 printf("\tfd %d ", ufds[i].fd); print_events(ufds[i].revents);
311 }
312 }
313 }
314 return ret;
315 }
316
thread_delay_close(struct thread_args * args)317 static void thread_delay_close(struct thread_args *args) {
318 printf("%d: START\n", gettid());
319 sleep(args->delay);
320 _close(args->fd, args->type);
321 printf("%d: END\n", gettid());
322 }
323
thread_poll(void * args)324 static void thread_poll(void *args) {
325 int fd = (int)args;
326 struct pollfd pfd;
327 printf("%d: START\n", gettid());
328 pfd.fd = fd;
329 pfd.events = 0;
330 _poll(&pfd, 1, -1);
331 printf("%d: END\n", gettid());
332 }
333
thread_read(void * args)334 static void thread_read(void *args) {
335 int fd = (int)args;
336 printf("%d: START\n", gettid());
337 _read(fd);
338 printf("%d: END\n", gettid());
339 }
340
thread_pollin(void * args)341 static void thread_pollin(void *args) {
342 int fd = (int)args;
343 struct pollfd pfd;
344 printf("%d: START\n", gettid());
345 pfd.fd = fd;
346 pfd.events = POLLIN;
347 _poll(&pfd, 1, -1);
348 printf("%d: END\n", gettid());
349 }
350
thread_shutdown(int fd)351 static void thread_shutdown(int fd) {
352 printf("%d: START\n", gettid());
353 sleep(4);
354 _shutdown(fd, SHUT_RDWR);
355 printf("%d: END\n", gettid());
356 }
357
thread_accept(struct thread_args * args)358 static void thread_accept(struct thread_args *args) {
359 printf("%d: START\n", gettid());
360 sleep(args->delay);
361 _accept(args->fd, args->type);
362 printf("%d: END\n", gettid());
363 }
364
thread_connect(struct thread_args * args)365 static void thread_connect(struct thread_args *args) {
366 printf("%d: START\n", gettid());
367 sleep(args->delay);
368 _connect(args->fd, args->type);
369 printf("%d: END\n", gettid());
370 }
371
thread_delay_close_write(struct thread_args * args)372 static void thread_delay_close_write(struct thread_args *args) {
373 printf("%d: START\n", gettid());
374 sleep(args->delay);
375 _close(args->fd, args->type);
376 sleep(args->delay);
377 _write(args->fd, args->type);
378 printf("%d: END\n", gettid());
379 }
380
thread_accept_write(struct thread_args * args)381 static void thread_accept_write(struct thread_args *args) {
382 printf("%d: START\n", gettid());
383 sleep(args->delay);
384 _accept(args->fd, args->type);
385 sleep(args->delay);
386 _write(args->fd, args->type);
387 printf("%d: END\n", gettid());
388 }
389
thread_delay_connect(struct thread_args * args)390 static void thread_delay_connect(struct thread_args *args) {
391 printf("%d: START\n", gettid());
392 sleep(args->delay);
393 args->fd = _socket(args->type);
394 _connect(args->fd, args->type);
395 printf("%d: END\n", gettid());
396 }
397
do_accept_accept_accept(int type)398 static int do_accept_accept_accept(int type) {
399 int fd;
400
401 fd = _socket(type);
402 if (fd < 0) goto error;
403
404 if (_bind(fd, type) < 0) goto error;
405
406 if (_listen(fd, type) < 0) goto error;
407
408 while (1) {
409 _accept(fd, type);
410 }
411
412 return 0;
413
414 error:
415 return -1;
416 }
417
do_accept_and_close(int type)418 static int do_accept_and_close(int type) {
419 int fd;
420 pthread_t thread;
421 struct thread_args args = {-1, type, 1};
422
423 fd = _socket(type);
424 if (fd < 0) goto error;
425
426 if (_bind(fd, type) < 0) goto error;
427
428 if (_listen(fd, type) < 0) goto error;
429
430 args.fd = fd;
431 pthread_create(&thread, NULL, (void *)thread_delay_close, (void *)&args);
432
433 _accept(fd, type);
434
435 pthread_join(thread, NULL);
436
437 return 0;
438
439 error:
440 return -1;
441 }
442
do_accept_shutdown(int type)443 static int do_accept_shutdown(int type) {
444 int fd;
445 pthread_t thread;
446 struct thread_args args = {-1, type, 0};
447
448 fd = _socket(type);
449 if (fd < 0) goto error;
450
451 if (_bind(fd, type) < 0) goto error;
452
453 if (_listen(fd, type) < 0) goto error;
454
455 args.fd = fd;
456 pthread_create(&thread, NULL, (void *)thread_accept, (void *)&args);
457
458 sleep(4);
459 _shutdown(fd, SHUT_RDWR);
460
461 pthread_join(thread, NULL);
462
463 _close(fd, type);
464
465 return 0;
466
467 error:
468 return -1;
469 }
470
do_connect_shutdown(int type)471 static int do_connect_shutdown(int type) {
472 int fd;
473 pthread_t thread;
474 struct thread_args args = {-1, type, 0};
475
476 fd = _socket(type);
477 if (fd < 0) goto error;
478
479 args.fd = fd;
480 pthread_create(&thread, NULL, (void *)thread_connect, (void *)&args);
481
482 sleep(4);
483 _shutdown(fd, SHUT_RDWR);
484
485 pthread_join(thread, NULL);
486
487 _close(fd, type);
488
489 return 0;
490
491 error:
492 return -1;
493 }
494
495 // accept in one thread. close then write in another
do_accept_close_write(int type)496 static int do_accept_close_write(int type) {
497 int fd;
498 pthread_t thread;
499 struct thread_args args = {-1, type, 1};
500
501 fd = _socket(type);
502 if (fd < 0) goto error;
503
504 if (_bind(fd, type) < 0) goto error;
505
506 if (_listen(fd, type) < 0) goto error;
507
508 args.fd = fd;
509 pthread_create(&thread, NULL, (void *)thread_delay_close_write, (void *)&args);
510
511 _accept(fd, type);
512
513 pthread_join(thread, NULL);
514
515 return 0;
516
517 error:
518 return -1;
519 }
520
do_poll_poll_poll_shutdown(int type)521 static int do_poll_poll_poll_shutdown(int type) {
522 const int MAX_T = 32;
523 int fd;
524 pthread_t t[MAX_T];
525 int i;
526
527 fd = _socket(type);
528
529 for (i=0; i<MAX_T; i++)
530 pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
531
532 sleep(1);
533
534 _shutdown(fd, SHUT_RDWR);
535
536 for (i=0; i<MAX_T; i++)
537 pthread_join(t[i], NULL);
538
539 _close(fd, type);
540
541 return 0;
542 }
543
do_poll_poll_poll_close(int type)544 static int do_poll_poll_poll_close(int type) {
545 const int MAX_T = 32;
546 int fd;
547 pthread_t t[MAX_T];
548 int i;
549
550 fd = _socket(type);
551
552 for (i=0; i<MAX_T; i++)
553 pthread_create(&t[i], NULL, (void *)thread_poll, (void *)fd);
554
555 sleep(1);
556
557 _close(fd, type);
558
559 for (i=0; i<MAX_T; i++)
560 pthread_join(t[i], NULL);
561
562 return 0;
563 }
564
do_read_read_read_close(int type)565 static int do_read_read_read_close(int type) {
566 const int MAX_T = 32;
567 int fd;
568 pthread_t t[MAX_T];
569 int i;
570
571 fd = _socket(type);
572
573 for (i=0; i<MAX_T; i++)
574 pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
575
576 sleep(1);
577
578 _close(fd, type);
579
580 for (i=0; i<MAX_T; i++)
581 pthread_join(t[i], NULL);
582
583 return 0;
584 }
585
do_read_read_read_shutdown(int type)586 static int do_read_read_read_shutdown(int type) {
587 const int MAX_T = 32;
588 int fd;
589 pthread_t t[MAX_T];
590 int i;
591
592 fd = _socket(type);
593
594 for (i=0; i<MAX_T; i++)
595 pthread_create(&t[i], NULL, (void *)thread_read, (void *)fd);
596
597 sleep(1);
598
599 _shutdown(fd, SHUT_RDWR);
600
601 for (i=0; i<MAX_T; i++)
602 pthread_join(t[i], NULL);
603
604 _close(fd, type);
605
606 return 0;
607 }
608
do_connected_read1_shutdown1(int type)609 static int do_connected_read1_shutdown1(int type) {
610 int fd1, fd2;
611 pthread_t t1;
612 pthread_t t2;
613 struct thread_args a1 = {-1, type, 0};
614 struct thread_args a2 = {-1, type, 2};
615
616 fd1 = _socket(type);
617 if (fd1 < 0) goto error;
618
619 if (_bind(fd1, type) < 0) goto error;
620
621 if (_listen(fd1, type) < 0) goto error;
622
623 a1.fd = fd1;
624 pthread_create(&t1, NULL, (void *)thread_accept_write, (void *)&a1);
625
626 fd2 = _socket(type);
627 if (_connect(fd2, type)) goto error;
628
629 pthread_create(&t2, NULL, (void *)thread_shutdown, (void *)&fd2);
630
631 while (1) if (_read(fd2)) break;
632
633 pthread_join(t1, NULL);
634 pthread_join(t2, NULL);
635
636 return 0;
637
638 error:
639 return -1;
640 }
641
642 // accept in one thread, connect from two different threads
do_accept_connect_connect(int type)643 static int do_accept_connect_connect(int type) {
644 int fd;
645 pthread_t t1;
646 pthread_t t2;
647 struct thread_args a1 = {-1, type, 1};
648 struct thread_args a2 = {-1, type, 2};
649
650 fd = _socket(type);
651 if (fd < 0) goto error;
652
653 if (_bind(fd, type) < 0) goto error;
654
655 if (_listen(fd, type) < 0) goto error;
656
657 pthread_create(&t1, NULL, (void *)thread_delay_connect, (void *)&a1);
658 pthread_create(&t2, NULL, (void *)thread_delay_connect, (void *)&a2);
659
660 _accept(fd, type);
661
662 pthread_join(t1, NULL);
663 pthread_join(t2, NULL);
664
665 return 0;
666
667 error:
668 return -1;
669 }
670
671 struct {
672 char *name;
673 int (*ptr)(int);
674 } action_table[] = {
675 {"accept_accept_accept", do_accept_accept_accept},
676 {"accept_and_close", do_accept_and_close},
677 {"accept_shutdown", do_accept_shutdown},
678 {"connect_shutdown", do_connect_shutdown},
679 {"accept_close_write", do_accept_close_write},
680 {"accept_connect_connect", do_accept_connect_connect},
681 {"poll_poll_poll_shutdown", do_poll_poll_poll_shutdown},
682 {"poll_poll_poll_close", do_poll_poll_poll_close},
683 {"read_read_read_shutdown", do_read_read_read_shutdown},
684 {"read_read_read_close", do_read_read_read_close},
685 {"connected_read1_shutdown1", do_connected_read1_shutdown1},
686 {NULL, NULL},
687 };
688
689 struct {
690 char *name;
691 enum sock_type type;
692 } type_table[] = {
693 {"unix", UNIX},
694 {"rfcomm", RFCOMM},
695 {"sco", SCO},
696 {"l2cap", L2CAP},
697 {"tcp", TCP},
698 {NULL, -1},
699 };
700
usage()701 static void usage() {
702 int i;
703
704 printf("socktest TYPE ACTION\n");
705 printf("\nTYPE:\n");
706 for (i = 0; type_table[i].name; i++) {
707 printf("\t%s\n", type_table[i].name);
708 }
709 printf("\nACTION:\n");
710 for (i = 0; action_table[i].name; i++) {
711 printf("\t%s\n", action_table[i].name);
712 }
713 }
714
main(int argc,char ** argv)715 int main(int argc, char **argv) {
716 int i;
717 int type = -1;
718
719 if (argc != 3) {
720 usage();
721 return -1;
722 }
723 for (i = 0; type_table[i].name; i++) {
724 if (!strcmp(argv[1], type_table[i].name)) {
725 type = type_table[i].type;
726 break;
727 }
728 }
729 if (type == -1) {
730 usage();
731 return -1;
732 }
733 for (i = 0; action_table[i].name; i++) {
734 if (!strcmp(argv[2], action_table[i].name)) {
735 printf("TYPE = %s ACTION = %s\n", type_table[type].name,
736 action_table[i].name);
737 return (*action_table[i].ptr)(type);
738 }
739 }
740 usage();
741 return -1;
742 }
743