gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r19425 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r19425 - gnunet/src/transport
Date: Thu, 26 Jan 2012 12:01:28 +0100

Author: wachs
Date: 2012-01-26 12:01:28 +0100 (Thu, 26 Jan 2012)
New Revision: 19425

Modified:
   gnunet/src/transport/plugin_transport_http.c
   gnunet/src/transport/plugin_transport_tcp.c
Log:
- new get_session functions


Modified: gnunet/src/transport/plugin_transport_http.c
===================================================================
--- gnunet/src/transport/plugin_transport_http.c        2012-01-26 10:18:23 UTC 
(rev 19424)
+++ gnunet/src/transport/plugin_transport_http.c        2012-01-26 11:01:28 UTC 
(rev 19425)
@@ -386,7 +386,7 @@
 }
 
 struct Session *
-lookup_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity 
*target,
+lookup_session_old (struct Plugin *plugin, const struct GNUNET_PeerIdentity 
*target,
                 struct Session *session, const void *addr, size_t addrlen,
                 int force_address)
 {
@@ -462,6 +462,29 @@
   return s;
 }
 
+struct Session *
+lookup_session (struct Plugin *plugin,
+                const struct GNUNET_HELLO_Address *address)
+{
+  struct Session *tmp = NULL;
+
+  tmp = plugin->head;
+  if (tmp == NULL)
+    return NULL;
+  while (tmp != NULL)
+  {
+    if (0 != memcmp (&address->peer, &tmp->target, sizeof (struct 
GNUNET_PeerIdentity)))
+      continue;
+    if ((address->address_length != tmp->addrlen) &&
+        (0 != memcmp (address->address, tmp->addr, tmp->addrlen)))
+      continue;
+
+    return tmp;
+  }
+  return NULL;
+}
+
+
 void
 delete_session (struct Session *s)
 {
@@ -508,7 +531,102 @@
   delete_session (s);
 }
 
+/**
+ * Creates a new session the transport service will use to send data to the
+ * peer
+ *
+ * @param cls the plugin
+ * @param address the address
+ * @return the session or NULL of max connections exceeded
+ */
 
+static const struct Session *
+http_get_session (void *cls,
+                  const struct GNUNET_HELLO_Address *address)
+{
+  struct Plugin *plugin = cls;
+  struct Session * s = NULL;
+  struct GNUNET_ATS_Information ats;
+  size_t addrlen;
+
+  GNUNET_assert (plugin != NULL);
+  GNUNET_assert (address != NULL);
+
+  /* find existing session */
+  s = lookup_session (plugin, address);
+  if (s != NULL)
+    return s;
+
+  if (plugin->max_connections <= plugin->cur_connections)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, plugin->name,
+                     "Maximum number of connections reached, "
+                     "cannot connect to peer `%s'\n", GNUNET_i2s 
(&address->peer));
+    return NULL;
+  }
+
+  /* create new session */
+  addrlen = address->address_length;
+
+  GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) ||
+                 (addrlen == sizeof (struct IPv4HttpAddress)));
+
+  s = GNUNET_malloc (sizeof (struct Session));
+  memcpy (&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity));
+  s->plugin = plugin;
+  s->addr = GNUNET_malloc (address->address_length);
+  memcpy (s->addr, address->address, address->address_length);
+  s->addrlen = addrlen;
+  s->next = NULL;
+  s->next_receive = GNUNET_TIME_absolute_get_zero ();
+
+  s->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED);
+
+  /* Get ATS type */
+  if ((addrlen == sizeof (struct IPv4HttpAddress)) && (address->address != 
NULL))
+  {
+    struct IPv4HttpAddress *a4 = (struct IPv4HttpAddress *) address->address;
+    struct sockaddr_in s4;
+
+    s4.sin_family = AF_INET;
+    s4.sin_addr.s_addr = a4->ipv4_addr;
+    s4.sin_port = a4->u4_port;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+    s4.sin_len = sizeof (struct sockaddr_in);
+#endif
+    ats = plugin->env->get_address_type (plugin->env->cls, (const struct 
sockaddr *) &s4, sizeof (struct sockaddr_in));
+  }
+  if ((addrlen == sizeof (struct IPv6HttpAddress)) && (address->address != 
NULL))
+  {
+    struct IPv6HttpAddress *a6 = (struct IPv6HttpAddress *) address->address;
+    struct sockaddr_in6 s6;
+
+    s6.sin6_family = AF_INET6;
+    s6.sin6_addr = a6->ipv6_addr;
+    s6.sin6_port = a6->u6_port;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+    s6.sin6_len = sizeof (struct sockaddr_in6);
+#endif
+    ats = plugin->env->get_address_type (plugin->env->cls, (const struct 
sockaddr *) &s6, sizeof (struct sockaddr_in6));
+  }
+  s->ats_address_network_type = ats.value;
+
+  /* add new session */
+  GNUNET_CONTAINER_DLL_insert (plugin->head, plugin->tail, s);
+  /* initiate new connection */
+  if (GNUNET_SYSERR == client_connect (s))
+  {
+    if (s != NULL)
+    {
+      GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s);
+      delete_session (s);
+    }
+    return NULL;
+  }
+
+  return s;
+}
+
 /**
  * Function that can be used by the transport service to transmit
  * a message using the plugin.   Note that in the case of a
@@ -518,6 +636,103 @@
  * a fresh connection to another peer.
  *
  * @param cls closure
+ * @param session which session must be used
+ * @param msgbuf the message to transmit
+ * @param msgbuf_size number of bytes in 'msgbuf'
+ * @param priority how important is the message (most plugins will
+ *                 ignore message priority and just FIFO)
+ * @param to how long to wait at most for the transmission (does not
+ *                require plugins to discard the message after the timeout,
+ *                just advisory for the desired delay; most plugins will ignore
+ *                this as well)
+ * @param cont continuation to call once the message has
+ *        been transmitted (or if the transport is ready
+ *        for the next transmission call; or if the
+ *        peer disconnected...); can be NULL
+ * @param cont_cls closure for cont
+ * @return number of bytes used (on the physical network, with overheads);
+ *         -1 on hard errors (i.e. address invalid); 0 is a legal value
+ *         and does NOT mean that the message was not transmitted (DV)
+ */
+static ssize_t
+http_plugin_send (void *cls,
+                  struct Session *session,
+                  const char *msgbuf, size_t msgbuf_size,
+                  unsigned int priority,
+                  struct GNUNET_TIME_Relative to,
+                  GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
+{
+  struct Plugin *plugin = cls;
+  struct HTTP_Message *msg;
+  struct Session *tmp;
+  size_t res = -1;
+
+  GNUNET_assert (plugin != NULL);
+  GNUNET_assert (session != NULL);
+
+  /* lookup if session is really existing */
+  tmp = plugin->head;
+  while (tmp != NULL)
+  {
+    if ((tmp == session) &&
+       (0 == memcmp (&session->target, &tmp->target, sizeof (struct 
GNUNET_PeerIdentity))) &&
+       (session->addrlen != tmp->addrlen) &&
+       (0 != memcmp (session->addr, tmp->addr, tmp->addrlen)))
+      break;
+    tmp = tmp->next;
+  }
+  if (tmp == NULL)
+  {
+    GNUNET_break_op (0);
+    return res;
+  }
+
+  /* create new message and schedule */
+
+  msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size);
+  msg->next = NULL;
+  msg->size = msgbuf_size;
+  msg->pos = 0;
+  msg->buf = (char *) &msg[1];
+  msg->transmit_cont = cont;
+  msg->transmit_cont_cls = cont_cls;
+  memcpy (msg->buf, msgbuf, msgbuf_size);
+
+  if (session->inbound == GNUNET_NO)
+  {
+#if DEBUG_HTTP
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                     "Using outbound client session %p to send to 
`%session'\n", session,
+                     GNUNET_i2s (&session->target));
+#endif
+
+    client_send (session, msg);
+    res = msgbuf_size;
+  }
+  if (session->inbound == GNUNET_YES)
+  {
+#if DEBUG_HTTP
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
+                     "Using inbound server %p session to send to 
`%session'\n", session,
+                     GNUNET_i2s (&session->target));
+#endif
+
+    server_send (session, msg);
+    res = msgbuf_size;
+  }
+  return res;
+
+}
+
+/**
+ * Function that can be used by the transport service to transmit
+ * a message using the plugin.   Note that in the case of a
+ * peer disconnecting, the continuation MUST be called
+ * prior to the disconnect notification itself.  This function
+ * will be called with this peer's HELLO message to initiate
+ * a fresh connection to another peer.
+ *
+ * @param cls closure
  * @param target who should receive this message
  * @param msgbuf the message to transmit
  * @param msgbuf_size number of bytes in 'msgbuf'
@@ -546,7 +761,7 @@
  *         and does NOT mean that the message was not transmitted (DV)
  */
 static ssize_t
-http_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
+http_plugin_send_old (void *cls, const struct GNUNET_PeerIdentity *target,
                   const char *msgbuf, size_t msgbuf_size, unsigned int 
priority,
                   struct GNUNET_TIME_Relative to, struct Session *session,
                   const void *addr, size_t addrlen, int force_address,
@@ -576,10 +791,8 @@
   if (addrlen != 0)
     GNUNET_assert ((addrlen == sizeof (struct IPv4HttpAddress)) ||
                    (addrlen == sizeof (struct IPv6HttpAddress)));
-
-
   /* look for existing connection */
-  s = lookup_session (plugin, target, session, addr, addrlen, 1);
+  s = lookup_session_old (plugin, target, session, addr, addrlen, 1);
 #if DEBUG_HTTP
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
                    "%s existing session: %s\n",
@@ -588,7 +801,6 @@
                                                           GNUNET_YES)) ?
                    "inbound" : "outbound");
 #endif
-
   /* create new outbound connection */
   if (s == NULL)
   {
@@ -605,6 +817,7 @@
                      "Initiiating new connection to peer `%s'\n",
                      GNUNET_i2s (target));
 #endif
+/* AAAAAAAAAAAAAAAAAAA */
     int res = GNUNET_OK;
     struct GNUNET_ATS_Information ats;
     if ((addrlen == sizeof (struct IPv4HttpAddress)) && (addr != NULL))
@@ -658,6 +871,8 @@
     }
   }
 
+  /* real sending */
+
   msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size);
   msg->next = NULL;
   msg->size = msgbuf_size;
@@ -1380,11 +1595,13 @@
   plugin->env = env;
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;
-  api->send = &http_plugin_send;
+  api->send = &http_plugin_send_old;
   api->disconnect = &http_plugin_disconnect;
   api->address_pretty_printer = &http_plugin_address_pretty_printer;
   api->check_address = &http_plugin_address_suggested;
   api->address_to_string = &http_plugin_address_to_string;
+  api->get_session = &http_get_session;
+  api->send_with_session =   &http_plugin_send;
 
 #if BUILD_HTTPS
   plugin->name = "transport-https";

Modified: gnunet/src/transport/plugin_transport_tcp.c
===================================================================
--- gnunet/src/transport/plugin_transport_tcp.c 2012-01-26 10:18:23 UTC (rev 
19424)
+++ gnunet/src/transport/plugin_transport_tcp.c 2012-01-26 11:01:28 UTC (rev 
19425)
@@ -1231,16 +1231,11 @@
  */
 static ssize_t
 tcp_plugin_send_new (void *cls,
-    const struct
-    GNUNET_PeerIdentity *
-    target,
-    const char *msg,
-    size_t msgbuf_size,
-    uint32_t priority,
-    struct GNUNET_TIME_Relative timeout,
-    struct Session * session,
-    GNUNET_TRANSPORT_TransmitContinuation
-    cont, void *cont_cls)
+    struct Session *session,
+    const char *msgbuf, size_t msgbuf_size,
+    unsigned int priority,
+    struct GNUNET_TIME_Relative to,
+    GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 {
   struct Plugin * plugin = cls;
   struct PendingMessage *pm;
@@ -1256,9 +1251,9 @@
   /* create new message entry */
   pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size);
   pm->msg = (const char *) &pm[1];
-  memcpy (&pm[1], msg, msgbuf_size);
+  memcpy (&pm[1], msgbuf, msgbuf_size);
   pm->message_size = msgbuf_size;
-  pm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  pm->timeout = GNUNET_TIME_relative_to_absolute (to);
   pm->transmit_cont = cont;
   pm->transmit_cont_cls = cont_cls;
 
@@ -1310,10 +1305,8 @@
  * @param addrlen length of addr
  * @return the session if the address is valid, NULL otherwise
  */
-const void * tcp_plugin_create_session (void *cls,
-                                        const struct GNUNET_PeerIdentity 
*target,
-                                        const void *addr,
-                                        size_t addrlen)
+const const struct Session * tcp_plugin_create_session (void *cls,
+                      const struct GNUNET_HELLO_Address *address)
 {
   struct Plugin * plugin = cls;
   struct Session * session = NULL;
@@ -1327,11 +1320,15 @@
   const struct IPv4TcpAddress *t4;
   const struct IPv6TcpAddress *t6;
   unsigned int is_natd = GNUNET_NO;
+  size_t addrlen = address->address_length;
 
+  GNUNET_assert (plugin != NULL);
+  GNUNET_assert (address != NULL);
+
   if (addrlen == sizeof (struct IPv6TcpAddress))
   {
-    GNUNET_assert (NULL != addr);     /* make static analysis happy */
-    t6 = addr;
+    GNUNET_assert (NULL != address->address);     /* make static analysis 
happy */
+    t6 = address->address;
     af = AF_INET6;
     memset (&a6, 0, sizeof (a6));
 #if HAVE_SOCKADDR_IN_SIN_LEN
@@ -1347,8 +1344,8 @@
   }
   else if (addrlen == sizeof (struct IPv4TcpAddress))
   {
-    GNUNET_assert (NULL != addr);     /* make static analysis happy */
-    t4 = addr;
+    GNUNET_assert (NULL != address->address);     /* make static analysis 
happy */
+    t4 = address->address;
     af = AF_INET;
     memset (&a4, 0, sizeof (a4));
 #if HAVE_SOCKADDR_IN_SIN_LEN
@@ -1371,12 +1368,12 @@
   }
 
   /* look for existing session */
-  if (GNUNET_CONTAINER_multihashmap_contains(plugin->sessionmap, 
&target->hashPubKey))
+  if (GNUNET_CONTAINER_multihashmap_contains(plugin->sessionmap, 
&address->peer.hashPubKey))
   {
     struct SessionItCtx si_ctx;
     si_ctx.addr = &sbs;
     si_ctx.addrlen = sbs;
-    GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessionmap, 
&target->hashPubKey, &session_it, &si_ctx);
+    GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessionmap, 
&address->peer.hashPubKey, &session_it, &si_ctx);
     if (si_ctx.result != NULL)
       session = si_ctx.result;
     return session;
@@ -1391,23 +1388,23 @@
   if ((is_natd == GNUNET_YES) &&
       (GNUNET_YES ==
        GNUNET_CONTAINER_multihashmap_contains (plugin->nat_wait_conns,
-                                               &target->hashPubKey)))
+                                               &address->peer.hashPubKey)))
      return NULL;             /* Only do one NAT punch attempt per peer 
identity */
 
   if ((is_natd == GNUNET_YES) && (NULL != plugin->nat) &&
       (GNUNET_NO ==
        GNUNET_CONTAINER_multihashmap_contains (plugin->nat_wait_conns,
-                                               &target->hashPubKey)))
+                                               &address->peer.hashPubKey)))
   {
 #if DEBUG_TCP_NAT
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
                      _("Found valid IPv4 NAT address (creating session)!\n"));
 #endif
-    session = create_session (plugin, target, NULL, GNUNET_YES);
+    session = create_session (plugin, &address->peer, NULL, GNUNET_YES);
     GNUNET_assert (session != NULL);
 
     GNUNET_assert (GNUNET_CONTAINER_multihashmap_put
-                   (plugin->nat_wait_conns, &target->hashPubKey, session,
+                   (plugin->nat_wait_conns, &address->peer.hashPubKey, session,
                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) == 
GNUNET_OK);
 #if DEBUG_TCP_NAT
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
@@ -1437,11 +1434,11 @@
                    GNUNET_i2s (target), GNUNET_a2s (sb, sbs));
 #endif
   session = create_session (plugin,
-                            target,
+                            &address->peer,
                             GNUNET_SERVER_connect_socket (plugin->server, sa),
                             GNUNET_NO);
   session->connect_addr = GNUNET_malloc (addrlen);
-  memcpy (session->connect_addr, addr, addrlen);
+  memcpy (session->connect_addr, address->address, addrlen);
   session->connect_alen = addrlen;
   if (addrlen != 0)
   {
@@ -1452,7 +1449,7 @@
   else
     GNUNET_break (0);
 
-  GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &target->hashPubKey, 
session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+  GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, 
&address->peer.hashPubKey, session, 
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 
   /* Send TCP Welcome */
   process_pending_messages (session);
@@ -2286,7 +2283,7 @@
   api->send = &tcp_plugin_send;
 
   api->send_with_session = &tcp_plugin_send_new;
-  api->create_session = &tcp_plugin_create_session;
+  api->get_session = &tcp_plugin_create_session;
 
   api->disconnect = &tcp_plugin_disconnect;
   api->address_pretty_printer = &tcp_plugin_address_pretty_printer;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]