From af3c0910bd25d73b1a3c06bbfa4e0a3c6b96ddc5 Mon Sep 17 00:00:00 2001
From: Adrian Friedli <adi@koalatux.ch>
Date: Mon, 6 Sep 2010 14:58:50 +0200
Subject: [PATCH 3/4] using address family in functions

---
 host.c              |    4 +-
 include/enet/enet.h |   22 +++++++++---
 protocol.c          |    5 ++-
 unix.c              |   87 ++++++++++++++++++++++++++++++++------------------
 4 files changed, 77 insertions(+), 41 deletions(-)

diff --git a/host.c b/host.c
index 8bb2433..9ccf894 100644
--- a/host.c
+++ b/host.c
@@ -48,8 +48,8 @@ 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);
-    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
+    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, ENET_IPV6);
+    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address, ENET_IPV6) < 0))
     {
        if (host -> socket != ENET_SOCKET_NULL)
          enet_socket_destroy (host -> socket);
diff --git a/include/enet/enet.h b/include/enet/enet.h
index d3ca971..7f5876f 100644
--- a/include/enet/enet.h
+++ b/include/enet/enet.h
@@ -82,6 +82,16 @@ typedef struct _ENetAddress
 } ENetAddress;
 
 /**
+ * The address family type.
+ */
+typedef enum _ENetAddressFamily
+{
+    ENET_NO_ADDRESS_FAMILY = 0,
+    ENET_IPV4 = (1 << 0),
+    ENET_IPV6 = (1 << 1)
+} ENetAddressFamily;
+
+/**
  * Packet flag bit constants.
  *
  * The host must be specified in network byte-order, and the port must be in
@@ -445,13 +455,13 @@ ENET_API void enet_time_set (enet_uint32);
 /** @defgroup socket ENet socket functions
     @{
 */
-ENET_API ENetSocket enet_socket_create (ENetSocketType);
-ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *);
+ENET_API ENetSocket enet_socket_create (ENetSocketType, ENetAddressFamily);
+ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *, ENetAddressFamily);
 ENET_API int        enet_socket_listen (ENetSocket, int);
-ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
-ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *);
-ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
-ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
+ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *, ENetAddressFamily);
+ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *, ENetAddressFamily);
+ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t, ENetAddressFamily);
+ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t, ENetAddressFamily);
 ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
 ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
 ENET_API void       enet_socket_destroy (ENetSocket);
diff --git a/protocol.c b/protocol.c
index 930835e..4c4850a 100644
--- a/protocol.c
+++ b/protocol.c
@@ -1046,7 +1046,8 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
        receivedLength = enet_socket_receive (host -> socket,
                                              & host -> receivedAddress,
                                              & buffer,
-                                             1);
+                                             1,
+                                             ENET_IPV6);
 
        if (receivedLength < 0)
          return -1;
@@ -1509,7 +1510,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
 
         currentPeer -> lastSendTime = host -> serviceTime;
 
-        sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
+        sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount, ENET_IPV6);
 
         enet_protocol_remove_sent_unreliable_commands (currentPeer);
 
diff --git a/unix.c b/unix.c
index de032bb..13a24d8 100644
--- a/unix.c
+++ b/unix.c
@@ -71,7 +71,28 @@ enet_time_set (enet_uint32 newTimeBase)
     timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
 }
 
-static int
+static enet_uint16
+enet_af (ENetAddressFamily family)
+{
+    if (family == ENET_IPV4)
+        return AF_INET;
+    if (family == ENET_IPV6)
+        return AF_INET6;
+    return 0;
+}
+
+static socklen_t
+enet_sa_size (ENetAddressFamily family)
+{
+    if (family == ENET_IPV4)
+        return sizeof (struct sockaddr_in);
+    if (family == ENET_IPV6)
+        return sizeof (struct sockaddr_in6);
+    return 0;
+}
+
+
+static ENetAddressFamily
 enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
 {
     memset (address, 0, sizeof (ENetAddress));
@@ -80,32 +101,31 @@ enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
         address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
         //address -> scopeID = 0;
         address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
-        return 0;
+        return ENET_IPV4;
     }
     if (sin -> sa_family == AF_INET6)
     {
         address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
         address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
         address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
-        return 0;
+        return ENET_IPV6;
     }
-    return -1;
+    return ENET_NO_ADDRESS_FAMILY;
 }
 
 static int
-enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, sa_family_t family)
+enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
 {
-    if (family == AF_INET)
+    memset (sin, 0, enet_sa_size(family));
+    if (family == ENET_IPV4)
     {
-        memset (sin, 0, sizeof (struct sockaddr_in));
         ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
         ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
         ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
         return 0;
     }
-    else if (family == AF_INET6)
+    else if (family == ENET_IPV6)
     {
-        memset (sin, 0, sizeof (struct sockaddr_in6));
         ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
         ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
         ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
@@ -132,7 +152,7 @@ enet_address_set_host (ENetAddress * address, const char * name)
 
     for (res = result; res != NULL; res = res -> ai_next)
     {
-        if ( !enet_address_set_address(address, res -> ai_addr) )
+        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
             break;
     }
 
@@ -147,9 +167,9 @@ static int
 enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
 {
     struct sockaddr_storage sin;
-    enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6);
+    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
 
-    if ( getnameinfo((struct sockaddr *) & sin, sizeof(struct sockaddr_in6), name, nameLength, NULL, 0, flags))
+    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
         return -1;
 
     return 0;
@@ -168,21 +188,21 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng
 }
 
 int
-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
+enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
 {
     struct sockaddr_storage sin;
 
     if (address != NULL)
     {
-        enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6);
+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
     }
     else
     {
         ENetAddress address_ = { ENET_HOST_ANY, 0, 0 };
-        enet_address_set_sin((struct sockaddr *) & sin, & address_, AF_INET6);
+        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
     }
 
-    return bind (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in6));
+    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family));
 }
 
 int
@@ -192,13 +212,16 @@ enet_socket_listen (ENetSocket socket, int backlog)
 }
 
 ENetSocket
-enet_socket_create (ENetSocketType type)
+enet_socket_create (ENetSocketType type, ENetAddressFamily family)
 {
-    ENetSocket sock = socket (AF_INET6, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
 
 #ifdef IPV6_V6ONLY
-    int value = 0;
-    setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
+    if (family == ENET_IPV6)
+    {
+        int value = 0;
+        setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
+    }
 #endif // IPV6_V6ONLY
 
     return sock;
@@ -241,25 +264,25 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
 }
 
 int
-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
 {
     struct sockaddr_storage sin;
-    enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6);
+    enet_address_set_sin((struct sockaddr *) & sin, address, family);
 
-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in6));
+    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family));
 }
 
 ENetSocket
-enet_socket_accept (ENetSocket socket, ENetAddress * address)
+enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
 {
     int result;
     struct sockaddr_storage sin;
-    socklen_t sinLength = sizeof (struct sockaddr_in6);
+    socklen_t sinLength = enet_sa_size (family);
 
     result = accept (socket, 
                      address != NULL ? (struct sockaddr *) & sin : NULL, 
                      address != NULL ? & sinLength : NULL);
-    
+
     if (result == -1)
       return ENET_SOCKET_NULL;
 
@@ -281,7 +304,8 @@ int
 enet_socket_send (ENetSocket socket,
                   const ENetAddress * address,
                   const ENetBuffer * buffers,
-                  size_t bufferCount)
+                  size_t bufferCount,
+                  ENetAddressFamily family)
 {
     struct msghdr msgHdr;
     struct sockaddr_storage sin;
@@ -291,9 +315,9 @@ enet_socket_send (ENetSocket socket,
 
     if (address != NULL)
     {
-        enet_address_set_sin((struct sockaddr *) & sin, address, AF_INET6);
+        enet_address_set_sin((struct sockaddr *) & sin, address, family);
         msgHdr.msg_name = & sin;
-        msgHdr.msg_namelen = sizeof (struct sockaddr_in6);
+        msgHdr.msg_namelen = enet_sa_size (family);
     }
 
     msgHdr.msg_iov = (struct iovec *) buffers;
@@ -316,7 +340,8 @@ int
 enet_socket_receive (ENetSocket socket,
                      ENetAddress * address,
                      ENetBuffer * buffers,
-                     size_t bufferCount)
+                     size_t bufferCount,
+                     ENetAddressFamily family)
 {
     struct msghdr msgHdr;
     struct sockaddr_storage sin;
@@ -327,7 +352,7 @@ enet_socket_receive (ENetSocket socket,
     if (address != NULL)
     {
         msgHdr.msg_name = & sin;
-        msgHdr.msg_namelen = sizeof (struct sockaddr_in6);
+        msgHdr.msg_namelen = enet_sa_size (family);
     }
 
     msgHdr.msg_iov = (struct iovec *) buffers;
-- 
1.7.1

