pidgin.2.x.y: bc79b1bf: Fix IPv6 link local file transfer.

elb at pidgin.im elb at pidgin.im
Tue Nov 29 20:05:47 EST 2011


----------------------------------------------------------------------
Revision: bc79b1bf09dcfa1d8edac86a06761fce7416e69c
Parent:   bea846665ecc0ab993e52afc4ccbdc7b08e9e54e
Author:   linus.luessing at web.de
Date:     11/29/11 20:04:16
Branch:   im.pidgin.pidgin.2.x.y
URL: http://d.pidgin.im/viewmtn/revision/info/bc79b1bf09dcfa1d8edac86a06761fce7416e69c

Changelog: 

Fix IPv6 link local file transfer.

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.

Changes against parent bea846665ecc0ab993e52afc4ccbdc7b08e9e54e

  patched  libpurple/protocols/bonjour/bonjour_ft.c

-------------- next part --------------
============================================================
--- libpurple/protocols/bonjour/bonjour_ft.c	3c48e74b73a074123f418c620bfa27fa4f1e8d59
+++ libpurple/protocols/bonjour/bonjour_ft.c	f7cb919d92bd63c3468df71a3dbeba08bafd851f
@@ -492,7 +492,61 @@ xep_si_parse(PurpleConnection *pc, xmlno
 		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,
 			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);


More information about the Commits mailing list