OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <arpa/inet.h> | 5 #include <arpa/inet.h> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <netinet/in.h> | 8 #include <netinet/in.h> |
9 #include <pthread.h> | 9 #include <pthread.h> |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
(...skipping 26 matching lines...) Expand all Loading... |
37 namespace { | 37 namespace { |
38 | 38 |
39 void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) { | 39 void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) { |
40 memset(addr, 0, sizeof(*addr)); | 40 memset(addr, 0, sizeof(*addr)); |
41 | 41 |
42 addr->sin_family = AF_INET; | 42 addr->sin_family = AF_INET; |
43 addr->sin_port = htons(port); | 43 addr->sin_port = htons(port); |
44 addr->sin_addr.s_addr = htonl(ip); | 44 addr->sin_addr.s_addr = htonl(ip); |
45 } | 45 } |
46 | 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 |
47 class SocketTest : public ::testing::Test { | 55 class SocketTest : public ::testing::Test { |
48 public: | 56 public: |
49 SocketTest() : sock1(-1), sock2(-1) {} | 57 SocketTest() : sock1(-1), sock2(-1) {} |
50 | 58 |
51 void TearDown() { | 59 void TearDown() { |
52 if (sock1 != -1) | 60 if (sock1 != -1) |
53 EXPECT_EQ(0, close(sock1)); | 61 EXPECT_EQ(0, close(sock1)); |
54 if (sock2 != -1) | 62 if (sock2 != -1) |
55 EXPECT_EQ(0, close(sock2)); | 63 EXPECT_EQ(0, close(sock2)); |
56 } | 64 } |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf))); | 292 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf))); |
285 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf))); | 293 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf))); |
286 | 294 |
287 strcpy(outbuf, "world"); | 295 strcpy(outbuf, "world"); |
288 memset(inbuf, 0, sizeof(inbuf)); | 296 memset(inbuf, 0, sizeof(inbuf)); |
289 ASSERT_EQ(sizeof(outbuf), write(sock_, outbuf, sizeof(outbuf))); | 297 ASSERT_EQ(sizeof(outbuf), write(sock_, outbuf, sizeof(outbuf))); |
290 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf))); | 298 ASSERT_EQ(sizeof(outbuf), read(sock_, inbuf, sizeof(inbuf))); |
291 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf))); | 299 EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf))); |
292 } | 300 } |
293 | 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 |
294 TEST_F(SocketTest, Getsockopt) { | 332 TEST_F(SocketTest, Getsockopt) { |
295 sock1 = socket(AF_INET, SOCK_STREAM, 0); | 333 sock1 = socket(AF_INET, SOCK_STREAM, 0); |
296 EXPECT_GT(sock1, -1); | 334 EXPECT_GT(sock1, -1); |
297 int socket_error = 99; | 335 int socket_error = 99; |
298 socklen_t len = sizeof(socket_error); | 336 socklen_t len = sizeof(socket_error); |
299 | 337 |
300 // Test for valid option (SO_ERROR) which should be 0 when a socket | 338 // Test for valid option (SO_ERROR) which should be 0 when a socket |
301 // is first created. | 339 // is first created. |
302 ASSERT_EQ(0, getsockopt(sock1, SOL_SOCKET, SO_ERROR, &socket_error, &len)); | 340 ASSERT_EQ(0, getsockopt(sock1, SOL_SOCKET, SO_ERROR, &socket_error, &len)); |
303 ASSERT_EQ(0, socket_error); | 341 ASSERT_EQ(0, socket_error); |
(...skipping 23 matching lines...) Expand all Loading... |
327 len = sizeof(reuse); | 365 len = sizeof(reuse); |
328 ASSERT_EQ(0, setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &reuse, len)); | 366 ASSERT_EQ(0, setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &reuse, len)); |
329 } | 367 } |
330 | 368 |
331 TEST_F(SocketTestUDP, Listen) { | 369 TEST_F(SocketTestUDP, Listen) { |
332 EXPECT_EQ(-1, listen(sock1, 10)); | 370 EXPECT_EQ(-1, listen(sock1, 10)); |
333 EXPECT_EQ(errno, ENOTSUP); | 371 EXPECT_EQ(errno, ENOTSUP); |
334 } | 372 } |
335 | 373 |
336 TEST_F(SocketTestTCP, Listen) { | 374 TEST_F(SocketTestTCP, Listen) { |
337 // Accept should fail when socket not listening | |
338 sockaddr_in addr; | 375 sockaddr_in addr; |
339 socklen_t addrlen = sizeof(addr); | 376 socklen_t addrlen = sizeof(addr); |
340 | 377 |
341 int server_sock = sock1; | 378 int server_sock = sock1; |
342 | 379 |
343 // Accept before listen should fail | 380 // Accept before listen should fail |
344 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen)); | 381 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen)); |
345 | 382 |
346 // Listen should fail on unbound socket | 383 // Listen should fail on unbound socket |
347 ASSERT_EQ(-1, listen(server_sock, 10)); | 384 ASSERT_EQ(-1, listen(server_sock, 10)); |
348 | 385 |
349 // bind and listen | 386 // Bind and Listen |
350 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1)); | 387 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1)); |
351 ASSERT_EQ(0, listen(server_sock, 10)) | 388 ASSERT_EQ(0, listen(server_sock, 10)) |
352 << "listen failed with: " << strerror(errno); | 389 << "listen failed with: " << strerror(errno); |
353 | 390 |
354 // Connect to listening socket | 391 // Connect to listening socket |
355 int client_sock = sock2; | 392 int client_sock = sock2; |
356 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr); | 393 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr); |
357 addrlen = sizeof(addr); | 394 addrlen = sizeof(addr); |
358 ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen)) | 395 ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen)) |
359 << "Failed with " << errno << ": " << strerror(errno) << "\n"; | 396 << "Failed with " << errno << ": " << strerror(errno) << "\n"; |
(...skipping 10 matching lines...) Expand all Loading... |
370 // Verify addr and addrlen were set correctly | 407 // Verify addr and addrlen were set correctly |
371 ASSERT_EQ(addrlen, sizeof(sockaddr_in)); | 408 ASSERT_EQ(addrlen, sizeof(sockaddr_in)); |
372 sockaddr_in client_addr; | 409 sockaddr_in client_addr; |
373 ASSERT_EQ(0, getsockname(client_sock, (sockaddr*)&client_addr, &addrlen)); | 410 ASSERT_EQ(0, getsockname(client_sock, (sockaddr*)&client_addr, &addrlen)); |
374 ASSERT_EQ(client_addr.sin_family, addr.sin_family); | 411 ASSERT_EQ(client_addr.sin_family, addr.sin_family); |
375 ASSERT_EQ(client_addr.sin_port, addr.sin_port); | 412 ASSERT_EQ(client_addr.sin_port, addr.sin_port); |
376 ASSERT_EQ(client_addr.sin_addr.s_addr, addr.sin_addr.s_addr); | 413 ASSERT_EQ(client_addr.sin_addr.s_addr, addr.sin_addr.s_addr); |
377 | 414 |
378 char inbuf[512]; | 415 char inbuf[512]; |
379 ASSERT_EQ(5, recv(new_socket, inbuf, 5, 0)); | 416 ASSERT_EQ(5, recv(new_socket, inbuf, 5, 0)); |
| 417 ASSERT_EQ(0, close(new_socket)); |
| 418 } |
| 419 |
| 420 TEST_F(SocketTestTCP, ListenNonBlocking) { |
| 421 int server_sock = sock1; |
| 422 |
| 423 // Set non-blocking |
| 424 SetNonBlocking(server_sock); |
| 425 |
| 426 // bind and listen |
| 427 ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1)); |
| 428 ASSERT_EQ(0, listen(server_sock, 10)) |
| 429 << "listen failed with: " << strerror(errno); |
| 430 |
| 431 // Accept should fail with EAGAIN since there is no incomming |
| 432 // connection. |
| 433 sockaddr_in addr; |
| 434 socklen_t addrlen = sizeof(addr); |
| 435 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen)); |
| 436 ASSERT_EQ(EAGAIN, errno); |
| 437 |
| 438 // If we poll the listening socket it should also return |
| 439 // not readable to indicate that no connections are available |
| 440 // to accept. |
| 441 struct pollfd pollfd = { server_sock, POLLIN|POLLOUT, 0 }; |
| 442 ASSERT_EQ(0, poll(&pollfd, 1, 0)); |
| 443 |
| 444 // Connect to listening socket |
| 445 int client_sock = sock2; |
| 446 IP4ToSockAddr(LOCAL_HOST, PORT1, &addr); |
| 447 addrlen = sizeof(addr); |
| 448 ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen)) |
| 449 << "Failed with " << errno << ": " << strerror(errno) << "\n"; |
| 450 |
| 451 // Not poll again but with an infintie timeout. |
| 452 pollfd.fd = server_sock; |
| 453 pollfd.events = POLLIN | POLLOUT; |
| 454 ASSERT_EQ(1, poll(&pollfd, 1, -1)); |
| 455 |
| 456 // Now non-blocking accept should return the new socket |
| 457 int new_socket = accept(server_sock, (sockaddr*)&addr, &addrlen); |
| 458 ASSERT_NE(-1, new_socket) |
| 459 << "accept failed with: " << strerror(errno) << "\n"; |
| 460 ASSERT_EQ(0, close(new_socket)); |
| 461 |
| 462 // Accept calls should once again fail with EAGAIN |
| 463 ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen)); |
| 464 ASSERT_EQ(EAGAIN, errno); |
| 465 |
| 466 // As should polling the listening socket |
| 467 pollfd.fd = server_sock; |
| 468 pollfd.events = POLLIN | POLLOUT; |
| 469 ASSERT_EQ(0, poll(&pollfd, 1, 0)); |
380 } | 470 } |
381 | 471 |
382 #endif // PROVIDES_SOCKET_API | 472 #endif // PROVIDES_SOCKET_API |
OLD | NEW |