# HG changeset patch # User Mark Doliner # Date 1081228562 0 # Node ID f3b928825a7276cddffd9609e85c987c0a4775e8 # Parent ba075b939aa609cff5fe8e0dcd5c2f21fe47e2c6 [gaim-migrate @ 9345] Some minor rendezvous changes. You still shouldn't use this yet, it has a long way to go. committer: Tailor Script diff -r ba075b939aa6 -r f3b928825a72 src/protocols/rendezvous/mdns.c --- 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; diff -r ba075b939aa6 -r f3b928825a72 src/protocols/rendezvous/mdns.h --- 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); diff -r ba075b939aa6 -r f3b928825a72 src/protocols/rendezvous/rendezvous.c --- 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%s: %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); }