diff options
Diffstat (limited to 'chromium/jingle/glue/fake_socket_factory.cc')
-rw-r--r-- | chromium/jingle/glue/fake_socket_factory.cc | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/chromium/jingle/glue/fake_socket_factory.cc b/chromium/jingle/glue/fake_socket_factory.cc new file mode 100644 index 00000000000..c5465a6f02a --- /dev/null +++ b/chromium/jingle/glue/fake_socket_factory.cc @@ -0,0 +1,195 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "jingle/glue/fake_socket_factory.h" + +#include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "jingle/glue/utils.h" +#include "third_party/libjingle/source/talk/base/asyncsocket.h" + +namespace jingle_glue { + +FakeUDPPacketSocket::FakeUDPPacketSocket(FakeSocketManager* fake_socket_manager, + const net::IPEndPoint& address) + : fake_socket_manager_(fake_socket_manager), + endpoint_(address), state_(IS_OPEN), error_(0) { + CHECK(IPEndPointToSocketAddress(endpoint_, &local_address_)); + fake_socket_manager_->AddSocket(this); +} + +FakeUDPPacketSocket::~FakeUDPPacketSocket() { + fake_socket_manager_->RemoveSocket(this); +} + +talk_base::SocketAddress FakeUDPPacketSocket::GetLocalAddress() const { + DCHECK(CalledOnValidThread()); + return local_address_; +} + +talk_base::SocketAddress FakeUDPPacketSocket::GetRemoteAddress() const { + DCHECK(CalledOnValidThread()); + return remote_address_; +} + +int FakeUDPPacketSocket::Send(const void *data, size_t data_size) { + DCHECK(CalledOnValidThread()); + return SendTo(data, data_size, remote_address_); +} + +int FakeUDPPacketSocket::SendTo(const void *data, size_t data_size, + const talk_base::SocketAddress& address) { + DCHECK(CalledOnValidThread()); + + if (state_ == IS_CLOSED) { + return ENOTCONN; + } + + net::IPEndPoint destination; + if (!SocketAddressToIPEndPoint(address, &destination)) { + return EINVAL; + } + + const char* data_char = reinterpret_cast<const char*>(data); + std::vector<char> data_vector(data_char, data_char + data_size); + + fake_socket_manager_->SendPacket(endpoint_, destination, data_vector); + + return data_size; +} + +int FakeUDPPacketSocket::Close() { + DCHECK(CalledOnValidThread()); + state_ = IS_CLOSED; + return 0; +} + +talk_base::AsyncPacketSocket::State FakeUDPPacketSocket::GetState() const { + DCHECK(CalledOnValidThread()); + + switch (state_) { + case IS_OPEN: + return STATE_BOUND; + case IS_CLOSED: + return STATE_CLOSED; + } + + NOTREACHED(); + return STATE_CLOSED; +} + +int FakeUDPPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) { + DCHECK(CalledOnValidThread()); + return -1; +} + +int FakeUDPPacketSocket::SetOption(talk_base::Socket::Option opt, int value) { + DCHECK(CalledOnValidThread()); + return -1; +} + +int FakeUDPPacketSocket::GetError() const { + DCHECK(CalledOnValidThread()); + return error_; +} + +void FakeUDPPacketSocket::SetError(int error) { + DCHECK(CalledOnValidThread()); + error_ = error; +} + +void FakeUDPPacketSocket::DeliverPacket(const net::IPEndPoint& from, + const std::vector<char>& data) { + DCHECK(CalledOnValidThread()); + + talk_base::SocketAddress address; + if (!jingle_glue::IPEndPointToSocketAddress(from, &address)) { + // We should always be able to convert address here because we + // don't expect IPv6 address on IPv4 connections. + NOTREACHED(); + return; + } + + SignalReadPacket(this, &data[0], data.size(), address); +} + +FakeSocketManager::FakeSocketManager() + : message_loop_(base::MessageLoop::current()) {} + +FakeSocketManager::~FakeSocketManager() { } + +void FakeSocketManager::SendPacket(const net::IPEndPoint& from, + const net::IPEndPoint& to, + const std::vector<char>& data) { + DCHECK_EQ(base::MessageLoop::current(), message_loop_); + + message_loop_->PostTask( + FROM_HERE, + base::Bind(&FakeSocketManager::DeliverPacket, this, from, to, data)); +} + +void FakeSocketManager::DeliverPacket(const net::IPEndPoint& from, + const net::IPEndPoint& to, + const std::vector<char>& data) { + DCHECK_EQ(base::MessageLoop::current(), message_loop_); + + std::map<net::IPEndPoint, FakeUDPPacketSocket*>::iterator it = + endpoints_.find(to); + if (it == endpoints_.end()) { + LOG(WARNING) << "Dropping packet with unknown destination: " + << to.ToString(); + return; + } + it->second->DeliverPacket(from, data); +} + +void FakeSocketManager::AddSocket(FakeUDPPacketSocket* socket_factory) { + DCHECK_EQ(base::MessageLoop::current(), message_loop_); + + endpoints_[socket_factory->endpoint()] = socket_factory; +} + +void FakeSocketManager::RemoveSocket(FakeUDPPacketSocket* socket_factory) { + DCHECK_EQ(base::MessageLoop::current(), message_loop_); + + endpoints_.erase(socket_factory->endpoint()); +} + +FakeSocketFactory::FakeSocketFactory(FakeSocketManager* socket_manager, + const net::IPAddressNumber& address) + : socket_manager_(socket_manager), + address_(address), + last_allocated_port_(0) { +} + +FakeSocketFactory::~FakeSocketFactory() { +} + +talk_base::AsyncPacketSocket* FakeSocketFactory::CreateUdpSocket( + const talk_base::SocketAddress& local_address, int min_port, int max_port) { + CHECK_EQ(min_port, 0); + CHECK_EQ(max_port, 0); + return new FakeUDPPacketSocket( + socket_manager_.get(), net::IPEndPoint(address_, ++last_allocated_port_)); +} + +talk_base::AsyncPacketSocket* FakeSocketFactory::CreateServerTcpSocket( + const talk_base::SocketAddress& local_address, int min_port, int max_port, + int opts) { + // TODO(sergeyu): Implement fake TCP sockets. + NOTIMPLEMENTED(); + return NULL; +} + +talk_base::AsyncPacketSocket* FakeSocketFactory::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) { + // TODO(sergeyu): Implement fake TCP sockets. + NOTIMPLEMENTED(); + return NULL; +} + +} // namespace jingle_glue |