# HG changeset patch # User Mark Doliner # Date 1083113301 0 # Node ID beb7be215db39f47176ed6de8886cba3e7d25090 # Parent 61fdef863ffa66d9bf464c3215f2fa22f02a5d27 [gaim-migrate @ 9598] I removed account->ip because it isn't used anywhere and I think it's dumb. Also added handling for a and aaaa records to rendezvous. Gaim peeps show up in iChat rendezvous lists now. There are still problems. committer: Tailor Script diff -r 61fdef863ffa -r beb7be215db3 plugins/tcl/tcl_cmds.c --- a/plugins/tcl/tcl_cmds.c Tue Apr 27 23:17:12 2004 +0000 +++ b/plugins/tcl/tcl_cmds.c Wed Apr 28 00:48:21 2004 +0000 @@ -77,15 +77,15 @@ { Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; char *cmds[] = { "alias", "connect", "connection", "disconnect", "find", - "handle", "isconnected", "list", "public_ip", + "handle", "isconnected", "list", "protocol", "username", NULL }; enum { CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE, - CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, CMD_ACCOUNT_PUBLIC_IP, + CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_USERNAME } cmd; char *listopts[] = { "-all", "-online", NULL }; enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt; - const char *alias, *ip; + const char *alias; GList *cur; GaimAccount *account; int error; @@ -188,17 +188,6 @@ } Tcl_SetObjResult(interp, list); break; - case CMD_ACCOUNT_PUBLIC_IP: - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "account"); - return TCL_ERROR; - } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) - return TCL_ERROR; - ip = gaim_account_get_public_ip(account); - Tcl_SetStringObj(result, ip != NULL ? (char *)ip : "", -1); - break; case CMD_ACCOUNT_PROTOCOL: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); diff -r 61fdef863ffa -r beb7be215db3 src/account.c --- a/src/account.c Tue Apr 27 23:17:12 2004 +0000 +++ b/src/account.c Wed Apr 28 00:48:21 2004 +0000 @@ -43,7 +43,6 @@ TAG_ALIAS, TAG_USERINFO, TAG_BUDDYICON, - TAG_PUBLIC_IP, TAG_SETTING, TAG_TYPE, TAG_HOST, @@ -509,19 +508,6 @@ } void -gaim_account_set_public_ip(GaimAccount *account, const char *ip) -{ - g_return_if_fail(account != NULL); - - if (account->ip != NULL) - g_free(account->ip); - - account->ip = (ip == NULL ? NULL : g_strdup(ip)); - - schedule_accounts_save(); -} - -void gaim_account_set_proxy_info(GaimAccount *account, GaimProxyInfo *info) { g_return_if_fail(account != NULL); @@ -786,14 +772,6 @@ return gaim_account_get_ui_bool(account, ui, "auto-login", FALSE); } -const char * -gaim_account_get_public_ip(const GaimAccount *account) -{ - g_return_val_if_fail(account != NULL, NULL); - - return account->ip; -} - GaimProxyInfo * gaim_account_get_proxy_info(const GaimAccount *account) { @@ -1005,8 +983,6 @@ data->tag = TAG_USERINFO; else if (!strcmp(element_name, "buddyicon")) data->tag = TAG_BUDDYICON; - else if (!strcmp(element_name, "public-ip")) - data->tag = TAG_PUBLIC_IP; else if (!strcmp(element_name, "proxy")) { data->in_proxy = TRUE; @@ -1095,10 +1071,6 @@ if (*buffer != '\0') gaim_account_set_buddy_icon(data->account, buffer); } - else if (data->tag == TAG_PUBLIC_IP) { - if (*buffer != '\0') - gaim_account_set_public_ip(data->account, buffer); - } else if (data->tag == TAG_TYPE) { if (data->in_proxy) { if (!strcmp(buffer, "global")) @@ -1307,7 +1279,7 @@ { GaimProxyInfo *proxy_info; GaimProxyType proxy_type; - const char *password, *alias, *user_info, *buddy_icon, *ip; + const char *password, *alias, *user_info, *buddy_icon; char *esc; fprintf(fp, " \n"); @@ -1342,10 +1314,6 @@ g_free(esc); } - if ((ip = gaim_account_get_public_ip(account)) != NULL) { - fprintf(fp, " %s\n", ip); - } - fprintf(fp, " \n"); g_hash_table_foreach(account->settings, write_setting, fp); fprintf(fp, " \n"); diff -r 61fdef863ffa -r beb7be215db3 src/account.h --- a/src/account.h Tue Apr 27 23:17:12 2004 +0000 +++ b/src/account.h Wed Apr 28 00:48:21 2004 +0000 @@ -64,7 +64,6 @@ GHashTable *settings; /**< Protocol-specific settings. */ GHashTable *ui_settings; /**< UI-specific settings. */ - char *ip; /**< The IP address for transfers. */ GaimProxyInfo *proxy_info; /**< Proxy information. This will be set */ /* to NULL when the account inherits */ /* proxy settings from global prefs. */ @@ -251,15 +250,6 @@ gboolean value); /** - * Sets the public IP address the account will use for such things - * as file transfer. - * - * @param account The account. - * @param ip The IP address. - */ -void gaim_account_set_public_ip(GaimAccount *account, const char *ip); - -/** * Sets the account's proxy information. * * @param account The account. @@ -448,15 +438,6 @@ const char *ui); /** - * Returns the account's public IP address. - * - * @param account The account. - * - * @return The IP address. - */ -const char *gaim_account_get_public_ip(const GaimAccount *account); - -/** * Returns the account's proxy information. * * @param account The account. diff -r 61fdef863ffa -r beb7be215db3 src/gtkprefs.c --- a/src/gtkprefs.c Tue Apr 27 23:17:12 2004 +0000 +++ b/src/gtkprefs.c Wed Apr 28 00:48:21 2004 +0000 @@ -1050,7 +1050,7 @@ static void network_ip_changed(GtkEntry *entry, gpointer data) { - gaim_prefs_set_string("/core/network/public_ip", gtk_entry_get_text(entry)); + gaim_network_set_public_ip(gtk_entry_get_text(entry)); } GtkWidget *network_page() { @@ -1083,9 +1083,9 @@ g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(network_ip_changed), NULL); - if (gaim_network_get_local_ip() != NULL) + if (gaim_network_get_public_ip() != NULL) gtk_entry_set_text(GTK_ENTRY(entry), - gaim_network_get_local_ip()); + gaim_network_get_public_ip()); gaim_set_accessible_label (entry, label); diff -r 61fdef863ffa -r beb7be215db3 src/network.c --- a/src/network.c Tue Apr 27 23:17:12 2004 +0000 +++ b/src/network.c Wed Apr 28 00:48:21 2004 +0000 @@ -31,7 +31,7 @@ #include "prefs.h" void -gaim_network_set_local_ip(const char *ip) +gaim_network_set_public_ip(const char *ip) { g_return_if_fail(ip != NULL); @@ -39,13 +39,10 @@ } const char * -gaim_network_get_local_ip(void) +gaim_network_get_public_ip(void) { const char *ip; - if (gaim_prefs_get_bool("/core/network/auto_ip")) - return NULL; - ip = gaim_prefs_get_string("/core/network/public_ip"); if (ip == NULL || *ip == '\0') @@ -111,15 +108,21 @@ const char * gaim_network_get_ip_for_account(const GaimAccount *account, int fd) { - if (account && (gaim_account_get_public_ip(account) != NULL)) - return gaim_account_get_public_ip(account); - else if (gaim_network_get_local_ip() != NULL) - return gaim_network_get_local_ip(); - else - return gaim_network_get_local_system_ip(fd); + const char *ip = NULL; + + /* Check if the user specified an IP manually */ + if (!gaim_prefs_get_bool("/core/network/auto_ip")) { + ip = gaim_network_get_public_ip(); + if (ip != NULL) + return ip; + } + + /* Just fetch the IP of the local system */ + return gaim_network_get_local_system_ip(fd); } -static int gaim_network_do_listen(unsigned short port) +static int +gaim_network_do_listen(unsigned short port) { #if HAVE_GETADDRINFO int listenfd; @@ -189,14 +192,16 @@ return listenfd; } -int gaim_network_listen(unsigned short port) +int +gaim_network_listen(unsigned short port) { g_return_val_if_fail(port != 0, -1); return gaim_network_do_listen(port); } -int gaim_network_listen_range(unsigned short start, unsigned short end) +int +gaim_network_listen_range(unsigned short start, unsigned short end) { int ret = -1; @@ -217,7 +222,8 @@ return ret; } -short gaim_network_get_port_from_fd(int fd) +unsigned short +gaim_network_get_port_from_fd(int fd) { struct sockaddr_in addr; socklen_t len; diff -r 61fdef863ffa -r beb7be215db3 src/network.h --- a/src/network.h Tue Apr 27 23:17:12 2004 +0000 +++ b/src/network.h Wed Apr 28 00:48:21 2004 +0000 @@ -30,26 +30,29 @@ #endif /**************************************************************************/ -/** @name Network API */ +/** @name Network API */ /**************************************************************************/ /*@{*/ /** - * Sets the IP address of the local system in preferences. + * Sets the IP address of the local system in preferences. This + * is the IP address that should be used for incoming connections + * (file transfer, direct IM, etc.) and should therefore be + * publicly accessible. * * @param ip The local IP address. */ -void gaim_network_set_local_ip(const char *ip); +void gaim_network_set_public_ip(const char *ip); /** * Returns the IP address of the local system set in preferences. * - * This returns the value set via gaim_network_set_local_ip(). + * This returns the value set via gaim_network_set_public_ip(). * You probably want to use gaim_network_get_ip_for_account() instead. * * @return The local IP address set in preferences. */ -const char *gaim_network_get_local_ip(void); +const char *gaim_network_get_public_ip(void); /** * Returns the IP address of the local system. @@ -66,15 +69,14 @@ const char *gaim_network_get_local_system_ip(int fd); /** - * Returns the IP address that should be used for the specified account. - * - * First, if @a account is not @c NULL, the IP associated with @a account - * is tried, via a call to gaim_account_get_local_ip(). + * Returns the IP address that should be used anywhere a + * public IP addresses is needed (listening for an incoming + * file transfer, etc). * - * If that IP is not set, the IP set in preferences is tried. - * - * If that IP is not set, the system's local IP is tried, via a call to - * gaim_network_get_local_ip(). + * If the user has manually specified an IP address via + * preferences, then this IP is returned. Otherwise the + * IP address returned by gaim_network_get_local_system_ip() + * is returned. * * @note The returned string is a pointer to a static buffer. If this * function is called twice, it may be important to make a copy @@ -140,7 +142,7 @@ * possible bug will inspire new and valuable contributors to Gaim. * @return The port number, in host byte order. */ -short gaim_network_get_port_from_fd(int fd); +unsigned short gaim_network_get_port_from_fd(int fd); /** * Initializes the network subsystem. diff -r 61fdef863ffa -r beb7be215db3 src/protocols/rendezvous/mdns.c --- a/src/protocols/rendezvous/mdns.c Tue Apr 27 23:17:12 2004 +0000 +++ b/src/protocols/rendezvous/mdns.c Wed Apr 28 00:48:21 2004 +0000 @@ -89,8 +89,10 @@ return; switch (type) { + case RENDEZVOUS_RRTYPE_A: case RENDEZVOUS_RRTYPE_NULL: case RENDEZVOUS_RRTYPE_PTR: + case RENDEZVOUS_RRTYPE_AAAA: g_free(rdata); break; @@ -237,18 +239,26 @@ return NULL; switch (type) { + case RENDEZVOUS_RRTYPE_A: + ret = g_memdup(rdata, rdlength); + break; + case RENDEZVOUS_RRTYPE_NULL: ret = g_memdup(rdata, rdlength); break; case RENDEZVOUS_RRTYPE_PTR: - ret = g_memdup(rdata, rdlength); + ret = g_strdup(rdata); break; case RENDEZVOUS_RRTYPE_TXT: ret = mdns_copy_rr_rdata_txt(rdata); break; + case RENDEZVOUS_RRTYPE_AAAA: + ret = g_memdup(rdata, rdlength); + break; + case RENDEZVOUS_RRTYPE_SRV: ret = mdns_copy_rr_rdata_srv(rdata); break; @@ -319,7 +329,7 @@ /******************************************/ int -mdns_establish_socket() +mdns_socket_establish() { int fd = -1; struct sockaddr_in addr; @@ -381,6 +391,15 @@ return fd; } +void +mdns_socket_close(int fd) +{ + if (fd >= 0) + close(fd); + + mdns_cache_remove_all(); +} + /** * Multicast raw data over a file descriptor. * @@ -457,6 +476,10 @@ int rdlength = 0; switch (type) { + case RENDEZVOUS_RRTYPE_A: + rdlength = 4; + break; + case RENDEZVOUS_RRTYPE_PTR: rdlength = mdns_getlength_name(rdata); break; @@ -473,6 +496,10 @@ } } break; + case RENDEZVOUS_RRTYPE_AAAA: + rdlength = 16; + break; + case RENDEZVOUS_RRTYPE_SRV: rdlength = 6 + mdns_getlength_name(((const ResourceRecordRDataSRV *)rdata)->target); break; @@ -580,6 +607,11 @@ i += util_put16(&data[offset + i], rr->rdlength); switch (rr->type) { + case RENDEZVOUS_RRTYPE_A: + memcpy(&data[offset + i], rr->rdata, rr->rdlength); + i += rr->rdlength; + break; + case RENDEZVOUS_RRTYPE_NULL: memcpy(&data[offset + i], rr->rdata, rr->rdlength); i += rr->rdlength; @@ -611,6 +643,11 @@ } } break; + case RENDEZVOUS_RRTYPE_AAAA: + memcpy(&data[offset + i], rr->rdata, rr->rdlength); + i += rr->rdlength; + break; + case RENDEZVOUS_RRTYPE_SRV: { ResourceRecordRDataSRV *srv = rr->rdata; i += util_put16(&data[offset + i], 0); @@ -735,6 +772,37 @@ } int +mdns_advertise_a(int fd, const char *name, unsigned char *ip) +{ + int ret; + ResourceRecord *rr; + ResourceRecordRDataA *rdata; + int i; + + if ((name == NULL) || (strlen(name) > 255)) { + return -EINVAL; + } + + rdata = g_malloc(4); + for (i = 0; i < 4; i++) + util_put8(&rdata[i], ip[i]); + + rr = (ResourceRecord *)g_malloc(sizeof(ResourceRecord)); + rr->name = g_strdup(name); + rr->type = RENDEZVOUS_RRTYPE_A; + rr->class = 0x0001; + rr->ttl = 0x000000f0; + rr->rdlength = 4; + rr->rdata = mdns_copy_rr_rdata(rr->type, rdata, rr->rdlength); + + ret = mdns_send_rr(fd, rr); + + mdns_free_rr(rr); + + return ret; +} + +int mdns_advertise_null(int fd, const char *name, const char *rdata, unsigned short rdlength) { int ret; @@ -810,6 +878,37 @@ } int +mdns_advertise_aaaa(int fd, const char *name, unsigned char *ip) +{ + int ret; + ResourceRecord *rr; + ResourceRecordRDataA *rdata; + int i; + + if ((name == NULL) || (strlen(name) > 255)) { + return -EINVAL; + } + + rdata = g_malloc(16); + for (i = 0; i < 16; i++) + util_put8(&rdata[i], ip[i]); + + rr = (ResourceRecord *)g_malloc(sizeof(ResourceRecord)); + rr->name = g_strdup(name); + rr->type = RENDEZVOUS_RRTYPE_A; + rr->class = 0x0001; + rr->ttl = 0x000000f0; + rr->rdlength = 16; + rr->rdata = mdns_copy_rr_rdata(rr->type, rdata, rr->rdlength); + + ret = mdns_send_rr(fd, rr); + + mdns_free_rr(rr); + + return ret; +} + +int mdns_advertise_srv(int fd, const char *name, unsigned short port, const char *target) { int ret; @@ -1194,7 +1293,14 @@ *offset += 2; /* RDATA */ - if (rr->type == RENDEZVOUS_RRTYPE_NULL) { + if (rr->type == RENDEZVOUS_RRTYPE_A) { + rr->rdata = mdns_read_rr_rdata_null(data, datalen, *offset, rr->rdlength); + if (rr->rdata == NULL) { + mdns_free_rr(rr); + return NULL; + } + + } else if (rr->type == RENDEZVOUS_RRTYPE_NULL) { rr->rdata = mdns_read_rr_rdata_null(data, datalen, *offset, rr->rdlength); if (rr->rdata == NULL) { mdns_free_rr(rr); @@ -1215,6 +1321,13 @@ return NULL; } + } else if (rr->type == RENDEZVOUS_RRTYPE_AAAA) { + rr->rdata = mdns_read_rr_rdata_null(data, datalen, *offset, rr->rdlength); + if (rr->rdata == NULL) { + mdns_free_rr(rr); + return NULL; + } + } else if (rr->type == RENDEZVOUS_RRTYPE_SRV) { rr->rdata = mdns_read_rr_rdata_srv(data, datalen, *offset, rr->rdlength); if (rr->rdata == NULL) { @@ -1298,11 +1411,6 @@ /* For the flags, some bits must be 0 and some must be 1, the rest are ignored */ dns->header.flags = util_get16(&data[offset]); /* Flags (QR, OPCODE, AA, TC, RD, RA, Z, AD, CD, and RCODE */ offset += 2; - if ((dns->header.flags & 0x8000) == 0) { - /* QR should be 1 */ - g_free(dns); - return NULL; - } if ((dns->header.flags & 0x7800) != 0) { /* OPCODE should be all 0's */ g_free(dns); diff -r 61fdef863ffa -r beb7be215db3 src/protocols/rendezvous/mdns.h --- a/src/protocols/rendezvous/mdns.h Tue Apr 27 23:17:12 2004 +0000 +++ b/src/protocols/rendezvous/mdns.h Wed Apr 28 00:48:21 2004 +0000 @@ -60,6 +60,7 @@ #define RENDEZVOUS_RRTYPE_NULL 10 #define RENDEZVOUS_RRTYPE_PTR 12 #define RENDEZVOUS_RRTYPE_TXT 16 +#define RENDEZVOUS_RRTYPE_AAAA 28 #define RENDEZVOUS_RRTYPE_SRV 33 #define RENDEZVOUS_RRTYPE_ALL 255 @@ -90,6 +91,8 @@ void *rdata; } ResourceRecord; +typedef unsigned char ResourceRecordRDataA; + typedef struct _ResourceRecordRDataTXTNode { char *name; char *value; @@ -97,6 +100,8 @@ typedef GSList ResourceRecordRDataTXT; +typedef unsigned char ResourceRecordRDataAAAA; + typedef struct _ResourceRecordRDataSRV { unsigned int priority; unsigned int weight; @@ -124,7 +129,16 @@ * @return The file descriptor of the new socket, or -1 if * there was an error establishing the socket. */ -int mdns_establish_socket(); +int mdns_socket_establish(); + + +/** + * Close a multicast socket. This also clears the MDNS + * cache. + * + * @param The file descriptor of the multicast socket. + */ +void mdns_socket_close(int fd); /** @@ -152,9 +166,11 @@ int mdns_query(int fd, const char *domain, unsigned short type); int mdns_send_rr(int fd, ResourceRecord *rr); +int mdns_advertise_a(int fd, const char *name, unsigned char *ip); int mdns_advertise_null(int fd, const char *name, const char *data, unsigned short rdlength); int mdns_advertise_ptr(int fd, const char *name, const char *domain); int mdns_advertise_txt(int fd, const char *name, const GSList *txt); +int mdns_advertise_aaaa(int fd, const char *name, unsigned char *ip); int mdns_advertise_srv(int fd, const char *name, unsigned short port, const char *target); /** diff -r 61fdef863ffa -r beb7be215db3 src/protocols/rendezvous/mdns_cache.c --- a/src/protocols/rendezvous/mdns_cache.c Tue Apr 27 23:17:12 2004 +0000 +++ b/src/protocols/rendezvous/mdns_cache.c Wed Apr 28 00:48:21 2004 +0000 @@ -27,29 +27,56 @@ #include "debug.h" #include "mdns.h" +#include "mdns_cache.h" -/* XXX - Make sure this is freed when we sign off */ GSList *rrs = NULL; +static ResourceRecord * +mdns_cache_find(gchar *name, unsigned short type) +{ + ResourceRecord *rr; + GSList *cur; + + g_return_val_if_fail(name != NULL, NULL); + g_return_val_if_fail((type != 0) || (type != RENDEZVOUS_RRTYPE_ALL), NULL); + + for (cur = rrs; cur != NULL; cur = cur->next) { + rr = cur->data; + if ((type == rr->type) && (!strcmp(name, rr->name))) + return rr; + } + + return NULL; +} + void mdns_cache_add(const ResourceRecord *rr) { ResourceRecord *new; g_return_if_fail(rr != NULL); + g_return_if_fail((rr->type != 0) && (rr->type != RENDEZVOUS_RRTYPE_ALL)); + mdns_cache_remove(rr->name, rr->type); + + printf("caching %d\n", rr->type); new = mdns_copy_rr(rr); - rrs = g_slist_prepend(rrs, new); } void -mdns_cache_remove(ResourceRecord *rr) +mdns_cache_remove(gchar *name, unsigned short type) { - g_return_if_fail(rr != NULL); + ResourceRecord *rr; + + g_return_if_fail(name != NULL); + g_return_if_fail((type != 0) && (type != RENDEZVOUS_RRTYPE_ALL)); - rrs = g_slist_remove_all(rrs, rr); + rr = mdns_cache_find(name, type); + if (rr == NULL) + return; + rrs = g_slist_remove(rrs, rr); mdns_free_rr(rr); } @@ -66,10 +93,13 @@ ResourceRecord *cur; g_return_if_fail(q != NULL); + printf("query for q->type=%d, q->name=%s\n", q->type, q->name); - for (slist = rrs; slist != NULL; slist = g_slist_next(slist)) { + for (slist = rrs; slist != NULL; slist = slist->next) { cur = slist->data; - if ((q->type == cur->type) && (!strcmp(q->name, cur->name))) - mdns_send_rr(fd, cur); + if ((q->type == cur->type) && (!strcmp(q->name, cur->name))) { + printf("responding to cur->type=%d, cur->name=%s\n", cur->type, cur->name); + //mdns_send_rr(fd, cur); + } } } diff -r 61fdef863ffa -r beb7be215db3 src/protocols/rendezvous/mdns_cache.h --- a/src/protocols/rendezvous/mdns_cache.h Tue Apr 27 23:17:12 2004 +0000 +++ b/src/protocols/rendezvous/mdns_cache.h Wed Apr 28 00:48:21 2004 +0000 @@ -39,7 +39,7 @@ /** * */ -void mdns_cache_remove(ResourceRecord *rr); +void mdns_cache_remove(gchar *name, unsigned short type); /** * diff -r 61fdef863ffa -r beb7be215db3 src/protocols/rendezvous/rendezvous.c --- a/src/protocols/rendezvous/rendezvous.c Tue Apr 27 23:17:12 2004 +0000 +++ b/src/protocols/rendezvous/rendezvous.c Wed Apr 28 00:48:21 2004 +0000 @@ -26,6 +26,7 @@ #include "blist.h" #include "conversation.h" #include "debug.h" +#include "network.h" #include "prpl.h" #include "mdns.h" @@ -45,6 +46,7 @@ #endif gchar *firstandlast; gchar *aim; + int ip[4]; int p2pjport; int status; int idle; @@ -179,6 +181,23 @@ } } +static void rendezvous_handle_rr_a(GaimConnection *gc, ResourceRecord *rr, const gchar *name) +{ + RendezvousData *rd = gc->proto_data; + RendezvousBuddy *rb; + ResourceRecordRDataSRV *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); + } + + memcpy(rb->ip, rdata, 4); +} + static void rendezvous_handle_rr_txt(GaimConnection *gc, ResourceRecord *rr, const gchar *name) { RendezvousData *rd = gc->proto_data; @@ -278,15 +297,18 @@ 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_A: { + name = rendezvous_extract_name(rr->name); + if (name != NULL) { + rendezvous_handle_rr_a(gc, rr, name); + g_free(name); + } + } break; - switch (rr->type) { case RENDEZVOUS_RRTYPE_NULL: { - if ((name = rendezvous_extract_name(rr->name)) != NULL) { + name = rendezvous_extract_name(rr->name); + if (name != NULL) { if (rr->rdlength > 0) { /* Data is a buddy icon */ gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc), name, rr->rdata, rr->rdlength); @@ -298,7 +320,9 @@ case RENDEZVOUS_RRTYPE_PTR: { gchar *rdata = rr->rdata; - if ((name = rendezvous_extract_name(rdata)) != NULL) { + + name = rendezvous_extract_name(rdata); + if (name != NULL) { if (rr->ttl > 0) { /* Add them to our buddy list and request their icon */ rendezvous_addtolocal(gc, name, "Rendezvous"); @@ -312,14 +336,16 @@ } break; case RENDEZVOUS_RRTYPE_TXT: { - if ((name = rendezvous_extract_name(rr->name)) != NULL) { + name = rendezvous_extract_name(rr->name); + if (name != NULL) { rendezvous_handle_rr_txt(gc, rr, name); g_free(name); } } break; case RENDEZVOUS_RRTYPE_SRV: { - if ((name = rendezvous_extract_name(rr->name)) != NULL) { + name = rendezvous_extract_name(rr->name); + if (name != NULL) { rendezvous_handle_rr_srv(gc, rr, name); g_free(name); } @@ -455,17 +481,36 @@ g_free(rdata); } +static int *rendezvous_get_ip_as_int_array(int fd) +{ + static int ret[4]; + const char *ip, *nexttoken; + int i = 0; + + ip = gaim_network_get_local_system_ip(fd); + nexttoken = strtok((char *)ip, "."); + while (nexttoken && i < 4) { + ret[i] = atoi(nexttoken); + nexttoken = strtok(NULL, "."); + } + + return ret; +} + static void rendezvous_send_online(GaimConnection *gc) { RendezvousData *rd = gc->proto_data; GaimAccount *account = gaim_connection_get_account(gc); const gchar *me; gchar *myname, *mycomp; + unsigned char *myip; me = gaim_account_get_username(account); myname = g_strdup_printf("%s._presence._tcp.local", me); mycomp = g_strdup_printf("%s.local", strchr(me, '@') + 1); + myip = rendezvous_get_ip_as_int_array(rd->fd); + mdns_advertise_a(rd->fd, mycomp, myip); mdns_advertise_ptr(rd->fd, "_presence._tcp.local", myname); mdns_advertise_srv(rd->fd, myname, 5298, mycomp); @@ -511,7 +556,7 @@ rendezvous_removeallfromlocal(gc); gaim_connection_update_progress(gc, _("Connecting"), 1, RENDEZVOUS_CONNECT_STEPS); - rd->fd = mdns_establish_socket(); + rd->fd = mdns_socket_establish(); if (rd->fd == -1) { gaim_connection_error(gc, _("Unable to login to rendezvous")); return; @@ -537,8 +582,7 @@ if (!rd) return; - if (rd->fd >= 0) - close(rd->fd); + mdns_socket_close(rd->fd); g_hash_table_destroy(rd->buddies);