- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / tests / nacl_io_socket_test / socket_test.cc
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.
4
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>
13
14 #include <map>
15 #include <string>
16
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"
26
27 #ifdef PROVIDES_SOCKET_API
28
29 using namespace nacl_io;
30 using namespace sdk_util;
31
32 #define LOCAL_HOST 0x7F000001
33 #define PORT1 4006
34 #define PORT2 4007
35 #define ANY_PORT 0
36
37 namespace {
38
39 void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) {
40   memset(addr, 0, sizeof(*addr));
41
42   addr->sin_family = AF_INET;
43   addr->sin_port = htons(port);
44   addr->sin_addr.s_addr = htonl(ip);
45 }
46
47 void SetNonBlocking(int sock) {
48   int flags = fcntl(sock, F_GETFL);
49   ASSERT_NE(-1, flags);
50   flags |= O_NONBLOCK;
51   ASSERT_EQ(0, fcntl(sock, F_SETFL, flags));
52   ASSERT_EQ(flags, fcntl(sock, F_GETFL));
53 }
54
55 class SocketTest : public ::testing::Test {
56  public:
57   SocketTest() : sock1_(-1), sock2_(-1) {}
58
59   void TearDown() {
60     if (sock1_ != -1)
61       EXPECT_EQ(0, close(sock1_));
62     if (sock2_ != -1)
63       EXPECT_EQ(0, close(sock2_));
64   }
65
66   int Bind(int fd, uint32_t ip, uint16_t port) {
67     sockaddr_in addr;
68     socklen_t addrlen = sizeof(addr);
69
70     IP4ToSockAddr(ip, port, &addr);
71     int err = bind(fd, (sockaddr*)&addr, addrlen);
72
73     if (err == -1)
74       return errno;
75     return 0;
76   }
77
78  protected:
79   int sock1_;
80   int sock2_;
81 };
82
83 class SocketTestUDP : public SocketTest {
84  public:
85   SocketTestUDP() {}
86
87   void SetUp() {
88     sock1_ = socket(AF_INET, SOCK_DGRAM, 0);
89     sock2_ = socket(AF_INET, SOCK_DGRAM, 0);
90
91     EXPECT_GT(sock1_, -1);
92     EXPECT_GT(sock2_, -1);
93   }
94 };
95
96 class SocketTestTCP : public SocketTest {
97  public:
98   SocketTestTCP() {}
99
100   void SetUp() {
101     sock1_ = socket(AF_INET, SOCK_STREAM, 0);
102     sock2_ = socket(AF_INET, SOCK_STREAM, 0);
103
104     EXPECT_GT(sock1_, -1);
105     EXPECT_GT(sock2_, -1);
106   }
107 };
108
109 class SocketTestWithServer : public ::testing::Test {
110  public:
111   SocketTestWithServer() : instance_(PSGetInstanceId()) {
112     pthread_mutex_init(&ready_lock_, NULL);
113     pthread_cond_init(&ready_cond_, NULL);
114   }
115
116   void ServerThreadMain() {
117     loop_.AttachToCurrentThread();
118     pp::Instance instance(PSGetInstanceId());
119     EchoServer server(&instance, PORT1, ServerLog, &ready_cond_, &ready_lock_);
120     loop_.Run();
121   }
122
123   static void* ServerThreadMainStatic(void* arg) {
124     SocketTestWithServer* test = (SocketTestWithServer*)arg;
125     test->ServerThreadMain();
126     return NULL;
127   }
128
129   void SetUp() {
130     loop_ = pp::MessageLoop(&instance_);
131     pthread_mutex_lock(&ready_lock_);
132
133     // Start an echo server on a background thread.
134     pthread_create(&server_thread_, NULL, ServerThreadMainStatic, this);
135
136     // Wait for thread to signal that it is ready to accept connections.
137     pthread_cond_wait(&ready_cond_, &ready_lock_);
138     pthread_mutex_unlock(&ready_lock_);
139
140     sock_ = socket(AF_INET, SOCK_STREAM, 0);
141     EXPECT_GT(sock_, -1);
142   }
143
144   void TearDown() {
145     // Stop the echo server and the background thread it runs on
146     loop_.PostQuit(true);
147     pthread_join(server_thread_, NULL);
148     ASSERT_EQ(0, close(sock_));
149   }
150
151   static void ServerLog(const char* msg) {
152     // Uncomment to see logs of echo server on stdout
153     //printf("server: %s\n", msg);
154   }
155
156  protected:
157   int sock_;
158   pp::MessageLoop loop_;
159   pp::Instance instance_;
160   pthread_cond_t ready_cond_;
161   pthread_mutex_t ready_lock_;
162   pthread_t server_thread_;
163 };
164
165 }  // namespace
166
167 TEST(SocketTestSimple, Socket) {
168   EXPECT_EQ(-1, socket(AF_UNIX, SOCK_STREAM, 0));
169   EXPECT_EQ(errno, EAFNOSUPPORT);
170   EXPECT_EQ(-1, socket(AF_INET, SOCK_RAW, 0));
171   EXPECT_EQ(errno, EPROTONOSUPPORT);
172
173   int sock1_ = socket(AF_INET, SOCK_DGRAM, 0);
174   EXPECT_NE(-1, sock1_);
175
176   int sock2_ = socket(AF_INET6, SOCK_DGRAM, 0);
177   EXPECT_NE(-1, sock2_);
178
179   int sock3 = socket(AF_INET, SOCK_STREAM, 0);
180   EXPECT_NE(-1, sock3);
181
182   int sock4 = socket(AF_INET6, SOCK_STREAM, 0);
183   EXPECT_NE(-1, sock4);
184
185   close(sock1_);
186   close(sock2_);
187   close(sock3);
188   close(sock4);
189 }
190
191 TEST_F(SocketTestUDP, Bind) {
192   // Bind away.
193   EXPECT_EQ(0, Bind(sock1_, LOCAL_HOST, PORT1));
194
195   // Invalid to rebind a socket.
196   EXPECT_EQ(EINVAL, Bind(sock1_, LOCAL_HOST, PORT1));
197
198   // Addr in use.
199   EXPECT_EQ(EADDRINUSE, Bind(sock2_, LOCAL_HOST, PORT1));
200
201   // Bind with a wildcard.
202   EXPECT_EQ(0, Bind(sock2_, LOCAL_HOST, ANY_PORT));
203
204   // Invalid to rebind after wildcard
205   EXPECT_EQ(EINVAL, Bind(sock2_, LOCAL_HOST, PORT1));
206 }
207
208 TEST_F(SocketTestUDP, SendRcv) {
209   char outbuf[256];
210   char inbuf[512];
211
212   memset(outbuf, 1, sizeof(outbuf));
213   memset(inbuf, 0, sizeof(inbuf));
214
215   EXPECT_EQ(0, Bind(sock1_, LOCAL_HOST, PORT1));
216   EXPECT_EQ(0, Bind(sock2_, LOCAL_HOST, PORT2));
217
218   sockaddr_in addr;
219   socklen_t addrlen = sizeof(addr);
220   IP4ToSockAddr(LOCAL_HOST, PORT2, &addr);
221
222   int len1 =
223      sendto(sock1_, outbuf, sizeof(outbuf), 0, (sockaddr*) &addr, addrlen);
224   EXPECT_EQ(sizeof(outbuf), len1);
225
226   // Ensure the buffers are different
227   EXPECT_NE(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
228   memset(&addr, 0, sizeof(addr));
229
230   // Try to receive the previously sent packet
231   int len2 =
232     recvfrom(sock2_, inbuf, sizeof(inbuf), 0, (sockaddr*) &addr, &addrlen);
233   EXPECT_EQ(sizeof(outbuf), len2);
234   EXPECT_EQ(sizeof(sockaddr_in), addrlen);
235   EXPECT_EQ(PORT1, htons(addr.sin_port));
236
237   // Now they should be the same
238   EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
239 }
240
241 const size_t kQueueSize = 65536 * 8;
242 TEST_F(SocketTestUDP, FullFifo) {
243   char outbuf[16 * 1024];
244
245   ASSERT_EQ(0, Bind(sock1_, LOCAL_HOST, PORT1));
246   ASSERT_EQ(0, Bind(sock2_, LOCAL_HOST, PORT2));
247
248   sockaddr_in addr;
249   socklen_t addrlen = sizeof(addr);
250   IP4ToSockAddr(LOCAL_HOST, PORT2, &addr);
251
252   size_t total = 0;
253   while (total < kQueueSize * 8) {
254     int len = sendto(sock1_, outbuf, sizeof(outbuf), MSG_DONTWAIT,
255                      (sockaddr*) &addr, addrlen);
256
257     if (len <= 0) {
258       EXPECT_EQ(-1, len);
259       EXPECT_EQ(EWOULDBLOCK, errno);
260       break;
261     }
262
263     if (len >= 0) {
264       EXPECT_EQ(sizeof(outbuf), len);
265       total += len;
266     }
267   }
268   EXPECT_GT(total, kQueueSize - 1);
269   EXPECT_LT(total, kQueueSize * 8);
270 }
271
272 TEST_F(SocketTestWithServer, TCPConnect) {
273   char outbuf[256];
274   char inbuf[512];
275
276   memset(outbuf, 1, sizeof(outbuf));
277
278   sockaddr_in addr;
279   socklen_t addrlen = sizeof(addr);
280
281   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
282
283   ASSERT_EQ(0, connect(sock_, (sockaddr*) &addr, addrlen))
284       << "Failed with " << errno << ": " << strerror(errno) << "\n";
285
286   // Send two different messages to the echo server and verify the
287   // response matches.
288   strcpy(outbuf, "hello");
289   memset(inbuf, 0, sizeof(inbuf));
290   ASSERT_EQ(sizeof(outbuf), write(sock_, outbuf, sizeof(outbuf)))
291       << "socket write failed with: " << strerror(errno);
292   ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf)));
293   EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
294
295   strcpy(outbuf, "world");
296   memset(inbuf, 0, sizeof(inbuf));
297   ASSERT_EQ(sizeof(outbuf), write(sock_, outbuf, sizeof(outbuf)));
298   ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf)));
299   EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
300 }
301
302 TEST_F(SocketTestWithServer, TCPConnectNonBlock) {
303   char outbuf[256];
304   //char inbuf[512];
305
306   memset(outbuf, 1, sizeof(outbuf));
307
308   sockaddr_in addr;
309   socklen_t addrlen = sizeof(addr);
310
311   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
312
313   SetNonBlocking(sock_);
314   ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
315   ASSERT_EQ(EINPROGRESS, errno)
316      << "expected EINPROGRESS but got: " << strerror(errno) << "\n";
317   ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
318   ASSERT_EQ(EALREADY, errno);
319
320   // Wait for the socket connection to complete using poll()
321   struct pollfd pollfd = { sock_, POLLIN|POLLOUT, 0 };
322   ASSERT_EQ(1, poll(&pollfd, 1, -1));
323   ASSERT_EQ(POLLOUT, pollfd.revents);
324
325   // Attempts to connect again should yield EISCONN
326   ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
327   ASSERT_EQ(EISCONN, errno);
328
329   // And SO_ERROR should be 0.
330 }
331
332 TEST_F(SocketTest, Getsockopt) {
333   sock1_ = socket(AF_INET, SOCK_STREAM, 0);
334   EXPECT_GT(sock1_, -1);
335   int socket_error = 99;
336   socklen_t len = sizeof(socket_error);
337
338   // Test for valid option (SO_ERROR) which should be 0 when a socket
339   // is first created.
340   ASSERT_EQ(0, getsockopt(sock1_, SOL_SOCKET, SO_ERROR, &socket_error, &len));
341   ASSERT_EQ(0, socket_error);
342   ASSERT_EQ(sizeof(socket_error), len);
343
344   // Test for an invalid option (-1)
345   ASSERT_EQ(-1, getsockopt(sock1_, SOL_SOCKET, -1, &socket_error, &len));
346   ASSERT_EQ(ENOPROTOOPT, errno);
347 }
348
349 TEST_F(SocketTest, Setsockopt) {
350   sock1_ = socket(AF_INET, SOCK_STREAM, 0);
351   EXPECT_GT(sock1_, -1);
352
353   // It should not be possible to set SO_ERROR using setsockopt.
354   int socket_error = 10;
355   socklen_t len = sizeof(socket_error);
356   ASSERT_EQ(-1, setsockopt(sock1_, SOL_SOCKET, SO_ERROR, &socket_error, len));
357   ASSERT_EQ(ENOPROTOOPT, errno);
358
359 }
360
361 TEST_F(SocketTest, Sockopt_KEEPALIVE) {
362   sock1_ = socket(AF_INET, SOCK_STREAM, 0);
363   ASSERT_GT(sock1_, -1);
364   sock2_ = socket(AF_INET, SOCK_DGRAM, 0);
365   ASSERT_GT(sock2_, -1);
366
367   int value = 0;
368   socklen_t len = sizeof(value);
369   ASSERT_EQ(0, getsockopt(sock1_, SOL_SOCKET, SO_KEEPALIVE, &value, &len));
370   ASSERT_EQ(0, value);
371   ASSERT_EQ(sizeof(int), len);
372 }
373
374 // Disabled until we support SO_LINGER (i.e. syncronouse close()/shutdown())
375 // TODO(sbc): re-enable once we fix http://crbug.com/312401
376 TEST_F(SocketTest, DISABLED_Sockopt_LINGER) {
377   sock1_ = socket(AF_INET, SOCK_STREAM, 0);
378   ASSERT_GT(sock1_, -1);
379   sock2_ = socket(AF_INET, SOCK_DGRAM, 0);
380   ASSERT_GT(sock2_, -1);
381
382   struct linger linger = { 7, 8 };
383   socklen_t len = sizeof(linger);
384   ASSERT_EQ(0, getsockopt(sock1_, SOL_SOCKET, SO_LINGER, &linger, &len));
385   ASSERT_EQ(0, linger.l_onoff);
386   ASSERT_EQ(0, linger.l_linger);
387   ASSERT_EQ(sizeof(struct linger), len);
388   ASSERT_EQ(0, getsockopt(sock2_, SOL_SOCKET, SO_LINGER, &linger, &len));
389   ASSERT_EQ(0, linger.l_onoff);
390   ASSERT_EQ(0, linger.l_linger);
391   ASSERT_EQ(sizeof(struct linger), len);
392
393   linger.l_onoff = 1;
394   linger.l_linger = 77;
395   len = sizeof(linger);
396   ASSERT_EQ(0, setsockopt(sock1_, SOL_SOCKET, SO_LINGER, &linger, len));
397   linger.l_onoff = 1;
398   linger.l_linger = 88;
399   ASSERT_EQ(0, setsockopt(sock2_, SOL_SOCKET, SO_LINGER, &linger, len));
400
401   len = sizeof(linger);
402   ASSERT_EQ(0, getsockopt(sock1_, SOL_SOCKET, SO_LINGER, &linger, &len));
403   ASSERT_EQ(1, linger.l_onoff);
404   ASSERT_EQ(77, linger.l_linger);
405   ASSERT_EQ(sizeof(struct linger), len);
406   ASSERT_EQ(0, getsockopt(sock2_, SOL_SOCKET, SO_LINGER, &linger, &len));
407   ASSERT_EQ(1, linger.l_onoff);
408   ASSERT_EQ(88, linger.l_linger);
409   ASSERT_EQ(sizeof(struct linger), len);
410 }
411
412 TEST_F(SocketTest, Sockopt_REUSEADDR) {
413   int value = 1;
414   socklen_t len = sizeof(value);
415   sock1_ = socket(AF_INET, SOCK_STREAM, 0);
416
417   ASSERT_GT(sock1_, -1);
418   ASSERT_EQ(0, setsockopt(sock1_, SOL_SOCKET, SO_REUSEADDR, &value, len));
419
420   value = 0;
421   len = sizeof(value);
422   ASSERT_EQ(0, getsockopt(sock1_, SOL_SOCKET, SO_REUSEADDR, &value, &len));
423   ASSERT_EQ(1, value);
424   ASSERT_EQ(sizeof(int), len);
425 }
426
427 // The size of the data to send is deliberately chosen to be
428 // larger than the TCP buffer in nacl_io.
429 // TODO(sbc): use ioctl to discover the actual buffer size at
430 // runtime.
431 #define LARGE_SEND_BYTES (800 * 1024)
432 TEST_F(SocketTestWithServer, LargeSend) {
433   char* outbuf = (char*)malloc(LARGE_SEND_BYTES);
434   char* inbuf = (char*)malloc(LARGE_SEND_BYTES);
435   int bytes_sent = 0;
436   int bytes_received = 0;
437
438   // Fill output buffer with ascending integers
439   int* outbuf_int = (int*)outbuf;
440   int* inbuf_int = (int*)inbuf;
441   for (int i = 0; i < LARGE_SEND_BYTES/sizeof(int); i++) {
442     outbuf_int[i] = i;
443   }
444
445   sockaddr_in addr;
446   socklen_t addrlen = sizeof(addr);
447
448   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
449   ASSERT_EQ(0, connect(sock_, (sockaddr*) &addr, addrlen))
450       << "Failed with " << errno << ": " << strerror(errno) << "\n";
451
452   // Call send an recv until all bytes have been transfered.
453   while (bytes_received < LARGE_SEND_BYTES) {
454     if (bytes_sent < LARGE_SEND_BYTES) {
455       int sent = send(sock_, outbuf + bytes_sent,
456                       LARGE_SEND_BYTES - bytes_sent, MSG_DONTWAIT);
457       if (sent < 0)
458         ASSERT_EQ(EWOULDBLOCK, errno) << "send failed: " << strerror(errno);
459       else
460         bytes_sent += sent;
461     }
462
463     int received = recv(sock_, inbuf + bytes_received,
464                         LARGE_SEND_BYTES - bytes_received, MSG_DONTWAIT);
465     if (received < 0)
466       ASSERT_EQ(EWOULDBLOCK, errno) << "recv failed: " << strerror(errno);
467     else
468       bytes_received += received;
469   }
470
471   // Make sure there is nothing else to recv at this point
472   char dummy[10];
473   ASSERT_EQ(-1, recv(sock_, dummy, 10, MSG_DONTWAIT));
474   ASSERT_EQ(EWOULDBLOCK, errno);
475
476   int errors = 0;
477   for (int i = 0; i < LARGE_SEND_BYTES/4; i++) {
478     if (inbuf_int[i] != outbuf_int[i]) {
479       printf("%d: in=%d out=%d\n", i, inbuf_int[i], outbuf_int[i]);
480       if (errors++ > 50)
481         break;
482     }
483   }
484
485   for (int i = 0; i < LARGE_SEND_BYTES; i++) {
486     ASSERT_EQ(outbuf[i], inbuf[i]) << "cmp failed at " << i;
487   }
488
489   ASSERT_EQ(0, memcmp(inbuf, outbuf, LARGE_SEND_BYTES));
490
491   free(inbuf);
492   free(outbuf);
493 }
494
495 TEST_F(SocketTestUDP, Listen) {
496   EXPECT_EQ(-1, listen(sock1_, 10));
497   EXPECT_EQ(errno, ENOTSUP);
498 }
499
500 TEST_F(SocketTestTCP, Listen) {
501   sockaddr_in addr;
502   socklen_t addrlen = sizeof(addr);
503
504   int server_sock = sock1_;
505
506   // Accept before listen should fail
507   ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
508
509   // Listen should fail on unbound socket
510   ASSERT_EQ(-1, listen(server_sock, 10));
511
512   // Bind and Listen
513   ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
514   ASSERT_EQ(0, listen(server_sock, 10))
515     << "listen failed with: " << strerror(errno);
516
517   // Connect to listening socket
518   int client_sock = sock2_;
519   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
520   addrlen = sizeof(addr);
521   ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
522     << "Failed with " << errno << ": " << strerror(errno) << "\n";
523
524   ASSERT_EQ(5, send(client_sock, "hello", 5, 0));
525
526   // Pass in addrlen that is larger than our actual address to make
527   // sure that it is correctly set back to sizeof(sockaddr_in)
528   addrlen = sizeof(addr) + 10;
529   int new_socket = accept(server_sock, (sockaddr*)&addr, &addrlen);
530   ASSERT_GT(new_socket, -1)
531     << "accept failed with " << errno << ": " << strerror(errno) << "\n";
532
533   // Verify addr and addrlen were set correctly
534   ASSERT_EQ(addrlen, sizeof(sockaddr_in));
535   sockaddr_in client_addr;
536   ASSERT_EQ(0, getsockname(client_sock, (sockaddr*)&client_addr, &addrlen));
537   ASSERT_EQ(client_addr.sin_family, addr.sin_family);
538   ASSERT_EQ(client_addr.sin_port, addr.sin_port);
539   ASSERT_EQ(client_addr.sin_addr.s_addr, addr.sin_addr.s_addr);
540
541   char inbuf[512];
542   ASSERT_EQ(5, recv(new_socket, inbuf, 5, 0));
543   ASSERT_EQ(0, close(new_socket));
544 }
545
546 TEST_F(SocketTestTCP, ListenNonBlocking) {
547   int server_sock = sock1_;
548
549   // Set non-blocking
550   SetNonBlocking(server_sock);
551
552   // bind and listen
553   ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
554   ASSERT_EQ(0, listen(server_sock, 10))
555     << "listen failed with: " << strerror(errno);
556
557   // Accept should fail with EAGAIN since there is no incomming
558   // connection.
559   sockaddr_in addr;
560   socklen_t addrlen = sizeof(addr);
561   ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
562   ASSERT_EQ(EAGAIN, errno);
563
564   // If we poll the listening socket it should also return
565   // not readable to indicate that no connections are available
566   // to accept.
567   struct pollfd pollfd = { server_sock, POLLIN|POLLOUT, 0 };
568   ASSERT_EQ(0, poll(&pollfd, 1, 0));
569
570   // Connect to listening socket
571   int client_sock = sock2_;
572   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
573   addrlen = sizeof(addr);
574   ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
575     << "Failed with " << errno << ": " << strerror(errno) << "\n";
576
577   // Not poll again but with an infintie timeout.
578   pollfd.fd = server_sock;
579   pollfd.events = POLLIN | POLLOUT;
580   ASSERT_EQ(1, poll(&pollfd, 1, -1));
581
582   // Now non-blocking accept should return the new socket
583   int new_socket = accept(server_sock, (sockaddr*)&addr, &addrlen);
584   ASSERT_NE(-1, new_socket)
585     << "accept failed with: " << strerror(errno) << "\n";
586   ASSERT_EQ(0, close(new_socket));
587
588   // Accept calls should once again fail with EAGAIN
589   ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
590   ASSERT_EQ(EAGAIN, errno);
591
592   // As should polling the listening socket
593   pollfd.fd = server_sock;
594   pollfd.events = POLLIN | POLLOUT;
595   ASSERT_EQ(0, poll(&pollfd, 1, 0));
596 }
597
598 TEST_F(SocketTestTCP, SendRecvAfterRemoteShutdown) {
599   sockaddr_in addr;
600   socklen_t addrlen = sizeof(addr);
601
602   int server_sock = sock1_;
603   int client_sock = sock2_;
604
605   // bind and listen
606   ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
607   ASSERT_EQ(0, listen(server_sock, 10))
608     << "listen failed with: " << strerror(errno);
609
610   // connect to listening socket
611   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
612   ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
613     << "Failed with " << errno << ": " << strerror(errno) << "\n";
614
615   addrlen = sizeof(addr);
616   int new_sock = accept(server_sock, (sockaddr*)&addr, &addrlen);
617   ASSERT_NE(-1, new_sock);
618
619   const char* send_buf = "hello world";
620   ASSERT_EQ(strlen(send_buf), send(new_sock, send_buf, strlen(send_buf), 0));
621
622   // Recv first 10 bytes
623   char buf[256];
624   ASSERT_EQ(10, recv(client_sock, buf, 10, 0));
625
626   // Close the new socket
627   ASSERT_EQ(0, close(new_sock));
628
629   // Recv remainder
630   int bytes_remaining = strlen(send_buf) - 10;
631   ASSERT_EQ(bytes_remaining, recv(client_sock, buf, 256, 0));
632
633   // Attempt to read/write after remote shutdown, with no bytes remainging
634   ASSERT_EQ(0, recv(client_sock, buf, 10, 0));
635   ASSERT_EQ(0, recv(client_sock, buf, 10, 0));
636   ASSERT_EQ(-1, send(client_sock, buf, 10, 0));
637   ASSERT_EQ(errno, EPIPE);
638 }
639
640 TEST_F(SocketTestTCP, SendRecvAfterLocalShutdown) {
641   sockaddr_in addr;
642   socklen_t addrlen = sizeof(addr);
643
644   int server_sock = sock1_;
645   int client_sock = sock2_;
646
647   // bind and listen
648   ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
649   ASSERT_EQ(0, listen(server_sock, 10))
650     << "listen failed with: " << strerror(errno);
651
652   // connect to listening socket
653   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
654   ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
655     << "Failed with " << errno << ": " << strerror(errno) << "\n";
656
657   addrlen = sizeof(addr);
658   int new_sock = accept(server_sock, (sockaddr*)&addr, &addrlen);
659   ASSERT_NE(-1, new_sock);
660
661   // Close the new socket
662   ASSERT_EQ(0, shutdown(client_sock, SHUT_RDWR));
663
664   // Attempt to read/write after shutdown
665   char buffer[10];
666   ASSERT_EQ(0, recv(client_sock, buffer, sizeof(buffer), 0));
667   ASSERT_EQ(-1, send(client_sock, buffer, sizeof(buffer), 0));
668   ASSERT_EQ(errno, EPIPE);
669 }
670
671 #define SEND_BYTES (1024)
672 TEST_F(SocketTestTCP, SendBufferedDataAfterShutdown) {
673   sockaddr_in addr;
674   socklen_t addrlen = sizeof(addr);
675
676   int server_sock = sock1_;
677   int client_sock = sock2_;
678
679   // bind and listen
680   ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
681   ASSERT_EQ(0, listen(server_sock, 10))
682     << "listen failed with: " << strerror(errno);
683
684   // connect to listening socket
685   IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
686   ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
687     << "Failed with " << errno << ": " << strerror(errno) << "\n";
688
689   addrlen = sizeof(addr);
690   int new_sock = accept(server_sock, (sockaddr*)&addr, &addrlen);
691   ASSERT_NE(-1, new_sock);
692
693   // send a fairly large amount of data and immediately close
694   // the socket.
695   void* buffer = alloca(SEND_BYTES);
696   ASSERT_EQ(SEND_BYTES, send(client_sock, buffer, SEND_BYTES, 0));
697   ASSERT_EQ(0, close(client_sock));
698
699   // avoid double close of sock2_
700   sock2_ = -1;
701
702   // Attempt to recv() all the sent data.  None should be lost.
703   int remainder = SEND_BYTES;
704   while (remainder > 0) {
705     int rtn = recv(new_sock, buffer, remainder, 0);
706     ASSERT_GT(rtn, 0);
707     remainder -= rtn;
708   }
709
710   ASSERT_EQ(0, close(new_sock));
711 }
712
713 #endif  // PROVIDES_SOCKET_API