summaryrefslogtreecommitdiff
path: root/tests/t_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/t_socket.c')
-rw-r--r--tests/t_socket.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/tests/t_socket.c b/tests/t_socket.c
index ab4b785..20a0c0a 100644
--- a/tests/t_socket.c
+++ b/tests/t_socket.c
@@ -78,15 +78,17 @@ static int sock_flag(int s, int level, int option) {
78} 78}
79 79
80/* Wait for one event, so a test never blocks forever on a lost packet */ 80/* Wait for one event, so a test never blocks forever on a lost packet */
81static int wait_for(int s, short events) { 81static int wait_for_ms(int s, short events, int timeout_ms) {
82 struct pollfd pfd; 82 struct pollfd pfd;
83 83
84 pfd.fd = s; 84 pfd.fd = s;
85 pfd.events = events; 85 pfd.events = events;
86 pfd.revents = 0; 86 pfd.revents = 0;
87 return poll(&pfd, 1, 2000) == 1; 87 return poll(&pfd, 1, timeout_ms) == 1;
88} 88}
89 89
90static int wait_for(int s, short events) { return wait_for_ms(s, events, 2000); }
91
90/* ------------------------------------------------------------ invariants */ 92/* ------------------------------------------------------------ invariants */
91 93
92/* Asked for the wildcard address, because a socket bound to one specific 94/* Asked for the wildcard address, because a socket bound to one specific
@@ -200,6 +202,42 @@ static void case_a_signal_ends_a_blocking_read(void) {
200 close(reader_socket); 202 close(reader_socket);
201} 203}
202 204
205/* What a deferred accept is for is a descriptor that already has the request
206 in it, so what is checked is the silence before: a client that has
207 connected but said nothing must not make the listener readable. Kernels
208 that cannot do this say so, and then there is nothing to check. */
209static void case_deferred_accept(void) {
210 struct sockaddr_in6 address;
211 char ip[16];
212 uint16_t port = 0;
213 int listener, client;
214
215 test_case("a connection that has sent nothing is held back from accept");
216 listener = socket_tcp_listen(ip_loopback, 0, SOCKET_EXCLUSIVE);
217 CHECK(listener != -1);
218 if (socket_defer_accept(listener) == -1) {
219 close(listener);
220 return;
221 }
222 bound_address(listener, ip, &port);
223
224 client = socket(AF_INET6, SOCK_STREAM, 0);
225 CHECK(client != -1);
226 memset(&address, 0, sizeof(address));
227 address.sin6_family = AF_INET6;
228 address.sin6_port = htons(port);
229 memcpy(&address.sin6_addr, ip_loopback, 16);
230 CHECK_INT(connect(client, (struct sockaddr *)&address, sizeof(address)), 0);
231
232 CHECK_INT(wait_for_ms(listener, POLLIN, 300), 0);
233
234 CHECK_INT((int)write(client, "GET / HTTP/1.0\r\n\r\n", 18), 18);
235 CHECK_INT(wait_for(listener, POLLIN), 1);
236
237 close(client);
238 close(listener);
239}
240
203/* An IPv4 peer must arrive in the v4 mapped form opentracker stores, however 241/* An IPv4 peer must arrive in the v4 mapped form opentracker stores, however
204 the kernel chose to report it. Linux fills a v4 mapped sockaddr_in6 here 242 the kernel chose to report it. Linux fills a v4 mapped sockaddr_in6 here
205 and the BSDs fill a plain sockaddr_in, so this is the case that tells the 243 and the BSDs fill a plain sockaddr_in, so this is the case that tells the
@@ -352,6 +390,7 @@ void test_socket(void) {
352 case_a_signal_ends_a_blocking_read(); 390 case_a_signal_ends_a_blocking_read();
353 case_udp_v4mapped(); 391 case_udp_v4mapped();
354 case_tcp_roundtrip(); 392 case_tcp_roundtrip();
393 case_deferred_accept();
355 case_connect_refused(); 394 case_connect_refused();
356 case_bind_failure(); 395 case_bind_failure();
357#ifdef WANT_SYNC_LIVE 396#ifdef WANT_SYNC_LIVE