diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-01 23:35:42 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-01 23:35:42 +0000 |
commit | 03fd0b387c8a0d052cc565ec35f65eddcf40f64b (patch) | |
tree | 16dd61ef4ea0a5dc539a449984b2a4272b0574be /jingle | |
parent | 0ad9685912a070af01439a27d8a5b164724c947c (diff) | |
download | chromium_src-03fd0b387c8a0d052cc565ec35f65eddcf40f64b.zip chromium_src-03fd0b387c8a0d052cc565ec35f65eddcf40f64b.tar.gz chromium_src-03fd0b387c8a0d052cc565ec35f65eddcf40f64b.tar.bz2 |
Add FakeSocketFactory.
The new FakeSocketFactory will be used for P2P transport and remoting unittests. Also moved socket address conversion functions to the new jingle/glue/utils.h .
BUG=None
TEST=None
Review URL: http://codereview.chromium.org/6670134
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80242 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'jingle')
-rw-r--r-- | jingle/glue/fake_socket_factory.cc | 197 | ||||
-rw-r--r-- | jingle/glue/fake_socket_factory.h | 122 | ||||
-rw-r--r-- | jingle/glue/utils.cc | 37 | ||||
-rw-r--r-- | jingle/glue/utils.h | 28 | ||||
-rw-r--r-- | jingle/jingle.gyp | 17 |
5 files changed, 400 insertions, 1 deletions
diff --git a/jingle/glue/fake_socket_factory.cc b/jingle/glue/fake_socket_factory.cc new file mode 100644 index 0000000..b0649ce --- /dev/null +++ b/jingle/glue/fake_socket_factory.cc @@ -0,0 +1,197 @@ +// 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/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_(STATE_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( + bool* allocated) const { + DCHECK(CalledOnValidThread()); + *allocated = true; + 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_ == STATE_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_ = STATE_CLOSED; + return 0; +} + +talk_base::Socket::ConnState FakeUDPPacketSocket::GetState() const { + DCHECK(CalledOnValidThread()); + + switch (state_) { + case STATE_OPEN: + return talk_base::Socket::CS_CONNECTED; + case STATE_CLOSED: + return talk_base::Socket::CS_CLOSED; + } + + NOTREACHED(); + return talk_base::Socket::CS_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_(MessageLoop::current()) { +} + +FakeSocketManager::~FakeSocketManager() { } + +void FakeSocketManager::SendPacket(const net::IPEndPoint& from, + const net::IPEndPoint& to, + const std::vector<char>& data) { + DCHECK_EQ(MessageLoop::current(), message_loop_); + + message_loop_->PostTask( + FROM_HERE, NewRunnableMethod(this, &FakeSocketManager::DeliverPacket, + from, to, data)); +} + +void FakeSocketManager::DeliverPacket(const net::IPEndPoint& from, + const net::IPEndPoint& to, + const std::vector<char>& data) { + DCHECK_EQ(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(MessageLoop::current(), message_loop_); + + endpoints_[socket_factory->endpoint()] = socket_factory; +} + +void FakeSocketManager::RemoveSocket(FakeUDPPacketSocket* socket_factory) { + DCHECK_EQ(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_, net::IPEndPoint(address_, ++last_allocated_port_)); +} + +talk_base::AsyncPacketSocket* FakeSocketFactory::CreateServerTcpSocket( + const talk_base::SocketAddress& local_address, int min_port, int max_port, + bool listen, bool ssl) { + // 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, + bool ssl) { + // TODO(sergeyu): Implement fake TCP sockets. + NOTIMPLEMENTED(); + return NULL; +} + +} // namespace jingle_glue diff --git a/jingle/glue/fake_socket_factory.h b/jingle/glue/fake_socket_factory.h new file mode 100644 index 0000000..fee73bb --- /dev/null +++ b/jingle/glue/fake_socket_factory.h @@ -0,0 +1,122 @@ +// 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. + +#ifndef JINGLE_GLUE_FAKE_SOCKET_FACTORY_H_ +#define JINGLE_GLUE_FAKE_SOCKET_FACTORY_H_ + +#include <map> +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/threading/non_thread_safe.h" +#include "net/base/ip_endpoint.h" +#include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" +#include "third_party/libjingle/source/talk/base/packetsocketfactory.h" + +class MessageLoop; + +namespace jingle_glue { + +class FakeSocketManager; + +class FakeUDPPacketSocket : public talk_base::AsyncPacketSocket, + public base::NonThreadSafe { + public: + FakeUDPPacketSocket(FakeSocketManager* fake_socket_manager, + const net::IPEndPoint& address); + virtual ~FakeUDPPacketSocket(); + + const net::IPEndPoint& endpoint() const { return endpoint_; } + void DeliverPacket(const net::IPEndPoint& from, + const std::vector<char>& data); + + // talk_base::AsyncPacketSocket implementation. + virtual talk_base::SocketAddress GetLocalAddress( + bool* allocated) const OVERRIDE; + virtual talk_base::SocketAddress GetRemoteAddress() const OVERRIDE; + virtual int Send(const void *pv, size_t cb) OVERRIDE; + virtual int SendTo(const void *pv, size_t cb, + const talk_base::SocketAddress& addr) OVERRIDE; + virtual int Close() OVERRIDE; + virtual talk_base::Socket::ConnState GetState() const OVERRIDE; + virtual int GetOption(talk_base::Socket::Option opt, int* value) OVERRIDE; + virtual int SetOption(talk_base::Socket::Option opt, int value) OVERRIDE; + virtual int GetError() const OVERRIDE; + virtual void SetError(int error) OVERRIDE; + + private: + enum State { + STATE_OPEN, + STATE_CLOSED, + }; + + scoped_refptr<FakeSocketManager> fake_socket_manager_; + net::IPEndPoint endpoint_; + talk_base::SocketAddress local_address_; + talk_base::SocketAddress remote_address_; + State state_; + int error_; + + DISALLOW_COPY_AND_ASSIGN(FakeUDPPacketSocket); +}; + +class FakeSocketManager : public base::RefCountedThreadSafe<FakeSocketManager> { + public: + FakeSocketManager(); + + void SendPacket(const net::IPEndPoint& from, + const net::IPEndPoint& to, + const std::vector<char>& data); + + void AddSocket(FakeUDPPacketSocket* socket_factory); + void RemoveSocket(FakeUDPPacketSocket* socket_factory); + + private: + friend class base::RefCountedThreadSafe<FakeSocketManager>; + + ~FakeSocketManager(); + + void DeliverPacket(const net::IPEndPoint& from, + const net::IPEndPoint& to, + const std::vector<char>& data); + + MessageLoop* message_loop_; + std::map<net::IPEndPoint, FakeUDPPacketSocket*> endpoints_; + + DISALLOW_COPY_AND_ASSIGN(FakeSocketManager); +}; + +class FakeSocketFactory : public talk_base::PacketSocketFactory { + public: + FakeSocketFactory(FakeSocketManager* socket_manager, + const net::IPAddressNumber& address); + virtual ~FakeSocketFactory(); + + // talk_base::PacketSocketFactory implementation. + virtual talk_base::AsyncPacketSocket* CreateUdpSocket( + const talk_base::SocketAddress& local_address, + int min_port, int max_port) OVERRIDE; + virtual talk_base::AsyncPacketSocket* CreateServerTcpSocket( + const talk_base::SocketAddress& local_address, int min_port, int max_port, + bool listen, bool ssl) OVERRIDE; + virtual talk_base::AsyncPacketSocket* CreateClientTcpSocket( + const talk_base::SocketAddress& local_address, + const talk_base::SocketAddress& remote_address, + const talk_base::ProxyInfo& proxy_info, + const std::string& user_agent, + bool ssl) OVERRIDE; + + private: + scoped_refptr<FakeSocketManager> socket_manager_; + net::IPAddressNumber address_; + int last_allocated_port_; + + DISALLOW_COPY_AND_ASSIGN(FakeSocketFactory); +}; + +} // namespace jingle_glue + +#endif // JINGLE_GLUE_FAKE_SOCKET_FACTORY_H_ diff --git a/jingle/glue/utils.cc b/jingle/glue/utils.cc new file mode 100644 index 0000000..88625cf --- /dev/null +++ b/jingle/glue/utils.cc @@ -0,0 +1,37 @@ +// 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/utils.h" + +#include "base/logging.h" +#include "net/base/ip_endpoint.h" +#include "net/base/net_util.h" +#include "third_party/libjingle/source/talk/base/byteorder.h" +#include "third_party/libjingle/source/talk/base/socketaddress.h" + +namespace jingle_glue { + +bool IPEndPointToSocketAddress(const net::IPEndPoint& address_chrome, + talk_base::SocketAddress* address_lj) { + if (address_chrome.GetFamily() != AF_INET) { + LOG(ERROR) << "Only IPv4 addresses are supported."; + return false; + } + uint32 ip_as_int = talk_base::NetworkToHost32( + *reinterpret_cast<const uint32*>(&address_chrome.address()[0])); + *address_lj = talk_base::SocketAddress(ip_as_int, address_chrome.port()); + return true; +} + +bool SocketAddressToIPEndPoint(const talk_base::SocketAddress& address_lj, + net::IPEndPoint* address_chrome) { + uint32 ip = talk_base::HostToNetwork32(address_lj.ip()); + net::IPAddressNumber address; + address.resize(net::kIPv4AddressSize); + memcpy(&address[0], &ip, net::kIPv4AddressSize); + *address_chrome = net::IPEndPoint(address, address_lj.port()); + return true; +} + +} // namespace jingle_glue diff --git a/jingle/glue/utils.h b/jingle/glue/utils.h new file mode 100644 index 0000000..895cf2c --- /dev/null +++ b/jingle/glue/utils.h @@ -0,0 +1,28 @@ +// 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. + +#ifndef JINGLE_GLUE_UTILS_H_ +#define JINGLE_GLUE_UTILS_H_ + +namespace net { +class IPEndPoint; +} // namespace net + +namespace talk_base { + class SocketAddress; +} // namespace talk_base + +namespace jingle_glue { + +// Chromium and libjingle represent socket addresses differently. The +// following two functions are used to convert addresses from one +// representation to another. +bool IPEndPointToSocketAddress(const net::IPEndPoint& address_chrome, + talk_base::SocketAddress* address_lj); +bool SocketAddressToIPEndPoint(const talk_base::SocketAddress& address_lj, + net::IPEndPoint* address_chrome); + +} // namespace jingle_glue + +#endif // JINGLE_GLUE_UTILS_H_ diff --git a/jingle/jingle.gyp b/jingle/jingle.gyp index f7f7f85..29c6c82 100644 --- a/jingle/jingle.gyp +++ b/jingle/jingle.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2010 The Chromium Authors. All rights reserved. +# 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. @@ -18,6 +18,8 @@ 'glue/stream_socket_adapter.h', 'glue/thread_wrapper.cc', 'glue/thread_wrapper.h', + 'glue/utils.cc', + 'glue/utils.h', ], 'dependencies': [ '../base/base.gyp:base', @@ -123,6 +125,18 @@ ], }, { + 'target_name': 'jingle_glue_test_util', + 'type': '<(library)', + 'sources': [ + 'glue/fake_socket_factory.cc', + 'glue/fake_socket_factory.h', + ], + 'dependencies': [ + 'jingle_glue', + '../base/base.gyp:base', + ], + }, + { 'target_name': 'jingle_unittests', 'type': 'executable', 'sources': [ @@ -149,6 +163,7 @@ ], 'dependencies': [ 'jingle_glue', + 'jingle_glue_test_util', 'notifier', 'notifier_test_util', '../base/base.gyp:base', |