Commit 8f3a86f9 authored by Kai Vehmanen's avatar Kai Vehmanen

Modified address module API to use standard berkeley socket API defines and data structs.

darcs-hash:20070829131320-77cd4-03f2b1b4246f8fac33d5f1573ef77cf23a2465d6.gz
parent d88379ee
...@@ -51,72 +51,118 @@ ...@@ -51,72 +51,118 @@
NICEAPI_EXPORT NiceAddress * NICEAPI_EXPORT NiceAddress *
nice_address_new (void) 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 NICEAPI_EXPORT void
nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4) nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4)
{ {
addr->type = NICE_ADDRESS_TYPE_IPV4; addr->s.ip4.sin_family = AF_INET;
addr->addr.addr_ipv4 = addr_ipv4; #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 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; g_assert (addr);
memcpy (addr->addr.addr_ipv6, addr_ipv6, sizeof (addr->addr.addr_ipv6));
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. * Returns FALSE on error.
*/ */
NICEAPI_EXPORT gboolean 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; union
{
if (inet_aton (str, &iaddr) != 0) struct in_addr ipv4;
{ struct in6_addr ipv6;
nice_address_set_ipv4 (addr, ntohl (iaddr.s_addr)); } a;
return TRUE;
} if (inet_pton (AF_INET, str, &a.ipv4) > 0)
nice_address_set_ipv4 (addr, ntohl (a.ipv4.s_addr));
else else
{ if (inet_pton (AF_INET6, str, &a.ipv6) > 0)
/* invalid address */ nice_address_set_ipv6 (addr, a.ipv6.s6_addr);
return FALSE; else
} return FALSE; /* Invalid address */
return TRUE;
} }
/** /**
* Sets address to match socket address struct 'sin'. * Sets address to match socket address struct 'sin'.
*/ */
NICEAPI_EXPORT void 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; switch (sa->sa_family)
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) */
{ {
addr->type = NICE_ADDRESS_TYPE_IPV6; case AF_INET:
nice_address_set_ipv6 (addr, memcpy(&addr->s.ip4, sa, sizeof (addr->s.ip4));
(gchar *) &sin6->sin6_addr); 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) ...@@ -124,45 +170,43 @@ nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin)
* Copies NiceAddress to socket address struct 'sin'. * Copies NiceAddress to socket address struct 'sin'.
*/ */
NICEAPI_EXPORT void 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_in *sin4 = (struct sockaddr_in *)sa;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sin; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
g_assert (sin); g_assert (sa);
g_assert (addr->type == NICE_ADDRESS_TYPE_IPV4 || addr->type == NICE_ADDRESS_TYPE_IPV6);
switch (addr->s.addr.sa_family)
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) */
{ {
sin4->sin_family = AF_INET6; case AF_INET:
memcpy (&sin6->sin6_addr.s6_addr, addr->addr.addr_ipv6, memcpy (sin4, &addr->s.ip4, sizeof (*sin4));
sizeof (addr->addr.addr_ipv6)); 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 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; const gchar *ret = NULL;
switch (addr->type) switch (addr->s.addr.sa_family)
{ {
case NICE_ADDRESS_TYPE_IPV4: case AF_INET:
iaddr.s_addr = htonl (addr->addr.addr_ipv4); ret = inet_ntop (AF_INET, &addr->s.ip4.sin_addr, dst, INET_ADDRSTRLEN);
ret = inet_ntop (AF_INET, &iaddr, dst, INET_ADDRSTRLEN);
break; break;
case NICE_ADDRESS_TYPE_IPV6: case AF_INET6:
ret = inet_ntop (AF_INET6, &addr->addr.addr_ipv6, dst, ret = inet_ntop (AF_INET6, &addr->s.ip6.sin6_addr, dst,
INET6_ADDRSTRLEN); INET6_ADDRSTRLEN);
break; break;
default:
g_assert_not_reached();
} }
g_assert (ret == dst); g_assert (ret == dst);
...@@ -172,21 +216,27 @@ nice_address_to_string (NiceAddress *addr, gchar *dst) ...@@ -172,21 +216,27 @@ nice_address_to_string (NiceAddress *addr, gchar *dst)
NICEAPI_EXPORT gboolean NICEAPI_EXPORT gboolean
nice_address_equal (const NiceAddress *a, const NiceAddress *b) 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->s.addr.sa_family != b->s.addr.sa_family)
if (a->type != b->type)
return FALSE; return FALSE;
if (a->type == NICE_ADDRESS_TYPE_IPV4) switch (a->s.addr.sa_family)
return (a->addr.addr_ipv4 == b->addr.addr_ipv4) && (a->port == b->port); {
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) */ g_assert_not_reached ();
return (memcmp (a->addr.addr_ipv6, b->addr.addr_ipv6, sizeof (a->addr.addr_ipv6)) == 0) && (a->port == b->port);
} }
NICEAPI_EXPORT NiceAddress * NICEAPI_EXPORT NiceAddress *
nice_address_dup (NiceAddress *a) nice_address_dup (const NiceAddress *a)
{ {
NiceAddress *dup = g_slice_new0 (NiceAddress); NiceAddress *dup = g_slice_new0 (NiceAddress);
...@@ -206,6 +256,8 @@ nice_address_free (NiceAddress *addr) ...@@ -206,6 +256,8 @@ nice_address_free (NiceAddress *addr)
static gboolean static gboolean
ipv4_address_is_private (guint32 addr) ipv4_address_is_private (guint32 addr)
{ {
addr = ntohl (addr);
/* http://tools.ietf.org/html/rfc3330 */ /* http://tools.ietf.org/html/rfc3330 */
return ( return (
/* 10.0.0.0/8 */ /* 10.0.0.0/8 */
...@@ -236,13 +288,16 @@ ipv6_address_is_private (const guchar *addr) ...@@ -236,13 +288,16 @@ ipv6_address_is_private (const guchar *addr)
NICEAPI_EXPORT gboolean 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) g_assert_not_reached ();
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);
} }
...@@ -38,18 +38,14 @@ ...@@ -38,18 +38,14 @@
#ifndef _ADDRESS_H #ifndef _ADDRESS_H
#define _ADDRESS_H #define _ADDRESS_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <glib.h> #include <glib.h>
G_BEGIN_DECLS G_BEGIN_DECLS
typedef enum
{
NICE_ADDRESS_TYPE_IPV4,
NICE_ADDRESS_TYPE_IPV6,
} NiceAddressType;
#define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN #define NICE_ADDRESS_STRING_LEN INET6_ADDRSTRLEN
typedef struct _NiceAddress NiceAddress; typedef struct _NiceAddress NiceAddress;
...@@ -57,13 +53,12 @@ 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 */ /* note: clients need to know the storage size, so needs to be public */
struct _NiceAddress struct _NiceAddress
{ {
NiceAddressType type;
union union
{ {
guint32 addr_ipv4; struct sockaddr addr;
guchar addr_ipv6[INET_ADDRSTRLEN]; struct sockaddr_in ip4;
} addr; struct sockaddr_in6 ip6;
guint16 port; } s;
}; };
NiceAddress * NiceAddress *
...@@ -73,17 +68,23 @@ void ...@@ -73,17 +68,23 @@ void
nice_address_free (NiceAddress *addr); nice_address_free (NiceAddress *addr);
NiceAddress * NiceAddress *
nice_address_dup (NiceAddress *a); nice_address_dup (const NiceAddress *a);
void void
nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4); nice_address_set_ipv4 (NiceAddress *addr, guint32 addr_ipv4);
void 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 G_GNUC_WARN_UNUSED_RESULT
gboolean gboolean
nice_address_set_ipv4_from_string (NiceAddress *addr, const gchar *str); nice_address_set_from_string (NiceAddress *addr, const gchar *str);
void void
nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin); nice_address_set_from_sockaddr (NiceAddress *addr, const struct sockaddr *sin);
...@@ -95,10 +96,10 @@ gboolean ...@@ -95,10 +96,10 @@ gboolean
nice_address_equal (const NiceAddress *a, const NiceAddress *b); nice_address_equal (const NiceAddress *a, const NiceAddress *b);
void void
nice_address_to_string (NiceAddress *addr, gchar *dst); nice_address_to_string (const NiceAddress *addr, gchar *dst);
gboolean gboolean
nice_address_is_private (NiceAddress *a); nice_address_is_private (const NiceAddress *a);
G_END_DECLS G_END_DECLS
......
...@@ -62,7 +62,7 @@ test_ipv4 (void) ...@@ -62,7 +62,7 @@ test_ipv4 (void)
memset (&addr, 0, sizeof (addr)); memset (&addr, 0, sizeof (addr));
memset (&other, 0, sizeof (other)); memset (&other, 0, sizeof (other));
nice_address_set_ipv4 (&addr, 0x01020304); 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); nice_address_to_string (&addr, str);
g_assert (0 == strcmp (str, "1.2.3.4")); g_assert (0 == strcmp (str, "1.2.3.4"));
...@@ -74,8 +74,8 @@ test_ipv4 (void) ...@@ -74,8 +74,8 @@ test_ipv4 (void)
g_assert (TRUE == nice_address_equal (&addr, &other)); g_assert (TRUE == nice_address_equal (&addr, &other));
/* from sockaddr_in */ /* from sockaddr_in */
other.port = 9876; /* in native byte order */ nice_address_set_port (&other, 9876); /* in native byte order */
other.type = NICE_ADDRESS_TYPE_IPV4; other.s.ip4.sin_family = AF_INET;
nice_address_set_from_sockaddr (&addr, (struct sockaddr*)&sin); nice_address_set_from_sockaddr (&addr, (struct sockaddr*)&sin);
nice_address_to_string (&addr, str); nice_address_to_string (&addr, str);
nice_address_to_string (&other, str); nice_address_to_string (&other, str);
...@@ -87,15 +87,15 @@ test_ipv4 (void) ...@@ -87,15 +87,15 @@ test_ipv4 (void)
/* different port */ /* different port */
nice_address_set_ipv4 (&other, 0x01020304); nice_address_set_ipv4 (&other, 0x01020304);
addr.port = 1; nice_address_set_port (&addr, 1);
g_assert (FALSE == nice_address_equal (&addr, &other)); g_assert (FALSE == nice_address_equal (&addr, &other));
/* test private address check */ /* test private address check */
{ {
NiceAddress *heap_addr = nice_address_new (); 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_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); nice_address_free (heap_addr);
} }
} }
...@@ -107,7 +107,7 @@ test_ipv6 (void) ...@@ -107,7 +107,7 @@ test_ipv6 (void)
gchar str[NICE_ADDRESS_STRING_LEN]; gchar str[NICE_ADDRESS_STRING_LEN];
struct sockaddr_in6 sin, sin2; 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 (&sin, 0, sizeof (sin));
memset (&sin2, 0, sizeof (sin2)); memset (&sin2, 0, sizeof (sin2));
...@@ -117,17 +117,17 @@ test_ipv6 (void) ...@@ -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); g_assert (inet_pton (AF_INET6, "11:2233:4455:6677:8899:aabb:ccdd:eeff", &sin.sin6_addr) > 0);
memset (&addr, 0, sizeof (addr)); memset (&addr, 0, sizeof (addr));
nice_address_set_ipv6 (&addr, nice_address_set_ipv6 (&addr, (guchar *)
"\x00\x11\x22\x33" "\x00\x11\x22\x33"
"\x44\x55\x66\x77" "\x44\x55\x66\x77"
"\x88\x99\xaa\xbb" "\x88\x99\xaa\xbb"
"\xcc\xdd\xee\xff"); "\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); nice_address_to_string (&addr, str);
g_assert (0 == strcmp (str, "11:2233:4455:6677:8899:aabb:ccdd:eeff")); 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_set_from_sockaddr (&other, (struct sockaddr*)&sin);
nice_address_copy_to_sockaddr (&other, (struct sockaddr*)&sin2); nice_address_copy_to_sockaddr (&other, (struct sockaddr*)&sin2);
g_assert (memcmp (&sin, &sin2, sizeof(sin)) == 0); g_assert (memcmp (&sin, &sin2, sizeof(sin)) == 0);
...@@ -136,13 +136,13 @@ test_ipv6 (void) ...@@ -136,13 +136,13 @@ test_ipv6 (void)
g_assert (nice_address_equal (&addr, &other) == TRUE); g_assert (nice_address_equal (&addr, &other) == TRUE);
/* private IPv6 address */ /* private IPv6 address */
nice_address_set_ipv6 (&addr, nice_address_set_ipv6 (&addr, (guchar *)
"\xfc\x00\x00\x00" "\xfc\x00\x00\x00"
"\x00\x00\x00\x00" "\x00\x00\x00\x00"
"\x00\x00\x00\x00" "\x00\x00\x00\x00"
"\x00\x00\x00\x01"); "\x00\x00\x00\x01");
g_assert (nice_address_is_private (&addr) == TRUE); 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" "\x00\x00\x00\x00"
"\x00\x00\x00\x00" "\x00\x00\x00\x00"
...@@ -153,7 +153,7 @@ test_ipv6 (void) ...@@ -153,7 +153,7 @@ test_ipv6 (void)
g_assert (nice_address_equal (&addr, &v4addr) != TRUE); g_assert (nice_address_equal (&addr, &v4addr) != TRUE);
/* mismatched type */ /* mismatched type */
addr.type = -1; addr.s.addr.sa_family = AF_UNSPEC;
/*g_assert (nice_address_equal (&addr, &v4addr) != TRUE);*/ /*g_assert (nice_address_equal (&addr, &v4addr) != TRUE);*/
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment