summaryrefslogtreecommitdiffstats
path: root/jingle
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-01 23:35:42 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-01 23:35:42 +0000
commit03fd0b387c8a0d052cc565ec35f65eddcf40f64b (patch)
tree16dd61ef4ea0a5dc539a449984b2a4272b0574be /jingle
parent0ad9685912a070af01439a27d8a5b164724c947c (diff)
downloadchromium_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.cc197
-rw-r--r--jingle/glue/fake_socket_factory.h122
-rw-r--r--jingle/glue/utils.cc37
-rw-r--r--jingle/glue/utils.h28
-rw-r--r--jingle/jingle.gyp17
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',