Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 299ab267c9 | |||
| 9bf55a3433 | |||
| 5c96da29c2 | |||
| d988023971 | |||
| 637cd52e96 | |||
| 512b3f26f9 | |||
| 5503534362 | |||
| 93b080b053 | |||
| cf38f85e08 | |||
| e770a52bca | |||
| 42891f6919 | |||
| eb38c3c737 | |||
| e33ca1dc47 | |||
| 7546b505c1 | |||
| 2bc07bb50d | |||
| a602abf244 | |||
| 167f41aa2b | |||
| b2ee3b7b48 | |||
| 8b24595dbd | |||
| b3e34fa1db | |||
| 4f7ef11c23 | |||
| a39d3bb49c | |||
| ae9002fe19 | |||
| 4d1067179b | |||
| 00ccd3bd3f | |||
| 809a1d15b6 | |||
| 5f476546ed |
@@ -7,7 +7,10 @@ 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)
|
||||
check_function_exists("gethostbyname_r" HAS_GETHOSTBYNAME_R)
|
||||
check_function_exists("gethostbyaddr_r" HAS_GETHOSTBYADDR_R)
|
||||
check_function_exists("inet_pton" HAS_INET_PTON)
|
||||
@@ -20,9 +23,18 @@ 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()
|
||||
if(HAS_GETNAMEINFO)
|
||||
add_definitions(-DHAS_GETNAMEINFO=1)
|
||||
endif()
|
||||
if(HAS_GETADDRINFO)
|
||||
add_definitions(-DHAS_GETADDRINFO=1)
|
||||
endif()
|
||||
if(HAS_GETHOSTBYNAME_R)
|
||||
add_definitions(-DHAS_GETHOSTBYNAME_R=1)
|
||||
endif()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
* use getaddrinfo and getnameinfo where available
|
||||
|
||||
ENet 1.3.13 (April 30, 2015):
|
||||
|
||||
* miscellaneous bug fixes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2002-2015 Lee Salzman
|
||||
Copyright (c) 2002-2016 Lee Salzman
|
||||
|
||||
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:
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_CC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAS_GETADDRINFO)])
|
||||
AC_CHECK_FUNC(getnameinfo, [AC_DEFINE(HAS_GETNAMEINFO)])
|
||||
AC_CHECK_FUNC(gethostbyaddr_r, [AC_DEFINE(HAS_GETHOSTBYADDR_R)])
|
||||
AC_CHECK_FUNC(gethostbyname_r, [AC_DEFINE(HAS_GETHOSTBYNAME_R)])
|
||||
AC_CHECK_FUNC(poll, [AC_DEFINE(HAS_POLL)])
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
@page License License
|
||||
|
||||
Copyright (c) 2002-2015 Lee Salzman
|
||||
Copyright (c) 2002-2016 Lee Salzman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -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
|
||||
|
||||
+22
-48
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -138,7 +127,11 @@ typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
|
||||
* (not supported for reliable packets)
|
||||
*
|
||||
* ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
|
||||
|
||||
*
|
||||
* ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT - packet will be fragmented using unreliable
|
||||
* (instead of reliable) sends if it exceeds the MTU
|
||||
*
|
||||
* ENET_PACKET_FLAG_SENT - whether the packet has been sent from all queues it has been entered into
|
||||
@sa ENetPacketFlag
|
||||
*/
|
||||
typedef struct _ENetPacket
|
||||
@@ -208,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,
|
||||
|
||||
@@ -344,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()
|
||||
@@ -405,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
|
||||
@@ -485,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);
|
||||
@@ -514,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);
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -542,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);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
|
||||
typedef SOCKET ENetSocket;
|
||||
|
||||
|
||||
+13
-11
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -38,12 +38,54 @@
|
||||
#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
|
||||
#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
|
||||
@@ -52,6 +94,10 @@
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#ifndef SOMAXCONN
|
||||
#define SOMAXCONN 128
|
||||
#endif
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
@@ -72,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
|
||||
@@ -95,134 +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)
|
||||
{
|
||||
struct hostent * hostEntry = NULL;
|
||||
#ifdef HAS_GETHOSTBYNAME_R
|
||||
struct hostent hostData;
|
||||
char buffer [2048];
|
||||
int errnum;
|
||||
struct addrinfo hints, * resultList = NULL, * result = NULL;
|
||||
|
||||
#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
|
||||
memset (& hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
if (hostEntry == NULL ||
|
||||
hostEntry -> h_addrtype != AF_INET)
|
||||
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
|
||||
return -1;
|
||||
|
||||
for (result = resultList; result != NULL; result = result -> ai_next)
|
||||
{
|
||||
#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;
|
||||
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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
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));
|
||||
(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;
|
||||
}
|
||||
|
||||
@@ -233,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
|
||||
@@ -248,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:
|
||||
@@ -290,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;
|
||||
}
|
||||
@@ -317,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;
|
||||
|
||||
@@ -337,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)
|
||||
{
|
||||
@@ -375,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)
|
||||
{
|
||||
@@ -415,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;
|
||||
@@ -439,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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user