changeset 8594:f3b928825a72

[gaim-migrate @ 9345] Some minor rendezvous changes. You still shouldn't use this yet, it has a long way to go. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Tue, 06 Apr 2004 05:16:02 +0000
parents ba075b939aa6
children 1d5e31e518fc
files src/protocols/rendezvous/mdns.c src/protocols/rendezvous/mdns.h src/protocols/rendezvous/rendezvous.c
diffstat 3 files changed, 103 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/rendezvous/mdns.c	Tue Apr 06 02:52:58 2004 +0000
+++ b/src/protocols/rendezvous/mdns.c	Tue Apr 06 05:16:02 2004 +0000
@@ -348,6 +348,43 @@
 }
 
 /*
+ *
+ *
+ */
+static ResourceRecordSRV *
+mdns_read_rr_rdata_srv(const char *data, int datalen, int offset, unsigned short rdlength)
+{
+	ResourceRecordSRV *ret = NULL;
+	int endoffset = offset + rdlength;
+
+	if (offset + 7 > endoffset)
+		return NULL;
+
+	ret = g_malloc(sizeof(ResourceRecordSRV));
+
+	/* Read in the priority */
+	ret->priority = util_get16(&data[offset]);
+	offset += 2;
+
+	/* Read in the weight */
+	ret->weight = util_get16(&data[offset]);
+	offset += 2;
+
+	/* Read in the port */
+	ret->port = util_get16(&data[offset]);
+	offset += 2;
+
+	/* Read in the target name */
+	/*
+	 * XXX - RFC2782 says it's not supposed to be an alias...
+	 * but it was in the packet capture I looked at from iChat.
+	 */
+	ret->target = mdns_read_name(data, datalen, offset);
+
+	return ret;
+}
+
+/*
  * XXX - Needs bounds checking!
  *
  */
@@ -384,6 +421,10 @@
 				ret[i].rdata = mdns_read_rr_rdata_txt(data, datalen, *offset, ret[i].rdlength);
 			break;
 
+			case RENDEZVOUS_RRTYPE_SRV:
+				ret[i].rdata = mdns_read_rr_rdata_srv(data, datalen, *offset, ret[i].rdlength);
+			break;
+
 			default:
 				ret[i].rdata = NULL;
 			break;
@@ -403,7 +444,7 @@
 {
 	DNSPacket *ret = NULL;
 	int i; /* Current position in datagram */
-	//char data[512];
+	/* char data[512]; */ /* XXX - Find out what to use as a maximum incoming UDP packet size */
 	char data[10096];
 	int datalen;
 	struct sockaddr_in addr;
--- a/src/protocols/rendezvous/mdns.h	Tue Apr 06 02:52:58 2004 +0000
+++ b/src/protocols/rendezvous/mdns.h	Tue Apr 06 05:16:02 2004 +0000
@@ -60,6 +60,7 @@
 #define RENDEZVOUS_RRTYPE_NULL	10
 #define RENDEZVOUS_RRTYPE_PTR	12
 #define RENDEZVOUS_RRTYPE_TXT	16
+#define RENDEZVOUS_RRTYPE_SRV	33
 
 /*
  * Express for Men's
@@ -79,7 +80,7 @@
 	unsigned short class;
 } Question;
 
-typedef struct ResourceRecord {
+typedef struct _ResourceRecord {
 	gchar *name;
 	unsigned short type;
 	unsigned short class;
@@ -88,6 +89,15 @@
 	void *rdata;
 } ResourceRecord;
 
+typedef GHashTable ResourceRecordTXT;
+
+typedef struct _ResourceRecordSRV {
+	unsigned int priority;
+	unsigned int weight;
+	unsigned int port;
+	gchar *target;
+} ResourceRecordSRV;
+
 typedef struct _DNSPacket {
 	Header header;
 	Question *questions;
@@ -123,8 +133,12 @@
 int mdns_query(int fd, const char *domain);
 
 /**
+ * Read a UDP packet from the given file descriptor and parse it
+ * into a DNSPacket.
  *
- *
+ * @param fd A UDP listening socket to read from.
+ * @return A newly allocated DNSPacket.  This should be freed with
+ *         mdns_free() when no longer needed.
  */
 DNSPacket *mdns_read(int fd);
 
--- a/src/protocols/rendezvous/rendezvous.c	Tue Apr 06 02:52:58 2004 +0000
+++ b/src/protocols/rendezvous/rendezvous.c	Tue Apr 06 05:16:02 2004 +0000
@@ -163,14 +163,19 @@
 	GHashTable *rdata;
 	gchar *tmp1, *tmp2;
 
+	rdata = rr->rdata;
+
+	/* Don't do a damn thing if the version is greater than 1 */
+	tmp1 = g_hash_table_lookup(rdata, "version");
+	if ((tmp1 == NULL) || (strcmp(tmp1, "1")))
+		return;
+
 	rb = g_hash_table_lookup(rd->buddies, name);
 	if (rb == NULL) {
 		rb = g_malloc0(sizeof(RendezvousBuddy));
 		g_hash_table_insert(rd->buddies, g_strdup(name), rb);
 	}
 
-	rdata = rr->rdata;
-
 	tmp1 = g_hash_table_lookup(rdata, "1st");
 	tmp2 = g_hash_table_lookup(rdata, "last");
 	g_free(rb->firstandlast);
@@ -186,8 +191,14 @@
 		rb->aim = g_strdup(tmp1);
 	}
 
-	tmp1 = g_hash_table_lookup(rdata, "port.p2pj");
-	rb->p2pjport = atoi(tmp1);
+	/*
+	 * We only want to use this port as a back-up.  Ideally the port
+	 * is specified in a separate, SRV resource record.
+	 */
+	if (rb->p2pjport == 0) {
+		tmp1 = g_hash_table_lookup(rdata, "port.p2pj");
+		rb->p2pjport = atoi(tmp1);
+	}
 
 	tmp1 = g_hash_table_lookup(rdata, "status");
 	if (tmp1 != NULL) {
@@ -212,8 +223,23 @@
 		g_free(rb->msg);
 		rb->msg = g_strdup(tmp1);
 	}
+}
 
-	/* XXX - Use the TTL value of the rr to cause this data to expire */
+static void rendezvous_handle_rr_srv(GaimConnection *gc, ResourceRecord *rr, const gchar *name)
+{
+	RendezvousData *rd = gc->proto_data;
+	RendezvousBuddy *rb;
+	ResourceRecordSRV *rdata;
+
+	rdata = rr->rdata;
+
+	rb = g_hash_table_lookup(rd->buddies, name);
+	if (rb == NULL) {
+		rb = g_malloc0(sizeof(RendezvousBuddy));
+		g_hash_table_insert(rd->buddies, g_strdup(name), rb);
+	}
+
+	rb->p2pjport = rdata->port;
 }
 
 /*
@@ -223,7 +249,13 @@
 {
 	gchar *name;
 
-	gaim_debug_error("XXX", "Parsing resource record with domain name %s\n", rr->name);
+	gaim_debug_misc("rendezvous", "Parsing resource record with domain name %s\n", rr->name);
+
+	/*
+	 * XXX - Cache resource records from this function, if needed.
+	 * Use the TTL value of the rr to cause this data to expire, but let
+	 * the mdns_cache stuff handle that as much as possible.
+	 */
 
 	switch (rr->type) {
 		case RENDEZVOUS_RRTYPE_NULL: {
@@ -255,6 +287,13 @@
 				g_free(name);
 			}
 		} break;
+
+		case RENDEZVOUS_RRTYPE_SRV: {
+			if ((name = rendezvous_extract_name(rr->name)) != NULL) {
+				rendezvous_handle_rr_srv(gc, rr, name);
+				g_free(name);
+			}
+		} break;
 	}
 }
 
@@ -315,8 +354,6 @@
 			g_string_append_printf(ret, "\n<b>%s</b>: %s", _("Available"), rb->msg);
 	}
 
-	/* XXX - Fix blist.c so we can prepend the \n's rather than appending them */
-
 	return g_string_free(ret, FALSE);
 }