• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "jingle/glue/fake_socket_factory.h"
6 
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "jingle/glue/utils.h"
10 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
11 #include "third_party/libjingle/source/talk/base/asyncsocket.h"
12 
13 namespace jingle_glue {
14 
FakeUDPPacketSocket(FakeSocketManager * fake_socket_manager,const net::IPEndPoint & address)15 FakeUDPPacketSocket::FakeUDPPacketSocket(FakeSocketManager* fake_socket_manager,
16                                          const net::IPEndPoint& address)
17     : fake_socket_manager_(fake_socket_manager),
18       endpoint_(address), state_(IS_OPEN), error_(0) {
19   CHECK(IPEndPointToSocketAddress(endpoint_, &local_address_));
20   fake_socket_manager_->AddSocket(this);
21 }
22 
~FakeUDPPacketSocket()23 FakeUDPPacketSocket::~FakeUDPPacketSocket() {
24   fake_socket_manager_->RemoveSocket(this);
25 }
26 
GetLocalAddress() const27 talk_base::SocketAddress FakeUDPPacketSocket::GetLocalAddress() const {
28   DCHECK(CalledOnValidThread());
29   return local_address_;
30 }
31 
GetRemoteAddress() const32 talk_base::SocketAddress FakeUDPPacketSocket::GetRemoteAddress() const {
33   DCHECK(CalledOnValidThread());
34   return remote_address_;
35 }
36 
Send(const void * data,size_t data_size,talk_base::DiffServCodePoint dscp)37 int FakeUDPPacketSocket::Send(const void *data, size_t data_size,
38                               talk_base::DiffServCodePoint dscp) {
39   DCHECK(CalledOnValidThread());
40   return SendTo(data, data_size, remote_address_, dscp);
41 }
42 
SendTo(const void * data,size_t data_size,const talk_base::SocketAddress & address,talk_base::DiffServCodePoint dscp)43 int FakeUDPPacketSocket::SendTo(const void *data, size_t data_size,
44                                 const talk_base::SocketAddress& address,
45                                 talk_base::DiffServCodePoint dscp) {
46   DCHECK(CalledOnValidThread());
47 
48   if (state_ == IS_CLOSED) {
49     return ENOTCONN;
50   }
51 
52   net::IPEndPoint destination;
53   if (!SocketAddressToIPEndPoint(address, &destination)) {
54     return EINVAL;
55   }
56 
57   const char* data_char = reinterpret_cast<const char*>(data);
58   std::vector<char> data_vector(data_char, data_char + data_size);
59 
60   fake_socket_manager_->SendPacket(endpoint_, destination, data_vector);
61 
62   return data_size;
63 }
64 
Close()65 int FakeUDPPacketSocket::Close() {
66   DCHECK(CalledOnValidThread());
67   state_ = IS_CLOSED;
68   return 0;
69 }
70 
GetState() const71 talk_base::AsyncPacketSocket::State FakeUDPPacketSocket::GetState() const {
72   DCHECK(CalledOnValidThread());
73 
74   switch (state_) {
75     case IS_OPEN:
76       return STATE_BOUND;
77     case IS_CLOSED:
78       return STATE_CLOSED;
79   }
80 
81   NOTREACHED();
82   return STATE_CLOSED;
83 }
84 
GetOption(talk_base::Socket::Option opt,int * value)85 int FakeUDPPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) {
86   DCHECK(CalledOnValidThread());
87   return -1;
88 }
89 
SetOption(talk_base::Socket::Option opt,int value)90 int FakeUDPPacketSocket::SetOption(talk_base::Socket::Option opt, int value) {
91   DCHECK(CalledOnValidThread());
92   return -1;
93 }
94 
GetError() const95 int FakeUDPPacketSocket::GetError() const {
96   DCHECK(CalledOnValidThread());
97   return error_;
98 }
99 
SetError(int error)100 void FakeUDPPacketSocket::SetError(int error) {
101   DCHECK(CalledOnValidThread());
102   error_ = error;
103 }
104 
DeliverPacket(const net::IPEndPoint & from,const std::vector<char> & data)105 void FakeUDPPacketSocket::DeliverPacket(const net::IPEndPoint& from,
106                                         const std::vector<char>& data) {
107   DCHECK(CalledOnValidThread());
108 
109   talk_base::SocketAddress address;
110   if (!jingle_glue::IPEndPointToSocketAddress(from, &address)) {
111     // We should always be able to convert address here because we
112     // don't expect IPv6 address on IPv4 connections.
113     NOTREACHED();
114     return;
115   }
116 
117   SignalReadPacket(this, &data[0], data.size(), address,
118                    talk_base::CreatePacketTime(0));
119 }
120 
FakeSocketManager()121 FakeSocketManager::FakeSocketManager()
122     : message_loop_(base::MessageLoop::current()) {}
123 
~FakeSocketManager()124 FakeSocketManager::~FakeSocketManager() { }
125 
SendPacket(const net::IPEndPoint & from,const net::IPEndPoint & to,const std::vector<char> & data)126 void FakeSocketManager::SendPacket(const net::IPEndPoint& from,
127                                    const net::IPEndPoint& to,
128                                    const std::vector<char>& data) {
129   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
130 
131   message_loop_->PostTask(
132       FROM_HERE,
133       base::Bind(&FakeSocketManager::DeliverPacket, this, from, to, data));
134 }
135 
DeliverPacket(const net::IPEndPoint & from,const net::IPEndPoint & to,const std::vector<char> & data)136 void FakeSocketManager::DeliverPacket(const net::IPEndPoint& from,
137                                       const net::IPEndPoint& to,
138                                       const std::vector<char>& data) {
139   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
140 
141   std::map<net::IPEndPoint, FakeUDPPacketSocket*>::iterator it =
142       endpoints_.find(to);
143   if (it == endpoints_.end()) {
144     LOG(WARNING) << "Dropping packet with unknown destination: "
145                  << to.ToString();
146     return;
147   }
148   it->second->DeliverPacket(from, data);
149 }
150 
AddSocket(FakeUDPPacketSocket * socket_factory)151 void FakeSocketManager::AddSocket(FakeUDPPacketSocket* socket_factory) {
152   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
153 
154   endpoints_[socket_factory->endpoint()] = socket_factory;
155 }
156 
RemoveSocket(FakeUDPPacketSocket * socket_factory)157 void FakeSocketManager::RemoveSocket(FakeUDPPacketSocket* socket_factory) {
158   DCHECK_EQ(base::MessageLoop::current(), message_loop_);
159 
160   endpoints_.erase(socket_factory->endpoint());
161 }
162 
FakeSocketFactory(FakeSocketManager * socket_manager,const net::IPAddressNumber & address)163 FakeSocketFactory::FakeSocketFactory(FakeSocketManager* socket_manager,
164                                      const net::IPAddressNumber& address)
165     : socket_manager_(socket_manager),
166       address_(address),
167       last_allocated_port_(0) {
168 }
169 
~FakeSocketFactory()170 FakeSocketFactory::~FakeSocketFactory() {
171 }
172 
CreateUdpSocket(const talk_base::SocketAddress & local_address,int min_port,int max_port)173 talk_base::AsyncPacketSocket* FakeSocketFactory::CreateUdpSocket(
174     const talk_base::SocketAddress& local_address, int min_port, int max_port) {
175   CHECK_EQ(min_port, 0);
176   CHECK_EQ(max_port, 0);
177   return new FakeUDPPacketSocket(
178       socket_manager_.get(), net::IPEndPoint(address_, ++last_allocated_port_));
179 }
180 
CreateServerTcpSocket(const talk_base::SocketAddress & local_address,int min_port,int max_port,int opts)181 talk_base::AsyncPacketSocket* FakeSocketFactory::CreateServerTcpSocket(
182     const talk_base::SocketAddress& local_address, int min_port, int max_port,
183     int opts) {
184   // TODO(sergeyu): Implement fake TCP sockets.
185   NOTIMPLEMENTED();
186   return NULL;
187 }
188 
CreateClientTcpSocket(const talk_base::SocketAddress & local_address,const talk_base::SocketAddress & remote_address,const talk_base::ProxyInfo & proxy_info,const std::string & user_agent,int opts)189 talk_base::AsyncPacketSocket* FakeSocketFactory::CreateClientTcpSocket(
190     const talk_base::SocketAddress& local_address,
191     const talk_base::SocketAddress& remote_address,
192     const talk_base::ProxyInfo& proxy_info, const std::string& user_agent,
193     int opts) {
194   // TODO(sergeyu): Implement fake TCP sockets.
195   NOTIMPLEMENTED();
196   return NULL;
197 }
198 
199 }  // namespace jingle_glue
200