Mercurial > pidgin
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
