diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-06-23 21:40:20 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-06-23 21:40:20 +0000 |
commit | 783e60f8924e639220c0dbf0d6aa55164ad79a91 (patch) | |
tree | 63b17555afc6332735ae5f406b2d248a8da0fb53 /src/transport | |
parent | 21d30199ab44f4aed55fcfed4cb3d8212107fca6 (diff) | |
download | gnunet-783e60f8924e639220c0dbf0d6aa55164ad79a91.tar.gz gnunet-783e60f8924e639220c0dbf0d6aa55164ad79a91.zip |
-simplify deletion logic, tell monitor that we are initiator
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 320 |
1 files changed, 154 insertions, 166 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index efcfcb1c3..68b25afe5 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -392,7 +392,7 @@ notify_session_monitor (struct HTTP_Client_Plugin *plugin, | |||
392 | return; | 392 | return; |
393 | memset (&info, 0, sizeof (info)); | 393 | memset (&info, 0, sizeof (info)); |
394 | info.state = state; | 394 | info.state = state; |
395 | info.is_inbound = GNUNET_SYSERR; /* hard to say */ | 395 | info.is_inbound = GNUNET_NO; |
396 | info.num_msg_pending = session->msgs_in_queue; | 396 | info.num_msg_pending = session->msgs_in_queue; |
397 | info.num_bytes_pending = session->bytes_in_queue; | 397 | info.num_bytes_pending = session->bytes_in_queue; |
398 | info.receive_delay = session->next_receive; | 398 | info.receive_delay = session->next_receive; |
@@ -405,6 +405,70 @@ notify_session_monitor (struct HTTP_Client_Plugin *plugin, | |||
405 | 405 | ||
406 | 406 | ||
407 | /** | 407 | /** |
408 | * Delete session @a s. | ||
409 | * | ||
410 | * @param s the session to delete | ||
411 | */ | ||
412 | static void | ||
413 | client_delete_session (struct Session *s) | ||
414 | { | ||
415 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
416 | struct HTTP_Message *pos; | ||
417 | struct HTTP_Message *next; | ||
418 | |||
419 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) | ||
420 | { | ||
421 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
422 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
423 | s->timeout = GNUNET_TIME_UNIT_ZERO_ABS; | ||
424 | } | ||
425 | if (GNUNET_SCHEDULER_NO_TASK != s->put_disconnect_task) | ||
426 | { | ||
427 | GNUNET_SCHEDULER_cancel (s->put_disconnect_task); | ||
428 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
429 | } | ||
430 | GNUNET_assert (GNUNET_OK == | ||
431 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, | ||
432 | &s->target, | ||
433 | s)); | ||
434 | |||
435 | next = s->msg_head; | ||
436 | while (NULL != (pos = next)) | ||
437 | { | ||
438 | next = pos->next; | ||
439 | GNUNET_CONTAINER_DLL_remove (s->msg_head, | ||
440 | s->msg_tail, | ||
441 | pos); | ||
442 | GNUNET_assert (0 < s->msgs_in_queue); | ||
443 | s->msgs_in_queue--; | ||
444 | GNUNET_assert (pos->size <= s->bytes_in_queue); | ||
445 | s->bytes_in_queue -= pos->size; | ||
446 | if (NULL != pos->transmit_cont) | ||
447 | pos->transmit_cont (pos->transmit_cont_cls, | ||
448 | &s->target, | ||
449 | GNUNET_SYSERR, | ||
450 | pos->size, | ||
451 | pos->pos + s->overhead); | ||
452 | s->overhead = 0; | ||
453 | GNUNET_free (pos); | ||
454 | } | ||
455 | GNUNET_assert (0 == s->msgs_in_queue); | ||
456 | GNUNET_assert (0 == s->bytes_in_queue); | ||
457 | notify_session_monitor (plugin, | ||
458 | s, | ||
459 | GNUNET_TRANSPORT_SS_DOWN); | ||
460 | if (NULL != s->msg_tk) | ||
461 | { | ||
462 | GNUNET_SERVER_mst_destroy (s->msg_tk); | ||
463 | s->msg_tk = NULL; | ||
464 | } | ||
465 | GNUNET_HELLO_address_free (s->address); | ||
466 | GNUNET_free (s->url); | ||
467 | GNUNET_free (s); | ||
468 | } | ||
469 | |||
470 | |||
471 | /** | ||
408 | * Increment session timeout due to activity for session @a s. | 472 | * Increment session timeout due to activity for session @a s. |
409 | * | 473 | * |
410 | * @param s the session | 474 | * @param s the session |
@@ -418,25 +482,85 @@ client_reschedule_session_timeout (struct Session *s) | |||
418 | 482 | ||
419 | 483 | ||
420 | /** | 484 | /** |
485 | * Task performing curl operations | ||
486 | * | ||
487 | * @param cls plugin as closure | ||
488 | * @param tc gnunet scheduler task context | ||
489 | */ | ||
490 | static void | ||
491 | client_run (void *cls, | ||
492 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
493 | |||
494 | |||
495 | /** | ||
421 | * Function setting up file descriptors and scheduling task to run | 496 | * Function setting up file descriptors and scheduling task to run |
422 | * | 497 | * |
423 | * @param plugin plugin as closure | 498 | * @param plugin the plugin as closure |
424 | * @param now schedule task in 1ms, regardless of what curl may say | 499 | * @param now schedule task in 1ms, regardless of what curl may say |
425 | * @return #GNUNET_SYSERR for hard failure, #GNUNET_OK for ok | 500 | * @return #GNUNET_SYSERR for hard failure, #GNUNET_OK for ok |
426 | */ | 501 | */ |
427 | static int | 502 | static int |
428 | client_schedule (struct HTTP_Client_Plugin *plugin, | 503 | client_schedule (struct HTTP_Client_Plugin *plugin, |
429 | int now); | 504 | int now) |
505 | { | ||
506 | fd_set rs; | ||
507 | fd_set ws; | ||
508 | fd_set es; | ||
509 | int max; | ||
510 | struct GNUNET_NETWORK_FDSet *grs; | ||
511 | struct GNUNET_NETWORK_FDSet *gws; | ||
512 | long to; | ||
513 | CURLMcode mret; | ||
514 | struct GNUNET_TIME_Relative timeout; | ||
430 | 515 | ||
516 | /* Cancel previous scheduled task */ | ||
517 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
518 | { | ||
519 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
520 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
521 | } | ||
522 | max = -1; | ||
523 | FD_ZERO (&rs); | ||
524 | FD_ZERO (&ws); | ||
525 | FD_ZERO (&es); | ||
526 | mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max); | ||
527 | if (mret != CURLM_OK) | ||
528 | { | ||
529 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), | ||
530 | "curl_multi_fdset", __FILE__, __LINE__, | ||
531 | curl_multi_strerror (mret)); | ||
532 | return GNUNET_SYSERR; | ||
533 | } | ||
534 | mret = curl_multi_timeout (plugin->curl_multi_handle, &to); | ||
535 | if (to == -1) | ||
536 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); | ||
537 | else | ||
538 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); | ||
539 | if (now == GNUNET_YES) | ||
540 | timeout = GNUNET_TIME_UNIT_MILLISECONDS; | ||
431 | 541 | ||
432 | /** | 542 | if (mret != CURLM_OK) |
433 | * Connect a HTTP put connection | 543 | { |
434 | * | 544 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
435 | * @param s the session to connect | 545 | _("%s failed at %s:%d: `%s'\n"), |
436 | * @return #GNUNET_SYSERR for hard failure, #GNUNET_OK for success | 546 | "curl_multi_timeout", __FILE__, __LINE__, |
437 | */ | 547 | curl_multi_strerror (mret)); |
438 | static int | 548 | return GNUNET_SYSERR; |
439 | client_connect_put (struct Session *s); | 549 | } |
550 | |||
551 | grs = GNUNET_NETWORK_fdset_create (); | ||
552 | gws = GNUNET_NETWORK_fdset_create (); | ||
553 | GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); | ||
554 | GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); | ||
555 | |||
556 | plugin->client_perform_task = | ||
557 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
558 | timeout, grs, gws, | ||
559 | &client_run, plugin); | ||
560 | GNUNET_NETWORK_fdset_destroy (gws); | ||
561 | GNUNET_NETWORK_fdset_destroy (grs); | ||
562 | return GNUNET_OK; | ||
563 | } | ||
440 | 564 | ||
441 | 565 | ||
442 | /** | 566 | /** |
@@ -502,6 +626,16 @@ client_log (CURL *curl, | |||
502 | 626 | ||
503 | 627 | ||
504 | /** | 628 | /** |
629 | * Connect a HTTP put connection | ||
630 | * | ||
631 | * @param s the session to connect | ||
632 | * @return #GNUNET_SYSERR for hard failure, #GNUNET_OK for success | ||
633 | */ | ||
634 | static int | ||
635 | client_connect_put (struct Session *s); | ||
636 | |||
637 | |||
638 | /** | ||
505 | * Function that can be used by the transport service to transmit | 639 | * Function that can be used by the transport service to transmit |
506 | * a message using the plugin. Note that in the case of a | 640 | * a message using the plugin. Note that in the case of a |
507 | * peer disconnecting, the continuation MUST be called | 641 | * peer disconnecting, the continuation MUST be called |
@@ -601,7 +735,7 @@ http_client_plugin_send (void *cls, | |||
601 | "Session %p: Reconnecting PUT connection\n", | 735 | "Session %p: Reconnecting PUT connection\n", |
602 | s); | 736 | s); |
603 | s->put_tmp_disconnected = GNUNET_NO; | 737 | s->put_tmp_disconnected = GNUNET_NO; |
604 | GNUNET_break (s->client_put == NULL); | 738 | GNUNET_break (NULL == s->client_put); |
605 | if (GNUNET_SYSERR == client_connect_put (s)) | 739 | if (GNUNET_SYSERR == client_connect_put (s)) |
606 | return GNUNET_SYSERR; | 740 | return GNUNET_SYSERR; |
607 | } | 741 | } |
@@ -612,70 +746,6 @@ http_client_plugin_send (void *cls, | |||
612 | 746 | ||
613 | 747 | ||
614 | /** | 748 | /** |
615 | * Delete session @a s. | ||
616 | * | ||
617 | * @param s the session to delete | ||
618 | */ | ||
619 | static void | ||
620 | client_delete_session (struct Session *s) | ||
621 | { | ||
622 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
623 | struct HTTP_Message *pos; | ||
624 | struct HTTP_Message *next; | ||
625 | |||
626 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) | ||
627 | { | ||
628 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
629 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
630 | s->timeout = GNUNET_TIME_UNIT_ZERO_ABS; | ||
631 | } | ||
632 | if (GNUNET_SCHEDULER_NO_TASK != s->put_disconnect_task) | ||
633 | { | ||
634 | GNUNET_SCHEDULER_cancel (s->put_disconnect_task); | ||
635 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
636 | } | ||
637 | GNUNET_assert (GNUNET_OK == | ||
638 | GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, | ||
639 | &s->target, | ||
640 | s)); | ||
641 | |||
642 | next = s->msg_head; | ||
643 | while (NULL != (pos = next)) | ||
644 | { | ||
645 | next = pos->next; | ||
646 | GNUNET_CONTAINER_DLL_remove (s->msg_head, | ||
647 | s->msg_tail, | ||
648 | pos); | ||
649 | GNUNET_assert (0 < s->msgs_in_queue); | ||
650 | s->msgs_in_queue--; | ||
651 | GNUNET_assert (pos->size <= s->bytes_in_queue); | ||
652 | s->bytes_in_queue -= pos->size; | ||
653 | if (NULL != pos->transmit_cont) | ||
654 | pos->transmit_cont (pos->transmit_cont_cls, | ||
655 | &s->target, | ||
656 | GNUNET_SYSERR, | ||
657 | pos->size, | ||
658 | pos->pos + s->overhead); | ||
659 | s->overhead = 0; | ||
660 | GNUNET_free (pos); | ||
661 | } | ||
662 | GNUNET_assert (0 == s->msgs_in_queue); | ||
663 | GNUNET_assert (0 == s->bytes_in_queue); | ||
664 | notify_session_monitor (plugin, | ||
665 | s, | ||
666 | GNUNET_TRANSPORT_SS_DOWN); | ||
667 | if (NULL != s->msg_tk) | ||
668 | { | ||
669 | GNUNET_SERVER_mst_destroy (s->msg_tk); | ||
670 | s->msg_tk = NULL; | ||
671 | } | ||
672 | GNUNET_HELLO_address_free (s->address); | ||
673 | GNUNET_free (s->url); | ||
674 | GNUNET_free (s); | ||
675 | } | ||
676 | |||
677 | |||
678 | /** | ||
679 | * Disconnect a session | 749 | * Disconnect a session |
680 | * | 750 | * |
681 | * @param cls the `struct HTTP_Client_Plugin *` | 751 | * @param cls the `struct HTTP_Client_Plugin *` |
@@ -701,7 +771,8 @@ http_client_plugin_session_disconnect (void *cls, | |||
701 | GNUNET_i2s (&s->target)); | 771 | GNUNET_i2s (&s->target)); |
702 | 772 | ||
703 | /* remove curl handle from multi handle */ | 773 | /* remove curl handle from multi handle */ |
704 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_put); | 774 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, |
775 | s->client_put); | ||
705 | if (mret != CURLM_OK) | 776 | if (mret != CURLM_OK) |
706 | { | 777 | { |
707 | /* clean up easy handle, handle is now invalid and free'd */ | 778 | /* clean up easy handle, handle is now invalid and free'd */ |
@@ -1203,88 +1274,6 @@ client_receive (void *stream, | |||
1203 | * Task performing curl operations | 1274 | * Task performing curl operations |
1204 | * | 1275 | * |
1205 | * @param cls plugin as closure | 1276 | * @param cls plugin as closure |
1206 | * @param tc gnunet scheduler task context | ||
1207 | */ | ||
1208 | static void | ||
1209 | client_run (void *cls, | ||
1210 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
1211 | |||
1212 | |||
1213 | /** | ||
1214 | * Function setting up file descriptors and scheduling task to run | ||
1215 | * | ||
1216 | * @param plugin the plugin as closure | ||
1217 | * @param now schedule task in 1ms, regardless of what curl may say | ||
1218 | * @return #GNUNET_SYSERR for hard failure, #GNUNET_OK for ok | ||
1219 | */ | ||
1220 | static int | ||
1221 | client_schedule (struct HTTP_Client_Plugin *plugin, | ||
1222 | int now) | ||
1223 | { | ||
1224 | fd_set rs; | ||
1225 | fd_set ws; | ||
1226 | fd_set es; | ||
1227 | int max; | ||
1228 | struct GNUNET_NETWORK_FDSet *grs; | ||
1229 | struct GNUNET_NETWORK_FDSet *gws; | ||
1230 | long to; | ||
1231 | CURLMcode mret; | ||
1232 | struct GNUNET_TIME_Relative timeout; | ||
1233 | |||
1234 | /* Cancel previous scheduled task */ | ||
1235 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
1236 | { | ||
1237 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
1238 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
1239 | } | ||
1240 | max = -1; | ||
1241 | FD_ZERO (&rs); | ||
1242 | FD_ZERO (&ws); | ||
1243 | FD_ZERO (&es); | ||
1244 | mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max); | ||
1245 | if (mret != CURLM_OK) | ||
1246 | { | ||
1247 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), | ||
1248 | "curl_multi_fdset", __FILE__, __LINE__, | ||
1249 | curl_multi_strerror (mret)); | ||
1250 | return GNUNET_SYSERR; | ||
1251 | } | ||
1252 | mret = curl_multi_timeout (plugin->curl_multi_handle, &to); | ||
1253 | if (to == -1) | ||
1254 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); | ||
1255 | else | ||
1256 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); | ||
1257 | if (now == GNUNET_YES) | ||
1258 | timeout = GNUNET_TIME_UNIT_MILLISECONDS; | ||
1259 | |||
1260 | if (mret != CURLM_OK) | ||
1261 | { | ||
1262 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1263 | _("%s failed at %s:%d: `%s'\n"), | ||
1264 | "curl_multi_timeout", __FILE__, __LINE__, | ||
1265 | curl_multi_strerror (mret)); | ||
1266 | return GNUNET_SYSERR; | ||
1267 | } | ||
1268 | |||
1269 | grs = GNUNET_NETWORK_fdset_create (); | ||
1270 | gws = GNUNET_NETWORK_fdset_create (); | ||
1271 | GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); | ||
1272 | GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); | ||
1273 | |||
1274 | plugin->client_perform_task = | ||
1275 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1276 | timeout, grs, gws, | ||
1277 | &client_run, plugin); | ||
1278 | GNUNET_NETWORK_fdset_destroy (gws); | ||
1279 | GNUNET_NETWORK_fdset_destroy (grs); | ||
1280 | return GNUNET_OK; | ||
1281 | } | ||
1282 | |||
1283 | |||
1284 | /** | ||
1285 | * Task performing curl operations | ||
1286 | * | ||
1287 | * @param cls plugin as closure | ||
1288 | * @param tc scheduler task context | 1277 | * @param tc scheduler task context |
1289 | */ | 1278 | */ |
1290 | static void | 1279 | static void |
@@ -1369,12 +1358,12 @@ client_run (void *cls, | |||
1369 | */ | 1358 | */ |
1370 | if (GNUNET_YES == s->put_reconnect_required) | 1359 | if (GNUNET_YES == s->put_reconnect_required) |
1371 | { | 1360 | { |
1372 | s->put_reconnect_required = GNUNET_NO; | 1361 | s->put_reconnect_required = GNUNET_NO; |
1373 | if (GNUNET_SYSERR == client_connect_put(s)) | 1362 | if (GNUNET_SYSERR == client_connect_put (s)) |
1374 | { | 1363 | { |
1375 | GNUNET_break (s->client_put == NULL); | 1364 | GNUNET_break (s->client_put == NULL); |
1376 | GNUNET_break (s->put_tmp_disconnected == GNUNET_NO); | 1365 | GNUNET_break (s->put_tmp_disconnected == GNUNET_NO); |
1377 | } | 1366 | } |
1378 | } | 1367 | } |
1379 | } | 1368 | } |
1380 | if (easy_h == s->client_get) | 1369 | if (easy_h == s->client_get) |
@@ -2171,7 +2160,6 @@ http_client_plugin_setup_monitor (void *cls, | |||
2171 | } | 2160 | } |
2172 | 2161 | ||
2173 | 2162 | ||
2174 | |||
2175 | /** | 2163 | /** |
2176 | * Entry point for the plugin. | 2164 | * Entry point for the plugin. |
2177 | */ | 2165 | */ |