Example #1
0
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);
}
Example #2
0
/*
 * 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);
}
Example #3
0
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(), "");
}
Example #4
0
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
}
Example #5
0
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());
}