# HG changeset patch # User Nicolas Cornu # Date 1282749349 -7200 # Node ID 1df5f5e3f1e7f3129ec658c0a09ca64883001b6c # Parent a068e57141203d451d41bdb7030c2a187d03456f Fix the segfault when quitting in IBB and various other bugs. Add various things in S5B. Session negociation/candidate exchange should now be working. diff -r a068e5714120 -r 1df5f5e3f1e7 jingle-ft/filetransfer.c --- a/jingle-ft/filetransfer.c Wed Aug 25 01:27:46 2010 +0200 +++ b/jingle-ft/filetransfer.c Wed Aug 25 17:15:49 2010 +0200 @@ -447,8 +447,8 @@ } ressource = jingle_find_compatible_res(CURRENT_JID, namespaces); if (ressource == NULL) { - scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: Cannot send file," - " because there is no ressource available"); + scr_LogPrint(LPRINT_LOGNORM, "Jingle File Transfer: Cannot send file, because this buddy" + " has no compatible ressource available"); return; } @@ -476,7 +476,7 @@ else if (!g_strcmp0(args[0], "flush")) _jft_flush(args); else - scr_LogPrint(LPRINT_LOGNORM, "/jft: %s is not a correct option.", args[1]); + scr_LogPrint(LPRINT_LOGNORM, "/jft: %s is not a correct option.", args[0]); free_arg_lst(args); } diff -r a068e5714120 -r 1df5f5e3f1e7 jingle-ibb/ibb.c --- a/jingle-ibb/ibb.c Wed Aug 25 01:27:46 2010 +0200 +++ b/jingle-ibb/ibb.c Wed Aug 25 17:15:49 2010 +0200 @@ -419,6 +419,8 @@ static void jingle_ibb_uninit(void) { lm_message_handler_invalidate(jingle_ibb_handler); + hk_del_handler(HOOK_POST_CONNECT, connect_hid); + hk_del_handler(HOOK_PRE_DISCONNECT, disconn_hid); lm_message_handler_unref(jingle_ibb_handler); xmpp_del_feature(NS_JINGLE_TRANSPORT_IBB); jingle_unregister_transport(NS_JINGLE_TRANSPORT_IBB); diff -r a068e5714120 -r 1df5f5e3f1e7 jingle-s5b/socks5.c --- a/jingle-s5b/socks5.c Wed Aug 25 01:27:46 2010 +0200 +++ b/jingle-s5b/socks5.c Wed Aug 25 17:15:49 2010 +0200 @@ -100,12 +100,12 @@ typedef struct { GInetAddress *address; guint32 priority; -} LocalCandidate; +} LocalIP; /** * @brief Linked list of candidates to send on session-initiate */ -static GSList *local_candidates = NULL; +static GSList *local_ips = NULL; static gint index_in_array(const gchar *str, const gchar **array) @@ -138,7 +138,7 @@ static GSList *parse_candidates(LmMessageNode *node) { LmMessageNode *node2; - GSList *list; + GSList *list = NULL; for (node2 = node->children; node2; node2 = node2->next) { if (g_strcmp0(node->name, "candidate")) @@ -171,10 +171,57 @@ return list; } +static GSList *get_our_candidates(guint16 port) +{ + GSList *our_candidates = NULL, *entry; + + for (entry = local_ips; entry; entry = entry->next) { + LocalIP *lcand = (LocalIP *)entry->data; + S5BCandidate *cand = g_new0(S5BCandidate, 1); + cand->cid = gen_random_cid(); + cand->host = g_inet_address_to_string(lcand->address); + cand->jid = g_strdup(lm_connection_get_jid(lconnection)); + cand->port = port; + cand->priority = lcand->priority; + + our_candidates = g_slist_prepend(our_candidates, cand); + } + our_candidates = g_slist_sort(our_candidates, prioritycmp); + return our_candidates; +} + +/** + * @brief Get a port number by settings or randomly + * @return A guint16 containing the port number + * */ +static guint16 get_port(void) +{ + // TODO: find a way to make sure the port is not already used + guint64 portstart, portend; + guint16 port; + const gchar *port_range = settings_opt_get("jingle_s5b_portrange"); + + if (port_range != NULL) { + sscanf(port_range, "%" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT, &portstart, &portend); + + if ((portstart >= 1024 && portstart <= (guint16)~0) && + (portend >= 1024 && portend <= (guint16)~0) && portstart <= portend) { + port = g_random_int_range(portstart, portend); + } else { + scr_LogPrint(LPRINT_LOGNORM, "Jingle S5B: Invalid port range specified"); + port = g_random_int_range(1024, (guint16)~0); + } + } else { + port = g_random_int_range(1024, (guint16)~0); + } + + return port; +} + static gconstpointer newfrommessage(JingleContent *cn, GError **err) { JingleS5B *js5b; - LmMessageNode *node = cn->transport, *node2; + LmMessageNode *node = cn->transport; const gchar *modestr; js5b = g_new0(JingleS5B, 1); @@ -190,6 +237,7 @@ } js5b->candidates = parse_candidates(node); + js5b->ourcandidates = get_our_candidates(get_port()); return (gconstpointer) js5b; } @@ -197,27 +245,16 @@ static gconstpointer new(void) { JingleS5B *js5b = g_new0(JingleS5B, 1); - GSList *entry; - gint port; + js5b->mode = JINGLE_S5B_TCP; js5b->sid = gen_random_sid(); - port = settings_opt_get_int("jingle_s5b_dir"); - if (port < 1024 && port > (guint16)~0) { - port = g_random_int_range(1024, (guint16)~0); - } + // the user can manually specify a port range to use in for format: + // portstart-portend - for (entry = local_candidates; entry; entry = entry->next) { - LocalCandidate *lcand = (LocalCandidate *)entry->data; - S5BCandidate *cand = g_new0(S5BCandidate, 1); - cand->cid = gen_random_cid(); - cand->host = g_inet_address_to_string(lcand->address); - cand->jid = g_strdup(lm_connection_get_jid(lconnection)); - cand->port = port; - cand->priority = lcand->priority; - js5b->ourcandidates = g_slist_prepend(js5b->ourcandidates, cand); - } + js5b->ourcandidates = get_our_candidates(get_port()); + return js5b; } @@ -338,7 +375,7 @@ * @brief Discover all IPs of this computer * @return A linked list of GInetAddress */ -static GSList *get_all_local_ips() { +static GSList *get_all_local_ips(void) { GSList *addresses = NULL; GInetAddress *thisaddr; GSocketFamily family; @@ -347,7 +384,7 @@ struct sockaddr_in6 *native6; const guint8 *addrdata; guint16 ifacecounter = 0; // for lack of a better method - LocalCandidate *candidate; + LocalIP *candidate; gint rval = getifaddrs(&first); if (!rval) @@ -375,7 +412,7 @@ }/* else if (g_inset_address_get_is_site_local(thisaddr)) { // TODO: should we offer a way to filter the offer of LAN ips ? } */ - candidate = g_new0(LocalCandidate, 1); + candidate = g_new0(LocalIP, 1); candidate->address = thisaddr; candidate->priority = (1<<16)*126+ifacecounter; addresses = g_slist_prepend(addresses, candidate); @@ -409,6 +446,11 @@ return random_str(7); } +static void free_localip(LocalIP *l) { + g_object_unref(l->address); + g_free(l); +} + static void jingle_socks5_init(void) { g_type_init(); @@ -416,12 +458,13 @@ JINGLE_TRANSPORT_STREAMING, JINGLE_TRANSPORT_PRIO_HIGH); xmpp_add_feature(NS_JINGLE_TRANSPORT_SOCKS5); - local_candidates = get_all_local_ips(); + local_ips = get_all_local_ips(); } static void jingle_socks5_uninit(void) { xmpp_del_feature(NS_JINGLE_TRANSPORT_SOCKS5); jingle_unregister_transport(NS_JINGLE_TRANSPORT_SOCKS5); - g_slist_foreach(local_candidates, (GFunc)g_object_unref, NULL); + g_slist_foreach(local_ips, (GFunc)free_localip, NULL); + g_slist_free(local_ips); } diff -r a068e5714120 -r 1df5f5e3f1e7 jingle/jingle.c --- a/jingle/jingle.c Wed Aug 25 01:27:46 2010 +0200 +++ b/jingle/jingle.c Wed Aug 25 17:15:49 2010 +0200 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -356,8 +357,9 @@ for (thisres = reslist; thisres; thisres = g_slist_next(thisres)) { found = TRUE; for (indexns = 0; ns[indexns]; indexns++) { - // if (!caps_has_feature(buddy_resource_getcaps(roster_usr->data, thisres->data), ns[indexns])) - // found = FALSE; + gchar *tmp = buddy_resource_getcaps(roster_usr->data, thisres->data); + if (!caps_has_feature(tmp, (gchar *)ns[indexns])) + found = FALSE; } if (!found) continue; diff -r a068e5714120 -r 1df5f5e3f1e7 jingle/send.c --- a/jingle/send.c Wed Aug 25 01:27:46 2010 +0200 +++ b/jingle/send.c Wed Aug 25 17:15:49 2010 +0200 @@ -125,7 +125,7 @@ } if (lm_message_get_sub_type(mess) == LM_MESSAGE_SUB_TYPE_RESULT) - return; + return; // TODO: put a timeout on the session-accept if (lm_message_get_sub_type(mess) == LM_MESSAGE_SUB_TYPE_ERROR) { node = lm_message_get_node(mess); node = lm_message_node_get_child(node,"error");