[PATCH] bonjour ipv6 interface fix

Linus Lüssing linus.luessing at web.de
Sat Nov 19 06:35:27 EST 2011


With pidgin I was having the issue of one pidgin 2.10.0 instance on a
Debian testing VM not being able to connect to another Debian testing
VM, although they seemed to see each other as they were showing up on
each others contact lists. Instead I was getting the "bonjour: We don't
like invisible buddies, this is not a superheroes comic" line when I
tried to actually send a message.

Adding a printf in jabber.c's
_match_buddies_by_address(gpointer value, gpointer data) showed that
strings compared via the g_ascii_strcasecmp() call in this function was
a little bogus:

~~~~
(05:42:21) bonjour: Received incoming connection from 2001:6f8:587:0:4:64ff:fea4:29b2.
Comparing: 2001:6f8:587:0:4:64ff:fea4:29b2%2 with: 2001:6f8:587:0:4:64ff:fea4:29b2
Comparing: 192.168.0.91 with: 2001:6f8:587:0:4:64ff:fea4:29b2
(05:42:21) bonjour: We don't like invisible buddies, this is not a superheroes comic
~~~~

Similarly, the addition of the interface id in mdns_avahi.c was not quite
consistent.

With this commit the interface id will only be appended to and checked for
IPv6 link local addresses. This should fix unsuccessful connection
attempts both for two IPv6 hosts with a non-link-local address
next to the link-local one or without.

Signed-off-by: Linus Lüssing <linus.luessing at web.de>
---
 libpurple/protocols/bonjour/jabber.c     |   22 +++++++++++++++++++++-
 libpurple/protocols/bonjour/jabber.h     |    2 ++
 libpurple/protocols/bonjour/mdns_avahi.c |    5 ++++-
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/libpurple/protocols/bonjour/jabber.c b/libpurple/protocols/bonjour/jabber.c
index 455d1f2..3e40165 100644
--- a/libpurple/protocols/bonjour/jabber.c
+++ b/libpurple/protocols/bonjour/jabber.c
@@ -665,9 +665,13 @@ _server_socket_handler(gpointer data, int server_socket, PurpleInputCondition co
 
 	/* Look for the buddy that has opened the conversation and fill information */
 #ifdef HAVE_INET_NTOP
-	if (their_addr.ss_family == AF_INET6)
+	if (their_addr.ss_family == AF_INET6) {
 		address_text = inet_ntop(their_addr.ss_family, &((struct sockaddr_in6 *)&their_addr)->sin6_addr,
 			addrstr, sizeof(addrstr));
+
+		append_iface_if_linklocal(addrstr,
+			((struct sockaddr_in6 *)&their_addr)->sin6_scope_id);
+	}
 	else
 		address_text = inet_ntop(their_addr.ss_family, &((struct sockaddr_in *)&their_addr)->sin_addr,
 			addrstr, sizeof(addrstr));
@@ -1442,3 +1446,19 @@ bonjour_jabber_get_local_ips(int fd)
 
 	return ips;
 }
+
+void
+append_iface_if_linklocal(char *ip, uint32_t interface) {
+	struct in6_addr in6_addr;
+	int len_remain = INET6_ADDRSTRLEN - strlen(ip);
+
+	if (len_remain <= 1)
+		return;
+
+	if (inet_pton(AF_INET6, ip, &in6_addr) != 1 ||
+	    !IN6_IS_ADDR_LINKLOCAL(&in6_addr))
+		return;
+
+	snprintf(ip + strlen(ip), len_remain, "%%%d",
+		 interface);
+}
diff --git a/libpurple/protocols/bonjour/jabber.h b/libpurple/protocols/bonjour/jabber.h
index 4b40600..81e1f7c 100644
--- a/libpurple/protocols/bonjour/jabber.h
+++ b/libpurple/protocols/bonjour/jabber.h
@@ -111,4 +111,6 @@ XepIq *xep_iq_new(void *data, XepIqType type, const char *to, const char *from,
 int xep_iq_send_and_free(XepIq *iq);
 GSList * bonjour_jabber_get_local_ips(int fd);
 
+void append_iface_if_linklocal(char *ip, uint32_t interface);
+
 #endif /* _BONJOUR_JABBER_H_ */
diff --git a/libpurple/protocols/bonjour/mdns_avahi.c b/libpurple/protocols/bonjour/mdns_avahi.c
index c402e05..5f28a70 100644
--- a/libpurple/protocols/bonjour/mdns_avahi.c
+++ b/libpurple/protocols/bonjour/mdns_avahi.c
@@ -179,6 +179,9 @@ _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtoco
 			ip[0] = '\0';
 			avahi_address_snprint(ip, AVAHI_ADDRESS_STR_MAX, a);
 
+			if (protocol == AVAHI_PROTO_INET6)
+				append_iface_if_linklocal(ip, interface);
+
 			purple_debug_info("bonjour", "_resolve_callback - name:%s ip:%s prev_ip:%s\n",
 				name, ip, rd->ip);
 
@@ -190,7 +193,7 @@ _resolver_callback(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtoco
 				}
 				/* IPv6 goes at the front of the list and IPv4 at the end so that we "prefer" IPv6, if present */
 				if (protocol == AVAHI_PROTO_INET6) {
-					rd->ip = g_strdup_printf("%s%%%d", ip, interface);
+					rd->ip = g_strdup_printf("%s", ip);
 					bb->ips = g_slist_prepend(bb->ips, (gchar *) rd->ip);
 				} else {
 					rd->ip = g_strdup(ip);
-- 
1.7.7.1




More information about the Devel mailing list