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.
5 #include "jingle/glue/fake_socket_factory.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"
13 namespace jingle_glue
{
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);
23 FakeUDPPacketSocket::~FakeUDPPacketSocket() {
24 fake_socket_manager_
->RemoveSocket(this);
27 talk_base::SocketAddress
FakeUDPPacketSocket::GetLocalAddress() const {
28 DCHECK(CalledOnValidThread());
29 return local_address_
;
32 talk_base::SocketAddress
FakeUDPPacketSocket::GetRemoteAddress() const {
33 DCHECK(CalledOnValidThread());
34 return remote_address_
;
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
);
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());
48 if (state_
== IS_CLOSED
) {
52 net::IPEndPoint destination
;
53 if (!SocketAddressToIPEndPoint(address
, &destination
)) {
57 const char* data_char
= reinterpret_cast<const char*>(data
);
58 std::vector
<char> data_vector(data_char
, data_char
+ data_size
);
60 fake_socket_manager_
->SendPacket(endpoint_
, destination
, data_vector
);
65 int FakeUDPPacketSocket::Close() {
66 DCHECK(CalledOnValidThread());
71 talk_base::AsyncPacketSocket::State
FakeUDPPacketSocket::GetState() const {
72 DCHECK(CalledOnValidThread());
85 int FakeUDPPacketSocket::GetOption(talk_base::Socket::Option opt
, int* value
) {
86 DCHECK(CalledOnValidThread());
90 int FakeUDPPacketSocket::SetOption(talk_base::Socket::Option opt
, int value
) {
91 DCHECK(CalledOnValidThread());
95 int FakeUDPPacketSocket::GetError() const {
96 DCHECK(CalledOnValidThread());
100 void FakeUDPPacketSocket::SetError(int error
) {
101 DCHECK(CalledOnValidThread());
105 void FakeUDPPacketSocket::DeliverPacket(const net::IPEndPoint
& from
,
106 const std::vector
<char>& data
) {
107 DCHECK(CalledOnValidThread());
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.
117 SignalReadPacket(this, &data
[0], data
.size(), address
,
118 talk_base::CreatePacketTime(0));
121 FakeSocketManager::FakeSocketManager()
122 : message_loop_(base::MessageLoop::current()) {}
124 FakeSocketManager::~FakeSocketManager() { }
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_
);
131 message_loop_
->PostTask(
133 base::Bind(&FakeSocketManager::DeliverPacket
, this, from
, to
, 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_
);
141 std::map
<net::IPEndPoint
, FakeUDPPacketSocket
*>::iterator it
=
143 if (it
== endpoints_
.end()) {
144 LOG(WARNING
) << "Dropping packet with unknown destination: "
148 it
->second
->DeliverPacket(from
, data
);
151 void FakeSocketManager::AddSocket(FakeUDPPacketSocket
* socket_factory
) {
152 DCHECK_EQ(base::MessageLoop::current(), message_loop_
);
154 endpoints_
[socket_factory
->endpoint()] = socket_factory
;
157 void FakeSocketManager::RemoveSocket(FakeUDPPacketSocket
* socket_factory
) {
158 DCHECK_EQ(base::MessageLoop::current(), message_loop_
);
160 endpoints_
.erase(socket_factory
->endpoint());
163 FakeSocketFactory::FakeSocketFactory(FakeSocketManager
* socket_manager
,
164 const net::IPAddressNumber
& address
)
165 : socket_manager_(socket_manager
),
167 last_allocated_port_(0) {
170 FakeSocketFactory::~FakeSocketFactory() {
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_
));
181 talk_base::AsyncPacketSocket
* FakeSocketFactory::CreateServerTcpSocket(
182 const talk_base::SocketAddress
& local_address
, int min_port
, int max_port
,
184 // TODO(sergeyu): Implement fake TCP sockets.
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
,
194 // TODO(sergeyu): Implement fake TCP sockets.
199 } // namespace jingle_glue