# HG changeset patch # User Mark Doliner # Date 1081654031 0 # Node ID fdff0f31002d420aa97ddf97944e28de760c4355 # Parent 54baaec95c0546ad1d4c55885803e4c942b4ea31 [gaim-migrate @ 9381] Rendezvous updates: Advertise txt stuff for Gaim; just a step toward having Gaim users show up in iChat rendezvous buddy lists. Also a fix to make away people show up as away and available people to not show up as away. No one should be using this yet. committer: Tailor Script diff -r 54baaec95c05 -r fdff0f31002d src/protocols/rendezvous/mdns.c --- a/src/protocols/rendezvous/mdns.c Sat Apr 10 20:55:58 2004 +0000 +++ b/src/protocols/rendezvous/mdns.c Sun Apr 11 03:27:11 2004 +0000 @@ -135,6 +135,23 @@ /***************************************/ static int +mdns_getlength_RR_txt(void *rdata) +{ + GSList *cur; + ResourceRecordTXTRDataNode *node; + int rdlength = 0; + + for (cur = (GSList *)rdata; cur != NULL; cur = cur->next) { + node = (ResourceRecordTXTRDataNode *)cur->data; + rdlength += 1 + strlen(node->name); + if (node->value != NULL) + rdlength += 1 + strlen(node->value); + } + + return rdlength; +} + +static int mdns_getlength_RR(const ResourceRecord *rr) { int ret = 0; @@ -146,6 +163,10 @@ case RENDEZVOUS_RRTYPE_PTR: ret += strlen((const char *)rr->rdata) + 2; break; + + case RENDEZVOUS_RRTYPE_TXT: + ret += mdns_getlength_RR_txt(rr->rdata); + break; } return ret; @@ -180,12 +201,36 @@ i += util_put16(&data[offset + i], rr->type); i += util_put16(&data[offset + i], rr->class); i += util_put32(&data[offset + i], rr->ttl); - i += util_put16(&data[offset + i], rr->rdlength); switch (rr->type) { case RENDEZVOUS_RRTYPE_PTR: + i += util_put16(&data[offset + i], strlen((const char *)rr->rdata) + 2); i += mdns_put_name(data, datalen, offset + i, (const char *)rr->rdata); break; + + case RENDEZVOUS_RRTYPE_TXT: { + GSList *cur; + ResourceRecordTXTRDataNode *node; + int rdlength = mdns_getlength_RR_txt(rr->rdata); + int mylength; + + i += util_put16(&data[offset + i], rdlength); + for (cur = (GSList *)rr->rdata; cur != NULL; cur = cur->next) { + node = (ResourceRecordTXTRDataNode *)cur->data; + mylength = 1 + strlen(node->name); + if (node->value) + mylength += 1 + strlen(node->value); + i += util_put8(&data[offset + i], mylength - 1); + memcpy(&data[offset + i], node->name, strlen(node->name)); + i += strlen(node->name); + if (node->value) { + data[offset + i] = '='; + i++; + memcpy(&data[offset + i], node->value, strlen(node->value)); + i += strlen(node->value); + } + } + } break; } return i; @@ -314,7 +359,7 @@ dns->answers[0].type = RENDEZVOUS_RRTYPE_PTR; dns->answers[0].class = 0x0001; dns->answers[0].ttl = 0x00001c20; - dns->answers[0].rdlength = strlen(domain) + 2; + dns->answers[0].rdlength = 0x0000; /* Set automatically */ dns->answers[0].rdata = (void *)g_strdup(domain); dns->authority = NULL; @@ -327,6 +372,46 @@ return ret; } +int +mdns_advertise_txt(int fd, const char *name, const GSList *rdata) +{ + int ret; + DNSPacket *dns; + + if ((strlen(name) > 255)) { + return -EINVAL; + } + + dns = (DNSPacket *)g_malloc(sizeof(DNSPacket)); + dns->header.id = 0x0000; + dns->header.flags = 0x8400; + dns->header.numquestions = 0x0000; + dns->header.numanswers = 0x0001; + dns->header.numauthority = 0x0000; + dns->header.numadditional = 0x0000; + dns->questions = NULL; + + dns->answers = (ResourceRecord *)g_malloc(1 * sizeof(ResourceRecord)); + dns->answers[0].name = g_strdup(name); + dns->answers[0].type = RENDEZVOUS_RRTYPE_TXT; + dns->answers[0].class = 0x0001; + dns->answers[0].ttl = 0x00001c20; + dns->answers[0].rdlength = 0x0000; /* Set automatically */ + dns->answers[0].rdata = (void *)rdata; + + dns->authority = NULL; + dns->additional = NULL; + + mdns_send_dns(fd, dns); + + /* The hash table should be freed by the caller of this function */ + dns->answers[0].rdata = NULL; + + mdns_free(dns); + + return ret; +} + /***************************************/ /* Functions for parsing mDNS messages */ /***************************************/ diff -r 54baaec95c05 -r fdff0f31002d src/protocols/rendezvous/mdns.h --- a/src/protocols/rendezvous/mdns.h Sat Apr 10 20:55:58 2004 +0000 +++ b/src/protocols/rendezvous/mdns.h Sun Apr 11 03:27:11 2004 +0000 @@ -89,6 +89,13 @@ void *rdata; } ResourceRecord; +typedef struct _ResourceRecordTXTRDataNode { + char *name; + char *value; +} ResourceRecordTXTRDataNode; + +typedef GSList ResourceRecordTXTRData; + typedef GHashTable ResourceRecordTXT; typedef struct _ResourceRecordSRV { @@ -146,6 +153,7 @@ int mdns_query(int fd, const char *domain); int mdns_advertise_ptr(int fd, const char *name, const char *domain); +int mdns_advertise_txt(int fd, const char *name, const GSList *txt); /** * Read a UDP packet from the given file descriptor and parse it diff -r 54baaec95c05 -r fdff0f31002d src/protocols/rendezvous/rendezvous.c --- a/src/protocols/rendezvous/rendezvous.c Sat Apr 10 20:55:58 2004 +0000 +++ b/src/protocols/rendezvous/rendezvous.c Sun Apr 11 03:27:11 2004 +0000 @@ -36,6 +36,7 @@ typedef struct _RendezvousData { int fd; GHashTable *buddies; + GSList *mytxtdata; } RendezvousData; typedef struct _RendezvousBuddy { @@ -224,7 +225,7 @@ tmp1 = g_hash_table_lookup(rdata, "status"); if (tmp1 != NULL) { - if (!strcmp(tmp1, "dnd")) { + if (!strcmp(tmp1, "avail")) { /* Available */ rb->status = 0; } else if (!strcmp(tmp1, "away")) { @@ -233,7 +234,7 @@ rb->idle = atoi(tmp2); gaim_debug_error("XXX", "User has been idle since %d\n", rb->idle); rb->status = UC_IDLE; - } else if (!strcmp(tmp1, "avail")) { + } else if (!strcmp(tmp1, "dnd")) { /* Away */ rb->status = UC_UNAVAILABLE; } @@ -405,6 +406,36 @@ mdns_free(dns); } +static void rendezvous_add_to_txt(RendezvousData *rd, const char *name, const char *value) +{ + ResourceRecordTXTRDataNode *node; + node = g_malloc(sizeof(ResourceRecordTXTRDataNode)); + node->name = g_strdup(name); + node->value = value != NULL ? g_strdup(value) : NULL; + rd->mytxtdata = g_slist_append(rd->mytxtdata, node); +} + +static void rendezvous_send_online(GaimConnection *gc) +{ + RendezvousData *rd = gc->proto_data; + GaimAccount *account = gaim_connection_get_account(gc); + + mdns_advertise_ptr(rd->fd, "_presence._tcp.local", "mark@diverge._presence._tcp.local"); + + rendezvous_add_to_txt(rd, "txtvers", "1"); + rendezvous_add_to_txt(rd, "status", "avail"); + rendezvous_add_to_txt(rd, "1st", gaim_account_get_string(account, "first", "Gaim")); + rendezvous_add_to_txt(rd, "AIM", "markdoliner"); + rendezvous_add_to_txt(rd, "version", "1"); + rendezvous_add_to_txt(rd, "port.p2pj", "5298"); + rendezvous_add_to_txt(rd, "last", gaim_account_get_string(account, "last", _("User"))); + mdns_advertise_txt(rd->fd, "mark@diverge._presence._tcp.local", rd->mytxtdata); + +#if 0 + mdns_advertise_srv(rd->fd, "mark@diverge._presence._tcp.local", port 5298, IP?); +#endif +} + static void rendezvous_prpl_login(GaimAccount *account) { GaimConnection *gc = gaim_account_get_connection(account); @@ -428,24 +459,13 @@ gaim_connection_set_state(gc, GAIM_CONNECTED); mdns_query(rd->fd, "_presence._tcp.local"); - /* mdns_advertise_ptr(rd->fd, "_presence._tcp.local", "mark@diverge._presence._tcp.local"); */ - -#if 0 - text_record_add("txtvers", "1"); - text_record_add("status", "avail"); - text_record_add("1st", gaim_account_get_string(account, "first", "Gaim")); - text_record_add("AIM", "markdoliner"); - text_record_add("version", "1"); - text_record_add("port.p2pj", "5298"); - text_record_add("last", gaim_account_get_string(account, "last", _("User"))); - - publish(account->username, "_presence._tcp", 5298); -#endif + rendezvous_send_online(gc); } static void rendezvous_prpl_close(GaimConnection *gc) { RendezvousData *rd = (RendezvousData *)gc->proto_data; + ResourceRecordTXTRDataNode *node; if (gc->inpa) gaim_input_remove(gc->inpa); @@ -460,6 +480,14 @@ g_hash_table_destroy(rd->buddies); + while (rd->mytxtdata != NULL) { + node = rd->mytxtdata->data; + rd->mytxtdata = g_slist_remove(rd->mytxtdata, node); + g_free(node->name); + g_free(node->value); + g_free(node); + } + g_free(rd); }