Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipv6 support #73

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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)

148 changes: 148 additions & 0 deletions common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@

int enet_address_host_is_any_(struct _all_host_address *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) {
int ret = -1;

struct addrinfo hints;
struct addrinfo *ai_list, *cur;

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;

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) {

/* 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;
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;
}

35 changes: 29 additions & 6 deletions host.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
25 changes: 23 additions & 2 deletions include/enet/enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern "C"
#endif

#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#include "enet/win32.h"
Expand Down Expand Up @@ -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

/**
Expand All @@ -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.
*
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Loading