aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2010-09-24 12:40:31 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2010-09-24 12:40:31 +0000
commit85588b1effe525b6de67d2cb3a6bc24424a1e3f7 (patch)
tree1953fcb7166de3466635eb9109f6ef669d5be4e4 /src/transport/plugin_transport_http.c
parent3be84aff5f8046e279b3527fc13db1102d52648c (diff)
downloadgnunet-85588b1effe525b6de67d2cb3a6bc24424a1e3f7.tar.gz
gnunet-85588b1effe525b6de67d2cb3a6bc24424a1e3f7.zip
Introduced limited per connection queue size
Diffstat (limited to 'src/transport/plugin_transport_http.c')
-rw-r--r--src/transport/plugin_transport_http.c95
1 files changed, 65 insertions, 30 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c
index 4389bbefc..0238746bc 100644
--- a/src/transport/plugin_transport_http.c
+++ b/src/transport/plugin_transport_http.c
@@ -316,6 +316,17 @@ struct Session
316 * inbound session: mhd_connection * 316 * inbound session: mhd_connection *
317 */ 317 */
318 void * recv_endpoint; 318 void * recv_endpoint;
319
320 /**
321 * Current queue size
322 */
323 size_t queue_length_cur;
324
325 /**
326 * Max queue size
327 */
328 size_t queue_length_max;
329
319}; 330};
320 331
321/** 332/**
@@ -503,8 +514,8 @@ static int remove_http_message (struct Session * ps, struct HTTP_Message * msg)
503/** 514/**
504 * Iterator to remove peer context 515 * Iterator to remove peer context
505 * @param cls the plugin 516 * @param cls the plugin
506 * @key the peers public key hashcode 517 * @param key the peers public key hashcode
507 * @value the peer context 518 * @param value the peer context
508 * @return GNUNET_YES on success 519 * @return GNUNET_YES on success
509 */ 520 */
510int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *value) 521int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *value)
@@ -858,6 +869,7 @@ mhd_send_callback (void *cls, uint64_t pos, char *buf, size_t max)
858 { 869 {
859 if (NULL!=msg->transmit_cont) 870 if (NULL!=msg->transmit_cont)
860 msg->transmit_cont (msg->transmit_cont_cls,&pc->identity,GNUNET_OK); 871 msg->transmit_cont (msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
872 ps->queue_length_cur -= msg->size;
861 remove_http_message(ps,msg); 873 remove_http_message(ps,msg);
862 } 874 }
863 } 875 }
@@ -1017,6 +1029,8 @@ mdh_access_cb (void *cls,
1017 ps->recv_active=GNUNET_NO; 1029 ps->recv_active=GNUNET_NO;
1018 ps->peercontext=pc; 1030 ps->peercontext=pc;
1019 ps->session_id =id_num; 1031 ps->session_id =id_num;
1032 ps->queue_length_cur = 0;
1033 ps->queue_length_max = GNUNET_SERVER_MAX_MESSAGE_SIZE;
1020 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id); 1034 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id);
1021 GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps); 1035 GNUNET_CONTAINER_DLL_insert(pc->head,pc->tail,ps);
1022 GNUNET_STATISTICS_update (plugin->env->stats, 1036 GNUNET_STATISTICS_update (plugin->env->stats,
@@ -1436,6 +1450,7 @@ static size_t curl_send_cb(void *stream, size_t size, size_t nmemb, void *ptr)
1436 /* Calling transmit continuation */ 1450 /* Calling transmit continuation */
1437 if (NULL != ps->pending_msgs_tail->transmit_cont) 1451 if (NULL != ps->pending_msgs_tail->transmit_cont)
1438 msg->transmit_cont (ps->pending_msgs_tail->transmit_cont_cls,&(ps->peercontext)->identity,GNUNET_OK); 1452 msg->transmit_cont (ps->pending_msgs_tail->transmit_cont_cls,&(ps->peercontext)->identity,GNUNET_OK);
1453 ps->queue_length_cur -= msg->size;
1439 remove_http_message(ps, msg); 1454 remove_http_message(ps, msg);
1440 } 1455 }
1441 return bytes_sent; 1456 return bytes_sent;
@@ -1533,9 +1548,14 @@ static void curl_handle_finished (struct Plugin *plugin)
1533 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint); 1548 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
1534 //curl_easy_cleanup(ps->send_endpoint); 1549 //curl_easy_cleanup(ps->send_endpoint);
1535 //ps->send_endpoint=NULL; 1550 //ps->send_endpoint=NULL;
1536 cur_msg = ps->pending_msgs_tail; 1551 while (ps->pending_msgs_tail != NULL)
1537 if (( NULL != cur_msg) && ( NULL != cur_msg->transmit_cont)) 1552 {
1538 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR); 1553 cur_msg = ps->pending_msgs_tail;
1554 if ( NULL != cur_msg->transmit_cont)
1555 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR);
1556 ps->queue_length_cur -= cur_msg->size;
1557 remove_http_message(ps,cur_msg);
1558 }
1539 } 1559 }
1540 /* GET connection failed */ 1560 /* GET connection failed */
1541 if (msg->easy_handle == ps->recv_endpoint) 1561 if (msg->easy_handle == ps->recv_endpoint)
@@ -1570,19 +1590,25 @@ static void curl_handle_finished (struct Plugin *plugin)
1570 http_result); 1590 http_result);
1571 #endif 1591 #endif
1572 /* Calling transmit continuation */ 1592 /* Calling transmit continuation */
1573 cur_msg = ps->pending_msgs_tail; 1593 while (ps->pending_msgs_tail != NULL)
1574 if (( NULL != cur_msg) && (NULL != cur_msg->transmit_cont))
1575 { 1594 {
1576 /* HTTP 1xx : Last message before here was informational */ 1595 cur_msg = ps->pending_msgs_tail;
1577 if ((http_result >=100) && (http_result < 200)) 1596 if ( NULL != cur_msg->transmit_cont)
1578 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK); 1597 {
1579 /* HTTP 2xx: successful operations */ 1598 /* HTTP 1xx : Last message before here was informational */
1580 if ((http_result >=200) && (http_result < 300)) 1599 if ((http_result >=100) && (http_result < 200))
1581 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK); 1600 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
1582 /* HTTP 3xx..5xx: error */ 1601 /* HTTP 2xx: successful operations */
1583 if ((http_result >=300) && (http_result < 600)) 1602 if ((http_result >=200) && (http_result < 300))
1584 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR); 1603 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_OK);
1604 /* HTTP 3xx..5xx: error */
1605 if ((http_result >=300) && (http_result < 600))
1606 cur_msg->transmit_cont (cur_msg->transmit_cont_cls,&pc->identity,GNUNET_SYSERR);
1607 }
1608 ps->queue_length_cur -= cur_msg->size;
1609 remove_http_message(ps,cur_msg);
1585 } 1610 }
1611
1586 ps->send_connected = GNUNET_NO; 1612 ps->send_connected = GNUNET_NO;
1587 ps->send_active = GNUNET_NO; 1613 ps->send_active = GNUNET_NO;
1588 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint); 1614 curl_multi_remove_handle(plugin->multi_handle,ps->send_endpoint);
@@ -1651,7 +1677,7 @@ static void curl_perform (void *cls,
1651/** 1677/**
1652 * Function setting up file descriptors and scheduling task to run 1678 * Function setting up file descriptors and scheduling task to run
1653 * 1679 *
1654 * @param cls plugin as closure 1680 * @param plugin plugin as closure
1655 * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok 1681 * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok
1656 */ 1682 */
1657static int curl_schedule(struct Plugin *plugin) 1683static int curl_schedule(struct Plugin *plugin)
@@ -1925,7 +1951,6 @@ static int send_check_connections (struct Plugin *plugin, struct Session *ps)
1925/** 1951/**
1926 * select best session to transmit data to peer 1952 * select best session to transmit data to peer
1927 * 1953 *
1928 * @param cls closure
1929 * @param pc peer context of target peer 1954 * @param pc peer context of target peer
1930 * @param addr address of target peer 1955 * @param addr address of target peer
1931 * @param addrlen address length 1956 * @param addrlen address length
@@ -2168,6 +2193,8 @@ http_plugin_send (void *cls,
2168 ps->pending_msgs_tail = NULL; 2193 ps->pending_msgs_tail = NULL;
2169 ps->peercontext=pc; 2194 ps->peercontext=pc;
2170 ps->session_id = pc->session_id_counter; 2195 ps->session_id = pc->session_id_counter;
2196 ps->queue_length_cur = 0;
2197 ps->queue_length_max = GNUNET_SERVER_MAX_MESSAGE_SIZE;
2171 pc->session_id_counter++; 2198 pc->session_id_counter++;
2172 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id); 2199 ps->url = create_url (plugin, ps->addr, ps->addrlen, ps->session_id);
2173 if (ps->msgtok == NULL) 2200 if (ps->msgtok == NULL)
@@ -2187,18 +2214,26 @@ http_plugin_send (void *cls,
2187 } 2214 }
2188 } 2215 }
2189 2216
2190 /* create msg */ 2217 if (msgbuf_size >= (ps->queue_length_max - ps->queue_length_cur))
2191 msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size); 2218 {
2192 msg->next = NULL; 2219 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"Queue %X full: (%u) bytes in queue, would discard message (%u)\n", ps, (ps->queue_length_max - ps->queue_length_cur), msgbuf_size);
2193 msg->size = msgbuf_size; 2220 //return GNUNET_SYSERR;
2194 msg->pos = 0; 2221 }
2195 msg->buf = (char *) &msg[1]; 2222
2196 msg->transmit_cont = cont; 2223 /* create msg */
2197 msg->transmit_cont_cls = cont_cls; 2224 msg = GNUNET_malloc (sizeof (struct HTTP_Message) + msgbuf_size);
2198 memcpy (msg->buf,msgbuf, msgbuf_size); 2225 msg->next = NULL;
2199 GNUNET_CONTAINER_DLL_insert(ps->pending_msgs_head,ps->pending_msgs_tail,msg); 2226 msg->size = msgbuf_size;
2200 2227 msg->pos = 0;
2201 if (send_check_connections (plugin, ps) == GNUNET_SYSERR) 2228 msg->buf = (char *) &msg[1];
2229 msg->transmit_cont = cont;
2230 msg->transmit_cont_cls = cont_cls;
2231 memcpy (msg->buf,msgbuf, msgbuf_size);
2232
2233 GNUNET_CONTAINER_DLL_insert(ps->pending_msgs_head,ps->pending_msgs_tail,msg);
2234 ps->queue_length_cur += msgbuf_size;
2235
2236 if (send_check_connections (plugin, ps) == GNUNET_SYSERR)
2202 return GNUNET_SYSERR; 2237 return GNUNET_SYSERR;
2203 if (force_address != GNUNET_YES) 2238 if (force_address != GNUNET_YES)
2204 pc->last_session = ps; 2239 pc->last_session = ps;