diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-06-25 14:14:16 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-06-25 14:14:16 +0000 |
commit | b9b0323eefcc0a595f56635be5b66de687650ae0 (patch) | |
tree | 63017efb9b00c59d174d025242c77b425ce6f402 /src/transport | |
parent | ca7daa5556bce347ce55933a831a8a402231ae48 (diff) | |
download | gnunet-b9b0323eefcc0a595f56635be5b66de687650ae0.tar.gz gnunet-b9b0323eefcc0a595f56635be5b66de687650ae0.zip |
-add monitor support to http server, more code clean up, add http server MHD suspend feature, support quota reset API from transport in HTTP server
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 308 | ||||
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 370 |
2 files changed, 407 insertions, 271 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index 68b25afe5..593b063ab 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -156,9 +156,10 @@ struct Session | |||
156 | struct HTTP_Client_Plugin *plugin; | 156 | struct HTTP_Client_Plugin *plugin; |
157 | 157 | ||
158 | /** | 158 | /** |
159 | * Client send handle | 159 | * Curl client PUT handle. |
160 | * FIXME: delta to put.easyhandle? | ||
160 | */ | 161 | */ |
161 | void *client_put; | 162 | CURL *client_put; |
162 | 163 | ||
163 | /** | 164 | /** |
164 | * Handle for the HTTP PUT request. | 165 | * Handle for the HTTP PUT request. |
@@ -166,14 +167,15 @@ struct Session | |||
166 | struct ConnectionHandle put; | 167 | struct ConnectionHandle put; |
167 | 168 | ||
168 | /** | 169 | /** |
169 | * Handle for the HTTP GET request. | 170 | * Curl client GET handle |
171 | * FIXME: delta to get.easyhandle? | ||
170 | */ | 172 | */ |
171 | struct ConnectionHandle get; | 173 | CURL *client_get; |
172 | 174 | ||
173 | /** | 175 | /** |
174 | * Client receive handle | 176 | * Handle for the HTTP GET request. |
175 | */ | 177 | */ |
176 | void *client_get; | 178 | struct ConnectionHandle get; |
177 | 179 | ||
178 | /** | 180 | /** |
179 | * next pointer for double linked list | 181 | * next pointer for double linked list |
@@ -415,6 +417,7 @@ client_delete_session (struct Session *s) | |||
415 | struct HTTP_Client_Plugin *plugin = s->plugin; | 417 | struct HTTP_Client_Plugin *plugin = s->plugin; |
416 | struct HTTP_Message *pos; | 418 | struct HTTP_Message *pos; |
417 | struct HTTP_Message *next; | 419 | struct HTTP_Message *next; |
420 | CURLMcode mret; | ||
418 | 421 | ||
419 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) | 422 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) |
420 | { | 423 | { |
@@ -427,11 +430,49 @@ client_delete_session (struct Session *s) | |||
427 | GNUNET_SCHEDULER_cancel (s->put_disconnect_task); | 430 | GNUNET_SCHEDULER_cancel (s->put_disconnect_task); |
428 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; | 431 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; |
429 | } | 432 | } |
433 | if (GNUNET_SCHEDULER_NO_TASK != s->recv_wakeup_task) | ||
434 | { | ||
435 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
436 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
437 | } | ||
430 | GNUNET_assert (GNUNET_OK == | 438 | GNUNET_assert (GNUNET_OK == |
431 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, | 439 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, |
432 | &s->target, | 440 | &s->target, |
433 | s)); | 441 | s)); |
442 | if (NULL != s->client_put) | ||
443 | { | ||
444 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
445 | "Session %p/connection %p: disconnecting PUT connection to peer `%s'\n", | ||
446 | s, | ||
447 | s->client_put, | ||
448 | GNUNET_i2s (&s->target)); | ||
434 | 449 | ||
450 | /* remove curl handle from multi handle */ | ||
451 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, | ||
452 | s->client_put); | ||
453 | GNUNET_break (CURLM_OK == mret); | ||
454 | curl_easy_cleanup (s->client_put); | ||
455 | s->client_put = NULL; | ||
456 | } | ||
457 | if (NULL != s->client_get) | ||
458 | { | ||
459 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
460 | "Session %p/connection %p: disconnecting GET connection to peer `%s'\n", | ||
461 | s, s->client_get, | ||
462 | GNUNET_i2s (&s->target)); | ||
463 | /* remove curl handle from multi handle */ | ||
464 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, | ||
465 | s->client_get); | ||
466 | GNUNET_break (CURLM_OK == mret); | ||
467 | curl_easy_cleanup (s->client_get); | ||
468 | GNUNET_assert (plugin->cur_connections > 0); | ||
469 | plugin->cur_connections--; | ||
470 | s->client_get = NULL; | ||
471 | } | ||
472 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
473 | HTTP_STAT_STR_CONNECTIONS, | ||
474 | plugin->cur_connections, | ||
475 | GNUNET_NO); | ||
435 | next = s->msg_head; | 476 | next = s->msg_head; |
436 | while (NULL != (pos = next)) | 477 | while (NULL != (pos = next)) |
437 | { | 478 | { |
@@ -757,86 +798,12 @@ http_client_plugin_session_disconnect (void *cls, | |||
757 | struct Session *s) | 798 | struct Session *s) |
758 | { | 799 | { |
759 | struct HTTP_Client_Plugin *plugin = cls; | 800 | struct HTTP_Client_Plugin *plugin = cls; |
760 | struct HTTP_Message *msg; | ||
761 | struct HTTP_Message *t; | ||
762 | int res = GNUNET_OK; | ||
763 | CURLMcode mret; | ||
764 | |||
765 | if (NULL != s->client_put) | ||
766 | { | ||
767 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
768 | "Session %p/connection %p: disconnecting PUT connection to peer `%s'\n", | ||
769 | s, | ||
770 | s->client_put, | ||
771 | GNUNET_i2s (&s->target)); | ||
772 | 801 | ||
773 | /* remove curl handle from multi handle */ | ||
774 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, | ||
775 | s->client_put); | ||
776 | if (mret != CURLM_OK) | ||
777 | { | ||
778 | /* clean up easy handle, handle is now invalid and free'd */ | ||
779 | res = GNUNET_SYSERR; | ||
780 | GNUNET_break (0); | ||
781 | } | ||
782 | curl_easy_cleanup (s->client_put); | ||
783 | s->client_put = NULL; | ||
784 | } | ||
785 | |||
786 | |||
787 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | ||
788 | { | ||
789 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
790 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
791 | } | ||
792 | |||
793 | if (NULL != s->client_get) | ||
794 | { | ||
795 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
796 | "Session %p/connection %p: disconnecting GET connection to peer `%s'\n", | ||
797 | s, s->client_get, | ||
798 | GNUNET_i2s (&s->target)); | ||
799 | /* remove curl handle from multi handle */ | ||
800 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_get); | ||
801 | if (mret != CURLM_OK) | ||
802 | { | ||
803 | /* clean up easy handle, handle is now invalid and free'd */ | ||
804 | res = GNUNET_SYSERR; | ||
805 | GNUNET_break (0); | ||
806 | } | ||
807 | curl_easy_cleanup (s->client_get); | ||
808 | s->client_get = NULL; | ||
809 | } | ||
810 | |||
811 | msg = s->msg_head; | ||
812 | while (NULL != msg) | ||
813 | { | ||
814 | t = msg->next; | ||
815 | if (NULL != msg->transmit_cont) | ||
816 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR, | ||
817 | msg->size, msg->pos + s->overhead); | ||
818 | s->overhead = 0; | ||
819 | GNUNET_CONTAINER_DLL_remove (s->msg_head, | ||
820 | s->msg_tail, | ||
821 | msg); | ||
822 | GNUNET_assert (0 < s->msgs_in_queue); | ||
823 | s->msgs_in_queue--; | ||
824 | GNUNET_assert (msg->size <= s->bytes_in_queue); | ||
825 | s->bytes_in_queue -= msg->size; | ||
826 | GNUNET_free (msg); | ||
827 | msg = t; | ||
828 | } | ||
829 | |||
830 | GNUNET_assert (plugin->cur_connections >= 2); | ||
831 | plugin->cur_connections -= 2; | ||
832 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
833 | HTTP_STAT_STR_CONNECTIONS, | ||
834 | plugin->cur_connections, | ||
835 | GNUNET_NO); | ||
836 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 802 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
837 | "Session %p: notifying transport about ending session\n",s); | 803 | "Session %p: notifying transport about ending session\n",s); |
838 | 804 | plugin->env->session_end (plugin->env->cls, | |
839 | plugin->env->session_end (plugin->env->cls, s->address, s); | 805 | s->address, |
806 | s); | ||
840 | client_delete_session (s); | 807 | client_delete_session (s); |
841 | 808 | ||
842 | /* Re-schedule since handles have changed */ | 809 | /* Re-schedule since handles have changed */ |
@@ -847,7 +814,7 @@ http_client_plugin_session_disconnect (void *cls, | |||
847 | } | 814 | } |
848 | client_schedule (plugin, GNUNET_YES); | 815 | client_schedule (plugin, GNUNET_YES); |
849 | 816 | ||
850 | return res; | 817 | return GNUNET_OK; |
851 | } | 818 | } |
852 | 819 | ||
853 | 820 | ||
@@ -993,11 +960,13 @@ client_put_disconnect (void *cls, | |||
993 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; | 960 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; |
994 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 961 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
995 | "Session %p/connection %p: will be disconnected due to no activity\n", | 962 | "Session %p/connection %p: will be disconnected due to no activity\n", |
996 | s, s->client_put); | 963 | s, |
964 | s->client_put); | ||
997 | s->put_paused = GNUNET_NO; | 965 | s->put_paused = GNUNET_NO; |
998 | s->put_tmp_disconnecting = GNUNET_YES; | 966 | s->put_tmp_disconnecting = GNUNET_YES; |
999 | if (NULL != s->client_put) | 967 | if (NULL != s->client_put) |
1000 | curl_easy_pause (s->client_put, CURLPAUSE_CONT); | 968 | curl_easy_pause (s->client_put, |
969 | CURLPAUSE_CONT); | ||
1001 | client_schedule (s->plugin, GNUNET_YES); | 970 | client_schedule (s->plugin, GNUNET_YES); |
1002 | } | 971 | } |
1003 | 972 | ||
@@ -1284,24 +1253,23 @@ client_run (void *cls, | |||
1284 | int running; | 1253 | int running; |
1285 | long http_statuscode; | 1254 | long http_statuscode; |
1286 | CURLMcode mret; | 1255 | CURLMcode mret; |
1256 | CURLMsg *msg; | ||
1257 | int msgs_left; | ||
1287 | 1258 | ||
1288 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | 1259 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; |
1289 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 1260 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
1290 | return; | 1261 | return; |
1291 | |||
1292 | do | 1262 | do |
1293 | { | 1263 | { |
1294 | running = 0; | 1264 | running = 0; |
1295 | mret = curl_multi_perform (plugin->curl_multi_handle, &running); | 1265 | mret = curl_multi_perform (plugin->curl_multi_handle, &running); |
1296 | 1266 | ||
1297 | CURLMsg *msg; | ||
1298 | int msgs_left; | ||
1299 | 1267 | ||
1300 | while ((msg = curl_multi_info_read (plugin->curl_multi_handle, &msgs_left))) | 1268 | while ((msg = curl_multi_info_read (plugin->curl_multi_handle, &msgs_left))) |
1301 | { | 1269 | { |
1302 | CURL *easy_h = msg->easy_handle; | 1270 | CURL *easy_h = msg->easy_handle; |
1303 | struct Session *s = NULL; | 1271 | struct Session *s = NULL; |
1304 | char *d = (char *) s; | 1272 | char *d = NULL; /* curl requires 'd' to be a 'char *' */ |
1305 | 1273 | ||
1306 | if (NULL == easy_h) | 1274 | if (NULL == easy_h) |
1307 | { | 1275 | { |
@@ -1316,80 +1284,88 @@ client_run (void *cls, | |||
1316 | GNUNET_assert (CURLE_OK == | 1284 | GNUNET_assert (CURLE_OK == |
1317 | curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); | 1285 | curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); |
1318 | s = (struct Session *) d; | 1286 | s = (struct Session *) d; |
1319 | GNUNET_assert (s != NULL); | 1287 | GNUNET_assert (NULL != s); |
1320 | if (msg->msg == CURLMSG_DONE) | 1288 | if (msg->msg == CURLMSG_DONE) |
1321 | { | 1289 | { |
1322 | GNUNET_break (CURLE_OK == curl_easy_getinfo (easy_h, | 1290 | GNUNET_break (CURLE_OK == |
1323 | CURLINFO_RESPONSE_CODE, &http_statuscode)); | 1291 | curl_easy_getinfo (easy_h, |
1292 | CURLINFO_RESPONSE_CODE, | ||
1293 | &http_statuscode)); | ||
1324 | if (easy_h == s->client_put) | 1294 | if (easy_h == s->client_put) |
1325 | { | 1295 | { |
1326 | if ((0 != msg->data.result) || (http_statuscode != 200)) | 1296 | if ((0 != msg->data.result) || (http_statuscode != 200)) |
1327 | { | 1297 | { |
1328 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1298 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1329 | "Session %p/connection %p: PUT connection to `%s' ended with status %i reason %i: `%s'\n", | 1299 | "Session %p/connection %p: PUT connection to `%s' ended with status %i reason %i: `%s'\n", |
1330 | s, msg->easy_handle, | 1300 | s, msg->easy_handle, |
1331 | GNUNET_i2s (&s->target), | 1301 | GNUNET_i2s (&s->target), |
1332 | http_statuscode, | 1302 | http_statuscode, |
1333 | msg->data.result, | 1303 | msg->data.result, |
1334 | curl_easy_strerror (msg->data.result)); | 1304 | curl_easy_strerror (msg->data.result)); |
1335 | } | 1305 | } |
1336 | else | 1306 | else |
1337 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1307 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1338 | "Session %p/connection %p: PUT connection to `%s' ended normal\n", | 1308 | "Session %p/connection %p: PUT connection to `%s' ended normal\n", |
1339 | s, msg->easy_handle, | 1309 | s, msg->easy_handle, |
1340 | GNUNET_i2s (&s->target)); | 1310 | GNUNET_i2s (&s->target)); |
1341 | if (NULL == s->client_get) | 1311 | if (NULL == s->client_get) |
1342 | { | 1312 | { |
1343 | /* Disconnect other transmission direction and tell transport */ | 1313 | /* Disconnect other transmission direction and tell transport */ |
1344 | /* FIXME? */ | 1314 | /* FIXME? */ |
1345 | } | 1315 | } |
1346 | curl_multi_remove_handle (plugin->curl_multi_handle, easy_h); | 1316 | curl_multi_remove_handle (plugin->curl_multi_handle, |
1347 | curl_easy_cleanup (easy_h); | 1317 | easy_h); |
1348 | s->put_tmp_disconnecting = GNUNET_NO; | 1318 | curl_easy_cleanup (easy_h); |
1349 | s->put_tmp_disconnected = GNUNET_YES; | 1319 | GNUNET_assert (plugin->cur_connections > 0); |
1350 | s->client_put = NULL; | 1320 | plugin->cur_connections--; |
1351 | s->put.easyhandle = NULL; | 1321 | s->put_tmp_disconnecting = GNUNET_NO; |
1352 | s->put.s = NULL; | 1322 | s->put_tmp_disconnected = GNUNET_YES; |
1353 | 1323 | s->client_put = NULL; | |
1354 | /* | 1324 | s->put.easyhandle = NULL; |
1355 | * Handling a rare case: | 1325 | s->put.s = NULL; |
1356 | * plugin_send was called during temporary put disconnect, | 1326 | |
1357 | * reconnect required after connection was disconnected | 1327 | /* |
1358 | */ | 1328 | * Handling a rare case: |
1359 | if (GNUNET_YES == s->put_reconnect_required) | 1329 | * plugin_send was called during temporary put disconnect, |
1330 | * reconnect required after connection was disconnected | ||
1331 | */ | ||
1332 | if (GNUNET_YES == s->put_reconnect_required) | ||
1333 | { | ||
1334 | s->put_reconnect_required = GNUNET_NO; | ||
1335 | if (GNUNET_SYSERR == client_connect_put (s)) | ||
1360 | { | 1336 | { |
1361 | s->put_reconnect_required = GNUNET_NO; | 1337 | GNUNET_break (s->client_put == NULL); |
1362 | if (GNUNET_SYSERR == client_connect_put (s)) | 1338 | GNUNET_break (s->put_tmp_disconnected == GNUNET_NO); |
1363 | { | ||
1364 | GNUNET_break (s->client_put == NULL); | ||
1365 | GNUNET_break (s->put_tmp_disconnected == GNUNET_NO); | ||
1366 | } | ||
1367 | } | 1339 | } |
1340 | } | ||
1368 | } | 1341 | } |
1369 | if (easy_h == s->client_get) | 1342 | if (easy_h == s->client_get) |
1370 | { | 1343 | { |
1371 | if ((0 != msg->data.result) || (http_statuscode != 200)) | 1344 | if ((0 != msg->data.result) || (http_statuscode != 200)) |
1372 | { | 1345 | { |
1373 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1346 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1374 | "Session %p/connection %p: GET connection to `%s' ended with status %i reason %i: `%s'\n", | 1347 | "Session %p/connection %p: GET connection to `%s' ended with status %i reason %i: `%s'\n", |
1375 | s, | 1348 | s, |
1376 | msg->easy_handle, | 1349 | msg->easy_handle, |
1377 | GNUNET_i2s (&s->target), | 1350 | GNUNET_i2s (&s->target), |
1378 | http_statuscode, | 1351 | http_statuscode, |
1379 | msg->data.result, | 1352 | msg->data.result, |
1380 | curl_easy_strerror (msg->data.result)); | 1353 | curl_easy_strerror (msg->data.result)); |
1381 | 1354 | ||
1382 | } | 1355 | } |
1383 | else | 1356 | else |
1384 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1357 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1385 | "Session %p/connection %p: GET connection to `%s' ended normal\n", | 1358 | "Session %p/connection %p: GET connection to `%s' ended normal\n", |
1386 | s, | 1359 | s, |
1387 | msg->easy_handle, | 1360 | msg->easy_handle, |
1388 | GNUNET_i2s (&s->target)); | 1361 | GNUNET_i2s (&s->target)); |
1389 | /* Disconnect other transmission direction and tell transport */ | 1362 | /* Disconnect other transmission direction and tell transport */ |
1390 | s->get.easyhandle = NULL; | 1363 | s->get.easyhandle = NULL; |
1391 | s->get.s = NULL; | 1364 | s->get.s = NULL; |
1392 | http_client_plugin_session_disconnect (plugin, s); | 1365 | /* FIXME: who calls curl_multi_remove on 'easy_h' now!? */ |
1366 | GNUNET_assert (plugin->cur_connections > 0); | ||
1367 | plugin->cur_connections--; | ||
1368 | http_client_plugin_session_disconnect (plugin, s); | ||
1393 | } | 1369 | } |
1394 | } | 1370 | } |
1395 | } | 1371 | } |
@@ -1423,6 +1399,7 @@ client_connect_get (struct Session *s) | |||
1423 | curl_easy_setopt (s->client_get, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); | 1399 | curl_easy_setopt (s->client_get, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); |
1424 | { | 1400 | { |
1425 | struct HttpAddress *ha; | 1401 | struct HttpAddress *ha; |
1402 | |||
1426 | ha = (struct HttpAddress *) s->address->address; | 1403 | ha = (struct HttpAddress *) s->address->address; |
1427 | 1404 | ||
1428 | if (HTTP_OPTIONS_VERIFY_CERTIFICATE == | 1405 | if (HTTP_OPTIONS_VERIFY_CERTIFICATE == |
@@ -1444,7 +1421,7 @@ client_connect_get (struct Session *s) | |||
1444 | curl_easy_setopt (s->client_get, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); | 1421 | curl_easy_setopt (s->client_get, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); |
1445 | #endif | 1422 | #endif |
1446 | 1423 | ||
1447 | if (s->plugin->proxy_hostname != NULL) | 1424 | if (NULL != s->plugin->proxy_hostname) |
1448 | { | 1425 | { |
1449 | curl_easy_setopt (s->client_get, CURLOPT_PROXY, s->plugin->proxy_hostname); | 1426 | curl_easy_setopt (s->client_get, CURLOPT_PROXY, s->plugin->proxy_hostname); |
1450 | curl_easy_setopt (s->client_get, CURLOPT_PROXYTYPE, s->plugin->proxytype); | 1427 | curl_easy_setopt (s->client_get, CURLOPT_PROXYTYPE, s->plugin->proxytype); |
@@ -1478,8 +1455,9 @@ client_connect_get (struct Session *s) | |||
1478 | #endif | 1455 | #endif |
1479 | curl_easy_setopt (s->client_get, CURLOPT_FOLLOWLOCATION, 0); | 1456 | curl_easy_setopt (s->client_get, CURLOPT_FOLLOWLOCATION, 0); |
1480 | 1457 | ||
1481 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, s->client_get); | 1458 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, |
1482 | if (mret != CURLM_OK) | 1459 | s->client_get); |
1460 | if (CURLM_OK != mret) | ||
1483 | { | 1461 | { |
1484 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1462 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1485 | "Session %p : Failed to add GET handle to multihandle: `%s'\n", | 1463 | "Session %p : Failed to add GET handle to multihandle: `%s'\n", |
@@ -1492,7 +1470,7 @@ client_connect_get (struct Session *s) | |||
1492 | GNUNET_break (0); | 1470 | GNUNET_break (0); |
1493 | return GNUNET_SYSERR; | 1471 | return GNUNET_SYSERR; |
1494 | } | 1472 | } |
1495 | 1473 | s->plugin->cur_connections++; | |
1496 | return GNUNET_OK; | 1474 | return GNUNET_OK; |
1497 | } | 1475 | } |
1498 | 1476 | ||
@@ -1576,8 +1554,9 @@ client_connect_put (struct Session *s) | |||
1576 | #if CURL_TCP_NODELAY | 1554 | #if CURL_TCP_NODELAY |
1577 | curl_easy_setopt (s->client_put, CURLOPT_TCP_NODELAY, 1); | 1555 | curl_easy_setopt (s->client_put, CURLOPT_TCP_NODELAY, 1); |
1578 | #endif | 1556 | #endif |
1579 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, s->client_put); | 1557 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, |
1580 | if (mret != CURLM_OK) | 1558 | s->client_put); |
1559 | if (CURLM_OK != mret) | ||
1581 | { | 1560 | { |
1582 | LOG (GNUNET_ERROR_TYPE_ERROR, | 1561 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1583 | "Session %p : Failed to add PUT handle to multihandle: `%s'\n", | 1562 | "Session %p : Failed to add PUT handle to multihandle: `%s'\n", |
@@ -1591,6 +1570,8 @@ client_connect_put (struct Session *s) | |||
1591 | return GNUNET_SYSERR; | 1570 | return GNUNET_SYSERR; |
1592 | } | 1571 | } |
1593 | s->put_tmp_disconnected = GNUNET_NO; | 1572 | s->put_tmp_disconnected = GNUNET_NO; |
1573 | s->plugin->cur_connections++; | ||
1574 | |||
1594 | return GNUNET_OK; | 1575 | return GNUNET_OK; |
1595 | } | 1576 | } |
1596 | 1577 | ||
@@ -1632,11 +1613,7 @@ client_connect (struct Session *s) | |||
1632 | 1613 | ||
1633 | if ((GNUNET_SYSERR == client_connect_get (s)) || | 1614 | if ((GNUNET_SYSERR == client_connect_get (s)) || |
1634 | (GNUNET_SYSERR == client_connect_put (s))) | 1615 | (GNUNET_SYSERR == client_connect_put (s))) |
1635 | { | ||
1636 | plugin->env->session_end (plugin->env->cls, s->address, s); | ||
1637 | client_delete_session (s); | ||
1638 | return GNUNET_SYSERR; | 1616 | return GNUNET_SYSERR; |
1639 | } | ||
1640 | 1617 | ||
1641 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1618 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1642 | "Session %p: connected with connections GET %p and PUT %p\n", | 1619 | "Session %p: connected with connections GET %p and PUT %p\n", |
@@ -1644,7 +1621,6 @@ client_connect (struct Session *s) | |||
1644 | s->client_get, | 1621 | s->client_get, |
1645 | s->client_put); | 1622 | s->client_put); |
1646 | /* Perform connect */ | 1623 | /* Perform connect */ |
1647 | plugin->cur_connections += 2; | ||
1648 | GNUNET_STATISTICS_set (plugin->env->stats, | 1624 | GNUNET_STATISTICS_set (plugin->env->stats, |
1649 | HTTP_STAT_STR_CONNECTIONS, | 1625 | HTTP_STAT_STR_CONNECTIONS, |
1650 | plugin->cur_connections, | 1626 | plugin->cur_connections, |
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 0db5e31c5..ab6b0d1da 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c | |||
@@ -23,6 +23,7 @@ | |||
23 | * @brief HTTP/S server transport plugin | 23 | * @brief HTTP/S server transport plugin |
24 | * @author Matthias Wachs | 24 | * @author Matthias Wachs |
25 | * @author David Barksdale | 25 | * @author David Barksdale |
26 | * @author Christian Grothoff | ||
26 | */ | 27 | */ |
27 | #include "platform.h" | 28 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
@@ -223,11 +224,31 @@ struct Session | |||
223 | struct GNUNET_TIME_Absolute next_receive; | 224 | struct GNUNET_TIME_Absolute next_receive; |
224 | 225 | ||
225 | /** | 226 | /** |
227 | * Absolute time when this connection will time out. | ||
228 | */ | ||
229 | struct GNUNET_TIME_Absolute timeout; | ||
230 | |||
231 | /** | ||
226 | * Session timeout task | 232 | * Session timeout task |
227 | */ | 233 | */ |
228 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 234 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
229 | 235 | ||
230 | /** | 236 | /** |
237 | * Task to resume MHD handling when receiving is allowed again | ||
238 | */ | ||
239 | GNUNET_SCHEDULER_TaskIdentifier recv_wakeup_task; | ||
240 | |||
241 | /** | ||
242 | * Number of bytes waiting for transmission to this peer. | ||
243 | */ | ||
244 | unsigned long long bytes_in_queue; | ||
245 | |||
246 | /** | ||
247 | * Number of messages waiting for transmission to this peer. | ||
248 | */ | ||
249 | unsigned int msgs_in_queue; | ||
250 | |||
251 | /** | ||
231 | * Unique HTTP/S connection tag for this connection | 252 | * Unique HTTP/S connection tag for this connection |
232 | */ | 253 | */ |
233 | uint32_t tag; | 254 | uint32_t tag; |
@@ -295,6 +316,7 @@ struct HTTP_Server_Plugin | |||
295 | * NAT handle & address management | 316 | * NAT handle & address management |
296 | */ | 317 | */ |
297 | struct GNUNET_NAT_Handle *nat; | 318 | struct GNUNET_NAT_Handle *nat; |
319 | |||
298 | /** | 320 | /** |
299 | * IPv4 addresses DLL head | 321 | * IPv4 addresses DLL head |
300 | */ | 322 | */ |
@@ -453,10 +475,10 @@ notify_session_monitor (struct HTTP_Server_Plugin *plugin, | |||
453 | memset (&info, 0, sizeof (info)); | 475 | memset (&info, 0, sizeof (info)); |
454 | info.state = state; | 476 | info.state = state; |
455 | info.is_inbound = GNUNET_YES; | 477 | info.is_inbound = GNUNET_YES; |
456 | // info.num_msg_pending = session->msgs_in_queue; // FIXME | 478 | info.num_msg_pending = session->msgs_in_queue; |
457 | // info.num_bytes_pending = session->bytes_in_queue; // FIXME | 479 | info.num_bytes_pending = session->bytes_in_queue; |
458 | // info.receive_delay = session->next_receive; // FIXME | 480 | info.receive_delay = session->next_receive; |
459 | // info.session_timeout = session->timeout; // FIXME | 481 | info.session_timeout = session->timeout; |
460 | info.address = session->address; | 482 | info.address = session->address; |
461 | plugin->sic (plugin->sic_cls, | 483 | plugin->sic (plugin->sic_cls, |
462 | session, | 484 | session, |
@@ -465,6 +487,28 @@ notify_session_monitor (struct HTTP_Server_Plugin *plugin, | |||
465 | 487 | ||
466 | 488 | ||
467 | /** | 489 | /** |
490 | * Wake up an MHD connection which was suspended | ||
491 | * | ||
492 | * @param cls the session | ||
493 | * @param tc task context | ||
494 | */ | ||
495 | static void | ||
496 | server_wake_up (void *cls, | ||
497 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
498 | { | ||
499 | struct Session *s = cls; | ||
500 | |||
501 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
502 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
503 | return; | ||
504 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
505 | "Session %p: Waking up PUT handle\n", | ||
506 | s); | ||
507 | MHD_resume_connection (s->server_recv->mhd_conn); | ||
508 | } | ||
509 | |||
510 | |||
511 | /** | ||
468 | * Reschedule the execution of both IPv4 and IPv6 server. | 512 | * Reschedule the execution of both IPv4 and IPv6 server. |
469 | * | 513 | * |
470 | * @param plugin the plugin | 514 | * @param plugin the plugin |
@@ -488,7 +532,6 @@ server_delete_session (struct Session *s) | |||
488 | { | 532 | { |
489 | struct HTTP_Server_Plugin *plugin = s->plugin; | 533 | struct HTTP_Server_Plugin *plugin = s->plugin; |
490 | struct HTTP_Message *msg; | 534 | struct HTTP_Message *msg; |
491 | struct HTTP_Message *tmp; | ||
492 | struct ServerConnection *send; | 535 | struct ServerConnection *send; |
493 | struct ServerConnection *recv; | 536 | struct ServerConnection *recv; |
494 | 537 | ||
@@ -496,15 +539,21 @@ server_delete_session (struct Session *s) | |||
496 | { | 539 | { |
497 | GNUNET_SCHEDULER_cancel (s->timeout_task); | 540 | GNUNET_SCHEDULER_cancel (s->timeout_task); |
498 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 541 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
542 | s->timeout = GNUNET_TIME_UNIT_ZERO_ABS; | ||
543 | } | ||
544 | if (GNUNET_SCHEDULER_NO_TASK != s->recv_wakeup_task) | ||
545 | { | ||
546 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
547 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
548 | if (NULL != s->server_recv) | ||
549 | MHD_resume_connection (s->server_recv->mhd_conn); | ||
499 | } | 550 | } |
500 | GNUNET_assert (GNUNET_OK == | 551 | GNUNET_assert (GNUNET_OK == |
501 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, | 552 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, |
502 | &s->target, | 553 | &s->target, |
503 | s)); | 554 | s)); |
504 | msg = s->msg_head; | 555 | while (NULL != (msg = s->msg_head)) |
505 | while (NULL != msg) | ||
506 | { | 556 | { |
507 | tmp = msg->next; | ||
508 | GNUNET_CONTAINER_DLL_remove (s->msg_head, | 557 | GNUNET_CONTAINER_DLL_remove (s->msg_head, |
509 | s->msg_tail, | 558 | s->msg_tail, |
510 | msg); | 559 | msg); |
@@ -514,9 +563,14 @@ server_delete_session (struct Session *s) | |||
514 | GNUNET_SYSERR, | 563 | GNUNET_SYSERR, |
515 | msg->size, | 564 | msg->size, |
516 | msg->pos + msg->overhead); | 565 | msg->pos + msg->overhead); |
566 | GNUNET_assert (s->msgs_in_queue > 0); | ||
567 | s->msgs_in_queue--; | ||
568 | GNUNET_assert (s->bytes_in_queue >= msg->size); | ||
569 | s->bytes_in_queue -= msg->size; | ||
517 | GNUNET_free (msg); | 570 | GNUNET_free (msg); |
518 | msg = tmp; | ||
519 | } | 571 | } |
572 | GNUNET_assert (0 == s->msgs_in_queue); | ||
573 | GNUNET_assert (0 == s->bytes_in_queue); | ||
520 | send = s->server_send; | 574 | send = s->server_send; |
521 | if (NULL != send) | 575 | if (NULL != send) |
522 | { | 576 | { |
@@ -546,6 +600,9 @@ server_delete_session (struct Session *s) | |||
546 | recv->mhd_daemon, | 600 | recv->mhd_daemon, |
547 | GNUNET_YES); | 601 | GNUNET_YES); |
548 | } | 602 | } |
603 | notify_session_monitor (plugin, | ||
604 | s, | ||
605 | GNUNET_TRANSPORT_SS_DOWN); | ||
549 | if (GNUNET_YES == s->known_to_service) | 606 | if (GNUNET_YES == s->known_to_service) |
550 | plugin->env->session_end (plugin->env->cls, | 607 | plugin->env->session_end (plugin->env->cls, |
551 | s->address, | 608 | s->address, |
@@ -591,8 +648,22 @@ server_session_timeout (void *cls, | |||
591 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 648 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
592 | { | 649 | { |
593 | struct Session *s = cls; | 650 | struct Session *s = cls; |
651 | struct GNUNET_TIME_Relative left; | ||
594 | 652 | ||
595 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 653 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
654 | left = GNUNET_TIME_absolute_get_remaining (s->timeout); | ||
655 | if (0 != left.rel_value_us) | ||
656 | { | ||
657 | /* not actually our turn yet, but let's at least update | ||
658 | the monitor, it may think we're about to die ... */ | ||
659 | notify_session_monitor (s->plugin, | ||
660 | s, | ||
661 | GNUNET_TRANSPORT_SS_UP); | ||
662 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (left, | ||
663 | &server_session_timeout, | ||
664 | s); | ||
665 | return; | ||
666 | } | ||
596 | GNUNET_log (TIMEOUT_LOG, | 667 | GNUNET_log (TIMEOUT_LOG, |
597 | "Session %p was idle for %s, disconnecting\n", | 668 | "Session %p was idle for %s, disconnecting\n", |
598 | s, | 669 | s, |
@@ -611,15 +682,7 @@ static void | |||
611 | server_reschedule_session_timeout (struct Session *s) | 682 | server_reschedule_session_timeout (struct Session *s) |
612 | { | 683 | { |
613 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); | 684 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); |
614 | GNUNET_SCHEDULER_cancel (s->timeout_task); | 685 | s->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
615 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (HTTP_SERVER_SESSION_TIMEOUT, | ||
616 | &server_session_timeout, | ||
617 | s); | ||
618 | GNUNET_log (TIMEOUT_LOG, | ||
619 | "Timeout rescheduled for session %p set to %s\n", | ||
620 | s, | ||
621 | GNUNET_STRINGS_relative_time_to_string (HTTP_SERVER_SESSION_TIMEOUT, | ||
622 | GNUNET_YES)); | ||
623 | } | 686 | } |
624 | 687 | ||
625 | 688 | ||
@@ -681,10 +744,17 @@ http_server_plugin_send (void *cls, | |||
681 | msg->buf = (char *) &msg[1]; | 744 | msg->buf = (char *) &msg[1]; |
682 | msg->transmit_cont = cont; | 745 | msg->transmit_cont = cont; |
683 | msg->transmit_cont_cls = cont_cls; | 746 | msg->transmit_cont_cls = cont_cls; |
684 | memcpy (msg->buf, msgbuf, msgbuf_size); | 747 | memcpy (msg->buf, |
748 | msgbuf, | ||
749 | msgbuf_size); | ||
685 | GNUNET_CONTAINER_DLL_insert_tail (session->msg_head, | 750 | GNUNET_CONTAINER_DLL_insert_tail (session->msg_head, |
686 | session->msg_tail, | 751 | session->msg_tail, |
687 | msg); | 752 | msg); |
753 | session->msgs_in_queue++; | ||
754 | session->bytes_in_queue += msg->size; | ||
755 | notify_session_monitor (plugin, | ||
756 | session, | ||
757 | GNUNET_TRANSPORT_SS_UP); | ||
688 | GNUNET_asprintf (&stat_txt, | 758 | GNUNET_asprintf (&stat_txt, |
689 | "# bytes currently in %s_server buffers", | 759 | "# bytes currently in %s_server buffers", |
690 | plugin->protocol); | 760 | plugin->protocol); |
@@ -1018,6 +1088,15 @@ http_server_query_keepalive_factor (void *cls) | |||
1018 | } | 1088 | } |
1019 | 1089 | ||
1020 | 1090 | ||
1091 | /** | ||
1092 | * Function that will be called whenever the transport service wants to | ||
1093 | * notify the plugin that a session is still active and in use and | ||
1094 | * therefore the session timeout for this session has to be updated | ||
1095 | * | ||
1096 | * @param cls closure | ||
1097 | * @param peer which peer was the session for | ||
1098 | * @param session which session is being updated | ||
1099 | */ | ||
1021 | static void | 1100 | static void |
1022 | http_server_plugin_update_session_timeout (void *cls, | 1101 | http_server_plugin_update_session_timeout (void *cls, |
1023 | const struct GNUNET_PeerIdentity *peer, | 1102 | const struct GNUNET_PeerIdentity *peer, |
@@ -1094,8 +1173,8 @@ server_parse_url (struct HTTP_Server_Plugin *plugin, | |||
1094 | 1173 | ||
1095 | if (NULL == url) | 1174 | if (NULL == url) |
1096 | { | 1175 | { |
1097 | GNUNET_break (0); | 1176 | GNUNET_break (0); |
1098 | return GNUNET_SYSERR; | 1177 | return GNUNET_SYSERR; |
1099 | } | 1178 | } |
1100 | 1179 | ||
1101 | if (regexec(&plugin->url_regex, url, 4, matches, 0)) | 1180 | if (regexec(&plugin->url_regex, url, 4, matches, 0)) |
@@ -1162,9 +1241,12 @@ server_parse_url (struct HTTP_Server_Plugin *plugin, | |||
1162 | GNUNET_i2s_full (target)); | 1241 | GNUNET_i2s_full (target)); |
1163 | 1242 | ||
1164 | /* convert options */ | 1243 | /* convert options */ |
1165 | if (-1 == matches[3].rm_so) { | 1244 | if (-1 == matches[3].rm_so) |
1166 | *options = 0; | 1245 | { |
1167 | } else { | 1246 | *options = 0; |
1247 | } | ||
1248 | else | ||
1249 | { | ||
1168 | rc = strtoul (&url[matches[3].rm_so + 1], &options_end, 10); | 1250 | rc = strtoul (&url[matches[3].rm_so + 1], &options_end, 10); |
1169 | if (&url[matches[3].rm_eo] != options_end) | 1251 | if (&url[matches[3].rm_eo] != options_end) |
1170 | { | 1252 | { |
@@ -1184,9 +1266,10 @@ server_parse_url (struct HTTP_Server_Plugin *plugin, | |||
1184 | "URL options > UINT32_MAX\n"); | 1266 | "URL options > UINT32_MAX\n"); |
1185 | return GNUNET_SYSERR; | 1267 | return GNUNET_SYSERR; |
1186 | } | 1268 | } |
1187 | (*options) = (uint32_t)rc; | 1269 | (*options) = (uint32_t) rc; |
1188 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1270 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1189 | "Found options `%u' in url\n", *options); | 1271 | "Found options `%u' in url\n", |
1272 | *options); | ||
1190 | } | 1273 | } |
1191 | return GNUNET_OK; | 1274 | return GNUNET_OK; |
1192 | } | 1275 | } |
@@ -1344,6 +1427,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, | |||
1344 | s->ats_address_network_type = ats.value; | 1427 | s->ats_address_network_type = ats.value; |
1345 | s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS; | 1428 | s->next_receive = GNUNET_TIME_UNIT_ZERO_ABS; |
1346 | s->tag = stc.tag; | 1429 | s->tag = stc.tag; |
1430 | s->timeout = GNUNET_TIME_relative_to_absolute (HTTP_SERVER_SESSION_TIMEOUT); | ||
1347 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (HTTP_SERVER_SESSION_TIMEOUT, | 1431 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (HTTP_SERVER_SESSION_TIMEOUT, |
1348 | &server_session_timeout, | 1432 | &server_session_timeout, |
1349 | s); | 1433 | s); |
@@ -1351,7 +1435,9 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, | |||
1351 | &s->target, | 1435 | &s->target, |
1352 | s, | 1436 | s, |
1353 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 1437 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
1354 | 1438 | notify_session_monitor (plugin, | |
1439 | s, | ||
1440 | GNUNET_TRANSPORT_SS_HANDSHAKE); | ||
1355 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1441 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1356 | "Creating new session %p for peer `%s' connecting from `%s'\n", | 1442 | "Creating new session %p for peer `%s' connecting from `%s'\n", |
1357 | s, GNUNET_i2s (&target), | 1443 | s, GNUNET_i2s (&target), |
@@ -1361,7 +1447,8 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, | |||
1361 | GNUNET_free_non_null (addr); | 1447 | GNUNET_free_non_null (addr); |
1362 | } | 1448 | } |
1363 | 1449 | ||
1364 | if ( (_RECEIVE == direction) && (NULL != s->server_recv) ) | 1450 | if ( (_RECEIVE == direction) && |
1451 | (NULL != s->server_recv) ) | ||
1365 | { | 1452 | { |
1366 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1453 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1367 | "Duplicate PUT connection from `%s' tag %u, dismissing new connection\n", | 1454 | "Duplicate PUT connection from `%s' tag %u, dismissing new connection\n", |
@@ -1392,13 +1479,15 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, | |||
1392 | if (direction == _RECEIVE) | 1479 | if (direction == _RECEIVE) |
1393 | s->server_recv = sc; | 1480 | s->server_recv = sc; |
1394 | 1481 | ||
1395 | if ((NULL != s->server_send) && (NULL != s->server_recv)) | 1482 | if ( (NULL != s->server_send) && |
1483 | (NULL != s->server_recv) ) | ||
1396 | { | 1484 | { |
1397 | s->known_to_service = GNUNET_YES; | 1485 | s->known_to_service = GNUNET_YES; |
1398 | plugin->env->session_start (NULL, s->address ,s, NULL, 0); | 1486 | plugin->env->session_start (NULL, s->address ,s, NULL, 0); |
1399 | } | 1487 | } |
1400 | 1488 | ||
1401 | if ((NULL == s->server_recv) || (NULL == s->server_send)) | 1489 | if ( (NULL == s->server_recv) || |
1490 | (NULL == s->server_send) ) | ||
1402 | { | 1491 | { |
1403 | to = (HTTP_SERVER_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL / 1000LL); | 1492 | to = (HTTP_SERVER_NOT_VALIDATED_TIMEOUT.rel_value_us / 1000LL / 1000LL); |
1404 | MHD_set_connection_option (mhd_connection, | 1493 | MHD_set_connection_option (mhd_connection, |
@@ -1425,8 +1514,8 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, | |||
1425 | * @param cls current session | 1514 | * @param cls current session |
1426 | * @param pos position in buffer | 1515 | * @param pos position in buffer |
1427 | * @param buf the buffer to write data to | 1516 | * @param buf the buffer to write data to |
1428 | * @param max max number of bytes available in buffer | 1517 | * @param max max number of bytes available in @a buf |
1429 | * @return bytes written to buffer | 1518 | * @return bytes written to @a buf |
1430 | */ | 1519 | */ |
1431 | static ssize_t | 1520 | static ssize_t |
1432 | server_send_callback (void *cls, | 1521 | server_send_callback (void *cls, |
@@ -1461,7 +1550,14 @@ server_send_callback (void *cls, | |||
1461 | if (NULL != msg->transmit_cont) | 1550 | if (NULL != msg->transmit_cont) |
1462 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK, | 1551 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_OK, |
1463 | msg->size, msg->size + msg->overhead); | 1552 | msg->size, msg->size + msg->overhead); |
1553 | GNUNET_assert (s->msgs_in_queue > 0); | ||
1554 | s->msgs_in_queue--; | ||
1555 | GNUNET_assert (s->bytes_in_queue >= msg->size); | ||
1556 | s->bytes_in_queue -= msg->size; | ||
1464 | GNUNET_free (msg); | 1557 | GNUNET_free (msg); |
1558 | notify_session_monitor (s->plugin, | ||
1559 | s, | ||
1560 | GNUNET_TRANSPORT_SS_UP); | ||
1465 | } | 1561 | } |
1466 | } | 1562 | } |
1467 | if (0 < bytes_read) | 1563 | if (0 < bytes_read) |
@@ -1469,13 +1565,19 @@ server_send_callback (void *cls, | |||
1469 | sc->connected = GNUNET_YES; | 1565 | sc->connected = GNUNET_YES; |
1470 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1566 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1471 | "Sent %u bytes to peer `%s' with session %p \n", | 1567 | "Sent %u bytes to peer `%s' with session %p \n", |
1472 | bytes_read, GNUNET_i2s (&s->target), s); | 1568 | bytes_read, |
1473 | GNUNET_asprintf (&stat_txt, "# bytes currently in %s_server buffers", | 1569 | GNUNET_i2s (&s->target), |
1570 | s); | ||
1571 | GNUNET_asprintf (&stat_txt, | ||
1572 | "# bytes currently in %s_server buffers", | ||
1474 | s->plugin->protocol); | 1573 | s->plugin->protocol); |
1475 | GNUNET_STATISTICS_update (s->plugin->env->stats, | 1574 | GNUNET_STATISTICS_update (s->plugin->env->stats, |
1476 | stat_txt, -bytes_read, GNUNET_NO); | 1575 | stat_txt, |
1576 | - bytes_read, | ||
1577 | GNUNET_NO); | ||
1477 | GNUNET_free (stat_txt); | 1578 | GNUNET_free (stat_txt); |
1478 | GNUNET_asprintf (&stat_txt, "# bytes transmitted via %s_server", | 1579 | GNUNET_asprintf (&stat_txt, |
1580 | "# bytes transmitted via %s_server", | ||
1479 | s->plugin->protocol); | 1581 | s->plugin->protocol); |
1480 | GNUNET_STATISTICS_update (s->plugin->env->stats, | 1582 | GNUNET_STATISTICS_update (s->plugin->env->stats, |
1481 | stat_txt, bytes_read, GNUNET_NO); | 1583 | stat_txt, bytes_read, GNUNET_NO); |
@@ -1484,8 +1586,9 @@ server_send_callback (void *cls, | |||
1484 | else if ((sc->options & OPTION_LONG_POLL) && sc->connected) | 1586 | else if ((sc->options & OPTION_LONG_POLL) && sc->connected) |
1485 | { | 1587 | { |
1486 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1588 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1487 | "Completing GET response to peer `%s' with session %p \n", | 1589 | "Completing GET response to peer `%s' with session %p\n", |
1488 | GNUNET_i2s (&s->target), s); | 1590 | GNUNET_i2s (&s->target), |
1591 | s); | ||
1489 | return MHD_CONTENT_READER_END_OF_STREAM; | 1592 | return MHD_CONTENT_READER_END_OF_STREAM; |
1490 | } | 1593 | } |
1491 | return bytes_read; | 1594 | return bytes_read; |
@@ -1519,7 +1622,14 @@ server_receive_mst_cb (void *cls, | |||
1519 | if (GNUNET_NO == s->known_to_service) | 1622 | if (GNUNET_NO == s->known_to_service) |
1520 | { | 1623 | { |
1521 | s->known_to_service = GNUNET_YES; | 1624 | s->known_to_service = GNUNET_YES; |
1522 | plugin->env->session_start (NULL, s->address, s, NULL, 0); | 1625 | plugin->env->session_start (NULL, |
1626 | s->address, | ||
1627 | s, | ||
1628 | NULL, | ||
1629 | 0); | ||
1630 | notify_session_monitor (plugin, | ||
1631 | s, | ||
1632 | GNUNET_TRANSPORT_SS_UP); | ||
1523 | } | 1633 | } |
1524 | delay = plugin->env->receive (plugin->env->cls, | 1634 | delay = plugin->env->receive (plugin->env->cls, |
1525 | s->address, | 1635 | s->address, |
@@ -1554,6 +1664,8 @@ server_receive_mst_cb (void *cls, | |||
1554 | /** | 1664 | /** |
1555 | * Add headers to a request indicating that we allow Cross-Origin Resource | 1665 | * Add headers to a request indicating that we allow Cross-Origin Resource |
1556 | * Sharing. | 1666 | * Sharing. |
1667 | * | ||
1668 | * @param response response object to modify | ||
1557 | */ | 1669 | */ |
1558 | static void | 1670 | static void |
1559 | add_cors_headers(struct MHD_Response *response) | 1671 | add_cors_headers(struct MHD_Response *response) |
@@ -1579,7 +1691,7 @@ add_cors_headers(struct MHD_Response *response) | |||
1579 | * @param method GET or PUT | 1691 | * @param method GET or PUT |
1580 | * @param version HTTP version | 1692 | * @param version HTTP version |
1581 | * @param upload_data upload data | 1693 | * @param upload_data upload data |
1582 | * @param upload_data_size sizeof upload data | 1694 | * @param upload_data_size size of @a upload_data |
1583 | * @param httpSessionCache the session cache to remember the connection | 1695 | * @param httpSessionCache the session cache to remember the connection |
1584 | * @return MHD_YES if connection is accepted, MHD_NO on reject | 1696 | * @return MHD_YES if connection is accepted, MHD_NO on reject |
1585 | */ | 1697 | */ |
@@ -1705,6 +1817,8 @@ server_access_cb (void *cls, | |||
1705 | } | 1817 | } |
1706 | else if ((*upload_data_size > 0) && (sc->connected == GNUNET_YES)) | 1818 | else if ((*upload_data_size > 0) && (sc->connected == GNUNET_YES)) |
1707 | { | 1819 | { |
1820 | struct GNUNET_TIME_Relative delay; | ||
1821 | |||
1708 | /* (*upload_data_size > 0) for every segment received */ | 1822 | /* (*upload_data_size > 0) for every segment received */ |
1709 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1823 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1710 | "Session %p / Connection %p: Peer `%s' PUT on address `%s' received %u bytes\n", | 1824 | "Session %p / Connection %p: Peer `%s' PUT on address `%s' received %u bytes\n", |
@@ -1714,9 +1828,8 @@ server_access_cb (void *cls, | |||
1714 | s->address->address, | 1828 | s->address->address, |
1715 | s->address->address_length), | 1829 | s->address->address_length), |
1716 | *upload_data_size); | 1830 | *upload_data_size); |
1717 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); | 1831 | delay = GNUNET_TIME_absolute_get_remaining (s->next_receive); |
1718 | 1832 | if (0 == delay.rel_value_us) | |
1719 | if ((s->next_receive.abs_value_us <= now.abs_value_us)) | ||
1720 | { | 1833 | { |
1721 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1834 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1722 | "PUT with %u bytes forwarded to MST\n", | 1835 | "PUT with %u bytes forwarded to MST\n", |
@@ -1725,19 +1838,26 @@ server_access_cb (void *cls, | |||
1725 | { | 1838 | { |
1726 | s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s); | 1839 | s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s); |
1727 | } | 1840 | } |
1728 | GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, | 1841 | GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, |
1729 | *upload_data_size, GNUNET_NO, GNUNET_NO); | 1842 | *upload_data_size, GNUNET_NO, GNUNET_NO); |
1730 | server_mhd_connection_timeout (plugin, s, | 1843 | server_mhd_connection_timeout (plugin, s, |
1731 | GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL / 1000LL); | 1844 | GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL / 1000LL); |
1732 | (*upload_data_size) = 0; | 1845 | (*upload_data_size) = 0; |
1733 | } | 1846 | } |
1734 | else | 1847 | else |
1735 | { | 1848 | { |
1849 | /* delay processing */ | ||
1736 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1850 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1737 | "Session %p / Connection %p: no inbound bandwidth available! Next read was delayed by %s\n", | 1851 | "Session %p / Connection %p: no inbound bandwidth available! Next read was delayed by %s\n", |
1738 | s, sc, | 1852 | s, sc, |
1739 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (s->next_receive), | 1853 | GNUNET_STRINGS_relative_time_to_string (delay, |
1740 | GNUNET_YES)); | 1854 | GNUNET_YES)); |
1855 | GNUNET_assert (s->server_recv->mhd_conn == mhd_connection); | ||
1856 | MHD_suspend_connection (s->server_recv->mhd_conn); | ||
1857 | if (GNUNET_SCHEDULER_NO_TASK == s->recv_wakeup_task) | ||
1858 | s->recv_wakeup_task = GNUNET_SCHEDULER_add_delayed (delay, | ||
1859 | &server_wake_up, | ||
1860 | s); | ||
1741 | } | 1861 | } |
1742 | return MHD_YES; | 1862 | return MHD_YES; |
1743 | } | 1863 | } |
@@ -1832,7 +1952,7 @@ server_disconnect_cb (void *cls, | |||
1832 | * | 1952 | * |
1833 | * @param cls plugin as closure | 1953 | * @param cls plugin as closure |
1834 | * @param addr address of incoming connection | 1954 | * @param addr address of incoming connection |
1835 | * @param addr_len address length of incoming connection | 1955 | * @param addr_len number of bytes in @a addr |
1836 | * @return MHD_YES if connection is accepted, MHD_NO if connection is rejected | 1956 | * @return MHD_YES if connection is accepted, MHD_NO if connection is rejected |
1837 | */ | 1957 | */ |
1838 | static int | 1958 | static int |
@@ -1860,6 +1980,14 @@ server_accept_cb (void *cls, | |||
1860 | } | 1980 | } |
1861 | 1981 | ||
1862 | 1982 | ||
1983 | /** | ||
1984 | * Log function called by MHD. | ||
1985 | * | ||
1986 | * @param arg NULL | ||
1987 | * @param fmt format string | ||
1988 | * @param ap arguments for the format string (va_start() and va_end() | ||
1989 | * will be called by MHD) | ||
1990 | */ | ||
1863 | static void | 1991 | static void |
1864 | server_log (void *arg, | 1992 | server_log (void *arg, |
1865 | const char *fmt, | 1993 | const char *fmt, |
@@ -1867,8 +1995,10 @@ server_log (void *arg, | |||
1867 | { | 1995 | { |
1868 | char text[1024]; | 1996 | char text[1024]; |
1869 | 1997 | ||
1870 | vsnprintf (text, sizeof (text), fmt, ap); | 1998 | vsnprintf (text, |
1871 | va_end (ap); | 1999 | sizeof (text), |
2000 | fmt, | ||
2001 | ap); | ||
1872 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2002 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1873 | "Server: %s\n", | 2003 | "Server: %s\n", |
1874 | text); | 2004 | text); |
@@ -1896,7 +2026,7 @@ server_load_file (const char *file) | |||
1896 | gn_file = | 2026 | gn_file = |
1897 | GNUNET_DISK_file_open (file, GNUNET_DISK_OPEN_READ, | 2027 | GNUNET_DISK_file_open (file, GNUNET_DISK_OPEN_READ, |
1898 | GNUNET_DISK_PERM_USER_READ); | 2028 | GNUNET_DISK_PERM_USER_READ); |
1899 | if (gn_file == NULL) | 2029 | if (NULL == gn_file) |
1900 | { | 2030 | { |
1901 | GNUNET_free (text); | 2031 | GNUNET_free (text); |
1902 | return NULL; | 2032 | return NULL; |
@@ -2114,7 +2244,9 @@ server_start (struct HTTP_Server_Plugin *plugin) | |||
2114 | plugin->name, plugin->port); | 2244 | plugin->name, plugin->port); |
2115 | } | 2245 | } |
2116 | else | 2246 | else |
2117 | server_reschedule (plugin, plugin->server_v4, GNUNET_NO); | 2247 | server_reschedule (plugin, |
2248 | plugin->server_v4, | ||
2249 | GNUNET_NO); | ||
2118 | } | 2250 | } |
2119 | 2251 | ||
2120 | 2252 | ||
@@ -2186,44 +2318,6 @@ server_start (struct HTTP_Server_Plugin *plugin) | |||
2186 | } | 2318 | } |
2187 | 2319 | ||
2188 | 2320 | ||
2189 | static void | ||
2190 | server_stop (struct HTTP_Server_Plugin *plugin) | ||
2191 | { | ||
2192 | if (plugin->server_v4 != NULL) | ||
2193 | { | ||
2194 | MHD_stop_daemon (plugin->server_v4); | ||
2195 | plugin->server_v4 = NULL; | ||
2196 | } | ||
2197 | if ( plugin->server_v6 != NULL) | ||
2198 | { | ||
2199 | MHD_stop_daemon (plugin->server_v6); | ||
2200 | plugin->server_v6 = NULL; | ||
2201 | } | ||
2202 | |||
2203 | |||
2204 | if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK) | ||
2205 | { | ||
2206 | GNUNET_SCHEDULER_cancel (plugin->server_v4_task); | ||
2207 | plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK; | ||
2208 | } | ||
2209 | |||
2210 | if (plugin->server_v6_task != GNUNET_SCHEDULER_NO_TASK) | ||
2211 | { | ||
2212 | GNUNET_SCHEDULER_cancel (plugin->server_v6_task); | ||
2213 | plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; | ||
2214 | } | ||
2215 | #if BUILD_HTTPS | ||
2216 | GNUNET_free_non_null (plugin->crypto_init); | ||
2217 | GNUNET_free_non_null (plugin->cert); | ||
2218 | GNUNET_free_non_null (plugin->key); | ||
2219 | #endif | ||
2220 | |||
2221 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2222 | "%s server component stopped\n", | ||
2223 | plugin->name); | ||
2224 | } | ||
2225 | |||
2226 | |||
2227 | /** | 2321 | /** |
2228 | * Add an address to the server's set of addresses and notify transport | 2322 | * Add an address to the server's set of addresses and notify transport |
2229 | * | 2323 | * |
@@ -2456,8 +2550,7 @@ server_get_addresses (struct HTTP_Server_Plugin *plugin, | |||
2456 | if (port > 65535) | 2550 | if (port > 65535) |
2457 | { | 2551 | { |
2458 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2552 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2459 | _ | 2553 | _("Require valid port number for service in configuration!\n")); |
2460 | ("Require valid port number for service in configuration!\n")); | ||
2461 | return GNUNET_SYSERR; | 2554 | return GNUNET_SYSERR; |
2462 | } | 2555 | } |
2463 | } | 2556 | } |
@@ -2469,7 +2562,8 @@ server_get_addresses (struct HTTP_Server_Plugin *plugin, | |||
2469 | } | 2562 | } |
2470 | 2563 | ||
2471 | 2564 | ||
2472 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) | 2565 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, |
2566 | "BINDTO")) | ||
2473 | { | 2567 | { |
2474 | GNUNET_break (GNUNET_OK == | 2568 | GNUNET_break (GNUNET_OK == |
2475 | GNUNET_CONFIGURATION_get_value_string (cfg, service_name, | 2569 | GNUNET_CONFIGURATION_get_value_string (cfg, service_name, |
@@ -2478,7 +2572,7 @@ server_get_addresses (struct HTTP_Server_Plugin *plugin, | |||
2478 | else | 2572 | else |
2479 | hostname = NULL; | 2573 | hostname = NULL; |
2480 | 2574 | ||
2481 | if (hostname != NULL) | 2575 | if (NULL != hostname) |
2482 | { | 2576 | { |
2483 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2577 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2484 | "Resolving `%s' since that is where `%s' will bind to.\n", | 2578 | "Resolving `%s' since that is where `%s' will bind to.\n", |
@@ -2487,10 +2581,12 @@ server_get_addresses (struct HTTP_Server_Plugin *plugin, | |||
2487 | if (disablev6) | 2581 | if (disablev6) |
2488 | hints.ai_family = AF_INET; | 2582 | hints.ai_family = AF_INET; |
2489 | if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || | 2583 | if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || |
2490 | (res == NULL)) | 2584 | (NULL == res)) |
2491 | { | 2585 | { |
2492 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to resolve `%s': %s\n"), | 2586 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2493 | hostname, gai_strerror (ret)); | 2587 | _("Failed to resolve `%s': %s\n"), |
2588 | hostname, | ||
2589 | gai_strerror (ret)); | ||
2494 | GNUNET_free (hostname); | 2590 | GNUNET_free (hostname); |
2495 | return GNUNET_SYSERR; | 2591 | return GNUNET_SYSERR; |
2496 | } | 2592 | } |
@@ -2522,9 +2618,9 @@ server_get_addresses (struct HTTP_Server_Plugin *plugin, | |||
2522 | next = pos->ai_next; | 2618 | next = pos->ai_next; |
2523 | if ((disablev6) && (pos->ai_family == AF_INET6)) | 2619 | if ((disablev6) && (pos->ai_family == AF_INET6)) |
2524 | continue; | 2620 | continue; |
2525 | if ((pos->ai_protocol != IPPROTO_TCP) && (pos->ai_protocol != 0)) | 2621 | if ((pos->ai_protocol != IPPROTO_TCP) && (0 != pos->ai_protocol)) |
2526 | continue; /* not TCP */ | 2622 | continue; /* not TCP */ |
2527 | if ((pos->ai_socktype != SOCK_STREAM) && (pos->ai_socktype != 0)) | 2623 | if ((pos->ai_socktype != SOCK_STREAM) && (0 != pos->ai_socktype)) |
2528 | continue; /* huh? */ | 2624 | continue; /* huh? */ |
2529 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2625 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2530 | "Service will bind to `%s'\n", | 2626 | "Service will bind to `%s'\n", |
@@ -2638,7 +2734,7 @@ server_start_report_addresses (struct HTTP_Server_Plugin *plugin) | |||
2638 | while (res > 0) | 2734 | while (res > 0) |
2639 | { | 2735 | { |
2640 | res--; | 2736 | res--; |
2641 | GNUNET_assert (addrs[res] != NULL); | 2737 | GNUNET_assert (NULL != addrs[res]); |
2642 | GNUNET_free (addrs[res]); | 2738 | GNUNET_free (addrs[res]); |
2643 | } | 2739 | } |
2644 | GNUNET_free_non_null (addrs); | 2740 | GNUNET_free_non_null (addrs); |
@@ -2733,7 +2829,10 @@ server_notify_external_hostname (void *cls, | |||
2733 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 2829 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
2734 | return; | 2830 | return; |
2735 | 2831 | ||
2736 | GNUNET_asprintf(&url, "%s://%s", plugin->protocol, plugin->external_hostname); | 2832 | GNUNET_asprintf(&url, |
2833 | "%s://%s", | ||
2834 | plugin->protocol, | ||
2835 | plugin->external_hostname); | ||
2737 | 2836 | ||
2738 | urlen = strlen (url) + 1; | 2837 | urlen = strlen (url) + 1; |
2739 | ext_addr = GNUNET_malloc (sizeof (struct HttpAddress) + urlen); | 2838 | ext_addr = GNUNET_malloc (sizeof (struct HttpAddress) + urlen); |
@@ -3048,7 +3147,32 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | |||
3048 | 3147 | ||
3049 | /* Stop to report addresses to transport service */ | 3148 | /* Stop to report addresses to transport service */ |
3050 | server_stop_report_addresses (plugin); | 3149 | server_stop_report_addresses (plugin); |
3051 | server_stop (plugin); | 3150 | if (NULL != plugin->server_v4) |
3151 | { | ||
3152 | MHD_stop_daemon (plugin->server_v4); | ||
3153 | plugin->server_v4 = NULL; | ||
3154 | } | ||
3155 | if (NULL != plugin->server_v6) | ||
3156 | { | ||
3157 | MHD_stop_daemon (plugin->server_v6); | ||
3158 | plugin->server_v6 = NULL; | ||
3159 | } | ||
3160 | if (GNUNET_SCHEDULER_NO_TASK != plugin->server_v4_task) | ||
3161 | { | ||
3162 | GNUNET_SCHEDULER_cancel (plugin->server_v4_task); | ||
3163 | plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK; | ||
3164 | } | ||
3165 | |||
3166 | if (GNUNET_SCHEDULER_NO_TASK != plugin->server_v6_task) | ||
3167 | { | ||
3168 | GNUNET_SCHEDULER_cancel (plugin->server_v6_task); | ||
3169 | plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; | ||
3170 | } | ||
3171 | #if BUILD_HTTPS | ||
3172 | GNUNET_free_non_null (plugin->crypto_init); | ||
3173 | GNUNET_free_non_null (plugin->cert); | ||
3174 | GNUNET_free_non_null (plugin->key); | ||
3175 | #endif | ||
3052 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions, | 3176 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions, |
3053 | &destroy_session_cb, | 3177 | &destroy_session_cb, |
3054 | plugin); | 3178 | plugin); |
@@ -3090,7 +3214,9 @@ http_server_plugin_address_to_string (void *cls, | |||
3090 | const void *addr, | 3214 | const void *addr, |
3091 | size_t addrlen) | 3215 | size_t addrlen) |
3092 | { | 3216 | { |
3093 | return http_common_plugin_address_to_string (PLUGIN_NAME, addr, addrlen); | 3217 | return http_common_plugin_address_to_string (PLUGIN_NAME, |
3218 | addr, | ||
3219 | addrlen); | ||
3094 | } | 3220 | } |
3095 | 3221 | ||
3096 | 3222 | ||
@@ -3099,7 +3225,7 @@ http_server_plugin_address_to_string (void *cls, | |||
3099 | * | 3225 | * |
3100 | * @param cls closure ('struct HTTP_Server_Plugin*') | 3226 | * @param cls closure ('struct HTTP_Server_Plugin*') |
3101 | * @param session the session | 3227 | * @param session the session |
3102 | * @return the network type in HBO or GNUNET_SYSERR | 3228 | * @return the network type in HBO or #GNUNET_SYSERR |
3103 | */ | 3229 | */ |
3104 | static enum GNUNET_ATS_Network_Type | 3230 | static enum GNUNET_ATS_Network_Type |
3105 | http_server_get_network (void *cls, | 3231 | http_server_get_network (void *cls, |
@@ -3110,6 +3236,38 @@ http_server_get_network (void *cls, | |||
3110 | 3236 | ||
3111 | 3237 | ||
3112 | /** | 3238 | /** |
3239 | * Function that will be called whenever the transport service wants to | ||
3240 | * notify the plugin that the inbound quota changed and that the plugin | ||
3241 | * should update it's delay for the next receive value | ||
3242 | * | ||
3243 | * @param cls closure | ||
3244 | * @param peer which peer was the session for | ||
3245 | * @param session which session is being updated | ||
3246 | * @param delay new delay to use for receiving | ||
3247 | */ | ||
3248 | static void | ||
3249 | http_server_plugin_update_inbound_delay (void *cls, | ||
3250 | const struct GNUNET_PeerIdentity *peer, | ||
3251 | struct Session *s, | ||
3252 | struct GNUNET_TIME_Relative delay) | ||
3253 | { | ||
3254 | s->next_receive = GNUNET_TIME_relative_to_absolute (delay); | ||
3255 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3256 | "New inbound delay %s\n", | ||
3257 | GNUNET_STRINGS_relative_time_to_string (delay, | ||
3258 | GNUNET_NO)); | ||
3259 | if (GNUNET_SCHEDULER_NO_TASK != s->recv_wakeup_task) | ||
3260 | { | ||
3261 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
3262 | s->recv_wakeup_task | ||
3263 | = GNUNET_SCHEDULER_add_delayed (delay, | ||
3264 | &server_wake_up, | ||
3265 | s); | ||
3266 | } | ||
3267 | } | ||
3268 | |||
3269 | |||
3270 | /** | ||
3113 | * Return information about the given session to the | 3271 | * Return information about the given session to the |
3114 | * monitor callback. | 3272 | * monitor callback. |
3115 | * | 3273 | * |
@@ -3207,7 +3365,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
3207 | api->address_pretty_printer = &http_common_plugin_address_pretty_printer; | 3365 | api->address_pretty_printer = &http_common_plugin_address_pretty_printer; |
3208 | api->get_network = &http_server_get_network; | 3366 | api->get_network = &http_server_get_network; |
3209 | api->update_session_timeout = &http_server_plugin_update_session_timeout; | 3367 | api->update_session_timeout = &http_server_plugin_update_session_timeout; |
3210 | // api->update_inbound_delay = &http_server_plugin_update_inbound_delay; // FIXME: implement/support! | 3368 | api->update_inbound_delay = &http_server_plugin_update_inbound_delay; |
3211 | api->setup_monitor = &http_server_plugin_setup_monitor; | 3369 | api->setup_monitor = &http_server_plugin_setup_monitor; |
3212 | #if BUILD_HTTPS | 3370 | #if BUILD_HTTPS |
3213 | plugin->name = "transport-https_server"; | 3371 | plugin->name = "transport-https_server"; |
@@ -3218,7 +3376,9 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
3218 | #endif | 3376 | #endif |
3219 | 3377 | ||
3220 | /* Compile URL regex */ | 3378 | /* Compile URL regex */ |
3221 | if (regcomp(&plugin->url_regex, URL_REGEX, REG_EXTENDED)) | 3379 | if (regcomp(&plugin->url_regex, |
3380 | URL_REGEX, | ||
3381 | REG_EXTENDED)) | ||
3222 | { | 3382 | { |
3223 | LOG (GNUNET_ERROR_TYPE_ERROR, | 3383 | LOG (GNUNET_ERROR_TYPE_ERROR, |
3224 | _("Unable to compile URL regex\n")); | 3384 | _("Unable to compile URL regex\n")); |