1 /* 2 * libjingle 3 * Copyright 2004, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <string> 29 30 #include "talk/base/gunit.h" 31 #include "talk/base/logging.h" 32 #include "talk/base/natserver.h" 33 #include "talk/base/natsocketfactory.h" 34 #include "talk/base/nethelpers.h" 35 #include "talk/base/network.h" 36 #include "talk/base/physicalsocketserver.h" 37 #include "talk/base/testclient.h" 38 #include "talk/base/virtualsocketserver.h" 39 40 using namespace talk_base; 41 42 bool CheckReceive( 43 TestClient* client, bool should_receive, const char* buf, size_t size) { 44 return (should_receive) ? 45 client->CheckNextPacket(buf, size, 0) : 46 client->CheckNoPacket(); 47 } 48 49 TestClient* CreateTestClient( 50 SocketFactory* factory, const SocketAddress& local_addr) { 51 AsyncUDPSocket* socket = AsyncUDPSocket::Create(factory, local_addr); 52 return new TestClient(socket); 53 } 54 55 // Tests that when sending from internal_addr to external_addrs through the 56 // NAT type specified by nat_type, all external addrs receive the sent packet 57 // and, if exp_same is true, all use the same mapped-address on the NAT. 58 void TestSend( 59 SocketServer* internal, const SocketAddress& internal_addr, 60 SocketServer* external, const SocketAddress external_addrs[4], 61 NATType nat_type, bool exp_same) { 62 Thread th_int(internal); 63 Thread th_ext(external); 64 65 SocketAddress server_addr = internal_addr; 66 server_addr.SetPort(0); // Auto-select a port 67 NATServer* nat = new NATServer( 68 nat_type, internal, server_addr, external, external_addrs[0]); 69 NATSocketFactory* natsf = new NATSocketFactory(internal, 70 nat->internal_address()); 71 72 TestClient* in = CreateTestClient(natsf, internal_addr); 73 TestClient* out[4]; 74 for (int i = 0; i < 4; i++) 75 out[i] = CreateTestClient(external, external_addrs[i]); 76 77 th_int.Start(); 78 th_ext.Start(); 79 80 const char* buf = "filter_test"; 81 size_t len = strlen(buf); 82 83 in->SendTo(buf, len, out[0]->address()); 84 SocketAddress trans_addr; 85 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); 86 87 for (int i = 1; i < 4; i++) { 88 in->SendTo(buf, len, out[i]->address()); 89 SocketAddress trans_addr2; 90 EXPECT_TRUE(out[i]->CheckNextPacket(buf, len, &trans_addr2)); 91 bool are_same = (trans_addr == trans_addr2); 92 ASSERT_EQ(are_same, exp_same) << "same translated address"; 93 ASSERT_NE(AF_UNSPEC, trans_addr.family()); 94 ASSERT_NE(AF_UNSPEC, trans_addr2.family()); 95 } 96 97 th_int.Stop(); 98 th_ext.Stop(); 99 100 delete nat; 101 delete natsf; 102 delete in; 103 for (int i = 0; i < 4; i++) 104 delete out[i]; 105 } 106 107 // Tests that when sending from external_addrs to internal_addr, the packet 108 // is delivered according to the specified filter_ip and filter_port rules. 109 void TestRecv( 110 SocketServer* internal, const SocketAddress& internal_addr, 111 SocketServer* external, const SocketAddress external_addrs[4], 112 NATType nat_type, bool filter_ip, bool filter_port) { 113 Thread th_int(internal); 114 Thread th_ext(external); 115 116 SocketAddress server_addr = internal_addr; 117 server_addr.SetPort(0); // Auto-select a port 118 NATServer* nat = new NATServer( 119 nat_type, internal, server_addr, external, external_addrs[0]); 120 NATSocketFactory* natsf = new NATSocketFactory(internal, 121 nat->internal_address()); 122 123 TestClient* in = CreateTestClient(natsf, internal_addr); 124 TestClient* out[4]; 125 for (int i = 0; i < 4; i++) 126 out[i] = CreateTestClient(external, external_addrs[i]); 127 128 th_int.Start(); 129 th_ext.Start(); 130 131 const char* buf = "filter_test"; 132 size_t len = strlen(buf); 133 134 in->SendTo(buf, len, out[0]->address()); 135 SocketAddress trans_addr; 136 EXPECT_TRUE(out[0]->CheckNextPacket(buf, len, &trans_addr)); 137 138 out[1]->SendTo(buf, len, trans_addr); 139 EXPECT_TRUE(CheckReceive(in, !filter_ip, buf, len)); 140 141 out[2]->SendTo(buf, len, trans_addr); 142 EXPECT_TRUE(CheckReceive(in, !filter_port, buf, len)); 143 144 out[3]->SendTo(buf, len, trans_addr); 145 EXPECT_TRUE(CheckReceive(in, !filter_ip && !filter_port, buf, len)); 146 147 th_int.Stop(); 148 th_ext.Stop(); 149 150 delete nat; 151 delete natsf; 152 delete in; 153 for (int i = 0; i < 4; i++) 154 delete out[i]; 155 } 156 157 // Tests that NATServer allocates bindings properly. 158 void TestBindings( 159 SocketServer* internal, const SocketAddress& internal_addr, 160 SocketServer* external, const SocketAddress external_addrs[4]) { 161 TestSend(internal, internal_addr, external, external_addrs, 162 NAT_OPEN_CONE, true); 163 TestSend(internal, internal_addr, external, external_addrs, 164 NAT_ADDR_RESTRICTED, true); 165 TestSend(internal, internal_addr, external, external_addrs, 166 NAT_PORT_RESTRICTED, true); 167 TestSend(internal, internal_addr, external, external_addrs, 168 NAT_SYMMETRIC, false); 169 } 170 171 // Tests that NATServer filters packets properly. 172 void TestFilters( 173 SocketServer* internal, const SocketAddress& internal_addr, 174 SocketServer* external, const SocketAddress external_addrs[4]) { 175 TestRecv(internal, internal_addr, external, external_addrs, 176 NAT_OPEN_CONE, false, false); 177 TestRecv(internal, internal_addr, external, external_addrs, 178 NAT_ADDR_RESTRICTED, true, false); 179 TestRecv(internal, internal_addr, external, external_addrs, 180 NAT_PORT_RESTRICTED, true, true); 181 TestRecv(internal, internal_addr, external, external_addrs, 182 NAT_SYMMETRIC, true, true); 183 } 184 185 bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) { 186 // The physical NAT tests require connectivity to the selected ip from the 187 // internal address used for the NAT. Things like firewalls can break that, so 188 // check to see if it's worth even trying with this ip. 189 scoped_ptr<PhysicalSocketServer> pss(new PhysicalSocketServer()); 190 scoped_ptr<AsyncSocket> client(pss->CreateAsyncSocket(src.family(), 191 SOCK_DGRAM)); 192 scoped_ptr<AsyncSocket> server(pss->CreateAsyncSocket(src.family(), 193 SOCK_DGRAM)); 194 if (client->Bind(SocketAddress(src.ipaddr(), 0)) != 0 || 195 server->Bind(SocketAddress(dst, 0)) != 0) { 196 return false; 197 } 198 const char* buf = "hello other socket"; 199 size_t len = strlen(buf); 200 int sent = client->SendTo(buf, len, server->GetLocalAddress()); 201 SocketAddress addr; 202 const size_t kRecvBufSize = 64; 203 char recvbuf[kRecvBufSize]; 204 Thread::Current()->SleepMs(100); 205 int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr); 206 return received == sent && ::memcmp(buf, recvbuf, len) == 0; 207 } 208 209 void TestPhysicalInternal(const SocketAddress& int_addr) { 210 BasicNetworkManager network_manager; 211 network_manager.set_ipv6_enabled(true); 212 network_manager.StartUpdating(); 213 // Process pending messages so the network list is updated. 214 Thread::Current()->ProcessMessages(0); 215 216 std::vector<Network*> networks; 217 network_manager.GetNetworks(&networks); 218 if (networks.empty()) { 219 LOG(LS_WARNING) << "Not enough network adapters for test."; 220 return; 221 } 222 223 SocketAddress ext_addr1(int_addr); 224 SocketAddress ext_addr2; 225 // Find an available IP with matching family. The test breaks if int_addr 226 // can't talk to ip, so check for connectivity as well. 227 for (std::vector<Network*>::iterator it = networks.begin(); 228 it != networks.end(); ++it) { 229 const IPAddress& ip = (*it)->ip(); 230 if (ip.family() == int_addr.family() && TestConnectivity(int_addr, ip)) { 231 ext_addr2.SetIP(ip); 232 break; 233 } 234 } 235 if (ext_addr2.IsNil()) { 236 LOG(LS_WARNING) << "No available IP of same family as " << int_addr; 237 return; 238 } 239 240 LOG(LS_INFO) << "selected ip " << ext_addr2.ipaddr(); 241 242 SocketAddress ext_addrs[4] = { 243 SocketAddress(ext_addr1), 244 SocketAddress(ext_addr2), 245 SocketAddress(ext_addr1), 246 SocketAddress(ext_addr2) 247 }; 248 249 scoped_ptr<PhysicalSocketServer> int_pss(new PhysicalSocketServer()); 250 scoped_ptr<PhysicalSocketServer> ext_pss(new PhysicalSocketServer()); 251 252 TestBindings(int_pss.get(), int_addr, ext_pss.get(), ext_addrs); 253 TestFilters(int_pss.get(), int_addr, ext_pss.get(), ext_addrs); 254 } 255 256 TEST(NatTest, TestPhysicalIPv4) { 257 TestPhysicalInternal(SocketAddress("127.0.0.1", 0)); 258 } 259 260 TEST(NatTest, TestPhysicalIPv6) { 261 if (HasIPv6Enabled()) { 262 TestPhysicalInternal(SocketAddress("::1", 0)); 263 } else { 264 LOG(LS_WARNING) << "No IPv6, skipping"; 265 } 266 } 267 268 class TestVirtualSocketServer : public VirtualSocketServer { 269 public: 270 explicit TestVirtualSocketServer(SocketServer* ss) 271 : VirtualSocketServer(ss), 272 ss_(ss) {} 273 // Expose this publicly 274 IPAddress GetNextIP(int af) { return VirtualSocketServer::GetNextIP(af); } 275 276 private: 277 scoped_ptr<SocketServer> ss_; 278 }; 279 280 void TestVirtualInternal(int family) { 281 scoped_ptr<TestVirtualSocketServer> int_vss(new TestVirtualSocketServer( 282 new PhysicalSocketServer())); 283 scoped_ptr<TestVirtualSocketServer> ext_vss(new TestVirtualSocketServer( 284 new PhysicalSocketServer())); 285 286 SocketAddress int_addr; 287 SocketAddress ext_addrs[4]; 288 int_addr.SetIP(int_vss->GetNextIP(family)); 289 ext_addrs[0].SetIP(ext_vss->GetNextIP(int_addr.family())); 290 ext_addrs[1].SetIP(ext_vss->GetNextIP(int_addr.family())); 291 ext_addrs[2].SetIP(ext_addrs[0].ipaddr()); 292 ext_addrs[3].SetIP(ext_addrs[1].ipaddr()); 293 294 TestBindings(int_vss.get(), int_addr, ext_vss.get(), ext_addrs); 295 TestFilters(int_vss.get(), int_addr, ext_vss.get(), ext_addrs); 296 } 297 298 TEST(NatTest, TestVirtualIPv4) { 299 TestVirtualInternal(AF_INET); 300 } 301 302 TEST(NatTest, TestVirtualIPv6) { 303 if (HasIPv6Enabled()) { 304 TestVirtualInternal(AF_INET6); 305 } else { 306 LOG(LS_WARNING) << "No IPv6, skipping"; 307 } 308 } 309 310 // TODO: Finish this test 311 class NatTcpTest : public testing::Test, public sigslot::has_slots<> { 312 public: 313 NatTcpTest() : connected_(false) {} 314 virtual void SetUp() { 315 int_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer()); 316 ext_vss_ = new TestVirtualSocketServer(new PhysicalSocketServer()); 317 nat_ = new NATServer(NAT_OPEN_CONE, int_vss_, SocketAddress(), 318 ext_vss_, SocketAddress()); 319 natsf_ = new NATSocketFactory(int_vss_, nat_->internal_address()); 320 } 321 void OnConnectEvent(AsyncSocket* socket) { 322 connected_ = true; 323 } 324 void OnAcceptEvent(AsyncSocket* socket) { 325 accepted_ = server_->Accept(NULL); 326 } 327 void OnCloseEvent(AsyncSocket* socket, int error) { 328 } 329 void ConnectEvents() { 330 server_->SignalReadEvent.connect(this, &NatTcpTest::OnAcceptEvent); 331 client_->SignalConnectEvent.connect(this, &NatTcpTest::OnConnectEvent); 332 } 333 TestVirtualSocketServer* int_vss_; 334 TestVirtualSocketServer* ext_vss_; 335 NATServer* nat_; 336 NATSocketFactory* natsf_; 337 AsyncSocket* client_; 338 AsyncSocket* server_; 339 AsyncSocket* accepted_; 340 bool connected_; 341 }; 342 343 TEST_F(NatTcpTest, DISABLED_TestConnectOut) { 344 server_ = ext_vss_->CreateAsyncSocket(SOCK_STREAM); 345 server_->Bind(SocketAddress()); 346 server_->Listen(5); 347 348 client_ = int_vss_->CreateAsyncSocket(SOCK_STREAM); 349 EXPECT_GE(0, client_->Bind(SocketAddress())); 350 EXPECT_GE(0, client_->Connect(server_->GetLocalAddress())); 351 352 353 ConnectEvents(); 354 355 EXPECT_TRUE_WAIT(connected_, 1000); 356 EXPECT_EQ(client_->GetRemoteAddress(), server_->GetLocalAddress()); 357 EXPECT_EQ(client_->GetRemoteAddress(), accepted_->GetLocalAddress()); 358 EXPECT_EQ(client_->GetLocalAddress(), accepted_->GetRemoteAddress()); 359 360 client_->Close(); 361 } 362 //#endif 363