[PATCH 4/4] bonjour: Fix IPv6 link local file transfer

Linus Lüssing linus.luessing at web.de
Fri Nov 25 06:20:10 EST 2011


Before bonjour did not accept a file transfer from IPv6 link local
addresses due to the address in the xep bytestream message not
containing an interface identifier and therefore not matching the
saved bonjour buddy's IPv6 link local address which does contain an
interface identifier.

With this patch we will only check the address and skip the buddy's
interface identifier in the case of an IPv6 link local address.

Note: This may theoretically result in the attempt to connect to the wrong
host, because we do not know for sure which interface the according link
local IPv6 address might relate to and RFC4862 for instance only ensures the
uniqueness of this address on a given link. So we could possibly have two
distinct buddies with the same ipv6 link local address on two distinct
interfaces. Unfortunately XEP-0065 does not seem to specify how to deal with
link local ip addresses properly...
However, in practice the possiblity for such a conflict is relatively low
(2011 - might be different in the future though?).

Signed-off-by: Linus Lüssing <linus.luessing at web.de>
---
 libpurple/protocols/bonjour/bonjour_ft.c |   58 ++++++++++++++++++++++++++++-
 1 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/libpurple/protocols/bonjour/bonjour_ft.c b/libpurple/protocols/bonjour/bonjour_ft.c
index b997d09..c551e53 100644
--- a/libpurple/protocols/bonjour/bonjour_ft.c
+++ b/libpurple/protocols/bonjour/bonjour_ft.c
@@ -492,6 +492,60 @@ xep_si_parse(PurpleConnection *pc, xmlnode *packet, PurpleBuddy *pb)
 		purple_debug_info("bonjour", "si offer Message type - Unknown-%s.\n", type);
 }
 
+/**
+ * Will compare a host with a buddy_ip.
+ *
+ * Additionally to a common '!strcmp(host, buddy_ip)', it will also return TRUE
+ * if 'host' is a link local IPv6 address without an appended interface
+ * identifier and 'buddy_ip' string is "host" + "%iface".
+ *
+ * Note: This may theoretically result in the attempt to connect to the wrong
+ * host, because we do not know for sure which interface the according link
+ * local IPv6 address might relate to and RFC4862 for instance only ensures the
+ * uniqueness of this address on a given link. So we could possibly have two
+ * distinct buddies with the same ipv6 link local address on two distinct
+ * interfaces. Unfortunately XEP-0065 does not seem to specify how to deal with
+ * link local ip addresses properly...
+ * However, in practice the possiblity for such a conflict is relatively low
+ * (2011 - might be different in the future though?).
+ *
+ * @param host		ipv4 or ipv6 address string
+ * @param buddy_ip	ipv4 or ipv6 address string
+ * @return		TRUE if they match, FALSE otherwise
+ */
+static gboolean
+xep_cmp_addr(const char *host, const char *buddy_ip)
+{
+#if defined(AF_INET6) && defined(HAVE_GETADDRINFO)
+	struct addrinfo hint, *res = NULL;
+	int ret;
+
+	memset(&hint, 0, sizeof(hint));
+	hint.ai_family = AF_UNSPEC;
+	hint.ai_flags = AI_NUMERICHOST;
+
+	ret = getaddrinfo(host, NULL, &hint, &res);
+	if(ret)
+		goto out;
+
+	if(res->ai_family != AF_INET6 ||
+	   !IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)) {
+		freeaddrinfo(res);
+		goto out;
+	}
+	freeaddrinfo(res);
+
+	if(strlen(buddy_ip) <= strlen(host) ||
+	   buddy_ip[strlen(host)] != '%')
+		return FALSE;
+
+	return !strncmp(host, buddy_ip, strlen(host));
+
+out:
+#endif
+	return !strcmp(host, buddy_ip);
+}
+
 static gboolean
 __xep_bytestreams_parse(PurpleBuddy *pb, PurpleXfer *xfer, xmlnode *query,
 			const char *iq_id)
@@ -514,13 +568,13 @@ __xep_bytestreams_parse(PurpleBuddy *pb, PurpleXfer *xfer, xmlnode *query,
 			continue;
 		}
 
-		if(strcmp(host, xf->buddy_ip))
+		if(!xep_cmp_addr(host, xf->buddy_ip))
 			continue;
 
 		g_free(xf->iq_id);
 		xf->iq_id = g_strdup(iq_id);
 		xf->jid = g_strdup(jid);
-		xf->proxy_host = g_strdup(host);
+		xf->proxy_host = g_strdup(xf->buddy_ip);
 		xf->proxy_port = portnum;
 		purple_debug_info("bonjour", "bytestream offer parse"
 				  "jid=%s host=%s port=%d.\n", jid, host, portnum);
-- 
1.7.7.1




More information about the Devel mailing list