Merge e336b2a051
into fe1e5c2d5d
This commit is contained in:
commit
7d66d0cb54
|
@ -34,6 +34,16 @@
|
|||
#include "core/io/ip.h"
|
||||
#include "core/reference.h"
|
||||
|
||||
typedef struct {
|
||||
#ifdef WINDOWS_ENABLED
|
||||
size_t dataLength;
|
||||
void *data;
|
||||
#else
|
||||
void *data;
|
||||
size_t dataLength;
|
||||
#endif
|
||||
} NetSocketBuffer;
|
||||
|
||||
class NetSocket : public Reference {
|
||||
protected:
|
||||
static NetSocket *(*_create)();
|
||||
|
@ -63,6 +73,7 @@ public:
|
|||
virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port, bool p_peek = false) = 0;
|
||||
virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent) = 0;
|
||||
virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
|
||||
virtual Error sendmsg(const NetSocketBuffer *p_buffers, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
|
||||
virtual Ref<NetSocket> accept(IP_Address &r_ip, uint16_t &r_port) = 0;
|
||||
|
||||
virtual bool is_open() const = 0;
|
||||
|
|
|
@ -618,6 +618,43 @@ Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP
|
|||
return OK;
|
||||
}
|
||||
|
||||
Error NetSocketPosix::sendmsg(const NetSocketBuffer *p_buffers, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) {
|
||||
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
size_t addr_size = _set_addr_storage(&addr, p_ip, p_port, _ip_type);
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
DWORD sentLength = 0;
|
||||
if (WSASendTo(_sock, (LPWSABUF)p_buffers, (DWORD)p_len, &sentLength, 0, (struct sockaddr *)&addr, addr_size, NULL, NULL) == SOCKET_ERROR) {
|
||||
NetError err = _get_socket_error();
|
||||
if (err == ERR_NET_WOULD_BLOCK)
|
||||
return ERR_BUSY;
|
||||
|
||||
return FAILED;
|
||||
}
|
||||
r_sent = (int)sentLength;
|
||||
#else
|
||||
struct msghdr msgHdr;
|
||||
memset(&msgHdr, 0, sizeof(struct msghdr));
|
||||
msgHdr.msg_name = (struct sockaddr *)&addr;
|
||||
msgHdr.msg_namelen = addr_size;
|
||||
msgHdr.msg_iov = (struct iovec *)p_buffers;
|
||||
msgHdr.msg_iovlen = (int)p_len;
|
||||
|
||||
r_sent = ::sendmsg(_sock, &msgHdr, 0);
|
||||
if (r_sent < 0) {
|
||||
NetError err = _get_socket_error();
|
||||
if (err == ERR_NET_WOULD_BLOCK)
|
||||
return ERR_BUSY;
|
||||
|
||||
return FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error NetSocketPosix::set_broadcasting_enabled(bool p_enabled) {
|
||||
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
|
||||
// IPv6 has no broadcast support.
|
||||
|
|
|
@ -83,6 +83,7 @@ public:
|
|||
virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port, bool p_peek = false);
|
||||
virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent);
|
||||
virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port);
|
||||
virtual Error sendmsg(const NetSocketBuffer *p_buffers, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port);
|
||||
virtual Ref<NetSocket> accept(IP_Address &r_ip, uint16_t &r_port);
|
||||
|
||||
virtual bool is_open() const;
|
||||
|
|
|
@ -217,22 +217,25 @@ void NetworkedMultiplayerENet::poll() {
|
|||
|
||||
_pop_current_packet();
|
||||
|
||||
if (!host || !active) { // Might be disconnected
|
||||
return;
|
||||
}
|
||||
|
||||
ENetEvent event;
|
||||
/* Keep servicing until there are no available events left in queue. */
|
||||
while (true) {
|
||||
if (!host || !active) { // Might have been disconnected while emitting a notification
|
||||
int ret = enet_host_service(host, &event, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
ERR_FAIL_MSG("Enet host service error");
|
||||
} else if (ret == 0) {
|
||||
return; // No events
|
||||
}
|
||||
|
||||
/* Keep servicing until there are no available events left in the queue. */
|
||||
do {
|
||||
if (!host || !active) { // Check again after every event
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = enet_host_service(host, &event, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
// Error, do something?
|
||||
break;
|
||||
} else if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (event.type) {
|
||||
case ENET_EVENT_TYPE_CONNECT: {
|
||||
// Store any relevant client information here.
|
||||
|
@ -436,7 +439,7 @@ void NetworkedMultiplayerENet::poll() {
|
|||
// Do nothing
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} while (enet_host_check_events(host, &event) > 0);
|
||||
}
|
||||
|
||||
bool NetworkedMultiplayerENet::is_server() const {
|
||||
|
@ -546,9 +549,10 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
|
|||
packet_flags = ENET_PACKET_FLAG_UNSEQUENCED;
|
||||
}
|
||||
channel = SYSCH_UNRELIABLE;
|
||||
packet_flags |= ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT;
|
||||
} break;
|
||||
case TRANSFER_MODE_UNRELIABLE_ORDERED: {
|
||||
packet_flags = 0;
|
||||
packet_flags = ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT;
|
||||
channel = SYSCH_UNRELIABLE;
|
||||
} break;
|
||||
case TRANSFER_MODE_RELIABLE: {
|
||||
|
|
5
thirdparty/enet/enet/godot.h
vendored
5
thirdparty/enet/enet/godot.h
vendored
|
@ -59,8 +59,13 @@ typedef void *ENetSocket;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef WINDOWS_ENABLED
|
||||
size_t dataLength;
|
||||
void *data;
|
||||
#else
|
||||
void *data;
|
||||
size_t dataLength;
|
||||
#endif
|
||||
} ENetBuffer;
|
||||
|
||||
#define ENET_CALLBACK
|
||||
|
|
56
thirdparty/enet/godot.cpp
vendored
56
thirdparty/enet/godot.cpp
vendored
|
@ -48,6 +48,7 @@ class ENetGodotSocket {
|
|||
public:
|
||||
virtual Error bind(IP_Address p_ip, uint16_t p_port) = 0;
|
||||
virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
|
||||
virtual Error sendmsg(const NetSocketBuffer *p_buffers, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
|
||||
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;
|
||||
|
@ -93,6 +94,10 @@ public:
|
|||
return sock->sendto(p_buffer, p_len, r_sent, p_ip, p_port);
|
||||
}
|
||||
|
||||
Error sendmsg(const NetSocketBuffer *p_buffers, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) {
|
||||
return sock->sendmsg(p_buffers, p_len, r_sent, p_ip, p_port);
|
||||
}
|
||||
|
||||
Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
|
||||
Error err = sock->poll(NetSocket::POLL_TYPE_IN, 0);
|
||||
if (err != OK) {
|
||||
|
@ -196,6 +201,22 @@ public:
|
|||
return dtls->put_packet(p_buffer, p_len);
|
||||
}
|
||||
|
||||
Error sendmsg(const NetSocketBuffer *p_buffers, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) {
|
||||
r_sent = 0;
|
||||
for(int i = 0; i < p_len; i++) {
|
||||
int sent = 0;
|
||||
Error e = sendto((const uint8_t *)p_buffers[i].data, p_buffers[i].dataLength, sent, p_ip, p_port);
|
||||
if(e != OK) {
|
||||
return e;
|
||||
}
|
||||
r_sent += sent;
|
||||
if(sent < p_buffers[i].dataLength) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
|
||||
dtls->poll();
|
||||
if (dtls->get_status() == PacketPeerDTLS::STATUS_HANDSHAKING) {
|
||||
|
@ -279,6 +300,22 @@ public:
|
|||
return err;
|
||||
}
|
||||
|
||||
Error sendmsg(const NetSocketBuffer *p_buffers, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) {
|
||||
r_sent = 0;
|
||||
for(int i = 0; i < p_len; i++) {
|
||||
int sent = 0;
|
||||
Error e = sendto((const uint8_t *)p_buffers[i].data, p_buffers[i].dataLength, sent, p_ip, p_port);
|
||||
if(e != OK) {
|
||||
return e;
|
||||
}
|
||||
r_sent += sent;
|
||||
if(sent < p_buffers[i].dataLength) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
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!
|
||||
|
@ -459,26 +496,9 @@ int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBu
|
|||
|
||||
dest.set_ipv6(address->host);
|
||||
|
||||
// Create a single packet.
|
||||
PoolVector<uint8_t> out;
|
||||
PoolVector<uint8_t>::Write w;
|
||||
int size = 0;
|
||||
int pos = 0;
|
||||
for (i = 0; i < bufferCount; i++) {
|
||||
size += buffers[i].dataLength;
|
||||
}
|
||||
|
||||
out.resize(size);
|
||||
w = out.write();
|
||||
for (i = 0; i < bufferCount; i++) {
|
||||
memcpy(&w[pos], buffers[i].data, buffers[i].dataLength);
|
||||
pos += buffers[i].dataLength;
|
||||
}
|
||||
|
||||
int sent = 0;
|
||||
err = sock->sendto((const uint8_t *)&w[0], size, sent, dest, address->port);
|
||||
err = sock->sendmsg((const NetSocketBuffer*)buffers, bufferCount, sent, dest, address->port);
|
||||
if (err != OK) {
|
||||
|
||||
if (err == ERR_BUSY) { // Blocking call
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue