Mercurial > pidgin.yaz
diff src/protocols/rendezvous/mdns.c @ 8631:7b8f2818f38a
[gaim-migrate @ 9383]
More rendezvous stuff. You still shouldn't be using this.
I refactored a few of the mDNS sending functions and unhardcoded
some of the username and hostname values.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 11 Apr 2004 17:04:33 +0000 |
parents | fdff0f31002d |
children | bcb09cc97b63 |
line wrap: on
line diff
--- a/src/protocols/rendezvous/mdns.c Sun Apr 11 16:09:06 2004 +0000 +++ b/src/protocols/rendezvous/mdns.c Sun Apr 11 17:04:33 2004 +0000 @@ -76,7 +76,7 @@ return -1; } - /* Ensure loopback is enabled (it should be enabled by default, by let's be sure) */ + /* Ensure loopback is enabled (it should be enabled by default, but let's be sure) */ loop = 1; if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(unsigned char)) == -1) { gaim_debug_error("mdns", "Error calling setsockopt for IP_MULTICAST_LOOP\n"); @@ -135,39 +135,51 @@ /***************************************/ static int -mdns_getlength_RR_txt(void *rdata) +mdns_getlength_name(const void *name) { - GSList *cur; - ResourceRecordTXTRDataNode *node; + return strlen((const char *)name) + 2; +} + +static int +mdns_getlength_RR_rdata(unsigned short type, const void *rdata) +{ 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); + switch (type) { + case RENDEZVOUS_RRTYPE_PTR: + rdlength = mdns_getlength_name(rdata); + break; + + case RENDEZVOUS_RRTYPE_TXT: { + GSList *cur; + ResourceRecordRDataTXTNode *node; + + for (cur = (GSList *)rdata; cur != NULL; cur = cur->next) { + node = (ResourceRecordRDataTXTNode *)cur->data; + rdlength += 1 + strlen(node->name); + if (node->value != NULL) + rdlength += 1 + strlen(node->value); + } + } break; + + case RENDEZVOUS_RRTYPE_SRV: + rdlength = 6 + mdns_getlength_name(((const ResourceRecordRDataSRV *)rdata)->target); + break; } return rdlength; } static int -mdns_getlength_RR(const ResourceRecord *rr) +mdns_getlength_RR(ResourceRecord *rr) { int ret = 0; + rr->rdlength = mdns_getlength_RR_rdata(rr->type, rr->rdata); + ret += strlen(rr->name) + 2; ret += 10; - - switch (rr->type) { - case RENDEZVOUS_RRTYPE_PTR: - ret += strlen((const char *)rr->rdata) + 2; - break; - - case RENDEZVOUS_RRTYPE_TXT: - ret += mdns_getlength_RR_txt(rr->rdata); - break; - } + ret += rr->rdlength; return ret; } @@ -201,22 +213,20 @@ 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); + ResourceRecordRDataTXTNode *node; int mylength; - i += util_put16(&data[offset + i], rdlength); for (cur = (GSList *)rr->rdata; cur != NULL; cur = cur->next) { - node = (ResourceRecordTXTRDataNode *)cur->data; + node = (ResourceRecordRDataTXTNode *)cur->data; mylength = 1 + strlen(node->name); if (node->value) mylength += 1 + strlen(node->value); @@ -231,6 +241,14 @@ } } } break; + + case RENDEZVOUS_RRTYPE_SRV: { + ResourceRecordRDataSRV *srv = rr->rdata; + i += util_put16(&data[offset + i], 0); + i += util_put16(&data[offset + i], 0); + i += util_put16(&data[offset + i], srv->port); + i += mdns_put_name(data, datalen, offset + i, srv->target); + } break; } return i; @@ -253,7 +271,7 @@ /* Questions */ for (i = 0; i < dns->header.numquestions; i++) - datalen += strlen(dns->questions[i].name) + 2 + 4; + datalen += mdns_getlength_name(dns->questions[i].name) + 4; /* Resource records */ for (i = 0; i < dns->header.numanswers; i++) @@ -357,7 +375,7 @@ dns->answers = (ResourceRecord *)g_malloc(1 * sizeof(ResourceRecord)); dns->answers[0].name = g_strdup(name); dns->answers[0].type = RENDEZVOUS_RRTYPE_PTR; - dns->answers[0].class = 0x0001; + dns->answers[0].class = 0x8001; dns->answers[0].ttl = 0x00001c20; dns->answers[0].rdlength = 0x0000; /* Set automatically */ dns->answers[0].rdata = (void *)g_strdup(domain); @@ -394,7 +412,7 @@ 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].class = 0x8001; dns->answers[0].ttl = 0x00001c20; dns->answers[0].rdlength = 0x0000; /* Set automatically */ dns->answers[0].rdata = (void *)rdata; @@ -404,7 +422,52 @@ mdns_send_dns(fd, dns); - /* The hash table should be freed by the caller of this function */ + /* The rdata should be freed by the caller of this function */ + dns->answers[0].rdata = NULL; + + mdns_free(dns); + + return ret; +} + +int +mdns_advertise_srv(int fd, const char *name, unsigned short port, const char *target) +{ + int ret; + DNSPacket *dns; + ResourceRecordRDataSRV *rdata; + + if ((strlen(target) > 255)) { + return -EINVAL; + } + + rdata = g_malloc(sizeof(ResourceRecordRDataSRV)); + rdata->port = port; + rdata->target = target; + + 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_SRV; + dns->answers[0].class = 0x8001; + dns->answers[0].ttl = 0x00001c20; + dns->answers[0].rdlength = 0x0000; /* Set automatically */ + dns->answers[0].rdata = rdata; + + dns->authority = NULL; + dns->additional = NULL; + + mdns_send_dns(fd, dns); + + g_free(dns->answers[0].rdata); dns->answers[0].rdata = NULL; mdns_free(dns); @@ -418,6 +481,7 @@ /* * XXX - Needs bounds checking! + * XXX - Also make sure you don't backtrack and infinitely loop. * * Read in a domain name from the given buffer starting at the given * offset. This handles using domain name compression to jump around @@ -803,7 +867,8 @@ mdns_free_rr(ResourceRecord *rr) { g_free(rr->name); - mdns_free_rr_rdata(rr->type, rr->rdata); + if (rr->rdata != NULL) + mdns_free_rr_rdata(rr->type, rr->rdata); } void