Skip to content

Commit fb71399

Browse files
SergeyUlanovJohn Abd-El-Malek
authored and
John Abd-El-Malek
committed
Reland "Cleanup lifetime handling in P2P sockets."
This is a reland of e6df634 Original change's description: > Cleanup lifetime handling in P2P sockets. > > Several fixes for P2P sockets: > 1. P2PSocketTcpBase no longer posts tasks with base::Unretained(). > 2. Previously P2P sockets were destroyed only in response to Mojo > interfaces errors. They were not destroyed on other error. Fixed > it now. > 3. Simplified TCP server socket protocol. Now the accepted socket is > passed directly in IncomingTcpConnection. > 4. Updated unittests to verify that P2P sockets are destroyed in > response to errors. > 5. Other minor cleanups, particularly moved packet dump logic to > SocketManager and removed some unittests that are not relevant > after migration to mojo. > > Bug: 877515, 877514 > Cq-Include-Trybots: luci.chromium.try:linux_mojo > Change-Id: I55276e372185c558667289a1efdfcf0421c3d7bc > Reviewed-on: https://chromium-review.googlesource.com/1189083 > Reviewed-by: Nasko Oskov <[email protected]> > Reviewed-by: John Abd-El-Malek <[email protected]> > Commit-Queue: Sergey Ulanov <[email protected]> > Cr-Commit-Position: refs/heads/master@{#588430} [email protected],[email protected] Bug: 877515, 877514,880218 Change-Id: I0cc79616b70f7900e6c551a7c91e404de2fb7dd3 Cq-Include-Trybots: luci.chromium.try:linux_mojo Reviewed-on: https://chromium-review.googlesource.com/1206338 Commit-Queue: John Abd-El-Malek <[email protected]> Reviewed-by: Sergey Ulanov <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#588887}(cherry picked from commit e07f397) Reviewed-on: https://chromium-review.googlesource.com/1207091 Reviewed-by: John Abd-El-Malek <[email protected]> Cr-Commit-Position: refs/branch-heads/3538@{#51} Cr-Branched-From: 79f7c91-refs/heads/master@{#587811}
1 parent 61a92ca commit fb71399

18 files changed

+438
-571
lines changed

content/renderer/p2p/socket_client_impl.cc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,29 +135,28 @@ void P2PSocketClientImpl::SendComplete(
135135
}
136136

137137
void P2PSocketClientImpl::IncomingTcpConnection(
138-
const net::IPEndPoint& socket_address) {
138+
const net::IPEndPoint& socket_address,
139+
network::mojom::P2PSocketPtr socket,
140+
network::mojom::P2PSocketClientRequest client_request) {
139141
DCHECK_EQ(state_, STATE_OPEN);
140142

141143
auto new_client =
142144
std::make_unique<P2PSocketClientImpl>(dispatcher_, traffic_annotation_);
143145
new_client->state_ = STATE_OPEN;
144146

145147
network::mojom::P2PSocketClientPtr socket_client;
146-
new_client->binding_.Bind(mojo::MakeRequest(&socket_client));
148+
new_client->socket_ = std::move(socket);
149+
new_client->binding_.Bind(std::move(client_request));
147150
new_client->binding_.set_connection_error_handler(base::Bind(
148151
&P2PSocketClientImpl::OnConnectionError, base::Unretained(this)));
149152

150-
socket_->AcceptIncomingTcpConnection(socket_address, std::move(socket_client),
151-
mojo::MakeRequest(&new_client->socket_));
152-
153153
DCHECK(thread_checker_.CalledOnValidThread());
154154
if (delegate_) {
155155
delegate_->OnIncomingTcpConnection(socket_address, std::move(new_client));
156156
} else {
157157
// Just close the socket if there is no delegate to accept it.
158158
new_client->Close();
159159
}
160-
161160
}
162161

163162
void P2PSocketClientImpl::DataReceived(const net::IPEndPoint& socket_address,

content/renderer/p2p/socket_client_impl.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ class P2PSocketClientImpl : public P2PSocketClient,
8787
void SocketCreated(const net::IPEndPoint& local_address,
8888
const net::IPEndPoint& remote_address) override;
8989
void SendComplete(const network::P2PSendPacketMetrics& send_metrics) override;
90-
void IncomingTcpConnection(const net::IPEndPoint& socket_address) override;
90+
void IncomingTcpConnection(
91+
const net::IPEndPoint& socket_address,
92+
network::mojom::P2PSocketPtr socket,
93+
network::mojom::P2PSocketClientRequest client_request) override;
9194
void DataReceived(const net::IPEndPoint& socket_address,
9295
const std::vector<int8_t>& data,
9396
base::TimeTicks timestamp) override;

services/network/p2p/socket.cc

Lines changed: 16 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,10 @@
99
#include "net/base/net_errors.h"
1010
#include "net/url_request/url_request_context.h"
1111
#include "net/url_request/url_request_context_getter.h"
12-
#include "services/network/p2p/socket_manager.h"
1312
#include "services/network/p2p/socket_tcp.h"
1413
#include "services/network/p2p/socket_tcp_server.h"
1514
#include "services/network/p2p/socket_udp.h"
1615
#include "services/network/proxy_resolving_client_socket_factory.h"
17-
#include "third_party/webrtc/media/base/rtputils.h"
18-
#include "third_party/webrtc/media/base/turnutils.h"
1916

2017
namespace {
2118

@@ -33,22 +30,6 @@ enum class SocketErrorCode {
3330
};
3431

3532
const uint32_t kStunMagicCookie = 0x2112A442;
36-
const size_t kMinRtcpHeaderLength = 8;
37-
const size_t kDtlsRecordHeaderLength = 13;
38-
39-
bool IsDtlsPacket(const int8_t* data, size_t length) {
40-
const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
41-
return (length >= kDtlsRecordHeaderLength && (u[0] > 19 && u[0] < 64));
42-
}
43-
44-
bool IsRtcpPacket(const int8_t* data, size_t length) {
45-
if (length < kMinRtcpHeaderLength) {
46-
return false;
47-
}
48-
49-
int type = (static_cast<uint8_t>(data[1]) & 0x7F);
50-
return (type >= 64 && type < 96);
51-
}
5233

5334
// Map the network error to SocketErrorCode for the UMA histogram.
5435
// static
@@ -79,24 +60,22 @@ static SocketErrorCode MapNetErrorToSocketErrorCode(int net_err) {
7960

8061
namespace network {
8162

82-
P2PSocket::P2PSocket(P2PSocketManager* socket_manager,
63+
P2PSocket::P2PSocket(Delegate* delegate,
8364
mojom::P2PSocketClientPtr client,
8465
mojom::P2PSocketRequest socket,
8566
ProtocolType protocol_type)
86-
: socket_manager_(socket_manager),
67+
: delegate_(delegate),
8768
client_(std::move(client)),
8869
binding_(this, std::move(socket)),
8970
state_(STATE_UNINITIALIZED),
90-
dump_incoming_rtp_packet_(false),
91-
dump_outgoing_rtp_packet_(false),
9271
protocol_type_(protocol_type),
9372
send_packets_delayed_total_(0),
9473
send_packets_total_(0),
9574
send_bytes_delayed_max_(0),
9675
send_bytes_delayed_cur_(0),
9776
weak_ptr_factory_(this) {
9877
binding_.set_connection_error_handler(
99-
base::BindOnce(&P2PSocket::OnConnectionError, base::Unretained(this)));
78+
base::BindOnce(&P2PSocket::OnError, base::Unretained(this)));
10079
}
10180

10281
P2PSocket::~P2PSocket() {
@@ -122,7 +101,7 @@ P2PSocket::~P2PSocket() {
122101

123102
// Verifies that the packet |data| has a valid STUN header.
124103
// static
125-
bool P2PSocket::GetStunPacketType(const int8_t* data,
104+
bool P2PSocket::GetStunPacketType(const uint8_t* data,
126105
int data_size,
127106
StunMessageType* type) {
128107
if (data_size < kStunHeaderSize) {
@@ -182,7 +161,7 @@ void P2PSocket::ReportSocketError(int result, const char* histogram_name) {
182161

183162
// static
184163
P2PSocket* P2PSocket::Create(
185-
P2PSocketManager* socket_manager,
164+
Delegate* delegate,
186165
mojom::P2PSocketClientPtr client,
187166
mojom::P2PSocketRequest socket,
188167
P2PSocketType type,
@@ -191,28 +170,27 @@ P2PSocket* P2PSocket::Create(
191170
P2PMessageThrottler* throttler) {
192171
switch (type) {
193172
case P2P_SOCKET_UDP:
194-
return new P2PSocketUdp(socket_manager, std::move(client),
195-
std::move(socket), throttler, net_log);
173+
return new P2PSocketUdp(delegate, std::move(client), std::move(socket),
174+
throttler, net_log);
196175
case P2P_SOCKET_TCP_SERVER:
197-
return new P2PSocketTcpServer(socket_manager, std::move(client),
176+
return new P2PSocketTcpServer(delegate, std::move(client),
198177
std::move(socket), P2P_SOCKET_TCP_CLIENT);
199178

200179
case P2P_SOCKET_STUN_TCP_SERVER:
201-
return new P2PSocketTcpServer(socket_manager, std::move(client),
180+
return new P2PSocketTcpServer(delegate, std::move(client),
202181
std::move(socket),
203182
P2P_SOCKET_STUN_TCP_CLIENT);
204183

205184
case P2P_SOCKET_TCP_CLIENT:
206185
case P2P_SOCKET_SSLTCP_CLIENT:
207186
case P2P_SOCKET_TLS_CLIENT:
208-
return new P2PSocketTcp(socket_manager, std::move(client),
209-
std::move(socket), type,
210-
proxy_resolving_socket_factory);
187+
return new P2PSocketTcp(delegate, std::move(client), std::move(socket),
188+
type, proxy_resolving_socket_factory);
211189

212190
case P2P_SOCKET_STUN_TCP_CLIENT:
213191
case P2P_SOCKET_STUN_SSLTCP_CLIENT:
214192
case P2P_SOCKET_STUN_TLS_CLIENT:
215-
return new P2PSocketStunTcp(socket_manager, std::move(client),
193+
return new P2PSocketStunTcp(delegate, std::move(client),
216194
std::move(socket), type,
217195
proxy_resolving_socket_factory);
218196
}
@@ -221,30 +199,6 @@ P2PSocket* P2PSocket::Create(
221199
return nullptr;
222200
}
223201

224-
void P2PSocket::StartRtpDump(bool incoming, bool outgoing) {
225-
DCHECK(incoming || outgoing);
226-
227-
if (incoming) {
228-
dump_incoming_rtp_packet_ = true;
229-
}
230-
231-
if (outgoing) {
232-
dump_outgoing_rtp_packet_ = true;
233-
}
234-
}
235-
236-
void P2PSocket::StopRtpDump(bool incoming, bool outgoing) {
237-
DCHECK(incoming || outgoing);
238-
239-
if (incoming) {
240-
dump_incoming_rtp_packet_ = false;
241-
}
242-
243-
if (outgoing) {
244-
dump_outgoing_rtp_packet_ = false;
245-
}
246-
}
247-
248202
mojom::P2PSocketClientPtr P2PSocket::ReleaseClientForTesting() {
249203
return std::move(client_);
250204
}
@@ -253,36 +207,6 @@ mojom::P2PSocketRequest P2PSocket::ReleaseBindingForTesting() {
253207
return binding_.Unbind();
254208
}
255209

256-
void P2PSocket::DumpRtpPacket(const int8_t* packet,
257-
size_t length,
258-
bool incoming) {
259-
if (!socket_manager_ || IsDtlsPacket(packet, length) ||
260-
IsRtcpPacket(packet, length)) {
261-
return;
262-
}
263-
264-
size_t rtp_packet_pos = 0;
265-
size_t rtp_packet_length = length;
266-
if (!cricket::UnwrapTurnPacket(reinterpret_cast<const uint8_t*>(packet),
267-
length, &rtp_packet_pos, &rtp_packet_length)) {
268-
return;
269-
}
270-
271-
packet += rtp_packet_pos;
272-
273-
size_t header_length = 0;
274-
bool valid =
275-
cricket::ValidateRtpHeader(reinterpret_cast<const uint8_t*>(packet),
276-
rtp_packet_length, &header_length);
277-
if (!valid) {
278-
NOTREACHED();
279-
return;
280-
}
281-
282-
socket_manager_->DumpPacket(packet, header_length, rtp_packet_length,
283-
incoming);
284-
}
285-
286210
void P2PSocket::IncrementDelayedPackets() {
287211
send_packets_delayed_total_++;
288212
}
@@ -303,9 +227,10 @@ void P2PSocket::DecrementDelayedBytes(uint32_t size) {
303227
DCHECK_GE(send_bytes_delayed_cur_, 0);
304228
}
305229

306-
void P2PSocket::OnConnectionError() {
307-
if (socket_manager_)
308-
socket_manager_->DestroySocket(this);
230+
void P2PSocket::OnError() {
231+
binding_.Close();
232+
client_.reset();
233+
delegate_->DestroySocket(this);
309234
}
310235

311236
} // namespace network

services/network/p2p/socket.h

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#include <stdint.h>
1010

1111
#include <memory>
12+
1213
#include "base/component_export.h"
14+
#include "base/containers/span.h"
1315
#include "base/macros.h"
1416
#include "base/memory/weak_ptr.h"
1517
#include "mojo/public/cpp/bindings/binding.h"
@@ -24,18 +26,38 @@ class NetLog;
2426
}
2527

2628
namespace network {
29+
2730
class ProxyResolvingClientSocketFactory;
28-
class P2PSocketManager;
2931
class P2PMessageThrottler;
3032

3133
// Base class for P2P sockets.
3234
class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocket : public mojom::P2PSocket {
3335
public:
36+
// Interface implemented in P2PSocketManager.
37+
class Delegate {
38+
public:
39+
Delegate() = default;
40+
41+
// Destroys |socket| and removes it from the list of sockets.
42+
virtual void DestroySocket(P2PSocket* socket) = 0;
43+
44+
// Called by P2PSocketTcpServer after a new socket is created for an
45+
// incoming connection.
46+
virtual void AddAcceptedConnection(std::unique_ptr<P2PSocket> socket) = 0;
47+
48+
// Called for each incoming/outgoing packet.
49+
virtual void DumpPacket(base::span<const uint8_t> data, bool incoming) = 0;
50+
51+
protected:
52+
virtual ~Delegate() = default;
53+
};
54+
3455
static const int kStunHeaderSize = 20;
3556
static const size_t kMaximumPacketSize = 32768;
57+
3658
// Creates P2PSocket of the specific type.
3759
static P2PSocket* Create(
38-
P2PSocketManager* socket_manager,
60+
Delegate* delegate,
3961
mojom::P2PSocketClientPtr client,
4062
mojom::P2PSocketRequest socket,
4163
P2PSocketType type,
@@ -45,7 +67,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocket : public mojom::P2PSocket {
4567

4668
~P2PSocket() override;
4769

48-
// Initalizes the socket. Returns false when initialization fails.
70+
// Initializes the socket. Returns false when initialization fails.
4971
// |min_port| and |max_port| specify the valid range of allowed ports.
5072
// |min_port| must be less than or equal to |max_port|.
5173
// If |min_port| is zero, |max_port| must also be zero and it means all ports
@@ -54,14 +76,11 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocket : public mojom::P2PSocket {
5476
// in the valid range.
5577
// If |local_address.port()| is nonzero and not in the valid range,
5678
// initialization will fail.
57-
virtual bool Init(const net::IPEndPoint& local_address,
79+
virtual void Init(const net::IPEndPoint& local_address,
5880
uint16_t min_port,
5981
uint16_t max_port,
6082
const P2PHostAndIPEndPoint& remote_address) = 0;
6183

62-
void StartRtpDump(bool incoming, bool outgoing);
63-
void StopRtpDump(bool incoming, bool outgoing);
64-
6584
mojom::P2PSocketClientPtr ReleaseClientForTesting();
6685
mojom::P2PSocketRequest ReleaseBindingForTesting();
6786

@@ -101,43 +120,41 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) P2PSocket : public mojom::P2PSocket {
101120
STATE_UNINITIALIZED,
102121
STATE_CONNECTING,
103122
STATE_OPEN,
104-
STATE_ERROR,
105123
};
106124

107-
P2PSocket(P2PSocketManager* socket_manager,
125+
P2PSocket(Delegate* delegate,
108126
mojom::P2PSocketClientPtr client,
109127
mojom::P2PSocketRequest socket,
110128
ProtocolType protocol_type);
111129

112130
// Verifies that the packet |data| has a valid STUN header. In case
113131
// of success stores type of the message in |type|.
114-
static bool GetStunPacketType(const int8_t* data,
132+
static bool GetStunPacketType(const uint8_t* data,
115133
int data_size,
116134
StunMessageType* type);
117135
static bool IsRequestOrResponse(StunMessageType type);
118136

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

121-
// Calls |socket_manager_| to record the RTP header.
122-
void DumpRtpPacket(const int8_t* packet, size_t length, bool incoming);
139+
// Should be called by subclasses on protocol errors. Closes P2PSocket and
140+
// P2PSocketClient channels and calls delegate_->DestroySocket() to
141+
// destroy the socket.
142+
void OnError();
123143

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

130-
P2PSocketManager* socket_manager_;
150+
Delegate* delegate_;
131151
mojom::P2PSocketClientPtr client_;
132152
mojo::Binding<mojom::P2PSocket> binding_;
133153
State state_;
134-
bool dump_incoming_rtp_packet_;
135-
bool dump_outgoing_rtp_packet_;
136154

137155
ProtocolType protocol_type_;
138156

139157
private:
140-
void OnConnectionError();
141158
// Track total delayed packets for calculating how many packets are
142159
// delayed by system at the end of call.
143160
uint32_t send_packets_delayed_total_;

0 commit comments

Comments
 (0)