1
0
Fork 0

Merge pull request #7985 from Faless/enet_godot_sock_squash

Update ENet to use Godot sockets.
This commit is contained in:
Rémi Verschelde 2017-03-24 22:47:18 +01:00 committed by GitHub
commit 296ece2c6a
19 changed files with 423 additions and 1199 deletions

View File

@ -31,6 +31,11 @@
PacketPeerUDP *(*PacketPeerUDP::_create)() = NULL; PacketPeerUDP *(*PacketPeerUDP::_create)() = NULL;
void PacketPeerUDP::set_blocking_mode(bool p_enable) {
blocking = p_enable;
}
String PacketPeerUDP::_get_packet_ip() const { String PacketPeerUDP::_get_packet_ip() const {
return get_packet_address(); return get_packet_address();
@ -78,4 +83,6 @@ PacketPeerUDP *PacketPeerUDP::create() {
} }
PacketPeerUDP::PacketPeerUDP() { PacketPeerUDP::PacketPeerUDP() {
blocking = true;
} }

View File

@ -36,6 +36,8 @@ class PacketPeerUDP : public PacketPeer {
GDCLASS(PacketPeerUDP, PacketPeer); GDCLASS(PacketPeerUDP, PacketPeer);
protected: protected:
bool blocking;
static PacketPeerUDP *(*_create)(); static PacketPeerUDP *(*_create)();
static void _bind_methods(); static void _bind_methods();
@ -44,6 +46,8 @@ protected:
Error _set_dest_address(const String &p_address, int p_port); Error _set_dest_address(const String &p_address, int p_port);
public: public:
void set_blocking_mode(bool p_enable);
virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0; virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0;
virtual void close() = 0; virtual void close() = 0;
virtual Error wait() = 0; virtual Error wait() = 0;

View File

@ -107,10 +107,14 @@ Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer, int p_buffer_size)
errno = 0; errno = 0;
int err; int err;
_set_sock_blocking(blocking);
while ((err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr *)&addr, addr_size)) != p_buffer_size) { while ((err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr *)&addr, addr_size)) != p_buffer_size) {
if (errno != EAGAIN) { if (errno != EAGAIN) {
return FAILED; return FAILED;
} else if (!blocking) {
return ERR_UNAVAILABLE;
} }
} }
@ -173,10 +177,12 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) {
return FAILED; return FAILED;
} }
_set_sock_blocking(p_wait);
struct sockaddr_storage from = { 0 }; struct sockaddr_storage from = { 0 };
socklen_t len = sizeof(struct sockaddr_storage); socklen_t len = sizeof(struct sockaddr_storage);
int ret; int ret;
while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), p_wait ? 0 : MSG_DONTWAIT, (struct sockaddr *)&from, &len)) > 0) { while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), 0, (struct sockaddr *)&from, &len)) > 0) {
uint32_t port = 0; uint32_t port = 0;
@ -243,9 +249,35 @@ int PacketPeerUDPPosix::_get_socket() {
sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP); sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd != -1)
_set_sock_blocking(false);
return sockfd; return sockfd;
} }
void PacketPeerUDPPosix::_set_sock_blocking(bool p_blocking) {
if (sock_blocking == p_blocking)
return;
sock_blocking = p_blocking;
#ifndef NO_FCNTL
int opts = fcntl(sockfd, F_GETFL);
int ret = 0;
if (sock_blocking)
ret = fcntl(sockfd, F_SETFL, opts & ~O_NONBLOCK);
else
ret = fcntl(sockfd, F_SETFL, opts | O_NONBLOCK);
if (ret == -1)
perror("setting non-block mode");
#else
int bval = sock_blocking ? 0 : 1;
if (ioctl(sockfd, FIONBIO, &bval) == -1)
perror("setting non-block mode");
#endif
}
void PacketPeerUDPPosix::set_dest_address(const IP_Address &p_address, int p_port) { void PacketPeerUDPPosix::set_dest_address(const IP_Address &p_address, int p_port) {
peer_addr = p_address; peer_addr = p_address;
@ -264,6 +296,8 @@ void PacketPeerUDPPosix::make_default() {
PacketPeerUDPPosix::PacketPeerUDPPosix() { PacketPeerUDPPosix::PacketPeerUDPPosix() {
blocking = true;
sock_blocking = true;
sockfd = -1; sockfd = -1;
packet_port = 0; packet_port = 0;
queue_count = 0; queue_count = 0;

View File

@ -47,6 +47,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP {
mutable int packet_port; mutable int packet_port;
mutable int queue_count; mutable int queue_count;
int sockfd; int sockfd;
bool sock_blocking;
IP::Type sock_type; IP::Type sock_type;
IP_Address peer_addr; IP_Address peer_addr;
@ -55,6 +56,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP {
_FORCE_INLINE_ int _get_socket(); _FORCE_INLINE_ int _get_socket();
static PacketPeerUDP *_create(); static PacketPeerUDP *_create();
void _set_sock_blocking(bool p_blocking);
virtual Error _poll(bool p_block); virtual Error _poll(bool p_block);
public: public:

View File

@ -10,6 +10,7 @@ env_enet = env_modules.Clone()
if (env['builtin_enet'] != 'no'): if (env['builtin_enet'] != 'no'):
thirdparty_dir = "#thirdparty/enet/" thirdparty_dir = "#thirdparty/enet/"
thirdparty_sources = [ thirdparty_sources = [
"godot.cpp",
"callbacks.c", "callbacks.c",
"compress.c", "compress.c",
"host.c", "host.c",
@ -17,12 +18,11 @@ if (env['builtin_enet'] != 'no'):
"packet.c", "packet.c",
"peer.c", "peer.c",
"protocol.c", "protocol.c",
"unix.c",
"win32.c",
] ]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_enet.add_source_files(env.modules_sources, thirdparty_sources) env_enet.add_source_files(env.modules_sources, thirdparty_sources)
env_enet.Append(CPPPATH=[thirdparty_dir]) env_enet.Append(CPPPATH=[thirdparty_dir])
env_enet.Append(CPPFLAGS=["-DGODOT_ENET"])
env_enet.add_source_files(env.modules_sources, "*.cpp") env_enet.add_source_files(env.modules_sources, "*.cpp")

View File

@ -53,8 +53,21 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
ENetAddress address; ENetAddress address;
address.host = bind_ip;
#ifdef GODOT_ENET
if (bind_ip.is_wildcard()) {
address.wildcard = 1;
} else {
enet_address_set_ip(&address, bind_ip.get_ipv6(), 16);
}
#else
if (bind_ip.is_wildcard()) {
address.host = 0;
} else {
ERR_FAIL_COND_V(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER);
address.host = *(uint32_t *)bind_ip.get_ipv4();
}
#endif
address.port = p_port; address.port = p_port;
host = enet_host_create(&address /* the address to bind the server host to */, host = enet_host_create(&address /* the address to bind the server host to */,
@ -76,7 +89,6 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port, int p_in_bandwidth, int p_out_bandwidth) { Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port, int p_in_bandwidth, int p_out_bandwidth) {
ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(!p_ip.is_ipv4(), ERR_INVALID_PARAMETER);
host = enet_host_create(NULL /* create a client host */, host = enet_host_create(NULL /* create a client host */,
1 /* only allow 1 outgoing connection */, 1 /* only allow 1 outgoing connection */,
@ -89,7 +101,12 @@ Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port
_setup_compressor(); _setup_compressor();
ENetAddress address; ENetAddress address;
address.host = *((uint32_t *)p_ip.get_ipv4()); #ifdef GODOT_ENET
enet_address_set_ip(&address, p_ip.get_ipv6(), 16);
#else
ERR_FAIL_COND_V(!p_ip.is_ipv4(), ERR_INVALID_PARAMETER);
address.host = *(uint32_t *)p_ip.get_ipv4();
#endif
address.port = p_port; address.port = p_port;
//enet_address_set_host (& address, "localhost"); //enet_address_set_host (& address, "localhost");
@ -146,9 +163,6 @@ void NetworkedMultiplayerENet::poll() {
break; break;
} }
IP_Address ip;
ip.set_ipv4((uint8_t *)&(event.peer->address.host));
int *new_id = memnew(int); int *new_id = memnew(int);
*new_id = event.data; *new_id = event.data;
@ -657,7 +671,7 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
enet_compressor.decompress = enet_decompress; enet_compressor.decompress = enet_decompress;
enet_compressor.destroy = enet_compressor_destroy; enet_compressor.destroy = enet_compressor_destroy;
bind_ip = ENET_HOST_ANY; bind_ip = IP_Address("*");
} }
NetworkedMultiplayerENet::~NetworkedMultiplayerENet() { NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
@ -668,6 +682,7 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
// sets IP for ENet to bind when using create_server // sets IP for ENet to bind when using create_server
// if no IP is set, then ENet bind to ENET_HOST_ANY // if no IP is set, then ENet bind to ENET_HOST_ANY
void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) { void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) {
ERR_FAIL_COND(!p_ip.is_ipv4()); ERR_FAIL_COND(!p_ip.is_valid() && !p_ip.is_wildcard());
bind_ip = *(uint32_t *)p_ip.get_ipv4();
bind_ip = p_ip;
} }

View File

@ -100,7 +100,7 @@ private:
static void enet_compressor_destroy(void *context); static void enet_compressor_destroy(void *context);
void _setup_compressor(); void _setup_compressor();
enet_uint32 bind_ip; IP_Address bind_ip;
protected: protected:
static void _bind_methods(); static void _bind_methods();

View File

@ -82,7 +82,7 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz
struct sockaddr_storage addr; struct sockaddr_storage addr;
size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, sock_type); size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, sock_type);
_set_blocking(true); _set_sock_blocking(blocking);
errno = 0; errno = 0;
int err; int err;
@ -90,7 +90,9 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz
if (WSAGetLastError() != WSAEWOULDBLOCK) { if (WSAGetLastError() != WSAEWOULDBLOCK) {
return FAILED; return FAILED;
}; } else if (!blocking) {
return ERR_UNAVAILABLE;
}
} }
return OK; return OK;
@ -101,15 +103,13 @@ int PacketPeerUDPWinsock::get_max_packet_size() const {
return 512; // uhm maybe not return 512; // uhm maybe not
} }
void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) { void PacketPeerUDPWinsock::_set_sock_blocking(bool p_blocking) {
//am no windows expert
//hope this is the right thing
if (blocking == p_blocking) if (sock_blocking == p_blocking)
return; return;
blocking = p_blocking; sock_blocking = p_blocking;
unsigned long par = blocking ? 0 : 1; unsigned long par = sock_blocking ? 0 : 1;
if (ioctlsocket(sockfd, FIONBIO, &par)) { if (ioctlsocket(sockfd, FIONBIO, &par)) {
perror("setting non-block mode"); perror("setting non-block mode");
//close(); //close();
@ -139,8 +139,6 @@ Error PacketPeerUDPWinsock::listen(int p_port, IP_Address p_bind_address, int p_
return ERR_UNAVAILABLE; return ERR_UNAVAILABLE;
} }
blocking = true;
printf("UDP Connection listening on port %i\n", p_port); printf("UDP Connection listening on port %i\n", p_port);
rb.resize(nearest_shift(p_recv_buffer_size)); rb.resize(nearest_shift(p_recv_buffer_size));
return OK; return OK;
@ -166,7 +164,7 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) {
return FAILED; return FAILED;
} }
_set_blocking(p_wait); _set_sock_blocking(p_wait);
struct sockaddr_storage from = { 0 }; struct sockaddr_storage from = { 0 };
int len = sizeof(struct sockaddr_storage); int len = sizeof(struct sockaddr_storage);
@ -252,6 +250,9 @@ int PacketPeerUDPWinsock::_get_socket() {
sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP); sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd != -1)
_set_sock_blocking(false);
return sockfd; return sockfd;
} }
@ -273,6 +274,8 @@ PacketPeerUDP *PacketPeerUDPWinsock::_create() {
PacketPeerUDPWinsock::PacketPeerUDPWinsock() { PacketPeerUDPWinsock::PacketPeerUDPWinsock() {
blocking = true;
sock_blocking = true;
sockfd = -1; sockfd = -1;
packet_port = 0; packet_port = 0;
queue_count = 0; queue_count = 0;

View File

@ -45,6 +45,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP {
mutable int packet_port; mutable int packet_port;
mutable int queue_count; mutable int queue_count;
int sockfd; int sockfd;
bool sock_blocking;
IP::Type sock_type; IP::Type sock_type;
IP_Address peer_addr; IP_Address peer_addr;
@ -54,8 +55,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP {
static PacketPeerUDP *_create(); static PacketPeerUDP *_create();
bool blocking; void _set_sock_blocking(bool p_blocking);
void _set_blocking(bool p_blocking);
Error _poll(bool p_wait); Error _poll(bool p_wait);

15
thirdparty/README.md vendored
View File

@ -16,13 +16,18 @@ TODO.
Files extracted from upstream source: Files extracted from upstream source:
- all .c files in the main directory - all .c files in the main directory (except unix.c win32.c)
- the include/enet/ folder as enet/ - the include/enet/ folder as enet/ (except unix.h win32.h)
- LICENSE file - LICENSE file
Important: Some files have been modified by Godot developers so that they work Important: enet.h, host.c, protocol.c have been slightly modified
for all platforms (especially UWP). Check the diff with the 1.3.13 tarball to be usable by godot socket implementation and allow IPv6.
before the next update. Two files (godot.cpp and enet/godot.h) have been added to provide
enet socket implementation using Godot classes.
It is still possible to build against a system wide ENet but doing so
will limit it's functionality to IPv4 only.
Check the diff of enet.h, protocol.c, and host.c with the 1.3.13
tarball before the next update.
## fonts ## fonts

View File

@ -12,11 +12,7 @@ extern "C"
#include <stdlib.h> #include <stdlib.h>
#ifdef _WIN32 #include "enet/godot.h"
#include "enet/win32.h"
#else
#include "enet/unix.h"
#endif
#include "enet/types.h" #include "enet/types.h"
#include "enet/protocol.h" #include "enet/protocol.h"
@ -72,7 +68,6 @@ typedef enum _ENetSocketShutdown
ENET_SOCKET_SHUTDOWN_READ_WRITE = 2 ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
} ENetSocketShutdown; } ENetSocketShutdown;
#define ENET_HOST_ANY 0
#define ENET_HOST_BROADCAST 0xFFFFFFFFU #define ENET_HOST_BROADCAST 0xFFFFFFFFU
#define ENET_PORT_ANY 0 #define ENET_PORT_ANY 0
@ -88,9 +83,11 @@ typedef enum _ENetSocketShutdown
*/ */
typedef struct _ENetAddress typedef struct _ENetAddress
{ {
enet_uint32 host; uint8_t host[16];
enet_uint16 port; enet_uint16 port;
uint8_t wildcard;
} ENetAddress; } ENetAddress;
#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
/** /**
* Packet flag bit constants. * Packet flag bit constants.
@ -519,6 +516,16 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
*/ */
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName); 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. /** Gives the printable form of the IP address specified in the address parameter.
@param address address printed @param address address printed
@param hostName destination for name, must not be NULL @param hostName destination for name, must not be NULL

71
thirdparty/enet/enet/godot.h vendored Normal file
View File

@ -0,0 +1,71 @@
/*************************************************************************/
/* godot.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
/**
@file godot.h
@brief ENet Godot header
*/
#ifndef __ENET_GODOT_H__
#define __ENET_GODOT_H__
#ifdef WINDOWS_ENABLED
#include <stdint.h>
#include <winsock2.h>
#endif
#ifdef UNIX_ENABLED
#include <arpa/inet.h>
#endif
#ifdef MSG_MAXIOVLEN
#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
#endif
typedef void *ENetSocket;
#define ENET_SOCKET_NULL NULL
#define ENET_HOST_TO_NET_16(value) (htons(value)) /**< macro that converts host to net byte-order of a 16-bit value */
#define ENET_HOST_TO_NET_32(value) (htonl(value)) /**< macro that converts host to net byte-order of a 32-bit value */
#define ENET_NET_TO_HOST_16(value) (ntohs(value)) /**< macro that converts net to host byte-order of a 16-bit value */
#define ENET_NET_TO_HOST_32(value) (ntohl(value)) /**< macro that converts net to host byte-order of a 32-bit value */
typedef struct
{
void *data;
size_t dataLength;
} ENetBuffer;
#define ENET_CALLBACK
#define ENET_API extern
typedef void ENetSocketSet;
#endif /* __ENET_GODOT_H__ */

View File

@ -1,47 +0,0 @@
/**
@file unix.h
@brief ENet Unix header
*/
#ifndef __ENET_UNIX_H__
#define __ENET_UNIX_H__
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#ifdef MSG_MAXIOVLEN
#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
#endif
typedef int ENetSocket;
#define ENET_SOCKET_NULL -1
#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
typedef struct
{
void * data;
size_t dataLength;
} ENetBuffer;
#define ENET_CALLBACK
#define ENET_API extern
typedef fd_set ENetSocketSet;
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
#endif /* __ENET_UNIX_H__ */

View File

@ -1,57 +0,0 @@
/**
@file win32.h
@brief ENet Win32 header
*/
#ifndef __ENET_WIN32_H__
#define __ENET_WIN32_H__
#ifdef _MSC_VER
#ifdef ENET_BUILDING_LIB
#pragma warning (disable: 4267) // size_t to int conversion
#pragma warning (disable: 4244) // 64bit to 32bit int
#pragma warning (disable: 4018) // signed/unsigned mismatch
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type
#endif
#endif
#include <stdlib.h>
#include <winsock2.h>
typedef SOCKET ENetSocket;
#define ENET_SOCKET_NULL INVALID_SOCKET
#define ENET_HOST_TO_NET_16(value) (htons (value))
#define ENET_HOST_TO_NET_32(value) (htonl (value))
#define ENET_NET_TO_HOST_16(value) (ntohs (value))
#define ENET_NET_TO_HOST_32(value) (ntohl (value))
typedef struct
{
size_t dataLength;
void * data;
} ENetBuffer;
#define ENET_CALLBACK __cdecl
#ifdef ENET_DLL
#ifdef ENET_BUILDING_LIB
#define ENET_API __declspec( dllexport )
#else
#define ENET_API __declspec( dllimport )
#endif /* ENET_BUILDING_LIB */
#else /* !ENET_DLL */
#define ENET_API extern
#endif /* ENET_DLL */
typedef fd_set ENetSocketSet;
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
#endif /* __ENET_WIN32_H__ */

232
thirdparty/enet/godot.cpp vendored Normal file
View File

@ -0,0 +1,232 @@
/*************************************************************************/
/* godot.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
/**
@file godot.cpp
@brief ENet Godot specific functions
*/
#include "core/io/ip.h"
#include "core/io/packet_peer_udp.h"
#include "core/os/os.h"
// This must be last for windows to compile (tested with MinGW)
#include "enet/enet.h"
static enet_uint32 timeBase = 0;
int enet_initialize(void) {
return 0;
}
void enet_deinitialize(void) {
}
enet_uint32 enet_host_random_seed(void) {
return (enet_uint32)OS::get_singleton()->get_unix_time();
}
enet_uint32 enet_time_get(void) {
return OS::get_singleton()->get_ticks_msec() - timeBase;
}
void enet_time_set(enet_uint32 newTimeBase) {
timeBase = OS::get_singleton()->get_ticks_msec() - newTimeBase;
}
int enet_address_set_host(ENetAddress *address, const char *name) {
IP_Address ip = IP::get_singleton()->resolve_hostname(name);
ERR_FAIL_COND_V(!ip.is_valid(), -1);
enet_address_set_ip(address, ip.get_ipv6(), 16);
return 0;
}
void enet_address_set_ip(ENetAddress *address, const uint8_t *ip, size_t size) {
int len = size > 16 ? 16 : size;
memset(address->host, 0, 16);
memcpy(address->host, ip, len);
}
int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) {
return -1;
}
int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) {
return -1;
}
int enet_socket_bind(ENetSocket socket, const ENetAddress *address) {
IP_Address ip;
if (address->wildcard) {
ip = IP_Address("*");
} else {
ip.set_ipv6(address->host);
}
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
if (sock->listen(address->port, ip) != OK) {
return -1;
}
return 0;
}
ENetSocket enet_socket_create(ENetSocketType type) {
PacketPeerUDP *socket = PacketPeerUDP::create();
socket->set_blocking_mode(false);
return socket;
}
void enet_socket_destroy(ENetSocket socket) {
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
sock->close();
memdelete(sock);
}
int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBuffer *buffers, size_t bufferCount) {
ERR_FAIL_COND_V(address == NULL, -1);
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
IP_Address dest;
Error err;
size_t i = 0;
dest.set_ipv6(address->host);
sock->set_dest_address(dest, address->port);
// 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;
}
err = sock->put_packet((const uint8_t *)&w[0], size);
if (err != OK) {
if (err == ERR_UNAVAILABLE) { // blocking call
return 0;
}
WARN_PRINT("Sending failed!");
return -1;
}
return size;
}
int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) {
ERR_FAIL_COND_V(bufferCount != 1, -1);
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
if (sock->get_available_packet_count() == 0) {
return 0;
}
const uint8_t *buffer;
int buffer_size;
Error err = sock->get_packet(&buffer, buffer_size);
if (err)
return -1;
copymem(buffers[0].data, buffer, buffer_size);
enet_address_set_ip(address, sock->get_packet_address().get_ipv6(), 16);
address->port = sock->get_packet_port();
return buffer_size;
}
// Not implemented
int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint32 timeout) {
return 0; // do we need this function?
}
int enet_socket_get_address(ENetSocket socket, ENetAddress *address) {
return -1; // do we need this function?
}
int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) {
return -1;
}
int enet_socket_listen(ENetSocket socket, int backlog) {
return -1;
}
int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) {
return -1;
}
int enet_socket_get_option(ENetSocket socket, ENetSocketOption option, int *value) {
return -1;
}
int enet_socket_connect(ENetSocket socket, const ENetAddress *address) {
return -1;
}
ENetSocket enet_socket_accept(ENetSocket socket, ENetAddress *address) {
return NULL;
}
int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) {
return -1;
}

View File

@ -87,7 +87,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
host -> commandCount = 0; host -> commandCount = 0;
host -> bufferCount = 0; host -> bufferCount = 0;
host -> checksum = NULL; host -> checksum = NULL;
host -> receivedAddress.host = ENET_HOST_ANY; memset(host -> receivedAddress.host, 0, 16);
host -> receivedAddress.port = 0; host -> receivedAddress.port = 0;
host -> receivedData = NULL; host -> receivedData = NULL;
host -> receivedDataLength = 0; host -> receivedDataLength = 0;

View File

@ -299,7 +299,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
} }
else else
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING && if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
currentPeer -> address.host == host -> receivedAddress.host) enet_host_equal(currentPeer -> address.host, host -> receivedAddress.host))
{ {
if (currentPeer -> address.port == host -> receivedAddress.port && if (currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> connectID == command -> connect.connectID) currentPeer -> connectID == command -> connect.connectID)
@ -1011,9 +1011,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED || if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ZOMBIE ||
((host -> receivedAddress.host != peer -> address.host || (!enet_host_equal(host -> receivedAddress.host, peer -> address.host) ||
host -> receivedAddress.port != peer -> address.port) && host -> receivedAddress.port != peer -> address.port) ||
peer -> address.host != ENET_HOST_BROADCAST) ||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
sessionID != peer -> incomingSessionID)) sessionID != peer -> incomingSessionID))
return 0; return 0;
@ -1055,7 +1054,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer != NULL) if (peer != NULL)
{ {
peer -> address.host = host -> receivedAddress.host; enet_address_set_ip(&(peer -> address), host -> receivedAddress.host, 16);
peer -> address.port = host -> receivedAddress.port; peer -> address.port = host -> receivedAddress.port;
peer -> incomingDataTotal += host -> receivedDataLength; peer -> incomingDataTotal += host -> receivedDataLength;
} }

616
thirdparty/enet/unix.c vendored
View File

@ -1,616 +0,0 @@
/**
@file unix.c
@brief ENet Unix system specific functions
*/
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
//@godot: added this since enet takes them fromt he build system
#define HAS_POLL
#define HAS_FCNTL
#define HAS_SOCKLEN_T
#ifdef __APPLE__
#ifdef HAS_POLL
#undef HAS_POLL
#endif
#ifndef HAS_FCNTL
#define HAS_FCNTL 1
#endif
#ifndef HAS_INET_PTON
#define HAS_INET_PTON 1
#endif
#ifndef HAS_INET_NTOP
#define HAS_INET_NTOP 1
#endif
#ifndef HAS_MSGHDR_FLAGS
#define HAS_MSGHDR_FLAGS 1
#endif
#ifndef HAS_SOCKLEN_T
#define HAS_SOCKLEN_T 1
#endif
#ifndef HAS_GETADDRINFO
#define HAS_GETADDRINFO 1
#endif
#ifndef HAS_GETNAMEINFO
#define HAS_GETNAMEINFO 1
#endif
#endif
#ifdef HAS_FCNTL
#include <fcntl.h>
#endif
#ifdef HAS_POLL
#include <sys/poll.h>
#endif
#ifndef HAS_SOCKLEN_T
typedef int socklen_t;
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
static enet_uint32 timeBase = 0;
int
enet_initialize (void)
{
return 0;
}
void
enet_deinitialize (void)
{
}
enet_uint32
enet_host_random_seed (void)
{
return (enet_uint32) time (NULL);
}
enet_uint32
enet_time_get (void)
{
struct timeval timeVal;
gettimeofday (& timeVal, NULL);
return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
}
void
enet_time_set (enet_uint32 newTimeBase)
{
struct timeval timeVal;
gettimeofday (& timeVal, NULL);
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
}
int
enet_address_set_host (ENetAddress * address, const char * name)
{
#ifdef HAS_GETADDRINFO
struct addrinfo hints, * resultList = NULL, * result = NULL;
memset (& hints, 0, sizeof (hints));
hints.ai_family = AF_INET;
if (getaddrinfo (name, NULL, NULL, & resultList) != 0)
return -1;
for (result = resultList; result != NULL; result = result -> ai_next)
{
if (result -> ai_family == AF_INET && result -> ai_addr != NULL && result -> ai_addrlen >= sizeof (struct sockaddr_in))
{
struct sockaddr_in * sin = (struct sockaddr_in *) result -> ai_addr;
address -> host = sin -> sin_addr.s_addr;
freeaddrinfo (resultList);
return 0;
}
}
if (resultList != NULL)
freeaddrinfo (resultList);
#else
struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYNAME_R
struct hostent hostData;
char buffer [2048];
int errnum;
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
hostEntry = gethostbyname (name);
#endif
if (hostEntry != NULL && hostEntry -> h_addrtype == AF_INET)
{
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
return 0;
}
#endif
#ifdef HAS_INET_PTON
if (! inet_pton (AF_INET, name, & address -> host))
#else
if (! inet_aton (name, (struct in_addr *) & address -> host))
#endif
return -1;
return 0;
}
int
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
{
#ifdef HAS_INET_NTOP
if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
#else
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
if (addr != NULL)
{
size_t addrLen = strlen(addr);
if (addrLen >= nameLength)
return -1;
memcpy (name, addr, addrLen + 1);
}
else
#endif
return -1;
return 0;
}
int
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
#ifdef HAS_GETNAMEINFO
struct sockaddr_in sin;
int err;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
err = getnameinfo ((struct sockaddr *) & sin, sizeof (sin), name, nameLength, NULL, 0, NI_NAMEREQD);
if (! err)
{
if (name != NULL && nameLength > 0 && ! memchr (name, '\0', nameLength))
return -1;
return 0;
}
if (err != EAI_NONAME)
return -1;
#else
struct in_addr in;
struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYADDR_R
struct hostent hostData;
char buffer [2048];
int errnum;
in.s_addr = address -> host;
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
#endif
#else
in.s_addr = address -> host;
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
#endif
if (hostEntry != NULL)
{
size_t hostLen = strlen (hostEntry -> h_name);
if (hostLen >= nameLength)
return -1;
memcpy (name, hostEntry -> h_name, hostLen + 1);
return 0;
}
#endif
return enet_address_get_host_ip (address, name, nameLength);
}
int
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
if (address != NULL)
{
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
else
{
sin.sin_port = 0;
sin.sin_addr.s_addr = INADDR_ANY;
}
return bind (socket,
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in));
}
int
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
{
struct sockaddr_in sin;
socklen_t sinLength = sizeof (struct sockaddr_in);
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
return -1;
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
return 0;
}
int
enet_socket_listen (ENetSocket socket, int backlog)
{
return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
}
ENetSocket
enet_socket_create (ENetSocketType type)
{
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
{
int result = -1;
switch (option)
{
case ENET_SOCKOPT_NONBLOCK:
#ifdef HAS_FCNTL
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL) & ~O_NONBLOCK));
#else
result = ioctl (socket, FIONBIO, & value);
#endif
break;
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVBUF:
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_SNDBUF:
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVTIMEO:
{
struct timeval timeVal;
timeVal.tv_sec = value / 1000;
timeVal.tv_usec = (value % 1000) * 1000;
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & timeVal, sizeof (struct timeval));
break;
}
case ENET_SOCKOPT_SNDTIMEO:
{
struct timeval timeVal;
timeVal.tv_sec = value / 1000;
timeVal.tv_usec = (value % 1000) * 1000;
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval));
break;
}
case ENET_SOCKOPT_NODELAY:
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break;
default:
break;
}
return result == -1 ? -1 : 0;
}
int
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
{
int result = -1;
socklen_t len;
switch (option)
{
case ENET_SOCKOPT_ERROR:
len = sizeof (int);
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
break;
default:
break;
}
return result == -1 ? -1 : 0;
}
int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
int result;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
if (result == -1 && errno == EINPROGRESS)
return 0;
return result;
}
ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
int result;
struct sockaddr_in sin;
socklen_t sinLength = sizeof (struct sockaddr_in);
result = accept (socket,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL);
if (result == -1)
return ENET_SOCKET_NULL;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return result;
}
int
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
{
return shutdown (socket, (int) how);
}
void
enet_socket_destroy (ENetSocket socket)
{
if (socket != -1)
close (socket);
}
int
enet_socket_send (ENetSocket socket,
const ENetAddress * address,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct msghdr msgHdr;
struct sockaddr_in sin;
int sentLength;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (address != NULL)
{
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
if (sentLength == -1)
{
if (errno == EWOULDBLOCK)
return 0;
return -1;
}
return sentLength;
}
int
enet_socket_receive (ENetSocket socket,
ENetAddress * address,
ENetBuffer * buffers,
size_t bufferCount)
{
struct msghdr msgHdr;
struct sockaddr_in sin;
int recvLength;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (address != NULL)
{
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
if (recvLength == -1)
{
if (errno == EWOULDBLOCK)
return 0;
return -1;
}
#ifdef HAS_MSGHDR_FLAGS
if (msgHdr.msg_flags & MSG_TRUNC)
return -1;
#endif
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return recvLength;
}
int
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
{
struct timeval timeVal;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
}
int
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
{
#ifdef HAS_POLL
struct pollfd pollSocket;
int pollCount;
pollSocket.fd = socket;
pollSocket.events = 0;
if (* condition & ENET_SOCKET_WAIT_SEND)
pollSocket.events |= POLLOUT;
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
pollSocket.events |= POLLIN;
pollCount = poll (& pollSocket, 1, timeout);
if (pollCount < 0)
{
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
{
* condition = ENET_SOCKET_WAIT_INTERRUPT;
return 0;
}
return -1;
}
* condition = ENET_SOCKET_WAIT_NONE;
if (pollCount == 0)
return 0;
if (pollSocket.revents & POLLOUT)
* condition |= ENET_SOCKET_WAIT_SEND;
if (pollSocket.revents & POLLIN)
* condition |= ENET_SOCKET_WAIT_RECEIVE;
return 0;
#else
fd_set readSet, writeSet;
struct timeval timeVal;
int selectCount;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
FD_ZERO (& readSet);
FD_ZERO (& writeSet);
if (* condition & ENET_SOCKET_WAIT_SEND)
FD_SET (socket, & writeSet);
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
FD_SET (socket, & readSet);
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
if (selectCount < 0)
{
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
{
* condition = ENET_SOCKET_WAIT_INTERRUPT;
return 0;
}
return -1;
}
* condition = ENET_SOCKET_WAIT_NONE;
if (selectCount == 0)
return 0;
if (FD_ISSET (socket, & writeSet))
* condition |= ENET_SOCKET_WAIT_SEND;
if (FD_ISSET (socket, & readSet))
* condition |= ENET_SOCKET_WAIT_RECEIVE;
return 0;
#endif
}
#endif

View File

@ -1,435 +0,0 @@
/**
@file win32.c
@brief ENet Win32 system specific functions
*/
#ifdef _WIN32
#define ENET_BUILDING_LIB 0
#include "enet/enet.h"
#include <windows.h>
#include <mmsystem.h>
static enet_uint32 timeBase = 0;
int
enet_initialize (void)
{
WORD versionRequested = MAKEWORD (1, 1);
WSADATA wsaData;
if (WSAStartup (versionRequested, & wsaData))
return -1;
if (LOBYTE (wsaData.wVersion) != 1||
HIBYTE (wsaData.wVersion) != 1)
{
WSACleanup ();
return -1;
}
#ifndef UWP_ENABLED
timeBeginPeriod (1);
#endif
return 0;
}
void
enet_deinitialize (void)
{
#ifndef UWP_ENABLED
timeEndPeriod (1);
#endif
WSACleanup ();
}
#ifdef UWP_ENABLED
enet_uint32
timeGetTime() {
ULONGLONG ticks = GetTickCount64();
return (enet_uint32)ticks;
}
#endif
enet_uint32
enet_host_random_seed (void)
{
return (enet_uint32) timeGetTime ();
}
enet_uint32
enet_time_get (void)
{
return (enet_uint32) timeGetTime () - timeBase;
}
void
enet_time_set (enet_uint32 newTimeBase)
{
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
}
int
enet_address_set_host (ENetAddress * address, const char * name)
{
struct hostent * hostEntry;
hostEntry = gethostbyname (name);
if (hostEntry == NULL ||
hostEntry -> h_addrtype != AF_INET)
{
unsigned long host = inet_addr (name);
if (host == INADDR_NONE)
return -1;
address -> host = host;
return 0;
}
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
return 0;
}
int
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
{
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
if (addr == NULL)
return -1;
else
{
size_t addrLen = strlen(addr);
if (addrLen >= nameLength)
return -1;
memcpy (name, addr, addrLen + 1);
}
return 0;
}
int
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
struct in_addr in;
struct hostent * hostEntry;
in.s_addr = address -> host;
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
if (hostEntry == NULL)
return enet_address_get_host_ip (address, name, nameLength);
else
{
size_t hostLen = strlen (hostEntry -> h_name);
if (hostLen >= nameLength)
return -1;
memcpy (name, hostEntry -> h_name, hostLen + 1);
}
return 0;
}
int
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
if (address != NULL)
{
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
else
{
sin.sin_port = 0;
sin.sin_addr.s_addr = INADDR_ANY;
}
return bind (socket,
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
}
int
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
{
struct sockaddr_in sin;
int sinLength = sizeof (struct sockaddr_in);
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
return -1;
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
return 0;
}
int
enet_socket_listen (ENetSocket socket, int backlog)
{
return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
}
ENetSocket
enet_socket_create (ENetSocketType type)
{
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
{
int result = SOCKET_ERROR;
switch (option)
{
case ENET_SOCKOPT_NONBLOCK:
{
u_long nonBlocking = (u_long) value;
result = ioctlsocket (socket, FIONBIO, & nonBlocking);
break;
}
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVBUF:
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_SNDBUF:
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVTIMEO:
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_SNDTIMEO:
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_NODELAY:
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break;
default:
break;
}
return result == SOCKET_ERROR ? -1 : 0;
}
int
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
{
int result = SOCKET_ERROR, len;
switch (option)
{
case ENET_SOCKOPT_ERROR:
len = sizeof(int);
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
break;
default:
break;
}
return result == SOCKET_ERROR ? -1 : 0;
}
int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
int result;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
return -1;
return 0;
}
ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
SOCKET result;
struct sockaddr_in sin;
int sinLength = sizeof (struct sockaddr_in);
result = accept (socket,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL);
if (result == INVALID_SOCKET)
return ENET_SOCKET_NULL;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return result;
}
int
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
{
return shutdown (socket, (int) how) == SOCKET_ERROR ? -1 : 0;
}
void
enet_socket_destroy (ENetSocket socket)
{
if (socket != INVALID_SOCKET)
closesocket (socket);
}
int
enet_socket_send (ENetSocket socket,
const ENetAddress * address,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct sockaddr_in sin;
DWORD sentLength;
if (address != NULL)
{
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
if (WSASendTo (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& sentLength,
0,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? sizeof (struct sockaddr_in) : 0,
NULL,
NULL) == SOCKET_ERROR)
{
if (WSAGetLastError () == WSAEWOULDBLOCK)
return 0;
return -1;
}
return (int) sentLength;
}
int
enet_socket_receive (ENetSocket socket,
ENetAddress * address,
ENetBuffer * buffers,
size_t bufferCount)
{
INT sinLength = sizeof (struct sockaddr_in);
DWORD flags = 0,
recvLength;
struct sockaddr_in sin;
if (WSARecvFrom (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& recvLength,
& flags,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL,
NULL,
NULL) == SOCKET_ERROR)
{
switch (WSAGetLastError ())
{
case WSAEWOULDBLOCK:
case WSAECONNRESET:
return 0;
}
return -1;
}
if (flags & MSG_PARTIAL)
return -1;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return (int) recvLength;
}
int
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
{
struct timeval timeVal;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
}
int
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
{
fd_set readSet, writeSet;
struct timeval timeVal;
int selectCount;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
FD_ZERO (& readSet);
FD_ZERO (& writeSet);
if (* condition & ENET_SOCKET_WAIT_SEND)
FD_SET (socket, & writeSet);
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
FD_SET (socket, & readSet);
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
if (selectCount < 0)
return -1;
* condition = ENET_SOCKET_WAIT_NONE;
if (selectCount == 0)
return 0;
if (FD_ISSET (socket, & writeSet))
* condition |= ENET_SOCKET_WAIT_SEND;
if (FD_ISSET (socket, & readSet))
* condition |= ENET_SOCKET_WAIT_RECEIVE;
return 0;
}
#endif