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 @@
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 gchar *addr_ipv6)
nice_address_set_ipv6 (NiceAddress *addr, const guchar *addr_ipv6)
{
addr->type = NICE_ADDRESS_TYPE_IPV6;
memcpy (addr->addr.addr_ipv6, addr_ipv6, sizeof (addr->addr.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_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)
{
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)
union
{
nice_address_set_ipv4 (addr, ntohl (iaddr.s_addr));
return TRUE;
}
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);
g_assert (sa);
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) */
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 ();
}
......@@ -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
......
......@@ -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);*/
}
......
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