Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / renderer / p2p / ipc_socket_factory.cc
blob3055016b864fb541c4fbd86bf4abf4ed949813d3
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/p2p/ipc_socket_factory.h"
7 #include <algorithm>
8 #include <deque>
10 #include "base/compiler_specific.h"
11 #include "base/debug/trace_event.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/threading/non_thread_safe.h"
16 #include "content/renderer/media/webrtc_logging.h"
17 #include "content/renderer/p2p/host_address_request.h"
18 #include "content/renderer/p2p/socket_client_delegate.h"
19 #include "content/renderer/p2p/socket_client_impl.h"
20 #include "content/renderer/p2p/socket_dispatcher.h"
21 #include "jingle/glue/utils.h"
22 #include "third_party/webrtc/base/asyncpacketsocket.h"
24 namespace content {
26 namespace {
28 const int kDefaultNonSetOptionValue = -1;
30 bool IsTcpClientSocket(P2PSocketType type) {
31 return (type == P2P_SOCKET_STUN_TCP_CLIENT) ||
32 (type == P2P_SOCKET_TCP_CLIENT) ||
33 (type == P2P_SOCKET_STUN_SSLTCP_CLIENT) ||
34 (type == P2P_SOCKET_SSLTCP_CLIENT) ||
35 (type == P2P_SOCKET_TLS_CLIENT) ||
36 (type == P2P_SOCKET_STUN_TLS_CLIENT);
39 bool JingleSocketOptionToP2PSocketOption(rtc::Socket::Option option,
40 P2PSocketOption* ipc_option) {
41 switch (option) {
42 case rtc::Socket::OPT_RCVBUF:
43 *ipc_option = P2P_SOCKET_OPT_RCVBUF;
44 break;
45 case rtc::Socket::OPT_SNDBUF:
46 *ipc_option = P2P_SOCKET_OPT_SNDBUF;
47 break;
48 case rtc::Socket::OPT_DSCP:
49 *ipc_option = P2P_SOCKET_OPT_DSCP;
50 break;
51 case rtc::Socket::OPT_DONTFRAGMENT:
52 case rtc::Socket::OPT_NODELAY:
53 case rtc::Socket::OPT_IPV6_V6ONLY:
54 case rtc::Socket::OPT_RTP_SENDTIME_EXTN_ID:
55 return false; // Not supported by the chrome sockets.
56 default:
57 NOTREACHED();
58 return false;
60 return true;
63 // TODO(miu): This needs tuning. http://crbug.com/237960
64 const size_t kMaximumInFlightBytes = 64 * 1024; // 64 KB
66 // IpcPacketSocket implements rtc::AsyncPacketSocket interface
67 // using P2PSocketClient that works over IPC-channel. It must be used
68 // on the thread it was created.
69 class IpcPacketSocket : public rtc::AsyncPacketSocket,
70 public P2PSocketClientDelegate {
71 public:
72 IpcPacketSocket();
73 virtual ~IpcPacketSocket();
75 // Always takes ownership of client even if initialization fails.
76 bool Init(P2PSocketType type, P2PSocketClientImpl* client,
77 const rtc::SocketAddress& local_address,
78 const rtc::SocketAddress& remote_address);
80 // rtc::AsyncPacketSocket interface.
81 virtual rtc::SocketAddress GetLocalAddress() const OVERRIDE;
82 virtual rtc::SocketAddress GetRemoteAddress() const OVERRIDE;
83 virtual int Send(const void *pv, size_t cb,
84 const rtc::PacketOptions& options) OVERRIDE;
85 virtual int SendTo(const void *pv, size_t cb,
86 const rtc::SocketAddress& addr,
87 const rtc::PacketOptions& options) OVERRIDE;
88 virtual int Close() OVERRIDE;
89 virtual State GetState() const OVERRIDE;
90 virtual int GetOption(rtc::Socket::Option option, int* value) OVERRIDE;
91 virtual int SetOption(rtc::Socket::Option option, int value) OVERRIDE;
92 virtual int GetError() const OVERRIDE;
93 virtual void SetError(int error) OVERRIDE;
95 // P2PSocketClientDelegate implementation.
96 virtual void OnOpen(const net::IPEndPoint& local_address,
97 const net::IPEndPoint& remote_address) OVERRIDE;
98 virtual void OnIncomingTcpConnection(
99 const net::IPEndPoint& address,
100 P2PSocketClient* client) OVERRIDE;
101 virtual void OnSendComplete() OVERRIDE;
102 virtual void OnError() OVERRIDE;
103 virtual void OnDataReceived(const net::IPEndPoint& address,
104 const std::vector<char>& data,
105 const base::TimeTicks& timestamp) OVERRIDE;
107 private:
108 enum InternalState {
109 IS_UNINITIALIZED,
110 IS_OPENING,
111 IS_OPEN,
112 IS_CLOSED,
113 IS_ERROR,
116 // Update trace of send throttling internal state. This should be called
117 // immediately after any changes to |send_bytes_available_| and/or
118 // |in_flight_packet_sizes_|.
119 void TraceSendThrottlingState() const;
121 void InitAcceptedTcp(P2PSocketClient* client,
122 const rtc::SocketAddress& local_address,
123 const rtc::SocketAddress& remote_address);
125 int DoSetOption(P2PSocketOption option, int value);
127 P2PSocketType type_;
129 // Message loop on which this socket was created and being used.
130 base::MessageLoop* message_loop_;
132 // Corresponding P2P socket client.
133 scoped_refptr<P2PSocketClient> client_;
135 // Local address is allocated by the browser process, and the
136 // renderer side doesn't know the address until it receives OnOpen()
137 // event from the browser.
138 rtc::SocketAddress local_address_;
140 // Remote address for client TCP connections.
141 rtc::SocketAddress remote_address_;
143 // Current state of the object.
144 InternalState state_;
146 // Track the number of bytes allowed to be sent non-blocking. This is used to
147 // throttle the sending of packets to the browser process. For each packet
148 // sent, the value is decreased. As callbacks to OnSendComplete() (as IPCs
149 // from the browser process) are made, the value is increased back. This
150 // allows short bursts of high-rate sending without dropping packets, but
151 // quickly restricts the client to a sustainable steady-state rate.
152 size_t send_bytes_available_;
153 std::deque<size_t> in_flight_packet_sizes_;
155 // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the
156 // caller expects SignalWritable notification.
157 bool writable_signal_expected_;
159 // Current error code. Valid when state_ == IS_ERROR.
160 int error_;
161 int options_[P2P_SOCKET_OPT_MAX];
163 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket);
166 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this
167 // class is to send SignalDone, after OnDone callback from
168 // P2PAsyncAddressResolver. Libjingle sig slots are not thread safe. In case
169 // of MT sig slots clients must call disconnect. This class is to make sure
170 // we destruct from the same thread on which is created.
171 class AsyncAddressResolverImpl : public base::NonThreadSafe,
172 public rtc::AsyncResolverInterface {
173 public:
174 AsyncAddressResolverImpl(P2PSocketDispatcher* dispatcher);
175 virtual ~AsyncAddressResolverImpl();
177 // rtc::AsyncResolverInterface interface.
178 virtual void Start(const rtc::SocketAddress& addr) OVERRIDE;
179 virtual bool GetResolvedAddress(
180 int family, rtc::SocketAddress* addr) const OVERRIDE;
181 virtual int GetError() const OVERRIDE;
182 virtual void Destroy(bool wait) OVERRIDE;
184 private:
185 virtual void OnAddressResolved(const net::IPAddressList& addresses);
187 scoped_refptr<P2PAsyncAddressResolver> resolver_;
188 int port_; // Port number in |addr| from Start() method.
189 std::vector<rtc::IPAddress> addresses_; // Resolved addresses.
192 IpcPacketSocket::IpcPacketSocket()
193 : type_(P2P_SOCKET_UDP),
194 message_loop_(base::MessageLoop::current()),
195 state_(IS_UNINITIALIZED),
196 send_bytes_available_(kMaximumInFlightBytes),
197 writable_signal_expected_(false),
198 error_(0) {
199 COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate);
200 std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX),
201 kDefaultNonSetOptionValue);
204 IpcPacketSocket::~IpcPacketSocket() {
205 if (state_ == IS_OPENING || state_ == IS_OPEN ||
206 state_ == IS_ERROR) {
207 Close();
211 void IpcPacketSocket::TraceSendThrottlingState() const {
212 TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(),
213 send_bytes_available_);
214 TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(),
215 in_flight_packet_sizes_.size());
218 bool IpcPacketSocket::Init(P2PSocketType type,
219 P2PSocketClientImpl* client,
220 const rtc::SocketAddress& local_address,
221 const rtc::SocketAddress& remote_address) {
222 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
223 DCHECK_EQ(state_, IS_UNINITIALIZED);
225 type_ = type;
226 client_ = client;
227 local_address_ = local_address;
228 remote_address_ = remote_address;
229 state_ = IS_OPENING;
231 net::IPEndPoint local_endpoint;
232 if (!jingle_glue::SocketAddressToIPEndPoint(
233 local_address, &local_endpoint)) {
234 return false;
237 net::IPEndPoint remote_endpoint;
238 if (!remote_address.IsNil()) {
239 DCHECK(IsTcpClientSocket(type_));
241 if (remote_address.IsUnresolvedIP()) {
242 remote_endpoint =
243 net::IPEndPoint(net::IPAddressNumber(), remote_address.port());
244 } else {
245 if (!jingle_glue::SocketAddressToIPEndPoint(remote_address,
246 &remote_endpoint)) {
247 return false;
252 // We need to send both resolved and unresolved address in Init. Unresolved
253 // address will be used in case of TLS for certificate hostname matching.
254 // Certificate will be tied to domain name not to IP address.
255 P2PHostAndIPEndPoint remote_info(remote_address.hostname(), remote_endpoint);
257 client->Init(type, local_endpoint, remote_info, this);
259 return true;
262 void IpcPacketSocket::InitAcceptedTcp(
263 P2PSocketClient* client,
264 const rtc::SocketAddress& local_address,
265 const rtc::SocketAddress& remote_address) {
266 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
267 DCHECK_EQ(state_, IS_UNINITIALIZED);
269 client_ = client;
270 local_address_ = local_address;
271 remote_address_ = remote_address;
272 state_ = IS_OPEN;
273 TraceSendThrottlingState();
274 client_->SetDelegate(this);
277 // rtc::AsyncPacketSocket interface.
278 rtc::SocketAddress IpcPacketSocket::GetLocalAddress() const {
279 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
280 return local_address_;
283 rtc::SocketAddress IpcPacketSocket::GetRemoteAddress() const {
284 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
285 return remote_address_;
288 int IpcPacketSocket::Send(const void *data, size_t data_size,
289 const rtc::PacketOptions& options) {
290 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
291 return SendTo(data, data_size, remote_address_, options);
294 int IpcPacketSocket::SendTo(const void *data, size_t data_size,
295 const rtc::SocketAddress& address,
296 const rtc::PacketOptions& options) {
297 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
299 switch (state_) {
300 case IS_UNINITIALIZED:
301 NOTREACHED();
302 return EWOULDBLOCK;
303 case IS_OPENING:
304 return EWOULDBLOCK;
305 case IS_CLOSED:
306 return ENOTCONN;
307 case IS_ERROR:
308 return error_;
309 case IS_OPEN:
310 // Continue sending the packet.
311 break;
314 if (data_size == 0) {
315 NOTREACHED();
316 return 0;
319 if (data_size > send_bytes_available_) {
320 TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock",
321 TRACE_EVENT_SCOPE_THREAD,
322 "id",
323 client_->GetSocketID());
324 if (!writable_signal_expected_) {
325 WebRtcLogMessage(base::StringPrintf(
326 "IpcPacketSocket: sending is blocked. %d packets_in_flight.",
327 static_cast<int>(in_flight_packet_sizes_.size())));
329 writable_signal_expected_ = true;
332 error_ = EWOULDBLOCK;
333 return -1;
336 net::IPEndPoint address_chrome;
337 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) {
338 NOTREACHED();
339 error_ = EINVAL;
340 return -1;
343 send_bytes_available_ -= data_size;
344 in_flight_packet_sizes_.push_back(data_size);
345 TraceSendThrottlingState();
347 const char* data_char = reinterpret_cast<const char*>(data);
348 std::vector<char> data_vector(data_char, data_char + data_size);
349 client_->SendWithDscp(address_chrome, data_vector, options);
351 // Fake successful send. The caller ignores result anyway.
352 return data_size;
355 int IpcPacketSocket::Close() {
356 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
358 client_->Close();
359 state_ = IS_CLOSED;
361 return 0;
364 rtc::AsyncPacketSocket::State IpcPacketSocket::GetState() const {
365 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
367 switch (state_) {
368 case IS_UNINITIALIZED:
369 NOTREACHED();
370 return STATE_CLOSED;
372 case IS_OPENING:
373 return STATE_BINDING;
375 case IS_OPEN:
376 if (IsTcpClientSocket(type_)) {
377 return STATE_CONNECTED;
378 } else {
379 return STATE_BOUND;
382 case IS_CLOSED:
383 case IS_ERROR:
384 return STATE_CLOSED;
387 NOTREACHED();
388 return STATE_CLOSED;
391 int IpcPacketSocket::GetOption(rtc::Socket::Option option, int* value) {
392 P2PSocketOption p2p_socket_option = P2P_SOCKET_OPT_MAX;
393 if (!JingleSocketOptionToP2PSocketOption(option, &p2p_socket_option)) {
394 // unsupported option.
395 return -1;
398 *value = options_[p2p_socket_option];
399 return 0;
402 int IpcPacketSocket::SetOption(rtc::Socket::Option option, int value) {
403 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
405 P2PSocketOption p2p_socket_option = P2P_SOCKET_OPT_MAX;
406 if (!JingleSocketOptionToP2PSocketOption(option, &p2p_socket_option)) {
407 // Option is not supported.
408 return -1;
411 options_[p2p_socket_option] = value;
413 if (state_ == IS_OPEN) {
414 // Options will be applied when state becomes IS_OPEN in OnOpen.
415 return DoSetOption(p2p_socket_option, value);
417 return 0;
420 int IpcPacketSocket::DoSetOption(P2PSocketOption option, int value) {
421 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
422 DCHECK_EQ(state_, IS_OPEN);
424 client_->SetOption(option, value);
425 return 0;
428 int IpcPacketSocket::GetError() const {
429 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
430 return error_;
433 void IpcPacketSocket::SetError(int error) {
434 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
435 error_ = error;
438 void IpcPacketSocket::OnOpen(const net::IPEndPoint& local_address,
439 const net::IPEndPoint& remote_address) {
440 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
442 if (!jingle_glue::IPEndPointToSocketAddress(local_address, &local_address_)) {
443 // Always expect correct IPv4 address to be allocated.
444 NOTREACHED();
445 OnError();
446 return;
449 state_ = IS_OPEN;
450 TraceSendThrottlingState();
452 // Set all pending options if any.
453 for (int i = 0; i < P2P_SOCKET_OPT_MAX; ++i) {
454 if (options_[i] != kDefaultNonSetOptionValue)
455 DoSetOption(static_cast<P2PSocketOption> (i), options_[i]);
458 SignalAddressReady(this, local_address_);
459 if (IsTcpClientSocket(type_)) {
460 SignalConnect(this);
461 // If remote address is unresolved, set resolved remote IP address received
462 // in the callback. This address will be used while sending the packets
463 // over the network.
464 if (remote_address_.IsUnresolvedIP()) {
465 rtc::SocketAddress jingle_socket_address;
466 if (!jingle_glue::IPEndPointToSocketAddress(
467 remote_address, &jingle_socket_address)) {
468 NOTREACHED();
470 // Set only the IP address.
471 remote_address_.SetResolvedIP(jingle_socket_address.ipaddr());
476 void IpcPacketSocket::OnIncomingTcpConnection(
477 const net::IPEndPoint& address,
478 P2PSocketClient* client) {
479 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
481 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
483 rtc::SocketAddress remote_address;
484 if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) {
485 // Always expect correct IPv4 address to be allocated.
486 NOTREACHED();
488 socket->InitAcceptedTcp(client, local_address_, remote_address);
489 SignalNewConnection(this, socket.release());
492 void IpcPacketSocket::OnSendComplete() {
493 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
495 CHECK(!in_flight_packet_sizes_.empty());
496 send_bytes_available_ += in_flight_packet_sizes_.front();
498 DCHECK_LE(send_bytes_available_, kMaximumInFlightBytes);
500 in_flight_packet_sizes_.pop_front();
501 TraceSendThrottlingState();
503 if (writable_signal_expected_ && send_bytes_available_ > 0) {
504 WebRtcLogMessage(base::StringPrintf(
505 "IpcPacketSocket: sending is unblocked. %d packets in flight.",
506 static_cast<int>(in_flight_packet_sizes_.size())));
508 SignalReadyToSend(this);
509 writable_signal_expected_ = false;
513 void IpcPacketSocket::OnError() {
514 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
515 bool was_closed = (state_ == IS_ERROR || state_ == IS_CLOSED);
516 state_ = IS_ERROR;
517 error_ = ECONNABORTED;
518 if (!was_closed) {
519 SignalClose(this, 0);
523 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address,
524 const std::vector<char>& data,
525 const base::TimeTicks& timestamp) {
526 DCHECK_EQ(base::MessageLoop::current(), message_loop_);
528 rtc::SocketAddress address_lj;
529 if (!jingle_glue::IPEndPointToSocketAddress(address, &address_lj)) {
530 // We should always be able to convert address here because we
531 // don't expect IPv6 address on IPv4 connections.
532 NOTREACHED();
533 return;
536 rtc::PacketTime packet_time(timestamp.ToInternalValue(), 0);
537 SignalReadPacket(this, &data[0], data.size(), address_lj,
538 packet_time);
541 AsyncAddressResolverImpl::AsyncAddressResolverImpl(
542 P2PSocketDispatcher* dispatcher)
543 : resolver_(new P2PAsyncAddressResolver(dispatcher)) {
546 AsyncAddressResolverImpl::~AsyncAddressResolverImpl() {
549 void AsyncAddressResolverImpl::Start(const rtc::SocketAddress& addr) {
550 DCHECK(CalledOnValidThread());
551 // Copy port number from |addr|. |port_| must be copied
552 // when resolved address is returned in GetResolvedAddress.
553 port_ = addr.port();
555 resolver_->Start(addr, base::Bind(
556 &AsyncAddressResolverImpl::OnAddressResolved,
557 base::Unretained(this)));
560 bool AsyncAddressResolverImpl::GetResolvedAddress(
561 int family, rtc::SocketAddress* addr) const {
562 DCHECK(CalledOnValidThread());
564 if (addresses_.empty())
565 return false;
567 for (size_t i = 0; i < addresses_.size(); ++i) {
568 if (family == addresses_[i].family()) {
569 addr->SetResolvedIP(addresses_[i]);
570 addr->SetPort(port_);
571 return true;
574 return false;
577 int AsyncAddressResolverImpl::GetError() const {
578 DCHECK(CalledOnValidThread());
579 return addresses_.empty() ? -1 : 0;
582 void AsyncAddressResolverImpl::Destroy(bool wait) {
583 DCHECK(CalledOnValidThread());
584 resolver_->Cancel();
585 // Libjingle doesn't need this object any more and it's not going to delete
586 // it explicitly.
587 delete this;
590 void AsyncAddressResolverImpl::OnAddressResolved(
591 const net::IPAddressList& addresses) {
592 DCHECK(CalledOnValidThread());
593 for (size_t i = 0; i < addresses.size(); ++i) {
594 rtc::SocketAddress socket_address;
595 if (!jingle_glue::IPEndPointToSocketAddress(
596 net::IPEndPoint(addresses[i], 0), &socket_address)) {
597 NOTREACHED();
599 addresses_.push_back(socket_address.ipaddr());
601 SignalDone(this);
604 } // namespace
606 IpcPacketSocketFactory::IpcPacketSocketFactory(
607 P2PSocketDispatcher* socket_dispatcher)
608 : socket_dispatcher_(socket_dispatcher) {
611 IpcPacketSocketFactory::~IpcPacketSocketFactory() {
614 rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateUdpSocket(
615 const rtc::SocketAddress& local_address, int min_port, int max_port) {
616 rtc::SocketAddress crome_address;
617 P2PSocketClientImpl* socket_client =
618 new P2PSocketClientImpl(socket_dispatcher_);
619 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
620 // TODO(sergeyu): Respect local_address and port limits here (need
621 // to pass them over IPC channel to the browser).
622 if (!socket->Init(P2P_SOCKET_UDP, socket_client,
623 local_address, rtc::SocketAddress())) {
624 return NULL;
626 return socket.release();
629 rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateServerTcpSocket(
630 const rtc::SocketAddress& local_address, int min_port, int max_port,
631 int opts) {
632 // TODO(sergeyu): Implement SSL support.
633 if (opts & rtc::PacketSocketFactory::OPT_SSLTCP)
634 return NULL;
636 P2PSocketType type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
637 P2P_SOCKET_STUN_TCP_SERVER : P2P_SOCKET_TCP_SERVER;
638 P2PSocketClientImpl* socket_client =
639 new P2PSocketClientImpl(socket_dispatcher_);
640 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
641 if (!socket->Init(type, socket_client, local_address,
642 rtc::SocketAddress())) {
643 return NULL;
645 return socket.release();
648 rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateClientTcpSocket(
649 const rtc::SocketAddress& local_address,
650 const rtc::SocketAddress& remote_address,
651 const rtc::ProxyInfo& proxy_info,
652 const std::string& user_agent, int opts) {
653 P2PSocketType type;
654 if (opts & rtc::PacketSocketFactory::OPT_SSLTCP) {
655 type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
656 P2P_SOCKET_STUN_SSLTCP_CLIENT : P2P_SOCKET_SSLTCP_CLIENT;
657 } else if (opts & rtc::PacketSocketFactory::OPT_TLS) {
658 type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
659 P2P_SOCKET_STUN_TLS_CLIENT : P2P_SOCKET_TLS_CLIENT;
660 } else {
661 type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
662 P2P_SOCKET_STUN_TCP_CLIENT : P2P_SOCKET_TCP_CLIENT;
664 P2PSocketClientImpl* socket_client =
665 new P2PSocketClientImpl(socket_dispatcher_);
666 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
667 if (!socket->Init(type, socket_client, local_address, remote_address))
668 return NULL;
669 return socket.release();
672 rtc::AsyncResolverInterface*
673 IpcPacketSocketFactory::CreateAsyncResolver() {
674 scoped_ptr<AsyncAddressResolverImpl> resolver(
675 new AsyncAddressResolverImpl(socket_dispatcher_));
676 return resolver.release();
679 } // namespace content