1 // Copyright (c) 2011 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 #ifndef SERVICES_NETWORK_P2P_SOCKET_TCP_H_
6 #define SERVICES_NETWORK_P2P_SOCKET_TCP_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <vector>
12 
13 #include "base/compiler_specific.h"
14 #include "base/component_export.h"
15 #include "base/containers/queue.h"
16 #include "base/macros.h"
17 #include "base/memory/ref_counted.h"
18 #include "mojo/public/cpp/bindings/pending_receiver.h"
19 #include "mojo/public/cpp/bindings/pending_remote.h"
20 #include "net/base/ip_endpoint.h"
21 #include "net/traffic_annotation/network_traffic_annotation.h"
22 #include "services/network/p2p/socket.h"
23 #include "services/network/public/cpp/p2p_socket_type.h"
24 
25 namespace net {
26 class DrainableIOBuffer;
27 class GrowableIOBuffer;
28 class StreamSocket;
29 }  // namespace net
30 
31 namespace network {
32 class ProxyResolvingClientSocketFactory;
33 
COMPONENT_EXPORT(NETWORK_SERVICE)34 class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocketTcpBase : public P2PSocket {
35  public:
36   P2PSocketTcpBase(
37       Delegate* delegate,
38       mojo::PendingRemote<mojom::P2PSocketClient> client,
39       mojo::PendingReceiver<mojom::P2PSocket> socket,
40       P2PSocketType type,
41       ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory);
42   ~P2PSocketTcpBase() override;
43 
44   void InitAccepted(const net::IPEndPoint& remote_address,
45                     std::unique_ptr<net::StreamSocket> socket);
46 
47   // P2PSocket overrides.
48   void Init(const net::IPEndPoint& local_address,
49             uint16_t min_port,
50             uint16_t max_port,
51             const P2PHostAndIPEndPoint& remote_address,
52             const net::NetworkIsolationKey& network_isolation_key) override;
53 
54   // mojom::P2PSocket implementation:
55   void Send(const std::vector<int8_t>& data,
56             const P2PPacketInfo& packet_info,
57             const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
58       override;
59   void SetOption(P2PSocketOption option, int32_t value) override;
60 
61  protected:
62   struct SendBuffer {
63     SendBuffer();
64     SendBuffer(int32_t packet_id,
65                scoped_refptr<net::DrainableIOBuffer> buffer,
66                const net::NetworkTrafficAnnotationTag traffic_annotation);
67     SendBuffer(const SendBuffer& rhs);
68     ~SendBuffer();
69 
70     int32_t rtc_packet_id;
71     scoped_refptr<net::DrainableIOBuffer> buffer;
72     net::MutableNetworkTrafficAnnotationTag traffic_annotation;
73   };
74 
75   // Derived classes will provide the implementation.
76   virtual bool ProcessInput(char* input,
77                             int input_len,
78                             size_t* bytes_consumed) = 0;
79   virtual void DoSend(
80       const net::IPEndPoint& to,
81       const std::vector<int8_t>& data,
82       const rtc::PacketOptions& options,
83       const net::NetworkTrafficAnnotationTag traffic_annotation) = 0;
84 
85   void WriteOrQueue(SendBuffer& send_buffer);
86   WARN_UNUSED_RESULT bool OnPacket(std::vector<int8_t> data);
87 
88  private:
89   friend class P2PSocketTcpTestBase;
90   friend class P2PSocketTcpServerTest;
91 
92   void DoRead();
93   void DoWrite();
94 
95   // Return |false| in case of an error. The socket is destroyed in that case,
96   // so the caller should not use |this|.
97   WARN_UNUSED_RESULT bool HandleReadResult(int result);
98   WARN_UNUSED_RESULT bool HandleWriteResult(int result);
99 
100   // Callbacks for Connect(), Read() and Write().
101   void OnConnected(int result);
102   void OnRead(int result);
103   void OnWritten(int result);
104 
105   // Helper method to send socket create message and start read.
106   void OnOpen();
107   bool DoSendSocketCreateMsg();
108 
109   P2PHostAndIPEndPoint remote_address_;
110 
111   std::unique_ptr<net::StreamSocket> socket_;
112   scoped_refptr<net::GrowableIOBuffer> read_buffer_;
113   base::queue<SendBuffer> write_queue_;
114   SendBuffer write_buffer_;
115 
116   bool write_pending_ = false;
117 
118   bool connected_ = false;
119   const P2PSocketType type_;
120   ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory_;
121 
122   DISALLOW_COPY_AND_ASSIGN(P2PSocketTcpBase);
123 };
124 
COMPONENT_EXPORT(NETWORK_SERVICE)125 class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocketTcp : public P2PSocketTcpBase {
126  public:
127   P2PSocketTcp(
128       Delegate* delegate,
129       mojo::PendingRemote<mojom::P2PSocketClient> client,
130       mojo::PendingReceiver<mojom::P2PSocket> socket,
131       P2PSocketType type,
132       ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory);
133 
134   ~P2PSocketTcp() override;
135 
136  protected:
137   bool ProcessInput(char* input,
138                     int input_len,
139                     size_t* bytes_consumed) override;
140   void DoSend(
141       const net::IPEndPoint& to,
142       const std::vector<int8_t>& data,
143       const rtc::PacketOptions& options,
144       const net::NetworkTrafficAnnotationTag traffic_annotation) override;
145 
146  private:
147   DISALLOW_COPY_AND_ASSIGN(P2PSocketTcp);
148 };
149 
150 // P2PSocketStunTcp class provides the framing of STUN messages when used
151 // with TURN. These messages will not have length at front of the packet and
152 // are padded to multiple of 4 bytes.
153 // Formatting of messages is defined in RFC5766.
COMPONENT_EXPORT(NETWORK_SERVICE)154 class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocketStunTcp
155     : public P2PSocketTcpBase {
156  public:
157   P2PSocketStunTcp(
158       Delegate* delegate,
159       mojo::PendingRemote<mojom::P2PSocketClient> client,
160       mojo::PendingReceiver<mojom::P2PSocket> socket,
161       P2PSocketType type,
162       ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory);
163 
164   ~P2PSocketStunTcp() override;
165 
166  protected:
167   bool ProcessInput(char* input,
168                     int input_len,
169                     size_t* bytes_consumed) override;
170   void DoSend(
171       const net::IPEndPoint& to,
172       const std::vector<int8_t>& data,
173       const rtc::PacketOptions& options,
174       const net::NetworkTrafficAnnotationTag traffic_annotation) override;
175 
176  private:
177   int GetExpectedPacketSize(const uint8_t* data, int len, int* pad_bytes);
178 
179   DISALLOW_COPY_AND_ASSIGN(P2PSocketStunTcp);
180 };
181 
182 }  // namespace network
183 
184 #endif  // SERVICES_NETWORK_P2P_SOCKET_TCP_H_
185