blob: 548a80caa88a1785e6355b84b0cb892d1783a63a [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/base/natsocketfactory.h"
12
13#include "webrtc/base/logging.h"
14#include "webrtc/base/natserver.h"
15#include "webrtc/base/virtualsocketserver.h"
16
17namespace rtc {
18
19// Packs the given socketaddress into the buffer in buf, in the quasi-STUN
20// format that the natserver uses.
21// Returns 0 if an invalid address is passed.
22size_t PackAddressForNAT(char* buf, size_t buf_size,
23 const SocketAddress& remote_addr) {
24 const IPAddress& ip = remote_addr.ipaddr();
25 int family = ip.family();
26 buf[0] = 0;
27 buf[1] = family;
28 // Writes the port.
Peter Boström0c4e06b2015-10-07 12:23:21 +020029 *(reinterpret_cast<uint16_t*>(&buf[2])) = HostToNetwork16(remote_addr.port());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000030 if (family == AF_INET) {
31 ASSERT(buf_size >= kNATEncodedIPv4AddressSize);
32 in_addr v4addr = ip.ipv4_address();
33 memcpy(&buf[4], &v4addr, kNATEncodedIPv4AddressSize - 4);
34 return kNATEncodedIPv4AddressSize;
35 } else if (family == AF_INET6) {
36 ASSERT(buf_size >= kNATEncodedIPv6AddressSize);
37 in6_addr v6addr = ip.ipv6_address();
38 memcpy(&buf[4], &v6addr, kNATEncodedIPv6AddressSize - 4);
39 return kNATEncodedIPv6AddressSize;
40 }
41 return 0U;
42}
43
44// Decodes the remote address from a packet that has been encoded with the nat's
45// quasi-STUN format. Returns the length of the address (i.e., the offset into
46// data where the original packet starts).
47size_t UnpackAddressFromNAT(const char* buf, size_t buf_size,
48 SocketAddress* remote_addr) {
49 ASSERT(buf_size >= 8);
50 ASSERT(buf[0] == 0);
51 int family = buf[1];
Peter Boström0c4e06b2015-10-07 12:23:21 +020052 uint16_t port =
53 NetworkToHost16(*(reinterpret_cast<const uint16_t*>(&buf[2])));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000054 if (family == AF_INET) {
55 const in_addr* v4addr = reinterpret_cast<const in_addr*>(&buf[4]);
56 *remote_addr = SocketAddress(IPAddress(*v4addr), port);
57 return kNATEncodedIPv4AddressSize;
58 } else if (family == AF_INET6) {
59 ASSERT(buf_size >= 20);
60 const in6_addr* v6addr = reinterpret_cast<const in6_addr*>(&buf[4]);
61 *remote_addr = SocketAddress(IPAddress(*v6addr), port);
62 return kNATEncodedIPv6AddressSize;
63 }
64 return 0U;
65}
66
67
68// NATSocket
69class NATSocket : public AsyncSocket, public sigslot::has_slots<> {
70 public:
71 explicit NATSocket(NATInternalSocketFactory* sf, int family, int type)
72 : sf_(sf), family_(family), type_(type), connected_(false),
73 socket_(NULL), buf_(NULL), size_(0) {
74 }
75
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000076 ~NATSocket() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000077 delete socket_;
78 delete[] buf_;
79 }
80
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000081 SocketAddress GetLocalAddress() const override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000082 return (socket_) ? socket_->GetLocalAddress() : SocketAddress();
83 }
84
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000085 SocketAddress GetRemoteAddress() const override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000086 return remote_addr_; // will be NIL if not connected
87 }
88
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000089 int Bind(const SocketAddress& addr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000090 if (socket_) { // already bound, bubble up error
91 return -1;
92 }
93
94 int result;
95 socket_ = sf_->CreateInternalSocket(family_, type_, addr, &server_addr_);
96 result = (socket_) ? socket_->Bind(addr) : -1;
97 if (result >= 0) {
98 socket_->SignalConnectEvent.connect(this, &NATSocket::OnConnectEvent);
99 socket_->SignalReadEvent.connect(this, &NATSocket::OnReadEvent);
100 socket_->SignalWriteEvent.connect(this, &NATSocket::OnWriteEvent);
101 socket_->SignalCloseEvent.connect(this, &NATSocket::OnCloseEvent);
102 } else {
103 server_addr_.Clear();
104 delete socket_;
105 socket_ = NULL;
106 }
107
108 return result;
109 }
110
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000111 int Connect(const SocketAddress& addr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000112 if (!socket_) { // socket must be bound, for now
113 return -1;
114 }
115
116 int result = 0;
117 if (type_ == SOCK_STREAM) {
118 result = socket_->Connect(server_addr_.IsNil() ? addr : server_addr_);
119 } else {
120 connected_ = true;
121 }
122
123 if (result >= 0) {
124 remote_addr_ = addr;
125 }
126
127 return result;
128 }
129
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000130 int Send(const void* data, size_t size) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000131 ASSERT(connected_);
132 return SendTo(data, size, remote_addr_);
133 }
134
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000135 int SendTo(const void* data,
136 size_t size,
137 const SocketAddress& addr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000138 ASSERT(!connected_ || addr == remote_addr_);
139 if (server_addr_.IsNil() || type_ == SOCK_STREAM) {
140 return socket_->SendTo(data, size, addr);
141 }
142 // This array will be too large for IPv4 packets, but only by 12 bytes.
143 scoped_ptr<char[]> buf(new char[size + kNATEncodedIPv6AddressSize]);
144 size_t addrlength = PackAddressForNAT(buf.get(),
145 size + kNATEncodedIPv6AddressSize,
146 addr);
147 size_t encoded_size = size + addrlength;
148 memcpy(buf.get() + addrlength, data, size);
149 int result = socket_->SendTo(buf.get(), encoded_size, server_addr_);
150 if (result >= 0) {
151 ASSERT(result == static_cast<int>(encoded_size));
152 result = result - static_cast<int>(addrlength);
153 }
154 return result;
155 }
156
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000157 int Recv(void* data, size_t size) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000158 SocketAddress addr;
159 return RecvFrom(data, size, &addr);
160 }
161
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000162 int RecvFrom(void* data, size_t size, SocketAddress* out_addr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000163 if (server_addr_.IsNil() || type_ == SOCK_STREAM) {
164 return socket_->RecvFrom(data, size, out_addr);
165 }
166 // Make sure we have enough room to read the requested amount plus the
167 // largest possible header address.
168 SocketAddress remote_addr;
169 Grow(size + kNATEncodedIPv6AddressSize);
170
171 // Read the packet from the socket.
172 int result = socket_->RecvFrom(buf_, size_, &remote_addr);
173 if (result >= 0) {
174 ASSERT(remote_addr == server_addr_);
175
176 // TODO: we need better framing so we know how many bytes we can
177 // return before we need to read the next address. For UDP, this will be
178 // fine as long as the reader always reads everything in the packet.
179 ASSERT((size_t)result < size_);
180
181 // Decode the wire packet into the actual results.
182 SocketAddress real_remote_addr;
deadbeefc5d0d952015-07-16 10:22:21 -0700183 size_t addrlength = UnpackAddressFromNAT(buf_, result, &real_remote_addr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000184 memcpy(data, buf_ + addrlength, result - addrlength);
185
186 // Make sure this packet should be delivered before returning it.
187 if (!connected_ || (real_remote_addr == remote_addr_)) {
188 if (out_addr)
189 *out_addr = real_remote_addr;
190 result = result - static_cast<int>(addrlength);
191 } else {
192 LOG(LS_ERROR) << "Dropping packet from unknown remote address: "
193 << real_remote_addr.ToString();
194 result = 0; // Tell the caller we didn't read anything
195 }
196 }
197
198 return result;
199 }
200
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000201 int Close() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000202 int result = 0;
203 if (socket_) {
204 result = socket_->Close();
205 if (result >= 0) {
206 connected_ = false;
207 remote_addr_ = SocketAddress();
208 delete socket_;
209 socket_ = NULL;
210 }
211 }
212 return result;
213 }
214
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000215 int Listen(int backlog) override { return socket_->Listen(backlog); }
216 AsyncSocket* Accept(SocketAddress* paddr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000217 return socket_->Accept(paddr);
218 }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000219 int GetError() const override { return socket_->GetError(); }
220 void SetError(int error) override { socket_->SetError(error); }
221 ConnState GetState() const override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000222 return connected_ ? CS_CONNECTED : CS_CLOSED;
223 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200224 int EstimateMTU(uint16_t* mtu) override { return socket_->EstimateMTU(mtu); }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000225 int GetOption(Option opt, int* value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000226 return socket_->GetOption(opt, value);
227 }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000228 int SetOption(Option opt, int value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000229 return socket_->SetOption(opt, value);
230 }
231
232 void OnConnectEvent(AsyncSocket* socket) {
deadbeefc5d0d952015-07-16 10:22:21 -0700233 // If we're NATed, we need to send a message with the real addr to use.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000234 ASSERT(socket == socket_);
235 if (server_addr_.IsNil()) {
236 connected_ = true;
237 SignalConnectEvent(this);
238 } else {
239 SendConnectRequest();
240 }
241 }
242 void OnReadEvent(AsyncSocket* socket) {
243 // If we're NATed, we need to process the connect reply.
244 ASSERT(socket == socket_);
245 if (type_ == SOCK_STREAM && !server_addr_.IsNil() && !connected_) {
246 HandleConnectReply();
247 } else {
248 SignalReadEvent(this);
249 }
250 }
251 void OnWriteEvent(AsyncSocket* socket) {
252 ASSERT(socket == socket_);
253 SignalWriteEvent(this);
254 }
255 void OnCloseEvent(AsyncSocket* socket, int error) {
256 ASSERT(socket == socket_);
257 SignalCloseEvent(this, error);
258 }
259
260 private:
261 // Makes sure the buffer is at least the given size.
262 void Grow(size_t new_size) {
263 if (size_ < new_size) {
264 delete[] buf_;
265 size_ = new_size;
266 buf_ = new char[size_];
267 }
268 }
269
270 // Sends the destination address to the server to tell it to connect.
271 void SendConnectRequest() {
deadbeefc5d0d952015-07-16 10:22:21 -0700272 char buf[kNATEncodedIPv6AddressSize];
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000273 size_t length = PackAddressForNAT(buf, ARRAY_SIZE(buf), remote_addr_);
274 socket_->Send(buf, length);
275 }
276
277 // Handles the byte sent back from the server and fires the appropriate event.
278 void HandleConnectReply() {
279 char code;
280 socket_->Recv(&code, sizeof(code));
281 if (code == 0) {
deadbeefc5d0d952015-07-16 10:22:21 -0700282 connected_ = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000283 SignalConnectEvent(this);
284 } else {
285 Close();
286 SignalCloseEvent(this, code);
287 }
288 }
289
290 NATInternalSocketFactory* sf_;
291 int family_;
292 int type_;
293 bool connected_;
294 SocketAddress remote_addr_;
295 SocketAddress server_addr_; // address of the NAT server
296 AsyncSocket* socket_;
297 char* buf_;
298 size_t size_;
299};
300
301// NATSocketFactory
302NATSocketFactory::NATSocketFactory(SocketFactory* factory,
deadbeefc5d0d952015-07-16 10:22:21 -0700303 const SocketAddress& nat_udp_addr,
304 const SocketAddress& nat_tcp_addr)
305 : factory_(factory), nat_udp_addr_(nat_udp_addr),
306 nat_tcp_addr_(nat_tcp_addr) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000307}
308
309Socket* NATSocketFactory::CreateSocket(int type) {
310 return CreateSocket(AF_INET, type);
311}
312
313Socket* NATSocketFactory::CreateSocket(int family, int type) {
314 return new NATSocket(this, family, type);
315}
316
317AsyncSocket* NATSocketFactory::CreateAsyncSocket(int type) {
318 return CreateAsyncSocket(AF_INET, type);
319}
320
321AsyncSocket* NATSocketFactory::CreateAsyncSocket(int family, int type) {
322 return new NATSocket(this, family, type);
323}
324
325AsyncSocket* NATSocketFactory::CreateInternalSocket(int family, int type,
326 const SocketAddress& local_addr, SocketAddress* nat_addr) {
deadbeefc5d0d952015-07-16 10:22:21 -0700327 if (type == SOCK_STREAM) {
328 *nat_addr = nat_tcp_addr_;
329 } else {
330 *nat_addr = nat_udp_addr_;
331 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000332 return factory_->CreateAsyncSocket(family, type);
333}
334
335// NATSocketServer
336NATSocketServer::NATSocketServer(SocketServer* server)
337 : server_(server), msg_queue_(NULL) {
338}
339
340NATSocketServer::Translator* NATSocketServer::GetTranslator(
341 const SocketAddress& ext_ip) {
342 return nats_.Get(ext_ip);
343}
344
345NATSocketServer::Translator* NATSocketServer::AddTranslator(
346 const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
347 // Fail if a translator already exists with this extternal address.
348 if (nats_.Get(ext_ip))
349 return NULL;
350
351 return nats_.Add(ext_ip, new Translator(this, type, int_ip, server_, ext_ip));
352}
353
354void NATSocketServer::RemoveTranslator(
355 const SocketAddress& ext_ip) {
356 nats_.Remove(ext_ip);
357}
358
359Socket* NATSocketServer::CreateSocket(int type) {
360 return CreateSocket(AF_INET, type);
361}
362
363Socket* NATSocketServer::CreateSocket(int family, int type) {
364 return new NATSocket(this, family, type);
365}
366
367AsyncSocket* NATSocketServer::CreateAsyncSocket(int type) {
368 return CreateAsyncSocket(AF_INET, type);
369}
370
371AsyncSocket* NATSocketServer::CreateAsyncSocket(int family, int type) {
372 return new NATSocket(this, family, type);
373}
374
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000375void NATSocketServer::SetMessageQueue(MessageQueue* queue) {
376 msg_queue_ = queue;
377 server_->SetMessageQueue(queue);
378}
379
380bool NATSocketServer::Wait(int cms, bool process_io) {
381 return server_->Wait(cms, process_io);
382}
383
384void NATSocketServer::WakeUp() {
385 server_->WakeUp();
386}
387
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000388AsyncSocket* NATSocketServer::CreateInternalSocket(int family, int type,
389 const SocketAddress& local_addr, SocketAddress* nat_addr) {
390 AsyncSocket* socket = NULL;
391 Translator* nat = nats_.FindClient(local_addr);
392 if (nat) {
393 socket = nat->internal_factory()->CreateAsyncSocket(family, type);
394 *nat_addr = (type == SOCK_STREAM) ?
deadbeefc5d0d952015-07-16 10:22:21 -0700395 nat->internal_tcp_address() : nat->internal_udp_address();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000396 } else {
397 socket = server_->CreateAsyncSocket(family, type);
398 }
399 return socket;
400}
401
402// NATSocketServer::Translator
403NATSocketServer::Translator::Translator(
404 NATSocketServer* server, NATType type, const SocketAddress& int_ip,
405 SocketFactory* ext_factory, const SocketAddress& ext_ip)
406 : server_(server) {
407 // Create a new private network, and a NATServer running on the private
408 // network that bridges to the external network. Also tell the private
409 // network to use the same message queue as us.
410 VirtualSocketServer* internal_server = new VirtualSocketServer(server_);
411 internal_server->SetMessageQueue(server_->queue());
412 internal_factory_.reset(internal_server);
deadbeefc5d0d952015-07-16 10:22:21 -0700413 nat_server_.reset(new NATServer(type, internal_server, int_ip, int_ip,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000414 ext_factory, ext_ip));
415}
416
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000417NATSocketServer::Translator::~Translator() = default;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000418
419NATSocketServer::Translator* NATSocketServer::Translator::GetTranslator(
420 const SocketAddress& ext_ip) {
421 return nats_.Get(ext_ip);
422}
423
424NATSocketServer::Translator* NATSocketServer::Translator::AddTranslator(
425 const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
426 // Fail if a translator already exists with this extternal address.
427 if (nats_.Get(ext_ip))
428 return NULL;
429
430 AddClient(ext_ip);
431 return nats_.Add(ext_ip,
432 new Translator(server_, type, int_ip, server_, ext_ip));
433}
434void NATSocketServer::Translator::RemoveTranslator(
435 const SocketAddress& ext_ip) {
436 nats_.Remove(ext_ip);
437 RemoveClient(ext_ip);
438}
439
440bool NATSocketServer::Translator::AddClient(
441 const SocketAddress& int_ip) {
442 // Fail if a client already exists with this internal address.
443 if (clients_.find(int_ip) != clients_.end())
444 return false;
445
446 clients_.insert(int_ip);
447 return true;
448}
449
450void NATSocketServer::Translator::RemoveClient(
451 const SocketAddress& int_ip) {
452 std::set<SocketAddress>::iterator it = clients_.find(int_ip);
453 if (it != clients_.end()) {
454 clients_.erase(it);
455 }
456}
457
458NATSocketServer::Translator* NATSocketServer::Translator::FindClient(
459 const SocketAddress& int_ip) {
460 // See if we have the requested IP, or any of our children do.
461 return (clients_.find(int_ip) != clients_.end()) ?
462 this : nats_.FindClient(int_ip);
463}
464
465// NATSocketServer::TranslatorMap
466NATSocketServer::TranslatorMap::~TranslatorMap() {
467 for (TranslatorMap::iterator it = begin(); it != end(); ++it) {
468 delete it->second;
469 }
470}
471
472NATSocketServer::Translator* NATSocketServer::TranslatorMap::Get(
473 const SocketAddress& ext_ip) {
474 TranslatorMap::iterator it = find(ext_ip);
475 return (it != end()) ? it->second : NULL;
476}
477
478NATSocketServer::Translator* NATSocketServer::TranslatorMap::Add(
479 const SocketAddress& ext_ip, Translator* nat) {
480 (*this)[ext_ip] = nat;
481 return nat;
482}
483
484void NATSocketServer::TranslatorMap::Remove(
485 const SocketAddress& ext_ip) {
486 TranslatorMap::iterator it = find(ext_ip);
487 if (it != end()) {
488 delete it->second;
489 erase(it);
490 }
491}
492
493NATSocketServer::Translator* NATSocketServer::TranslatorMap::FindClient(
494 const SocketAddress& int_ip) {
495 Translator* nat = NULL;
496 for (TranslatorMap::iterator it = begin(); it != end() && !nat; ++it) {
497 nat = it->second->FindClient(int_ip);
498 }
499 return nat;
500}
501
502} // namespace rtc