]> granicus.if.org Git - strace/blob - tests/net-yy-inet.c
strace: terminate itself if interrupted by a signal
[strace] / tests / net-yy-inet.c
1 /*
2  * This file is part of net-yy-inet strace test.
3  *
4  * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org>
5  * Copyright (c) 2016-2018 The strace developers.
6  * All rights reserved.
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "tests.h"
12 #include <assert.h>
13 #include <stddef.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <netinet/tcp.h>
20 #include <arpa/inet.h>
21
22 #include "accept_compat.h"
23
24 #ifndef ADDR_FAMILY
25 # define ADDR_FAMILY_FIELD sin_family
26 # define ADDR_FAMILY AF_INET
27 # define AF_STR "AF_INET"
28 # define LOOPBACK_FIELD .sin_addr.s_addr = htonl(INADDR_LOOPBACK)
29 # define LOOPBACK "127.0.0.1"
30 # define SOCKADDR_TYPE sockaddr_in
31 # define TCP_STR "TCP"
32 # define INPORT sin_port
33 # define INPORT_STR "sin_port"
34 # define INADDR_STR "sin_addr=inet_addr(\"" LOOPBACK "\")"
35 # define SA_FIELDS ""
36 #endif
37
38 int
39 main(void)
40 {
41         skip_if_unavailable("/proc/self/fd/");
42
43         const struct SOCKADDR_TYPE addr = {
44                 .ADDR_FAMILY_FIELD = ADDR_FAMILY,
45                 LOOPBACK_FIELD
46         };
47         struct sockaddr * const listen_sa = tail_memdup(&addr, sizeof(addr));
48         TAIL_ALLOC_OBJECT_CONST_PTR(socklen_t, len);
49         *len = sizeof(addr);
50
51         const int listen_fd = socket(ADDR_FAMILY, SOCK_STREAM, 0);
52         if (listen_fd < 0)
53                 perror_msg_and_skip("socket");
54         const unsigned long listen_inode = inode_of_sockfd(listen_fd);
55         printf("socket(" AF_STR ", SOCK_STREAM, IPPROTO_IP) = %d<" TCP_STR
56                ":[%lu]>\n",
57                listen_fd, listen_inode);
58
59         if (bind(listen_fd, listen_sa, *len))
60                 perror_msg_and_skip("bind");
61         printf("bind(%d<" TCP_STR ":[%lu]>, {sa_family=" AF_STR ", " INPORT_STR
62                "=htons(0), " INADDR_STR SA_FIELDS "}, %u) = 0\n",
63                listen_fd, listen_inode, (unsigned) *len);
64
65         if (listen(listen_fd, 1))
66                 perror_msg_and_skip("listen");
67         printf("listen(%d<" TCP_STR ":[%lu]>, 1) = 0\n",
68                listen_fd, listen_inode);
69
70         memset(listen_sa, 0, sizeof(addr));
71         *len = sizeof(addr);
72         if (getsockname(listen_fd, listen_sa, len))
73                 perror_msg_and_fail("getsockname");
74         const unsigned int listen_port =
75                 ntohs(((struct SOCKADDR_TYPE *) listen_sa)->INPORT);
76         printf("getsockname(%d<" TCP_STR ":[" LOOPBACK ":%u]>, {sa_family="
77                AF_STR ", " INPORT_STR "=htons(%u), " INADDR_STR SA_FIELDS "}"
78                ", [%u]) = 0\n",
79                listen_fd, listen_port, listen_port, (unsigned) *len);
80
81         TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, optval);
82         *len = sizeof(*optval);
83         if (getsockopt(listen_fd, SOL_TCP, TCP_MAXSEG, optval, len))
84                 perror_msg_and_fail("getsockopt");
85         printf("getsockopt(%d<" TCP_STR ":[" LOOPBACK ":%u]>, SOL_TCP, "
86                "TCP_MAXSEG, [%u], [%u]) = 0\n",
87                listen_fd, listen_port, *optval, (unsigned) *len);
88
89         const int connect_fd = socket(ADDR_FAMILY, SOCK_STREAM, 0);
90         if (connect_fd < 0)
91                 perror_msg_and_fail("socket");
92         const unsigned long connect_inode = inode_of_sockfd(connect_fd);
93         printf("socket(" AF_STR ", SOCK_STREAM, IPPROTO_IP) = %d<" TCP_STR
94                ":[%lu]>\n",
95                connect_fd, connect_inode);
96
97         *len = sizeof(addr);
98         if (connect(connect_fd, listen_sa, *len))
99                 perror_msg_and_fail("connect");
100         printf("connect(%d<" TCP_STR ":[%lu]>, {sa_family=" AF_STR ", "
101                INPORT_STR "=htons(%u), " INADDR_STR SA_FIELDS "}, %u) = 0\n",
102                connect_fd, connect_inode, listen_port, (unsigned) *len);
103
104         struct sockaddr * const accept_sa = tail_alloc(sizeof(addr));
105         memset(accept_sa, 0, sizeof(addr));
106         *len = sizeof(addr);
107         const int accept_fd = do_accept(listen_fd, accept_sa, len);
108         if (accept_fd < 0)
109                 perror_msg_and_fail("accept");
110         const unsigned int connect_port =
111                 ntohs(((struct SOCKADDR_TYPE *) accept_sa)->INPORT);
112         printf("accept(%d<" TCP_STR ":[" LOOPBACK ":%u]>, {sa_family=" AF_STR
113                ", " INPORT_STR "=htons(%u), " INADDR_STR SA_FIELDS "}"
114                ", [%u]) = %d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>\n",
115                listen_fd, listen_port, connect_port, (unsigned) *len,
116                accept_fd, listen_port, connect_port);
117
118         memset(accept_sa, 0, sizeof(addr));
119         *len = sizeof(addr);
120         if (getpeername(accept_fd, accept_sa, len))
121                 perror_msg_and_fail("getpeername");
122         printf("getpeername(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>"
123                ", {sa_family=" AF_STR ", " INPORT_STR "=htons(%u)"
124                ", " INADDR_STR SA_FIELDS "}, [%u]) = 0\n",
125                accept_fd, listen_port, connect_port, connect_port,
126                (unsigned) *len);
127
128         memset(listen_sa, 0, sizeof(addr));
129         *len = sizeof(addr);
130         if (getpeername(connect_fd, listen_sa, len))
131                 perror_msg_and_fail("getpeername");
132         printf("getpeername(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>"
133                ", {sa_family=" AF_STR ", " INPORT_STR "=htons(%u)"
134                ", " INADDR_STR SA_FIELDS "}, [%u]) = 0\n",
135                connect_fd, connect_port, listen_port, listen_port,
136                (unsigned) *len);
137
138         *len = sizeof(*optval);
139         if (setsockopt(connect_fd, SOL_TCP, TCP_MAXSEG, optval, *len))
140                 perror_msg_and_fail("setsockopt");
141         printf("setsockopt(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>"
142                ", SOL_TCP, TCP_MAXSEG, [%u], %u) = 0\n",
143                connect_fd, connect_port, listen_port, *optval,
144                (unsigned) *len);
145
146         char text[] = "text";
147         assert(sendto(connect_fd, text, sizeof(text) - 1,
148                MSG_DONTROUTE | MSG_DONTWAIT, NULL, 0) == sizeof(text) - 1);
149         printf("sendto(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>, "
150                "\"%s\", %u, MSG_DONTROUTE|MSG_DONTWAIT, NULL, 0) = %u\n",
151                connect_fd, connect_port, listen_port, text,
152                (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
153
154         assert(close(connect_fd) == 0);
155         printf("close(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>) = "
156                "0\n",
157                connect_fd, connect_port, listen_port);
158
159         assert(recvfrom(accept_fd, text, sizeof(text) - 1, MSG_WAITALL,
160                         NULL, NULL) == sizeof(text) - 1);
161         printf("recvfrom(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>, "
162                "\"%s\", %u, MSG_WAITALL, NULL, NULL) = %u\n",
163                accept_fd, listen_port, connect_port, text,
164                (unsigned) sizeof(text) - 1, (unsigned) sizeof(text) - 1);
165
166         assert(close(accept_fd) == 0);
167         printf("close(%d<" TCP_STR ":[" LOOPBACK ":%u->" LOOPBACK ":%u]>) = "
168                "0\n",
169                accept_fd, listen_port, connect_port);
170
171         assert(close(listen_fd) == 0);
172         printf("close(%d<" TCP_STR ":[" LOOPBACK ":%u]>) = 0\n",
173                listen_fd, listen_port);
174
175         puts("+++ exited with 0 +++");
176         return 0;
177 }