[enet-cvs] CVS: enet enet.dsp,NONE,1.1 host.c,1.7,1.8 list.c,1.2,1.3 memory.c,1.2,1.3 packet.c,1.3,1.4 peer.c,1.8,1.9 protocol.c,1.10,1.11 unix.c,1.7,1.8 win32.c,1.6,1.7

Brian Hook (ENet CVS) enet-discuss@lists.puremagic.com
Sat, 8 Mar 2003 16:56:31 -0700


Update of /home/enet/cvsroot/enet
In directory sferik:/tmp/cvs-serv10499

Modified Files:
	host.c list.c memory.c packet.c peer.c protocol.c unix.c 
	win32.c 
Added Files:
	enet.dsp 
Log Message:



--- NEW FILE: enet.dsp ---
# Microsoft Developer Studio Project File - Name="enet" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Static Library" 0x0104

CFG=enet - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "enet.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "enet.mak" CFG="enet - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "enet - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "enet - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE 

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe

!IF  "$(CFG)" == "enet - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo

!ELSEIF  "$(CFG)" == "enet - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ  /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "include/enet" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ  /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo

!ENDIF 

# Begin Target

# Name "enet - Win32 Release"
# Name "enet - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=.\host.c
# End Source File
# Begin Source File

SOURCE=.\list.c
# End Source File
# Begin Source File

SOURCE=.\memory.c
# End Source File
# Begin Source File

SOURCE=.\packet.c
# End Source File
# Begin Source File

SOURCE=.\peer.c
# End Source File
# Begin Source File

SOURCE=.\protocol.c
# End Source File
# Begin Source File

SOURCE=.\unix.c
# End Source File
# Begin Source File

SOURCE=.\win32.c
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File

SOURCE=.\include\enet\enet.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\list.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\memory.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\protocol.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\time.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\types.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\unix.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\utility.h
# End Source File
# Begin Source File

SOURCE=.\include\enet\win32.h
# End Source File
# End Group
# End Target
# End Project

Index: host.c
===================================================================
RCS file: /home/enet/cvsroot/enet/host.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- host.c	2003/03/08 01:49:13	1.7
+++ host.c	2003/03/08 23:56:28	1.8
@@ -1,328 +1,374 @@
-#include "memory.h"
-#include "enet.h"
-
-ENetHost *
-enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
-{
-    ENetHost * host = (ENetHost *) enet_malloc (sizeof (ENetHost));
-    ENetPeer * currentPeer;
-
-    host -> peers = (ENetPeer *) enet_calloc (peerCount, sizeof (ENetPeer));
-
-    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, address);
-    if (host -> socket == ENET_SOCKET_NULL)
-    {
-       enet_free (host -> peers);
-       enet_free (host);
-
-       return NULL;
-    }
-
-    if (address != NULL)
-      host -> address = * address;
-
-    host -> incomingBandwidth = incomingBandwidth;
-    host -> outgoingBandwidth = outgoingBandwidth;
-    host -> bandwidthThrottleEpoch = 0;
-    host -> recalculateBandwidthLimits = 0;
-    host -> peerCount = peerCount;
-    host -> lastServicedPeer = host -> peers;
-    host -> commandCount = 0;
-    host -> bufferCount = 0;
-    host -> receivedAddress.host = ENET_HOST_ANY;
-    host -> receivedAddress.port = 0;
-    host -> receivedDataLength = 0;
-     
-    for (currentPeer = host -> peers;
-         currentPeer < & host -> peers [host -> peerCount];
-         ++ currentPeer)
-    {
-       currentPeer -> host = host;
-       currentPeer -> incomingPeerID = currentPeer - host -> peers;
-       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_peer_reset (currentPeer);
-    }
- 
-    return host;
-}
-
-void
-enet_host_destroy (ENetHost * host)
-{
-    ENetPeer * currentPeer;
-
-    enet_socket_destroy (host -> socket);
-
-    for (currentPeer = host -> peers;
-         currentPeer < & host -> peers [host -> peerCount];
-         ++ currentPeer)
-    {
-       enet_peer_reset (currentPeer);
-    }
-
-    enet_free (host -> peers);
-    enet_free (host);
-}
-
-ENetPeer *
-enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount)
-{
-    ENetPeer * currentPeer;
-    ENetChannel * channel;
-    ENetProtocol command;
-
-    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
-      channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
-    else
-    if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
-      channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
-
-    for (currentPeer = host -> peers;
-         currentPeer < & host -> peers [host -> peerCount];
-         ++ currentPeer)
-    {
-       if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
-         break;
-    }
-
-    if (currentPeer >= & host -> peers [host -> peerCount])
-      return NULL;
-
-    currentPeer -> state = ENET_PEER_STATE_CONNECTING;
-    currentPeer -> address = * address;
-    currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
-    currentPeer -> channelCount = channelCount;
-
-    for (channel = currentPeer -> channels;
-         channel < & currentPeer -> channels [channelCount];
-         ++ channel)
-    {
-        channel -> outgoingReliableSequenceNumber = 0;
-        channel -> outgoingUnreliableSequenceNumber = 0;
-        channel -> incomingReliableSequenceNumber = 0;
-        channel -> incomingUnreliableSequenceNumber = 0;
-
-        enet_list_clear (& channel -> incomingReliableCommands);
-        enet_list_clear (& channel -> incomingUnreliableCommands);
-    }
-        
-    command.header.command = ENET_PROTOCOL_COMMAND_CONNECT;
-    command.header.channelID = 0xFF;
-    command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
-    command.header.commandLength = sizeof (ENetProtocolConnect);
-    command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
-    command.connect.packetSize = ENET_HOST_TO_NET_16 (currentPeer -> packetSize);
-    command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
-    command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
-    command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
-    command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
-    command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
-    command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
-    command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
-    
-    enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
-
-    return currentPeer;
-}
-
-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);
-}
-
-void
-enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
-{
-    host -> incomingBandwidth = incomingBandwidth;
-    host -> outgoingBandwidth = outgoingBandwidth;
-    host -> recalculateBandwidthLimits = 1;
-}
-
-void
-enet_host_bandwidth_throttle (ENetHost * host)
-{
-    enet_uint32 timeCurrent = enet_time_get (),
-           elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
-           peersTotal = 0,
-           dataTotal = 0,
-           peersRemaining,
-           bandwidth,
-           throttle = 0,
-           bandwidthLimit = 0;
-    int needsAdjustment;
-    ENetPeer * peer;
-    ENetProtocol command;
-
-    if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
-      return;
-
-    for (peer = host -> peers;
-         peer < & host -> peers [host -> peerCount];
-         ++ peer)
-    {
-        if (peer -> state != ENET_PEER_STATE_CONNECTED)
-          continue;
-
-        ++ peersTotal;
-        dataTotal += peer -> outgoingDataTotal;
-    }
-
-    if (peersTotal == 0)
-      return;
-
-    peersRemaining = peersTotal;
-    needsAdjustment = 1;
-
-    if (host -> outgoingBandwidth == 0)
-      bandwidth = ~0;
-    else
-      bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
-
-    while (peersRemaining > 0 && needsAdjustment != 0)
-    {
-        needsAdjustment = 0;
-        
-        if (dataTotal < bandwidth)
-          throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
-        else
-          throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
-
-        for (peer = host -> peers;
-             peer < & host -> peers [host -> peerCount];
-             ++ peer)
-        {
-            enet_uint32 peerBandwidth;
-            
-            if (peer -> state != ENET_PEER_STATE_CONNECTED ||
-                peer -> incomingBandwidth == 0 ||
-                peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
-              continue;
-
-            peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
-            if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
-              continue;
-
-            peer -> packetThrottleLimit = (peerBandwidth * 
-                                            ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
-            
-            if (peer -> packetThrottleLimit == 0)
-              peer -> packetThrottleLimit = 1;
-            
-            if (peer -> packetThrottle > peer -> packetThrottleLimit)
-              peer -> packetThrottle = peer -> packetThrottleLimit;
-
-            peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
-
-            
-            needsAdjustment = 1;
-            -- peersRemaining;
-            bandwidth -= peerBandwidth;
-            dataTotal -= peerBandwidth;
-        }
-    }
-
-    if (peersRemaining > 0)
-    for (peer = host -> peers;
-         peer < & host -> peers [host -> peerCount];
-         ++ peer)
-    {
-        if (peer -> state != ENET_PEER_STATE_CONNECTED ||
-            peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
-          continue;
-
-        peer -> packetThrottleLimit = throttle;
-
-        if (peer -> packetThrottle > peer -> packetThrottleLimit)
-          peer -> packetThrottle = peer -> packetThrottleLimit;
-    }
-    
-    if (host -> recalculateBandwidthLimits)
-    {
-       host -> recalculateBandwidthLimits = 0;
-
-       peersRemaining = peersTotal;
-       bandwidth = host -> incomingBandwidth;
-       needsAdjustment = 1;
-
-       if (bandwidth == 0)
-         bandwidthLimit = 0;
-       else
-       while (peersRemaining > 0 && needsAdjustment != 0)
-       {
-           needsAdjustment = 0;
-           bandwidthLimit = bandwidth / peersRemaining;
-
-           for (peer = host -> peers;
-                peer < & host -> peers [host -> peerCount];
-                ++ peer)
-           {
-               if (peer -> state != ENET_PEER_STATE_CONNECTED ||
-                   peer -> incomingBandwidthThrottleEpoch == timeCurrent)
-                 continue;
-
-               if (peer -> outgoingBandwidth > 0 &&
-                   bandwidthLimit > peer -> outgoingBandwidth)
-                 continue;
-
-               peer -> incomingBandwidthThrottleEpoch = timeCurrent;
- 
-               needsAdjustment = 1;
-               -- peersRemaining;
-               bandwidth -= peer -> outgoingBandwidth;
-           }
-       }
-
-       for (peer = host -> peers;
-            peer < & host -> peers [host -> peerCount];
-            ++ peer)
-       {
-           if (peer -> state != ENET_PEER_STATE_CONNECTED)
-             continue;
-
-           command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT;
-           command.header.channelID = 0xFF;
-           command.header.flags = 0;
-           command.header.commandLength = sizeof (ENetProtocolBandwidthLimit);
-           command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
-
-           if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
-             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
-           else
-             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
-
-           enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
-       } 
-    }
-
-    host -> bandwidthThrottleEpoch = timeCurrent;
-
-    for (peer = host -> peers;
-         peer < & host -> peers [host -> peerCount];
-         ++ peer)
-    {
-        peer -> incomingDataTotal = 0;
-        peer -> outgoingDataTotal = 0;
-    }
-}
-    
+/** 
+ @file host.c
+ @brief ENet host management functions
+*/
+#include "memory.h"
+#include "enet.h"
+
+/** @defgroup host ENet host functions
+    @{
+*/
+
+/** 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.
+    @param peerCount the maximum number of peers that should be allocated for the host.
+    @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+    @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+
+    @returns the host on success and NULL on failure
+
+    @remarks ENet will strategically drop packets on specific sides of a connection between hosts
+    to ensure the host's bandwidth is not overwhelmed.  The bandwidth parameters also determine
+    the window size of a connection which limits the amount of reliable packets that may be in transit
+    at any given time.
+*/
+ENetHost *
+enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+    ENetHost * host = (ENetHost *) enet_malloc (sizeof (ENetHost));
+    ENetPeer * currentPeer;
+
+    host -> peers = (ENetPeer *) enet_calloc (peerCount, sizeof (ENetPeer));
+
+    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, address);
+    if (host -> socket == ENET_SOCKET_NULL)
+    {
+       enet_free (host -> peers);
+       enet_free (host);
+
+       return NULL;
+    }
+
+    if (address != NULL)
+      host -> address = * address;
+
+    host -> incomingBandwidth = incomingBandwidth;
+    host -> outgoingBandwidth = outgoingBandwidth;
+    host -> bandwidthThrottleEpoch = 0;
+    host -> recalculateBandwidthLimits = 0;
+    host -> peerCount = peerCount;
+    host -> lastServicedPeer = host -> peers;
+    host -> commandCount = 0;
+    host -> bufferCount = 0;
+    host -> receivedAddress.host = ENET_HOST_ANY;
+    host -> receivedAddress.port = 0;
+    host -> receivedDataLength = 0;
+     
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       currentPeer -> host = host;
+       currentPeer -> incomingPeerID = currentPeer - host -> peers;
+       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_peer_reset (currentPeer);
+    }
+ 
+    return host;
+}
+
+/** Destroys the host and all resources associated with it.
+    @param host pointer to the host to destroy
+*/
+void
+enet_host_destroy (ENetHost * host)
+{
+    ENetPeer * currentPeer;
+
+    enet_socket_destroy (host -> socket);
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       enet_peer_reset (currentPeer);
+    }
+
+    enet_free (host -> peers);
+    enet_free (host);
+}
+
+/** Initiates a connection to a foreign host.
+    @param host host seeking the connection
+    @param address destination for the connection
+    @param channelCount number of channels to allocate
+    @returns a peer representing the foreign host on success, NULL on failure
+    @remarks The peer returned will have not completed the connection until enet_host_service()
+    notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
+*/
+ENetPeer *
+enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount)
+{
+    ENetPeer * currentPeer;
+    ENetChannel * channel;
+    ENetProtocol command;
+
+    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+      channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+    else
+    if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
+         break;
+    }
+
+    if (currentPeer >= & host -> peers [host -> peerCount])
+      return NULL;
+
+    currentPeer -> state = ENET_PEER_STATE_CONNECTING;
+    currentPeer -> address = * address;
+    currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
+    currentPeer -> channelCount = channelCount;
+
+    for (channel = currentPeer -> channels;
+         channel < & currentPeer -> channels [channelCount];
+         ++ channel)
+    {
+        channel -> outgoingReliableSequenceNumber = 0;
+        channel -> outgoingUnreliableSequenceNumber = 0;
+        channel -> incomingReliableSequenceNumber = 0;
+        channel -> incomingUnreliableSequenceNumber = 0;
+
+        enet_list_clear (& channel -> incomingReliableCommands);
+        enet_list_clear (& channel -> incomingUnreliableCommands);
+    }
+        
+    command.header.command = ENET_PROTOCOL_COMMAND_CONNECT;
+    command.header.channelID = 0xFF;
+    command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
+    command.header.commandLength = sizeof (ENetProtocolConnect);
+    command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
+    command.connect.packetSize = ENET_HOST_TO_NET_16 (currentPeer -> packetSize);
+    command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
+    command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
+    command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
+    command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+    command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
+    command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
+    command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
+    
+    enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
+
+    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);
+}
+
+/** Adjusts the bandwidth limits of a host.
+    @param host host to adjust
+    @param incomingBandwidth new incoming bandwidth
+    @param outgoingBandwidth new outgoing bandwidth
+    @remarks the incoming and outgoing bandwidth parameters are identical in function to those
+    specified in enet_host_create().
+*/
+void
+enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+    host -> incomingBandwidth = incomingBandwidth;
+    host -> outgoingBandwidth = outgoingBandwidth;
+    host -> recalculateBandwidthLimits = 1;
+}
+
+void
+enet_host_bandwidth_throttle (ENetHost * host)
+{
+    enet_uint32 timeCurrent = enet_time_get (),
+           elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
+           peersTotal = 0,
+           dataTotal = 0,
+           peersRemaining,
+           bandwidth,
+           throttle = 0,
+           bandwidthLimit = 0;
+    int needsAdjustment;
+    ENetPeer * peer;
+    ENetProtocol command;
+
+    if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
+      return;
+
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        if (peer -> state != ENET_PEER_STATE_CONNECTED)
+          continue;
+
+        ++ peersTotal;
+        dataTotal += peer -> outgoingDataTotal;
+    }
+
+    if (peersTotal == 0)
+      return;
+
+    peersRemaining = peersTotal;
+    needsAdjustment = 1;
+
+    if (host -> outgoingBandwidth == 0)
+      bandwidth = ~0;
+    else
+      bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
+
+    while (peersRemaining > 0 && needsAdjustment != 0)
+    {
+        needsAdjustment = 0;
+        
+        if (dataTotal < bandwidth)
+          throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
+        else
+          throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
+
+        for (peer = host -> peers;
+             peer < & host -> peers [host -> peerCount];
+             ++ peer)
+        {
+            enet_uint32 peerBandwidth;
+            
+            if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+                peer -> incomingBandwidth == 0 ||
+                peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+              continue;
+
+            peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
+            if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
+              continue;
+
+            peer -> packetThrottleLimit = (peerBandwidth * 
+                                            ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
+            
+            if (peer -> packetThrottleLimit == 0)
+              peer -> packetThrottleLimit = 1;
+            
+            if (peer -> packetThrottle > peer -> packetThrottleLimit)
+              peer -> packetThrottle = peer -> packetThrottleLimit;
+
+            peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
+
+            
+            needsAdjustment = 1;
+            -- peersRemaining;
+            bandwidth -= peerBandwidth;
+            dataTotal -= peerBandwidth;
+        }
+    }
+
+    if (peersRemaining > 0)
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+            peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+          continue;
+
+        peer -> packetThrottleLimit = throttle;
+
+        if (peer -> packetThrottle > peer -> packetThrottleLimit)
+          peer -> packetThrottle = peer -> packetThrottleLimit;
+    }
+    
+    if (host -> recalculateBandwidthLimits)
+    {
+       host -> recalculateBandwidthLimits = 0;
+
+       peersRemaining = peersTotal;
+       bandwidth = host -> incomingBandwidth;
+       needsAdjustment = 1;
+
+       if (bandwidth == 0)
+         bandwidthLimit = 0;
+       else
+       while (peersRemaining > 0 && needsAdjustment != 0)
+       {
+           needsAdjustment = 0;
+           bandwidthLimit = bandwidth / peersRemaining;
+
+           for (peer = host -> peers;
+                peer < & host -> peers [host -> peerCount];
+                ++ peer)
+           {
+               if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+                   peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+                 continue;
+
+               if (peer -> outgoingBandwidth > 0 &&
+                   bandwidthLimit > peer -> outgoingBandwidth)
+                 continue;
+
+               peer -> incomingBandwidthThrottleEpoch = timeCurrent;
+ 
+               needsAdjustment = 1;
+               -- peersRemaining;
+               bandwidth -= peer -> outgoingBandwidth;
+           }
+       }
+
+       for (peer = host -> peers;
+            peer < & host -> peers [host -> peerCount];
+            ++ peer)
+       {
+           if (peer -> state != ENET_PEER_STATE_CONNECTED)
+             continue;
+
+           command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT;
+           command.header.channelID = 0xFF;
+           command.header.flags = 0;
+           command.header.commandLength = sizeof (ENetProtocolBandwidthLimit);
+           command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+
+           if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
+           else
+             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
+
+           enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+       } 
+    }
+
+    host -> bandwidthThrottleEpoch = timeCurrent;
+
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        peer -> incomingDataTotal = 0;
+        peer -> outgoingDataTotal = 0;
+    }
+}
+    
+/** @} */

Index: list.c
===================================================================
RCS file: /home/enet/cvsroot/enet/list.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- list.c	2003/03/08 01:49:13	1.2
+++ list.c	2003/03/08 23:56:28	1.3
@@ -1,46 +1,56 @@
-#include "list.h"
-
-void
-enet_list_clear (ENetList * list)
-{
-   list -> sentinel.next = & list -> sentinel;
-   list -> sentinel.previous = & list -> sentinel;
-}
-
-ENetListIterator
-enet_list_insert (ENetListIterator position, void * data)
-{
-   ENetListIterator result = (ENetListIterator) data;
-
-   result -> previous = position -> previous;
-   result -> next = position;
-
-   result -> previous -> next = result;
-   position -> previous = result;
-
-   return result;
-}
-
-void *
-enet_list_remove (ENetListIterator position)
-{
-   position -> previous -> next = position -> next;
-   position -> next -> previous = position -> previous;
-
-   return position;
-}
-
-size_t
-enet_list_size (ENetList * list)
-{
-   size_t size = 0;
-   ENetListIterator position;
-
-   for (position = enet_list_begin (list);
-        position != enet_list_end (list);
-        position = enet_list_next (position))
-     ++ size;
-   
-   return size;
-}
-
+/** 
+ @file list.c
+ @brief ENet linked list functions
+*/
+#include "list.h"
+
+/** 
+    @defgroup list ENet linked list utility functions
+    @ingroup private
+    @{
+*/
+void
+enet_list_clear (ENetList * list)
+{
+   list -> sentinel.next = & list -> sentinel;
+   list -> sentinel.previous = & list -> sentinel;
+}
+
+ENetListIterator
+enet_list_insert (ENetListIterator position, void * data)
+{
+   ENetListIterator result = (ENetListIterator) data;
+
+   result -> previous = position -> previous;
+   result -> next = position;
+
+   result -> previous -> next = result;
+   position -> previous = result;
+
+   return result;
+}
+
+void *
+enet_list_remove (ENetListIterator position)
+{
+   position -> previous -> next = position -> next;
+   position -> next -> previous = position -> previous;
+
+   return position;
+}
+
+size_t
+enet_list_size (ENetList * list)
+{
+   size_t size = 0;
+   ENetListIterator position;
+
+   for (position = enet_list_begin (list);
+        position != enet_list_end (list);
+        position = enet_list_next (position))
+     ++ size;
+   
+   return size;
+}
+
+/** @} */

Index: memory.c
===================================================================
RCS file: /home/enet/cvsroot/enet/memory.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- memory.c	2003/03/08 01:49:13	1.2
+++ memory.c	2003/03/08 23:56:28	1.3
@@ -1,43 +1,47 @@
-#include "types.h"
-#include "memory.h"
-
-void *
-enet_malloc (size_t size)
-{
-   void * memory = malloc (size);
-
-   if (memory == NULL)
-     abort ();
-
-   return memory;
-}
-
-void *
-enet_realloc (void * memory, size_t size)
-{
-   memory = realloc (memory, size);
-
-   if (size > 0 &&
-       memory == NULL)
-     abort ();
-
-   return memory;
-}
-
-void *
-enet_calloc (size_t elements, size_t size)
-{
-   void * memory = calloc (elements, size);
-
-   if (memory == NULL)
-     abort ();
-
-   return memory;
-}
-
-void
-enet_free (void * memory)
-{
-   free (memory);
-}
-
+/** 
+ @file memory.c
+ @brief ENet memory management functions
+*/
+#include "types.h"
+#include "memory.h"
+
+void *
+enet_malloc (size_t size)
+{
+   void * memory = malloc (size);
+
+   if (memory == NULL)
+     abort ();
+
+   return memory;
+}
+
+void *
+enet_realloc (void * memory, size_t size)
+{
+   memory = realloc (memory, size);
+
+   if (size > 0 &&
+       memory == NULL)
+     abort ();
+
+   return memory;
+}
+
+void *
+enet_calloc (size_t elements, size_t size)
+{
+   void * memory = calloc (elements, size);
+
+   if (memory == NULL)
+     abort ();
+
+   return memory;
+}
+
+void
+enet_free (void * memory)
+{
+   free (memory);
+}
+

Index: packet.c
===================================================================
RCS file: /home/enet/cvsroot/enet/packet.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- packet.c	2003/03/08 01:49:13	1.3
+++ packet.c	2003/03/08 23:56:28	1.4
@@ -1,48 +1,72 @@
-#include <string.h>
-#include "memory.h"
-#include "enet.h"
-
-ENetPacket *
-enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
-{
-    ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
-
-    packet -> data = (enet_uint8 *) enet_malloc (dataLength);
-
-    if (data != NULL)
-      memcpy (packet -> data, data, dataLength);
-
-    packet -> referenceCount = 0;
-    packet -> flags = flags;
-    packet -> dataLength = dataLength;
-
-    return packet;
-}
-
-void
-enet_packet_destroy (ENetPacket * packet)
-{
-    enet_free (packet -> data);
-    enet_free (packet);
-}
-
-int
-enet_packet_resize (ENetPacket * packet, size_t dataLength)
-{
-    enet_uint8 * newData;
-   
-    if (dataLength <= packet -> dataLength)
-    {
-       packet -> dataLength = dataLength;
-
-       return 0;
-    }
-
-    newData = (enet_uint8 *) enet_realloc (packet -> data, dataLength);
-
-    packet -> data = newData;
-    packet -> dataLength = dataLength;
-
-    return 0;
-}
-
+/** 
+ @file  packet.c
+ @brief ENet packet management functions
+*/
+#include <string.h>
+#include "memory.h"
+#include "enet.h"
+
+/** @defgroup Packet ENet packet functions 
+    @{ 
+*/
+
+/** Creates a packet that may be sent to a peer.
+    @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
+    @param dataLength   size of the data allocated for this packet
+    @param flags        flags for this packet as described for the ENetPacket structure.
+    @returns the packet on success, NULL on failure
+*/
+ENetPacket *
+enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
+{
+    ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
+
+    packet -> data = (enet_uint8 *) enet_malloc (dataLength);
+
+    if (data != NULL)
+      memcpy (packet -> data, data, dataLength);
+
+    packet -> referenceCount = 0;
+    packet -> flags = flags;
+    packet -> dataLength = dataLength;
+
+    return packet;
+}
+
+/** Destroys the packet and deallocates its data.
+    @param packet packet to be destroyed
+*/
+void
+enet_packet_destroy (ENetPacket * packet)
+{
+    enet_free (packet -> data);
+    enet_free (packet);
+}
+
+/** Attempts to resize the data in the packet to length specified in the 
+    dataLength parameter 
+    @param packet packet to resize
+    @param dataLength new size for the packet data
+    @returns 0 on success, < 0 on failure
+*/
+int
+enet_packet_resize (ENetPacket * packet, size_t dataLength)
+{
+    enet_uint8 * newData;
+   
+    if (dataLength <= packet -> dataLength)
+    {
+       packet -> dataLength = dataLength;
+
+       return 0;
+    }
+
+    newData = (enet_uint8 *) enet_realloc (packet -> data, dataLength);
+
+    packet -> data = newData;
+    packet -> dataLength = dataLength;
+
+    return 0;
+}
+
+/** @} */

Index: peer.c
===================================================================
RCS file: /home/enet/cvsroot/enet/peer.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- peer.c	2003/03/08 01:49:13	1.8
+++ peer.c	2003/03/08 23:56:28	1.9
@@ -1,508 +1,576 @@
-#include "memory.h"
-#include "enet.h"
-
-void
-enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
-{
-    ENetProtocol command;
-
-    peer -> packetThrottleInterval = interval;
-    peer -> packetThrottleAcceleration = acceleration;
-    peer -> packetThrottleDeceleration = deceleration;
[...1053 lines suppressed...]
+      incomingCommand -> fragments = NULL;
+
+    if (packet != NULL)
+      ++ packet -> referenceCount;
+
+    enet_list_insert (enet_list_next (currentCommand), incomingCommand);
+
+    return incomingCommand;
+
+freePacket:
+    if (packet != NULL)
+    {
+       if (packet -> referenceCount == 0)
+         enet_packet_destroy (packet);
+    }
+
+    return NULL;
+}
+
+/** @} */

Index: protocol.c
===================================================================
RCS file: /home/enet/cvsroot/enet/protocol.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- protocol.c	2003/03/08 01:49:13	1.10
+++ protocol.c	2003/03/08 23:56:28	1.11
@@ -1,1104 +1,1126 @@
-#include <stdio.h>
-#include "memory.h"
-#include "time.h"
-#include "enet.h"
-
-static enet_uint32 timeCurrent;
-
-static int
-enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
-{
-    ENetPeer * currentPeer = host -> lastServicedPeer;
[...2199 lines suppressed...]
+       default:
+          break;
+       }
+
+       timeCurrent = enet_time_get ();
+
+       if (ENET_TIME_GREATER_EQUAL (timeCurrent, timeout))
+         return 0;
+
+       waitCondition = ENET_SOCKET_WAIT_RECEIVE;
+
+       if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, timeCurrent)) != 0)
+         return -1;
+       
+       timeCurrent = enet_time_get ();
+    } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE);
+
+    return 0; 
+}
+

Index: unix.c
===================================================================
RCS file: /home/enet/cvsroot/enet/unix.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- unix.c	2003/03/08 01:49:13	1.7
+++ unix.c	2003/03/08 23:56:29	1.8
@@ -1,361 +1,365 @@
-#ifndef WIN32
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include "enet.h"
-
-#ifdef HAS_FCNTL
-#include <fcntl.h>
-#endif
-
-#ifdef HAS_POLL
-#include <sys/poll.h>
-#endif
-
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-
-static enet_uint32 timeBase = 0;
-
-int
-enet_initialize (void)
-{
-    return 0;
-}
-
-void
-enet_deinitialize (void)
-{
-}
-
-enet_uint32
-enet_time_get (void)
-{
-    struct timeval timeVal;
-
-    gettimeofday (& timeVal, NULL);
-
-    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
-}
-
-void
-enet_time_set (enet_uint32 newTimeBase)
-{
-    struct timeval timeVal;
-
-    gettimeofday (& timeVal, NULL);
-    
-    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
-}
-
-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;
-
-#ifdef linux
-    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
-#else
-    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
-#endif
-#else
-    hostEntry = gethostbyname (name);
-#endif
-
-    if (hostEntry == NULL ||
-        hostEntry -> h_addrtype != AF_INET)
-      return -1;
-
-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
-
-    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;
-
-#ifdef linux
-    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 -1;
-
-    strncpy (name, hostEntry -> h_name, nameLength);
-
-    return 0;
-}
-
-ENetSocket
-enet_socket_create (ENetSocketType type, const ENetAddress * address)
-{
-    ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
-    int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE;
-#ifndef HAS_FCNTL
-    int nonBlocking = 1;
-#endif
-    struct sockaddr_in sin;
-
-    if (newSocket == ENET_SOCKET_NULL)
-      return ENET_SOCKET_NULL;
-
-    if (type == ENET_SOCKET_TYPE_DATAGRAM)
-    {
-#ifdef HAS_FCNTL
-        fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL));
-#else
-        ioctl (newSocket, FIONBIO, & nonBlocking);
-#endif
-
-        setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
-    }
-    
-    if (address == NULL)
-      return newSocket;
-
-    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;
-
-    if ((type == ENET_SOCKET_TYPE_STREAM &&
-          listen (newSocket, SOMAXCONN) == -1) ||
-        bind (newSocket, 
-              (struct sockaddr *) & sin,
-              sizeof (struct sockaddr_in)) == -1)
-    {
-       close (newSocket);
-
-       return ENET_SOCKET_NULL;
-    }
-
-    return newSocket;
-}
-
-int
-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    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;
-
-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
-}
-
-ENetSocket
-enet_socket_accept (ENetSocket socket, ENetAddress * address)
-{
-    int result;
-    struct sockaddr_in sin;
-    socklen_t sinLength = sizeof (struct sockaddr_in);
-
-    result = accept (socket, 
-                     address != NULL ? (struct sockaddr *) & sin : NULL, 
-                     address != NULL ? & sinLength : 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;
-} 
-    
-void
-enet_socket_destroy (ENetSocket socket)
-{
-    close (socket);
-}
-
-int
-enet_socket_send (ENetSocket socket,
-                  const ENetAddress * address,
-                  const ENetBuffer * buffers,
-                  size_t bufferCount)
-{
-    struct msghdr msgHdr;
-    struct sockaddr_in sin;
-    int sentLength;
-
-    memset (& msgHdr, 0, sizeof (struct msghdr));
-
-    if (address != NULL)
-    {
-        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_iov = (struct iovec *) buffers;
-    msgHdr.msg_iovlen = bufferCount;
-
-    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
-    
-    if (sentLength == -1)
-    {
-       if (errno == EWOULDBLOCK)
-         return 0;
-
-       return -1;
-    }
-
-    return sentLength;
-}
-
-int
-enet_socket_receive (ENetSocket socket,
-                     ENetAddress * address,
-                     ENetBuffer * buffers,
-                     size_t bufferCount)
-{
-    struct msghdr msgHdr;
-    struct sockaddr_in sin;
-    int recvLength;
-
-    memset (& msgHdr, 0, sizeof (struct msghdr));
-
-    if (address != NULL)
-    {
-        msgHdr.msg_name = & sin;
-        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
-    }
-
-    msgHdr.msg_iov = (struct iovec *) buffers;
-    msgHdr.msg_iovlen = bufferCount;
-
-    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
-
-    if (recvLength == -1)
-    {
-       if (errno == EWOULDBLOCK)
-         return 0;
-
-       return -1;
-    }
-
-#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;
-}
-
-int
-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
-{
-#ifdef HAS_POLL
-    struct pollfd pollSocket;
-    int pollCount;
-    
-    pollSocket.fd = socket;
-    pollSocket.events = 0;
-
-    if (* condition & ENET_SOCKET_WAIT_SEND)
-      pollSocket.events |= POLLOUT;
-
-    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-      pollSocket.events |= POLLIN;
-
-    pollCount = poll (& pollSocket, 1, timeout);
-
-    if (pollCount < 0)
-      return -1;
-
-    * condition = ENET_SOCKET_WAIT_NONE;
-
-    if (pollCount == 0)
-      return 0;
-
-    if (pollSocket.revents & POLLOUT)
-      * condition |= ENET_SOCKET_WAIT_SEND;
-    
-    if (pollSocket.revents & POLLIN)
-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
-    return 0;
-#else
-    fd_set readSet, writeSet;
-    struct timeval timeVal;
-    int selectCount;
-
-    timeVal.tv_sec = timeout / 1000;
-    timeVal.tv_usec = (timeout % 1000) * 1000;
-
-    FD_ZERO (& readSet);
-    FD_ZERO (& writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_SEND)
-      FD_SET (socket, & writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-      FD_SET (socket, & readSet);
-
-    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
-
-    if (selectCount < 0)
-      return -1;
-
-    * condition = ENET_SOCKET_WAIT_NONE;
-
-    if (selectCount == 0)
-      return 0;
-
-    if (FD_ISSET (socket, & writeSet))
-      * condition |= ENET_SOCKET_WAIT_SEND;
-
-    if (FD_ISSET (socket, & readSet))
-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
-    return 0;
-#endif
-}
-
-#endif
-
+/** 
+ @file  unix.c
+ @brief ENet Unix system specific functions
+*/
+#ifndef WIN32
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include "enet.h"
+
+#ifdef HAS_FCNTL
+#include <fcntl.h>
+#endif
+
+#ifdef HAS_POLL
+#include <sys/poll.h>
+#endif
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+    return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+}
+
+enet_uint32
+enet_time_get (void)
+{
+    struct timeval timeVal;
+
+    gettimeofday (& timeVal, NULL);
+
+    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+    struct timeval timeVal;
+
+    gettimeofday (& timeVal, NULL);
+    
+    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
+}
+
+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;
+
+#ifdef linux
+    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+#else
+    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
+#endif
+#else
+    hostEntry = gethostbyname (name);
+#endif
+
+    if (hostEntry == NULL ||
+        hostEntry -> h_addrtype != AF_INET)
+      return -1;
+
+    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+    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;
+
+#ifdef linux
+    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 -1;
+
+    strncpy (name, hostEntry -> h_name, nameLength);
+
+    return 0;
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type, const ENetAddress * address)
+{
+    ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+    int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE;
+#ifndef HAS_FCNTL
+    int nonBlocking = 1;
+#endif
+    struct sockaddr_in sin;
+
+    if (newSocket == ENET_SOCKET_NULL)
+      return ENET_SOCKET_NULL;
+
+    if (type == ENET_SOCKET_TYPE_DATAGRAM)
+    {
+#ifdef HAS_FCNTL
+        fcntl (newSocket, F_SETFL, O_NONBLOCK | fcntl (newSocket, F_GETFL));
+#else
+        ioctl (newSocket, FIONBIO, & nonBlocking);
+#endif
+
+        setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
+    }
+    
+    if (address == NULL)
+      return newSocket;
+
+    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;
+
+    if ((type == ENET_SOCKET_TYPE_STREAM &&
+          listen (newSocket, SOMAXCONN) == -1) ||
+        bind (newSocket, 
+              (struct sockaddr *) & sin,
+              sizeof (struct sockaddr_in)) == -1)
+    {
+       close (newSocket);
+
+       return ENET_SOCKET_NULL;
+    }
+
+    return newSocket;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    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;
+
+    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+    int result;
+    struct sockaddr_in sin;
+    socklen_t sinLength = sizeof (struct sockaddr_in);
+
+    result = accept (socket, 
+                     address != NULL ? (struct sockaddr *) & sin : NULL, 
+                     address != NULL ? & sinLength : 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;
+} 
+    
+void
+enet_socket_destroy (ENetSocket socket)
+{
+    close (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+                  const ENetAddress * address,
+                  const ENetBuffer * buffers,
+                  size_t bufferCount)
+{
+    struct msghdr msgHdr;
+    struct sockaddr_in sin;
+    int sentLength;
+
+    memset (& msgHdr, 0, sizeof (struct msghdr));
+
+    if (address != NULL)
+    {
+        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_iov = (struct iovec *) buffers;
+    msgHdr.msg_iovlen = bufferCount;
+
+    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
+    
+    if (sentLength == -1)
+    {
+       if (errno == EWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+    return sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+                     ENetAddress * address,
+                     ENetBuffer * buffers,
+                     size_t bufferCount)
+{
+    struct msghdr msgHdr;
+    struct sockaddr_in sin;
+    int recvLength;
+
+    memset (& msgHdr, 0, sizeof (struct msghdr));
+
+    if (address != NULL)
+    {
+        msgHdr.msg_name = & sin;
+        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+    }
+
+    msgHdr.msg_iov = (struct iovec *) buffers;
+    msgHdr.msg_iovlen = bufferCount;
+
+    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
+
+    if (recvLength == -1)
+    {
+       if (errno == EWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+#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;
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+#ifdef HAS_POLL
+    struct pollfd pollSocket;
+    int pollCount;
+    
+    pollSocket.fd = socket;
+    pollSocket.events = 0;
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      pollSocket.events |= POLLOUT;
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      pollSocket.events |= POLLIN;
+
+    pollCount = poll (& pollSocket, 1, timeout);
+
+    if (pollCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (pollCount == 0)
+      return 0;
+
+    if (pollSocket.revents & POLLOUT)
+      * condition |= ENET_SOCKET_WAIT_SEND;
+    
+    if (pollSocket.revents & POLLIN)
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+#else
+    fd_set readSet, writeSet;
+    struct timeval timeVal;
+    int selectCount;
+
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+
+    FD_ZERO (& readSet);
+    FD_ZERO (& writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      FD_SET (socket, & writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      FD_SET (socket, & readSet);
+
+    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+    if (selectCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (selectCount == 0)
+      return 0;
+
+    if (FD_ISSET (socket, & writeSet))
+      * condition |= ENET_SOCKET_WAIT_SEND;
+
+    if (FD_ISSET (socket, & readSet))
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+#endif
+}
+
+#endif
+

Index: win32.c
===================================================================
RCS file: /home/enet/cvsroot/enet/win32.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- win32.c	2003/03/08 01:49:13	1.6
+++ win32.c	2003/03/08 23:56:29	1.7
@@ -1,286 +1,290 @@
-#ifdef WIN32
-
-#include <time.h>
-#include "enet.h"
-
-static enet_uint32 timeBase = 0;
-
-int
-enet_initialize (void)
-{
-    WORD versionRequested = MAKEWORD (1, 1);
-    WSADATA wsaData;
-   
-    if (WSAStartup (versionRequested, & wsaData))
-       return -1;
-
-    if (LOBYTE (wsaData.wVersion) != 1||
-        HIBYTE (wsaData.wVersion) != 1)
-    {
-       WSACleanup ();
-       
-       return -1;
-    }
-
-    return 0;
-}
-
-void
-enet_deinitialize (void)
-{
-    WSACleanup ();
-}
-
-enet_uint32
-enet_time_get (void)
-{
-    return (enet_uint32) GetTickCount () - timeBase;
-}
-
-void
-enet_time_set (enet_uint32 newTimeBase)
-{
-    timeBase = (enet_uint32) GetTickCount () - newTimeBase;
-}
-
-int
-enet_address_set_host (ENetAddress * address, const char * name)
-{
-    struct hostent * hostEntry;
-
-    hostEntry = gethostbyname (name);
-    if (hostEntry == NULL ||
-        hostEntry -> h_addrtype != AF_INET)
-      return -1;
-
-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
-
-    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 -1;
-
-    strncpy (name, hostEntry -> h_name, nameLength);
-
-    return 0;
-}
-
-ENetSocket
-enet_socket_create (ENetSocketType type, const ENetAddress * address)
-{
-    ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
-    int nonBlocking = 1,
-        receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE;
-    struct sockaddr_in sin;
-
-    if (newSocket == ENET_SOCKET_NULL)
-      return ENET_SOCKET_NULL;
-
-    if (type == ENET_SOCKET_TYPE_DATAGRAM)
-    {
-        ioctlsocket (newSocket, FIONBIO, & nonBlocking);
-
-        setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
-    }
-
-    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;
-    }
-
-    if ((type == ENET_SOCKET_TYPE_STREAM &&
-          address != NULL &&
-          listen (newSocket, SOMAXCONN) == SOCKET_ERROR) ||
-        bind (newSocket,    
-              (struct sockaddr *) & sin,
-              sizeof (struct sockaddr_in)) == SOCKET_ERROR)
-    {
-       closesocket (newSocket);
-
-       return ENET_SOCKET_NULL;
-    }
-
-    return newSocket;
-}
-
-int
-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    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;
-
-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
-}
-
-ENetSocket
-enet_socket_accept (ENetSocket socket, ENetAddress * address)
-{
-    int 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 == -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;
-}
-
-void
-enet_socket_destroy (ENetSocket socket)
-{
-    closesocket (socket);
-}
-
-int
-enet_socket_send (ENetSocket socket,
-                  const ENetAddress * address,
-                  const ENetBuffer * buffers,
-                  size_t bufferCount)
-{
-    struct sockaddr_in sin;
-    DWORD sentLength;
-
-    if (address != NULL)
-    {
-        sin.sin_family = AF_INET;
-        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-        sin.sin_addr.s_addr = address -> host;
-    }
-
-    if (WSASendTo (socket, 
-                   (LPWSABUF) buffers,
-                   (DWORD) bufferCount,
-                   & sentLength,
-                   0,
-                   address != NULL ? (struct sockaddr *) & sin : 0,
-                   address != NULL ? sizeof (struct sockaddr_in) : 0,
-                   NULL,
-                   NULL) == SOCKET_ERROR)
-    {
-       if (WSAGetLastError () == WSAEWOULDBLOCK)
-         return 0;
-
-       return -1;
-    }
-
-    return (int) sentLength;
-}
-
-int
-enet_socket_receive (ENetSocket socket,
-                     ENetAddress * address,
-                     ENetBuffer * buffers,
-                     size_t bufferCount)
-{
-    DWORD sinLength = sizeof (struct sockaddr_in),
-          flags = 0,
-          recvLength;
-    struct sockaddr_in sin;
-
-    if (WSARecvFrom (socket,
-                     (LPWSABUF) buffers,
-                     (DWORD) bufferCount,
-                     & recvLength,
-                     & flags,
-                     address != NULL ? (struct sockaddr *) & sin : NULL,
-                     address != NULL ? & sinLength : NULL,
-                     NULL,
-                     NULL) == SOCKET_ERROR)
-    {
-       switch (WSAGetLastError ())
-       {
-       case WSAEWOULDBLOCK:
-       case WSAECONNRESET:
-          return 0;
-       }
-
-       return -1;
-    }
-
-    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;
-}
-
-int
-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
-{
-    fd_set readSet, writeSet;
-    struct timeval timeVal;
-    int selectCount;
-    
-    timeVal.tv_sec = timeout / 1000;
-    timeVal.tv_usec = (timeout % 1000) * 1000;
-    
-    FD_ZERO (& readSet);
-    FD_ZERO (& writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_SEND)
-      FD_SET (socket, & writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-      FD_SET (socket, & readSet);
-
-    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
-
-    if (selectCount < 0)
-      return -1;
-
-    * condition = ENET_SOCKET_WAIT_NONE;
-
-    if (selectCount == 0)
-      return 0;
-
-    if (FD_ISSET (socket, & writeSet))
-      * condition |= ENET_SOCKET_WAIT_SEND;
-    
-    if (FD_ISSET (socket, & readSet))
-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
-    return 0;
-} 
-
-#endif
-
+/** 
+ @file  win32.c
+ @brief ENet Win32 system specific functions
+*/
+#ifdef WIN32
+
+#include <time.h>
+#include "enet.h"
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+    WORD versionRequested = MAKEWORD (1, 1);
+    WSADATA wsaData;
+   
+    if (WSAStartup (versionRequested, & wsaData))
+       return -1;
+
+    if (LOBYTE (wsaData.wVersion) != 1||
+        HIBYTE (wsaData.wVersion) != 1)
+    {
+       WSACleanup ();
+       
+       return -1;
+    }
+
+    return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+    WSACleanup ();
+}
+
+enet_uint32
+enet_time_get (void)
+{
+    return (enet_uint32) GetTickCount () - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+    timeBase = (enet_uint32) GetTickCount () - newTimeBase;
+}
+
+int
+enet_address_set_host (ENetAddress * address, const char * name)
+{
+    struct hostent * hostEntry;
+
+    hostEntry = gethostbyname (name);
+    if (hostEntry == NULL ||
+        hostEntry -> h_addrtype != AF_INET)
+      return -1;
+
+    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+    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 -1;
+
+    strncpy (name, hostEntry -> h_name, nameLength);
+
+    return 0;
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type, const ENetAddress * address)
+{
+    ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+    int nonBlocking = 1,
+        receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE;
+    struct sockaddr_in sin;
+
+    if (newSocket == ENET_SOCKET_NULL)
+      return ENET_SOCKET_NULL;
+
+    if (type == ENET_SOCKET_TYPE_DATAGRAM)
+    {
+        ioctlsocket (newSocket, FIONBIO, & nonBlocking);
+
+        setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
+    }
+
+    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;
+    }
+
+    if ((type == ENET_SOCKET_TYPE_STREAM &&
+          address != NULL &&
+          listen (newSocket, SOMAXCONN) == SOCKET_ERROR) ||
+        bind (newSocket,    
+              (struct sockaddr *) & sin,
+              sizeof (struct sockaddr_in)) == SOCKET_ERROR)
+    {
+       closesocket (newSocket);
+
+       return ENET_SOCKET_NULL;
+    }
+
+    return newSocket;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    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;
+
+    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+    int 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 == -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;
+}
+
+void
+enet_socket_destroy (ENetSocket socket)
+{
+    closesocket (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+                  const ENetAddress * address,
+                  const ENetBuffer * buffers,
+                  size_t bufferCount)
+{
+    struct sockaddr_in sin;
+    DWORD sentLength;
+
+    if (address != NULL)
+    {
+        sin.sin_family = AF_INET;
+        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+        sin.sin_addr.s_addr = address -> host;
+    }
+
+    if (WSASendTo (socket, 
+                   (LPWSABUF) buffers,
+                   (DWORD) bufferCount,
+                   & sentLength,
+                   0,
+                   address != NULL ? (struct sockaddr *) & sin : 0,
+                   address != NULL ? sizeof (struct sockaddr_in) : 0,
+                   NULL,
+                   NULL) == SOCKET_ERROR)
+    {
+       if (WSAGetLastError () == WSAEWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+    return (int) sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+                     ENetAddress * address,
+                     ENetBuffer * buffers,
+                     size_t bufferCount)
+{
+    DWORD sinLength = sizeof (struct sockaddr_in),
+          flags = 0,
+          recvLength;
+    struct sockaddr_in sin;
+
+    if (WSARecvFrom (socket,
+                     (LPWSABUF) buffers,
+                     (DWORD) bufferCount,
+                     & recvLength,
+                     & flags,
+                     address != NULL ? (struct sockaddr *) & sin : NULL,
+                     address != NULL ? & sinLength : NULL,
+                     NULL,
+                     NULL) == SOCKET_ERROR)
+    {
+       switch (WSAGetLastError ())
+       {
+       case WSAEWOULDBLOCK:
+       case WSAECONNRESET:
+          return 0;
+       }
+
+       return -1;
+    }
+
+    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;
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+    fd_set readSet, writeSet;
+    struct timeval timeVal;
+    int selectCount;
+    
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+    
+    FD_ZERO (& readSet);
+    FD_ZERO (& writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      FD_SET (socket, & writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      FD_SET (socket, & readSet);
+
+    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+    if (selectCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (selectCount == 0)
+      return 0;
+
+    if (FD_ISSET (socket, & writeSet))
+      * condition |= ENET_SOCKET_WAIT_SEND;
+    
+    if (FD_ISSET (socket, & readSet))
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+} 
+
+#endif
+