OLD | NEW |
(Empty) | |
| 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 "gmock/gmock.h" |
| 18 #include "gtest/gtest.h" |
| 19 |
| 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 |
| 25 #ifdef PROVIDES_SOCKET_API |
| 26 |
| 27 using namespace nacl_io; |
| 28 using namespace sdk_util; |
| 29 |
| 30 // No error expected |
| 31 #define ENONE 0 |
| 32 #define LOCAL_HOST 0x7F000001 |
| 33 #define PORT1 4006 |
| 34 #define PORT2 4007 |
| 35 #define ANY_PORT 0 |
| 36 |
| 37 |
| 38 namespace { |
| 39 class SocketTest : public ::testing::Test { |
| 40 public: |
| 41 SocketTest() : sock1(0), sock2(0) {} |
| 42 |
| 43 ~SocketTest() { |
| 44 EXPECT_EQ(0, close(sock1)); |
| 45 EXPECT_EQ(0, close(sock2)); |
| 46 } |
| 47 |
| 48 void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) { |
| 49 memset(addr, 0, sizeof(*addr)); |
| 50 |
| 51 addr->sin_family = AF_INET; |
| 52 addr->sin_port = htons(port); |
| 53 addr->sin_addr.s_addr = htonl(ip); |
| 54 } |
| 55 |
| 56 int Bind(int fd, uint32_t ip, uint16_t port) { |
| 57 sockaddr_in addr; |
| 58 socklen_t addrlen = sizeof(addr); |
| 59 |
| 60 IP4ToSockAddr(ip, port, &addr); |
| 61 int err = bind(fd, (sockaddr*) &addr, addrlen); |
| 62 |
| 63 if (err == -1) |
| 64 return errno; |
| 65 return 0; |
| 66 } |
| 67 |
| 68 void SetupPorts() { |
| 69 EXPECT_EQ(Bind(sock1, LOCAL_HOST, 0), ENONE); |
| 70 EXPECT_EQ(Bind(sock2, LOCAL_HOST, 0), ENONE); |
| 71 } |
| 72 |
| 73 public: |
| 74 int sock1; |
| 75 int sock2; |
| 76 }; |
| 77 |
| 78 class SocketTestUDP : public SocketTest { |
| 79 public: |
| 80 SocketTestUDP() { |
| 81 sock1 = socket(AF_INET, SOCK_DGRAM, 0); |
| 82 sock2 = socket(AF_INET, SOCK_DGRAM, 0); |
| 83 |
| 84 EXPECT_LT(-1, sock1); |
| 85 EXPECT_LT(-1, sock2); |
| 86 } |
| 87 }; |
| 88 |
| 89 class SocketTestTCP : public SocketTest { |
| 90 public: |
| 91 SocketTestTCP() { |
| 92 sock1 = socket(AF_INET, SOCK_STREAM, 0); |
| 93 sock2 = socket(AF_INET, SOCK_STREAM, 0); |
| 94 |
| 95 EXPECT_LT(-1, sock1); |
| 96 EXPECT_LT(-1, sock2); |
| 97 } |
| 98 }; |
| 99 |
| 100 } // namespace |
| 101 |
| 102 TEST(SocketTestSimple, Socket) { |
| 103 EXPECT_EQ(-1, socket(AF_UNIX, SOCK_STREAM, 0)); |
| 104 EXPECT_EQ(errno, EAFNOSUPPORT); |
| 105 EXPECT_EQ(-1, socket(AF_INET, SOCK_RAW, 0)); |
| 106 EXPECT_EQ(errno, EPROTONOSUPPORT); |
| 107 |
| 108 int sock1 = socket(AF_INET, SOCK_DGRAM, 0); |
| 109 EXPECT_NE(-1, sock1); |
| 110 |
| 111 int sock2 = socket(AF_INET6, SOCK_DGRAM, 0); |
| 112 EXPECT_NE(-1, sock2); |
| 113 |
| 114 int sock3 = socket(AF_INET, SOCK_STREAM, 0); |
| 115 EXPECT_NE(-1, sock3); |
| 116 |
| 117 int sock4 = socket(AF_INET6, SOCK_STREAM, 0); |
| 118 EXPECT_NE(-1, sock4); |
| 119 |
| 120 close(sock1); |
| 121 close(sock2); |
| 122 close(sock3); |
| 123 close(sock4); |
| 124 } |
| 125 |
| 126 TEST_F(SocketTestUDP, Bind) { |
| 127 // Bind away. |
| 128 EXPECT_EQ(Bind(sock1, LOCAL_HOST, PORT1), ENONE); |
| 129 |
| 130 // Invalid to rebind a socket. |
| 131 EXPECT_EQ(Bind(sock1, LOCAL_HOST, PORT1), EINVAL); |
| 132 |
| 133 // Addr in use. |
| 134 EXPECT_EQ(Bind(sock2, LOCAL_HOST, PORT1), EADDRINUSE); |
| 135 |
| 136 // Bind with a wildcard. |
| 137 EXPECT_EQ(Bind(sock2, LOCAL_HOST, ANY_PORT), ENONE); |
| 138 |
| 139 // Invalid to rebind after wildcard |
| 140 EXPECT_EQ(Bind(sock2, LOCAL_HOST, PORT1), EINVAL); |
| 141 |
| 142 } |
| 143 |
| 144 TEST_F(SocketTestUDP, SendRcv) { |
| 145 char outbuf[256]; |
| 146 char inbuf[512]; |
| 147 |
| 148 memset(outbuf, 1, sizeof(outbuf)); |
| 149 memset(inbuf, 0, sizeof(inbuf)); |
| 150 |
| 151 EXPECT_EQ(Bind(sock1, LOCAL_HOST, PORT1), ENONE); |
| 152 EXPECT_EQ(Bind(sock2, LOCAL_HOST, PORT2), ENONE); |
| 153 |
| 154 sockaddr_in addr; |
| 155 socklen_t addrlen = sizeof(addr); |
| 156 IP4ToSockAddr(LOCAL_HOST, PORT2, &addr); |
| 157 |
| 158 int len1 = |
| 159 sendto(sock1, outbuf, sizeof(outbuf), 0, (sockaddr *) &addr, addrlen); |
| 160 EXPECT_EQ(sizeof(outbuf), len1); |
| 161 |
| 162 // Ensure the buffers are different |
| 163 EXPECT_NE(0, memcmp(outbuf, inbuf, sizeof(outbuf))); |
| 164 memset(&addr, 0, sizeof(addr)); |
| 165 |
| 166 // Try to receive the previously sent packet |
| 167 int len2 = |
| 168 recvfrom(sock2, inbuf, sizeof(inbuf), 0, (sockaddr *) &addr, &addrlen); |
| 169 EXPECT_EQ(sizeof(outbuf), len2); |
| 170 EXPECT_EQ(sizeof(sockaddr_in), addrlen); |
| 171 EXPECT_EQ(PORT1, htons(addr.sin_port)); |
| 172 |
| 173 // Now they should be the same |
| 174 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf))); |
| 175 } |
| 176 |
| 177 #if 0 |
| 178 TEST_F(SocketTestTCP, Connect) { |
| 179 int sock = socket(AF_INET, SOCK_STREAM, 0); |
| 180 EXPECT_NE(-1, sock); |
| 181 |
| 182 sockaddr_in addr; |
| 183 socklen_t addrlen = sizeof(addr); |
| 184 |
| 185 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr); |
| 186 int err = connect(sock, (sockaddr*) &addr, addrlen); |
| 187 EXPECT_EQ(ENONE, err) << "Failed with errno: " << errno << "\n"; |
| 188 } |
| 189 #endif |
| 190 |
| 191 #endif // PROVIDES_SOCKETPAIR_API |
OLD | NEW |