jingle-s5b/socks5.c
changeset 157 8ec7ce3ecaac
parent 156 653fa009fea3
child 158 a068e5714120
equal deleted inserted replaced
156:653fa009fea3 157:8ec7ce3ecaac
    31 
    31 
    32 #include <mcabber/xmpp.h>
    32 #include <mcabber/xmpp.h>
    33 #include <mcabber/modules.h>
    33 #include <mcabber/modules.h>
    34 #include <mcabber/utils.h>
    34 #include <mcabber/utils.h>
    35 #include <mcabber/xmpp_helper.h>
    35 #include <mcabber/xmpp_helper.h>
       
    36 #include <mcabber/settings.h>
    36 #include <mcabber/logprint.h>
    37 #include <mcabber/logprint.h>
    37 #include <mcabber/hooks.h>
    38 #include <mcabber/hooks.h>
    38 
    39 
    39 #include <jingle/jingle.h>
    40 #include <jingle/jingle.h>
    40 #include <jingle/check.h>
    41 #include <jingle/check.h>
    41 #include <jingle/register.h>
    42 #include <jingle/register.h>
    42 
    43 
    43 #include "socks5.h"
    44 #include "socks5.h"
    44 
    45 
    45 static gconstpointer newfrommessage(JingleContent *cn, GError **err);
    46 static gconstpointer newfrommessage(JingleContent *cn, GError **err);
       
    47 static JingleHandleStatus handle(JingleAction action, gconstpointer data,
       
    48                                  LmMessageNode *node, GError **err);
    46 static void tomessage(gconstpointer data, LmMessageNode *node);
    49 static void tomessage(gconstpointer data, LmMessageNode *node);
       
    50 static gconstpointer new(void);
    47 // static void _send(session_content *sc, gconstpointer data, gchar *buf, gsize size);
    51 // static void _send(session_content *sc, gconstpointer data, gchar *buf, gsize size);
    48 static void init(session_content *sc);
    52 static void init(session_content *sc);
    49 static void end(session_content *sc, gconstpointer data);
    53 static void end(session_content *sc, gconstpointer data);
    50 
    54 
    51 static void handle_sock_io(GSocket *sock, GIOCondition cond, gpointer data);
    55 static void handle_sock_io(GSocket *sock, GIOCondition cond, gpointer data);
    52 static GSList *get_all_local_ips();
    56 static GSList *get_all_local_ips();
       
    57 static gchar *gen_random_cid(void);
    53 static void jingle_socks5_init(void);
    58 static void jingle_socks5_init(void);
    54 static void jingle_socks5_uninit(void);
    59 static void jingle_socks5_uninit(void);
    55 
    60 
    56 
    61 
    57 const gchar *deps[] = { "jingle", NULL };
    62 const gchar *deps[] = { "jingle", NULL };
    58 
    63 
    59 static JingleTransportFuncs funcs = {
    64 static JingleTransportFuncs funcs = {
    60   .newfrommessage = newfrommessage,
    65   .newfrommessage = newfrommessage,
       
    66   .handle         = handle,
    61   .tomessage      = tomessage,
    67   .tomessage      = tomessage,
    62   .new            = NULL,
    68   .new            = new,
    63   .send           = NULL,
    69   .send           = NULL,
    64   .init           = init,
    70   .init           = init,
    65   .end            = end
    71   .end            = end
    66 };
    72 };
    67 
    73 
    88   "tcp",
    94   "tcp",
    89   "udp",
    95   "udp",
    90   NULL
    96   NULL
    91 };
    97 };
    92 
    98 
       
    99 typedef struct {
       
   100   GInetAddress *address;
       
   101   guint32       priority;
       
   102 } LocalCandidate;
       
   103 
    93 /**
   104 /**
    94  * @brief Linked list of candidates to send on session-initiate
   105  * @brief Linked list of candidates to send on session-initiate
    95  */
   106  */
    96 GSList *local_candidates = NULL;
   107 static GSList *local_candidates = NULL;
    97 
   108 
    98 
   109 
    99 static gint index_in_array(const gchar *str, const gchar **array)
   110 static gint index_in_array(const gchar *str, const gchar **array)
   100 {
   111 {
   101   gint i;
   112   gint i;
   165     }
   176     }
   166     js5b->candidates = g_slist_sort(js5b->candidates, prioritycmp);
   177     js5b->candidates = g_slist_sort(js5b->candidates, prioritycmp);
   167   }
   178   }
   168 
   179 
   169   return (gconstpointer) js5b;
   180   return (gconstpointer) js5b;
       
   181 }
       
   182 
       
   183 static gconstpointer new(void)
       
   184 {
       
   185   JingleS5B *js5b = g_new0(JingleS5B, 1);
       
   186   GSList *entry;
       
   187   gint port = settings_opt_get_int("jingle_s5b_dir");
       
   188   if (port < 1024 && port > (guint16)~0) {
       
   189     port = g_random_int_range(1024, (guint16)~0);
       
   190   }
       
   191   
       
   192   for (entry = local_candidates; entry; entry = entry->next) {
       
   193     LocalCandidate *lcand = (LocalCandidate *)entry->data;
       
   194     S5BCandidate *cand = g_new0(S5BCandidate, 1);
       
   195     cand->cid      = gen_random_cid();
       
   196     cand->host     = g_inet_address_to_string(lcand->address);
       
   197     cand->jid      = g_strdup(lm_connection_get_jid(lconnection));
       
   198     cand->port     = port;
       
   199     cand->priority = lcand->priority;
       
   200 
       
   201     js5b->candidates = g_slist_prepend(js5b->candidates, cand);
       
   202   }
       
   203   return js5b;
       
   204 }
       
   205 
       
   206 static JingleHandleStatus handle(JingleAction action, gconstpointer data,
       
   207                                  LmMessageNode *node, GError **err)
       
   208 {
       
   209   if (action == JINGLE_SESSION_ACCEPT) {
       
   210     return JINGLE_STATUS_HANDLED;
       
   211   }
       
   212   return JINGLE_STATUS_NOT_HANDLED;
   170 }
   213 }
   171 
   214 
   172 static void tomessage(gconstpointer data, LmMessageNode *node)
   215 static void tomessage(gconstpointer data, LmMessageNode *node)
   173 {
   216 {
   174   JingleS5B *js5 = (JingleS5B *)data;
   217   JingleS5B *js5 = (JingleS5B *)data;
   238     return;
   281     return;
   239   }
   282   }
   240 
   283 
   241 }
   284 }
   242 
   285 
       
   286 static void end(session_content *sc, gconstpointer data) {
       
   287   return;
       
   288 }
       
   289 
   243 /**
   290 /**
   244  * Handle any event on a sock
   291  * Handle any event on a sock
   245  */
   292  */
   246 static void handle_sock_io(GSocket *sock, GIOCondition cond, gpointer data)
   293 static void handle_sock_io(GSocket *sock, GIOCondition cond, gpointer data)
   247 {
   294 {
   270   GSocketFamily family;
   317   GSocketFamily family;
   271   struct ifaddrs *first, *ifaddr;
   318   struct ifaddrs *first, *ifaddr;
   272   struct sockaddr_in *native;
   319   struct sockaddr_in *native;
   273   struct sockaddr_in6 *native6;
   320   struct sockaddr_in6 *native6;
   274   const guint8 *addrdata;
   321   const guint8 *addrdata;
   275   int rval;
   322   guint16 ifacecounter = 0; // for lack of a better method
   276 
   323   LocalCandidate *candidate;
   277   rval = getifaddrs(&first);
   324 
       
   325   gint rval = getifaddrs(&first);
       
   326   if (!rval)
       
   327     return NULL;
   278 
   328 
   279   for (ifaddr = first; ifaddr; ifaddr = ifaddr->ifa_next) {
   329   for (ifaddr = first; ifaddr; ifaddr = ifaddr->ifa_next) {
   280     if (!(ifaddr->ifa_flags & IFF_UP) || ifaddr->ifa_flags & IFF_LOOPBACK)
   330     if (!(ifaddr->ifa_flags & IFF_UP) || ifaddr->ifa_flags & IFF_LOOPBACK)
   281       continue;
   331       continue;
   282 
   332 
   296       g_object_unref(thisaddr);
   346       g_object_unref(thisaddr);
   297       continue;
   347       continue;
   298     }/* else if (g_inset_address_get_is_site_local(thisaddr)) {
   348     }/* else if (g_inset_address_get_is_site_local(thisaddr)) {
   299       // TODO: should we offer a way to filter the offer of LAN ips ?
   349       // TODO: should we offer a way to filter the offer of LAN ips ?
   300     } */
   350     } */
   301     addresses = g_slist_prepend(addresses, thisaddr);
   351     candidate = g_new0(LocalCandidate, 1);
   302   }
   352     candidate->address  = thisaddr;
       
   353     candidate->priority = (1<<16)*126+ifacecounter;
       
   354     addresses = g_slist_prepend(addresses, candidate);
       
   355     ++ifacecounter;
       
   356   }
       
   357   freeifaddrs(first);
       
   358 
   303   return addresses;
   359   return addresses;
       
   360 }
       
   361 
       
   362 static gchar *gen_random_cid(void)
       
   363 {
       
   364   gchar *sid;
       
   365   gchar car[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
       
   366   int i;
       
   367   sid = g_new0(gchar, 8);
       
   368   for (i = 0; i < 6; i++)
       
   369     sid[i] = car[g_random_int_range(0, sizeof(car)/sizeof(car[0]))];
       
   370 
       
   371   sid[6] = '\0';
       
   372   return sid;
   304 }
   373 }
   305 
   374 
   306 static void jingle_socks5_init(void)
   375 static void jingle_socks5_init(void)
   307 {
   376 {
   308   g_type_init();
   377   g_type_init();