diff options
author | mallinath@chromium.org <mallinath@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-21 21:07:55 +0000 |
---|---|---|
committer | mallinath@chromium.org <mallinath@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-21 21:07:55 +0000 |
commit | f25eb36e3344223ffcabcf96d54cf000862d6088 (patch) | |
tree | 5b3517da2e3cf47cf72c307334c0b14daa150e61 /content | |
parent | f6dfbfd60af638964d15dc5b752cecd3504dc2d1 (diff) | |
download | chromium_src-f25eb36e3344223ffcabcf96d54cf000862d6088.zip chromium_src-f25eb36e3344223ffcabcf96d54cf000862d6088.tar.gz chromium_src-f25eb36e3344223ffcabcf96d54cf000862d6088.tar.bz2 |
Proxy detection is important feature for the P2P sockets, as
it provides additional security for enterprise use cases.
Communication between webrtc endpoints happens through UDP/TCP/STUN
with or without the help of TURN server.
In case of firewall restrictions like outgoing UDP block and allowing
only secure ports, direct communication between two endbecomes impossible
without the help of TURN.
In the presence of proxies, direct communication even to TURN server also
becomes impossible without first esablishing connection with the proxy.
This CL is trying to address the last problem.
If proxies are configured(HTTP/S/SOCKS) send data(stun+media) through it.
jingle_glue::ProxyResolvingClientSocket solves the problem of proxy detection and establishing the connection and also it's a type of net::StreamSocket, this class can be directly used in P2PSocketHostTcpBase.
R=sergeyu@chromium.org,juberti@chromium.org,thakis@chromium.org
Review URL: https://chromiumcodereview.appspot.com/17132012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207919 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
9 files changed, 115 insertions, 91 deletions
diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc index 25fbea5..253475c 100644 --- a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc +++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc @@ -15,6 +15,7 @@ #include "net/base/net_log.h" #include "net/base/sys_addrinfo.h" #include "net/dns/single_request_host_resolver.h" +#include "net/url_request/url_request_context_getter.h" using content::BrowserMessageFilter; using content::BrowserThread; @@ -83,8 +84,10 @@ class P2PSocketDispatcherHost::DnsRequest { }; P2PSocketDispatcherHost::P2PSocketDispatcherHost( - content::ResourceContext* resource_context) + content::ResourceContext* resource_context, + net::URLRequestContextGetter* url_context) : resource_context_(resource_context), + url_context_(url_context), monitoring_networks_(false) { } @@ -188,7 +191,7 @@ void P2PSocketDispatcherHost::OnCreateSocket( } scoped_ptr<P2PSocketHost> socket( - P2PSocketHost::Create(this, socket_id, type)); + P2PSocketHost::Create(this, socket_id, type, url_context_)); if (!socket) { Send(new P2PMsg_OnError(socket_id)); diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.h b/content/browser/renderer_host/p2p/socket_dispatcher_host.h index 6f7f4e5..8a31ae5 100644 --- a/content/browser/renderer_host/p2p/socket_dispatcher_host.h +++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.h @@ -13,6 +13,10 @@ #include "net/base/ip_endpoint.h" #include "net/base/network_change_notifier.h" +namespace net { +class URLRequestContextGetter; +} + namespace content { class P2PSocketHost; @@ -22,7 +26,8 @@ class P2PSocketDispatcherHost : public content::BrowserMessageFilter, public net::NetworkChangeNotifier::IPAddressObserver { public: - P2PSocketDispatcherHost(content::ResourceContext* resource_context); + P2PSocketDispatcherHost(content::ResourceContext* resource_context, + net::URLRequestContextGetter* url_context); // content::BrowserMessageFilter overrides. virtual void OnChannelClosing() OVERRIDE; @@ -72,6 +77,7 @@ class P2PSocketDispatcherHost const net::IPAddressNumber& result); content::ResourceContext* resource_context_; + scoped_refptr<net::URLRequestContextGetter> url_context_; SocketsMap sockets_; diff --git a/content/browser/renderer_host/p2p/socket_host.cc b/content/browser/renderer_host/p2p/socket_host.cc index 1eb4f0e..062405f 100644 --- a/content/browser/renderer_host/p2p/socket_host.cc +++ b/content/browser/renderer_host/p2p/socket_host.cc @@ -72,7 +72,8 @@ bool P2PSocketHost::IsRequestOrResponse(StunMessageType type) { // static P2PSocketHost* P2PSocketHost::Create( - IPC::Sender* message_sender, int id, P2PSocketType type) { + IPC::Sender* message_sender, int id, P2PSocketType type, + net::URLRequestContextGetter* url_context) { switch (type) { case P2P_SOCKET_UDP: return new P2PSocketHostUdp(message_sender, id); @@ -86,16 +87,12 @@ P2PSocketHost* P2PSocketHost::Create( message_sender, id, P2P_SOCKET_STUN_TCP_CLIENT); case P2P_SOCKET_TCP_CLIENT: - return new P2PSocketHostTcp(message_sender, id, type); - - case P2P_SOCKET_STUN_TCP_CLIENT: - return new P2PSocketHostStunTcp(message_sender, id, type); - case P2P_SOCKET_SSLTCP_CLIENT: - return new P2PSocketHostTcp(message_sender, id, type); + return new P2PSocketHostTcp(message_sender, id, type, url_context); + case P2P_SOCKET_STUN_TCP_CLIENT: case P2P_SOCKET_STUN_SSLTCP_CLIENT: - return new P2PSocketHostStunTcp(message_sender, id, type); + return new P2PSocketHostStunTcp(message_sender, id, type, url_context); } NOTREACHED(); diff --git a/content/browser/renderer_host/p2p/socket_host.h b/content/browser/renderer_host/p2p/socket_host.h index 9c8911a..bd5d7c0 100644 --- a/content/browser/renderer_host/p2p/socket_host.h +++ b/content/browser/renderer_host/p2p/socket_host.h @@ -14,6 +14,10 @@ namespace IPC { class Sender; } +namespace net { +class URLRequestContextGetter; +} + namespace content { // Base class for P2P sockets. @@ -22,7 +26,8 @@ class CONTENT_EXPORT P2PSocketHost { static const int kStunHeaderSize = 20; // Creates P2PSocketHost of the specific type. static P2PSocketHost* Create(IPC::Sender* message_sender, - int id, P2PSocketType type); + int id, P2PSocketType type, + net::URLRequestContextGetter* url_context); virtual ~P2PSocketHost(); @@ -38,8 +43,7 @@ class CONTENT_EXPORT P2PSocketHost { const net::IPEndPoint& remote_address, int id) = 0; protected: - friend class P2PSocketHostTcpTest; - friend class P2PSocketHostStunTcpTest; + friend class P2PSocketHostTcpTestBase; enum StunMessageType { STUN_BINDING_REQUEST = 0x0001, diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.cc b/content/browser/renderer_host/p2p/socket_host_tcp.cc index 383ce0a..ec85da0 100644 --- a/content/browser/renderer_host/p2p/socket_host_tcp.cc +++ b/content/browser/renderer_host/p2p/socket_host_tcp.cc @@ -8,10 +8,12 @@ #include "content/common/p2p_messages.h" #include "ipc/ipc_sender.h" #include "jingle/glue/fake_ssl_client_socket.h" +#include "jingle/glue/proxy_resolving_client_socket.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/socket/tcp_client_socket.h" +#include "net/url_request/url_request_context_getter.h" namespace { @@ -30,13 +32,14 @@ bool IsSslClientSocket(content::P2PSocketType type) { namespace content { -P2PSocketHostTcpBase::P2PSocketHostTcpBase(IPC::Sender* message_sender, - int id, - P2PSocketType type) +P2PSocketHostTcpBase::P2PSocketHostTcpBase( + IPC::Sender* message_sender, int id, + P2PSocketType type, net::URLRequestContextGetter* url_context) : P2PSocketHost(message_sender, id), write_pending_(false), connected_(false), - type_(type) { + type_(type), + url_context_(url_context) { } P2PSocketHostTcpBase::~P2PSocketHostTcpBase() { @@ -60,28 +63,43 @@ bool P2PSocketHostTcpBase::InitAccepted(const net::IPEndPoint& remote_address, } bool P2PSocketHostTcpBase::Init(const net::IPEndPoint& local_address, - const net::IPEndPoint& remote_address) { + const net::IPEndPoint& remote_address) { DCHECK_EQ(state_, STATE_UNINITIALIZED); remote_address_ = remote_address; state_ = STATE_CONNECTING; - scoped_ptr<net::TCPClientSocket> tcp_socket(new net::TCPClientSocket( - net::AddressList(remote_address), - NULL, net::NetLog::Source())); - if (tcp_socket->Bind(local_address) != net::OK) { - OnError(); - return false; - } + + net::HostPortPair dest_host_port_pair = + net::HostPortPair::FromIPEndPoint(remote_address); + // TODO(mallinath) - We are ignoring local_address altogether. We should + // find a way to inject this into ProxyResolvingClientSocket. This could be + // a problem on multi-homed host. + + // The default SSLConfig is good enough for us for now. + const net::SSLConfig ssl_config; + socket_.reset(new jingle_glue::ProxyResolvingClientSocket( + NULL, // Default socket pool provided by the net::Proxy. + url_context_, + ssl_config, + dest_host_port_pair)); if (IsSslClientSocket(type_)) { - socket_.reset(new jingle_glue::FakeSSLClientSocket(tcp_socket.release())); - } else { - socket_ = tcp_socket.PassAs<net::StreamSocket>(); + socket_.reset(new jingle_glue::FakeSSLClientSocket(socket_.release())); } - int result = socket_->Connect( - base::Bind(&P2PSocketHostTcp::OnConnected, base::Unretained(this))); - if (result != net::ERR_IO_PENDING) { - OnConnected(result); + int status = socket_->Connect( + base::Bind(&P2PSocketHostTcpBase::OnConnected, + base::Unretained(this))); + if (status != net::ERR_IO_PENDING) { + // We defer execution of ProcessConnectDone instead of calling it + // directly here as the caller may not expect an error/close to + // happen here. This is okay, as from the caller's point of view, + // the connect always happens asynchronously. + base::MessageLoop* message_loop = base::MessageLoop::current(); + CHECK(message_loop); + message_loop->PostTask( + FROM_HERE, + base::Bind(&P2PSocketHostTcpBase::OnConnected, + base::Unretained(this), status)); } return state_ != STATE_ERROR; @@ -285,10 +303,10 @@ void P2PSocketHostTcpBase::DidCompleteRead(int result) { } } -P2PSocketHostTcp::P2PSocketHostTcp(IPC::Sender* message_sender, - int id, - P2PSocketType type) - : P2PSocketHostTcpBase(message_sender, id, type) { +P2PSocketHostTcp::P2PSocketHostTcp( + IPC::Sender* message_sender, int id, + P2PSocketType type, net::URLRequestContextGetter* url_context) + : P2PSocketHostTcpBase(message_sender, id, type, url_context) { DCHECK(type == P2P_SOCKET_TCP_CLIENT || type == P2P_SOCKET_SSLTCP_CLIENT); } @@ -322,10 +340,10 @@ void P2PSocketHostTcp::DoSend(const net::IPEndPoint& to, } // P2PSocketHostStunTcp -P2PSocketHostStunTcp::P2PSocketHostStunTcp(IPC::Sender* message_sender, - int id, - P2PSocketType type) - : P2PSocketHostTcpBase(message_sender, id, type) { +P2PSocketHostStunTcp::P2PSocketHostStunTcp( + IPC::Sender* message_sender, int id, + P2PSocketType type, net::URLRequestContextGetter* url_context) + : P2PSocketHostTcpBase(message_sender, id, type, url_context) { DCHECK(type == P2P_SOCKET_STUN_TCP_CLIENT || type == P2P_SOCKET_STUN_SSLTCP_CLIENT); } diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.h b/content/browser/renderer_host/p2p/socket_host_tcp.h index 2e73169..1a605f4 100644 --- a/content/browser/renderer_host/p2p/socket_host_tcp.h +++ b/content/browser/renderer_host/p2p/socket_host_tcp.h @@ -21,13 +21,17 @@ namespace net { class DrainableIOBuffer; class GrowableIOBuffer; class StreamSocket; +class URLRequestContextGetter; } // namespace net namespace content { class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost { public: - P2PSocketHostTcpBase(IPC::Sender* message_sender, int id, P2PSocketType type); + P2PSocketHostTcpBase(IPC::Sender* message_sender, + int id, + P2PSocketType type, + net::URLRequestContextGetter* url_context); virtual ~P2PSocketHostTcpBase(); bool InitAccepted(const net::IPEndPoint& remote_address, @@ -52,9 +56,8 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost { void OnError(); private: - friend class P2PSocketHostTcpTest; + friend class P2PSocketHostTcpTestBase; friend class P2PSocketHostTcpServerTest; - friend class P2PSocketHostStunTcpTest; void DidCompleteRead(int result); void DoRead(); @@ -77,15 +80,18 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost { bool write_pending_; bool connected_; - P2PSocketType type_; + scoped_refptr<net::URLRequestContextGetter> url_context_; DISALLOW_COPY_AND_ASSIGN(P2PSocketHostTcpBase); }; class CONTENT_EXPORT P2PSocketHostTcp : public P2PSocketHostTcpBase { public: - P2PSocketHostTcp(IPC::Sender* message_sender, int id, P2PSocketType type); + P2PSocketHostTcp(IPC::Sender* message_sender, + int id, + P2PSocketType type, + net::URLRequestContextGetter* url_context); virtual ~P2PSocketHostTcp(); protected: @@ -102,7 +108,11 @@ class CONTENT_EXPORT P2PSocketHostTcp : public P2PSocketHostTcpBase { // Formatting of messages is defined in RFC5766. class CONTENT_EXPORT P2PSocketHostStunTcp : public P2PSocketHostTcpBase { public: - P2PSocketHostStunTcp(IPC::Sender* message_sender, int id, P2PSocketType type); + P2PSocketHostStunTcp(IPC::Sender* message_sender, + int id, + P2PSocketType type, + net::URLRequestContextGetter* url_context); + virtual ~P2PSocketHostStunTcp(); protected: diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_server.cc b/content/browser/renderer_host/p2p/socket_host_tcp_server.cc index b29eb1b..146e5c8 100644 --- a/content/browser/renderer_host/p2p/socket_host_tcp_server.cc +++ b/content/browser/renderer_host/p2p/socket_host_tcp_server.cc @@ -131,9 +131,10 @@ P2PSocketHost* P2PSocketHostTcpServer::AcceptIncomingTcpConnection( scoped_ptr<P2PSocketHostTcpBase> result; if (client_type_ == P2P_SOCKET_TCP_CLIENT) { - result.reset(new P2PSocketHostTcp(message_sender_, id, client_type_)); + result.reset(new P2PSocketHostTcp(message_sender_, id, client_type_, NULL)); } else { - result.reset(new P2PSocketHostStunTcp(message_sender_, id, client_type_)); + result.reset(new P2PSocketHostStunTcp( + message_sender_, id, client_type_, NULL)); } if (!result->InitAccepted(remote_address, socket)) return NULL; diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc index 6ac41f0..340c6b5 100644 --- a/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc +++ b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc @@ -19,15 +19,25 @@ using ::testing::Return; namespace content { -class P2PSocketHostTcpTest : public testing::Test { +class P2PSocketHostTcpTestBase : public testing::Test { protected: + explicit P2PSocketHostTcpTestBase(P2PSocketType type) + : socket_type_(type) { + } + virtual void SetUp() OVERRIDE { EXPECT_CALL(sender_, Send( MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID)))) .WillOnce(DoAll(DeleteArg<0>(), Return(true))); - socket_host_.reset(new P2PSocketHostTcp(&sender_, 0, - P2P_SOCKET_TCP_CLIENT)); + if (socket_type_ == P2P_SOCKET_TCP_CLIENT) { + socket_host_.reset(new P2PSocketHostTcp( + &sender_, 0, P2P_SOCKET_TCP_CLIENT, NULL)); + } else { + socket_host_.reset(new P2PSocketHostStunTcp( + &sender_, 0, P2P_SOCKET_STUN_TCP_CLIENT, NULL)); + } + socket_ = new FakeSocket(&sent_data_); socket_->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1)); socket_host_->socket_.reset(socket_); @@ -50,55 +60,28 @@ class P2PSocketHostTcpTest : public testing::Test { } std::string sent_data_; - FakeSocket* socket_; // Owned by |socket_host_|. - scoped_ptr<P2PSocketHostTcp> socket_host_; + FakeSocket* socket_; // Owned by |socket_host_|. + scoped_ptr<P2PSocketHostTcpBase> socket_host_; MockIPCSender sender_; net::IPEndPoint local_address_; net::IPEndPoint dest_; net::IPEndPoint dest2_; + + P2PSocketType socket_type_; }; -class P2PSocketHostStunTcpTest : public testing::Test { +class P2PSocketHostTcpTest : public P2PSocketHostTcpTestBase { protected: - virtual void SetUp() OVERRIDE { - EXPECT_CALL(sender_, Send( - MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID)))) - .WillOnce(DoAll(DeleteArg<0>(), Return(true))); - - socket_host_.reset(new P2PSocketHostStunTcp(&sender_, 0, - P2P_SOCKET_STUN_TCP_CLIENT)); - socket_ = new FakeSocket(&sent_data_); - socket_->SetLocalAddress(ParseAddress(kTestLocalIpAddress, kTestPort1)); - socket_host_->socket_.reset(socket_); - - dest_ = ParseAddress(kTestIpAddress1, kTestPort1); - - local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1); - - socket_host_->remote_address_ = dest_; - socket_host_->state_ = P2PSocketHost::STATE_CONNECTING; - socket_host_->OnConnected(net::OK); - } + P2PSocketHostTcpTest() : P2PSocketHostTcpTestBase(P2P_SOCKET_TCP_CLIENT) { } +}; - std::string IntToSize(int size) { - std::string result; - uint16 size16 = base::HostToNet16(size); - result.resize(sizeof(size16)); - memcpy(&result[0], &size16, sizeof(size16)); - return result; +class P2PSocketHostStunTcpTest : public P2PSocketHostTcpTestBase { + protected: + P2PSocketHostStunTcpTest() + : P2PSocketHostTcpTestBase(P2P_SOCKET_STUN_TCP_CLIENT) { } - - std::string sent_data_; - FakeSocket* socket_; // Owned by |socket_host_|. - scoped_ptr<P2PSocketHostStunTcp> socket_host_; - MockIPCSender sender_; - - net::IPEndPoint local_address_; - - net::IPEndPoint dest_; - net::IPEndPoint dest2_; }; // Verify that we can send STUN message and that they are formatted diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 7773a25..65268c1 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -684,7 +684,9 @@ void RenderProcessHostImpl::CreateMessageFilters() { base::Unretained(widget_helper_.get())))); #if defined(ENABLE_WEBRTC) - channel_->AddFilter(new P2PSocketDispatcherHost(resource_context)); + channel_->AddFilter(new P2PSocketDispatcherHost( + resource_context, + browser_context->GetRequestContextForRenderProcess(GetID()))); #endif channel_->AddFilter(new TraceMessageFilter()); |