Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / native_client_sdk / src / tests / nacl_io_socket_test / socket_test.cc
blobdafa87227a0c833d198507b74b4ef1c9eb3ebb31
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <arpa/inet.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <netinet/in.h>
9 #include <pthread.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <sys/stat.h>
14 #include <map>
15 #include <string>
17 #include "echo_server.h"
18 #include "gmock/gmock.h"
19 #include "gtest/gtest.h"
20 #include "nacl_io/kernel_intercept.h"
21 #include "nacl_io/kernel_proxy.h"
22 #include "nacl_io/ossocket.h"
23 #include "nacl_io/ostypes.h"
24 #include "ppapi/cpp/message_loop.h"
25 #include "ppapi_simple/ps.h"
27 #ifdef PROVIDES_SOCKET_API
29 using namespace nacl_io;
30 using namespace sdk_util;
32 #define LOCAL_HOST 0x7F000001
33 #define PORT1 4006
34 #define PORT2 4007
35 #define ANY_PORT 0
37 namespace {
39 void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) {
40 memset(addr, 0, sizeof(*addr));
42 addr->sin_family = AF_INET;
43 addr->sin_port = htons(port);
44 addr->sin_addr.s_addr = htonl(ip);
47 static int ki_fcntl_wrapper(int fd, int request, ...) {
48 va_list ap;
49 va_start(ap, request);
50 int rtn = ki_fcntl(fd, request, ap);
51 va_end(ap);
52 return rtn;
55 static void SetNonBlocking(int sock) {
56 int flags = ki_fcntl_wrapper(sock, F_GETFL);
57 ASSERT_NE(-1, flags);
58 flags |= O_NONBLOCK;
59 ASSERT_EQ(0, ki_fcntl_wrapper(sock, F_SETFL, flags));
60 ASSERT_EQ(flags, ki_fcntl_wrapper(sock, F_GETFL));
63 class SocketTest : public ::testing::Test {
64 public:
65 SocketTest() : sock1_(-1), sock2_(-1) {}
67 void TearDown() {
68 if (sock1_ != -1)
69 EXPECT_EQ(0, ki_close(sock1_));
70 if (sock2_ != -1)
71 EXPECT_EQ(0, ki_close(sock2_));
74 int Bind(int fd, uint32_t ip, uint16_t port) {
75 sockaddr_in addr;
76 socklen_t addrlen = sizeof(addr);
78 IP4ToSockAddr(ip, port, &addr);
79 int err = ki_bind(fd, (sockaddr*)&addr, addrlen);
81 if (err == -1)
82 return errno;
83 return 0;
86 protected:
87 int sock1_;
88 int sock2_;
91 class SocketTestUDP : public SocketTest {
92 public:
93 SocketTestUDP() {}
95 void SetUp() {
96 sock1_ = ki_socket(AF_INET, SOCK_DGRAM, 0);
97 sock2_ = ki_socket(AF_INET, SOCK_DGRAM, 0);
99 EXPECT_GT(sock1_, -1);
100 EXPECT_GT(sock2_, -1);
104 class SocketTestTCP : public SocketTest {
105 public:
106 SocketTestTCP() {}
108 void SetUp() {
109 sock1_ = ki_socket(AF_INET, SOCK_STREAM, 0);
110 sock2_ = ki_socket(AF_INET, SOCK_STREAM, 0);
112 EXPECT_GT(sock1_, -1);
113 EXPECT_GT(sock2_, -1);
117 class SocketTestWithServer : public ::testing::Test {
118 public:
119 SocketTestWithServer() : instance_(PSGetInstanceId()) {
120 pthread_mutex_init(&ready_lock_, NULL);
121 pthread_cond_init(&ready_cond_, NULL);
124 void ServerThreadMain() {
125 loop_.AttachToCurrentThread();
126 pp::Instance instance(PSGetInstanceId());
127 EchoServer server(&instance, PORT1, ServerLog, &ready_cond_, &ready_lock_);
128 loop_.Run();
131 static void* ServerThreadMainStatic(void* arg) {
132 SocketTestWithServer* test = (SocketTestWithServer*)arg;
133 test->ServerThreadMain();
134 return NULL;
137 void SetUp() {
138 loop_ = pp::MessageLoop(&instance_);
139 pthread_mutex_lock(&ready_lock_);
141 // Start an echo server on a background thread.
142 pthread_create(&server_thread_, NULL, ServerThreadMainStatic, this);
144 // Wait for thread to signal that it is ready to accept connections.
145 pthread_cond_wait(&ready_cond_, &ready_lock_);
146 pthread_mutex_unlock(&ready_lock_);
148 sock_ = ki_socket(AF_INET, SOCK_STREAM, 0);
149 EXPECT_GT(sock_, -1);
152 void TearDown() {
153 // Stop the echo server and the background thread it runs on
154 loop_.PostQuit(true);
155 pthread_join(server_thread_, NULL);
156 ASSERT_EQ(0, ki_close(sock_));
159 static void ServerLog(const char* msg) {
160 // Uncomment to see logs of echo server on stdout
161 //printf("server: %s\n", msg);
164 protected:
165 int sock_;
166 pp::MessageLoop loop_;
167 pp::Instance instance_;
168 pthread_cond_t ready_cond_;
169 pthread_mutex_t ready_lock_;
170 pthread_t server_thread_;
173 } // namespace
175 TEST(SocketTestSimple, Socket) {
176 EXPECT_EQ(-1, ki_socket(AF_UNIX, SOCK_STREAM, 0));
177 EXPECT_EQ(errno, EAFNOSUPPORT);
179 // We don't support RAW sockets
180 EXPECT_EQ(-1, ki_socket(AF_INET, SOCK_RAW, IPPROTO_TCP));
181 EXPECT_EQ(EPROTONOSUPPORT, errno);
183 // Invalid type
184 EXPECT_EQ(-1, ki_socket(AF_INET, -1, 0));
185 EXPECT_EQ(EINVAL, errno);
187 int sock1_ = ki_socket(AF_INET, SOCK_DGRAM, 0);
188 EXPECT_NE(-1, sock1_);
190 int sock2_ = ki_socket(AF_INET6, SOCK_DGRAM, 0);
191 EXPECT_NE(-1, sock2_);
193 int sock3 = ki_socket(AF_INET, SOCK_STREAM, 0);
194 EXPECT_NE(-1, sock3);
196 int sock4 = ki_socket(AF_INET6, SOCK_STREAM, 0);
197 EXPECT_NE(-1, sock4);
199 ki_close(sock1_);
200 ki_close(sock2_);
201 ki_close(sock3);
202 ki_close(sock4);
205 TEST_F(SocketTestUDP, Bind) {
206 // Bind away.
207 EXPECT_EQ(0, Bind(sock1_, LOCAL_HOST, PORT1));
209 // Invalid to rebind a socket.
210 EXPECT_EQ(EINVAL, Bind(sock1_, LOCAL_HOST, PORT1));
212 // Addr in use.
213 EXPECT_EQ(EADDRINUSE, Bind(sock2_, LOCAL_HOST, PORT1));
215 // Bind with a wildcard.
216 EXPECT_EQ(0, Bind(sock2_, LOCAL_HOST, ANY_PORT));
218 // Invalid to rebind after wildcard
219 EXPECT_EQ(EINVAL, Bind(sock2_, LOCAL_HOST, PORT1));
222 TEST_F(SocketTestUDP, SendRcv) {
223 char outbuf[256];
224 char inbuf[512];
226 memset(outbuf, 1, sizeof(outbuf));
227 memset(inbuf, 0, sizeof(inbuf));
229 EXPECT_EQ(0, Bind(sock1_, LOCAL_HOST, PORT1));
230 EXPECT_EQ(0, Bind(sock2_, LOCAL_HOST, PORT2));
232 sockaddr_in addr;
233 socklen_t addrlen = sizeof(addr);
234 IP4ToSockAddr(LOCAL_HOST, PORT2, &addr);
236 int len1 =
237 ki_sendto(sock1_, outbuf, sizeof(outbuf), 0, (sockaddr*) &addr, addrlen);
238 EXPECT_EQ(sizeof(outbuf), len1);
240 // Ensure the buffers are different
241 EXPECT_NE(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
242 memset(&addr, 0, sizeof(addr));
244 // Try to receive the previously sent packet
245 int len2 =
246 ki_recvfrom(sock2_, inbuf, sizeof(inbuf), 0, (sockaddr*) &addr, &addrlen);
247 EXPECT_EQ(sizeof(outbuf), len2);
248 EXPECT_EQ(sizeof(sockaddr_in), addrlen);
249 EXPECT_EQ(PORT1, htons(addr.sin_port));
251 // Now they should be the same
252 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
255 TEST_F(SocketTestUDP, SendRcvUnbound) {
256 char outbuf[256];
257 char inbuf[512];
259 memset(outbuf, 1, sizeof(outbuf));
260 memset(inbuf, 0, sizeof(inbuf));
262 // Don't bind sock1_, this will automatically bind sock1_ to a random port
263 // at the time of the first send.
264 EXPECT_EQ(0, Bind(sock2_, LOCAL_HOST, PORT2));
266 sockaddr_in addr;
267 sockaddr_in addr2;
268 socklen_t addrlen = sizeof(addr2);
269 IP4ToSockAddr(LOCAL_HOST, PORT2, &addr2);
271 // The first send hasn't occurred, so the socket is not yet bound.
272 socklen_t out_addrlen = sizeof(addr);
273 ASSERT_EQ(0, ki_getsockname(sock1_, (sockaddr*)&addr, &out_addrlen));
274 EXPECT_EQ(addrlen, out_addrlen);
275 EXPECT_EQ(0, htonl(addr.sin_addr.s_addr));
276 EXPECT_EQ(0, htons(addr.sin_port));
278 int len1 =
279 ki_sendto(sock1_, outbuf, sizeof(outbuf), 0, (sockaddr*) &addr2, addrlen);
280 EXPECT_EQ(sizeof(outbuf), len1);
282 // After the first send, the socket should be bound; the port is set, but
283 // the address is still 0.
284 ASSERT_EQ(0, ki_getsockname(sock1_, (sockaddr*)&addr, &out_addrlen));
285 EXPECT_EQ(addrlen, out_addrlen);
286 EXPECT_EQ(0, htonl(addr.sin_addr.s_addr));
287 EXPECT_NE(0, htons(addr.sin_port));
289 // Ensure the buffers are different
290 EXPECT_NE(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
292 // Try to receive the previously sent packet
293 int len2 =
294 ki_recvfrom(sock2_, inbuf, sizeof(inbuf), 0, (sockaddr*) &addr, &addrlen);
295 EXPECT_EQ(sizeof(outbuf), len2);
296 EXPECT_EQ(sizeof(sockaddr_in), addrlen);
297 EXPECT_EQ(LOCAL_HOST, htonl(addr.sin_addr.s_addr));
298 EXPECT_NE(0, htons(addr.sin_port));
300 // Now they should be the same
301 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
304 const size_t kQueueSize = 65536 * 8;
305 TEST_F(SocketTestUDP, FullFifo) {
306 char outbuf[16 * 1024];
308 ASSERT_EQ(0, Bind(sock1_, LOCAL_HOST, PORT1));
309 ASSERT_EQ(0, Bind(sock2_, LOCAL_HOST, PORT2));
311 sockaddr_in addr;
312 socklen_t addrlen = sizeof(addr);
313 IP4ToSockAddr(LOCAL_HOST, PORT2, &addr);
315 size_t total = 0;
316 while (total < kQueueSize * 8) {
317 int len = ki_sendto(sock1_, outbuf, sizeof(outbuf), MSG_DONTWAIT,
318 (sockaddr*) &addr, addrlen);
320 if (len <= 0) {
321 EXPECT_EQ(-1, len);
322 EXPECT_EQ(EWOULDBLOCK, errno);
323 break;
326 if (len >= 0) {
327 EXPECT_EQ(sizeof(outbuf), len);
328 total += len;
331 EXPECT_GT(total, kQueueSize - 1);
332 EXPECT_LT(total, kQueueSize * 8);
335 TEST_F(SocketTestWithServer, TCPConnect) {
336 char outbuf[256];
337 char inbuf[512];
339 memset(outbuf, 1, sizeof(outbuf));
341 sockaddr_in addr;
342 socklen_t addrlen = sizeof(addr);
344 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
346 ASSERT_EQ(0, ki_connect(sock_, (sockaddr*) &addr, addrlen))
347 << "Failed with " << errno << ": " << strerror(errno);
349 // Send two different messages to the echo server and verify the
350 // response matches.
351 strcpy(outbuf, "hello");
352 memset(inbuf, 0, sizeof(inbuf));
353 ASSERT_EQ(sizeof(outbuf), ki_write(sock_, outbuf, sizeof(outbuf)))
354 << "socket write failed with: " << strerror(errno);
355 ASSERT_EQ(sizeof(outbuf), ki_read(sock_, inbuf, sizeof(inbuf)));
356 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
358 strcpy(outbuf, "world");
359 memset(inbuf, 0, sizeof(inbuf));
360 ASSERT_EQ(sizeof(outbuf), ki_write(sock_, outbuf, sizeof(outbuf)));
361 ASSERT_EQ(sizeof(outbuf), ki_read(sock_, inbuf, sizeof(inbuf)));
362 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
365 TEST_F(SocketTestWithServer, TCPConnectNonBlock) {
366 char outbuf[256];
367 //char inbuf[512];
369 memset(outbuf, 1, sizeof(outbuf));
371 sockaddr_in addr;
372 socklen_t addrlen = sizeof(addr);
374 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
376 SetNonBlocking(sock_);
377 ASSERT_EQ(-1, ki_connect(sock_, (sockaddr*) &addr, addrlen));
378 ASSERT_EQ(EINPROGRESS, errno)
379 << "expected EINPROGRESS but got: " << strerror(errno);
380 ASSERT_EQ(-1, ki_connect(sock_, (sockaddr*) &addr, addrlen));
381 ASSERT_EQ(EALREADY, errno);
383 // Wait for the socket connection to complete using poll()
384 struct pollfd pollfd = { sock_, POLLIN|POLLOUT, 0 };
385 ASSERT_EQ(1, ki_poll(&pollfd, 1, -1));
386 ASSERT_EQ(POLLOUT, pollfd.revents);
388 // Attempts to connect again should yield EISCONN
389 ASSERT_EQ(-1, ki_connect(sock_, (sockaddr*) &addr, addrlen));
390 ASSERT_EQ(EISCONN, errno);
392 // And SO_ERROR should be 0.
395 TEST_F(SocketTestTCP, TCPConnectFails) {
396 sockaddr_in addr;
397 socklen_t addrlen = sizeof(addr);
399 // 10 is an unassigned well-known port, nothing should be bound to it.
400 IP4ToSockAddr(LOCAL_HOST, 10, &addr);
401 ASSERT_EQ(-1, ki_connect(sock1_, (sockaddr*) &addr, addrlen));
402 ASSERT_EQ(ECONNREFUSED, errno);
405 TEST_F(SocketTest, Getsockopt) {
406 sock1_ = ki_socket(AF_INET, SOCK_STREAM, 0);
407 EXPECT_GT(sock1_, -1);
408 int socket_error = 99;
409 socklen_t len = sizeof(socket_error);
411 // Test for valid option (SO_ERROR) which should be 0 when a socket
412 // is first created.
413 ASSERT_EQ(0, ki_getsockopt(sock1_, SOL_SOCKET, SO_ERROR,
414 &socket_error, &len));
415 ASSERT_EQ(0, socket_error);
416 ASSERT_EQ(sizeof(socket_error), len);
418 // Test for an invalid option (-1)
419 ASSERT_EQ(-1, ki_getsockopt(sock1_, SOL_SOCKET, -1, &socket_error, &len));
420 ASSERT_EQ(ENOPROTOOPT, errno);
423 TEST_F(SocketTest, Setsockopt) {
424 sock1_ = ki_socket(AF_INET, SOCK_STREAM, 0);
425 EXPECT_GT(sock1_, -1);
427 // It should not be possible to set SO_ERROR using setsockopt.
428 int socket_error = 10;
429 socklen_t len = sizeof(socket_error);
430 ASSERT_EQ(-1, ki_setsockopt(sock1_, SOL_SOCKET, SO_ERROR,
431 &socket_error, len));
432 ASSERT_EQ(ENOPROTOOPT, errno);
435 TEST_F(SocketTest, Sockopt_TCP_NODELAY) {
436 int option = 0;
437 socklen_t len = sizeof(option);
438 // Getting and setting TCP_NODELAY on UDP socket should fail
439 sock1_ = ki_socket(AF_INET, SOCK_DGRAM, 0);
440 ASSERT_EQ(-1, ki_setsockopt(sock1_, IPPROTO_TCP, TCP_NODELAY, &option, len));
441 ASSERT_EQ(ENOPROTOOPT, errno);
442 ASSERT_EQ(-1, ki_getsockopt(sock1_, IPPROTO_TCP, TCP_NODELAY, &option, &len));
443 ASSERT_EQ(ENOPROTOOPT, errno);
445 // Getting and setting TCP_NODELAY on TCP socket should preserve value
446 sock2_ = ki_socket(AF_INET, SOCK_STREAM, 0);
447 ASSERT_EQ(0, ki_getsockopt(sock2_, IPPROTO_TCP, TCP_NODELAY, &option, &len));
448 ASSERT_EQ(0, option);
449 ASSERT_EQ(sizeof(option), len);
451 option = 1;
452 len = sizeof(option);
453 ASSERT_EQ(0, ki_setsockopt(sock2_, IPPROTO_TCP, TCP_NODELAY, &option, len))
454 << "Failed with " << errno << ": " << strerror(errno);
455 ASSERT_EQ(1, option);
458 TEST_F(SocketTest, Sockopt_KEEPALIVE) {
459 sock1_ = ki_socket(AF_INET, SOCK_STREAM, 0);
460 ASSERT_GT(sock1_, -1);
461 sock2_ = ki_socket(AF_INET, SOCK_DGRAM, 0);
462 ASSERT_GT(sock2_, -1);
464 int value = 0;
465 socklen_t len = sizeof(value);
466 ASSERT_EQ(0, ki_getsockopt(sock1_, SOL_SOCKET, SO_KEEPALIVE, &value, &len));
467 ASSERT_EQ(0, value);
468 ASSERT_EQ(sizeof(int), len);
471 // Disabled until we support SO_LINGER (i.e. syncronouse close()/shutdown())
472 // TODO(sbc): re-enable once we fix http://crbug.com/312401
473 TEST_F(SocketTest, DISABLED_Sockopt_LINGER) {
474 sock1_ = ki_socket(AF_INET, SOCK_STREAM, 0);
475 ASSERT_GT(sock1_, -1);
476 sock2_ = ki_socket(AF_INET, SOCK_DGRAM, 0);
477 ASSERT_GT(sock2_, -1);
479 struct linger linger = { 7, 8 };
480 socklen_t len = sizeof(linger);
481 ASSERT_EQ(0, ki_getsockopt(sock1_, SOL_SOCKET, SO_LINGER, &linger, &len));
482 ASSERT_EQ(0, linger.l_onoff);
483 ASSERT_EQ(0, linger.l_linger);
484 ASSERT_EQ(sizeof(struct linger), len);
485 ASSERT_EQ(0, ki_getsockopt(sock2_, SOL_SOCKET, SO_LINGER, &linger, &len));
486 ASSERT_EQ(0, linger.l_onoff);
487 ASSERT_EQ(0, linger.l_linger);
488 ASSERT_EQ(sizeof(struct linger), len);
490 linger.l_onoff = 1;
491 linger.l_linger = 77;
492 len = sizeof(linger);
493 ASSERT_EQ(0, ki_setsockopt(sock1_, SOL_SOCKET, SO_LINGER, &linger, len));
494 linger.l_onoff = 1;
495 linger.l_linger = 88;
496 ASSERT_EQ(0, ki_setsockopt(sock2_, SOL_SOCKET, SO_LINGER, &linger, len));
498 len = sizeof(linger);
499 ASSERT_EQ(0, ki_getsockopt(sock1_, SOL_SOCKET, SO_LINGER, &linger, &len));
500 ASSERT_EQ(1, linger.l_onoff);
501 ASSERT_EQ(77, linger.l_linger);
502 ASSERT_EQ(sizeof(struct linger), len);
503 ASSERT_EQ(0, ki_getsockopt(sock2_, SOL_SOCKET, SO_LINGER, &linger, &len));
504 ASSERT_EQ(1, linger.l_onoff);
505 ASSERT_EQ(88, linger.l_linger);
506 ASSERT_EQ(sizeof(struct linger), len);
509 TEST_F(SocketTest, Sockopt_REUSEADDR) {
510 int value = 1;
511 socklen_t len = sizeof(value);
512 sock1_ = ki_socket(AF_INET, SOCK_STREAM, 0);
514 ASSERT_GT(sock1_, -1);
515 ASSERT_EQ(0, ki_setsockopt(sock1_, SOL_SOCKET, SO_REUSEADDR, &value, len));
517 value = 0;
518 len = sizeof(value);
519 ASSERT_EQ(0, ki_getsockopt(sock1_, SOL_SOCKET, SO_REUSEADDR, &value, &len));
520 ASSERT_EQ(1, value);
521 ASSERT_EQ(sizeof(int), len);
524 // The size of the data to send is deliberately chosen to be
525 // larger than the TCP buffer in nacl_io.
526 // TODO(sbc): use ioctl to discover the actual buffer size at
527 // runtime.
528 #define LARGE_SEND_BYTES (800 * 1024)
529 TEST_F(SocketTestWithServer, LargeSend) {
530 char* outbuf = (char*)malloc(LARGE_SEND_BYTES);
531 char* inbuf = (char*)malloc(LARGE_SEND_BYTES);
532 int bytes_sent = 0;
533 int bytes_received = 0;
535 // Fill output buffer with ascending integers
536 int* outbuf_int = (int*)outbuf;
537 int* inbuf_int = (int*)inbuf;
538 for (int i = 0; i < LARGE_SEND_BYTES/sizeof(int); i++) {
539 outbuf_int[i] = i;
542 sockaddr_in addr;
543 socklen_t addrlen = sizeof(addr);
545 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
546 ASSERT_EQ(0, ki_connect(sock_, (sockaddr*) &addr, addrlen))
547 << "Failed with " << errno << ": " << strerror(errno);
549 // Call send an recv until all bytes have been transfered.
550 while (bytes_received < LARGE_SEND_BYTES) {
551 if (bytes_sent < LARGE_SEND_BYTES) {
552 int sent = ki_send(sock_, outbuf + bytes_sent,
553 LARGE_SEND_BYTES - bytes_sent, MSG_DONTWAIT);
554 if (sent < 0)
555 ASSERT_EQ(EWOULDBLOCK, errno) << "send failed: " << strerror(errno);
556 else
557 bytes_sent += sent;
560 int received = ki_recv(sock_, inbuf + bytes_received,
561 LARGE_SEND_BYTES - bytes_received, MSG_DONTWAIT);
562 if (received < 0)
563 ASSERT_EQ(EWOULDBLOCK, errno) << "recv failed: " << strerror(errno);
564 else
565 bytes_received += received;
568 // Make sure there is nothing else to recv at this point
569 char dummy[10];
570 ASSERT_EQ(-1, ki_recv(sock_, dummy, 10, MSG_DONTWAIT));
571 ASSERT_EQ(EWOULDBLOCK, errno);
573 int errors = 0;
574 for (int i = 0; i < LARGE_SEND_BYTES/4; i++) {
575 if (inbuf_int[i] != outbuf_int[i]) {
576 printf("%d: in=%d out=%d\n", i, inbuf_int[i], outbuf_int[i]);
577 if (errors++ > 50)
578 break;
582 for (int i = 0; i < LARGE_SEND_BYTES; i++) {
583 ASSERT_EQ(outbuf[i], inbuf[i]) << "cmp failed at " << i;
586 ASSERT_EQ(0, memcmp(inbuf, outbuf, LARGE_SEND_BYTES));
588 free(inbuf);
589 free(outbuf);
592 TEST_F(SocketTestUDP, Listen) {
593 EXPECT_EQ(-1, ki_listen(sock1_, 10));
594 EXPECT_EQ(errno, EOPNOTSUPP);
597 TEST_F(SocketTestUDP, Sockopt_BUFSIZE) {
598 int option = 1024*1024;
599 socklen_t len = sizeof(option);
601 ASSERT_EQ(0, Bind(sock1_, LOCAL_HOST, ANY_PORT));
603 // Modify the test to verify the change by calling getsockopt
604 // once UDPInterface supports GetOption() call
605 ASSERT_EQ(0, ki_setsockopt(sock1_, SOL_SOCKET, SO_RCVBUF, &option, len))
606 << "failed with: " << strerror(errno);
607 ASSERT_EQ(0, ki_setsockopt(sock1_, SOL_SOCKET, SO_SNDBUF, &option, len))
608 << "failed with: " << strerror(errno);
611 TEST_F(SocketTestUDP, Sockopt_BROADCAST) {
612 int option = 1;
613 socklen_t len = sizeof(option);
615 ASSERT_EQ(0, Bind(sock1_, LOCAL_HOST, ANY_PORT));
617 // Modify the test to verify the change by calling getsockopt
618 // once UDPInterface supports GetOption() call
619 ASSERT_EQ(0, ki_setsockopt(sock1_, SOL_SOCKET, SO_BROADCAST, &option, len))
620 << "failed with: " << strerror(errno);
623 TEST_F(SocketTestTCP, AcceptNoParams) {
624 sockaddr_in addr;
625 socklen_t addrlen = sizeof(addr);
626 int server_sock = sock1_;
628 // Bind and Listen
629 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
630 ASSERT_EQ(0, ki_listen(server_sock, 10));
632 // Connect to listening socket
633 int client_sock = sock2_;
634 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
635 addrlen = sizeof(addr);
636 ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen))
637 << "Failed with " << errno << ": " << strerror(errno);
639 // Accept without addr and len should succeed
640 int new_socket = ki_accept(server_sock, NULL, NULL);
641 ASSERT_GT(new_socket, -1);
643 ASSERT_EQ(0, ki_close(new_socket));
646 TEST_F(SocketTestTCP, Listen) {
647 sockaddr_in addr;
648 socklen_t addrlen = sizeof(addr);
649 const char* client_greeting = "hello";
650 const char* server_reply = "reply";
651 const int greeting_len = strlen(client_greeting);
652 const int reply_len = strlen(server_reply);
654 int server_sock = sock1_;
656 // Accept before listen should fail
657 ASSERT_EQ(-1, ki_accept(server_sock, (sockaddr*)&addr, &addrlen));
659 // Listen should fail on unbound socket
660 ASSERT_EQ(-1, ki_listen(server_sock, 10));
662 // Bind and Listen
663 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
664 ASSERT_EQ(0, ki_listen(server_sock, 10))
665 << "listen failed with: " << strerror(errno);
667 // Connect to listening socket, and send greeting
668 int client_sock = sock2_;
669 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
670 addrlen = sizeof(addr);
671 ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen))
672 << "Failed with " << errno << ": " << strerror(errno);
674 ASSERT_EQ(greeting_len, ki_send(client_sock, client_greeting,
675 greeting_len, 0));
677 // Pass in addrlen that is larger than our actual address to make
678 // sure that it is correctly set back to sizeof(sockaddr_in)
679 sockaddr_in client_addr[2];
680 sockaddr_in cmp_addr;
681 memset(&client_addr[0], 0, sizeof(client_addr[0]));
682 memset(&client_addr[1], 0xab, sizeof(client_addr[1]));
683 memset(&cmp_addr, 0xab, sizeof(cmp_addr));
684 addrlen = sizeof(client_addr[0]) + 10;
685 int new_socket = ki_accept(server_sock, (sockaddr*)&client_addr[0],
686 &addrlen);
687 ASSERT_GT(new_socket, -1)
688 << "accept failed with " << errno << ": " << strerror(errno);
689 ASSERT_EQ(addrlen, sizeof(sockaddr_in));
690 // Check that client_addr[1] and cmp_addr are the same (not overwritten).
691 ASSERT_EQ(0, memcmp(&client_addr[1], &cmp_addr, sizeof(cmp_addr)));
692 ASSERT_EQ(0xabab, client_addr[1].sin_port);
694 // Verify addr and addrlen were set correctly
695 ASSERT_EQ(addrlen, sizeof(sockaddr_in));
696 ASSERT_EQ(0, ki_getsockname(client_sock, (sockaddr*)&client_addr[1],
697 &addrlen));
698 ASSERT_EQ(client_addr[1].sin_family, client_addr[0].sin_family);
699 ASSERT_EQ(client_addr[1].sin_port, client_addr[0].sin_port);
700 ASSERT_EQ(client_addr[1].sin_addr.s_addr, client_addr[0].sin_addr.s_addr);
702 // Try a call where the supplied len is smaller than the expected length.
703 // The API should only write up to that amount, but should return the
704 // expected length.
705 sockaddr_in client_addr2;
706 memset(&client_addr2, 0, sizeof(client_addr2));
708 // truncated_len is the size of the structure up to and including sin_family.
709 // TODO(sbc): Fix this test so it doesn't depend on the layout of the
710 // sockaddr_in structure.
711 socklen_t truncated_len = offsetof(sockaddr_in, sin_family) +
712 sizeof(client_addr2.sin_family);
713 ASSERT_GT(sizeof(sockaddr_in), truncated_len);
714 ASSERT_EQ(0, ki_getsockname(client_sock, (sockaddr*)&client_addr2,
715 &truncated_len));
716 ASSERT_EQ(sizeof(sockaddr_in), truncated_len);
717 ASSERT_EQ(client_addr2.sin_family, client_addr[0].sin_family);
718 ASSERT_EQ(client_addr2.sin_port, 0);
719 ASSERT_EQ(client_addr2.sin_addr.s_addr, 0);
721 // Recv greeting from client and send reply
722 char inbuf[512];
723 ASSERT_EQ(greeting_len, ki_recv(new_socket, inbuf, sizeof(inbuf), 0));
724 inbuf[greeting_len] = 0;
725 ASSERT_STREQ(inbuf, client_greeting);
726 ASSERT_EQ(reply_len, ki_send(new_socket, server_reply, reply_len, 0));
728 // Recv reply on client socket
729 ASSERT_EQ(reply_len, ki_recv(client_sock, inbuf, sizeof(inbuf), 0));
730 inbuf[reply_len] = 0;
731 ASSERT_STREQ(inbuf, server_reply);
733 ASSERT_EQ(0, ki_close(new_socket));
736 TEST_F(SocketTestTCP, BindAndGetSockName) {
737 sockaddr_in addr;
738 socklen_t addrlen = sizeof(addr);
740 // Bind
741 ASSERT_EQ(0, Bind(sock1_, LOCAL_HOST, 0));
742 EXPECT_EQ(0, ki_getsockname(sock1_, (struct sockaddr*)&addr, &addrlen));
743 EXPECT_NE(0, addr.sin_port);
746 TEST_F(SocketTestTCP, ListenNonBlocking) {
747 int server_sock = sock1_;
749 // Set non-blocking
750 SetNonBlocking(server_sock);
752 // bind and listen
753 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
754 ASSERT_EQ(0, ki_listen(server_sock, 10))
755 << "listen failed with: " << strerror(errno);
757 // Accept should fail with EAGAIN since there is no incomming
758 // connection.
759 sockaddr_in addr;
760 socklen_t addrlen = sizeof(addr);
761 ASSERT_EQ(-1, ki_accept(server_sock, (sockaddr*)&addr, &addrlen));
762 ASSERT_EQ(EAGAIN, errno);
764 // If we poll the listening socket it should also return
765 // not readable to indicate that no connections are available
766 // to accept.
767 struct pollfd pollfd = { server_sock, POLLIN|POLLOUT, 0 };
768 ASSERT_EQ(0, ki_poll(&pollfd, 1, 0));
770 // Connect to listening socket
771 int client_sock = sock2_;
772 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
773 addrlen = sizeof(addr);
774 ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen))
775 << "Failed with " << errno << ": " << strerror(errno);
777 // Not poll again but with an infintie timeout.
778 pollfd.fd = server_sock;
779 pollfd.events = POLLIN | POLLOUT;
780 ASSERT_EQ(1, ki_poll(&pollfd, 1, -1));
782 // Now non-blocking accept should return the new socket
783 int new_socket = ki_accept(server_sock, (sockaddr*)&addr, &addrlen);
784 ASSERT_NE(-1, new_socket)
785 << "accept failed with: " << strerror(errno);
786 ASSERT_EQ(0, ki_close(new_socket));
788 // Accept calls should once again fail with EAGAIN
789 ASSERT_EQ(-1, ki_accept(server_sock, (sockaddr*)&addr, &addrlen));
790 ASSERT_EQ(EAGAIN, errno);
792 // As should polling the listening socket
793 pollfd.fd = server_sock;
794 pollfd.events = POLLIN | POLLOUT;
795 ASSERT_EQ(0, ki_poll(&pollfd, 1, 0));
798 TEST_F(SocketTestTCP, SendRecvAfterRemoteShutdown) {
799 sockaddr_in addr;
800 socklen_t addrlen = sizeof(addr);
802 int server_sock = sock1_;
803 int client_sock = sock2_;
805 // bind and listen
806 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
807 ASSERT_EQ(0, ki_listen(server_sock, 10))
808 << "listen failed with: " << strerror(errno);
810 // connect to listening socket
811 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
812 ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen))
813 << "Failed with " << errno << ": " << strerror(errno);
815 addrlen = sizeof(addr);
816 int new_sock = ki_accept(server_sock, (sockaddr*)&addr, &addrlen);
817 ASSERT_NE(-1, new_sock);
819 const char* send_buf = "hello world";
820 ASSERT_EQ(strlen(send_buf), ki_send(new_sock, send_buf, strlen(send_buf), 0));
822 // Recv first 10 bytes
823 char buf[256];
824 ASSERT_EQ(10, ki_recv(client_sock, buf, 10, 0));
826 // Close the new socket
827 ASSERT_EQ(0, ki_close(new_sock));
829 // Recv remainder
830 int bytes_remaining = strlen(send_buf) - 10;
831 ASSERT_EQ(bytes_remaining, ki_recv(client_sock, buf, 256, 0));
833 // Attempt to read/write after remote shutdown, with no bytes remaining
834 ASSERT_EQ(0, ki_recv(client_sock, buf, 10, 0));
835 ASSERT_EQ(0, ki_recv(client_sock, buf, 10, 0));
837 // It is still legal to send to the remote socket, even after it is closed.
838 ASSERT_EQ(10, ki_send(client_sock, buf, 10, 0));
841 TEST_F(SocketTestTCP, SendRecvAfterLocalShutdown) {
842 sockaddr_in addr;
843 socklen_t addrlen = sizeof(addr);
845 int server_sock = sock1_;
846 int client_sock = sock2_;
848 // bind and listen
849 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
850 ASSERT_EQ(0, ki_listen(server_sock, 10))
851 << "listen failed with: " << strerror(errno);
853 // connect to listening socket
854 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
855 ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen))
856 << "Failed with " << errno << ": " << strerror(errno);
858 addrlen = sizeof(addr);
859 int new_sock = ki_accept(server_sock, (sockaddr*)&addr, &addrlen);
860 ASSERT_NE(-1, new_sock);
862 // Close the new socket
863 ASSERT_EQ(0, ki_shutdown(client_sock, SHUT_RDWR));
865 // Attempt to read/write after shutdown
866 char buffer[10];
867 ASSERT_EQ(0, ki_recv(client_sock, buffer, sizeof(buffer), 0));
868 ASSERT_EQ(-1, ki_send(client_sock, buffer, sizeof(buffer), 0));
869 ASSERT_EQ(errno, EPIPE);
872 #define SEND_BYTES (1024)
873 TEST_F(SocketTestTCP, SendBufferedDataAfterShutdown) {
874 sockaddr_in addr;
875 socklen_t addrlen = sizeof(addr);
877 int server_sock = sock1_;
878 int client_sock = sock2_;
880 // bind and listen
881 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
882 ASSERT_EQ(0, ki_listen(server_sock, 10))
883 << "listen failed with: " << strerror(errno);
885 // connect to listening socket
886 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
887 ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen))
888 << "Failed with " << errno << ": " << strerror(errno);
890 addrlen = sizeof(addr);
891 int new_sock = ki_accept(server_sock, (sockaddr*)&addr, &addrlen);
892 ASSERT_NE(-1, new_sock);
894 // send a fairly large amount of data and immediately close
895 // the socket.
896 void* buffer = alloca(SEND_BYTES);
897 ASSERT_EQ(SEND_BYTES, ki_send(client_sock, buffer, SEND_BYTES, 0));
898 ASSERT_EQ(0, ki_close(client_sock));
900 // avoid double close of sock2_
901 sock2_ = -1;
903 // Attempt to recv() all the sent data. None should be lost.
904 int remainder = SEND_BYTES;
905 while (remainder > 0) {
906 int rtn = ki_recv(new_sock, buffer, remainder, 0);
907 ASSERT_GT(rtn, 0);
908 remainder -= rtn;
911 ASSERT_EQ(0, ki_close(new_sock));
914 TEST_F(SocketTestTCP, Sockopt_BUFSIZE) {
915 int option = 1024*1024;
916 socklen_t len = sizeof(option);
917 sockaddr_in addr;
918 socklen_t addrlen = sizeof(addr);
920 int server_sock = sock1_;
921 int client_sock = sock2_;
923 // bind and listen
924 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
925 ASSERT_EQ(0, ki_listen(server_sock, 10))
926 << "listen failed with: " << strerror(errno);
928 // connect to listening socket
929 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
930 ASSERT_EQ(0, ki_connect(client_sock, (sockaddr*)&addr, addrlen))
931 << "Failed with " << errno << ": " << strerror(errno);
933 addrlen = sizeof(addr);
934 int new_sock = ki_accept(server_sock, (sockaddr*)&addr, &addrlen);
935 ASSERT_NE(-1, new_sock);
937 // Modify the test to verify the change by calling getsockopt
938 // once TCPInterface supports GetOption() call
939 ASSERT_EQ(0, ki_setsockopt(sock2_, SOL_SOCKET, SO_RCVBUF, &option, len))
940 << "failed with: " << strerror(errno);
941 ASSERT_EQ(0, ki_setsockopt(sock2_, SOL_SOCKET, SO_SNDBUF, &option, len))
942 << "failed with: " << strerror(errno);
945 #endif // PROVIDES_SOCKET_API