From c10f16e25bfe3a8a42358bd2162a652c203a2d48 Mon Sep 17 00:00:00 2001 From: lcinx Date: Sat, 24 Jun 2017 22:37:03 +0800 Subject: [PATCH 1/3] Add ipv6 support. --- Makefile | 102 +++++++++++++++++++++++++++++++ common.h | 139 +++++++++++++++++++++++++++++++++++++++++++ host.c | 35 +++++++++-- include/enet/enet.h | 25 +++++++- include/enet/types.h | 7 +++ protocol.c | 9 ++- unix.c | 86 ++++++++++++-------------- win32.c | 103 +++++++++++++++++--------------- 8 files changed, 399 insertions(+), 107 deletions(-) create mode 100644 Makefile create mode 100644 common.h diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..7970d6c9 --- /dev/null +++ b/Makefile @@ -0,0 +1,102 @@ + +# +# c、cpp混合编译的makefile模板 +# + + +PLAT = none + +TARGET_NAME = libenet.a +CC = $(CROSS)gcc +CXX = $(CROSS)g++ +AR = $(CROSS)ar rcu +RANLIB = $(CROSS)ranlib +STRIP = $(CROSS)strip +RM = rm -f + +COMMON_FLAGS = -DHAS_FCNTL=1 -DHAS_POLL=1 -DHAS_GETNAMEINFO=1 -DHAS_GETADDRINFO=1 -DHAS_MSGHDR_FLAGS=1 -DHAS_SOCKLEN_T=1 +CFLAGS = $(CROSS_FLAGS) $(EXTRA_CFLAGS) $(COMMON_FLAGS) +CXXFLAGS = $(CROSS_FLAGS) $(EXTRA_CXXFLAGS) $(COMMON_FLAGS) + +EXTRA_CFLAGS = +EXTRA_CXXFLAGS = + +EXTRA_INCS = +EXTRA_LIBS = + + +SRC_INCS = -I"./include/" + +SRC_LIBS = + + +C_SRC_ALL = $(wildcard ./*.c) + +CXX_SRC_ALL = $(wildcard ./*.cpp) + + + + +PLATS = win-debug win-release linux-debug linux-release +none: + @echo "Please choose a platform:" + @echo " $(PLATS)" + + + +win-debug: + $(MAKE) all EXTRA_CFLAGS="-Wall -D_WIN32 -DDEBUG -g" EXTRA_CXXFLAGS="-Wall -D_WIN32 -DDEBUG -g" + +win-release: + $(MAKE) all EXTRA_CFLAGS="-Wall -D_WIN32 -DNDEBUG -O2" EXTRA_CXXFLAGS="-Wall -D_WIN32 -DNDEBUG -O2" + + +linux-debug: + $(MAKE) all EXTRA_CFLAGS="-fPIC -Wall -DDEBUG -g" EXTRA_CXXFLAGS="-fPIC -Wall -DDEBUG -g" + +linux-release: + $(MAKE) all EXTRA_CFLAGS="-fPIC -Wall -DNDEBUG -O2" EXTRA_CXXFLAGS="-fPIC -Wall -DNDEBUG -O2" + + +all:$(TARGET_NAME) + + +echo: + @echo "PLAT = $(PLAT)" + @echo "CC = $(CC)" + @echo "CXX = $(CXX)" + @echo "AR = $(AR)" + @echo "RANLIB = $(RANLIB)" + @echo "RM = $(RM)" + @echo "CFLAGS = $(CFLAGS)" + @echo "CXXFLAGS = $(CXXFLAGS)" + @echo "EXTRA_CFLAGS = $(EXTRA_CFLAGS)" + @echo "EXTRA_CXXFLAGS = $(EXTRA_CXXFLAGS)" + + + +C_OBJ_ALL := $(C_SRC_ALL:.c=.o) +CXX_OBJ_ALL := $(CXX_SRC_ALL:.cpp=.o) + +#$(OBJS):%.o :%.c 先用$(OBJS)中的一项,比如foo.o: %.o : %.c 含义为:试着用%.o匹配foo.o。如果成功%就等于foo。如果不成功,Make就会警告,然后。给foo.o添加依赖文件foo.c(用foo替换了%.c里的%) +# $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。每次$< $@ 代表的值就是列表中的 +$(C_OBJ_ALL) : %.o: %.c + $(CC) -c $< -o $@ $(EXTRA_INCS) $(SRC_INCS) $(CFLAGS) +$(CXX_OBJ_ALL) : %.o: %.cpp + $(CXX) -c $< -o $@ $(EXTRA_INCS) $(SRC_INCS) $(CXXFLAGS) + + +$(TARGET_NAME): $(C_OBJ_ALL) $(CXX_OBJ_ALL) + $(AR) $(TARGET_NAME) $(C_OBJ_ALL) $(CXX_OBJ_ALL) + $(RANLIB) $(TARGET_NAME) + $(RM) $(C_OBJ_ALL) $(CXX_OBJ_ALL) + + +.PHONY: all $(PLATS) clean cleanall echo + +clean: + $(RM) $(TARGET_NAME) $(C_OBJ_ALL) $(CXX_OBJ_ALL) + +cleanall: + $(RM) $(TARGET_NAME) $(C_OBJ_ALL) $(CXX_OBJ_ALL) + diff --git a/common.h b/common.h new file mode 100644 index 00000000..1dee31cf --- /dev/null +++ b/common.h @@ -0,0 +1,139 @@ + +int enet_address_host_is_any_(struct _all_host_address *host) { + char zero[sizeof(struct _all_host_address)] = {0}; + return enet_address_host_equal(*((struct _all_host_address *)&zero), *host); +} + +int enet_address_set_host_ip(ENetAddress *address, const char *name) { + int ret = -1; + + struct addrinfo hints; + struct addrinfo *ai_list, *cur; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + + if (getaddrinfo(name, 0, &hints, &ai_list) != 0) + return ret; + + cur = ai_list; + do { + if (cur->ai_family == AF_INET && cur->ai_addrlen >= sizeof(struct sockaddr_in)) { + struct sockaddr_in *addr = (struct sockaddr_in *)cur->ai_addr; + address->host.is_ipv6 = 0; + address->host.host_v4 = (unsigned int) addr->sin_addr.s_addr; + ret = 0; + break; + } + + if (cur->ai_family == AF_INET6 && cur->ai_addrlen >= sizeof(struct sockaddr_in6)) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)cur->ai_addr; + address->host.is_ipv6 = 1; + memcpy(&address->host.host_v6, &addr->sin6_addr.s6_addr, ENET_HOST_v6_LENGTH); + ret = 0; + break; + } + + } while ((cur = cur->ai_next) != NULL); + + freeaddrinfo(ai_list); + + return ret; +} + +int enet_address_set_host(ENetAddress *address, const char *name) { + return enet_address_set_host_ip(address, name); +} + +static int enet_address_get_nameinfo(const ENetAddress *address, char *name, size_t nameLength, + int flags) { + int ret = -1; + + struct sockaddr *addr; + socklen_t addr_len; + struct sockaddr_in addr_v4; + struct sockaddr_in6 addr_v6; + + if (!name || nameLength == 0) + return ret; + + name[0] = '\0'; + if (address->host.is_ipv6) { + addr = (struct sockaddr *)&addr_v6; + addr_len = sizeof(addr_v6); + memset(addr, 0, addr_len); + + addr_v6.sin6_family = AF_INET6; + memcpy(&addr_v6.sin6_addr.s6_addr, address->host.host_v6, ENET_HOST_v6_LENGTH); + } else { + addr = (struct sockaddr *)&addr_v4; + addr_len = sizeof(addr_v4); + memset(addr, 0, addr_len); + + addr_v4.sin_family = AF_INET; + addr_v4.sin_addr.s_addr = address->host.host_v4; + } + + if (getnameinfo(addr, addr_len, name, nameLength, 0, 0, flags) == 0) { + name[nameLength - 1] = '\0'; + ret = 0; + } + + return ret; +} + +int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) { + return enet_address_get_nameinfo(address, name, nameLength, NI_NUMERICHOST); +} + +int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) { + int ret = enet_address_get_nameinfo(address, name, nameLength, NI_NAMEREQD); + if (ret != 0) { + ret = enet_address_get_host_ip(address, name, nameLength); + } + return ret; +} + +static int enet_address_init_from_sockaddr_storage(ENetAddress *address, + const struct sockaddr_storage *localaddr) { + + if (localaddr->ss_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)localaddr; + address->host.is_ipv6 = 0; + address->host.host_v4 = (enet_uint32)addr->sin_addr.s_addr; + address->port = ENET_NET_TO_HOST_16(addr->sin_port); + } else if (localaddr->ss_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)localaddr; + address->host.is_ipv6 = 1; + memcpy(& address->host.host_v6, & addr->sin6_addr.s6_addr, ENET_HOST_v6_LENGTH); + address->port = ENET_NET_TO_HOST_16 (addr->sin6_port); + } else { + return -1; + } + + return 0; +} + +static socklen_t sockaddr_storage_init_from_enet_address(struct sockaddr_storage *localaddr, + const ENetAddress *address) { + socklen_t addr_len; + + memset(localaddr, 0, sizeof(struct sockaddr_storage)); + + if (address->host.is_ipv6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)localaddr; + addr->sin6_family = AF_INET6; + addr->sin6_port = ENET_HOST_TO_NET_16(address->port); + memcpy(&addr->sin6_addr.s6_addr, address->host.host_v6, ENET_HOST_v6_LENGTH); + addr_len = sizeof(struct sockaddr_in6); + } else { + struct sockaddr_in *addr = (struct sockaddr_in *)localaddr; + addr->sin_family = AF_INET; + addr->sin_port = ENET_HOST_TO_NET_16(address->port); + addr->sin_addr.s_addr = address->host.host_v4; + addr_len = sizeof(struct sockaddr_in); + } + + return addr_len; +} + diff --git a/host.c b/host.c index 3be6c092..05859bb6 100644 --- a/host.c +++ b/host.c @@ -10,6 +10,14 @@ @{ */ +static void enet_socket_set_default_option (ENetSocket socket) +{ + enet_socket_set_option (socket, ENET_SOCKOPT_NONBLOCK, 1); + enet_socket_set_option (socket, ENET_SOCKOPT_BROADCAST, 1); + enet_socket_set_option (socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE); + enet_socket_set_option (socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE); +} + /** Creates a host for communicating to peers. @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host. @@ -48,7 +56,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 (ENET_SOCKET_TYPE_DATAGRAM, address); if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0)) { if (host -> socket != ENET_SOCKET_NULL) @@ -60,10 +68,10 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL return NULL; } - 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_default_option (host -> socket); + + if (address != NULL) + host -> for_listen = 1; if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0) host -> address = * address; @@ -87,7 +95,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; + enet_address_host_init_any (host -> receivedAddress.host); host -> receivedAddress.port = 0; host -> receivedData = NULL; host -> receivedDataLength = 0; @@ -177,6 +185,21 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC ENetChannel * channel; ENetProtocol command; + if (host -> for_listen == 0) + { + if (host -> socket != ENET_SOCKET_NULL) + { + enet_socket_destroy(host -> socket); + host -> socket = ENET_SOCKET_NULL; + } + + host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, address); + if (host -> socket == ENET_SOCKET_NULL) + return NULL; + + enet_socket_set_default_option (host -> socket); + } + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; else diff --git a/include/enet/enet.h b/include/enet/enet.h index c7624538..af20372d 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -11,6 +11,7 @@ extern "C" #endif #include +#include #ifdef _WIN32 #include "enet/win32.h" @@ -72,8 +73,10 @@ 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 /** @@ -86,12 +89,28 @@ typedef enum _ENetSocketShutdown * but not for enet_host_create. Once a server responds to a broadcast, the * address is updated from ENET_HOST_BROADCAST to the server's actual IP address. */ +#define ENET_HOST_v6_LENGTH 16 +struct _all_host_address { + enet_uint8 is_ipv6; + enet_uint32 host_v4; + enet_uint8 host_v6[ENET_HOST_v6_LENGTH]; +}; + typedef struct _ENetAddress { - enet_uint32 host; + struct _all_host_address host; enet_uint16 port; } ENetAddress; +int enet_address_host_is_any_(struct _all_host_address *); + +#define enet_address_host_is_any(a) enet_address_host_is_any_(&a) +#define enet_address_host_init_any(a) (memset(&a, 0, sizeof(struct _all_host_address))) +#define enet_address_host_equal(a, b) (memcmp(&a, &b, sizeof(struct _all_host_address)) == 0) +#define enet_address_host_copy_from(dest, src) (memcpy(&dest, &src, sizeof(struct _all_host_address))) + + + /** * Packet flag bit constants. * @@ -317,6 +336,7 @@ typedef struct _ENetPeer enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; enet_uint32 eventData; size_t totalWaitingData; + enet_int64 sessionGuid; } ENetPeer; /** An ENet packet compressor for compressing UDP packets before socket sends or receives. @@ -359,6 +379,7 @@ typedef struct _ENetHost { ENetSocket socket; ENetAddress address; /**< Internet address of the host */ + int for_listen; enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ enet_uint32 bandwidthThrottleEpoch; @@ -489,7 +510,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 (ENetSocketType, const ENetAddress *); 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); diff --git a/include/enet/types.h b/include/enet/types.h index ab010a4b..b57b40b3 100644 --- a/include/enet/types.h +++ b/include/enet/types.h @@ -9,5 +9,12 @@ typedef unsigned char enet_uint8; /**< unsigned 8-bit type */ typedef unsigned short enet_uint16; /**< unsigned 16-bit type */ typedef unsigned int enet_uint32; /**< unsigned 32-bit type */ +#ifdef _MSC_VER +typedef signed __int64 enet_int64; +#else +#include +typedef int64_t enet_int64; +#endif + #endif /* __ENET_TYPES_H__ */ diff --git a/protocol.c b/protocol.c index 29d64873..6ae8e0fe 100644 --- a/protocol.c +++ b/protocol.c @@ -298,7 +298,7 @@ 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_host_equal(currentPeer -> address.host, host -> receivedAddress.host)) { if (currentPeer -> address.port == host -> receivedAddress.port && currentPeer -> connectID == command -> connect.connectID) @@ -1010,9 +1010,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 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_host_equal(host -> receivedAddress.host, peer -> address.host) || + host -> receivedAddress.port != peer -> address.port) || (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && sessionID != peer -> incomingSessionID)) return 0; @@ -1054,7 +1053,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) if (peer != NULL) { - peer -> address.host = host -> receivedAddress.host; + enet_address_host_copy_from(peer -> address.host, host -> receivedAddress.host); peer -> address.port = host -> receivedAddress.port; peer -> incomingDataTotal += host -> receivedDataLength; } diff --git a/unix.c b/unix.c index c36a082a..be01997a 100644 --- a/unix.c +++ b/unix.c @@ -101,6 +101,7 @@ enet_time_set (enet_uint32 newTimeBase) timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; } +/* int enet_address_set_host_ip (ENetAddress * address, const char * name) { @@ -244,45 +245,46 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng return enet_address_get_host_ip (address, name, nameLength); } +*/ + +#include "common.h" int enet_socket_bind (ENetSocket socket, const ENetAddress * address) { + struct sockaddr *addr; + socklen_t addr_len; struct sockaddr_in sin; - - memset (& sin, 0, sizeof (struct sockaddr_in)); - - sin.sin_family = AF_INET; + struct sockaddr_storage addr_all; if (address != NULL) { - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + addr = (struct sockaddr *) & addr_all; + addr_len = sockaddr_storage_init_from_enet_address (& addr_all, address); } else { + memset (& sin, 0, sizeof (struct sockaddr_in)); + sin.sin_family = AF_INET; sin.sin_port = 0; sin.sin_addr.s_addr = INADDR_ANY; + addr = (struct sockaddr *) & sin; + addr_len = sizeof (struct sockaddr_in); } - return bind (socket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)); + return bind (socket, addr, addr_len); } int enet_socket_get_address (ENetSocket socket, ENetAddress * address) { - struct sockaddr_in sin; - socklen_t sinLength = sizeof (struct sockaddr_in); + struct sockaddr_storage localaddr; + int addrLen = sizeof (localaddr); - if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1) + if (getpeername (socket, (struct sockaddr *) & localaddr, & addrLen) == -1) return -1; - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - - return 0; + return enet_address_init_from_sockaddr_storage(address, &localaddr); } int @@ -292,9 +294,13 @@ enet_socket_listen (ENetSocket socket, int backlog) } ENetSocket -enet_socket_create (ENetSocketType type) +enet_socket_create (ENetSocketType type, const ENetAddress * address) { - return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); + int family = AF_INET; + if (address && address -> host.is_ipv6) + family = AF_INET6; + + return socket (family, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); } int @@ -376,16 +382,10 @@ 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)); + struct sockaddr_storage addr; + socklen_t addr_len = sockaddr_storage_init_from_enet_address (& addr, address); + result = connect (socket, (struct sockaddr *) & addr, addr_len); if (result == -1 && errno == EINPROGRESS) return 0; @@ -396,20 +396,19 @@ ENetSocket enet_socket_accept (ENetSocket socket, ENetAddress * address) { int result; - struct sockaddr_in sin; - socklen_t sinLength = sizeof (struct sockaddr_in); + struct sockaddr_storage client_addr; + socklen_t addr_len = sizeof (client_addr); result = accept (socket, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL); + address != NULL ? (struct sockaddr *) & client_addr : NULL, + address != NULL ? & addr_len : 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); + enet_address_init_from_sockaddr_storage(address, & client_addr); } return result; @@ -435,21 +434,15 @@ enet_socket_send (ENetSocket socket, size_t bufferCount) { struct msghdr msgHdr; - struct sockaddr_in sin; + struct sockaddr_storage addr; 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_name = & addr; + msgHdr.msg_namelen = sockaddr_storage_init_from_enet_address (& addr, address); } msgHdr.msg_iov = (struct iovec *) buffers; @@ -475,15 +468,15 @@ enet_socket_receive (ENetSocket socket, size_t bufferCount) { struct msghdr msgHdr; - struct sockaddr_in sin; + struct sockaddr_storage addr; int recvLength; memset (& msgHdr, 0, sizeof (struct msghdr)); if (address != NULL) { - msgHdr.msg_name = & sin; - msgHdr.msg_namelen = sizeof (struct sockaddr_in); + msgHdr.msg_name = & addr; + msgHdr.msg_namelen = sizeof (addr); } msgHdr.msg_iov = (struct iovec *) buffers; @@ -506,8 +499,7 @@ enet_socket_receive (ENetSocket socket, if (address != NULL) { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + enet_address_init_from_sockaddr_storage(address, & addr); } return recvLength; diff --git a/win32.c b/win32.c index 81175a41..28821d30 100644 --- a/win32.c +++ b/win32.c @@ -5,10 +5,24 @@ #ifdef _WIN32 #define ENET_BUILDING_LIB 1 + +#ifdef __GNUC__ +#if (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif +#endif + +#include + #include "enet/enet.h" #include #include +#ifdef _MSC_VER +#pragma comment(lib, "winmm.lib") +#endif + static enet_uint32 timeBase = 0; int @@ -59,6 +73,7 @@ enet_time_set (enet_uint32 newTimeBase) timeBase = (enet_uint32) timeGetTime () - newTimeBase; } +/* int enet_address_set_host_ip (ENetAddress * address, const char * name) { @@ -137,45 +152,46 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng return 0; } +*/ + +#include "common.h" int enet_socket_bind (ENetSocket socket, const ENetAddress * address) { + struct sockaddr *addr; + socklen_t addr_len; struct sockaddr_in sin; - - memset (& sin, 0, sizeof (struct sockaddr_in)); - - sin.sin_family = AF_INET; + struct sockaddr_storage addr_all; if (address != NULL) { - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + addr = (struct sockaddr *) & addr_all; + addr_len = sockaddr_storage_init_from_enet_address (& addr_all, address); } else { + memset (& sin, 0, sizeof (struct sockaddr_in)); + sin.sin_family = AF_INET; sin.sin_port = 0; sin.sin_addr.s_addr = INADDR_ANY; + addr = (struct sockaddr *) & sin; + addr_len = sizeof (struct sockaddr_in); } - return bind (socket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; + return bind (socket, addr, addr_len) == SOCKET_ERROR ? -1 : 0; } int enet_socket_get_address (ENetSocket socket, ENetAddress * address) { - struct sockaddr_in sin; - int sinLength = sizeof (struct sockaddr_in); + struct sockaddr_storage localaddr; + int addrLen = sizeof (localaddr); - if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1) + if (getpeername (socket, (struct sockaddr *) & localaddr, & addrLen) == -1) return -1; - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - - return 0; + return enet_address_init_from_sockaddr_storage(address, &localaddr); } int @@ -185,9 +201,13 @@ enet_socket_listen (ENetSocket socket, int backlog) } ENetSocket -enet_socket_create (ENetSocketType type) +enet_socket_create (ENetSocketType type, const ENetAddress * address) { - return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); + int family = AF_INET; + if (address && address -> host.is_ipv6) + family = AF_INET6; + + return socket (family, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); } int @@ -257,16 +277,10 @@ 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)); + struct sockaddr_storage addr; + socklen_t addr_len = sockaddr_storage_init_from_enet_address (& addr, address); + result = connect (socket, (struct sockaddr *) & addr, addr_len); if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK) return -1; @@ -277,20 +291,19 @@ ENetSocket enet_socket_accept (ENetSocket socket, ENetAddress * address) { SOCKET result; - struct sockaddr_in sin; - int sinLength = sizeof (struct sockaddr_in); + struct sockaddr_storage client_addr; + socklen_t addr_len = sizeof (client_addr); result = accept (socket, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL); + address != NULL ? (struct sockaddr *) & client_addr : NULL, + address != NULL ? & addr_len : 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); + enet_address_init_from_sockaddr_storage(address, & client_addr); } return result; @@ -315,16 +328,13 @@ enet_socket_send (ENetSocket socket, const ENetBuffer * buffers, size_t bufferCount) { - struct sockaddr_in sin; + struct sockaddr_storage addr; + socklen_t addr_len; 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; + addr_len = sockaddr_storage_init_from_enet_address (& addr, address); } if (WSASendTo (socket, @@ -332,8 +342,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 *) & addr : NULL, + address != NULL ? addr_len : 0, NULL, NULL) == SOCKET_ERROR) { @@ -352,18 +362,18 @@ enet_socket_receive (ENetSocket socket, ENetBuffer * buffers, size_t bufferCount) { - INT sinLength = sizeof (struct sockaddr_in); DWORD flags = 0, recvLength; - struct sockaddr_in sin; + struct sockaddr_storage addr; + socklen_t addr_len = sizeof (addr); if (WSARecvFrom (socket, (LPWSABUF) buffers, (DWORD) bufferCount, & recvLength, & flags, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL, + address != NULL ? (struct sockaddr *) & addr : NULL, + address != NULL ? & addr_len : NULL, NULL, NULL) == SOCKET_ERROR) { @@ -382,8 +392,7 @@ enet_socket_receive (ENetSocket socket, if (address != NULL) { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + enet_address_init_from_sockaddr_storage(address, & addr); } return (int) recvLength; From c6c236222e476a07970f47e366549b4b277d6834 Mon Sep 17 00:00:00 2001 From: lcinx Date: Sun, 25 Jun 2017 02:27:51 +0800 Subject: [PATCH 2/3] Fix warning. --- common.h | 5 +++-- unix.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/common.h b/common.h index 1dee31cf..40018cc4 100644 --- a/common.h +++ b/common.h @@ -1,7 +1,8 @@ int enet_address_host_is_any_(struct _all_host_address *host) { - char zero[sizeof(struct _all_host_address)] = {0}; - return enet_address_host_equal(*((struct _all_host_address *)&zero), *host); + static char zero[sizeof(struct _all_host_address)] = {0}; + struct _all_host_address *temp = (struct _all_host_address *)&zero; + return enet_address_host_equal(*temp, *host); } int enet_address_set_host_ip(ENetAddress *address, const char *name) { diff --git a/unix.c b/unix.c index be01997a..0f6518a8 100644 --- a/unix.c +++ b/unix.c @@ -279,9 +279,9 @@ int enet_socket_get_address (ENetSocket socket, ENetAddress * address) { struct sockaddr_storage localaddr; - int addrLen = sizeof (localaddr); + socklen_t addr_len = sizeof (localaddr); - if (getpeername (socket, (struct sockaddr *) & localaddr, & addrLen) == -1) + if (getpeername (socket, (struct sockaddr *) & localaddr, & addr_len) == -1) return -1; return enet_address_init_from_sockaddr_storage(address, &localaddr); From 53ed819f60cf3897a1cd072aac1e8eb536bf699d Mon Sep 17 00:00:00 2001 From: lcinx Date: Tue, 27 Jun 2017 22:03:13 +0800 Subject: [PATCH 3/3] Fix do connect - Clear the Address. --- common.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common.h b/common.h index 40018cc4..c35eff06 100644 --- a/common.h +++ b/common.h @@ -14,6 +14,11 @@ int enet_address_set_host_ip(ENetAddress *address, const char *name) { memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; + /* clear address data. */ + enet_uint16 addr_port = address->port; + memset(address, 0, sizeof(ENetAddress)); + address->port = addr_port; + if (getaddrinfo(name, 0, &hints, &ai_list) != 0) return ret; @@ -98,6 +103,9 @@ int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLen static int enet_address_init_from_sockaddr_storage(ENetAddress *address, const struct sockaddr_storage *localaddr) { + /* clear address data. */ + memset(address, 0, sizeof(ENetAddress)); + if (localaddr->ss_family == AF_INET) { struct sockaddr_in *addr = (struct sockaddr_in *)localaddr; address->host.is_ipv6 = 0;