1/**************************************************************************/
2/* godot.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31/**
32 @file godot.cpp
33 @brief ENet Godot specific functions
34*/
35
36#include "core/io/dtls_server.h"
37#include "core/io/ip.h"
38#include "core/io/net_socket.h"
39#include "core/io/packet_peer_dtls.h"
40#include "core/io/udp_server.h"
41#include "core/os/os.h"
42
43// This must be last for windows to compile (tested with MinGW)
44#include "enet/enet.h"
45
46/// Abstract ENet interface for UDP/DTLS.
47class ENetGodotSocket {
48public:
49 virtual Error bind(IPAddress p_ip, uint16_t p_port) = 0;
50 virtual Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) = 0;
51 virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) = 0;
52 virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port) = 0;
53 virtual int set_option(ENetSocketOption p_option, int p_value) = 0;
54 virtual void close() = 0;
55 virtual void set_refuse_new_connections(bool p_enable) {} /* Only used by dtls server */
56 virtual bool can_upgrade() { return false; } /* Only true in ENetUDP */
57 virtual ~ENetGodotSocket() {}
58};
59
60class ENetDTLSClient;
61class ENetDTLSServer;
62
63/// NetSocket interface
64class ENetUDP : public ENetGodotSocket {
65 friend class ENetDTLSClient;
66 friend class ENetDTLSServer;
67
68private:
69 Ref<NetSocket> sock;
70 IPAddress local_address;
71 bool bound = false;
72
73public:
74 ENetUDP() {
75 sock = Ref<NetSocket>(NetSocket::create());
76 IP::Type ip_type = IP::TYPE_ANY;
77 sock->open(NetSocket::TYPE_UDP, ip_type);
78 }
79
80 ~ENetUDP() {
81 sock->close();
82 }
83
84 bool can_upgrade() {
85 return true;
86 }
87
88 Error bind(IPAddress p_ip, uint16_t p_port) {
89 local_address = p_ip;
90 bound = true;
91 return sock->bind(p_ip, p_port);
92 }
93
94 Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) {
95 Error err = sock->get_socket_address(r_ip, r_port);
96 if (bound) {
97 *r_ip = local_address;
98 }
99 return err;
100 }
101
102 Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) {
103 return sock->sendto(p_buffer, p_len, r_sent, p_ip, p_port);
104 }
105
106 Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port) {
107 Error err = sock->poll(NetSocket::POLL_TYPE_IN, 0);
108 if (err != OK) {
109 return err;
110 }
111 return sock->recvfrom(p_buffer, p_len, r_read, r_ip, r_port);
112 }
113
114 int set_option(ENetSocketOption p_option, int p_value) {
115 switch (p_option) {
116 case ENET_SOCKOPT_NONBLOCK: {
117 sock->set_blocking_enabled(p_value ? false : true);
118 return 0;
119 } break;
120
121 case ENET_SOCKOPT_BROADCAST: {
122 sock->set_broadcasting_enabled(p_value ? true : false);
123 return 0;
124 } break;
125
126 case ENET_SOCKOPT_REUSEADDR: {
127 sock->set_reuse_address_enabled(p_value ? true : false);
128 return 0;
129 } break;
130
131 case ENET_SOCKOPT_RCVBUF: {
132 return -1;
133 } break;
134
135 case ENET_SOCKOPT_SNDBUF: {
136 return -1;
137 } break;
138
139 case ENET_SOCKOPT_RCVTIMEO: {
140 return -1;
141 } break;
142
143 case ENET_SOCKOPT_SNDTIMEO: {
144 return -1;
145 } break;
146
147 case ENET_SOCKOPT_NODELAY: {
148 sock->set_tcp_no_delay_enabled(p_value ? true : false);
149 return 0;
150 } break;
151 }
152
153 return -1;
154 }
155
156 void close() {
157 sock->close();
158 local_address.clear();
159 }
160};
161
162/// DTLS Client ENet interface
163class ENetDTLSClient : public ENetGodotSocket {
164 bool connected = false;
165 Ref<PacketPeerUDP> udp;
166 Ref<PacketPeerDTLS> dtls;
167 Ref<TLSOptions> tls_options;
168 String for_hostname;
169 IPAddress local_address;
170
171public:
172 ENetDTLSClient(ENetUDP *p_base, String p_for_hostname, Ref<TLSOptions> p_options) {
173 for_hostname = p_for_hostname;
174 tls_options = p_options;
175 udp.instantiate();
176 dtls = Ref<PacketPeerDTLS>(PacketPeerDTLS::create());
177 if (p_base->bound) {
178 uint16_t port;
179 p_base->get_socket_address(&local_address, &port);
180 p_base->close();
181 bind(local_address, port);
182 }
183 }
184
185 ~ENetDTLSClient() {
186 close();
187 }
188
189 Error bind(IPAddress p_ip, uint16_t p_port) {
190 local_address = p_ip;
191 return udp->bind(p_port, p_ip);
192 }
193
194 Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) {
195 if (!udp->is_bound()) {
196 return ERR_UNCONFIGURED;
197 }
198 *r_ip = local_address;
199 *r_port = udp->get_local_port();
200 return OK;
201 }
202
203 Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) {
204 if (!connected) {
205 udp->connect_to_host(p_ip, p_port);
206 if (dtls->connect_to_peer(udp, for_hostname, tls_options)) {
207 return FAILED;
208 }
209 connected = true;
210 }
211 dtls->poll();
212 if (dtls->get_status() == PacketPeerDTLS::STATUS_HANDSHAKING) {
213 return ERR_BUSY;
214 } else if (dtls->get_status() != PacketPeerDTLS::STATUS_CONNECTED) {
215 return FAILED;
216 }
217 r_sent = p_len;
218 return dtls->put_packet(p_buffer, p_len);
219 }
220
221 Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port) {
222 dtls->poll();
223 if (dtls->get_status() == PacketPeerDTLS::STATUS_HANDSHAKING) {
224 return ERR_BUSY;
225 }
226 if (dtls->get_status() != PacketPeerDTLS::STATUS_CONNECTED) {
227 return FAILED;
228 }
229 int pc = dtls->get_available_packet_count();
230 if (pc == 0) {
231 return ERR_BUSY;
232 } else if (pc < 0) {
233 return FAILED;
234 }
235
236 const uint8_t *buffer;
237 Error err = dtls->get_packet(&buffer, r_read);
238 ERR_FAIL_COND_V(err != OK, err);
239 ERR_FAIL_COND_V(p_len < r_read, ERR_OUT_OF_MEMORY);
240
241 memcpy(p_buffer, buffer, r_read);
242 r_ip = udp->get_packet_address();
243 r_port = udp->get_packet_port();
244 return err;
245 }
246
247 int set_option(ENetSocketOption p_option, int p_value) {
248 return -1;
249 }
250
251 void close() {
252 dtls->disconnect_from_peer();
253 udp->close();
254 }
255};
256
257/// DTLSServer - ENet interface
258class ENetDTLSServer : public ENetGodotSocket {
259 Ref<DTLSServer> server;
260 Ref<UDPServer> udp_server;
261 HashMap<String, Ref<PacketPeerDTLS>> peers;
262 int last_service = 0;
263 IPAddress local_address;
264
265public:
266 ENetDTLSServer(ENetUDP *p_base, Ref<TLSOptions> p_options) {
267 udp_server.instantiate();
268 if (p_base->bound) {
269 uint16_t port;
270 p_base->get_socket_address(&local_address, &port);
271 p_base->close();
272 bind(local_address, port);
273 }
274 server = Ref<DTLSServer>(DTLSServer::create());
275 server->setup(p_options);
276 }
277
278 ~ENetDTLSServer() {
279 close();
280 }
281
282 void set_refuse_new_connections(bool p_refuse) {
283 udp_server->set_max_pending_connections(p_refuse ? 0 : 16);
284 }
285
286 Error bind(IPAddress p_ip, uint16_t p_port) {
287 local_address = p_ip;
288 return udp_server->listen(p_port, p_ip);
289 }
290
291 Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) {
292 if (!udp_server->is_listening()) {
293 return ERR_UNCONFIGURED;
294 }
295 *r_ip = local_address;
296 *r_port = udp_server->get_local_port();
297 return OK;
298 }
299
300 Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) {
301 String key = String(p_ip) + ":" + itos(p_port);
302 ERR_FAIL_COND_V(!peers.has(key), ERR_UNAVAILABLE);
303 Ref<PacketPeerDTLS> peer = peers[key];
304 Error err = peer->put_packet(p_buffer, p_len);
305 if (err == OK) {
306 r_sent = p_len;
307 } else if (err == ERR_BUSY) {
308 r_sent = 0;
309 } else {
310 r_sent = -1;
311 }
312 return err;
313 }
314
315 Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port) {
316 udp_server->poll();
317 // TODO limits? Maybe we can better enforce allowed connections!
318 if (udp_server->is_connection_available()) {
319 Ref<PacketPeerUDP> udp = udp_server->take_connection();
320 IPAddress peer_ip = udp->get_packet_address();
321 int peer_port = udp->get_packet_port();
322 Ref<PacketPeerDTLS> peer = server->take_connection(udp);
323 PacketPeerDTLS::Status status = peer->get_status();
324 if (status == PacketPeerDTLS::STATUS_HANDSHAKING || status == PacketPeerDTLS::STATUS_CONNECTED) {
325 String key = String(peer_ip) + ":" + itos(peer_port);
326 peers[key] = peer;
327 }
328 }
329
330 List<String> remove;
331 Error err = ERR_BUSY;
332 // TODO this needs to be fair!
333
334 for (KeyValue<String, Ref<PacketPeerDTLS>> & E : peers) {
335 Ref<PacketPeerDTLS> peer = E.value;
336 peer->poll();
337
338 if (peer->get_status() == PacketPeerDTLS::STATUS_HANDSHAKING) {
339 continue;
340 } else if (peer->get_status() != PacketPeerDTLS::STATUS_CONNECTED) {
341 // Peer disconnected, removing it.
342 remove.push_back(E.key);
343 continue;
344 }
345
346 if (peer->get_available_packet_count() > 0) {
347 const uint8_t *buffer;
348 err = peer->get_packet(&buffer, r_read);
349 if (err != OK || p_len < r_read) {
350 // Something wrong with this peer, removing it.
351 remove.push_back(E.key);
352 err = FAILED;
353 continue;
354 }
355
356 Vector<String> s = E.key.rsplit(":", false, 1);
357 ERR_CONTINUE(s.size() != 2); // BUG!
358
359 memcpy(p_buffer, buffer, r_read);
360 r_ip = s[0];
361 r_port = s[1].to_int();
362 break; // err = OK
363 }
364 }
365
366 // Remove disconnected peers from map.
367 for (String &E : remove) {
368 peers.erase(E);
369 }
370
371 return err; // OK, ERR_BUSY, or possibly an error.
372 }
373
374 int set_option(ENetSocketOption p_option, int p_value) {
375 return -1;
376 }
377
378 void close() {
379 for (KeyValue<String, Ref<PacketPeerDTLS>> &E : peers) {
380 E.value->disconnect_from_peer();
381 }
382 peers.clear();
383 udp_server->stop();
384 server->stop();
385 local_address.clear();
386 }
387};
388
389static enet_uint32 timeBase = 0;
390
391int enet_initialize(void) {
392 return 0;
393}
394
395void enet_deinitialize(void) {
396}
397
398enet_uint32 enet_host_random_seed(void) {
399 return (enet_uint32)OS::get_singleton()->get_unix_time();
400}
401
402enet_uint32 enet_time_get(void) {
403 return OS::get_singleton()->get_ticks_msec() - timeBase;
404}
405
406void enet_time_set(enet_uint32 newTimeBase) {
407 timeBase = OS::get_singleton()->get_ticks_msec() - newTimeBase;
408}
409
410int enet_address_set_host(ENetAddress *address, const char *name) {
411 IPAddress ip = IP::get_singleton()->resolve_hostname(name);
412 ERR_FAIL_COND_V(!ip.is_valid(), -1);
413
414 enet_address_set_ip(address, ip.get_ipv6(), 16);
415 return 0;
416}
417
418void enet_address_set_ip(ENetAddress *address, const uint8_t *ip, size_t size) {
419 int len = size > 16 ? 16 : size;
420 memset(address->host, 0, 16);
421 memcpy(address->host, ip, len);
422}
423
424int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) {
425 return -1;
426}
427
428int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) {
429 return -1;
430}
431
432ENetSocket enet_socket_create(ENetSocketType type) {
433 ENetUDP *socket = memnew(ENetUDP);
434
435 return socket;
436}
437
438int enet_host_dtls_server_setup(ENetHost *host, void *p_options) {
439 ERR_FAIL_COND_V_MSG(!DTLSServer::is_available(), -1, "DTLS server is not available in this build.");
440 ENetGodotSocket *sock = (ENetGodotSocket *)host->socket;
441 if (!sock->can_upgrade()) {
442 return -1;
443 }
444 host->socket = memnew(ENetDTLSServer(static_cast<ENetUDP *>(sock), Ref<TLSOptions>(static_cast<TLSOptions *>(p_options))));
445 memdelete(sock);
446 return 0;
447}
448
449int enet_host_dtls_client_setup(ENetHost *host, const char *p_for_hostname, void *p_options) {
450 ERR_FAIL_COND_V_MSG(!PacketPeerDTLS::is_available(), -1, "DTLS is not available in this build.");
451 ENetGodotSocket *sock = (ENetGodotSocket *)host->socket;
452 if (!sock->can_upgrade()) {
453 return -1;
454 }
455 host->socket = memnew(ENetDTLSClient(static_cast<ENetUDP *>(sock), String::utf8(p_for_hostname), Ref<TLSOptions>(static_cast<TLSOptions *>(p_options))));
456 memdelete(sock);
457 return 0;
458}
459
460void enet_host_refuse_new_connections(ENetHost *host, int p_refuse) {
461 ERR_FAIL_COND(!host->socket);
462 ((ENetGodotSocket *)host->socket)->set_refuse_new_connections(p_refuse);
463}
464
465int enet_socket_bind(ENetSocket socket, const ENetAddress *address) {
466 IPAddress ip;
467 if (address->wildcard) {
468 ip = IPAddress("*");
469 } else {
470 ip.set_ipv6(address->host);
471 }
472
473 ENetGodotSocket *sock = (ENetGodotSocket *)socket;
474 if (sock->bind(ip, address->port) != OK) {
475 return -1;
476 }
477 return 0;
478}
479
480void enet_socket_destroy(ENetSocket socket) {
481 ENetGodotSocket *sock = (ENetGodotSocket *)socket;
482 sock->close();
483 memdelete(sock);
484}
485
486int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBuffer *buffers, size_t bufferCount) {
487 ERR_FAIL_COND_V(address == nullptr, -1);
488
489 ENetGodotSocket *sock = (ENetGodotSocket *)socket;
490 IPAddress dest;
491 Error err;
492 size_t i = 0;
493
494 dest.set_ipv6(address->host);
495
496 // Create a single packet.
497 Vector<uint8_t> out;
498 uint8_t *w;
499 int size = 0;
500 int pos = 0;
501 for (i = 0; i < bufferCount; i++) {
502 size += buffers[i].dataLength;
503 }
504
505 out.resize(size);
506 w = out.ptrw();
507 for (i = 0; i < bufferCount; i++) {
508 memcpy(&w[pos], buffers[i].data, buffers[i].dataLength);
509 pos += buffers[i].dataLength;
510 }
511
512 int sent = 0;
513 err = sock->sendto((const uint8_t *)&w[0], size, sent, dest, address->port);
514 if (err != OK) {
515 if (err == ERR_BUSY) { // Blocking call
516 return 0;
517 }
518
519 WARN_PRINT("Sending failed!");
520 return -1;
521 }
522
523 return sent;
524}
525
526int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) {
527 ERR_FAIL_COND_V(bufferCount != 1, -1);
528
529 ENetGodotSocket *sock = (ENetGodotSocket *)socket;
530
531 int read;
532 IPAddress ip;
533
534 Error err = sock->recvfrom((uint8_t *)buffers[0].data, buffers[0].dataLength, read, ip, address->port);
535 if (err == ERR_BUSY) {
536 return 0;
537 }
538 if (err == ERR_OUT_OF_MEMORY) {
539 // A packet above the ENET_PROTOCOL_MAXIMUM_MTU was received.
540 return -2;
541 }
542
543 if (err != OK) {
544 return -1;
545 }
546
547 enet_address_set_ip(address, ip.get_ipv6(), 16);
548
549 return read;
550}
551
552int enet_socket_get_address (ENetSocket socket, ENetAddress * address) {
553 IPAddress ip;
554 uint16_t port;
555 ENetGodotSocket *sock = (ENetGodotSocket *)socket;
556
557 if (sock->get_socket_address(&ip, &port) != OK) {
558 return -1;
559 }
560
561 enet_address_set_ip(address, ip.get_ipv6(), 16);
562 address->port = port;
563
564 return 0;
565}
566
567// Not implemented
568int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint32 timeout) {
569 return 0; // do we need this function?
570}
571
572int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) {
573 return -1;
574}
575
576int enet_socket_listen(ENetSocket socket, int backlog) {
577 return -1;
578}
579
580int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) {
581 ENetGodotSocket *sock = (ENetGodotSocket *)socket;
582 return sock->set_option(option, value);
583}
584
585int enet_socket_get_option(ENetSocket socket, ENetSocketOption option, int *value) {
586 return -1;
587}
588
589int enet_socket_connect(ENetSocket socket, const ENetAddress *address) {
590 return -1;
591}
592
593ENetSocket enet_socket_accept(ENetSocket socket, ENetAddress *address) {
594 return nullptr;
595}
596
597int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) {
598 return -1;
599}
600