summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2020-07-14 16:31:19 +0200
committerGitHub <noreply@github.com>2020-07-14 16:31:19 +0200
commit9bdcfc4e875ec57f425150e28878232aa2d086bc (patch)
treee9f61472452ad8cd40a51cf011bab7d0c72ccbb5
parent0692deee23363b229482e593354373442822c8b6 (diff)
parent32fbe37ab4d0f654fc4625bda018d157e0987ab2 (diff)
Merge pull request #40374 from Faless/udp/server_abstraction
UDPServer uses single socket, abstract clients.
-rw-r--r--core/io/packet_peer_udp.cpp65
-rw-r--r--core/io/packet_peer_udp.h7
-rw-r--r--core/io/udp_server.cpp100
-rw-r--r--core/io/udp_server.h29
-rw-r--r--doc/classes/UDPServer.xml20
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp3
-rw-r--r--thirdparty/enet/enet/enet.h34
-rw-r--r--thirdparty/enet/enet/godot.h8
-rw-r--r--thirdparty/enet/enet/godot_ext.h18
-rw-r--r--thirdparty/enet/godot.cpp11
-rw-r--r--thirdparty/enet/patches/dtls_support.patch13
-rw-r--r--thirdparty/enet/patches/godot.patch (renamed from thirdparty/enet/patches/ipv6_support.patch)71
12 files changed, 274 insertions, 105 deletions
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index 862fca96fc..e633a56d54 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -31,12 +31,14 @@
#include "packet_peer_udp.h"
#include "core/io/ip.h"
+#include "core/io/udp_server.h"
void PacketPeerUDP::set_blocking_mode(bool p_enable) {
blocking = p_enable;
}
void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
+ ERR_FAIL_COND(udp_server);
broadcast = p_enabled;
if (_sock.is_valid() && _sock->is_open()) {
_sock->set_broadcasting_enabled(p_enabled);
@@ -44,6 +46,7 @@ void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
}
Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) {
+ ERR_FAIL_COND_V(udp_server, ERR_LOCKED);
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(!p_multi_address.is_valid(), ERR_INVALID_PARAMETER);
@@ -58,6 +61,7 @@ Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_i
}
Error PacketPeerUDP::leave_multicast_group(IP_Address p_multi_address, String p_if_name) {
+ ERR_FAIL_COND_V(udp_server, ERR_LOCKED);
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(!_sock->is_open(), ERR_UNCONFIGURED);
return _sock->leave_multicast_group(p_multi_address, p_if_name);
@@ -130,7 +134,7 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
}
do {
- if (connected) {
+ if (connected && !udp_server) {
err = _sock->send(p_buffer, p_buffer_size, sent);
} else {
err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
@@ -186,26 +190,25 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
return OK;
}
-Error PacketPeerUDP::connect_socket(Ref<NetSocket> p_sock) {
- Error err;
- int read = 0;
- uint16_t r_port;
- IP_Address r_ip;
-
- err = p_sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, r_ip, r_port, true);
- ERR_FAIL_COND_V(err != OK, err);
- err = p_sock->connect_to_host(r_ip, r_port);
- ERR_FAIL_COND_V(err != OK, err);
+Error PacketPeerUDP::connect_shared_socket(Ref<NetSocket> p_sock, IP_Address p_ip, uint16_t p_port, UDPServer *p_server) {
+ udp_server = p_server;
+ connected = true;
_sock = p_sock;
- peer_addr = r_ip;
- peer_port = r_port;
+ peer_addr = p_ip;
+ peer_port = p_port;
packet_ip = peer_addr;
packet_port = peer_port;
- connected = true;
return OK;
}
+void PacketPeerUDP::disconnect_shared_socket() {
+ udp_server = nullptr;
+ _sock = Ref<NetSocket>(NetSocket::create());
+ close();
+}
+
Error PacketPeerUDP::connect_to_host(const IP_Address &p_host, int p_port) {
+ ERR_FAIL_COND_V(udp_server, ERR_LOCKED);
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);
@@ -243,7 +246,11 @@ bool PacketPeerUDP::is_connected_to_host() const {
}
void PacketPeerUDP::close() {
- if (_sock.is_valid()) {
+ if (udp_server) {
+ udp_server->remove_peer(peer_addr, peer_port);
+ udp_server = nullptr;
+ _sock = Ref<NetSocket>(NetSocket::create());
+ } else if (_sock.is_valid()) {
_sock->close();
}
rb.resize(16);
@@ -262,6 +269,9 @@ Error PacketPeerUDP::_poll() {
if (!_sock->is_open()) {
return FAILED;
}
+ if (udp_server) {
+ return OK; // Handled by UDPServer.
+ }
Error err;
int read;
@@ -284,24 +294,29 @@ Error PacketPeerUDP::_poll() {
return FAILED;
}
- if (rb.space_left() < read + 24) {
+ err = store_packet(ip, port, recv_buffer, read);
#ifdef TOOLS_ENABLED
+ if (err != OK) {
WARN_PRINT("Buffer full, dropping packets!");
-#endif
- continue;
}
-
- uint32_t port32 = port;
- rb.write(ip.get_ipv6(), 16);
- rb.write((uint8_t *)&port32, 4);
- rb.write((uint8_t *)&read, 4);
- rb.write(recv_buffer, read);
- ++queue_count;
+#endif
}
return OK;
}
+Error PacketPeerUDP::store_packet(IP_Address p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size) {
+ if (rb.space_left() < p_buf_size + 24) {
+ return ERR_OUT_OF_MEMORY;
+ }
+ rb.write(p_ip.get_ipv6(), 16);
+ rb.write((uint8_t *)&p_port, 4);
+ rb.write((uint8_t *)&p_buf_size, 4);
+ rb.write(p_buf, p_buf_size);
+ ++queue_count;
+ return OK;
+}
+
bool PacketPeerUDP::is_listening() const {
return _sock.is_valid() && _sock->is_open();
}
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index ad0a60f60d..9a44a1ebea 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -35,6 +35,8 @@
#include "core/io/net_socket.h"
#include "core/io/packet_peer.h"
+class UDPServer;
+
class PacketPeerUDP : public PacketPeer {
GDCLASS(PacketPeerUDP, PacketPeer);
@@ -55,6 +57,7 @@ protected:
bool connected = false;
bool blocking = true;
bool broadcast = false;
+ UDPServer *udp_server = nullptr;
Ref<NetSocket> _sock;
static void _bind_methods();
@@ -72,7 +75,9 @@ public:
Error wait();
bool is_listening() const;
- Error connect_socket(Ref<NetSocket> p_sock); // Used by UDPServer
+ Error connect_shared_socket(Ref<NetSocket> p_sock, IP_Address p_ip, uint16_t p_port, UDPServer *ref); // Used by UDPServer
+ void disconnect_shared_socket(); // Used by UDPServer
+ Error store_packet(IP_Address p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size); // Used internally and by UDPServer
Error connect_to_host(const IP_Address &p_host, int p_port);
bool is_connected_to_host() const;
diff --git a/core/io/udp_server.cpp b/core/io/udp_server.cpp
index 1d329daf8b..acd15aadc6 100644
--- a/core/io/udp_server.cpp
+++ b/core/io/udp_server.cpp
@@ -32,10 +32,58 @@
void UDPServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &UDPServer::listen, DEFVAL("*"));
+ ClassDB::bind_method(D_METHOD("poll"), &UDPServer::poll);
ClassDB::bind_method(D_METHOD("is_connection_available"), &UDPServer::is_connection_available);
ClassDB::bind_method(D_METHOD("is_listening"), &UDPServer::is_listening);
ClassDB::bind_method(D_METHOD("take_connection"), &UDPServer::take_connection);
ClassDB::bind_method(D_METHOD("stop"), &UDPServer::stop);
+ ClassDB::bind_method(D_METHOD("set_max_pending_connections", "max_pending_connections"), &UDPServer::set_max_pending_connections);
+ ClassDB::bind_method(D_METHOD("get_max_pending_connections"), &UDPServer::get_max_pending_connections);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_pending_connections", PROPERTY_HINT_RANGE, "0,256,1"), "set_max_pending_connections", "get_max_pending_connections");
+}
+
+Error UDPServer::poll() {
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ if (!_sock->is_open()) {
+ return ERR_UNCONFIGURED;
+ }
+ Error err;
+ int read;
+ IP_Address ip;
+ uint16_t port;
+ while (true) {
+ err = _sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, ip, port);
+ if (err != OK) {
+ if (err == ERR_BUSY) {
+ break;
+ }
+ return FAILED;
+ }
+ Peer p;
+ p.ip = ip;
+ p.port = port;
+ List<Peer>::Element *E = peers.find(p);
+ if (!E) {
+ E = pending.find(p);
+ }
+ if (E) {
+ E->get().peer->store_packet(ip, port, recv_buffer, read);
+ } else {
+ if (pending.size() >= max_pending_connections) {
+ // Drop connection.
+ continue;
+ }
+ // It's a new peer, add it to the pending list.
+ Peer peer;
+ peer.ip = ip;
+ peer.port = port;
+ peer.peer = memnew(PacketPeerUDP);
+ peer.peer->connect_shared_socket(_sock, ip, port, this);
+ peer.peer->store_packet(ip, port, recv_buffer, read);
+ pending.push_back(peer);
+ }
+ }
+ return OK;
}
Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) {
@@ -82,8 +130,24 @@ bool UDPServer::is_connection_available() const {
return false;
}
- Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
- return (err == OK);
+ return pending.size() > 0;
+}
+
+void UDPServer::set_max_pending_connections(int p_max) {
+ ERR_FAIL_COND_MSG(p_max < 0, "Max pending connections value must be a positive number (0 means refuse new connections).");
+ max_pending_connections = p_max;
+ while (p_max > pending.size()) {
+ List<Peer>::Element *E = pending.back();
+ if (!E) {
+ break;
+ }
+ memdelete(E->get().peer);
+ pending.erase(E);
+ }
+}
+
+int UDPServer::get_max_pending_connections() const {
+ return max_pending_connections;
}
Ref<PacketPeerUDP> UDPServer::take_connection() {
@@ -92,11 +156,20 @@ Ref<PacketPeerUDP> UDPServer::take_connection() {
return conn;
}
- conn = Ref<PacketPeerUDP>(memnew(PacketPeerUDP));
- conn->connect_socket(_sock);
- _sock = Ref<NetSocket>(NetSocket::create());
- listen(bind_port, bind_address);
- return conn;
+ Peer peer = pending[0];
+ pending.pop_front();
+ peers.push_back(peer);
+ return peer.peer;
+}
+
+void UDPServer::remove_peer(IP_Address p_ip, int p_port) {
+ Peer peer;
+ peer.ip = p_ip;
+ peer.port = p_port;
+ List<Peer>::Element *E = peers.find(peer);
+ if (E) {
+ peers.erase(E);
+ }
}
void UDPServer::stop() {
@@ -105,6 +178,19 @@ void UDPServer::stop() {
}
bind_port = 0;
bind_address = IP_Address();
+ List<Peer>::Element *E = peers.front();
+ while (E) {
+ E->get().peer->disconnect_shared_socket();
+ E = E->next();
+ }
+ E = pending.front();
+ while (E) {
+ E->get().peer->disconnect_shared_socket();
+ memdelete(E->get().peer);
+ E = E->next();
+ }
+ peers.clear();
+ pending.clear();
}
UDPServer::UDPServer() :
diff --git a/core/io/udp_server.h b/core/io/udp_server.h
index 90bb82b62b..3175b09b19 100644
--- a/core/io/udp_server.h
+++ b/core/io/udp_server.h
@@ -38,15 +38,40 @@ class UDPServer : public Reference {
GDCLASS(UDPServer, Reference);
protected:
- static void _bind_methods();
- int bind_port;
+ enum {
+ PACKET_BUFFER_SIZE = 65536
+ };
+
+ struct Peer {
+ PacketPeerUDP *peer;
+ IP_Address ip;
+ uint16_t port = 0;
+
+ bool operator==(const Peer &p_other) const {
+ return (ip == p_other.ip && port == p_other.port);
+ }
+ };
+ uint8_t recv_buffer[PACKET_BUFFER_SIZE];
+
+ int bind_port = 0;
IP_Address bind_address;
+
+ List<Peer> peers;
+ List<Peer> pending;
+ int max_pending_connections = 16;
+
Ref<NetSocket> _sock;
+ static void _bind_methods();
+
public:
+ void remove_peer(IP_Address p_ip, int p_port);
Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*"));
+ Error poll();
bool is_listening() const;
bool is_connection_available() const;
+ void set_max_pending_connections(int p_max);
+ int get_max_pending_connections() const;
Ref<PacketPeerUDP> take_connection();
void stop();
diff --git a/doc/classes/UDPServer.xml b/doc/classes/UDPServer.xml
index f3c865c392..aabfed85f0 100644
--- a/doc/classes/UDPServer.xml
+++ b/doc/classes/UDPServer.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
A simple server that opens a UDP socket and returns connected [PacketPeerUDP] upon receiving new packets. See also [method PacketPeerUDP.connect_to_host].
+ After starting the server ([method listen]), you will need to [method poll] it at regular intervals (e.g. inside [method Node._process]) for it to process new packets, delivering them to the appropriate [PacketPeerUDP], and taking new connections.
Below a small example of how it can be used:
[codeblock]
# server.gd
@@ -17,6 +18,7 @@
server.listen(4242)
func _process(delta):
+ server.poll() # Important!
if server.is_connection_available():
var peer : PacketPeerUDP = server.take_connection()
var pkt = peer.get_packet()
@@ -57,7 +59,7 @@
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if a packet with a new address/port combination is received on the socket.
+ Returns [code]true[/code] if a packet with a new address/port combination was received on the socket.
</description>
</method>
<method name="is_listening" qualifiers="const">
@@ -78,21 +80,33 @@
Starts the server by opening a UDP socket listening on the given port. You can optionally specify a [code]bind_address[/code] to only listen for packets sent to that address. See also [method PacketPeerUDP.listen].
</description>
</method>
+ <method name="poll">
+ <return type="int" enum="Error">
+ </return>
+ <description>
+ Call this method at regular intervals (e.g. inside [method Node._process]) to process new packets. And packet from known address/port pair will be delivered to the appropriate [PacketPeerUDP], any packet received from an unknown address/port pair will be added as a pending connection (see [method is_connection_available], [method take_connection]). The maximum number of pending connection is defined via [member max_pending_connections].
+ </description>
+ </method>
<method name="stop">
<return type="void">
</return>
<description>
- Stops the server, closing the UDP socket if open. Will not disconnect any connected [PacketPeerUDP].
+ Stops the server, closing the UDP socket if open. Will close all connected [PacketPeerUDP] accepted via [method take_connection] (remote peers will not be notified).
</description>
</method>
<method name="take_connection">
<return type="PacketPeerUDP">
</return>
<description>
- Returns a [PacketPeerUDP] connected to the address/port combination of the first packet in queue. Will return [code]null[/code] if no packet is in queue. See also [method PacketPeerUDP.connect_to_host].
+ Returns the first pending connection (connected to the appropriate address/port). Will return [code]null[/code] if no new connection is available. See also [method is_connection_available], [method PacketPeerUDP.connect_to_host].
</description>
</method>
</methods>
+ <members>
+ <member name="max_pending_connections" type="int" setter="set_max_pending_connections" getter="get_max_pending_connections" default="16">
+ Define the maximum number of pending connections, during [method poll], any new pending connection exceeding that value will be automatically dropped. Setting this value to [code]0[/code] effectively prevents any new pending connection to be accepted (e.g. when all your players have connected).
+ </member>
+ </members>
<constants>
</constants>
</class>
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index 4e7698b67c..ed3924f2d2 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -640,6 +640,9 @@ int NetworkedMultiplayerENet::get_unique_id() const {
void NetworkedMultiplayerENet::set_refuse_new_connections(bool p_enable) {
refuse_connections = p_enable;
+#ifdef GODOT_ENET
+ enet_host_refuse_new_connections(host, p_enable);
+#endif
}
bool NetworkedMultiplayerENet::is_refusing_new_connections() const {
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
index 3900353c34..24d36647d9 100644
--- a/thirdparty/enet/enet/enet.h
+++ b/thirdparty/enet/enet/enet.h
@@ -13,7 +13,16 @@ extern "C"
#include <stdint.h>
#include <stdlib.h>
+// -- Godot start --
+#if 0
+#ifdef _WIN32
+#include "enet/win32.h"
+#else
+#include "enet/unix.h"
+#endif
+#endif
#include "enet/godot.h"
+// -- Godot end --
#include "enet/types.h"
#include "enet/protocol.h"
@@ -69,6 +78,7 @@ typedef enum _ENetSocketShutdown
ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
} ENetSocketShutdown;
+#define ENET_HOST_ANY 0
#define ENET_HOST_BROADCAST 0xFFFFFFFFU
#define ENET_PORT_ANY 0
@@ -82,13 +92,15 @@ typedef enum _ENetSocketShutdown
* but not for enet_host_create. Once a server responds to a broadcast, the
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
*/
+// -- Godot start --
+#if 0
typedef struct _ENetAddress
{
- uint8_t host[16];
+ enet_uint32 host;
enet_uint16 port;
- uint8_t wildcard;
} ENetAddress;
-#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
+#endif
+// -- Godot end --
/**
* Packet flag bit constants.
@@ -535,16 +547,6 @@ ENET_API int enet_address_set_host_ip (ENetAddress * address, const char * hostN
*/
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
-/** Sets the host field in the address parameter from ip struct.
- @param address destination to store resolved address
- @param ip the ip struct to read from
- @param size the size of the ip struct.
- @retval 0 on success
- @retval != 0 on failure
- @returns the address of the given ip in address on success.
-*/
-ENET_API void enet_address_set_ip(ENetAddress * address, const uint8_t * ip, size_t size);
-
/** Gives the printable form of the IP address specified in the address parameter.
@param address address printed
@param hostName destination for name, must not be NULL
@@ -585,8 +587,6 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t);
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
extern void enet_host_bandwidth_throttle (ENetHost *);
extern enet_uint32 enet_host_random_seed (void);
-ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
-ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
@@ -616,6 +616,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t,
extern size_t enet_protocol_command_size (enet_uint8);
+// -- Godot start --
+#include "enet/godot_ext.h"
+// -- Godot end --
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/enet/enet/godot.h b/thirdparty/enet/enet/godot.h
index 4f25ea9c7b..296b92763d 100644
--- a/thirdparty/enet/enet/godot.h
+++ b/thirdparty/enet/enet/godot.h
@@ -69,4 +69,12 @@ typedef struct
typedef void ENetSocketSet;
+typedef struct _ENetAddress
+{
+ uint8_t host[16];
+ uint16_t port;
+ uint8_t wildcard;
+} ENetAddress;
+#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
+
#endif /* __ENET_GODOT_H__ */
diff --git a/thirdparty/enet/enet/godot_ext.h b/thirdparty/enet/enet/godot_ext.h
new file mode 100644
index 0000000000..84a23b1c85
--- /dev/null
+++ b/thirdparty/enet/enet/godot_ext.h
@@ -0,0 +1,18 @@
+#ifndef __ENET_GODOT_EXT_H__
+#define __ENET_GODOT_EXT_H__
+
+/** Sets the host field in the address parameter from ip struct.
+ @param address destination to store resolved address
+ @param ip the ip struct to read from
+ @param size the size of the ip struct.
+ @retval 0 on success
+ @retval != 0 on failure
+ @returns the address of the given ip in address on success.
+*/
+ENET_API void enet_address_set_ip(ENetAddress * address, const uint8_t * ip, size_t size);
+
+ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
+ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
+ENET_API void enet_host_refuse_new_connections (ENetHost *, int);
+
+#endif // __ENET_GODOT_EXT_H__
diff --git a/thirdparty/enet/godot.cpp b/thirdparty/enet/godot.cpp
index 9fefa53e77..36b5131f80 100644
--- a/thirdparty/enet/godot.cpp
+++ b/thirdparty/enet/godot.cpp
@@ -51,6 +51,7 @@ public:
virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) = 0;
virtual int set_option(ENetSocketOption p_option, int p_value) = 0;
virtual void close() = 0;
+ virtual void set_refuse_new_connections(bool p_refuse) { /* Only used by dtls server */ }
virtual ~ENetGodotSocket(){};
};
@@ -250,6 +251,10 @@ public:
close();
}
+ void set_refuse_new_connections(bool p_refuse) {
+ udp_server->set_max_pending_connections(p_refuse ? 0 : 16);
+ }
+
Error bind(IP_Address p_ip, uint16_t p_port) {
return udp_server->listen(p_port, p_ip);
}
@@ -269,6 +274,7 @@ public:
}
Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
+ udp_server->poll();
// TODO limits? Maybe we can better enforce allowed connections!
if (udp_server->is_connection_available()) {
Ref<PacketPeerUDP> udp = udp_server->take_connection();
@@ -409,6 +415,11 @@ void enet_host_dtls_client_setup(ENetHost *host, void *p_cert, uint8_t p_verify,
memdelete(sock);
}
+void enet_host_refuse_new_connections(ENetHost *host, int p_refuse) {
+ ERR_FAIL_COND(!host->socket);
+ ((ENetGodotSocket *)host->socket)->set_refuse_new_connections(p_refuse);
+}
+
int enet_socket_bind(ENetSocket socket, const ENetAddress *address) {
IP_Address ip;
diff --git a/thirdparty/enet/patches/dtls_support.patch b/thirdparty/enet/patches/dtls_support.patch
deleted file mode 100644
index ce3480a858..0000000000
--- a/thirdparty/enet/patches/dtls_support.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
-index 966e3a465d..ac7552adb2 100644
---- a/thirdparty/enet/enet/enet.h
-+++ b/thirdparty/enet/enet/enet.h
-@@ -578,6 +578,8 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t);
- ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
- extern void enet_host_bandwidth_throttle (ENetHost *);
- extern enet_uint32 enet_host_random_seed (void);
-+ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
-+ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
-
- ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
- ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
diff --git a/thirdparty/enet/patches/ipv6_support.patch b/thirdparty/enet/patches/godot.patch
index 1f79863645..c8b4a5225d 100644
--- a/thirdparty/enet/patches/ipv6_support.patch
+++ b/thirdparty/enet/patches/godot.patch
@@ -1,61 +1,54 @@
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
-index 650b199ee5..246cbb0a62 100644
+index 54d91b5603..24d36647d9 100644
--- a/thirdparty/enet/enet/enet.h
+++ b/thirdparty/enet/enet/enet.h
-@@ -10,13 +10,10 @@ extern "C"
+@@ -10,13 +10,19 @@ extern "C"
{
#endif
+#include <stdint.h>
#include <stdlib.h>
--#ifdef _WIN32
--#include "enet/win32.h"
--#else
--#include "enet/unix.h"
--#endif
++// -- Godot start --
++#if 0
+ #ifdef _WIN32
+ #include "enet/win32.h"
+ #else
+ #include "enet/unix.h"
+ #endif
++#endif
+#include "enet/godot.h"
++// -- Godot end --
#include "enet/types.h"
#include "enet/protocol.h"
-@@ -72,7 +69,6 @@ typedef enum _ENetSocketShutdown
- ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
- } ENetSocketShutdown;
-
--#define ENET_HOST_ANY 0
- #define ENET_HOST_BROADCAST 0xFFFFFFFFU
- #define ENET_PORT_ANY 0
-
-@@ -88,9 +84,11 @@ typedef enum _ENetSocketShutdown
+@@ -86,11 +92,15 @@ typedef enum _ENetSocketShutdown
+ * but not for enet_host_create. Once a server responds to a broadcast, the
+ * address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
*/
++// -- Godot start --
++#if 0
typedef struct _ENetAddress
{
-- enet_uint32 host;
-+ uint8_t host[16];
+ enet_uint32 host;
enet_uint16 port;
-+ uint8_t wildcard;
} ENetAddress;
-+#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
++#endif
++// -- Godot end --
/**
* Packet flag bit constants.
-@@ -519,6 +517,16 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
- */
- ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
+@@ -606,6 +616,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t,
+
+ extern size_t enet_protocol_command_size (enet_uint8);
-+/** Sets the host field in the address parameter from ip struct.
-+ @param address destination to store resolved address
-+ @param ip the ip struct to read from
-+ @param size the size of the ip struct.
-+ @retval 0 on success
-+ @retval != 0 on failure
-+ @returns the address of the given ip in address on success.
-+*/
-+ENET_API void enet_address_set_ip(ENetAddress * address, const uint8_t * ip, size_t size);
++// -- Godot start --
++#include "enet/godot_ext.h"
++// -- Godot end --
+
- /** Gives the printable form of the IP address specified in the address parameter.
- @param address address printed
- @param hostName destination for name, must not be NULL
+ #ifdef __cplusplus
+ }
+ #endif
diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c
index 3be6c0922c..fc4da4ca67 100644
--- a/thirdparty/enet/host.c
@@ -70,10 +63,10 @@ index 3be6c0922c..fc4da4ca67 100644
host -> receivedData = NULL;
host -> receivedDataLength = 0;
diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c
-index 29d648732d..ab26886de4 100644
+index 0a60253173..fefc0e6f0a 100644
--- a/thirdparty/enet/protocol.c
+++ b/thirdparty/enet/protocol.c
-@@ -298,7 +298,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
+@@ -307,7 +307,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
}
else
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
@@ -82,7 +75,7 @@ index 29d648732d..ab26886de4 100644
{
if (currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> connectID == command -> connect.connectID)
-@@ -1010,9 +1010,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+@@ -1027,9 +1027,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
@@ -94,7 +87,7 @@ index 29d648732d..ab26886de4 100644
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
sessionID != peer -> incomingSessionID))
return 0;
-@@ -1054,7 +1053,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+@@ -1071,7 +1070,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer != NULL)
{