15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Copyright 2011 Google Inc. All Rights Reserved.
25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <string>
55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/asynchttprequest.h"
75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/gunit.h"
85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/fakenetwork.h"
95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/scoped_ptr.h"
105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/socketaddress.h"
115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/basicpacketsocketfactory.h"
125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/relayport.h"
135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/stunport.h"
145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/client/connectivitychecker.h"
155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/client/httpportallocator.h"
165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace cricket {
185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const talk_base::SocketAddress kClientAddr1("11.11.11.11", 0);
205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const talk_base::SocketAddress kClientAddr2("22.22.22.22", 0);
215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const talk_base::SocketAddress kExternalAddr("33.33.33.33", 3333);
225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const talk_base::SocketAddress kStunAddr("44.44.44.44", 4444);
235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const talk_base::SocketAddress kRelayAddr("55.55.55.55", 5555);
245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const talk_base::SocketAddress kProxyAddr("66.66.66.66", 6666);
255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const talk_base::ProxyType kProxyType = talk_base::PROXY_HTTPS;
265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kChannelName[] = "rtp_test";
275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kComponent = 1;
285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kRelayHost[] = "relay.google.com";
295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kRelayToken[] =
305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "CAESFwoOb2phQGdvb2dsZS5jb20Q043h47MmGhBTB1rbfIXkhuarDCZe+xF6";
315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kBrowserAgent[] = "browser_test";
325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kJid[] = "a.b@c";
335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kUserName[] = "testuser";
345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kPassword[] = "testpassword";
355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kMagicCookie[] = "testcookie";
365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kRelayUdpPort[] = "4444";
375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kRelayTcpPort[] = "5555";
385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kRelaySsltcpPort[] = "6666";
395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kSessionId[] = "testsession";
405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const char kConnection[] = "testconnection";
415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kMinPort = 1000;
425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kMaxPort = 2000;
435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Fake implementation to mock away real network usage.
455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass FakeRelayPort : public RelayPort {
465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  FakeRelayPort(talk_base::Thread* thread,
485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                talk_base::PacketSocketFactory* factory,
495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                talk_base::Network* network, const talk_base::IPAddress& ip,
505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                int min_port, int max_port,
515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                const std::string& username, const std::string& password)
525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : RelayPort(thread, factory, network, ip, min_port, max_port,
535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                  username, password) {
545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Just signal that we are done.
575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void PrepareAddress() {
585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalPortComplete(this);
595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Fake implementation to mock away real network usage.
635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass FakeStunPort : public StunPort {
645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  FakeStunPort(talk_base::Thread* thread,
665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               talk_base::PacketSocketFactory* factory,
675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               talk_base::Network* network,
685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               const talk_base::IPAddress& ip,
695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               int min_port, int max_port,
705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               const std::string& username, const std::string& password,
715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               const talk_base::SocketAddress& server_addr)
725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : StunPort(thread, factory, network, ip, min_port, max_port,
735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 username, password, server_addr) {
745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Just set external address and signal that we are done.
775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void PrepareAddress() {
785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    AddAddress(kExternalAddr, kExternalAddr, "udp",
795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               STUN_PORT_TYPE, ICE_TYPE_PREFERENCE_SRFLX, true);
805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalPortComplete(this);
815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Fake implementation to mock away real network usage by responding
855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// to http requests immediately.
865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass FakeHttpPortAllocatorSession : public TestHttpPortAllocatorSession {
875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  FakeHttpPortAllocatorSession(
895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      HttpPortAllocator* allocator,
905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& content_name,
915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      int component,
925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& ice_ufrag, const std::string& ice_pwd,
935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::vector<talk_base::SocketAddress>& stun_hosts,
945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::vector<std::string>& relay_hosts,
955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& relay_token,
965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& agent)
975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : TestHttpPortAllocatorSession(allocator,
985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     content_name,
995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     component,
1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     ice_ufrag,
1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     ice_pwd,
1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     stun_hosts,
1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     relay_hosts,
1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     relay_token,
1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     agent) {
1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SendSessionRequest(const std::string& host, int port) {
1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    FakeReceiveSessionResponse(host, port);
1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Pass results to the real implementation.
1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void FakeReceiveSessionResponse(const std::string& host, int port) {
1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::AsyncHttpRequest* response = CreateAsyncHttpResponse(port);
1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    TestHttpPortAllocatorSession::OnRequestDone(response);
1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    response->Destroy(true);
1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private:
1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Helper method for creating a response to a relay session request.
1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::AsyncHttpRequest* CreateAsyncHttpResponse(int port) {
1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::AsyncHttpRequest* request =
1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new talk_base::AsyncHttpRequest(kBrowserAgent);
1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::stringstream ss;
1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ss << "username=" << kUserName << std::endl
1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       << "password=" << kPassword << std::endl
1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       << "magic_cookie=" << kMagicCookie << std::endl
1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       << "relay.ip=" << kRelayAddr.ipaddr().ToString() << std::endl
1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       << "relay.udp_port=" << kRelayUdpPort << std::endl
1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       << "relay.tcp_port=" << kRelayTcpPort << std::endl
1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       << "relay.ssltcp_port=" << kRelaySsltcpPort << std::endl;
1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    request->response().document.reset(
1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new talk_base::MemoryStream(ss.str().c_str()));
1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    request->response().set_success();
1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    request->set_port(port);
1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    request->set_secure(port == talk_base::HTTP_SECURE_PORT);
1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return request;
1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Fake implementation for creating fake http sessions.
1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass FakeHttpPortAllocator : public HttpPortAllocator {
1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  FakeHttpPortAllocator(talk_base::NetworkManager* network_manager,
1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& user_agent)
1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : HttpPortAllocator(network_manager, user_agent) {
1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual PortAllocatorSession* CreateSessionInternal(
1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& content_name, int component,
1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& ice_ufrag, const std::string& ice_pwd) {
1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::vector<talk_base::SocketAddress> stun_hosts;
1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    stun_hosts.push_back(kStunAddr);
1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::vector<std::string> relay_hosts;
1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    relay_hosts.push_back(kRelayHost);
1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return new FakeHttpPortAllocatorSession(this,
1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            content_name,
1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            component,
1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            ice_ufrag,
1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            ice_pwd,
1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            stun_hosts,
1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            relay_hosts,
1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            kRelayToken,
1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                            kBrowserAgent);
1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass ConnectivityCheckerForTest : public ConnectivityChecker {
1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ConnectivityCheckerForTest(talk_base::Thread* worker,
1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& jid,
1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& session_id,
1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& user_agent,
1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& relay_token,
1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& connection)
1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : ConnectivityChecker(worker,
1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            jid,
1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            session_id,
1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            user_agent,
1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            relay_token,
1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            connection),
1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        proxy_initiated_(false) {
1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::FakeNetworkManager* network_manager() const {
1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return network_manager_;
1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  FakeHttpPortAllocator* port_allocator() const {
1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return fake_port_allocator_;
1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Overridden methods for faking a real network.
1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual talk_base::NetworkManager* CreateNetworkManager() {
1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    network_manager_ = new talk_base::FakeNetworkManager();
1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return network_manager_;
1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual talk_base::BasicPacketSocketFactory* CreateSocketFactory(
1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      talk_base::Thread* thread) {
2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Create socket factory, for simplicity, let it run on the current thread.
2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    socket_factory_ =
2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new talk_base::BasicPacketSocketFactory(talk_base::Thread::Current());
2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return socket_factory_;
2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual HttpPortAllocator* CreatePortAllocator(
2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      talk_base::NetworkManager* network_manager,
2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& user_agent,
2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& relay_token) {
2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    fake_port_allocator_ =
2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new FakeHttpPortAllocator(network_manager, user_agent);
2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return fake_port_allocator_;
2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual StunPort* CreateStunPort(
2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& username, const std::string& password,
2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const PortConfiguration* config, talk_base::Network* network) {
2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return new FakeStunPort(worker(), socket_factory_,
2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            network, network->ip(),
2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            kMinPort, kMaxPort,
2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            username, password,
2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            config->stun_address);
2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual RelayPort* CreateRelayPort(
2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const std::string& username, const std::string& password,
2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const PortConfiguration* config, talk_base::Network* network) {
2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return new FakeRelayPort(worker(), socket_factory_,
2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             network, network->ip(),
2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             kMinPort, kMaxPort,
2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             username, password);
2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void InitiateProxyDetection() {
2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!proxy_initiated_) {
2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      proxy_initiated_ = true;
2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      proxy_info_.address = kProxyAddr;
2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      proxy_info_.type = kProxyType;
2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      SetProxyInfo(proxy_info_);
2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual talk_base::ProxyInfo GetProxyInfo() const {
2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return proxy_info_;
2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private:
2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::BasicPacketSocketFactory* socket_factory_;
2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  FakeHttpPortAllocator* fake_port_allocator_;
2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::FakeNetworkManager* network_manager_;
2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::ProxyInfo proxy_info_;
2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool proxy_initiated_;
2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass ConnectivityCheckerTest : public testing::Test {
2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void VerifyNic(const NicInfo& info,
2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const talk_base::SocketAddress& local_address) {
2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Verify that the external address has been set.
2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kExternalAddr, info.external_address);
2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Verify that the stun server address has been set.
2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kStunAddr, info.stun_server_address);
2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Verify that the media server address has been set. Don't care
2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // about port since it is different for different protocols.
2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kRelayAddr.ipaddr(), info.media_server_address.ipaddr());
2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Verify that local ip matches.
2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(local_address.ipaddr(), info.ip);
2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Verify that we have received responses for our
2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // pings. Unsuccessful ping has rtt value -1, successful >= 0.
2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_GE(info.stun.rtt, 0);
2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_GE(info.udp.rtt, 0);
2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_GE(info.tcp.rtt, 0);
2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_GE(info.ssltcp.rtt, 0);
2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // If proxy has been set, verify address and type.
2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!info.proxy_info.address.IsNil()) {
2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(kProxyAddr, info.proxy_info.address);
2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(kProxyType, info.proxy_info.type);
2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Tests a configuration with two network interfaces. Verifies that 4
2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// combinations of ip/proxy are created and that all protocols are
2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// tested on each combination.
2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(ConnectivityCheckerTest, TestStart) {
2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ConnectivityCheckerForTest connectivity_checker(talk_base::Thread::Current(),
2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kJid,
2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kSessionId,
2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kBrowserAgent,
2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kRelayToken,
2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kConnection);
2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  connectivity_checker.Initialize();
2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  connectivity_checker.set_stun_address(kStunAddr);
2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  connectivity_checker.network_manager()->AddInterface(kClientAddr1);
2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  connectivity_checker.network_manager()->AddInterface(kClientAddr2);
2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  connectivity_checker.Start();
2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::Thread::Current()->ProcessMessages(1000);
3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  NicMap nics = connectivity_checker.GetResults();
3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // There should be 4 nics in our map. 2 for each interface added,
3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // one with proxy set and one without.
3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(4U, nics.size());
3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // First verify interfaces without proxy.
3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::SocketAddress nilAddress;
3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // First lookup the address of the first nic combined with no proxy.
3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  NicMap::iterator i = nics.find(NicId(kClientAddr1.ipaddr(), nilAddress));
3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ASSERT(i != nics.end());
3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  NicInfo info = i->second;
3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VerifyNic(info, kClientAddr1);
3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Then make sure the second device has been tested without proxy.
3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  i = nics.find(NicId(kClientAddr2.ipaddr(), nilAddress));
3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ASSERT(i != nics.end());
3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  info = i->second;
3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VerifyNic(info, kClientAddr2);
3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Now verify both interfaces with proxy.
3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  i = nics.find(NicId(kClientAddr1.ipaddr(), kProxyAddr));
3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ASSERT(i != nics.end());
3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  info = i->second;
3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VerifyNic(info, kClientAddr1);
3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  i = nics.find(NicId(kClientAddr2.ipaddr(), kProxyAddr));
3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ASSERT(i != nics.end());
3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  info = i->second;
3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VerifyNic(info, kClientAddr2);
3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Tests that nothing bad happens if thera are no network interfaces
3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// available to check.
3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(ConnectivityCheckerTest, TestStartNoNetwork) {
3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ConnectivityCheckerForTest connectivity_checker(talk_base::Thread::Current(),
3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kJid,
3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kSessionId,
3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kBrowserAgent,
3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kRelayToken,
3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                  kConnection);
3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  connectivity_checker.Initialize();
3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  connectivity_checker.Start();
3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::Thread::Current()->ProcessMessages(1000);
3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  NicMap nics = connectivity_checker.GetResults();
3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Verify that no nics where checked.
3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(0U, nics.size());
3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}  // namespace cricket
354