blob: a92498429c24e5e221069454dc728d95ac263dfb [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
tfarina5237aaf2015-11-10 23:44:30 -080013#include "webrtc/base/arraysize.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000014#include "webrtc/base/logging.h"
15#include "webrtc/base/natserver.h"
16#include "webrtc/base/virtualsocketserver.h"
17
18namespace rtc {
19
20// Packs the given socketaddress into the buffer in buf, in the quasi-STUN
21// format that the natserver uses.
22// Returns 0 if an invalid address is passed.
23size_t PackAddressForNAT(char* buf, size_t buf_size,
24 const SocketAddress& remote_addr) {
25 const IPAddress& ip = remote_addr.ipaddr();
26 int family = ip.family();
27 buf[0] = 0;
28 buf[1] = family;
29 // Writes the port.
Peter Boström0c4e06b2015-10-07 12:23:21 +020030 *(reinterpret_cast<uint16_t*>(&buf[2])) = HostToNetwork16(remote_addr.port());
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000031 if (family == AF_INET) {
32 ASSERT(buf_size >= kNATEncodedIPv4AddressSize);
33 in_addr v4addr = ip.ipv4_address();
34 memcpy(&buf[4], &v4addr, kNATEncodedIPv4AddressSize - 4);
35 return kNATEncodedIPv4AddressSize;
36 } else if (family == AF_INET6) {
37 ASSERT(buf_size >= kNATEncodedIPv6AddressSize);
38 in6_addr v6addr = ip.ipv6_address();
39 memcpy(&buf[4], &v6addr, kNATEncodedIPv6AddressSize - 4);
40 return kNATEncodedIPv6AddressSize;
41 }
42 return 0U;
43}
44
45// Decodes the remote address from a packet that has been encoded with the nat's
46// quasi-STUN format. Returns the length of the address (i.e., the offset into
47// data where the original packet starts).
48size_t UnpackAddressFromNAT(const char* buf, size_t buf_size,
49 SocketAddress* remote_addr) {
50 ASSERT(buf_size >= 8);
51 ASSERT(buf[0] == 0);
52 int family = buf[1];
Peter Boström0c4e06b2015-10-07 12:23:21 +020053 uint16_t port =
54 NetworkToHost16(*(reinterpret_cast<const uint16_t*>(&buf[2])));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000055 if (family == AF_INET) {
56 const in_addr* v4addr = reinterpret_cast<const in_addr*>(&buf[4]);
57 *remote_addr = SocketAddress(IPAddress(*v4addr), port);
58 return kNATEncodedIPv4AddressSize;
59 } else if (family == AF_INET6) {
60 ASSERT(buf_size >= 20);
61 const in6_addr* v6addr = reinterpret_cast<const in6_addr*>(&buf[4]);
62 *remote_addr = SocketAddress(IPAddress(*v6addr), port);
63 return kNATEncodedIPv6AddressSize;
64 }
65 return 0U;
66}
67
68
69// NATSocket
70class NATSocket : public AsyncSocket, public sigslot::has_slots<> {
71 public:
72 explicit NATSocket(NATInternalSocketFactory* sf, int family, int type)
73 : sf_(sf), family_(family), type_(type), connected_(false),
74 socket_(NULL), buf_(NULL), size_(0) {
75 }
76
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000077 ~NATSocket() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000078 delete socket_;
79 delete[] buf_;
80 }
81
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000082 SocketAddress GetLocalAddress() const override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000083 return (socket_) ? socket_->GetLocalAddress() : SocketAddress();
84 }
85
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000086 SocketAddress GetRemoteAddress() const override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000087 return remote_addr_; // will be NIL if not connected
88 }
89
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +000090 int Bind(const SocketAddress& addr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000091 if (socket_) { // already bound, bubble up error
92 return -1;
93 }
94
95 int result;
96 socket_ = sf_->CreateInternalSocket(family_, type_, addr, &server_addr_);
97 result = (socket_) ? socket_->Bind(addr) : -1;
98 if (result >= 0) {
99 socket_->SignalConnectEvent.connect(this, &NATSocket::OnConnectEvent);
100 socket_->SignalReadEvent.connect(this, &NATSocket::OnReadEvent);
101 socket_->SignalWriteEvent.connect(this, &NATSocket::OnWriteEvent);
102 socket_->SignalCloseEvent.connect(this, &NATSocket::OnCloseEvent);
103 } else {
104 server_addr_.Clear();
105 delete socket_;
106 socket_ = NULL;
107 }
108
109 return result;
110 }
111
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000112 int Connect(const SocketAddress& addr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000113 if (!socket_) { // socket must be bound, for now
114 return -1;
115 }
116
117 int result = 0;
118 if (type_ == SOCK_STREAM) {
119 result = socket_->Connect(server_addr_.IsNil() ? addr : server_addr_);
120 } else {
121 connected_ = true;
122 }
123
124 if (result >= 0) {
125 remote_addr_ = addr;
126 }
127
128 return result;
129 }
130
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000131 int Send(const void* data, size_t size) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000132 ASSERT(connected_);
133 return SendTo(data, size, remote_addr_);
134 }
135
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000136 int SendTo(const void* data,
137 size_t size,
138 const SocketAddress& addr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000139 ASSERT(!connected_ || addr == remote_addr_);
140 if (server_addr_.IsNil() || type_ == SOCK_STREAM) {
141 return socket_->SendTo(data, size, addr);
142 }
143 // This array will be too large for IPv4 packets, but only by 12 bytes.
jbauch555604a2016-04-26 03:13:22 -0700144 std::unique_ptr<char[]> buf(new char[size + kNATEncodedIPv6AddressSize]);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000145 size_t addrlength = PackAddressForNAT(buf.get(),
146 size + kNATEncodedIPv6AddressSize,
147 addr);
148 size_t encoded_size = size + addrlength;
149 memcpy(buf.get() + addrlength, data, size);
150 int result = socket_->SendTo(buf.get(), encoded_size, server_addr_);
151 if (result >= 0) {
152 ASSERT(result == static_cast<int>(encoded_size));
153 result = result - static_cast<int>(addrlength);
154 }
155 return result;
156 }
157
Stefan Holmer9131efd2016-05-23 18:19:26 +0200158 int Recv(void* data, size_t size, int64_t* timestamp) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000159 SocketAddress addr;
Stefan Holmer9131efd2016-05-23 18:19:26 +0200160 return RecvFrom(data, size, &addr, timestamp);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000161 }
162
Stefan Holmer9131efd2016-05-23 18:19:26 +0200163 int RecvFrom(void* data,
164 size_t size,
165 SocketAddress* out_addr,
166 int64_t* timestamp) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000167 if (server_addr_.IsNil() || type_ == SOCK_STREAM) {
Stefan Holmer9131efd2016-05-23 18:19:26 +0200168 return socket_->RecvFrom(data, size, out_addr, timestamp);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000169 }
170 // Make sure we have enough room to read the requested amount plus the
171 // largest possible header address.
172 SocketAddress remote_addr;
173 Grow(size + kNATEncodedIPv6AddressSize);
174
175 // Read the packet from the socket.
Stefan Holmer9131efd2016-05-23 18:19:26 +0200176 int result = socket_->RecvFrom(buf_, size_, &remote_addr, timestamp);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000177 if (result >= 0) {
178 ASSERT(remote_addr == server_addr_);
179
180 // TODO: we need better framing so we know how many bytes we can
181 // return before we need to read the next address. For UDP, this will be
182 // fine as long as the reader always reads everything in the packet.
183 ASSERT((size_t)result < size_);
184
185 // Decode the wire packet into the actual results.
186 SocketAddress real_remote_addr;
deadbeefc5d0d952015-07-16 10:22:21 -0700187 size_t addrlength = UnpackAddressFromNAT(buf_, result, &real_remote_addr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000188 memcpy(data, buf_ + addrlength, result - addrlength);
189
190 // Make sure this packet should be delivered before returning it.
191 if (!connected_ || (real_remote_addr == remote_addr_)) {
192 if (out_addr)
193 *out_addr = real_remote_addr;
194 result = result - static_cast<int>(addrlength);
195 } else {
196 LOG(LS_ERROR) << "Dropping packet from unknown remote address: "
197 << real_remote_addr.ToString();
198 result = 0; // Tell the caller we didn't read anything
199 }
200 }
201
202 return result;
203 }
204
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000205 int Close() override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000206 int result = 0;
207 if (socket_) {
208 result = socket_->Close();
209 if (result >= 0) {
210 connected_ = false;
211 remote_addr_ = SocketAddress();
212 delete socket_;
213 socket_ = NULL;
214 }
215 }
216 return result;
217 }
218
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000219 int Listen(int backlog) override { return socket_->Listen(backlog); }
220 AsyncSocket* Accept(SocketAddress* paddr) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000221 return socket_->Accept(paddr);
222 }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000223 int GetError() const override { return socket_->GetError(); }
224 void SetError(int error) override { socket_->SetError(error); }
225 ConnState GetState() const override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000226 return connected_ ? CS_CONNECTED : CS_CLOSED;
227 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200228 int EstimateMTU(uint16_t* mtu) override { return socket_->EstimateMTU(mtu); }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000229 int GetOption(Option opt, int* value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000230 return socket_->GetOption(opt, value);
231 }
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000232 int SetOption(Option opt, int value) override {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000233 return socket_->SetOption(opt, value);
234 }
235
236 void OnConnectEvent(AsyncSocket* socket) {
deadbeefc5d0d952015-07-16 10:22:21 -0700237 // If we're NATed, we need to send a message with the real addr to use.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000238 ASSERT(socket == socket_);
239 if (server_addr_.IsNil()) {
240 connected_ = true;
241 SignalConnectEvent(this);
242 } else {
243 SendConnectRequest();
244 }
245 }
246 void OnReadEvent(AsyncSocket* socket) {
247 // If we're NATed, we need to process the connect reply.
248 ASSERT(socket == socket_);
249 if (type_ == SOCK_STREAM && !server_addr_.IsNil() && !connected_) {
250 HandleConnectReply();
251 } else {
252 SignalReadEvent(this);
253 }
254 }
255 void OnWriteEvent(AsyncSocket* socket) {
256 ASSERT(socket == socket_);
257 SignalWriteEvent(this);
258 }
259 void OnCloseEvent(AsyncSocket* socket, int error) {
260 ASSERT(socket == socket_);
261 SignalCloseEvent(this, error);
262 }
263
264 private:
265 // Makes sure the buffer is at least the given size.
266 void Grow(size_t new_size) {
267 if (size_ < new_size) {
268 delete[] buf_;
269 size_ = new_size;
270 buf_ = new char[size_];
271 }
272 }
273
274 // Sends the destination address to the server to tell it to connect.
275 void SendConnectRequest() {
deadbeefc5d0d952015-07-16 10:22:21 -0700276 char buf[kNATEncodedIPv6AddressSize];
tfarina5237aaf2015-11-10 23:44:30 -0800277 size_t length = PackAddressForNAT(buf, arraysize(buf), remote_addr_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000278 socket_->Send(buf, length);
279 }
280
281 // Handles the byte sent back from the server and fires the appropriate event.
282 void HandleConnectReply() {
283 char code;
Stefan Holmer9131efd2016-05-23 18:19:26 +0200284 socket_->Recv(&code, sizeof(code), nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000285 if (code == 0) {
deadbeefc5d0d952015-07-16 10:22:21 -0700286 connected_ = true;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000287 SignalConnectEvent(this);
288 } else {
289 Close();
290 SignalCloseEvent(this, code);
291 }
292 }
293
294 NATInternalSocketFactory* sf_;
295 int family_;
296 int type_;
297 bool connected_;
298 SocketAddress remote_addr_;
299 SocketAddress server_addr_; // address of the NAT server
300 AsyncSocket* socket_;
301 char* buf_;
302 size_t size_;
303};
304
305// NATSocketFactory
306NATSocketFactory::NATSocketFactory(SocketFactory* factory,
deadbeefc5d0d952015-07-16 10:22:21 -0700307 const SocketAddress& nat_udp_addr,
308 const SocketAddress& nat_tcp_addr)
309 : factory_(factory), nat_udp_addr_(nat_udp_addr),
310 nat_tcp_addr_(nat_tcp_addr) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000311}
312
313Socket* NATSocketFactory::CreateSocket(int type) {
314 return CreateSocket(AF_INET, type);
315}
316
317Socket* NATSocketFactory::CreateSocket(int family, int type) {
318 return new NATSocket(this, family, type);
319}
320
321AsyncSocket* NATSocketFactory::CreateAsyncSocket(int type) {
322 return CreateAsyncSocket(AF_INET, type);
323}
324
325AsyncSocket* NATSocketFactory::CreateAsyncSocket(int family, int type) {
326 return new NATSocket(this, family, type);
327}
328
329AsyncSocket* NATSocketFactory::CreateInternalSocket(int family, int type,
330 const SocketAddress& local_addr, SocketAddress* nat_addr) {
deadbeefc5d0d952015-07-16 10:22:21 -0700331 if (type == SOCK_STREAM) {
332 *nat_addr = nat_tcp_addr_;
333 } else {
334 *nat_addr = nat_udp_addr_;
335 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000336 return factory_->CreateAsyncSocket(family, type);
337}
338
339// NATSocketServer
340NATSocketServer::NATSocketServer(SocketServer* server)
341 : server_(server), msg_queue_(NULL) {
342}
343
344NATSocketServer::Translator* NATSocketServer::GetTranslator(
345 const SocketAddress& ext_ip) {
346 return nats_.Get(ext_ip);
347}
348
349NATSocketServer::Translator* NATSocketServer::AddTranslator(
350 const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
351 // Fail if a translator already exists with this extternal address.
352 if (nats_.Get(ext_ip))
353 return NULL;
354
355 return nats_.Add(ext_ip, new Translator(this, type, int_ip, server_, ext_ip));
356}
357
358void NATSocketServer::RemoveTranslator(
359 const SocketAddress& ext_ip) {
360 nats_.Remove(ext_ip);
361}
362
363Socket* NATSocketServer::CreateSocket(int type) {
364 return CreateSocket(AF_INET, type);
365}
366
367Socket* NATSocketServer::CreateSocket(int family, int type) {
368 return new NATSocket(this, family, type);
369}
370
371AsyncSocket* NATSocketServer::CreateAsyncSocket(int type) {
372 return CreateAsyncSocket(AF_INET, type);
373}
374
375AsyncSocket* NATSocketServer::CreateAsyncSocket(int family, int type) {
376 return new NATSocket(this, family, type);
377}
378
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000379void NATSocketServer::SetMessageQueue(MessageQueue* queue) {
380 msg_queue_ = queue;
381 server_->SetMessageQueue(queue);
382}
383
384bool NATSocketServer::Wait(int cms, bool process_io) {
385 return server_->Wait(cms, process_io);
386}
387
388void NATSocketServer::WakeUp() {
389 server_->WakeUp();
390}
391
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000392AsyncSocket* NATSocketServer::CreateInternalSocket(int family, int type,
393 const SocketAddress& local_addr, SocketAddress* nat_addr) {
394 AsyncSocket* socket = NULL;
395 Translator* nat = nats_.FindClient(local_addr);
396 if (nat) {
397 socket = nat->internal_factory()->CreateAsyncSocket(family, type);
398 *nat_addr = (type == SOCK_STREAM) ?
deadbeefc5d0d952015-07-16 10:22:21 -0700399 nat->internal_tcp_address() : nat->internal_udp_address();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000400 } else {
401 socket = server_->CreateAsyncSocket(family, type);
402 }
403 return socket;
404}
405
406// NATSocketServer::Translator
407NATSocketServer::Translator::Translator(
408 NATSocketServer* server, NATType type, const SocketAddress& int_ip,
409 SocketFactory* ext_factory, const SocketAddress& ext_ip)
410 : server_(server) {
411 // Create a new private network, and a NATServer running on the private
412 // network that bridges to the external network. Also tell the private
413 // network to use the same message queue as us.
414 VirtualSocketServer* internal_server = new VirtualSocketServer(server_);
415 internal_server->SetMessageQueue(server_->queue());
416 internal_factory_.reset(internal_server);
deadbeefc5d0d952015-07-16 10:22:21 -0700417 nat_server_.reset(new NATServer(type, internal_server, int_ip, int_ip,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000418 ext_factory, ext_ip));
419}
420
kwiberg@webrtc.org67186fe2015-03-09 22:21:53 +0000421NATSocketServer::Translator::~Translator() = default;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000422
423NATSocketServer::Translator* NATSocketServer::Translator::GetTranslator(
424 const SocketAddress& ext_ip) {
425 return nats_.Get(ext_ip);
426}
427
428NATSocketServer::Translator* NATSocketServer::Translator::AddTranslator(
429 const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
430 // Fail if a translator already exists with this extternal address.
431 if (nats_.Get(ext_ip))
432 return NULL;
433
434 AddClient(ext_ip);
435 return nats_.Add(ext_ip,
436 new Translator(server_, type, int_ip, server_, ext_ip));
437}
438void NATSocketServer::Translator::RemoveTranslator(
439 const SocketAddress& ext_ip) {
440 nats_.Remove(ext_ip);
441 RemoveClient(ext_ip);
442}
443
444bool NATSocketServer::Translator::AddClient(
445 const SocketAddress& int_ip) {
446 // Fail if a client already exists with this internal address.
447 if (clients_.find(int_ip) != clients_.end())
448 return false;
449
450 clients_.insert(int_ip);
451 return true;
452}
453
454void NATSocketServer::Translator::RemoveClient(
455 const SocketAddress& int_ip) {
456 std::set<SocketAddress>::iterator it = clients_.find(int_ip);
457 if (it != clients_.end()) {
458 clients_.erase(it);
459 }
460}
461
462NATSocketServer::Translator* NATSocketServer::Translator::FindClient(
463 const SocketAddress& int_ip) {
464 // See if we have the requested IP, or any of our children do.
465 return (clients_.find(int_ip) != clients_.end()) ?
466 this : nats_.FindClient(int_ip);
467}
468
469// NATSocketServer::TranslatorMap
470NATSocketServer::TranslatorMap::~TranslatorMap() {
471 for (TranslatorMap::iterator it = begin(); it != end(); ++it) {
472 delete it->second;
473 }
474}
475
476NATSocketServer::Translator* NATSocketServer::TranslatorMap::Get(
477 const SocketAddress& ext_ip) {
478 TranslatorMap::iterator it = find(ext_ip);
479 return (it != end()) ? it->second : NULL;
480}
481
482NATSocketServer::Translator* NATSocketServer::TranslatorMap::Add(
483 const SocketAddress& ext_ip, Translator* nat) {
484 (*this)[ext_ip] = nat;
485 return nat;
486}
487
488void NATSocketServer::TranslatorMap::Remove(
489 const SocketAddress& ext_ip) {
490 TranslatorMap::iterator it = find(ext_ip);
491 if (it != end()) {
492 delete it->second;
493 erase(it);
494 }
495}
496
497NATSocketServer::Translator* NATSocketServer::TranslatorMap::FindClient(
498 const SocketAddress& int_ip) {
499 Translator* nat = NULL;
500 for (TranslatorMap::iterator it = begin(); it != end() && !nat; ++it) {
501 nat = it->second->FindClient(int_ip);
502 }
503 return nat;
504}
505
506} // namespace rtc