TEST(SocketAddress, SetFromSocketIPv4) { TSocketAddress serverBindAddr("0.0.0.0", 0); TSocketAddress clientBindAddr("0.0.0.0", 0); TSocketAddress listenAddr; TSocketAddress acceptAddr; TSocketAddress serverAddr; TSocketAddress serverPeerAddr; TSocketAddress clientAddr; TSocketAddress clientPeerAddr; testSetFromSocket(&serverBindAddr, &clientBindAddr, &listenAddr, &acceptAddr, &serverAddr, &serverPeerAddr, &clientAddr, &clientPeerAddr); // The server socket's local address should have the same port as the listen // address. The IP will be different, since the listening socket is // listening on INADDR_ANY, but the server socket will have a concrete IP // address assigned to it. EXPECT_EQ(serverAddr.getPort(), listenAddr.getPort()); // The client's peer address should always be the same as the server // socket's address. EXPECT_EQ(clientPeerAddr, serverAddr); // The address returned by getpeername() on the server socket should // be the same as the address returned by accept() EXPECT_EQ(serverPeerAddr, acceptAddr); EXPECT_EQ(serverPeerAddr, clientAddr); EXPECT_EQ(acceptAddr, clientAddr); }
void testSetFromSocket(const TSocketAddress *serverBindAddr, const TSocketAddress *clientBindAddr, TSocketAddress *listenAddrRet, TSocketAddress *acceptAddrRet, TSocketAddress *serverAddrRet, TSocketAddress *serverPeerAddrRet, TSocketAddress *clientAddrRet, TSocketAddress *clientPeerAddrRet) { int listenSock = socket(serverBindAddr->getFamily(), SOCK_STREAM, 0); REQUIRE_ERRNO(listenSock > 0, "failed to create listen socket"); sockaddr_storage laddr; serverBindAddr->getAddress(&laddr); socklen_t laddrLen = serverBindAddr->getActualSize(); int rc = bind(listenSock, reinterpret_cast<sockaddr*>(&laddr), laddrLen); REQUIRE_ERRNO(rc == 0, "failed to bind to server socket"); rc = listen(listenSock, 10); REQUIRE_ERRNO(rc == 0, "failed to listen"); listenAddrRet->setFromLocalAddress(listenSock); TSocketAddress listenPeerAddr; EXPECT_THROW(listenPeerAddr.setFromPeerAddress(listenSock), TTransportException); // Note that we use the family from serverBindAddr here, since we allow // clientBindAddr to be nullptr. int clientSock = socket(serverBindAddr->getFamily(), SOCK_STREAM, 0); REQUIRE_ERRNO(clientSock > 0, "failed to create client socket"); if (clientBindAddr != nullptr) { sockaddr_storage clientAddr; clientBindAddr->getAddress(&clientAddr); rc = bind(clientSock, reinterpret_cast<sockaddr*>(&clientAddr), clientBindAddr->getActualSize()); REQUIRE_ERRNO(rc == 0, "failed to bind to client socket"); } sockaddr_storage listenAddr; listenAddrRet->getAddress(&listenAddr); rc = connect(clientSock, reinterpret_cast<sockaddr*>(&listenAddr), listenAddrRet->getActualSize()); REQUIRE_ERRNO(rc == 0, "failed to connect"); sockaddr_storage acceptAddr; socklen_t acceptAddrLen = sizeof(acceptAddr); int serverSock = accept(listenSock, reinterpret_cast<sockaddr*>(&acceptAddr), &acceptAddrLen); REQUIRE_ERRNO(serverSock > 0, "failed to accept"); acceptAddrRet->setFromSockaddr(reinterpret_cast<sockaddr*>(&acceptAddr), acceptAddrLen); serverAddrRet->setFromLocalAddress(serverSock); serverPeerAddrRet->setFromPeerAddress(serverSock); clientAddrRet->setFromLocalAddress(clientSock); clientPeerAddrRet->setFromPeerAddress(clientSock); close(clientSock); close(serverSock); close(listenSock); }
void CheckPrefixMatch(const TSocketAddress& first, const TSocketAddress& second, unsigned matchingPrefixLen) { unsigned i; for (i = 0; i <= matchingPrefixLen; i++) { EXPECT_TRUE(first.prefixMatch(second, i)); } unsigned addrLen = (first.getFamily() == AF_INET6) ? 128 : 32; for (; i <= addrLen; i++) { EXPECT_TRUE(!first.prefixMatch(second, i)); } }
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/TSocketAddressTest.server.XXXXXX"; int serverPathFd = mkstemp(serverPath); EXPECT_GE(serverPathFd, 0); char clientPath[] = "/tmp/TSocketAddressTest.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); TSocketAddress serverBindAddr; TSocketAddress clientBindAddr; TSocketAddress listenAddr; TSocketAddress acceptAddr; TSocketAddress serverAddr; TSocketAddress serverPeerAddr; TSocketAddress clientAddr; TSocketAddress clientPeerAddr; try { serverBindAddr.setFromPath(serverPath); clientBindAddr.setFromPath(clientPath); testSetFromSocket(&serverBindAddr, &clientBindAddr, &listenAddr, &acceptAddr, &serverAddr, &serverPeerAddr, &clientAddr, &clientPeerAddr); } catch (...) { // Remove the socket files after we are done unlink(serverPath); unlink(clientPath); throw; } unlink(serverPath); unlink(clientPath); // The server socket's local address should be the same as the listen // address. EXPECT_EQ(serverAddr, listenAddr); // The client's peer address should always be the same as the server // socket's address. EXPECT_EQ(clientPeerAddr, serverAddr); EXPECT_EQ(serverPeerAddr, clientAddr); EXPECT_EQ(serverPeerAddr, acceptAddr); EXPECT_EQ(acceptAddr, clientAddr); }
TEST(SocketAddress, IPv4ToStringConversion) { // testing addresses *.5.5.5, 5.*.5.5, 5.5.*.5, 5.5.5.* TSocketAddress addr; for (int pos = 0; pos < 4; ++pos) { for (int i = 0; i < 256; ++i) { int fragments[] = {5,5,5,5}; fragments[pos] = i; std::ostringstream ss; ss << fragments[0] << "." << fragments[1] << "." << fragments[2] << "." << fragments[3]; string ipString = ss.str(); addr.setFromIpPort(ipString, 1234); EXPECT_EQ(addr.getAddressStr(), ipString); } } }
std::string HeaderServerChannel::getTransportDebugString(TAsyncTransport* transport) { if (!transport) { return std::string(); } auto ret = folly::to<std::string>("(transport ", folly::demangle(typeid(*transport))); try { TSocketAddress addr; transport->getPeerAddress(&addr); folly::toAppend(", address ", addr.getAddressStr(), ", port ", addr.getPort(), &ret); } catch (const TTransportException& e) { } ret += ')'; return std::move(ret); }
/* * Note this test exercises Linux-specific Unix socket behavior */ TEST(SocketAddress, SetFromSocketUnixAbstract) { // Explicitly binding to an empty path results in an abstract socket // name being picked for us automatically. TSocketAddress serverBindAddr; string path(1, 0); path.append("test address"); serverBindAddr.setFromPath(path); TSocketAddress clientBindAddr; clientBindAddr.setFromPath(""); TSocketAddress listenAddr; TSocketAddress acceptAddr; TSocketAddress serverAddr; TSocketAddress serverPeerAddr; TSocketAddress clientAddr; TSocketAddress clientPeerAddr; testSetFromSocket(&serverBindAddr, &clientBindAddr, &listenAddr, &acceptAddr, &serverAddr, &serverPeerAddr, &clientAddr, &clientPeerAddr); // The server socket's local address should be the same as the listen // address. EXPECT_EQ(serverAddr, listenAddr); // The client's peer address should always be the same as the server // socket's address. EXPECT_EQ(clientPeerAddr, serverAddr); EXPECT_EQ(serverPeerAddr, clientAddr); // Oddly, the address returned by accept() does not seem to match the address // returned by getpeername() on the server socket or getsockname() on the // client socket. // EXPECT_EQ(serverPeerAddr, acceptAddr); // EXPECT_EQ(acceptAddr, clientAddr); }
TEST(SocketAddress, SetFromSocketUnixAnonymous) { // Test an anonymous client talking to a fixed-path unix socket. char serverPath[] = "/tmp/TSocketAddressTest.server.XXXXXX"; int serverPathFd = mkstemp(serverPath); EXPECT_GE(serverPathFd, 0); int rc = unlink(serverPath); EXPECT_EQ(rc, 0); TSocketAddress serverBindAddr; TSocketAddress listenAddr; TSocketAddress acceptAddr; TSocketAddress serverAddr; TSocketAddress serverPeerAddr; TSocketAddress clientAddr; TSocketAddress clientPeerAddr; try { serverBindAddr.setFromPath(serverPath); testSetFromSocket(&serverBindAddr, nullptr, &listenAddr, &acceptAddr, &serverAddr, &serverPeerAddr, &clientAddr, &clientPeerAddr); } catch (...) { // Remove the socket file after we are done unlink(serverPath); throw; } unlink(serverPath); // The server socket's local address should be the same as the listen // address. EXPECT_EQ(serverAddr, listenAddr); // The client's peer address should always be the same as the server // socket's address. EXPECT_EQ(clientPeerAddr, serverAddr); // Since the client is using an anonymous address, it won't compare equal to // any other anonymous addresses. Make sure the addresses are anonymous. EXPECT_EQ(serverPeerAddr.getPath(), ""); EXPECT_EQ(clientAddr.getPath(), ""); EXPECT_EQ(acceptAddr.getPath(), ""); }
TEST(SocketAddress, SetFromIpv4) { TSocketAddress addr; addr.setFromIpPort("255.254.253.252", 8888); EXPECT_EQ(addr.getFamily(), AF_INET); EXPECT_EQ(addr.getAddressStr(), "255.254.253.252"); EXPECT_EQ(addr.getPort(), 8888); sockaddr_storage addrStorage; addr.getAddress(&addrStorage); const sockaddr_in* inaddr = reinterpret_cast<sockaddr_in*>(&addrStorage); EXPECT_EQ(inaddr->sin_addr.s_addr, htonl(0xfffefdfc)); EXPECT_EQ(inaddr->sin_port, htons(8888)); }
virtual void run() { for (uint32_t n = 0; n < numIterations_; ++n) { for (vector<TSocketAddress>::const_iterator it = addresses_->begin(); it != addresses_->end(); ++it) { // Connect to the server std::shared_ptr<TSocket> socket(new TSocket(&*it)); socket->open(); // Get the local address that our client socket is using TSocketAddress clientAddress; clientAddress.setFromLocalAddress(socket->getSocketFD()); // Create a client, and call getAddress() to have the server tell // us what address it thinks we are connecting from. std::shared_ptr<TFramedTransport> transport(new TFramedTransport(socket)); std::shared_ptr<Protocol> protocol(new Protocol(transport)); ConnCtxServiceClient client(protocol); string addressData; try { client.getClientAddress(addressData); } catch (const std::exception& ex) { TSocketAddress uninitAddress; errors_.push_back(make_pair(uninitAddress, clientAddress)); continue; } TSocketAddress returnedAddress; returnedAddress.setFromSockaddr( reinterpret_cast<const struct sockaddr*>(addressData.c_str()), addressData.size()); if (returnedAddress != clientAddress) { returnedAddress.tryConvertToIPv4(); clientAddress.tryConvertToIPv4(); if (returnedAddress != clientAddress) { errors_.push_back(make_pair(returnedAddress, clientAddress)); } } } } }
TEST(SocketAddress, Unix) { TSocketAddress addr; // Test a small path addr.setFromPath("foo"); EXPECT_EQ(addr.getFamily(), AF_UNIX); EXPECT_EQ(addr.describe(), "foo"); EXPECT_THROW(addr.getAddressStr(), TTransportException); EXPECT_THROW(addr.getPort(), TTransportException); EXPECT_TRUE(addr.isPrivateAddress()); EXPECT_TRUE(addr.isLoopbackAddress()); // Test a path that is too large const char longPath[] = "abcdefghijklmnopqrstuvwxyz0123456789" "abcdefghijklmnopqrstuvwxyz0123456789" "abcdefghijklmnopqrstuvwxyz0123456789" "abcdefghijklmnopqrstuvwxyz0123456789"; EXPECT_THROW(addr.setFromPath(longPath), TTransportException); // The original address should still be the same EXPECT_EQ(addr.getFamily(), AF_UNIX); EXPECT_EQ(addr.describe(), "foo"); // Test a path that exactly fits in sockaddr_un // (not including the NUL terminator) const char exactLengthPath[] = "abcdefghijklmnopqrstuvwxyz0123456789" "abcdefghijklmnopqrstuvwxyz0123456789" "abcdefghijklmnopqrstuvwxyz0123456789"; addr.setFromPath(exactLengthPath); EXPECT_EQ(addr.describe(), exactLengthPath); // Test converting a unix socket address to an IPv4 one, then back addr.setFromHostPort("127.0.0.1", 1234); EXPECT_EQ(addr.getFamily(), AF_INET); EXPECT_EQ(addr.describe(), "127.0.0.1:1234"); addr.setFromPath("/i/am/a/unix/address"); EXPECT_EQ(addr.getFamily(), AF_UNIX); EXPECT_EQ(addr.describe(), "/i/am/a/unix/address"); // Test copy constructor and assignment operator { TSocketAddress copy(addr); EXPECT_EQ(copy, addr); copy.setFromPath("/abc"); EXPECT_NE(copy, addr); copy = addr; EXPECT_EQ(copy, addr); copy.setFromIpPort("127.0.0.1", 80); EXPECT_NE(copy, addr); copy = addr; EXPECT_EQ(copy, addr); } { TSocketAddress copy(addr); EXPECT_EQ(copy, addr); EXPECT_EQ(copy.describe(), "/i/am/a/unix/address"); EXPECT_EQ(copy.getPath(), "/i/am/a/unix/address"); TSocketAddress other("127.0.0.1", 80); EXPECT_NE(other, addr); other = copy; EXPECT_EQ(other, copy); EXPECT_EQ(other, addr); EXPECT_EQ(copy, addr); } #if __GXX_EXPERIMENTAL_CXX0X__ { TSocketAddress copy; { // move a unix address into a non-unix address TSocketAddress tmpCopy(addr); copy = std::move(tmpCopy); } EXPECT_EQ(copy, addr); copy.setFromPath("/another/path"); { // move a unix address into a unix address TSocketAddress tmpCopy(addr); copy = std::move(tmpCopy); } EXPECT_EQ(copy, addr); { // move a non-unix address into a unix address TSocketAddress tmp("127.0.0.1", 80); copy = std::move(tmp); } EXPECT_EQ(copy.getAddressStr(), "127.0.0.1"); EXPECT_EQ(copy.getPort(), 80); copy = addr; // move construct a unix address TSocketAddress other(std::move(copy)); EXPECT_EQ(other, addr); EXPECT_EQ(other.getPath(), addr.getPath()); } #endif }
TEST(SocketAddress, EqualityAndHash) { // IPv4 TSocketAddress local1("127.0.0.1", 1234); EXPECT_EQ(local1, local1); EXPECT_EQ(local1.hash(), local1.hash()); TSocketAddress local2("127.0.0.1", 1234); EXPECT_EQ(local1, local2); EXPECT_EQ(local1.hash(), local2.hash()); TSocketAddress local3("127.0.0.1", 4321); EXPECT_NE(local1, local3); EXPECT_NE(local1.hash(), local3.hash()); TSocketAddress other1("1.2.3.4", 1234); EXPECT_EQ(other1, other1); EXPECT_EQ(other1.hash(), other1.hash()); EXPECT_NE(local1, other1); EXPECT_NE(local1.hash(), other1.hash()); TSocketAddress other2("4.3.2.1", 1234); EXPECT_NE(other1.hash(), other2.hash()); EXPECT_NE(other1.hash(), other2.hash()); other2.setFromIpPort("1.2.3.4", 0); EXPECT_NE(other1.hash(), other2.hash()); EXPECT_NE(other1.hash(), other2.hash()); other2.setPort(1234); EXPECT_EQ(other1.hash(), other2.hash()); EXPECT_EQ(other1.hash(), other2.hash()); // IPv6 TSocketAddress v6_1("2620:0:1c00:face:b00c:0:0:abcd", 1234); TSocketAddress v6_2("2620:0:1c00:face:b00c::abcd", 1234); TSocketAddress v6_3("2620:0:1c00:face:b00c::bcda", 1234); EXPECT_EQ(v6_1, v6_2); EXPECT_EQ(v6_1.hash(), v6_2.hash()); EXPECT_NE(v6_1, v6_3); EXPECT_NE(v6_1.hash(), v6_3.hash()); // IPv4 versus IPv6 comparison TSocketAddress localIPv6("::1", 1234); // Even though these both refer to localhost, // IPv4 and IPv6 addresses are never treated as the same address EXPECT_NE(local1, localIPv6); EXPECT_NE(local1.hash(), localIPv6.hash()); // IPv4-mapped IPv6 addresses are not treated as equal // to the equivalent IPv4 address TSocketAddress v4("10.0.0.3", 99); TSocketAddress v6_mapped1("::ffff:10.0.0.3", 99); TSocketAddress v6_mapped2("::ffff:0a00:0003", 99); EXPECT_NE(v4, v6_mapped1); EXPECT_NE(v4, v6_mapped2); EXPECT_EQ(v6_mapped1, v6_mapped2); // However, after calling convertToIPv4(), the mapped address should now be // equal to the v4 version. EXPECT_TRUE(v6_mapped1.isIPv4Mapped()); v6_mapped1.convertToIPv4(); EXPECT_EQ(v6_mapped1, v4); EXPECT_NE(v6_mapped1, v6_mapped2); // Unix TSocketAddress unix1; unix1.setFromPath("/foo"); TSocketAddress unix2; unix2.setFromPath("/foo"); TSocketAddress unix3; unix3.setFromPath("/bar"); TSocketAddress unixAnon; unixAnon.setFromPath(""); EXPECT_EQ(unix1, unix2); EXPECT_EQ(unix1.hash(), unix2.hash()); EXPECT_NE(unix1, unix3); EXPECT_NE(unix1, unixAnon); EXPECT_NE(unix2, unix3); EXPECT_NE(unix2, unixAnon); // anonymous addresses aren't equal to any other address, // including themselves EXPECT_NE(unixAnon, unixAnon); // It isn't strictly required that hashes for different addresses be // different, but we should have very few collisions. It generally indicates // a problem if these collide EXPECT_NE(unix1.hash(), unix3.hash()); EXPECT_NE(unix1.hash(), unixAnon.hash()); EXPECT_NE(unix3.hash(), unixAnon.hash()); }
TEST(SocketAddress, SetFromStrings) { TSocketAddress addr; // Set from a numeric port string addr.setFromLocalPort("1234"); EXPECT_EQ(addr.getPort(), 1234); // setFromLocalPort() should not accept service names EXPECT_THROW(addr.setFromLocalPort("http"), TTransportException); // Call setFromLocalIpPort() with just a port, no IP addr.setFromLocalIpPort("80"); 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); // setFromIpPort() without an address should fail EXPECT_THROW(addr.setFromIpPort("4321"), TTransportException); // Call setFromIpPort() with an IPv6 address and port addr.setFromIpPort("2620:0:1cfe:face:b00c::3:65535"); EXPECT_EQ(addr.getFamily(), AF_INET6); EXPECT_EQ(addr.getAddressStr(), "2620:0:1cfe:face:b00c::3"); EXPECT_EQ(addr.getPort(), 65535); // Call setFromIpPort() with an IPv4 address and port addr.setFromIpPort("1.2.3.4:9999"); EXPECT_EQ(addr.getFamily(), AF_INET); EXPECT_EQ(addr.getAddressStr(), "1.2.3.4"); EXPECT_EQ(addr.getPort(), 9999); }
TEST(SSLUtilsTest, ValidatePeerCertNamesIPSanityTest) { X509Cert cert("thrift/lib/cpp/test/ssl/tests-cert.pem"); TSocketAddress addr; addr.setFromIpPort("127.0.0.1", 1); EXPECT_TRUE(OpenSSLUtils::validatePeerCertNames( cert.getX509(), addr.getAddress(), addr.getActualSize())); addr.setFromIpPort("::1", 1); EXPECT_TRUE(OpenSSLUtils::validatePeerCertNames( cert.getX509(), addr.getAddress(), addr.getActualSize())); addr.setFromIpPort("127.0.0.2", 1); EXPECT_FALSE(OpenSSLUtils::validatePeerCertNames( cert.getX509(), addr.getAddress(), addr.getActualSize())); addr.setFromIpPort("::2", 1); EXPECT_FALSE(OpenSSLUtils::validatePeerCertNames( cert.getX509(), addr.getAddress(), addr.getActualSize())); }