Fix the segfault when quitting in IBB and various other bugs.
authorNicolas Cornu <nicolas.cornu@ensi-bourges.fr>
Wed, 25 Aug 2010 17:15:49 +0200
changeset 159 1df5f5e3f1e7
parent 158 a068e5714120
child 160 e149e868d501
Fix the segfault when quitting in IBB and various other bugs. Add various things in S5B. Session negociation/candidate exchange should now be working.
jingle-ft/filetransfer.c
jingle-ibb/ibb.c
jingle-s5b/socks5.c
jingle/jingle.c
jingle/send.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);
 }
--- 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");