Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / renderer / p2p / ipc_socket_factory.cc
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.
4
5 #include "content/renderer/p2p/ipc_socket_factory.h"
6
7 #include <algorithm>
8 #include <deque>
9
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/metrics/histogram.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/threading/non_thread_safe.h"
17 #include "content/renderer/media/webrtc_logging.h"
18 #include "content/renderer/p2p/host_address_request.h"
19 #include "content/renderer/p2p/socket_client_delegate.h"
20 #include "content/renderer/p2p/socket_client_impl.h"
21 #include "content/renderer/p2p/socket_dispatcher.h"
22 #include "jingle/glue/utils.h"
23 #include "third_party/webrtc/base/asyncpacketsocket.h"
24
25 namespace content {
26
27 namespace {
28
29 const int kDefaultNonSetOptionValue = -1;
30
31 bool IsTcpClientSocket(P2PSocketType type) {
32   return (type == P2P_SOCKET_STUN_TCP_CLIENT) ||
33          (type == P2P_SOCKET_TCP_CLIENT) ||
34          (type == P2P_SOCKET_STUN_SSLTCP_CLIENT) ||
35          (type == P2P_SOCKET_SSLTCP_CLIENT) ||
36          (type == P2P_SOCKET_TLS_CLIENT) ||
37          (type == P2P_SOCKET_STUN_TLS_CLIENT);
38 }
39
40 bool JingleSocketOptionToP2PSocketOption(rtc::Socket::Option option,
41                                          P2PSocketOption* ipc_option) {
42   switch (option) {
43     case rtc::Socket::OPT_RCVBUF:
44       *ipc_option = P2P_SOCKET_OPT_RCVBUF;
45       break;
46     case rtc::Socket::OPT_SNDBUF:
47       *ipc_option = P2P_SOCKET_OPT_SNDBUF;
48       break;
49     case rtc::Socket::OPT_DSCP:
50       *ipc_option = P2P_SOCKET_OPT_DSCP;
51       break;
52     case rtc::Socket::OPT_DONTFRAGMENT:
53     case rtc::Socket::OPT_NODELAY:
54     case rtc::Socket::OPT_IPV6_V6ONLY:
55     case rtc::Socket::OPT_RTP_SENDTIME_EXTN_ID:
56       return false;  // Not supported by the chrome sockets.
57     default:
58       NOTREACHED();
59       return false;
60   }
61   return true;
62 }
63
64 // TODO(miu): This needs tuning.  http://crbug.com/237960
65 // http://crbug.com/427555
66 const size_t kMaximumInFlightBytes = 256 * 1024;  // 256 KB
67
68 // IpcPacketSocket implements rtc::AsyncPacketSocket interface
69 // using P2PSocketClient that works over IPC-channel. It must be used
70 // on the thread it was created.
71 class IpcPacketSocket : public rtc::AsyncPacketSocket,
72                         public P2PSocketClientDelegate {
73  public:
74   IpcPacketSocket();
75   ~IpcPacketSocket() override;
76
77   // Always takes ownership of client even if initialization fails.
78   bool Init(P2PSocketType type, P2PSocketClientImpl* client,
79             const rtc::SocketAddress& local_address,
80             const rtc::SocketAddress& remote_address);
81
82   // rtc::AsyncPacketSocket interface.
83   rtc::SocketAddress GetLocalAddress() const override;
84   rtc::SocketAddress GetRemoteAddress() const override;
85   int Send(const void* pv,
86            size_t cb,
87            const rtc::PacketOptions& options) override;
88   int SendTo(const void* pv,
89              size_t cb,
90              const rtc::SocketAddress& addr,
91              const rtc::PacketOptions& options) override;
92   int Close() override;
93   State GetState() const override;
94   int GetOption(rtc::Socket::Option option, int* value) override;
95   int SetOption(rtc::Socket::Option option, int value) override;
96   int GetError() const override;
97   void SetError(int error) override;
98
99   // P2PSocketClientDelegate implementation.
100   void OnOpen(const net::IPEndPoint& local_address,
101               const net::IPEndPoint& remote_address) override;
102   void OnIncomingTcpConnection(const net::IPEndPoint& address,
103                                P2PSocketClient* client) override;
104   void OnSendComplete() override;
105   void OnError() override;
106   void OnDataReceived(const net::IPEndPoint& address,
107                       const std::vector<char>& data,
108                       const base::TimeTicks& timestamp) override;
109
110  private:
111   enum InternalState {
112     IS_UNINITIALIZED,
113     IS_OPENING,
114     IS_OPEN,
115     IS_CLOSED,
116     IS_ERROR,
117   };
118
119   // Increment the counter for consecutive bytes discarded as socket is running
120   // out of buffer.
121   void IncrementDiscardCounters(size_t bytes_discarded);
122
123   // Update trace of send throttling internal state. This should be called
124   // immediately after any changes to |send_bytes_available_| and/or
125   // |in_flight_packet_sizes_|.
126   void TraceSendThrottlingState() const;
127
128   void InitAcceptedTcp(P2PSocketClient* client,
129                        const rtc::SocketAddress& local_address,
130                        const rtc::SocketAddress& remote_address);
131
132   int DoSetOption(P2PSocketOption option, int value);
133
134   P2PSocketType type_;
135
136   // Message loop on which this socket was created and being used.
137   base::MessageLoop* message_loop_;
138
139   // Corresponding P2P socket client.
140   scoped_refptr<P2PSocketClient> client_;
141
142   // Local address is allocated by the browser process, and the
143   // renderer side doesn't know the address until it receives OnOpen()
144   // event from the browser.
145   rtc::SocketAddress local_address_;
146
147   // Remote address for client TCP connections.
148   rtc::SocketAddress remote_address_;
149
150   // Current state of the object.
151   InternalState state_;
152
153   // Track the number of bytes allowed to be sent non-blocking. This is used to
154   // throttle the sending of packets to the browser process. For each packet
155   // sent, the value is decreased. As callbacks to OnSendComplete() (as IPCs
156   // from the browser process) are made, the value is increased back. This
157   // allows short bursts of high-rate sending without dropping packets, but
158   // quickly restricts the client to a sustainable steady-state rate.
159   size_t send_bytes_available_;
160   std::deque<size_t> in_flight_packet_sizes_;
161
162   // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the
163   // caller expects SignalWritable notification.
164   bool writable_signal_expected_;
165
166   // Current error code. Valid when state_ == IS_ERROR.
167   int error_;
168   int options_[P2P_SOCKET_OPT_MAX];
169
170   // Track the maximum and current consecutive bytes discarded due to not enough
171   // send_bytes_available_.
172   size_t max_discard_bytes_sequence_;
173   size_t current_discard_bytes_sequence_;
174
175   // Track the total number of packets and the number of packets discarded.
176   size_t packets_discarded_;
177   size_t total_packets_;
178
179   DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket);
180 };
181
182 // Simple wrapper around P2PAsyncAddressResolver. The main purpose of this
183 // class is to send SignalDone, after OnDone callback from
184 // P2PAsyncAddressResolver. Libjingle sig slots are not thread safe. In case
185 // of MT sig slots clients must call disconnect. This class is to make sure
186 // we destruct from the same thread on which is created.
187 class AsyncAddressResolverImpl :  public base::NonThreadSafe,
188                                   public rtc::AsyncResolverInterface {
189  public:
190   AsyncAddressResolverImpl(P2PSocketDispatcher* dispatcher);
191   ~AsyncAddressResolverImpl() override;
192
193   // rtc::AsyncResolverInterface interface.
194   void Start(const rtc::SocketAddress& addr) override;
195   bool GetResolvedAddress(int family, rtc::SocketAddress* addr) const override;
196   int GetError() const override;
197   void Destroy(bool wait) override;
198
199  private:
200   virtual void OnAddressResolved(const net::IPAddressList& addresses);
201
202   scoped_refptr<P2PAsyncAddressResolver> resolver_;
203   int port_;   // Port number in |addr| from Start() method.
204   std::vector<rtc::IPAddress> addresses_;  // Resolved addresses.
205 };
206
207 IpcPacketSocket::IpcPacketSocket()
208     : type_(P2P_SOCKET_UDP),
209       message_loop_(base::MessageLoop::current()),
210       state_(IS_UNINITIALIZED),
211       send_bytes_available_(kMaximumInFlightBytes),
212       writable_signal_expected_(false),
213       error_(0),
214       max_discard_bytes_sequence_(0),
215       current_discard_bytes_sequence_(0),
216       packets_discarded_(0),
217       total_packets_(0) {
218   COMPILE_ASSERT(kMaximumInFlightBytes > 0, would_send_at_zero_rate);
219   std::fill_n(options_, static_cast<int> (P2P_SOCKET_OPT_MAX),
220               kDefaultNonSetOptionValue);
221 }
222
223 IpcPacketSocket::~IpcPacketSocket() {
224   if (state_ == IS_OPENING || state_ == IS_OPEN ||
225       state_ == IS_ERROR) {
226     Close();
227   }
228
229   UMA_HISTOGRAM_COUNTS_10000("WebRTC.ApplicationMaxConsecutiveBytesDiscard",
230                              max_discard_bytes_sequence_);
231
232   if (total_packets_ > 0) {
233     UMA_HISTOGRAM_PERCENTAGE("WebRTC.ApplicationPercentPacketsDiscarded",
234                              (packets_discarded_ * 100) / total_packets_);
235   }
236 }
237
238 void IpcPacketSocket::TraceSendThrottlingState() const {
239   TRACE_COUNTER_ID1("p2p", "P2PSendBytesAvailable", local_address_.port(),
240                     send_bytes_available_);
241   TRACE_COUNTER_ID1("p2p", "P2PSendPacketsInFlight", local_address_.port(),
242                     in_flight_packet_sizes_.size());
243 }
244
245 void IpcPacketSocket::IncrementDiscardCounters(size_t bytes_discarded) {
246   current_discard_bytes_sequence_ += bytes_discarded;
247   packets_discarded_++;
248
249   if (current_discard_bytes_sequence_ > max_discard_bytes_sequence_) {
250     max_discard_bytes_sequence_ = current_discard_bytes_sequence_;
251   }
252 }
253
254 bool IpcPacketSocket::Init(P2PSocketType type,
255                            P2PSocketClientImpl* client,
256                            const rtc::SocketAddress& local_address,
257                            const rtc::SocketAddress& remote_address) {
258   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
259   DCHECK_EQ(state_, IS_UNINITIALIZED);
260
261   type_ = type;
262   client_ = client;
263   local_address_ = local_address;
264   remote_address_ = remote_address;
265   state_ = IS_OPENING;
266
267   net::IPEndPoint local_endpoint;
268   if (!jingle_glue::SocketAddressToIPEndPoint(
269           local_address, &local_endpoint)) {
270     return false;
271   }
272
273   net::IPEndPoint remote_endpoint;
274   if (!remote_address.IsNil()) {
275     DCHECK(IsTcpClientSocket(type_));
276
277     if (remote_address.IsUnresolvedIP()) {
278       remote_endpoint =
279           net::IPEndPoint(net::IPAddressNumber(), remote_address.port());
280     } else {
281       if (!jingle_glue::SocketAddressToIPEndPoint(remote_address,
282                                                   &remote_endpoint)) {
283         return false;
284       }
285     }
286   }
287
288   // We need to send both resolved and unresolved address in Init. Unresolved
289   // address will be used in case of TLS for certificate hostname matching.
290   // Certificate will be tied to domain name not to IP address.
291   P2PHostAndIPEndPoint remote_info(remote_address.hostname(), remote_endpoint);
292
293   client->Init(type, local_endpoint, remote_info, this);
294
295   return true;
296 }
297
298 void IpcPacketSocket::InitAcceptedTcp(
299     P2PSocketClient* client,
300     const rtc::SocketAddress& local_address,
301     const rtc::SocketAddress& remote_address) {
302   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
303   DCHECK_EQ(state_, IS_UNINITIALIZED);
304
305   client_ = client;
306   local_address_ = local_address;
307   remote_address_ = remote_address;
308   state_ = IS_OPEN;
309   TraceSendThrottlingState();
310   client_->SetDelegate(this);
311 }
312
313 // rtc::AsyncPacketSocket interface.
314 rtc::SocketAddress IpcPacketSocket::GetLocalAddress() const {
315   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
316   return local_address_;
317 }
318
319 rtc::SocketAddress IpcPacketSocket::GetRemoteAddress() const {
320   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
321   return remote_address_;
322 }
323
324 int IpcPacketSocket::Send(const void *data, size_t data_size,
325                           const rtc::PacketOptions& options) {
326   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
327   return SendTo(data, data_size, remote_address_, options);
328 }
329
330 int IpcPacketSocket::SendTo(const void *data, size_t data_size,
331                             const rtc::SocketAddress& address,
332                             const rtc::PacketOptions& options) {
333   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
334
335   switch (state_) {
336     case IS_UNINITIALIZED:
337       NOTREACHED();
338       return EWOULDBLOCK;
339     case IS_OPENING:
340       return EWOULDBLOCK;
341     case IS_CLOSED:
342       return ENOTCONN;
343     case IS_ERROR:
344       return error_;
345     case IS_OPEN:
346       // Continue sending the packet.
347       break;
348   }
349
350   if (data_size == 0) {
351     NOTREACHED();
352     return 0;
353   }
354
355   total_packets_++;
356
357   if (data_size > send_bytes_available_) {
358     TRACE_EVENT_INSTANT1("p2p", "MaxPendingBytesWouldBlock",
359                          TRACE_EVENT_SCOPE_THREAD,
360                          "id",
361                          client_->GetSocketID());
362     if (!writable_signal_expected_) {
363       WebRtcLogMessage(base::StringPrintf(
364           "IpcPacketSocket: sending is blocked. %d packets_in_flight.",
365           static_cast<int>(in_flight_packet_sizes_.size())));
366
367       writable_signal_expected_ = true;
368     }
369
370     error_ = EWOULDBLOCK;
371     IncrementDiscardCounters(data_size);
372     return -1;
373   } else {
374     current_discard_bytes_sequence_ = 0;
375   }
376
377   net::IPEndPoint address_chrome;
378   if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) {
379     VLOG(1) << "Failed to convert remote address to IPEndPoint: address = "
380             << address.ToSensitiveString() << ", remote_address_ = "
381             << remote_address_.ToSensitiveString();
382     NOTREACHED();
383     error_ = EINVAL;
384     return -1;
385   }
386
387   send_bytes_available_ -= data_size;
388   in_flight_packet_sizes_.push_back(data_size);
389   TraceSendThrottlingState();
390
391   const char* data_char = reinterpret_cast<const char*>(data);
392   std::vector<char> data_vector(data_char, data_char + data_size);
393   client_->SendWithDscp(address_chrome, data_vector, options);
394
395   // Fake successful send. The caller ignores result anyway.
396   return data_size;
397 }
398
399 int IpcPacketSocket::Close() {
400   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
401
402   client_->Close();
403   state_ = IS_CLOSED;
404
405   return 0;
406 }
407
408 rtc::AsyncPacketSocket::State IpcPacketSocket::GetState() const {
409   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
410
411   switch (state_) {
412     case IS_UNINITIALIZED:
413       NOTREACHED();
414       return STATE_CLOSED;
415
416     case IS_OPENING:
417       return STATE_BINDING;
418
419     case IS_OPEN:
420       if (IsTcpClientSocket(type_)) {
421         return STATE_CONNECTED;
422       } else {
423         return STATE_BOUND;
424       }
425
426     case IS_CLOSED:
427     case IS_ERROR:
428       return STATE_CLOSED;
429   }
430
431   NOTREACHED();
432   return STATE_CLOSED;
433 }
434
435 int IpcPacketSocket::GetOption(rtc::Socket::Option option, int* value) {
436   P2PSocketOption p2p_socket_option = P2P_SOCKET_OPT_MAX;
437   if (!JingleSocketOptionToP2PSocketOption(option, &p2p_socket_option)) {
438     // unsupported option.
439     return -1;
440   }
441
442   *value = options_[p2p_socket_option];
443   return 0;
444 }
445
446 int IpcPacketSocket::SetOption(rtc::Socket::Option option, int value) {
447   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
448
449   P2PSocketOption p2p_socket_option = P2P_SOCKET_OPT_MAX;
450   if (!JingleSocketOptionToP2PSocketOption(option, &p2p_socket_option)) {
451     // Option is not supported.
452     return -1;
453   }
454
455   options_[p2p_socket_option] = value;
456
457   if (state_ == IS_OPEN) {
458     // Options will be applied when state becomes IS_OPEN in OnOpen.
459     return DoSetOption(p2p_socket_option, value);
460   }
461   return 0;
462 }
463
464 int IpcPacketSocket::DoSetOption(P2PSocketOption option, int value) {
465   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
466   DCHECK_EQ(state_, IS_OPEN);
467
468   client_->SetOption(option, value);
469   return 0;
470 }
471
472 int IpcPacketSocket::GetError() const {
473   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
474   return error_;
475 }
476
477 void IpcPacketSocket::SetError(int error) {
478   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
479   error_ = error;
480 }
481
482 void IpcPacketSocket::OnOpen(const net::IPEndPoint& local_address,
483                              const net::IPEndPoint& remote_address) {
484   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
485
486   if (!jingle_glue::IPEndPointToSocketAddress(local_address, &local_address_)) {
487     // Always expect correct IPv4 address to be allocated.
488     NOTREACHED();
489     OnError();
490     return;
491   }
492
493   state_ = IS_OPEN;
494   TraceSendThrottlingState();
495
496   // Set all pending options if any.
497   for (int i = 0; i < P2P_SOCKET_OPT_MAX; ++i) {
498     if (options_[i] != kDefaultNonSetOptionValue)
499       DoSetOption(static_cast<P2PSocketOption> (i), options_[i]);
500   }
501
502   SignalAddressReady(this, local_address_);
503   if (IsTcpClientSocket(type_)) {
504     // If remote address is unresolved, set resolved remote IP address received
505     // in the callback. This address will be used while sending the packets
506     // over the network.
507     if (remote_address_.IsUnresolvedIP()) {
508       rtc::SocketAddress jingle_socket_address;
509       if (!jingle_glue::IPEndPointToSocketAddress(
510             remote_address, &jingle_socket_address)) {
511         NOTREACHED();
512       }
513       // Set only the IP address.
514       remote_address_.SetResolvedIP(jingle_socket_address.ipaddr());
515     }
516
517     // SignalConnect after updating the |remote_address_| so that the listener
518     // can get the resolved remote address.
519     SignalConnect(this);
520   }
521 }
522
523 void IpcPacketSocket::OnIncomingTcpConnection(
524     const net::IPEndPoint& address,
525     P2PSocketClient* client) {
526   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
527
528   scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
529
530   rtc::SocketAddress remote_address;
531   if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) {
532     // Always expect correct IPv4 address to be allocated.
533     NOTREACHED();
534   }
535   socket->InitAcceptedTcp(client, local_address_, remote_address);
536   SignalNewConnection(this, socket.release());
537 }
538
539 void IpcPacketSocket::OnSendComplete() {
540   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
541
542   CHECK(!in_flight_packet_sizes_.empty());
543   send_bytes_available_ += in_flight_packet_sizes_.front();
544
545   DCHECK_LE(send_bytes_available_, kMaximumInFlightBytes);
546
547   in_flight_packet_sizes_.pop_front();
548   TraceSendThrottlingState();
549
550   if (writable_signal_expected_ && send_bytes_available_ > 0) {
551     WebRtcLogMessage(base::StringPrintf(
552         "IpcPacketSocket: sending is unblocked. %d packets in flight.",
553         static_cast<int>(in_flight_packet_sizes_.size())));
554
555     SignalReadyToSend(this);
556     writable_signal_expected_ = false;
557   }
558 }
559
560 void IpcPacketSocket::OnError() {
561   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
562   bool was_closed = (state_ == IS_ERROR || state_ == IS_CLOSED);
563   state_ = IS_ERROR;
564   error_ = ECONNABORTED;
565   if (!was_closed) {
566     SignalClose(this, 0);
567   }
568 }
569
570 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address,
571                                      const std::vector<char>& data,
572                                      const base::TimeTicks& timestamp) {
573   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
574
575   rtc::SocketAddress address_lj;
576   if (!jingle_glue::IPEndPointToSocketAddress(address, &address_lj)) {
577     // We should always be able to convert address here because we
578     // don't expect IPv6 address on IPv4 connections.
579     NOTREACHED();
580     return;
581   }
582
583   rtc::PacketTime packet_time(timestamp.ToInternalValue(), 0);
584   SignalReadPacket(this, &data[0], data.size(), address_lj,
585                    packet_time);
586 }
587
588 AsyncAddressResolverImpl::AsyncAddressResolverImpl(
589     P2PSocketDispatcher* dispatcher)
590     : resolver_(new P2PAsyncAddressResolver(dispatcher)) {
591 }
592
593 AsyncAddressResolverImpl::~AsyncAddressResolverImpl() {
594 }
595
596 void AsyncAddressResolverImpl::Start(const rtc::SocketAddress& addr) {
597   DCHECK(CalledOnValidThread());
598   // Copy port number from |addr|. |port_| must be copied
599   // when resolved address is returned in GetResolvedAddress.
600   port_ = addr.port();
601
602   resolver_->Start(addr, base::Bind(
603       &AsyncAddressResolverImpl::OnAddressResolved,
604       base::Unretained(this)));
605 }
606
607 bool AsyncAddressResolverImpl::GetResolvedAddress(
608     int family, rtc::SocketAddress* addr) const {
609   DCHECK(CalledOnValidThread());
610
611   if (addresses_.empty())
612    return false;
613
614   for (size_t i = 0; i < addresses_.size(); ++i) {
615     if (family == addresses_[i].family()) {
616       addr->SetResolvedIP(addresses_[i]);
617       addr->SetPort(port_);
618       return true;
619     }
620   }
621   return false;
622 }
623
624 int AsyncAddressResolverImpl::GetError() const {
625   DCHECK(CalledOnValidThread());
626   return addresses_.empty() ? -1 : 0;
627 }
628
629 void AsyncAddressResolverImpl::Destroy(bool wait) {
630   DCHECK(CalledOnValidThread());
631   resolver_->Cancel();
632   // Libjingle doesn't need this object any more and it's not going to delete
633   // it explicitly.
634   delete this;
635 }
636
637 void AsyncAddressResolverImpl::OnAddressResolved(
638     const net::IPAddressList& addresses) {
639   DCHECK(CalledOnValidThread());
640   for (size_t i = 0; i < addresses.size(); ++i) {
641     rtc::SocketAddress socket_address;
642     if (!jingle_glue::IPEndPointToSocketAddress(
643             net::IPEndPoint(addresses[i], 0), &socket_address)) {
644       NOTREACHED();
645     }
646     addresses_.push_back(socket_address.ipaddr());
647   }
648   SignalDone(this);
649 }
650
651 }  // namespace
652
653 IpcPacketSocketFactory::IpcPacketSocketFactory(
654     P2PSocketDispatcher* socket_dispatcher)
655     : socket_dispatcher_(socket_dispatcher) {
656 }
657
658 IpcPacketSocketFactory::~IpcPacketSocketFactory() {
659 }
660
661 rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateUdpSocket(
662     const rtc::SocketAddress& local_address, uint16 min_port, uint16 max_port) {
663   rtc::SocketAddress crome_address;
664   P2PSocketClientImpl* socket_client =
665       new P2PSocketClientImpl(socket_dispatcher_);
666   scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
667   // TODO(sergeyu): Respect local_address and port limits here (need
668   // to pass them over IPC channel to the browser).
669   if (!socket->Init(P2P_SOCKET_UDP, socket_client,
670                     local_address, rtc::SocketAddress())) {
671     return NULL;
672   }
673   return socket.release();
674 }
675
676 rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateServerTcpSocket(
677     const rtc::SocketAddress& local_address, uint16 min_port, uint16 max_port,
678     int opts) {
679   // TODO(sergeyu): Implement SSL support.
680   if (opts & rtc::PacketSocketFactory::OPT_SSLTCP)
681     return NULL;
682
683   P2PSocketType type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
684       P2P_SOCKET_STUN_TCP_SERVER : P2P_SOCKET_TCP_SERVER;
685   P2PSocketClientImpl* socket_client =
686       new P2PSocketClientImpl(socket_dispatcher_);
687   scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
688   if (!socket->Init(type, socket_client, local_address,
689                     rtc::SocketAddress())) {
690     return NULL;
691   }
692   return socket.release();
693 }
694
695 rtc::AsyncPacketSocket* IpcPacketSocketFactory::CreateClientTcpSocket(
696     const rtc::SocketAddress& local_address,
697     const rtc::SocketAddress& remote_address,
698     const rtc::ProxyInfo& proxy_info,
699     const std::string& user_agent, int opts) {
700   P2PSocketType type;
701   if (opts & rtc::PacketSocketFactory::OPT_SSLTCP) {
702     type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
703         P2P_SOCKET_STUN_SSLTCP_CLIENT : P2P_SOCKET_SSLTCP_CLIENT;
704   } else if (opts & rtc::PacketSocketFactory::OPT_TLS) {
705     type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
706         P2P_SOCKET_STUN_TLS_CLIENT : P2P_SOCKET_TLS_CLIENT;
707   } else {
708     type = (opts & rtc::PacketSocketFactory::OPT_STUN) ?
709         P2P_SOCKET_STUN_TCP_CLIENT : P2P_SOCKET_TCP_CLIENT;
710   }
711   P2PSocketClientImpl* socket_client =
712       new P2PSocketClientImpl(socket_dispatcher_);
713   scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
714   if (!socket->Init(type, socket_client, local_address, remote_address))
715     return NULL;
716   return socket.release();
717 }
718
719 rtc::AsyncResolverInterface*
720 IpcPacketSocketFactory::CreateAsyncResolver() {
721   scoped_ptr<AsyncAddressResolverImpl> resolver(
722     new AsyncAddressResolverImpl(socket_dispatcher_));
723   return resolver.release();
724 }
725
726 }  // namespace content