diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fe2f1bb..6e5d8553 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,4 +62,5 @@ add_library(enet STATIC protocol.c unix.c win32.c + bilayer.c ) diff --git a/Makefile.am b/Makefile.am index e839463c..d596a389 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,7 @@ enetinclude_HEADERS = \ include/enet/win32.h lib_LTLIBRARIES = libenet.la -libenet_la_SOURCES = callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c +libenet_la_SOURCES = callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c bilayer.c # see info '(libtool) Updating version info' before making a release libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:1:0 AM_CPPFLAGS = -I$(top_srcdir)/include diff --git a/bilayer.c b/bilayer.c new file mode 100644 index 00000000..fff42b96 --- /dev/null +++ b/bilayer.c @@ -0,0 +1,159 @@ +#include + +#include "bilayer.h" + +ENetTransport enet_socket_create_transport(ENetSocketType type, ENetSocket socket) +{ + ENetTransport transport; + + transport.type = ENET_TRANSPORT_TYPE_SOCKET; + transport.context = (void*)0x1; + transport.handle.socket = socket; + + transport.send = enet_socket_send; + transport.recv = enet_socket_receive; + + return transport; +} + + +ENetHost * +enet_host_create_bilayer (ENetTransportType type, const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +{ + if (type == ENET_TRANSPORT_TYPE_CUSTOM) { + ENetHost *host = enet_host_create_notp(address, peerCount, channelLimit, incomingBandwidth, outgoingBandwidth); + host->address = *address; + return host; + } else { + ENetHost *host = enet_host_create(address, peerCount, channelLimit, incomingBandwidth, outgoingBandwidth); + ENetTransport transport = enet_socket_create_transport(ENET_SOCKET_TYPE_DATAGRAM, host->socket); + host->transport = transport; + return host; + } + return NULL; +} + +void enet_host_transport(ENetHost *host, const ENetTransport *transport) +{ + if (transport->type != ENET_TRANSPORT_TYPE_CUSTOM) { + // error + } + + if (transport->context == NULL) { + // error + } + + host->transport = *transport; +} + +ENetHost * +enet_host_create_notp (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +{ + ENetHost * host; + ENetPeer * currentPeer; + + if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID) + return NULL; + + host = (ENetHost *) enet_malloc (sizeof (ENetHost)); + if (host == NULL) + return NULL; + memset (host, 0, sizeof (ENetHost)); + + host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer)); + if (host -> peers == NULL) + { + enet_free (host); + + return NULL; + } + memset (host -> peers, 0, peerCount * sizeof (ENetPeer)); + + /* + host -> socket = enet_socket_create (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) + enet_socket_destroy (host -> socket); + + enet_free (host -> peers); + enet_free (host); + + 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); + + if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0) + host -> address = * address; + + */ + + if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + else + if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + + host -> randomSeed = (enet_uint32) (size_t) host; + host -> randomSeed += enet_host_random_seed (); + host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16); + host -> channelLimit = channelLimit; + host -> incomingBandwidth = incomingBandwidth; + host -> outgoingBandwidth = outgoingBandwidth; + host -> bandwidthThrottleEpoch = 0; + host -> recalculateBandwidthLimits = 0; + host -> mtu = ENET_HOST_DEFAULT_MTU; + host -> peerCount = peerCount; + host -> commandCount = 0; + host -> bufferCount = 0; + host -> checksum = NULL; + host -> receivedAddress.host = ENET_HOST_ANY; + host -> receivedAddress.port = 0; + host -> receivedData = NULL; + host -> receivedDataLength = 0; + + host -> totalSentData = 0; + host -> totalSentPackets = 0; + host -> totalReceivedData = 0; + host -> totalReceivedPackets = 0; + + host -> connectedPeers = 0; + host -> bandwidthLimitedPeers = 0; + host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID; + host -> maximumPacketSize = ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE; + host -> maximumWaitingData = ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA; + + host -> compressor.context = NULL; + host -> compressor.compress = NULL; + host -> compressor.decompress = NULL; + host -> compressor.destroy = NULL; + + host -> intercept = NULL; + + enet_list_clear (& host -> dispatchQueue); + + for (currentPeer = host -> peers; + currentPeer < & host -> peers [host -> peerCount]; + ++ currentPeer) + { + currentPeer -> host = host; + currentPeer -> incomingPeerID = currentPeer - host -> peers; + currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF; + currentPeer -> data = NULL; + + enet_list_clear (& currentPeer -> acknowledgements); + enet_list_clear (& currentPeer -> sentReliableCommands); + enet_list_clear (& currentPeer -> sentUnreliableCommands); + enet_list_clear (& currentPeer -> outgoingReliableCommands); + enet_list_clear (& currentPeer -> outgoingUnreliableCommands); + enet_list_clear (& currentPeer -> dispatchedCommands); + + enet_peer_reset (currentPeer); + } + + return host; +} diff --git a/bilayer.h b/bilayer.h new file mode 100644 index 00000000..bbc3f3cb --- /dev/null +++ b/bilayer.h @@ -0,0 +1,12 @@ +#ifndef BILAYER_H +#define BILAYER_H + +#include "enet/enet.h" + +ENET_API ENetTransport enet_socket_create_transport(ENetSocketType, ENetSocket); + +ENET_API ENetHost * enet_host_create_bilayer (ENetTransportType type, const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); +ENET_API ENetHost * enet_host_create_notp (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); +ENET_API void enet_host_transport(ENetHost *host, const ENetTransport *transport); + +#endif /* BILAYER_H */ diff --git a/include/enet/enet.h b/include/enet/enet.h index 5e21ee8e..ce158310 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -90,6 +90,7 @@ typedef struct _ENetAddress { enet_uint32 host; enet_uint16 port; + uint64_t extra; } ENetAddress; /** @@ -334,7 +335,28 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b /** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, struct _ENetEvent * event); - + +typedef enum _ENetTransportType +{ + /** no event occurred within the specified time limit */ + ENET_TRANSPORT_TYPE_NONE = 0, + ENET_TRANSPORT_TYPE_SOCKET = 1, + ENET_TRANSPORT_TYPE_CUSTOM = 2, +} ENetTransportType; + +typedef struct _ENetTransport +{ + ENetTransportType type; + void *context; + union { + ENetSocket socket; + void *nosocket; + } handle; + + void (*send)(); + void (*recv)(); +} ENetTransport; + /** An ENet host for communicating with peers. * * No fields should be modified unless otherwise stated. @@ -353,6 +375,7 @@ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, st */ typedef struct _ENetHost { + ENetTransport transport; ENetSocket socket; ENetAddress address; /**< Internet address of the host */ enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ @@ -541,7 +564,6 @@ ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32); 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 void enet_host_destroy (ENetHost *); ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);