| 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 |