23 Commits

Author SHA1 Message Date
Cameron Gutman 299ab267c9 Enable ECN/L4S on UNIX
Since this is enabled as a QoS option, it will benefit from the opportunistic
disablement code when ECN-intolerant networks are encountered.
2024-02-03 14:32:25 -06:00
Cameron Gutman 9bf55a3433 Disable QoS tagging if 2 connect packets in a row are dropped 2020-06-12 21:16:46 -07:00
Cameron Gutman 5c96da29c2 Enable QoS prioritization on Windows 2020-04-09 17:42:12 -07:00
Cameron Gutman d988023971 Use EF instead of CS7 for DSCP
Some security guidelines recommend dropping CS7 tagged packets at the edge,
since CS7 is reserved for network control. EF seems to be the standard for
telephony applications and is fairly well preserved across the Internet per
https://www.sciencedirect.com/science/article/pii/S0166531619300203
2020-04-03 16:58:18 -07:00
Cameron Gutman 637cd52e96 Enable QoS prioritization on Linux 2020-03-29 15:44:14 -07:00
Cameron Gutman 512b3f26f9 Enable QOS prioritization on macOS 2020-03-29 15:21:26 -07:00
Cameron Gutman 5503534362 Fix Linux build 2019-10-12 19:41:41 -07:00
Sunguk Lee 93b080b053 vita: No more need vita specific codesets (#4)
* vita: No more need to define sockaddr_storage

* vita: Remove everything and combine unix codeset

* unix: Remove HACK for the specialized code of the vita nonblock IO
2019-10-12 15:10:59 -07:00
Cameron Gutman cf38f85e08 Be more lenient with the expected peer address for multi-homed hosts 2019-09-14 14:05:05 -07:00
Cameron Gutman e770a52bca Merge pull request #3 from d3m3vilurr/fix-vita-error-code
vita: No more use self defined net error code
2019-02-17 09:49:11 -08:00
Sunguk Lee 42891f6919 vita: No more use self defined net error code 2018-07-28 21:50:59 +09:00
Antonio Aloisio eb38c3c737 Fixed build with latest VitaSDK (#2) 2018-07-25 21:27:12 -07:00
Sunguk Lee e33ca1dc47 Add vita environment (#1)
* vita: Initial port

* vita: add debug logging and reduce max number of IOV (caused errors)

* vita: now using newlib's socket apis

* vita: Refactoring for cgutman/enet

* Fix review things

https://github.com/cgutman/enet/pull/1#pullrequestreview-2436331
2016-10-02 00:56:59 -07:00
Cameron Gutman 7546b505c1 Lower ENet's MTU to 900 because some ISPs will drop the RTSP DESCRIBE response packets with the default MTU 2016-05-21 18:01:31 -05:00
Cameron Gutman 2bc07bb50d Add enet_address_set_address() function to allow ENetAddress to be populated from sockaddr directly 2016-04-02 14:04:31 -04:00
Cameron Gutman a602abf244 Switch to gettimeofday() for seeding on UNIX 2016-03-31 11:22:06 -04:00
Cameron Gutman 167f41aa2b Fix build with NO_MSGAPI undefined 2016-03-27 22:47:50 -04:00
Cameron Gutman b2ee3b7b48 Add support for building with PNaCl's newlibc 2016-03-11 00:27:48 -08:00
Cameron Gutman 8b24595dbd Require an address family to be specified when creating a host 2016-03-07 14:26:13 -08:00
Cameron Gutman b3e34fa1db Fix some IPv6 compatibility issues 2016-03-06 23:22:59 -08:00
Cameron Gutman 4f7ef11c23 Fix some compilation warnings 2016-03-06 15:33:32 -08:00
Cameron Gutman a39d3bb49c Wake up every once in a while to see if any retransmissions or pings need to be sent 2016-03-06 14:56:08 -08:00
Cameron Gutman ae9002fe19 Protocol agnostic socket address to fix IPv6 and remove broadcast support 2016-03-06 14:47:01 -08:00
7 changed files with 424 additions and 403 deletions
+4
View File
@@ -7,6 +7,7 @@ include(CheckFunctionExists)
include(CheckStructHasMember)
include(CheckTypeSize)
check_function_exists("fcntl" HAS_FCNTL)
check_function_exists("ioctl" HAS_IOCTL)
check_function_exists("poll" HAS_POLL)
check_function_exists("getaddrinfo" HAS_GETADDRINFO)
check_function_exists("getnameinfo" HAS_GETNAMEINFO)
@@ -22,6 +23,9 @@ unset(CMAKE_EXTRA_INCLUDE_FILES)
if(HAS_FCNTL)
add_definitions(-DHAS_FCNTL=1)
endif()
if(HAS_IOCTL)
add_definitions(-DHAS_IOCTL=1)
endif()
if(HAS_POLL)
add_definitions(-DHAS_POLL=1)
endif()
+5 -29
View File
@@ -12,6 +12,7 @@
/** Creates a host for communicating to peers.
@param addressFamily the address family of the socket that should be created (ex: PF_INET/PF_INET6)
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
@param peerCount the maximum number of peers that should be allocated for the host.
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
@@ -26,7 +27,7 @@
at any given time.
*/
ENetHost *
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
ENetHost * host;
ENetPeer * currentPeer;
@@ -48,7 +49,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
}
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
host -> socket = enet_socket_create (addressFamily, ENET_SOCKET_TYPE_DATAGRAM);
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
{
if (host -> socket != ENET_SOCKET_NULL)
@@ -61,9 +62,9 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
}
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 1);
if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
host -> address = * address;
@@ -87,8 +88,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
host -> commandCount = 0;
host -> bufferCount = 0;
host -> checksum = NULL;
host -> receivedAddress.host = ENET_HOST_ANY;
host -> receivedAddress.port = 0;
memset(& host -> receivedAddress, 0, sizeof (host -> receivedAddress));
host -> receivedData = NULL;
host -> receivedDataLength = 0;
@@ -252,30 +252,6 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
return currentPeer;
}
/** Queues a packet to be sent to all peers associated with the host.
@param host host on which to broadcast the packet
@param channelID channel on which to broadcast
@param packet packet to broadcast
*/
void
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
{
ENetPeer * currentPeer;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
continue;
enet_peer_send (currentPeer, channelID, packet);
}
if (packet -> referenceCount == 0)
enet_packet_destroy (packet);
}
/** Sets the packet compressor the host should use to compress and decompress packets.
@param host host to enable or disable compression for
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
+17 -47
View File
@@ -55,14 +55,14 @@ typedef enum _ENetSocketWait
typedef enum _ENetSocketOption
{
ENET_SOCKOPT_NONBLOCK = 1,
ENET_SOCKOPT_BROADCAST = 2,
ENET_SOCKOPT_RCVBUF = 3,
ENET_SOCKOPT_SNDBUF = 4,
ENET_SOCKOPT_REUSEADDR = 5,
ENET_SOCKOPT_RCVTIMEO = 6,
ENET_SOCKOPT_SNDTIMEO = 7,
ENET_SOCKOPT_ERROR = 8,
ENET_SOCKOPT_NODELAY = 9
ENET_SOCKOPT_RCVBUF,
ENET_SOCKOPT_SNDBUF,
ENET_SOCKOPT_REUSEADDR,
ENET_SOCKOPT_RCVTIMEO,
ENET_SOCKOPT_SNDTIMEO,
ENET_SOCKOPT_ERROR,
ENET_SOCKOPT_NODELAY,
ENET_SOCKOPT_QOS,
} ENetSocketOption;
typedef enum _ENetSocketShutdown
@@ -72,24 +72,13 @@ 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
/**
* Portable internet address structure.
*
* The host must be specified in network byte-order, and the port must be in host
* byte-order. The constant ENET_HOST_ANY may be used to specify the default
* server host. The constant ENET_HOST_BROADCAST may be used to specify the
* broadcast address (255.255.255.255). This makes sense for enet_host_connect,
* 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.
*/
typedef struct _ENetAddress
{
enet_uint32 host;
enet_uint16 port;
socklen_t addressLength;
struct sockaddr_storage address;
} ENetAddress;
/**
@@ -212,7 +201,7 @@ enum
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
ENET_HOST_DEFAULT_MTU = 1400,
ENET_HOST_DEFAULT_MTU = 900,
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024,
@@ -348,7 +337,6 @@ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, st
@sa enet_host_connect()
@sa enet_host_service()
@sa enet_host_flush()
@sa enet_host_broadcast()
@sa enet_host_compress()
@sa enet_host_compress_with_range_coder()
@sa enet_host_channel_limit()
@@ -409,7 +397,7 @@ typedef enum _ENetEventType
ENET_EVENT_TYPE_CONNECT = 1,
/** a peer has disconnected. This event is generated on a successful
* completion of a disconnect initiated by enet_pper_disconnect, if
* completion of a disconnect initiated by enet_peer_disconnect, if
* a peer has timed out, or if a connection request intialized by
* enet_host_connect has timed out. The peer field contains the peer
* which disconnected. The data field contains user supplied data
@@ -489,7 +477,7 @@ ENET_API void enet_time_set (enet_uint32);
/** @defgroup socket ENet socket functions
@{
*/
ENET_API ENetSocket enet_socket_create (ENetSocketType);
ENET_API ENetSocket enet_socket_create (int, ENetSocketType);
ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_get_address (ENetSocket, ENetAddress *);
ENET_API int enet_socket_listen (ENetSocket, int);
@@ -518,26 +506,9 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
@returns the address of the given hostName in address on success
*/
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
/** 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
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
/** Attempts to do a reverse lookup of the host field in the address parameter.
@param address address used for reverse lookup
@param hostName destination for name, must not be NULL
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
ENET_API int enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen);
ENET_API int enet_address_set_port (ENetAddress * address, enet_uint16 port);
ENET_API int enet_address_equal (ENetAddress * address1, ENetAddress * address2);
/** @} */
@@ -546,13 +517,12 @@ ENET_API void enet_packet_destroy (ENetPacket *);
ENET_API int enet_packet_resize (ENetPacket *, size_t);
ENET_API enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
ENET_API ENetHost * enet_host_create (int, const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
ENET_API void enet_host_destroy (ENetHost *);
ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
ENET_API void enet_host_flush (ENetHost *);
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
ENET_API void enet_host_channel_limit (ENetHost *, size_t);
+1
View File
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
typedef SOCKET ENetSocket;
+13 -11
View File
@@ -298,10 +298,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
}
else
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
currentPeer -> address.host == host -> receivedAddress.host)
enet_address_equal (& currentPeer -> address, & host -> receivedAddress))
{
if (currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> connectID == command -> connect.connectID)
if (currentPeer -> connectID == command -> connect.connectID)
return NULL;
++ duplicatePeers;
@@ -1010,9 +1009,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
((host -> receivedAddress.host != peer -> address.host ||
host -> receivedAddress.port != peer -> address.port) &&
peer -> address.host != ENET_HOST_BROADCAST) ||
/* ! enet_address_equal(& host -> receivedAddress, & peer -> address) || */
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
sessionID != peer -> incomingSessionID))
return 0;
@@ -1054,8 +1051,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer != NULL)
{
peer -> address.host = host -> receivedAddress.host;
peer -> address.port = host -> receivedAddress.port;
memcpy(& peer -> address, & host -> receivedAddress, sizeof (host -> receivedAddress));
peer -> incomingDataTotal += host -> receivedDataLength;
}
@@ -1722,6 +1718,12 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
currentPeer -> lastSendTime = host -> serviceTime;
if (currentPeer -> state == ENET_PEER_STATE_CONNECTING && currentPeer -> packetsLost == 2) {
// Disable QoS tagging if we don't get a response to 2 connection requests in a row.
// Some networks drop QoS tagged packets, so let's try without it.
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 0);
}
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
enet_protocol_remove_sent_unreliable_commands (currentPeer);
@@ -1816,7 +1818,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
timeout += host -> serviceTime;
do
for (;;)
{
if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
enet_host_bandwidth_throttle (host);
@@ -1900,13 +1902,13 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime) / 10) != 0)
return -1;
}
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
host -> serviceTime = enet_time_get ();
} while (waitCondition & ENET_SOCKET_WAIT_RECEIVE);
}
return 0;
}
+229 -194
View File
@@ -6,7 +6,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
@@ -19,7 +19,7 @@
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
#ifdef __APPLE__
#if defined(__APPLE__)
#ifdef HAS_POLL
#undef HAS_POLL
#endif
@@ -44,12 +44,48 @@
#ifndef HAS_GETNAMEINFO
#define HAS_GETNAMEINFO 1
#endif
#elif defined(__vita__)
#ifdef HAS_POLL
#undef HAS_POLL
#endif
#ifdef HAS_FCNTL
#undef HAS_FCNTL
#endif
#ifdef HAS_IOCTL
#undef HAS_IOCTL
#endif
#ifndef HAS_INET_PTON
#define HAS_INET_PTON 1
#endif
#ifndef HAS_INET_NTOP
#define HAS_INET_NTOP 1
#endif
#ifdef HAS_MSGHDR_FLAGS
#undef HAS_MSGHDR_FLAGS
#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
#else
#ifndef HAS_IOCTL
#define HAS_IOCTL 1
#endif
#endif
#ifdef HAS_FCNTL
#include <fcntl.h>
#endif
#ifdef HAS_IOCTL
#include <sys/ioctl.h>
#endif
#ifdef HAS_POLL
#include <sys/poll.h>
#endif
@@ -58,6 +94,10 @@
typedef int socklen_t;
#endif
#ifndef SOMAXCONN
#define SOMAXCONN 128
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
@@ -78,7 +118,11 @@ enet_deinitialize (void)
enet_uint32
enet_host_random_seed (void)
{
return (enet_uint32) time (NULL);
struct timeval timeVal;
gettimeofday (& timeVal, NULL);
return (timeVal.tv_sec * 1000) ^ (timeVal.tv_usec / 1000);
}
enet_uint32
@@ -101,181 +145,113 @@ enet_time_set (enet_uint32 newTimeBase)
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
}
int
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
{
if (address1 -> address.ss_family != address2 -> address.ss_family)
return 0;
switch (address1 -> address.ss_family)
{
case AF_INET:
{
struct sockaddr_in *sin1, *sin2;
sin1 = (struct sockaddr_in *) & address1 -> address;
sin2 = (struct sockaddr_in *) & address2 -> address;
return sin1 -> sin_port == sin2 -> sin_port &&
sin1 -> sin_addr.s_addr == sin2 -> sin_addr.s_addr;
}
case AF_INET6:
{
struct sockaddr_in6 *sin6a, *sin6b;
sin6a = (struct sockaddr_in6 *) & address1 -> address;
sin6b = (struct sockaddr_in6 *) & address2 -> address;
return sin6a -> sin6_port == sin6b -> sin6_port &&
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
}
default:
{
return 0;
}
}
}
int
enet_address_set_port (ENetAddress * address, enet_uint16 port)
{
if (address -> address.ss_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in *) &address -> address;
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
else if (address -> address.ss_family == AF_INET6)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
else
{
return -1;
}
}
int
enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen)
{
if (addrlen > sizeof(struct sockaddr_storage))
return -1;
memcpy (&address->address, addr, addrlen);
address->addressLength = addrlen;
return 0;
}
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;
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
if (getaddrinfo (name, NULL, NULL, & resultList) != 0)
if (getaddrinfo (name, NULL, & hints, & 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;
}
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
address -> addressLength = result -> ai_addrlen;
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);
return -1;
}
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));
(struct sockaddr *) & address -> address,
address -> addressLength);
}
int
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
{
struct sockaddr_in sin;
socklen_t sinLength = sizeof (struct sockaddr_in);
address -> addressLength = sizeof (address -> address);
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
return -1;
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
return 0;
}
@@ -286,9 +262,9 @@ enet_socket_listen (ENetSocket socket, int backlog)
}
ENetSocket
enet_socket_create (ENetSocketType type)
enet_socket_create (int af, ENetSocketType type)
{
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
return socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
@@ -301,12 +277,12 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
#ifdef HAS_FCNTL
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL) & ~O_NONBLOCK));
#else
#ifdef HAS_IOCTL
result = ioctl (socket, FIONBIO, & value);
#else
result = setsockopt (socket, SOL_SOCKET, SO_NONBLOCK, (char *) & value, sizeof(int));
#endif
#endif
break;
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
@@ -343,6 +319,30 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_QOS:
#ifdef SO_NET_SERVICE_TYPE
// iOS/macOS
value = value ? NET_SERVICE_TYPE_VO : NET_SERVICE_TYPE_BE;
result = setsockopt (socket, SOL_SOCKET, SO_NET_SERVICE_TYPE, (char *) & value, sizeof (int));
#else
#ifdef IP_TOS
// UNIX - IPv4
value = value ? (46 << 2 | 0x01) : 0; // DSCP: Expedited Forwarding + ECT(1) (L4S)
result = setsockopt (socket, IPPROTO_IP, IP_TOS, (char *) & value, sizeof (int));
#endif
#ifdef IPV6_TCLASS
// UNIX - IPv6
value = value ? (46 << 2 | 0x01): 0; // DSCP: Expedited Forwarding + ECT(1) (L4S)
result = setsockopt (socket, IPPROTO_IPV6, IPV6_TCLASS, (char *) & value, sizeof (int));
#endif
#ifdef SO_PRIORITY
// Linux
value = value ? 6 : 0; // Max priority without NET_CAP_ADMIN
result = setsockopt (socket, SOL_SOCKET, SO_PRIORITY, (char *) & value, sizeof (int));
#endif
#endif /* SO_NET_SERVICE_TYPE */
break;
default:
break;
}
@@ -370,16 +370,9 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
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));
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
if (result == -1 && errno == EINPROGRESS)
return 0;
@@ -390,25 +383,20 @@ ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
int result;
struct sockaddr_in sin;
socklen_t sinLength = sizeof (struct sockaddr_in);
if (address != NULL)
address -> addressLength = sizeof (address -> address);
result = accept (socket,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL);
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? & address -> addressLength : 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)
{
@@ -428,28 +416,60 @@ enet_socket_send (ENetSocket socket,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct msghdr msgHdr;
struct sockaddr_in sin;
int sentLength;
#ifdef NO_MSGAPI
void* sendBuffer;
size_t sendLength;
if (bufferCount > 1)
{
size_t i;
sendLength = 0;
for (i = 0; i < bufferCount; i++)
{
sendLength += buffers[i].dataLength;
}
sendBuffer = malloc (sendLength);
if (sendBuffer == NULL)
return -1;
sendLength = 0;
for (i = 0; i < bufferCount; i++)
{
memcpy (& ((unsigned char *)sendBuffer)[sendLength], buffers[i].data, buffers[i].dataLength);
sendLength += buffers[i].dataLength;
}
}
else
{
sendBuffer = buffers[0].data;
sendLength = buffers[0].dataLength;
}
sentLength = sendto (socket, sendBuffer, sendLength, MSG_NOSIGNAL,
(struct sockaddr *) & address -> address, address -> addressLength);
if (bufferCount > 1)
free(sendBuffer);
#else
struct msghdr msgHdr;
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_name = (void*) & address -> address;
msgHdr.msg_namelen = address -> addressLength;
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
#endif
if (sentLength == -1)
{
@@ -468,16 +488,33 @@ enet_socket_receive (ENetSocket socket,
ENetBuffer * buffers,
size_t bufferCount)
{
struct msghdr msgHdr;
struct sockaddr_in sin;
int recvLength;
#ifdef NO_MSGAPI
// This will ONLY work with a single buffer!
address -> addressLength = sizeof (address -> address);
recvLength = recvfrom (socket, buffers[0].data, buffers[0].dataLength, MSG_NOSIGNAL,
(struct sockaddr *) & address -> address, & address -> addressLength);
if (recvLength == -1)
{
if (errno == EWOULDBLOCK)
return 0;
return -1;
}
return recvLength;
#else
struct msghdr msgHdr;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (address != NULL)
{
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
msgHdr.msg_name = & address -> address;
msgHdr.msg_namelen = sizeof (address -> address);
}
msgHdr.msg_iov = (struct iovec *) buffers;
@@ -492,19 +529,17 @@ enet_socket_receive (ENetSocket socket,
return -1;
}
if (address != NULL)
address -> addressLength = msgHdr.msg_namelen;
#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;
#endif
}
int
+155 -122
View File
@@ -8,20 +8,24 @@
#include "enet/enet.h"
#include <windows.h>
#include <mmsystem.h>
#include <qos2.h>
static enet_uint32 timeBase = 0;
static HANDLE qosHandle = INVALID_HANDLE_VALUE;
static QOS_FLOWID qosFlowId;
static BOOL qosAddedFlow;
int
enet_initialize (void)
{
WORD versionRequested = MAKEWORD (1, 1);
WORD versionRequested = MAKEWORD (2, 0);
WSADATA wsaData;
if (WSAStartup (versionRequested, & wsaData))
return -1;
if (LOBYTE (wsaData.wVersion) != 1||
HIBYTE (wsaData.wVersion) != 1)
if (LOBYTE (wsaData.wVersion) != 2||
HIBYTE (wsaData.wVersion) != 0)
{
WSACleanup ();
@@ -36,6 +40,15 @@ enet_initialize (void)
void
enet_deinitialize (void)
{
qosAddedFlow = FALSE;
qosFlowId = 0;
if (qosHandle != INVALID_HANDLE_VALUE)
{
QOSCloseHandle(qosHandle);
qosHandle = INVALID_HANDLE_VALUE;
}
timeEndPeriod (1);
WSACleanup ();
@@ -59,102 +72,113 @@ enet_time_set (enet_uint32 newTimeBase)
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
}
int
enet_address_set_port (ENetAddress * address, enet_uint16 port)
{
if (address -> address.ss_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in *) &address -> address;
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
else if (address -> address.ss_family == AF_INET6)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
else
{
return -1;
}
}
int
enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen)
{
if (addrlen > sizeof(struct sockaddr_storage))
return -1;
memcpy (&address->address, addr, addrlen);
address->addressLength = addrlen;
return 0;
}
int
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
{
if (address1 -> address.ss_family != address2 -> address.ss_family)
return 0;
switch (address1 -> address.ss_family)
{
case AF_INET:
{
struct sockaddr_in *sin1, *sin2;
sin1 = (struct sockaddr_in *) & address1 -> address;
sin2 = (struct sockaddr_in *) & address2 -> address;
return sin1 -> sin_port == sin2 -> sin_port &&
sin1 -> sin_addr.S_un.S_addr == sin2 -> sin_addr.S_un.S_addr;
}
case AF_INET6:
{
struct sockaddr_in6 *sin6a, *sin6b;
sin6a = (struct sockaddr_in6 *) & address1 -> address;
sin6b = (struct sockaddr_in6 *) & address2 -> address;
return sin6a -> sin6_port == sin6b -> sin6_port &&
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
}
default:
{
return 0;
}
}
}
int
enet_address_set_host (ENetAddress * address, const char * name)
{
struct hostent * hostEntry;
struct addrinfo hints, * resultList = NULL, * result = NULL;
hostEntry = gethostbyname (name);
if (hostEntry == NULL ||
hostEntry -> h_addrtype != AF_INET)
memset (& hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
return -1;
for (result = resultList; result != NULL; result = result -> ai_next)
{
unsigned long host = inet_addr (name);
if (host == INADDR_NONE)
return -1;
address -> host = host;
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
address -> addressLength = result -> ai_addrlen;
freeaddrinfo (resultList);
return 0;
}
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
if (resultList != NULL)
freeaddrinfo (resultList);
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;
return -1;
}
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;
(struct sockaddr *) & address -> address,
address -> addressLength);
}
int
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
{
struct sockaddr_in sin;
int sinLength = sizeof (struct sockaddr_in);
address -> addressLength = sizeof (address -> address);
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
return -1;
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
return 0;
}
@@ -165,9 +189,9 @@ enet_socket_listen (ENetSocket socket, int backlog)
}
ENetSocket
enet_socket_create (ENetSocketType type)
enet_socket_create (int af, ENetSocketType type)
{
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
return socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
@@ -183,10 +207,6 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
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;
@@ -211,6 +231,32 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_QOS:
{
if (value)
{
QOS_VERSION qosVersion;
qosVersion.MajorVersion = 1;
qosVersion.MinorVersion = 0;
if (!QOSCreateHandle(&qosVersion, &qosHandle))
{
qosHandle = INVALID_HANDLE_VALUE;
}
}
else if (qosHandle != INVALID_HANDLE_VALUE)
{
QOSCloseHandle(qosHandle);
qosHandle = INVALID_HANDLE_VALUE;
}
qosAddedFlow = FALSE;
qosFlowId = 0;
result = 0;
break;
}
default:
break;
}
@@ -237,16 +283,9 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
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));
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
return -1;
@@ -256,22 +295,17 @@ enet_socket_connect (ENetSocket socket, const ENetAddress * address)
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;
int result;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
address -> addressLength = sizeof (address -> address);
result = accept (socket,
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? & address -> addressLength : NULL);
if (result == -1)
return ENET_SOCKET_NULL;
return result;
}
@@ -295,16 +329,20 @@ enet_socket_send (ENetSocket socket,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct sockaddr_in sin;
DWORD sentLength;
if (address != NULL)
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
{
memset (& sin, 0, sizeof (struct sockaddr_in));
qosFlowId = 0; // Must be initialized to 0
QOSAddSocketToFlow(qosHandle,
socket,
(struct sockaddr *)&address->address,
QOSTrafficTypeControl,
QOS_NON_ADAPTIVE_FLOW,
&qosFlowId);
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
// Even if we failed, don't try again
qosAddedFlow = TRUE;
}
if (WSASendTo (socket,
@@ -312,8 +350,8 @@ enet_socket_send (ENetSocket socket,
(DWORD) bufferCount,
& sentLength,
0,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? sizeof (struct sockaddr_in) : 0,
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? address -> addressLength : 0,
NULL,
NULL) == SOCKET_ERROR)
{
@@ -332,18 +370,19 @@ enet_socket_receive (ENetSocket socket,
ENetBuffer * buffers,
size_t bufferCount)
{
INT sinLength = sizeof (struct sockaddr_in);
DWORD flags = 0,
recvLength;
struct sockaddr_in sin;
if (address != NULL)
address -> addressLength = sizeof (address -> address);
if (WSARecvFrom (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& recvLength,
& flags,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL,
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? & address -> addressLength : NULL,
NULL,
NULL) == SOCKET_ERROR)
{
@@ -360,12 +399,6 @@ enet_socket_receive (ENetSocket socket,
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;
}