/*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <folly/SocketAddress.h>
-#include <gtest/gtest.h>
#include <iostream>
#include <sstream>
+#include <system_error>
+
+#include <folly/experimental/TestUtil.h>
+#include <folly/portability/GTest.h>
+#include <folly/portability/Sockets.h>
+#include <folly/test/SocketAddressTestHelper.h>
using namespace boost;
using std::string;
using std::cerr;
using std::endl;
using folly::SocketAddress;
+using folly::SocketAddressTestHelper;
+using folly::test::TemporaryDirectory;
+
+namespace fsp = folly::portability::sockets;
TEST(SocketAddress, Size) {
SocketAddress addr;
EXPECT_EQ(inaddr->sin_port, htons(4321));
}
+TEST(SocketAddress, StringConversion) {
+ SocketAddress addr("1.2.3.4", 4321);
+ EXPECT_EQ(addr.getFamily(), AF_INET);
+ EXPECT_EQ(addr.getAddressStr(), "1.2.3.4");
+ char buf[30];
+ addr.getAddressStr(buf, 2);
+ EXPECT_STREQ(buf, "1");
+}
+
TEST(SocketAddress, IPv4ToStringConversion) {
// testing addresses *.5.5.5, 5.*.5.5, 5.5.*.5, 5.5.5.*
SocketAddress addr;
}
}
+TEST(SocketAddress, SetFromIpAddressPort) {
+ SocketAddress addr;
+ folly::IPAddress ipAddr("123.234.0.23");
+ addr.setFromIpAddrPort(ipAddr, 8888);
+ EXPECT_EQ(addr.getFamily(), AF_INET);
+ EXPECT_EQ(addr.getAddressStr(), "123.234.0.23");
+ EXPECT_EQ(addr.getIPAddress(), ipAddr);
+ EXPECT_EQ(addr.getPort(), 8888);
+
+ folly::IPAddress ip6Addr("2620:0:1cfe:face:b00c::3");
+ SocketAddress addr6(ip6Addr, 8888);
+ EXPECT_EQ(addr6.getFamily(), AF_INET6);
+ EXPECT_EQ(addr6.getAddressStr(), "2620:0:1cfe:face:b00c::3");
+ EXPECT_EQ(addr6.getIPAddress(), ip6Addr);
+ EXPECT_EQ(addr6.getPort(), 8888);
+}
+
TEST(SocketAddress, SetFromIpv4) {
SocketAddress addr;
addr.setFromIpPort("255.254.253.252", 8888);
EXPECT_EQ(addr.getPort(), 80);
// Call setFromLocalIpPort() with an IP and port.
- addr.setFromLocalIpPort("127.0.0.1:4321");
- EXPECT_EQ(addr.getAddressStr(), "127.0.0.1");
- EXPECT_EQ(addr.getPort(), 4321);
+ if (SocketAddressTestHelper::isIPv4Enabled()) {
+ addr.setFromLocalIpPort("127.0.0.1:4321");
+ EXPECT_EQ(addr.getAddressStr(), "127.0.0.1");
+ EXPECT_EQ(addr.getPort(), 4321);
+ }
+ if (SocketAddressTestHelper::isIPv6Enabled()) {
+ addr.setFromLocalIpPort("::1:4321");
+ EXPECT_EQ(addr.getAddressStr(), "::1");
+ EXPECT_EQ(addr.getPort(), 4321);
+ }
// setFromIpPort() without an address should fail
EXPECT_THROW(addr.setFromIpPort("4321"), std::invalid_argument);
EXPECT_EQ(addr.getFamily(), AF_INET);
EXPECT_EQ(addr.getAddressStr(), "1.2.3.4");
EXPECT_EQ(addr.getPort(), 9999);
+
+ // Call setFromIpPort() with a bracketed IPv6
+ addr.setFromIpPort("[::]:1234");
+ EXPECT_EQ(addr.getFamily(), AF_INET6);
+ EXPECT_EQ(addr.getAddressStr(), "::");
+ EXPECT_EQ(addr.getPort(), 1234);
+
+ // Call setFromIpPort() with a bracketed IPv6
+ addr.setFromIpPort("[9:8::2]:1234");
+ EXPECT_EQ(addr.getFamily(), AF_INET6);
+ EXPECT_EQ(addr.getAddressStr(), "9:8::2");
+ EXPECT_EQ(addr.getPort(), 1234);
+
+ // Call setFromIpPort() with a bracketed IPv6 and no port
+ EXPECT_THROW(addr.setFromIpPort("[::]"), std::system_error);
}
TEST(SocketAddress, EqualityAndHash) {
SocketAddress *serverPeerAddrRet,
SocketAddress *clientAddrRet,
SocketAddress *clientPeerAddrRet) {
- int listenSock = socket(serverBindAddr->getFamily(), SOCK_STREAM, 0);
+ int listenSock = fsp::socket(serverBindAddr->getFamily(), SOCK_STREAM, 0);
REQUIRE_ERRNO(listenSock > 0, "failed to create listen socket");
sockaddr_storage laddr;
serverBindAddr->getAddress(&laddr);
// Note that we use the family from serverBindAddr here, since we allow
// clientBindAddr to be nullptr.
- int clientSock = socket(serverBindAddr->getFamily(), SOCK_STREAM, 0);
+ int clientSock = fsp::socket(serverBindAddr->getFamily(), SOCK_STREAM, 0);
REQUIRE_ERRNO(clientSock > 0, "failed to create client socket");
if (clientBindAddr != nullptr) {
sockaddr_storage clientAddr;
TEST(SocketAddress, SetFromSocketUnixExplicit) {
// Pick two temporary path names.
- // We use mkstemp() just to avoid warnings about mktemp,
- // but we need to remove the file to let the socket code bind to it.
- char serverPath[] = "/tmp/SocketAddressTest.server.XXXXXX";
- int serverPathFd = mkstemp(serverPath);
- EXPECT_GE(serverPathFd, 0);
- char clientPath[] = "/tmp/SocketAddressTest.client.XXXXXX";
- int clientPathFd = mkstemp(clientPath);
- EXPECT_GE(clientPathFd, 0);
-
- int rc = unlink(serverPath);
- EXPECT_EQ(rc, 0);
- rc = unlink(clientPath);
- EXPECT_EQ(rc, 0);
+ TemporaryDirectory tempDirectory("SocketAddressTest");
+ std::string serverPath = (tempDirectory.path() / "server").string();
+ std::string clientPath = (tempDirectory.path() / "client").string();
SocketAddress serverBindAddr;
SocketAddress clientBindAddr;
SocketAddress clientAddr;
SocketAddress clientPeerAddr;
try {
- serverBindAddr.setFromPath(serverPath);
- clientBindAddr.setFromPath(clientPath);
+ serverBindAddr.setFromPath(serverPath.c_str());
+ clientBindAddr.setFromPath(clientPath.c_str());
testSetFromSocket(&serverBindAddr, &clientBindAddr,
&listenAddr, &acceptAddr,
&clientAddr, &clientPeerAddr);
} catch (...) {
// Remove the socket files after we are done
- unlink(serverPath);
- unlink(clientPath);
+ unlink(serverPath.c_str());
+ unlink(clientPath.c_str());
throw;
}
- unlink(serverPath);
- unlink(clientPath);
+ unlink(serverPath.c_str());
+ unlink(clientPath.c_str());
// The server socket's local address should be the same as the listen
// address.
TEST(SocketAddress, SetFromSocketUnixAnonymous) {
// Test an anonymous client talking to a fixed-path unix socket.
- char serverPath[] = "/tmp/SocketAddressTest.server.XXXXXX";
- int serverPathFd = mkstemp(serverPath);
- EXPECT_GE(serverPathFd, 0);
- int rc = unlink(serverPath);
- EXPECT_EQ(rc, 0);
+ TemporaryDirectory tempDirectory("SocketAddressTest");
+ std::string serverPath = (tempDirectory.path() / "server").string();
SocketAddress serverBindAddr;
SocketAddress listenAddr;
SocketAddress clientAddr;
SocketAddress clientPeerAddr;
try {
- serverBindAddr.setFromPath(serverPath);
+ serverBindAddr.setFromPath(serverPath.c_str());
testSetFromSocket(&serverBindAddr, nullptr,
&listenAddr, &acceptAddr,
&clientAddr, &clientPeerAddr);
} catch (...) {
// Remove the socket file after we are done
- unlink(serverPath);
+ unlink(serverPath.c_str());
throw;
}
- unlink(serverPath);
+ unlink(serverPath.c_str());
// The server socket's local address should be the same as the listen
// address.
addy.reset();
EXPECT_EQ(addy.getFamily(), AF_UNSPEC);
}
+
+TEST(SocketAddress, ResetIPAddress) {
+ SocketAddress addr;
+ addr.setFromIpPort("127.0.0.1", 80);
+ addr.reset();
+ EXPECT_EQ(addr.getFamily(), AF_UNSPEC);
+ EXPECT_FALSE(addr.isInitialized());
+ EXPECT_TRUE(addr.empty());
+
+ addr.setFromIpPort("2620:0:1cfe:face:b00c::3:65535");
+ addr.reset();
+ EXPECT_EQ(addr.getFamily(), AF_UNSPEC);
+ EXPECT_FALSE(addr.isInitialized());
+ EXPECT_TRUE(addr.empty());
+}
+
+TEST(SocketAddress, ValidFamilyInet) {
+ SocketAddress addr;
+ EXPECT_FALSE(addr.isFamilyInet());
+ folly::IPAddress ipAddr("123.234.0.23");
+ addr.setFromIpAddrPort(ipAddr, 8888);
+ EXPECT_TRUE(addr.isFamilyInet());
+
+ folly::IPAddress ip6Addr("2620:0:1cfe:face:b00c::3");
+ SocketAddress addr6(ip6Addr, 8888);
+ EXPECT_TRUE(addr6.isFamilyInet());
+}