summaryrefslogtreecommitdiff
path: root/chromium/content/browser/renderer_host/p2p/socket_host.h
blob: 992a67ecd34ef8af25a3366ea2f4468cef0d3569 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
#include "content/public/browser/render_process_host.h"
#include "net/base/ip_endpoint.h"
#include "net/socket/datagram_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"

namespace IPC {
class Sender;
}

namespace net {
class URLRequestContextGetter;
}

namespace network {
class ProxyResolvingClientSocketFactory;
}

namespace rtc {
struct PacketOptions;
}

namespace content {
class P2PMessageThrottler;

// Base class for P2P sockets.
class CONTENT_EXPORT P2PSocketHost {
 public:
  static const int kStunHeaderSize = 20;
  // Creates P2PSocketHost of the specific type.
  static P2PSocketHost* Create(IPC::Sender* message_sender,
                               int socket_id,
                               P2PSocketType type,
                               net::URLRequestContextGetter* url_context,
                               network::ProxyResolvingClientSocketFactory*
                                   proxy_resolving_socket_factory,
                               P2PMessageThrottler* throttler);

  virtual ~P2PSocketHost();

  // Initalizes the socket. Returns false when initialization fails.
  // |min_port| and |max_port| specify the valid range of allowed ports.
  // |min_port| must be less than or equal to |max_port|.
  // If |min_port| is zero, |max_port| must also be zero and it means all ports
  // are valid.
  // If |local_address.port()| is zero, the socket will be initialized to a port
  // in the valid range.
  // If |local_address.port()| is nonzero and not in the valid range,
  // initialization will fail.
  virtual bool Init(const net::IPEndPoint& local_address,
                    uint16_t min_port,
                    uint16_t max_port,
                    const P2PHostAndIPEndPoint& remote_address) = 0;

  // Sends |data| on the socket to |to|.
  virtual void Send(
      const net::IPEndPoint& to,
      const std::vector<char>& data,
      const rtc::PacketOptions& options,
      uint64_t packet_id,
      const net::NetworkTrafficAnnotationTag traffic_annotation) = 0;

  virtual std::unique_ptr<P2PSocketHost> AcceptIncomingTcpConnection(
      const net::IPEndPoint& remote_address,
      int id) = 0;

  virtual bool SetOption(P2PSocketOption option, int value) = 0;

  void StartRtpDump(
      bool incoming,
      bool outgoing,
      const RenderProcessHost::WebRtcRtpPacketCallback& packet_callback);
  void StopRtpDump(bool incoming, bool outgoing);

 protected:
  friend class P2PSocketHostTcpTestBase;

  // This should match suffix IPProtocolType defined in histograms.xml.
  enum ProtocolType { UDP = 0x1, TCP = 0x2 };

  // TODO(mallinath) - Remove this below enum and use one defined in
  // libjingle/souce/talk/p2p/base/stun.h
  enum StunMessageType {
    STUN_BINDING_REQUEST = 0x0001,
    STUN_BINDING_RESPONSE = 0x0101,
    STUN_BINDING_ERROR_RESPONSE = 0x0111,
    STUN_SHARED_SECRET_REQUEST = 0x0002,
    STUN_SHARED_SECRET_RESPONSE = 0x0102,
    STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112,
    STUN_ALLOCATE_REQUEST = 0x0003,
    STUN_ALLOCATE_RESPONSE = 0x0103,
    STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
    STUN_SEND_REQUEST = 0x0004,
    STUN_SEND_RESPONSE = 0x0104,
    STUN_SEND_ERROR_RESPONSE = 0x0114,
    STUN_DATA_INDICATION = 0x0115,
    TURN_SEND_INDICATION = 0x0016,
    TURN_DATA_INDICATION = 0x0017,
    TURN_CREATE_PERMISSION_REQUEST = 0x0008,
    TURN_CREATE_PERMISSION_RESPONSE = 0x0108,
    TURN_CREATE_PERMISSION_ERROR_RESPONSE = 0x0118,
    TURN_CHANNEL_BIND_REQUEST = 0x0009,
    TURN_CHANNEL_BIND_RESPONSE = 0x0109,
    TURN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119,
  };

  enum State {
    STATE_UNINITIALIZED,
    STATE_CONNECTING,
    STATE_TLS_CONNECTING,
    STATE_OPEN,
    STATE_ERROR,
  };

  P2PSocketHost(IPC::Sender* message_sender,
                int socket_id,
                ProtocolType protocol_type);

  // Verifies that the packet |data| has a valid STUN header. In case
  // of success stores type of the message in |type|.
  static bool GetStunPacketType(const char* data, int data_size,
                                StunMessageType* type);
  static bool IsRequestOrResponse(StunMessageType type);

  static void ReportSocketError(int result, const char* histogram_name);

  // Calls |packet_dump_callback_| to record the RTP header.
  void DumpRtpPacket(const char* packet, size_t length, bool incoming);

  // A helper to dump the packet on the IO thread.
  void DumpRtpPacketOnIOThread(std::unique_ptr<uint8_t[]> packet_header,
                               size_t header_length,
                               size_t packet_length,
                               bool incoming);

  // Used by subclasses to track the metrics of delayed bytes and packets.
  void IncrementDelayedPackets();
  void IncrementTotalSentPackets();
  void IncrementDelayedBytes(uint32_t size);
  void DecrementDelayedBytes(uint32_t size);

  IPC::Sender* message_sender_;
  int id_;
  State state_;
  bool dump_incoming_rtp_packet_;
  bool dump_outgoing_rtp_packet_;
  RenderProcessHost::WebRtcRtpPacketCallback packet_dump_callback_;

  ProtocolType protocol_type_;

 private:
  // Track total delayed packets for calculating how many packets are
  // delayed by system at the end of call.
  uint32_t send_packets_delayed_total_;
  uint32_t send_packets_total_;

  // Track the maximum of consecutive delayed bytes caused by system's
  // EWOULDBLOCK.
  int32_t send_bytes_delayed_max_;
  int32_t send_bytes_delayed_cur_;

  base::WeakPtrFactory<P2PSocketHost> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(P2PSocketHost);
};

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_