diff libpurple/util.c @ 29741:35a1cf247168

Add network listen functions that accept a family argument (AF_INET(6?)). These allow code to portably support IPv6 for listeners (mostly file transfers and Bonjour). Callers should use the purple_socket_speaks_ipv4 to determine whether they need two sockets or just an IPv6 one. I used GIO's g_socket_speaks_ipv4 as the inspiration for that.
author Paul Aurich <paul@darkrain42.org>
date Sat, 17 Apr 2010 01:27:04 +0000
parents 5be4137c4a68
children 933c8251e036
line wrap: on
line diff
--- a/libpurple/util.c	Fri Apr 16 03:44:18 2010 +0000
+++ b/libpurple/util.c	Sat Apr 17 01:27:04 2010 +0000
@@ -3002,6 +3002,47 @@
 	return NULL;
 }
 
+int
+purple_socket_get_family(int fd)
+{
+	struct sockaddr_storage addr;
+	socklen_t len = sizeof(addr);
+
+	g_return_val_if_fail(fd >= 0, -1);
+
+	if (getsockname(fd, (struct sockaddr *)&addr, &len))
+		return -1;
+
+	return ((struct sockaddr *)&addr)->sa_family;
+}
+
+gboolean
+purple_socket_speaks_ipv4(int fd)
+{
+	int family;
+	
+	g_return_val_if_fail(fd >= 0, FALSE);
+
+	family = purple_socket_get_family(fd);
+
+	switch (family) {
+	case AF_INET:
+		return TRUE;
+#if defined(IPV6_V6ONLY)
+	case AF_INET6:
+	{
+		int val = 0;
+		guint len = sizeof(val);
+
+		if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, &len) != 0)
+			return FALSE;
+		return !val;
+	}
+#endif
+	default:
+		return FALSE;
+	}
+}
 
 /**************************************************************************
  * String Functions