aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_udp.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-12-13 12:39:09 +0000
committerChristian Grothoff <christian@grothoff.org>2013-12-13 12:39:09 +0000
commit9ff68546aa6e7226e37e9231b3961ae72eb0cbb2 (patch)
treee389457d5da2b28e452fb12c0233d46d1fd8b219 /src/transport/plugin_transport_udp.c
parente803ed2a69a7a925d51c50334e79223284c00f5f (diff)
downloadgnunet-9ff68546aa6e7226e37e9231b3961ae72eb0cbb2.tar.gz
gnunet-9ff68546aa6e7226e37e9231b3961ae72eb0cbb2.zip
-code cleanup, fixing #3207: timeout can be NULL in reschedule_session_timeout if we are 'in destroy', in which case we should simply do nothing
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r--src/transport/plugin_transport_udp.c170
1 files changed, 84 insertions, 86 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 99d4f9fb1..c85cbd885 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -193,8 +193,20 @@ struct Session
193 */ 193 */
194 size_t addrlen; 194 size_t addrlen;
195 195
196 /**
197 * Reference counter to indicate that this session is
198 * currently being used and must not be destroyed;
199 * setting @e in_destroy will destroy it as soon as
200 * possible.
201 */
196 unsigned int rc; 202 unsigned int rc;
197 203
204 /**
205 * Is this session about to be destroyed (sometimes we cannot
206 * destroy a session immediately as below us on the stack
207 * there might be code that still uses it; in this case,
208 * @e rc is non-zero).
209 */
198 int in_destroy; 210 int in_destroy;
199 211
200 int inbound; 212 int inbound;
@@ -479,25 +491,6 @@ udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
479 491
480 492
481/** 493/**
482 * Cancel timeout
483 */
484static void
485stop_session_timeout (struct Session *s)
486{
487 GNUNET_assert (NULL != s);
488
489 if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task)
490 {
491 GNUNET_SCHEDULER_cancel (s->timeout_task);
492 s->timeout_task = GNUNET_SCHEDULER_NO_TASK;
493 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
494 "Timeout stopped for session %p canceled\n",
495 s);
496 }
497}
498
499
500/**
501 * (re)schedule select tasks for this plugin. 494 * (re)schedule select tasks for this plugin.
502 * 495 *
503 * @param plugin plugin to reschedule 496 * @param plugin plugin to reschedule
@@ -713,19 +706,19 @@ udp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
713 706
714 707
715static void 708static void
716ppc_cancel_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 709ppc_cancel_task (void *cls,
710 const struct GNUNET_SCHEDULER_TaskContext *tc)
717{ 711{
718 struct PrettyPrinterContext *ppc = cls; 712 struct PrettyPrinterContext *ppc = cls;
719 /* GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PPC %p was not removed!\n", ppc); */ 713
720 ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK; 714 ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK;
721 if (NULL != ppc->resolver_handle) 715 if (NULL != ppc->resolver_handle)
722 { 716 {
723 GNUNET_RESOLVER_request_cancel (ppc->resolver_handle); 717 GNUNET_RESOLVER_request_cancel (ppc->resolver_handle);
724 ppc->resolver_handle = NULL; 718 ppc->resolver_handle = NULL;
725 } 719 }
726 720 GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc);
727 GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc); 721 GNUNET_free (ppc);
728 GNUNET_free (ppc);
729} 722}
730 723
731 724
@@ -741,7 +734,7 @@ append_port (void *cls, const char *hostname)
741 struct PrettyPrinterContext *ppc = cls; 734 struct PrettyPrinterContext *ppc = cls;
742 struct PrettyPrinterContext *cur; 735 struct PrettyPrinterContext *cur;
743 char *ret; 736 char *ret;
744 /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC callback: %p `%s'\n",ppc, hostname); */ 737
745 if (hostname == NULL) 738 if (hostname == NULL)
746 { 739 {
747 ppc->asc (ppc->asc_cls, NULL); 740 ppc->asc (ppc->asc_cls, NULL);
@@ -749,29 +742,40 @@ append_port (void *cls, const char *hostname)
749 GNUNET_SCHEDULER_cancel (ppc->timeout_task); 742 GNUNET_SCHEDULER_cancel (ppc->timeout_task);
750 ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK; 743 ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK;
751 ppc->resolver_handle = NULL; 744 ppc->resolver_handle = NULL;
752 /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was removed!\n", ppc); */
753 GNUNET_free (ppc); 745 GNUNET_free (ppc);
754 return; 746 return;
755 } 747 }
756 for (cur = ppc_dll_head; (NULL != cur); cur = cur->next) 748 for (cur = ppc_dll_head; (NULL != cur); cur = cur->next)
757 { 749 {
758 if (cur == ppc) 750 if (cur == ppc)
759 break; 751 break;
760 } 752 }
761 if (NULL == cur) 753 if (NULL == cur)
762 { 754 {
763 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid callback for PPC %p \n", ppc); 755 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
764 return; 756 "Invalid callback for PPC %p \n", ppc);
757 return;
765 } 758 }
766 759
767 if (GNUNET_YES == ppc->ipv6) 760 if (GNUNET_YES == ppc->ipv6)
768 GNUNET_asprintf (&ret, "%s.%u.[%s]:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port); 761 GNUNET_asprintf (&ret,
762 "%s.%u.[%s]:%d",
763 PLUGIN_NAME,
764 ppc->options,
765 hostname,
766 ppc->port);
769 else 767 else
770 GNUNET_asprintf (&ret, "%s.%u.%s:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port); 768 GNUNET_asprintf (&ret,
769 "%s.%u.%s:%d",
770 PLUGIN_NAME,
771 ppc->options,
772 hostname,
773 ppc->port);
771 ppc->asc (ppc->asc_cls, ret); 774 ppc->asc (ppc->asc_cls, ret);
772 GNUNET_free (ret); 775 GNUNET_free (ret);
773} 776}
774 777
778
775/** 779/**
776 * Convert the transports address to a nice, human-readable 780 * Convert the transports address to a nice, human-readable
777 * format. 781 * format.
@@ -841,7 +845,7 @@ udp_plugin_address_pretty_printer (void *cls, const char *type,
841 asc (asc_cls, NULL); 845 asc (asc_cls, NULL);
842 return; 846 return;
843 } 847 }
844 ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); 848 ppc = GNUNET_new (struct PrettyPrinterContext);
845 ppc->asc = asc; 849 ppc->asc = asc;
846 ppc->asc_cls = asc_cls; 850 ppc->asc_cls = asc_cls;
847 ppc->port = port; 851 ppc->port = port;
@@ -853,9 +857,10 @@ udp_plugin_address_pretty_printer (void *cls, const char *type,
853 ppc->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(timeout, 2), 857 ppc->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(timeout, 2),
854 &ppc_cancel_task, ppc); 858 &ppc_cancel_task, ppc);
855 GNUNET_CONTAINER_DLL_insert (ppc_dll_head, ppc_dll_tail, ppc); 859 GNUNET_CONTAINER_DLL_insert (ppc_dll_head, ppc_dll_tail, ppc);
856 /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was created!\n", ppc); */ 860 ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sb, sbs,
857 ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc); 861 !numeric,
858 862 timeout,
863 &append_port, ppc);
859} 864}
860 865
861 866
@@ -1104,7 +1109,7 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
1104 1109
1105 1110
1106/** 1111/**
1107 * Task to free resources associated with a session. 1112 * Function to free last resources associated with a session.
1108 * 1113 *
1109 * @param s session to free 1114 * @param s session to free
1110 */ 1115 */
@@ -1113,7 +1118,7 @@ free_session (struct Session *s)
1113{ 1118{
1114 if (NULL != s->frag_ctx) 1119 if (NULL != s->frag_ctx)
1115 { 1120 {
1116 GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag, NULL, NULL); 1121 GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag, NULL, NULL);
1117 GNUNET_free (s->frag_ctx); 1122 GNUNET_free (s->frag_ctx);
1118 s->frag_ctx = NULL; 1123 s->frag_ctx = NULL;
1119 } 1124 }
@@ -1235,8 +1240,12 @@ udp_disconnect_session (void *cls,
1235 s, 1240 s,
1236 GNUNET_i2s (&s->target), 1241 GNUNET_i2s (&s->target),
1237 GNUNET_a2s (s->sock_addr, s->addrlen)); 1242 GNUNET_a2s (s->sock_addr, s->addrlen));
1238 stop_session_timeout (s); 1243 /* stop timeout task */
1239 1244 if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task)
1245 {
1246 GNUNET_SCHEDULER_cancel (s->timeout_task);
1247 s->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1248 }
1240 if (NULL != s->frag_ctx) 1249 if (NULL != s->frag_ctx)
1241 { 1250 {
1242 /* Remove fragmented message due to disconnect */ 1251 /* Remove fragmented message due to disconnect */
@@ -1340,6 +1349,9 @@ udp_disconnect (void *cls,
1340 1349
1341/** 1350/**
1342 * Session was idle, so disconnect it 1351 * Session was idle, so disconnect it
1352 *
1353 * @param cls the `struct Session` to time out
1354 * @param tc scheduler context
1343 */ 1355 */
1344static void 1356static void
1345session_timeout (void *cls, 1357session_timeout (void *cls,
@@ -1360,42 +1372,23 @@ session_timeout (void *cls,
1360 1372
1361 1373
1362/** 1374/**
1363 * Start session timeout
1364 */
1365static void
1366start_session_timeout (struct Session *s)
1367{
1368 GNUNET_assert (NULL != s);
1369 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task);
1370 s->timeout_task = GNUNET_SCHEDULER_add_delayed (UDP_SESSION_TIME_OUT,
1371 &session_timeout,
1372 s);
1373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1374 "Timeout for session %p set to %s\n",
1375 s,
1376 GNUNET_STRINGS_relative_time_to_string (UDP_SESSION_TIME_OUT,
1377 GNUNET_YES));
1378}
1379
1380
1381/**
1382 * Increment session timeout due to activity 1375 * Increment session timeout due to activity
1376 *
1377 * @param s session to reschedule timeout activity for
1383 */ 1378 */
1384static void 1379static void
1385reschedule_session_timeout (struct Session *s) 1380reschedule_session_timeout (struct Session *s)
1386{ 1381{
1387 GNUNET_assert (NULL != s); 1382 if (GNUNET_YES == s->in_destroy)
1383 return;
1388 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); 1384 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task);
1389
1390 GNUNET_SCHEDULER_cancel (s->timeout_task); 1385 GNUNET_SCHEDULER_cancel (s->timeout_task);
1391 s->timeout_task = GNUNET_SCHEDULER_add_delayed (UDP_SESSION_TIME_OUT, 1386 s->timeout_task = GNUNET_SCHEDULER_add_delayed (UDP_SESSION_TIME_OUT,
1392 &session_timeout, 1387 &session_timeout,
1393 s); 1388 s);
1394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1395 "Timeout rescheduled for session %p set to %s\n", 1390 "Timeout restarted for session %p\n",
1396 s, 1391 s);
1397 GNUNET_STRINGS_relative_time_to_string (UDP_SESSION_TIME_OUT,
1398 GNUNET_YES));
1399} 1392}
1400 1393
1401 1394
@@ -1480,7 +1473,9 @@ create_session (struct Plugin *plugin,
1480 s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS; 1473 s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS;
1481 s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO; 1474 s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO;
1482 s->inbound = GNUNET_NO; 1475 s->inbound = GNUNET_NO;
1483 start_session_timeout (s); 1476 s->timeout_task = GNUNET_SCHEDULER_add_delayed (UDP_SESSION_TIME_OUT,
1477 &session_timeout,
1478 s);
1484 return s; 1479 return s;
1485} 1480}
1486 1481
@@ -1988,18 +1983,18 @@ process_inbound_tokenized_messages (void *cls, void *client,
1988 &si->sender, 1983 &si->sender,
1989 hdr, 1984 hdr,
1990 si->session, 1985 si->session,
1991 (GNUNET_YES == si->session->inbound) ? NULL : si->arg, 1986 (GNUNET_YES == si->session->inbound)
1992 (GNUNET_YES == si->session->inbound) ? 0 : si->args); 1987 ? NULL : si->arg,
1993 1988 (GNUNET_YES == si->session->inbound)
1989 ? 0 : si->args);
1994 plugin->env->update_address_metrics (plugin->env->cls, 1990 plugin->env->update_address_metrics (plugin->env->cls,
1995 &si->sender, 1991 &si->sender,
1996 (GNUNET_YES == si->session->inbound) ? NULL : si->arg, 1992 (GNUNET_YES == si->session->inbound) ? NULL : si->arg,
1997 (GNUNET_YES == si->session->inbound) ? 0 : si->args, 1993 (GNUNET_YES == si->session->inbound) ? 0 : si->args,
1998 si->session, 1994 si->session,
1999 &si->session->ats, 1); 1995 &si->session->ats, 1);
2000
2001 si->session->flow_delay_for_other_peer = delay; 1996 si->session->flow_delay_for_other_peer = delay;
2002 reschedule_session_timeout(si->session); 1997 reschedule_session_timeout (si->session);
2003 return GNUNET_OK; 1998 return GNUNET_OK;
2004} 1999}
2005 2000
@@ -2081,9 +2076,12 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
2081 si.arg = arg; 2076 si.arg = arg;
2082 si.args = args; 2077 si.args = args;
2083 s->rc++; 2078 s->rc++;
2084 GNUNET_SERVER_mst_receive (plugin->mst, &si, (const char *) &msg[1], 2079 GNUNET_SERVER_mst_receive (plugin->mst,
2085 ntohs (msg->header.size) - 2080 &si,
2086 sizeof (struct UDPMessage), GNUNET_YES, GNUNET_NO); 2081 (const char *) &msg[1],
2082 ntohs (msg->header.size) - sizeof (struct UDPMessage),
2083 GNUNET_YES,
2084 GNUNET_NO);
2087 s->rc--; 2085 s->rc--;
2088 if ( (0 == s->rc) && (GNUNET_YES == s->in_destroy)) 2086 if ( (0 == s->rc) && (GNUNET_YES == s->in_destroy))
2089 free_session (s); 2087 free_session (s);