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