Fix the segfault when quitting in IBB and various other bugs.
Add various things in S5B. Session negociation/candidate exchange
should now be working.
--- 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);
}
--- 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);
--- 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);
}
--- 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 <mcabber/logprint.h>
#include <mcabber/xmpp_helper.h>
#include <mcabber/events.h>
+#include <mcabber/caps.h>
#include <jingle/jingle.h>
#include <jingle/check.h>
@@ -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;
--- 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");