# HG changeset patch # User Mark Doliner # Date 1102281944 0 # Node ID 782c1b5649063b61b11614cb490a9aff33a0a7ae # Parent 61852117568f36ceb22b1f93c77059aaee903c92 [gaim-migrate @ 11528] Some rendezvous changes I've had sitting around for a while. committer: Tailor Script diff -r 61852117568f -r 782c1b564906 src/protocols/rendezvous/direct.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/rendezvous/direct.c Sun Dec 05 21:25:44 2004 +0000 @@ -0,0 +1,102 @@ +/* + * gaim - Rendezvous Protocol Plugin + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "internal.h" + +#include "connection.h" +#include "network.h" + +#include "direct.h" +#include "rendezvous.h" + +/* +gchar * +gaim_network_convert_ipv4_to_string(void *ip) +{ + gchar *ret; + unsigned char *ipv4 = (unsigned char *)ip; + + ret = g_strdup_printf("::ffff:%02hhx%02hhx:%02hhx%02hhx", ipv4[0], ipv4[1], ipv4[2], ipv4[3]); + + return ret; +} + +gchar * +gaim_network_convert_ipv6_to_string(void *ip) +{ + gchar *ret; + + //ret = g_strdup_printf("%02hhx%02hhx:%02hhx%02hhx:%02hhx%02hhx:%02hhx%02hhx:%02hhx%02hhx:%02hhx%02hhx:%02hhx%02hhx:%02hhx%02hhx", ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]); + ret = g_malloc0(INET6_ADDRSTRLEN + 1); + inet_ntop(AF_INET6, ip, ret, sizeof(ret)); + + return ret; +} +*/ + +static gboolean rendezvous_find_buddy_by_ip(gpointer key, gpointer value, gpointer user_data) +{ + RendezvousBuddy *rb = value; + +printf("looking at ip=%s\n", rb->ip); + if ((rb->ip != NULL) && !strcasecmp(rb->ip, user_data)) + return TRUE; + + return FALSE; +} + +void rendezvous_direct_acceptconnection(gpointer data, gint source, GaimInputCondition condition) +{ + GaimConnection *gc = (GaimConnection *)data; + RendezvousData *rd = gc->proto_data; + int fd; + struct sockaddr_in6 addr; + socklen_t addrlen = sizeof(addr); + gchar *ip; + RendezvousBuddy *rb; + + fd = accept(rd->listener, (struct sockaddr *)&addr, &addrlen); + if (fd == -1) { + gaim_debug_warning("rendezvous", "accept: %s\n", strerror(errno)); + return; + } +/* + printf("\nsa_family=%d\n\n", ((struct sockaddr *)&addr)->sa_family); + if (((struct sockaddr *)&addr)->sa_family == AF_INET) + ip = gaim_network_convert_ipv4_to_string((unsigned char *)&ip); + else if (((struct sockaddr *)&addr)->sa_family == AF_INET6) + ip = gaim_network_convert_ipv6_to_string((unsigned char *)&(addr.sin6_addr)); + printf("\nip=%s\n", ip); + + rb = g_hash_table_find(rd->buddies, rendezvous_find_buddy_by_ip, ip); + g_free(ip); +*/ + if (rb == NULL) { + /* We don't want to talk to people that don't advertise themselves */ +printf("\ndid not find rb\n\n"); + close(fd); + return; + } +printf("\nip belongs to=%s\n\n", rb->aim); + + rb->fd = fd; + +} diff -r 61852117568f -r 782c1b564906 src/protocols/rendezvous/direct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/rendezvous/direct.h Sun Dec 05 21:25:44 2004 +0000 @@ -0,0 +1,34 @@ +/** + * @file direct.h Code to handle rendezvous direct connection. This + * is basically a mini Jabber implementation. + * + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _DIRECT_H_ +#define _DIRECT_H_ + +#include "eventloop.h" + +void rendezvous_direct_acceptconnection(gpointer data, gint source, GaimInputCondition condition); + +#endif /* _DIRECT_H_ */ diff -r 61852117568f -r 782c1b564906 src/protocols/rendezvous/mdns.c --- a/src/protocols/rendezvous/mdns.c Sun Dec 05 21:05:52 2004 +0000 +++ b/src/protocols/rendezvous/mdns.c Sun Dec 05 21:25:44 2004 +0000 @@ -174,6 +174,7 @@ /* Functions for duplicating a DNS structure */ /**********************************************/ +#if 0 static Question * mdns_copy_q(const Question *q) { @@ -204,6 +205,7 @@ return ret; } +#endif static void * mdns_copy_rr_rdata_txt(const ResourceRecordRDataTXT *rdata) @@ -275,6 +277,7 @@ return ret; } +#if 0 ResourceRecord * mdns_copy_rr(const ResourceRecord *rr) { @@ -331,6 +334,7 @@ return ret; } +#endif /******************************************/ /* Functions for connection establishment */ @@ -1383,7 +1387,6 @@ /** * If invalid data is encountered at any point when parsing data * then the entire packet is discarded and NULL is returned. - * */ DNSPacket * mdns_read(int fd) diff -r 61852117568f -r 782c1b564906 src/protocols/rendezvous/rendezvous.c --- a/src/protocols/rendezvous/rendezvous.c Sun Dec 05 21:05:52 2004 +0000 +++ b/src/protocols/rendezvous/rendezvous.c Sun Dec 05 21:25:44 2004 +0000 @@ -29,19 +29,26 @@ #include "network.h" #include "prpl.h" #include "sha.h" -#include "util.h" #include "version.h" +#include "direct.h" +#include "mdns.h" #include "rendezvous.h" -#include "mdns.h" +#include "util.h" /****************************/ /* Utility Functions */ /****************************/ -static void rendezvous_buddy_free(gpointer data) +static void +rendezvous_buddy_free(gpointer data) { RendezvousBuddy *rb = data; + if (rb->fd >= 0) + close(rb->fd); + if (rb->watcher >= 0) + gaim_input_remove(rb->watcher); + g_free(rb->firstandlast); g_free(rb->msg); g_free(rb); @@ -57,11 +64,12 @@ * the given domain. This string should be g_free'd * when no longer needed. */ -static gchar *rendezvous_extract_name(gchar *domain) +static gchar * +rendezvous_extract_name(gchar *domain) { gchar *ret, *suffix; - if (!g_str_has_suffix(domain, "._presence._tcp.local")) + if (!gaim_str_has_suffix(domain, "._presence._tcp.local")) return NULL; suffix = strstr(domain, "._presence._tcp.local"); @@ -74,7 +82,8 @@ /* Buddy List Functions */ /****************************/ -static void rendezvous_addtolocal(GaimConnection *gc, const char *name, const char *domain) +static void +rendezvous_addtolocal(GaimConnection *gc, const char *name, const char *domain) { GaimAccount *account = gaim_connection_get_account(gc); GaimBuddy *b; @@ -109,7 +118,8 @@ #endif } -static void rendezvous_removefromlocal(GaimConnection *gc, const char *name, const char *domain) +static void +rendezvous_removefromlocal(GaimConnection *gc, const char *name, const char *domain) { GaimAccount *account = gaim_connection_get_account(gc); GaimBuddy *b; @@ -134,7 +144,8 @@ */ } -static void rendezvous_removeallfromlocal(GaimConnection *gc) +static void +rendezvous_removeallfromlocal(GaimConnection *gc) { GaimAccount *account = gaim_connection_get_account(gc); GaimBuddyList *blist; @@ -163,7 +174,8 @@ } } -static void rendezvous_handle_rr_a(GaimConnection *gc, ResourceRecord *rr, const gchar *name) +static void +rendezvous_handle_rr_a(GaimConnection *gc, ResourceRecord *rr, const gchar *name) { RendezvousData *rd = gc->proto_data; RendezvousBuddy *rb; @@ -177,12 +189,11 @@ g_hash_table_insert(rd->buddies, g_strdup(name), rb); } -#if 0 - memcpy(rb->ip, rdata, 4); -#endif + /* rb->ipv4 = gaim_network_convert_ipv4_to_string((unsigned char *)rdata); */ } -static void rendezvous_handle_rr_txt(GaimConnection *gc, ResourceRecord *rr, const gchar *name) +static void +rendezvous_handle_rr_txt(GaimConnection *gc, ResourceRecord *rr, const gchar *name) { RendezvousData *rd = gc->proto_data; GaimAccount *account = gaim_connection_get_account(gc); @@ -258,7 +269,26 @@ } } -static void rendezvous_handle_rr_srv(GaimConnection *gc, ResourceRecord *rr, const gchar *name) +static void +rendezvous_handle_rr_aaaa(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); + } + + /* rb->ip = gaim_network_convert_ipv6_to_string((unsigned char *)rdata); */ +} + +static void +rendezvous_handle_rr_srv(GaimConnection *gc, ResourceRecord *rr, const gchar *name) { RendezvousData *rd = gc->proto_data; RendezvousBuddy *rb; @@ -278,12 +308,13 @@ /* * Parse a resource record and do stuff if we need to. */ -static void rendezvous_handle_rr(GaimConnection *gc, ResourceRecord *rr) +static void +rendezvous_handle_rr(GaimConnection *gc, ResourceRecord *rr) { RendezvousData *rd = gc->proto_data; gchar *name; - gaim_debug_misc("rendezvous", "Parsing resource record with domain name %s\n", rr->name); + gaim_debug_misc("rendezvous", "Parsing resource record with domain name %s and type %d\n", rr->name, rr->type); switch (rr->type) { case RENDEZVOUS_RRTYPE_A: { @@ -331,6 +362,14 @@ } } break; + case RENDEZVOUS_RRTYPE_AAAA: { + name = rendezvous_extract_name(rr->name); + if (name != NULL) { + rendezvous_handle_rr_aaaa(gc, rr, name); + g_free(name); + } + } break; + case RENDEZVOUS_RRTYPE_SRV: { name = rendezvous_extract_name(rr->name); if (name != NULL) { @@ -344,12 +383,14 @@ /****************************/ /* Icon and Emblem Functions */ /****************************/ -static const char* rendezvous_prpl_list_icon(GaimAccount *a, GaimBuddy *b) +static const char * +rendezvous_prpl_list_icon(GaimAccount *a, GaimBuddy *b) { return "rendezvous"; } -static void rendezvous_prpl_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) +static void +rendezvous_prpl_list_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) { if (GAIM_BUDDY_IS_ONLINE(b)) { if (b->uc & UC_UNAVAILABLE) @@ -359,7 +400,8 @@ } } -static gchar *rendezvous_prpl_status_text(GaimBuddy *b) +static gchar * +rendezvous_prpl_status_text(GaimBuddy *b) { GaimConnection *gc = b->account->gc; RendezvousData *rd = gc->proto_data; @@ -375,7 +417,8 @@ return ret; } -static gchar *rendezvous_prpl_tooltip_text(GaimBuddy *b) +static gchar * +rendezvous_prpl_tooltip_text(GaimBuddy *b) { GaimConnection *gc = b->account->gc; RendezvousData *rd = gc->proto_data; @@ -404,7 +447,8 @@ /****************************/ /* Connection Functions */ /****************************/ -static void rendezvous_callback(gpointer data, gint source, GaimInputCondition condition) +static void +rendezvous_callback(gpointer data, gint source, GaimInputCondition condition) { GaimConnection *gc = data; RendezvousData *rd = gc->proto_data; @@ -428,7 +472,8 @@ mdns_free(dns); } -static void rendezvous_add_to_txt(RendezvousData *rd, const char *name, const char *value) +static void +rendezvous_add_to_txt(RendezvousData *rd, const char *name, const char *value) { ResourceRecordRDataTXTNode *node; node = g_malloc(sizeof(ResourceRecordRDataTXTNode)); @@ -437,7 +482,8 @@ rd->mytxtdata = g_slist_append(rd->mytxtdata, node); } -static guchar *rendezvous_read_icon_data(const char *filename, unsigned short *length) +static guchar * +rendezvous_read_icon_data(const char *filename, unsigned short *length) { struct stat st; FILE *file; @@ -461,7 +507,8 @@ return data; } -static void rendezvous_add_to_txt_iconhash(RendezvousData *rd, const char *iconfile) +static void +rendezvous_add_to_txt_iconhash(RendezvousData *rd, const char *iconfile) { guchar *icondata; unsigned short iconlength; @@ -482,7 +529,8 @@ g_free(base16); } -static void rendezvous_send_icon(GaimConnection *gc) +static void +rendezvous_send_icon(GaimConnection *gc) { RendezvousData *rd = gc->proto_data; GaimAccount *account = gaim_connection_get_account(gc); @@ -503,26 +551,28 @@ g_free(rdata); } -static void rendezvous_send_online(GaimConnection *gc) +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[4]; + gchar *myname, *mycomp, *myport; + unsigned char myipv4[4]; 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 = gaim_network_ip_atoi(gaim_network_get_local_system_ip(-1)); */ - myip[0] = 192; - myip[1] = 168; - myip[2] = 1; - myip[3] = 41; + /* myipv4 = gaim_network_ip_atoi(gaim_network_get_local_system_ip(-1)); */ + myipv4[0] = 192; + myipv4[1] = 168; + myipv4[2] = 1; + myipv4[3] = 41; + myport = g_strdup_printf("%d", rd->listener_port); - mdns_advertise_a(rd->fd, mycomp, myip); + mdns_advertise_a(rd->fd, mycomp, myipv4); mdns_advertise_ptr(rd->fd, "_presence._tcp.local", myname); - mdns_advertise_srv(rd->fd, myname, 5298, mycomp); + mdns_advertise_srv(rd->fd, myname, rd->listener_port, mycomp); rendezvous_add_to_txt(rd, "txtvers", "1"); rendezvous_add_to_txt(rd, "status", "avail"); @@ -543,7 +593,7 @@ } rendezvous_add_to_txt(rd, "version", "1"); rendezvous_add_to_txt(rd, "msg", "Groovin'"); - rendezvous_add_to_txt(rd, "port.p2pj", "5298"); + rendezvous_add_to_txt(rd, "port.p2pj", myport); rendezvous_add_to_txt(rd, "last", gaim_account_get_string(account, "last", _("User"))); mdns_advertise_txt(rd->fd, myname, rd->mytxtdata); @@ -551,9 +601,11 @@ g_free(myname); g_free(mycomp); + g_free(myport); } -static void rendezvous_prpl_login(GaimAccount *account) +static void +rendezvous_prpl_login(GaimAccount *account) { GaimConnection *gc = gaim_account_get_connection(account); RendezvousData *rd; @@ -565,10 +617,18 @@ gaim_connection_update_progress(gc, _("Preparing Buddy List"), 0, RENDEZVOUS_CONNECT_STEPS); rendezvous_removeallfromlocal(gc); + rd->listener = gaim_network_listen_range(5298, 5308); + if (rd->listener == -1) { + gaim_connection_error(gc, _("Unable to establish listening port.")); + return; + } + rd->listener_watcher = gaim_input_add(rd->listener, GAIM_INPUT_READ, rendezvous_direct_acceptconnection, gc); + rd->listener_port = gaim_network_get_port_from_fd(rd->listener); + gaim_connection_update_progress(gc, _("Connecting"), 1, RENDEZVOUS_CONNECT_STEPS); rd->fd = mdns_socket_establish(); if (rd->fd == -1) { - gaim_connection_error(gc, _("Unable to login to rendezvous")); + gaim_connection_error(gc, _("Unable to establish mDNS socket.")); return; } @@ -579,7 +639,8 @@ rendezvous_send_online(gc); } -static void rendezvous_prpl_close(GaimConnection *gc) +static void +rendezvous_prpl_close(GaimConnection *gc) { RendezvousData *rd = (RendezvousData *)gc->proto_data; ResourceRecordRDataTXTNode *node; @@ -589,11 +650,17 @@ rendezvous_removeallfromlocal(gc); - if (!rd) + if (rd == NULL) return; mdns_socket_close(rd->fd); + if (rd->listener >= 0) + close(rd->listener); + + if (rd->listener_watcher != 0) + gaim_input_remove(rd->listener_watcher); + g_hash_table_destroy(rd->buddies); while (rd->mytxtdata != NULL) { @@ -607,13 +674,20 @@ g_free(rd); } -static int rendezvous_prpl_send_im(GaimConnection *gc, const char *who, const char *message, GaimConvImFlags flags) +static int +rendezvous_prpl_send_im(GaimConnection *gc, const char *who, const char *message, GaimConvImFlags flags) { gaim_debug_info("rendezvous", "Sending IM\n"); return 1; } +static void +rendezvous_prpl_set_status(GaimAccount *account, GaimStatus *status) +{ + gaim_debug_error("rendezvous", "Set status to %s\n", gaim_status_get_name(status)); +} + static GaimPlugin *my_protocol = NULL; static GaimPluginProtocolInfo prpl_info; @@ -669,6 +743,7 @@ prpl_info.login = rendezvous_prpl_login; prpl_info.close = rendezvous_prpl_close; prpl_info.send_im = rendezvous_prpl_send_im; + prpl_info.set_status = rendezvous_prpl_set_status; if (gethostname(hostname, 255) != 0) { gaim_debug_warning("rendezvous", "Error %d when getting host name. Using \"localhost.\"\n", errno); diff -r 61852117568f -r 782c1b564906 src/protocols/rendezvous/rendezvous.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/protocols/rendezvous/rendezvous.h Sun Dec 05 21:25:44 2004 +0000 @@ -0,0 +1,64 @@ +/** + * @file rendezvous.h The Gaim interface to mDNS and peer to peer Jabber. + * + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _RENDEZVOUS_H_ +#define _RENDEZVOUS_H_ + +#include "internal.h" +#include "debug.h" + +#include "mdns.h" + +#define RENDEZVOUS_CONNECT_STEPS 2 + +#define UC_UNAVAILABLE 1 +#define UC_IDLE 2 + +typedef struct _RendezvousData { + int fd; + GHashTable *buddies; + GSList *mytxtdata; + unsigned short listener_port; + int listener; + int listener_watcher; +} RendezvousData; + +typedef struct _RendezvousBuddy { +#if 0 + guint ttltimer; +#endif + gchar *firstandlast; + gchar *aim; + gchar *ipv4; /* String representation of an IPv4 address */ + gchar *ipv6; /* String representation of an IPv6 address */ + unsigned short p2pjport; + int status; + int idle; /**< Current idle time in seconds since the epoch. */ + gchar *msg; /**< Current status message of this buddy. */ + int fd; /**< File descriptor of the P2PJ socket. */ + int watcher; /**< Handle for the watcher of the P2PJ socket. */ +} RendezvousBuddy; + +#endif /* _RENDEZVOUS_H_ */