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.
5 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
10 #include "base/logging.h"
11 #include "base/sys_byteorder.h"
12 #include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
13 #include "content/browser/renderer_host/p2p/socket_host_throttler.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/ip_endpoint.h"
16 #include "net/base/net_errors.h"
17 #include "net/udp/datagram_server_socket.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/libjingle/source/talk/base/timing.h"
23 using ::testing::DeleteArg;
24 using ::testing::DoAll;
25 using ::testing::Return;
29 class FakeTiming : public talk_base::Timing {
31 FakeTiming() : now_(0.0) {}
32 virtual double TimerNow() OVERRIDE { return now_; }
33 void set_now(double now) { now_ = now; }
39 class FakeDatagramServerSocket : public net::DatagramServerSocket {
41 typedef std::pair<net::IPEndPoint, std::vector<char> > UDPPacket;
43 // P2PSocketHostUdp destroyes a socket on errors so sent packets
44 // need to be stored outside of this object.
45 explicit FakeDatagramServerSocket(std::deque<UDPPacket>* sent_packets)
46 : sent_packets_(sent_packets) {
49 virtual void Close() OVERRIDE {
52 virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE {
54 return net::ERR_SOCKET_NOT_CONNECTED;
57 virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE {
62 virtual int Listen(const net::IPEndPoint& address) OVERRIDE {
67 virtual int RecvFrom(net::IOBuffer* buf, int buf_len,
68 net::IPEndPoint* address,
69 const net::CompletionCallback& callback) OVERRIDE {
70 CHECK(recv_callback_.is_null());
71 if (incoming_packets_.size() > 0) {
72 scoped_refptr<net::IOBuffer> buffer(buf);
74 static_cast<int>(incoming_packets_.front().second.size()), buf_len);
75 memcpy(buffer->data(), &*incoming_packets_.front().second.begin(), size);
76 *address = incoming_packets_.front().first;
77 incoming_packets_.pop_front();
80 recv_callback_ = callback;
83 recv_address_ = address;
84 return net::ERR_IO_PENDING;
88 virtual int SendTo(net::IOBuffer* buf, int buf_len,
89 const net::IPEndPoint& address,
90 const net::CompletionCallback& callback) OVERRIDE {
91 scoped_refptr<net::IOBuffer> buffer(buf);
92 std::vector<char> data_vector(buffer->data(), buffer->data() + buf_len);
93 sent_packets_->push_back(UDPPacket(address, data_vector));
97 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE {
101 virtual bool SetSendBufferSize(int32 size) OVERRIDE {
105 void ReceivePacket(const net::IPEndPoint& address, std::vector<char> data) {
106 if (!recv_callback_.is_null()) {
107 int size = std::min(recv_size_, static_cast<int>(data.size()));
108 memcpy(recv_buffer_->data(), &*data.begin(), size);
109 *recv_address_ = address;
110 net::CompletionCallback cb = recv_callback_;
111 recv_callback_.Reset();
115 incoming_packets_.push_back(UDPPacket(address, data));
119 virtual const net::BoundNetLog& NetLog() const OVERRIDE {
123 virtual void AllowAddressReuse() OVERRIDE {
127 virtual void AllowBroadcast() OVERRIDE {
131 virtual int JoinGroup(
132 const net::IPAddressNumber& group_address) const OVERRIDE {
134 return net::ERR_NOT_IMPLEMENTED;
137 virtual int LeaveGroup(
138 const net::IPAddressNumber& group_address) const OVERRIDE {
140 return net::ERR_NOT_IMPLEMENTED;
143 virtual int SetMulticastTimeToLive(int time_to_live) OVERRIDE {
145 return net::ERR_NOT_IMPLEMENTED;
148 virtual int SetMulticastLoopbackMode(bool loopback) OVERRIDE {
150 return net::ERR_NOT_IMPLEMENTED;
153 virtual int SetDiffServCodePoint(net::DiffServCodePoint dscp) OVERRIDE {
155 return net::ERR_NOT_IMPLEMENTED;
159 net::IPEndPoint address_;
160 std::deque<UDPPacket>* sent_packets_;
161 std::deque<UDPPacket> incoming_packets_;
162 net::BoundNetLog net_log_;
164 scoped_refptr<net::IOBuffer> recv_buffer_;
165 net::IPEndPoint* recv_address_;
167 net::CompletionCallback recv_callback_;
174 class P2PSocketHostUdpTest : public testing::Test {
176 virtual void SetUp() OVERRIDE {
177 EXPECT_CALL(sender_, Send(
178 MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID))))
179 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
181 socket_host_.reset(new P2PSocketHostUdp(&sender_, 0, &throttler_));
182 socket_ = new FakeDatagramServerSocket(&sent_packets_);
183 socket_host_->socket_.reset(socket_);
185 local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1);
186 socket_host_->Init(local_address_, net::IPEndPoint());
188 dest1_ = ParseAddress(kTestIpAddress1, kTestPort1);
189 dest2_ = ParseAddress(kTestIpAddress2, kTestPort2);
191 scoped_ptr<talk_base::Timing> timing(new FakeTiming());
192 throttler_.SetTiming(timing.Pass());
195 P2PMessageThrottler throttler_;
196 std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets_;
197 FakeDatagramServerSocket* socket_; // Owned by |socket_host_|.
198 scoped_ptr<P2PSocketHostUdp> socket_host_;
199 MockIPCSender sender_;
201 net::IPEndPoint local_address_;
203 net::IPEndPoint dest1_;
204 net::IPEndPoint dest2_;
207 // Verify that we can send STUN messages before we receive anything
208 // from the other side.
209 TEST_F(P2PSocketHostUdpTest, SendStunNoAuth) {
210 EXPECT_CALL(sender_, Send(
211 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
213 .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
215 std::vector<char> packet1;
216 CreateStunRequest(&packet1);
217 socket_host_->Send(dest1_, packet1, net::DSCP_NO_CHANGE, 0);
219 std::vector<char> packet2;
220 CreateStunResponse(&packet2);
221 socket_host_->Send(dest1_, packet2, net::DSCP_NO_CHANGE, 0);
223 std::vector<char> packet3;
224 CreateStunError(&packet3);
225 socket_host_->Send(dest1_, packet3, net::DSCP_NO_CHANGE, 0);
227 ASSERT_EQ(sent_packets_.size(), 3U);
228 ASSERT_EQ(sent_packets_[0].second, packet1);
229 ASSERT_EQ(sent_packets_[1].second, packet2);
230 ASSERT_EQ(sent_packets_[2].second, packet3);
233 // Verify that no data packets can be sent before STUN binding has
235 TEST_F(P2PSocketHostUdpTest, SendDataNoAuth) {
236 EXPECT_CALL(sender_, Send(
237 MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
238 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
240 std::vector<char> packet;
241 CreateRandomPacket(&packet);
242 socket_host_->Send(dest1_, packet, net::DSCP_NO_CHANGE, 0);
244 ASSERT_EQ(sent_packets_.size(), 0U);
247 // Verify that we can send data after we've received STUN request
248 // from the other side.
249 TEST_F(P2PSocketHostUdpTest, SendAfterStunRequest) {
250 // Receive packet from |dest1_|.
251 std::vector<char> request_packet;
252 CreateStunRequest(&request_packet);
254 EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
255 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
256 socket_->ReceivePacket(dest1_, request_packet);
258 // Now we should be able to send any data to |dest1_|.
259 EXPECT_CALL(sender_, Send(
260 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
261 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
262 std::vector<char> packet;
263 CreateRandomPacket(&packet);
264 socket_host_->Send(dest1_, packet, net::DSCP_NO_CHANGE, 0);
266 ASSERT_EQ(1U, sent_packets_.size());
267 ASSERT_EQ(dest1_, sent_packets_[0].first);
270 // Verify that we can send data after we've received STUN response
271 // from the other side.
272 TEST_F(P2PSocketHostUdpTest, SendAfterStunResponse) {
273 // Receive packet from |dest1_|.
274 std::vector<char> request_packet;
275 CreateStunRequest(&request_packet);
277 EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
278 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
279 socket_->ReceivePacket(dest1_, request_packet);
281 // Now we should be able to send any data to |dest1_|.
282 EXPECT_CALL(sender_, Send(
283 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
284 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
285 std::vector<char> packet;
286 CreateRandomPacket(&packet);
287 socket_host_->Send(dest1_, packet, net::DSCP_NO_CHANGE, 0);
289 ASSERT_EQ(1U, sent_packets_.size());
290 ASSERT_EQ(dest1_, sent_packets_[0].first);
293 // Verify messages still cannot be sent to an unathorized host after
294 // successful binding with different host.
295 TEST_F(P2PSocketHostUdpTest, SendAfterStunResponseDifferentHost) {
296 // Receive packet from |dest1_|.
297 std::vector<char> request_packet;
298 CreateStunRequest(&request_packet);
300 EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
301 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
302 socket_->ReceivePacket(dest1_, request_packet);
304 // Should fail when trying to send the same packet to |dest2_|.
305 std::vector<char> packet;
306 CreateRandomPacket(&packet);
307 EXPECT_CALL(sender_, Send(
308 MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID))))
309 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
310 socket_host_->Send(dest2_, packet, net::DSCP_NO_CHANGE, 0);
313 // Verify throttler not allowing unlimited sending of ICE messages to
315 TEST_F(P2PSocketHostUdpTest, ThrottleAfterLimit) {
316 EXPECT_CALL(sender_, Send(
317 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
319 .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
321 std::vector<char> packet1;
322 CreateStunRequest(&packet1);
323 throttler_.SetSendIceBandwidth(packet1.size() * 2);
324 socket_host_->Send(dest1_, packet1, net::DSCP_NO_CHANGE, 0);
325 socket_host_->Send(dest2_, packet1, net::DSCP_NO_CHANGE, 0);
327 net::IPEndPoint dest3 = ParseAddress(kTestIpAddress1, 2222);
328 // This packet must be dropped by the throttler.
329 socket_host_->Send(dest3, packet1, net::DSCP_NO_CHANGE, 0);
330 ASSERT_EQ(sent_packets_.size(), 2U);
333 // Verify we can send packets to a known destination when ICE throttling is
335 TEST_F(P2PSocketHostUdpTest, ThrottleAfterLimitAfterReceive) {
336 // Receive packet from |dest1_|.
337 std::vector<char> request_packet;
338 CreateStunRequest(&request_packet);
340 EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
341 .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
342 socket_->ReceivePacket(dest1_, request_packet);
344 EXPECT_CALL(sender_, Send(
345 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
347 .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
349 std::vector<char> packet1;
350 CreateStunRequest(&packet1);
351 throttler_.SetSendIceBandwidth(packet1.size());
352 // |dest1_| is known address, throttling will not be applied.
353 socket_host_->Send(dest1_, packet1, net::DSCP_NO_CHANGE, 0);
354 // Trying to send the packet to dest1_ in the same window. It should go.
355 socket_host_->Send(dest1_, packet1, net::DSCP_NO_CHANGE, 0);
357 // Throttler should allow this packet to go through.
358 socket_host_->Send(dest2_, packet1, net::DSCP_NO_CHANGE, 0);
360 net::IPEndPoint dest3 = ParseAddress(kTestIpAddress1, 2223);
361 // This packet will be dropped, as limit only for a single packet.
362 socket_host_->Send(dest3, packet1, net::DSCP_NO_CHANGE, 0);
363 net::IPEndPoint dest4 = ParseAddress(kTestIpAddress1, 2224);
364 // This packet should also be dropped.
365 socket_host_->Send(dest4, packet1, net::DSCP_NO_CHANGE, 0);
366 // |dest1| is known, we can send as many packets to it.
367 socket_host_->Send(dest1_, packet1, net::DSCP_NO_CHANGE, 0);
368 ASSERT_EQ(sent_packets_.size(), 4U);
371 } // namespace content