gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r11942 - gnunet/src/transport
Date: Fri, 25 Jun 2010 10:48:06 +0200

Author: wachs
Date: 2010-06-25 10:48:06 +0200 (Fri, 25 Jun 2010)
New Revision: 11942

Modified:
   gnunet/src/transport/plugin_transport_http.c
   gnunet/src/transport/test_plugin_transport_http.c
Log:


Modified: gnunet/src/transport/plugin_transport_http.c
===================================================================
--- gnunet/src/transport/plugin_transport_http.c        2010-06-24 22:44:22 UTC 
(rev 11941)
+++ gnunet/src/transport/plugin_transport_http.c        2010-06-25 08:48:06 UTC 
(rev 11942)
@@ -41,7 +41,7 @@
 #include <curl/curl.h>
 
 
-#define DEBUG_CURL GNUNET_NO
+#define DEBUG_CURL GNUNET_YES
 #define DEBUG_HTTP GNUNET_NO
 
 /**
@@ -157,6 +157,27 @@
 };
 
 
+struct HTTP_Connection
+{
+  struct HTTP_Connection * next;
+
+  struct HTTP_Connection * prev;
+
+  void * addr;
+  size_t addrlen;
+
+  struct HTTP_Message * pending_msgs_head;
+  struct HTTP_Message * pending_msgs_tail;
+
+  char * url;
+  unsigned int connected;
+
+  /**
+   * curl handle for this ransmission
+   */
+  CURL *curl_handle;
+};
+
 /**
  * Session handle for connections.
  */
@@ -256,6 +277,9 @@
    * Message tokenizer for incoming data
    */
   struct GNUNET_SERVER_MessageStreamTokenizer * msgtok;
+
+  struct HTTP_Connection *outbound_addresses_head;
+  struct HTTP_Connection *outbound_addresses_tail;
 };
 
 /**
@@ -323,28 +347,30 @@
 static struct Session * create_session (void * cls, char * addr_in, size_t 
addrlen_in, char * addr_out, size_t addrlen_out, const struct 
GNUNET_PeerIdentity *peer)
 {
   struct Plugin *plugin = cls;
-  struct Session * ses = GNUNET_malloc ( sizeof( struct Session) );
+  struct Session * cs = GNUNET_malloc ( sizeof( struct Session) );
 
   GNUNET_assert(cls !=NULL);
   if (addrlen_in != 0)
   {
-    ses->addr_in = GNUNET_malloc (addrlen_in);
-    ses->addr_in_len = addrlen_in;
-    memcpy(ses->addr_in,addr_in,addrlen_in);
+    cs->addr_in = GNUNET_malloc (addrlen_in);
+    cs->addr_in_len = addrlen_in;
+    memcpy(cs->addr_in,addr_in,addrlen_in);
   }
 
   if (addrlen_out != 0)
   {
-    ses->addr_out = GNUNET_malloc (addrlen_out);
-    ses->addr_out_len = addrlen_out;
-    memcpy(ses->addr_out,addr_out,addrlen_out);
+    cs->addr_out = GNUNET_malloc (addrlen_out);
+    cs->addr_out_len = addrlen_out;
+    memcpy(cs->addr_out,addr_out,addrlen_out);
   }
-  ses->plugin = plugin;
-  memcpy(&ses->partner, peer, sizeof (struct GNUNET_PeerIdentity));
-  GNUNET_CRYPTO_hash_to_enc(&ses->partner.hashPubKey,&(ses->hash));
-  ses->pending_inbound_msg.bytes_recv = 0;
-  ses->msgtok = NULL;
-  return ses;
+  cs->plugin = plugin;
+  memcpy(&cs->partner, peer, sizeof (struct GNUNET_PeerIdentity));
+  GNUNET_CRYPTO_hash_to_enc(&cs->partner.hashPubKey,&(cs->hash));
+  cs->pending_inbound_msg.bytes_recv = 0;
+  cs->msgtok = NULL;
+  cs->outbound_addresses_head = NULL;
+  cs->outbound_addresses_tail = NULL;
+  return cs;
 }
 
 /**
@@ -852,42 +878,45 @@
  * @param ses session to send data to
  * @return bytes sent to peer
  */
-static ssize_t send_select_init (void *cls, struct Session* ses )
+static ssize_t send_select_init (void *cls, struct Session* ses , struct 
HTTP_Connection *con)
 {
   struct Plugin *plugin = cls;
   int bytes_sent = 0;
   CURLMcode mret;
   struct HTTP_Message * msg;
 
+  /* already connected, no need to initiate connection */
+  if (con->connected == GNUNET_YES)
+    return bytes_sent;
+
+
+  /* not connected, initiate connection */
   GNUNET_assert(cls !=NULL);
-  if ( NULL == ses->curl_handle)
-    ses->curl_handle = curl_easy_init();
-  if( NULL == ses->curl_handle)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Getting cURL handle failed\n");
-    return -1;
-  }
-  GNUNET_assert (NULL != ses->pending_outbound_msg_tail);
-  msg = ses->pending_outbound_msg_tail;
+  if ( NULL == con->curl_handle)
+    con->curl_handle = curl_easy_init();
+  GNUNET_assert (con->curl_handle != NULL);
 
+  GNUNET_assert (NULL != con->pending_msgs_tail);
+  msg = con->pending_msgs_tail;
+
 #if DEBUG_CURL
-  curl_easy_setopt(ses->curl_handle, CURLOPT_VERBOSE, 1L);
+  curl_easy_setopt(con->curl_handle, CURLOPT_VERBOSE, 1L);
 #endif
-  curl_easy_setopt(ses->curl_handle, CURLOPT_URL, msg->dest_url);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_PUT, 1L);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_HEADERFUNCTION, &header_function);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_WRITEHEADER, ses);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_READFUNCTION, send_read_callback);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_READDATA, ses);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_WRITEFUNCTION, 
send_write_callback);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_READDATA, ses);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 
msg->size);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_TIMEOUT, 
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
-  GNUNET_assert (CURLE_OK == curl_easy_setopt(ses->curl_handle, 
CURLOPT_PRIVATE, ses));
-  curl_easy_setopt(ses->curl_handle, CURLOPT_CONNECTTIMEOUT, 
HTTP_CONNECT_TIMEOUT);
-  curl_easy_setopt(ses->curl_handle, CURLOPT_BUFFERSIZE, 
GNUNET_SERVER_MAX_MESSAGE_SIZE);
+  curl_easy_setopt(con->curl_handle, CURLOPT_URL, con->url);
+  curl_easy_setopt(con->curl_handle, CURLOPT_PUT, 1L);
+  curl_easy_setopt(con->curl_handle, CURLOPT_HEADERFUNCTION, &header_function);
+  curl_easy_setopt(con->curl_handle, CURLOPT_WRITEHEADER, con);
+  curl_easy_setopt(con->curl_handle, CURLOPT_READFUNCTION, send_read_callback);
+  curl_easy_setopt(con->curl_handle, CURLOPT_READDATA, con);
+  curl_easy_setopt(con->curl_handle, CURLOPT_WRITEFUNCTION, 
send_write_callback);
+  curl_easy_setopt(con->curl_handle, CURLOPT_READDATA, con);
+  curl_easy_setopt(con->curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 
msg->size);
+  curl_easy_setopt(con->curl_handle, CURLOPT_TIMEOUT, 
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
+  GNUNET_assert (CURLE_OK == curl_easy_setopt(con->curl_handle, 
CURLOPT_PRIVATE, ses));
+  curl_easy_setopt(con->curl_handle, CURLOPT_CONNECTTIMEOUT, 
HTTP_CONNECT_TIMEOUT);
+  curl_easy_setopt(con->curl_handle, CURLOPT_BUFFERSIZE, 
GNUNET_SERVER_MAX_MESSAGE_SIZE);
 
-  mret = curl_multi_add_handle(plugin->multi_handle, ses->curl_handle);
+  mret = curl_multi_add_handle(plugin->multi_handle, con->curl_handle);
   if (mret != CURLM_OK)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -896,7 +925,7 @@
                 curl_multi_strerror (mret));
     return -1;
   }
-  bytes_sent = send_prepare (plugin, ses );
+  bytes_sent = send_prepare (plugin, ses);
   return bytes_sent;
 }
 
@@ -981,7 +1010,7 @@
                   /* send pending messages */
                   if (cs->pending_outbound_msg_tail!= NULL)
                   {
-                    send_select_init (plugin, cs);
+                    send_select_init (plugin, cs, NULL);
                   }
                   return;
                 default:
@@ -1059,6 +1088,112 @@
 }
 
 /**
+ * Check if session for this peer is already existing, otherwise create it
+ * @param cls the plugin used
+ * @param p peer to get session for
+ * @return session found or created
+ */
+static struct Session * session_get (void * cls, const struct 
GNUNET_PeerIdentity *p)
+{
+  struct Plugin *plugin = cls;
+  struct Session *cs;
+  unsigned int res;
+
+  cs = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, &p->hashPubKey);
+  if (cs != NULL)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Session `%s' found\n", GNUNET_i2s(p));
+  }
+  if (cs == NULL)
+  {
+    cs = create_session(plugin, NULL, 0, NULL, 0, p);
+    res = GNUNET_CONTAINER_multihashmap_put ( plugin->sessions,
+                                        &cs->partner.hashPubKey,
+                                        cs,
+                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+    if (res == GNUNET_OK)
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "New Session `%s' inserted\n", GNUNET_i2s(p));
+  }
+  return cs;
+}
+
+static char * create_url(void * cls, const void * addr, size_t addrlen)
+{
+  struct Plugin *plugin = cls;
+  char *address;
+  char *url;
+
+  GNUNET_assert ((addr!=NULL) && (addrlen != 0));
+  if (addrlen == (sizeof (struct IPv4HttpAddress)))
+  {
+    address = GNUNET_malloc(INET_ADDRSTRLEN + 1);
+    inet_ntop(AF_INET, &((struct IPv4HttpAddress *) 
addr)->ipv4_addr,address,INET_ADDRSTRLEN);
+    GNUNET_asprintf (&url,
+                     "http://%s:%u/%s";,
+                     address,
+                     ntohs(((struct IPv4HttpAddress *) addr)->u_port),
+                     (char *) (&plugin->my_ascii_hash_ident));
+    GNUNET_free(address);
+  }
+  else if (addrlen == (sizeof (struct IPv6HttpAddress)))
+  {
+    address = GNUNET_malloc(INET6_ADDRSTRLEN + 1);
+    inet_ntop(AF_INET6, &((struct IPv6HttpAddress *) 
addr)->ipv6_addr,address,INET6_ADDRSTRLEN);
+    GNUNET_asprintf(&url,
+                    "http://%s:%u/%s";,
+                    address,
+                    ntohs(((struct IPv6HttpAddress *) addr)->u6_port),
+                    (char *) (&plugin->my_ascii_hash_ident));
+    GNUNET_free(address);
+  }
+  return url;
+}
+
+/**
+ * Check if session already knows this address for a outbound connection to 
this peer
+ * If address not in session, add it to the session
+ * @param cls the plugin used
+ * @param p the session
+ * @param addr address
+ * @param addr_len address length
+ * @return GNUNET_NO if address not known, GNUNET_YES if known
+ */
+static struct HTTP_Connection * session_check_address (void * cls, struct 
Session *cs, const void * addr, size_t addr_len)
+{
+  struct Plugin *plugin = cls;
+  struct HTTP_Connection * cc = cs->outbound_addresses_head;
+  struct HTTP_Connection * con = NULL;
+
+  GNUNET_assert((addr_len == sizeof (struct IPv4HttpAddress)) || (addr_len == 
sizeof (struct IPv6HttpAddress)));
+
+  while (cc!=NULL)
+  {
+    if (addr_len == cc->addrlen)
+    {
+      if (0 == memcmp(cc->addr, addr, addr_len))
+      {
+        con = cc;
+        break;
+      }
+    }
+    cc=cc->next;
+  }
+  if (con==NULL)
+  {
+    con = GNUNET_malloc(sizeof(struct HTTP_Connection) + addr_len);
+    con->addrlen = addr_len;
+    con->addr=&con[1];
+    con->url=create_url(plugin, addr, addr_len);
+    con->connected = GNUNET_NO;
+    memcpy(con->addr, addr, addr_len);
+    
GNUNET_CONTAINER_DLL_insert(cs->outbound_addresses_head,cs->outbound_addresses_tail,con);
+  }
+  return con;
+}
+
+/**
  * Function that can be used by the transport service to transmit
  * a message using the plugin.
  *
@@ -1103,54 +1238,18 @@
   char *url;
   struct Session *cs;
   struct HTTP_Message *msg;
-  unsigned int res;
+  struct HTTP_Connection *con;
+  //unsigned int ret;
 
   GNUNET_assert(cls !=NULL);
   url = NULL;
   address = NULL;
 
-  cs = GNUNET_CONTAINER_multihashmap_get (plugin->sessions, 
&target->hashPubKey);
-  if (cs != NULL)
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Session `%s' found\n", GNUNET_i2s(target));
+  /* get session from hashmap */
+  cs = session_get(plugin, target);
+  con = session_check_address(plugin, cs, addr, addrlen);
 
-  if ( cs == NULL)
-  {
-    cs = create_session(plugin, (char *) addr, addrlen, NULL, 0, target);
-    res = GNUNET_CONTAINER_multihashmap_put ( plugin->sessions,
-                                        &cs->partner.hashPubKey,
-                                        cs,
-                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-    if (res == GNUNET_OK)
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "New Session `%s' inserted\n", GNUNET_i2s(target));
-  }
-
-  GNUNET_assert ((addr!=NULL) && (addrlen != 0));
-  if (addrlen == (sizeof (struct IPv4HttpAddress)))
-  {
-    address = GNUNET_malloc(INET_ADDRSTRLEN + 1);
-    inet_ntop(AF_INET, &((struct IPv4HttpAddress *) 
addr)->ipv4_addr,address,INET_ADDRSTRLEN);
-    GNUNET_asprintf (&url,
-                     "http://%s:%u/%s";,
-                     address,
-                     ntohs(((struct IPv4HttpAddress *) addr)->u_port),
-                     (char *) (&plugin->my_ascii_hash_ident));
-    GNUNET_free(address);
-  }
-  else if (addrlen == (sizeof (struct IPv6HttpAddress)))
-  {
-    address = GNUNET_malloc(INET6_ADDRSTRLEN + 1);
-    inet_ntop(AF_INET6, &((struct IPv6HttpAddress *) 
addr)->ipv6_addr,address,INET6_ADDRSTRLEN);
-    GNUNET_asprintf(&url,
-                    "http://%s:%u/%s";,
-                    address,
-                    ntohs(((struct IPv6HttpAddress *) addr)->u6_port),
-                    (char *) (&plugin->my_ascii_hash_ident));
-    GNUNET_free(address);
-  }
-
-  /* setting up message */
+  /* create msg */
   msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size);
   msg->next = NULL;
   msg->size = msgbuf_size;
@@ -1160,7 +1259,25 @@
   msg->transmit_cont = cont;
   msg->transmit_cont_cls = cont_cls;
   memcpy (msg->buf,msgbuf, msgbuf_size);
+
+  /* must use this address */
+  if (force_address == GNUNET_YES)
+  {
+    /* enqueue in connection message queue */
+    
GNUNET_CONTAINER_DLL_insert(con->pending_msgs_head,con->pending_msgs_tail,msg);
+  }
+  /* can use existing connection to send */
+  else
+  {
+    /* enqueue in connection message queue */
+    
GNUNET_CONTAINER_DLL_insert(con->pending_msgs_head,con->pending_msgs_tail,msg);
+  }
+
+  return send_select_init (plugin, cs, con);
+
+
   /* insert created message in double linked list of pending messages */
+  /*
   GNUNET_CONTAINER_DLL_insert (cs->pending_outbound_msg_head, 
cs->pending_outbound_msg_tail, msg);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"HTTP Plugin: sending %u bytes of data 
from peer `%4.4s' to peer `%s'\n",msgbuf_size,(char *) 
&plugin->my_ascii_hash_ident,GNUNET_i2s(target));
@@ -1170,6 +1287,7 @@
     return send_select_init (plugin, cs);
   }
   return msgbuf_size;
+  */
 }
 
 

Modified: gnunet/src/transport/test_plugin_transport_http.c
===================================================================
--- gnunet/src/transport/test_plugin_transport_http.c   2010-06-24 22:44:22 UTC 
(rev 11941)
+++ gnunet/src/transport/test_plugin_transport_http.c   2010-06-25 08:48:06 UTC 
(rev 11942)
@@ -997,6 +997,8 @@
     type ++;
   }
 
+  return;
+
   /* send a multiple GNUNET_messages at a time*/
   GNUNET_free(tmp);
   tmp = GNUNET_malloc(4 * sizeof(struct GNUNET_MessageHeader));




reply via email to

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