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. 4 5 #include "content/browser/renderer_host/p2p/socket_host_udp.h" 6 7 #include <deque> 8 #include <vector> 9 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 "net/base/io_buffer.h" 14 #include "net/base/ip_endpoint.h" 15 #include "net/base/net_errors.h" 16 #include "net/udp/datagram_server_socket.h" 17 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 using ::testing::_; 21 using ::testing::DeleteArg; 22 using ::testing::DoAll; 23 using ::testing::Return; 24 25 namespace { 26 27 class FakeDatagramServerSocket : public net::DatagramServerSocket { 28 public: 29 typedef std::pair<net::IPEndPoint, std::vector<char> > UDPPacket; 30 31 // P2PSocketHostUdp destroyes a socket on errors so sent packets 32 // need to be stored outside of this object. 33 explicit FakeDatagramServerSocket(std::deque<UDPPacket>* sent_packets) 34 : sent_packets_(sent_packets) { 35 } 36 37 virtual void Close() OVERRIDE { 38 } 39 40 virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE { 41 NOTREACHED(); 42 return net::ERR_SOCKET_NOT_CONNECTED; 43 } 44 45 virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE { 46 *address = address_; 47 return 0; 48 } 49 50 virtual int Listen(const net::IPEndPoint& address) OVERRIDE { 51 address_ = address; 52 return 0; 53 } 54 55 virtual int RecvFrom(net::IOBuffer* buf, int buf_len, 56 net::IPEndPoint* address, 57 const net::CompletionCallback& callback) OVERRIDE { 58 CHECK(recv_callback_.is_null()); 59 if (incoming_packets_.size() > 0) { 60 scoped_refptr<net::IOBuffer> buffer(buf); 61 int size = std::min( 62 static_cast<int>(incoming_packets_.front().second.size()), buf_len); 63 memcpy(buffer->data(), &*incoming_packets_.front().second.begin(), size); 64 *address = incoming_packets_.front().first; 65 incoming_packets_.pop_front(); 66 return size; 67 } else { 68 recv_callback_ = callback; 69 recv_buffer_ = buf; 70 recv_size_ = buf_len; 71 recv_address_ = address; 72 return net::ERR_IO_PENDING; 73 } 74 } 75 76 virtual int SendTo(net::IOBuffer* buf, int buf_len, 77 const net::IPEndPoint& address, 78 const net::CompletionCallback& callback) OVERRIDE { 79 scoped_refptr<net::IOBuffer> buffer(buf); 80 std::vector<char> data_vector(buffer->data(), buffer->data() + buf_len); 81 sent_packets_->push_back(UDPPacket(address, data_vector)); 82 return buf_len; 83 } 84 85 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE { 86 return true; 87 } 88 89 virtual bool SetSendBufferSize(int32 size) OVERRIDE { 90 return true; 91 } 92 93 void ReceivePacket(const net::IPEndPoint& address, std::vector<char> data) { 94 if (!recv_callback_.is_null()) { 95 int size = std::min(recv_size_, static_cast<int>(data.size())); 96 memcpy(recv_buffer_->data(), &*data.begin(), size); 97 *recv_address_ = address; 98 net::CompletionCallback cb = recv_callback_; 99 recv_callback_.Reset(); 100 recv_buffer_ = NULL; 101 cb.Run(size); 102 } else { 103 incoming_packets_.push_back(UDPPacket(address, data)); 104 } 105 } 106 107 virtual const net::BoundNetLog& NetLog() const OVERRIDE { 108 return net_log_; 109 } 110 111 virtual void AllowAddressReuse() OVERRIDE { 112 NOTIMPLEMENTED(); 113 } 114 115 virtual void AllowBroadcast() OVERRIDE { 116 NOTIMPLEMENTED(); 117 } 118 119 virtual int JoinGroup( 120 const net::IPAddressNumber& group_address) const OVERRIDE { 121 NOTIMPLEMENTED(); 122 return net::ERR_NOT_IMPLEMENTED; 123 } 124 125 virtual int LeaveGroup( 126 const net::IPAddressNumber& group_address) const OVERRIDE { 127 NOTIMPLEMENTED(); 128 return net::ERR_NOT_IMPLEMENTED; 129 } 130 131 virtual int SetMulticastTimeToLive(int time_to_live) OVERRIDE { 132 NOTIMPLEMENTED(); 133 return net::ERR_NOT_IMPLEMENTED; 134 } 135 136 virtual int SetMulticastLoopbackMode(bool loopback) OVERRIDE { 137 NOTIMPLEMENTED(); 138 return net::ERR_NOT_IMPLEMENTED; 139 } 140 141 private: 142 net::IPEndPoint address_; 143 std::deque<UDPPacket>* sent_packets_; 144 std::deque<UDPPacket> incoming_packets_; 145 net::BoundNetLog net_log_; 146 147 scoped_refptr<net::IOBuffer> recv_buffer_; 148 net::IPEndPoint* recv_address_; 149 int recv_size_; 150 net::CompletionCallback recv_callback_; 151 }; 152 153 } // namespace 154 155 namespace content { 156 157 class P2PSocketHostUdpTest : public testing::Test { 158 protected: 159 virtual void SetUp() OVERRIDE { 160 EXPECT_CALL(sender_, Send( 161 MatchMessage(static_cast<uint32>(P2PMsg_OnSocketCreated::ID)))) 162 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 163 164 socket_host_.reset(new P2PSocketHostUdp(&sender_, 0)); 165 socket_ = new FakeDatagramServerSocket(&sent_packets_); 166 socket_host_->socket_.reset(socket_); 167 168 local_address_ = ParseAddress(kTestLocalIpAddress, kTestPort1); 169 socket_host_->Init(local_address_, net::IPEndPoint()); 170 171 dest1_ = ParseAddress(kTestIpAddress1, kTestPort1); 172 dest2_ = ParseAddress(kTestIpAddress2, kTestPort2); 173 } 174 175 std::deque<FakeDatagramServerSocket::UDPPacket> sent_packets_; 176 FakeDatagramServerSocket* socket_; // Owned by |socket_host_|. 177 scoped_ptr<P2PSocketHostUdp> socket_host_; 178 MockIPCSender sender_; 179 180 net::IPEndPoint local_address_; 181 182 net::IPEndPoint dest1_; 183 net::IPEndPoint dest2_; 184 }; 185 186 // Verify that we can send STUN messages before we receive anything 187 // from the other side. 188 TEST_F(P2PSocketHostUdpTest, SendStunNoAuth) { 189 EXPECT_CALL(sender_, Send( 190 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID)))) 191 .Times(3) 192 .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true))); 193 194 std::vector<char> packet1; 195 CreateStunRequest(&packet1); 196 socket_host_->Send(dest1_, packet1); 197 198 std::vector<char> packet2; 199 CreateStunResponse(&packet2); 200 socket_host_->Send(dest1_, packet2); 201 202 std::vector<char> packet3; 203 CreateStunError(&packet3); 204 socket_host_->Send(dest1_, packet3); 205 206 ASSERT_EQ(sent_packets_.size(), 3U); 207 ASSERT_EQ(sent_packets_[0].second, packet1); 208 ASSERT_EQ(sent_packets_[1].second, packet2); 209 ASSERT_EQ(sent_packets_[2].second, packet3); 210 } 211 212 // Verify that no data packets can be sent before STUN binding has 213 // finished. 214 TEST_F(P2PSocketHostUdpTest, SendDataNoAuth) { 215 EXPECT_CALL(sender_, Send( 216 MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID)))) 217 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 218 219 std::vector<char> packet; 220 CreateRandomPacket(&packet); 221 socket_host_->Send(dest1_, packet); 222 223 ASSERT_EQ(sent_packets_.size(), 0U); 224 } 225 226 // Verify that we can send data after we've received STUN request 227 // from the other side. 228 TEST_F(P2PSocketHostUdpTest, SendAfterStunRequest) { 229 // Receive packet from |dest1_|. 230 std::vector<char> request_packet; 231 CreateStunRequest(&request_packet); 232 233 EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet))) 234 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 235 socket_->ReceivePacket(dest1_, request_packet); 236 237 // Now we should be able to send any data to |dest1_|. 238 EXPECT_CALL(sender_, Send( 239 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID)))) 240 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 241 std::vector<char> packet; 242 CreateRandomPacket(&packet); 243 socket_host_->Send(dest1_, packet); 244 245 ASSERT_EQ(1U, sent_packets_.size()); 246 ASSERT_EQ(dest1_, sent_packets_[0].first); 247 } 248 249 // Verify that we can send data after we've received STUN response 250 // from the other side. 251 TEST_F(P2PSocketHostUdpTest, SendAfterStunResponse) { 252 // Receive packet from |dest1_|. 253 std::vector<char> request_packet; 254 CreateStunRequest(&request_packet); 255 256 EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet))) 257 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 258 socket_->ReceivePacket(dest1_, request_packet); 259 260 // Now we should be able to send any data to |dest1_|. 261 EXPECT_CALL(sender_, Send( 262 MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID)))) 263 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 264 std::vector<char> packet; 265 CreateRandomPacket(&packet); 266 socket_host_->Send(dest1_, packet); 267 268 ASSERT_EQ(1U, sent_packets_.size()); 269 ASSERT_EQ(dest1_, sent_packets_[0].first); 270 } 271 272 // Verify messages still cannot be sent to an unathorized host after 273 // successful binding with different host. 274 TEST_F(P2PSocketHostUdpTest, SendAfterStunResponseDifferentHost) { 275 // Receive packet from |dest1_|. 276 std::vector<char> request_packet; 277 CreateStunRequest(&request_packet); 278 279 EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet))) 280 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 281 socket_->ReceivePacket(dest1_, request_packet); 282 283 // Should fail when trying to send the same packet to |dest2_|. 284 std::vector<char> packet; 285 CreateRandomPacket(&packet); 286 EXPECT_CALL(sender_, Send( 287 MatchMessage(static_cast<uint32>(P2PMsg_OnError::ID)))) 288 .WillOnce(DoAll(DeleteArg<0>(), Return(true))); 289 socket_host_->Send(dest2_, packet); 290 } 291 292 } // namespace content 293