diff options
author | Kai Vehmanen <first.surname@nokia.com> | 2007-08-29 13:13:00 +0000 |
---|---|---|
committer | Kai Vehmanen <first.surname@nokia.com> | 2007-08-29 13:13:00 +0000 |
commit | 8f3a86f92e3782e69c6068109e1ada2cb62d8aae (patch) | |
tree | 8ab250f2f9cbfcece56a7bfb456b4ed615722209 /address | |
parent | d88379ee53aaa271d4d3014c0d8dea01bf4d0745 (diff) | |
download | libnice-8f3a86f92e3782e69c6068109e1ada2cb62d8aae.tar.gz |
Modified address module API to use standard berkeley socket API defines and data structs.
darcs-hash:20070829131320-77cd4-03f2b1b4246f8fac33d5f1573ef77cf23a2465d6.gz
Diffstat (limited to 'address')
-rw-r--r-- | address/address.c | 205 | ||||
-rw-r--r-- | address/address.h | 33 | ||||
-rw-r--r-- | address/test.c | 26 |
3 files changed, 160 insertions, 104 deletions
diff --git a/address/address.c b/address/address.c index 19d380a..e691396 100644 --- a/address/address.c +++ b/address/address.c @@ -51,72 +51,118 @@ NICEAPI_EXPORT NiceAddress * nice_address_new (void) { - return g_slice_new0 (NiceAddress); + NiceAddress *addr = g_slice_new0 (NiceAddress); + memset (addr, 0, sizeof (addr)); + addr->s.addr.sa_family = AF_UNSPEC; +#ifdef HAVE_SA_LEN + addr->s.addr.sa_len = sizeof (addr->s.addr); +#endif + return addr; } NICEAPI_EXPORT void nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4) { - addr->type = NICE_ADDRESS_TYPE_IPV4; - addr->addr.addr_ipv4 = addr_ipv4; + addr->s.ip4.sin_family = AF_INET; +#ifdef HAVE_SA_LEN + addr->s.ip4.sin_len = sizeof (addr->sa.ip4); +#endif + addr->s.ip4.sin_addr.s_addr = addr_ipv4 ? htonl (addr_ipv4) : INADDR_ANY; +} + + +NICEAPI_EXPORT void +nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6) +{ + addr->s.ip6.sin6_family = AF_INET6; +#ifdef HAVE_SA_LEN + addr->s.ip6.sin6_len = sizeof (addr->sa.ip6); +#endif + memcpy (addr->s.ip6.sin6_addr.s6_addr, addr_ipv6, 16); } NICEAPI_EXPORT void -nice_address_set_ipv6 (NiceAddress *addr, const gchar *addr_ipv6) +nice_address_set_port (NiceAddress *addr, guint port) +{ + g_assert (addr); + + switch (addr->s.addr.sa_family) + { + case AF_INET: + addr->s.ip4.sin_port = htons (port); + break; + case AF_INET6: + addr->s.ip6.sin6_port = htons (port); + break; + default: + g_assert_not_reached(); + } +} + + +guint +nice_address_get_port (const NiceAddress *addr) { - addr->type = NICE_ADDRESS_TYPE_IPV6; - memcpy (addr->addr.addr_ipv6, addr_ipv6, sizeof (addr->addr.addr_ipv6)); + g_assert (addr); + + switch (addr->s.addr.sa_family) + { + case AF_INET: + return ntohs (addr->s.ip4.sin_port); + case AF_INET6: + return ntohs (addr->s.ip6.sin6_port); + } + + g_assert_not_reached(); } /** - * address_set_ipv4_from_string () + * address_set_from_string () * * Returns FALSE on error. */ NICEAPI_EXPORT gboolean -nice_address_set_ipv4_from_string (NiceAddress *addr, const gchar *str) +nice_address_set_from_string (NiceAddress *addr, const gchar *str) { - struct in_addr iaddr; - - if (inet_aton (str, &iaddr) != 0) - { - nice_address_set_ipv4 (addr, ntohl (iaddr.s_addr)); - return TRUE; - } + union + { + struct in_addr ipv4; + struct in6_addr ipv6; + } a; + + if (inet_pton (AF_INET, str, &a.ipv4) > 0) + nice_address_set_ipv4 (addr, ntohl (a.ipv4.s_addr)); else - { - /* invalid address */ - return FALSE; - } + if (inet_pton (AF_INET6, str, &a.ipv6) > 0) + nice_address_set_ipv6 (addr, a.ipv6.s6_addr); + else + return FALSE; /* Invalid address */ + + return TRUE; } + /** * Sets address to match socket address struct 'sin'. */ NICEAPI_EXPORT void -nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin) +nice_address_set_from_sockaddr (NiceAddress *addr, + const struct sockaddr *sa) { - const struct sockaddr_in *sin4 = (const struct sockaddr_in *)sin; - const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sin; - - g_assert (sin4->sin_family == AF_INET || sin4->sin_family == AF_INET6); - - if (sin4->sin_family == AF_INET) - { - addr->type = NICE_ADDRESS_TYPE_IPV4; - nice_address_set_ipv4 (addr, ntohl (sin4->sin_addr.s_addr)); - } - else /* (sin4->sin_family == AF_INET6) */ + switch (sa->sa_family) { - addr->type = NICE_ADDRESS_TYPE_IPV6; - nice_address_set_ipv6 (addr, - (gchar *) &sin6->sin6_addr); + case AF_INET: + memcpy(&addr->s.ip4, sa, sizeof (addr->s.ip4)); + break; + case AF_INET6: + memcpy(&addr->s.ip6, sa, sizeof (addr->s.ip6)); + break; + default: + g_assert_not_reached(); } - - addr->port = ntohs (sin4->sin_port); } @@ -124,45 +170,43 @@ nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin) * Copies NiceAddress to socket address struct 'sin'. */ NICEAPI_EXPORT void -nice_address_copy_to_sockaddr (const NiceAddress *addr, struct sockaddr *sin) +nice_address_copy_to_sockaddr (const NiceAddress *addr, + struct sockaddr *sa) { - struct sockaddr_in *sin4 = (struct sockaddr_in *)sin; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin; + struct sockaddr_in *sin4 = (struct sockaddr_in *)sa; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - g_assert (sin); - g_assert (addr->type == NICE_ADDRESS_TYPE_IPV4 || addr->type == NICE_ADDRESS_TYPE_IPV6); - - if (addr->type == NICE_ADDRESS_TYPE_IPV4) - { - sin4->sin_family = AF_INET; - sin4->sin_addr.s_addr = htonl (addr->addr.addr_ipv4); - } - else /* (addr->type == NICE_ADDRESS_TYPE_IPV6) */ + g_assert (sa); + + switch (addr->s.addr.sa_family) { - sin4->sin_family = AF_INET6; - memcpy (&sin6->sin6_addr.s6_addr, addr->addr.addr_ipv6, - sizeof (addr->addr.addr_ipv6)); + case AF_INET: + memcpy (sin4, &addr->s.ip4, sizeof (*sin4)); + break; + case AF_INET6: + memcpy (sin6, &addr->s.ip6, sizeof (*sin6)); + break; + default: + g_assert_not_reached (); } - - sin4->sin_port = htons (addr->port); } NICEAPI_EXPORT void -nice_address_to_string (NiceAddress *addr, gchar *dst) +nice_address_to_string (const NiceAddress *addr, gchar *dst) { - struct in_addr iaddr = {0,}; const gchar *ret = NULL; - switch (addr->type) + switch (addr->s.addr.sa_family) { - case NICE_ADDRESS_TYPE_IPV4: - iaddr.s_addr = htonl (addr->addr.addr_ipv4); - ret = inet_ntop (AF_INET, &iaddr, dst, INET_ADDRSTRLEN); + case AF_INET: + ret = inet_ntop (AF_INET, &addr->s.ip4.sin_addr, dst, INET_ADDRSTRLEN); break; - case NICE_ADDRESS_TYPE_IPV6: - ret = inet_ntop (AF_INET6, &addr->addr.addr_ipv6, dst, + case AF_INET6: + ret = inet_ntop (AF_INET6, &addr->s.ip6.sin6_addr, dst, INET6_ADDRSTRLEN); break; + default: + g_assert_not_reached(); } g_assert (ret == dst); @@ -172,21 +216,27 @@ nice_address_to_string (NiceAddress *addr, gchar *dst) NICEAPI_EXPORT gboolean nice_address_equal (const NiceAddress *a, const NiceAddress *b) { - g_assert (a->type == NICE_ADDRESS_TYPE_IPV4 || a->type == NICE_ADDRESS_TYPE_IPV6); - - if (a->type != b->type) + if (a->s.addr.sa_family != b->s.addr.sa_family) return FALSE; - if (a->type == NICE_ADDRESS_TYPE_IPV4) - return (a->addr.addr_ipv4 == b->addr.addr_ipv4) && (a->port == b->port); + switch (a->s.addr.sa_family) + { + case AF_INET: + return (a->s.ip4.sin_addr.s_addr == b->s.ip4.sin_addr.s_addr) + && (a->s.ip4.sin_port == b->s.ip4.sin_port); + + case AF_INET6: + return IN6_ARE_ADDR_EQUAL (&a->s.ip6.sin6_addr, &b->s.ip6.sin6_addr) + && (a->s.ip6.sin6_port == b->s.ip6.sin6_port) + && (a->s.ip6.sin6_scope_id == b->s.ip6.sin6_scope_id); + } - else /* (a->type == NICE_ADDRESS_TYPE_IPV6) */ - return (memcmp (a->addr.addr_ipv6, b->addr.addr_ipv6, sizeof (a->addr.addr_ipv6)) == 0) && (a->port == b->port); + g_assert_not_reached (); } NICEAPI_EXPORT NiceAddress * -nice_address_dup (NiceAddress *a) +nice_address_dup (const NiceAddress *a) { NiceAddress *dup = g_slice_new0 (NiceAddress); @@ -206,6 +256,8 @@ nice_address_free (NiceAddress *addr) static gboolean ipv4_address_is_private (guint32 addr) { + addr = ntohl (addr); + /* http://tools.ietf.org/html/rfc3330 */ return ( /* 10.0.0.0/8 */ @@ -236,13 +288,16 @@ ipv6_address_is_private (const guchar *addr) NICEAPI_EXPORT gboolean -nice_address_is_private (NiceAddress *a) +nice_address_is_private (const NiceAddress *a) { - g_assert (a->type == NICE_ADDRESS_TYPE_IPV4 || a->type == NICE_ADDRESS_TYPE_IPV6); + switch (a->s.addr.sa_family) + { + case AF_INET: + return ipv4_address_is_private (a->s.ip4.sin_addr.s_addr); + case AF_INET6: + return ipv6_address_is_private (a->s.ip6.sin6_addr.s6_addr); + } - if (a->type == NICE_ADDRESS_TYPE_IPV4) - return ipv4_address_is_private (a->addr.addr_ipv4); - else /* (a->type == NICE_ADDRESS_TYPE_IPV6) */ - return ipv6_address_is_private (a->addr.addr_ipv6); + g_assert_not_reached (); } diff --git a/address/address.h b/address/address.h index 79ea1ff..f7444cb 100644 --- a/address/address.h +++ b/address/address.h @@ -38,18 +38,14 @@ #ifndef _ADDRESS_H #define _ADDRESS_H +#include <sys/types.h> +#include <sys/socket.h> #include <netinet/in.h> #include <glib.h> G_BEGIN_DECLS -typedef enum -{ - NICE_ADDRESS_TYPE_IPV4, - NICE_ADDRESS_TYPE_IPV6, -} NiceAddressType; - #define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN typedef struct _NiceAddress NiceAddress; @@ -57,13 +53,12 @@ typedef struct _NiceAddress NiceAddress; /* note: clients need to know the storage size, so needs to be public */ struct _NiceAddress { - NiceAddressType type; union { - guint32 addr_ipv4; - guchar addr_ipv6[INET_ADDRSTRLEN]; - } addr; - guint16 port; + struct sockaddr addr; + struct sockaddr_in ip4; + struct sockaddr_in6 ip6; + } s; }; NiceAddress * @@ -73,17 +68,23 @@ void nice_address_free (NiceAddress *addr); NiceAddress * -nice_address_dup (NiceAddress *a); +nice_address_dup (const NiceAddress *a); void nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4); void -nice_address_set_ipv6 (NiceAddress *addr, const gchar *addr_ipv6); +nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6); + +void +nice_address_set_port (NiceAddress *addr, guint port); + +guint +nice_address_get_port (const NiceAddress *addr); G_GNUC_WARN_UNUSED_RESULT gboolean -nice_address_set_ipv4_from_string (NiceAddress *addr, const gchar *str); +nice_address_set_from_string (NiceAddress *addr, const gchar *str); void nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin); @@ -95,10 +96,10 @@ gboolean nice_address_equal (const NiceAddress *a, const NiceAddress *b); void -nice_address_to_string (NiceAddress *addr, gchar *dst); +nice_address_to_string (const NiceAddress *addr, gchar *dst); gboolean -nice_address_is_private (NiceAddress *a); +nice_address_is_private (const NiceAddress *a); G_END_DECLS diff --git a/address/test.c b/address/test.c index 4e692fd..d770107 100644 --- a/address/test.c +++ b/address/test.c @@ -62,7 +62,7 @@ test_ipv4 (void) memset (&addr, 0, sizeof (addr)); memset (&other, 0, sizeof (other)); nice_address_set_ipv4 (&addr, 0x01020304); - g_assert (addr.type == NICE_ADDRESS_TYPE_IPV4); + g_assert (addr.s.ip4.sin_family == AF_INET); nice_address_to_string (&addr, str); g_assert (0 == strcmp (str, "1.2.3.4")); @@ -74,8 +74,8 @@ test_ipv4 (void) g_assert (TRUE == nice_address_equal (&addr, &other)); /* from sockaddr_in */ - other.port = 9876; /* in native byte order */ - other.type = NICE_ADDRESS_TYPE_IPV4; + nice_address_set_port (&other, 9876); /* in native byte order */ + other.s.ip4.sin_family = AF_INET; nice_address_set_from_sockaddr (&addr, (struct sockaddr*)&sin); nice_address_to_string (&addr, str); nice_address_to_string (&other, str); @@ -87,15 +87,15 @@ test_ipv4 (void) /* different port */ nice_address_set_ipv4 (&other, 0x01020304); - addr.port = 1; + nice_address_set_port (&addr, 1); g_assert (FALSE == nice_address_equal (&addr, &other)); /* test private address check */ { NiceAddress *heap_addr = nice_address_new (); - g_assert (nice_address_set_ipv4_from_string (heap_addr, "127.0.0.1") == TRUE); + g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1") == TRUE); g_assert (nice_address_is_private (heap_addr) == TRUE); - g_assert (nice_address_set_ipv4_from_string (heap_addr, "127.0.0.1.1") != TRUE); + g_assert (nice_address_set_from_string (heap_addr, "127.0.0.1.1") != TRUE); nice_address_free (heap_addr); } } @@ -107,7 +107,7 @@ test_ipv6 (void) gchar str[NICE_ADDRESS_STRING_LEN]; struct sockaddr_in6 sin, sin2; - g_assert (nice_address_set_ipv4_from_string (&v4addr, "172.1.0.1") == TRUE); + g_assert (nice_address_set_from_string (&v4addr, "172.1.0.1") == TRUE); memset (&sin, 0, sizeof (sin)); memset (&sin2, 0, sizeof (sin2)); @@ -117,17 +117,17 @@ test_ipv6 (void) g_assert (inet_pton (AF_INET6, "11:2233:4455:6677:8899:aabb:ccdd:eeff", &sin.sin6_addr) > 0); memset (&addr, 0, sizeof (addr)); - nice_address_set_ipv6 (&addr, + nice_address_set_ipv6 (&addr, (guchar *) "\x00\x11\x22\x33" "\x44\x55\x66\x77" "\x88\x99\xaa\xbb" "\xcc\xdd\xee\xff"); - g_assert (addr.type == NICE_ADDRESS_TYPE_IPV6); + g_assert (addr.s.ip6.sin6_family == AF_INET6); nice_address_to_string (&addr, str); g_assert (0 == strcmp (str, "11:2233:4455:6677:8899:aabb:ccdd:eeff")); - addr.port = 9876; /* in native byte order */ + nice_address_set_port (&addr, 9876); /* in native byte order */ nice_address_set_from_sockaddr (&other, (struct sockaddr*)&sin); nice_address_copy_to_sockaddr (&other, (struct sockaddr*)&sin2); g_assert (memcmp (&sin, &sin2, sizeof(sin)) == 0); @@ -136,13 +136,13 @@ test_ipv6 (void) g_assert (nice_address_equal (&addr, &other) == TRUE); /* private IPv6 address */ - nice_address_set_ipv6 (&addr, + nice_address_set_ipv6 (&addr, (guchar *) "\xfc\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x01"); g_assert (nice_address_is_private (&addr) == TRUE); - nice_address_set_ipv6 (&addr, + nice_address_set_ipv6 (&addr, (guchar *) "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" @@ -153,7 +153,7 @@ test_ipv6 (void) g_assert (nice_address_equal (&addr, &v4addr) != TRUE); /* mismatched type */ - addr.type = -1; + addr.s.addr.sa_family = AF_UNSPEC; /*g_assert (nice_address_equal (&addr, &v4addr) != TRUE);*/ } |