OLD | NEW |
| (Empty) |
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 | |
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 | |
23 FakeUDPPacketSocket::~FakeUDPPacketSocket() { | |
24 fake_socket_manager_->RemoveSocket(this); | |
25 } | |
26 | |
27 talk_base::SocketAddress FakeUDPPacketSocket::GetLocalAddress() const { | |
28 DCHECK(CalledOnValidThread()); | |
29 return local_address_; | |
30 } | |
31 | |
32 talk_base::SocketAddress FakeUDPPacketSocket::GetRemoteAddress() const { | |
33 DCHECK(CalledOnValidThread()); | |
34 return remote_address_; | |
35 } | |
36 | |
37 int FakeUDPPacketSocket::Send(const void *data, size_t data_size, | |
38 const talk_base::PacketOptions& options) { | |
39 DCHECK(CalledOnValidThread()); | |
40 return SendTo(data, data_size, remote_address_, options); | |
41 } | |
42 | |
43 int FakeUDPPacketSocket::SendTo(const void *data, size_t data_size, | |
44 const talk_base::SocketAddress& address, | |
45 const talk_base::PacketOptions& options) { | |
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 | |
65 int FakeUDPPacketSocket::Close() { | |
66 DCHECK(CalledOnValidThread()); | |
67 state_ = IS_CLOSED; | |
68 return 0; | |
69 } | |
70 | |
71 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 | |
85 int FakeUDPPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) { | |
86 DCHECK(CalledOnValidThread()); | |
87 return -1; | |
88 } | |
89 | |
90 int FakeUDPPacketSocket::SetOption(talk_base::Socket::Option opt, int value) { | |
91 DCHECK(CalledOnValidThread()); | |
92 return -1; | |
93 } | |
94 | |
95 int FakeUDPPacketSocket::GetError() const { | |
96 DCHECK(CalledOnValidThread()); | |
97 return error_; | |
98 } | |
99 | |
100 void FakeUDPPacketSocket::SetError(int error) { | |
101 DCHECK(CalledOnValidThread()); | |
102 error_ = error; | |
103 } | |
104 | |
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 | |
121 FakeSocketManager::FakeSocketManager() | |
122 : message_loop_(base::MessageLoop::current()) {} | |
123 | |
124 FakeSocketManager::~FakeSocketManager() { } | |
125 | |
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 | |
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 | |
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 | |
157 void FakeSocketManager::RemoveSocket(FakeUDPPacketSocket* socket_factory) { | |
158 DCHECK_EQ(base::MessageLoop::current(), message_loop_); | |
159 | |
160 endpoints_.erase(socket_factory->endpoint()); | |
161 } | |
162 | |
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 | |
170 FakeSocketFactory::~FakeSocketFactory() { | |
171 } | |
172 | |
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 | |
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 | |
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 | |
OLD | NEW |