diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-02-04 16:54:59 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-02-04 16:54:59 +0000 |
commit | 9815c9428b6cffa128244d2186197adf7208b7ee (patch) | |
tree | 15d08c540ac11fbe74b34fc2c7f7ad028a22f035 /src/transport/plugin_transport_tcp.c | |
parent | ad376cd585fea449457b9339f5ae39b74d5dd5a0 (diff) | |
download | gnunet-9815c9428b6cffa128244d2186197adf7208b7ee.tar.gz gnunet-9815c9428b6cffa128244d2186197adf7208b7ee.zip |
limit connection for tcp
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 01d474a0c..07abc46cf 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -385,6 +385,11 @@ struct Plugin | |||
385 | unsigned long long max_connections; | 385 | unsigned long long max_connections; |
386 | 386 | ||
387 | /** | 387 | /** |
388 | * How many more TCP sessions do we have right now? | ||
389 | */ | ||
390 | unsigned long long cur_connections; | ||
391 | |||
392 | /** | ||
388 | * ID of task used to update our addresses when one expires. | 393 | * ID of task used to update our addresses when one expires. |
389 | */ | 394 | */ |
390 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; | 395 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; |
@@ -486,13 +491,12 @@ plugin_tcp_access_check (void *cls, | |||
486 | const struct sockaddr *addr, socklen_t addrlen) | 491 | const struct sockaddr *addr, socklen_t addrlen) |
487 | { | 492 | { |
488 | struct Plugin *plugin = cls; | 493 | struct Plugin *plugin = cls; |
489 | 494 | LOG (GNUNET_ERROR_TYPE_DEBUG, | |
490 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
491 | "Accepting new incoming TCP connection from `%s'\n", | 495 | "Accepting new incoming TCP connection from `%s'\n", |
492 | GNUNET_a2s (addr, addrlen)); | 496 | GNUNET_a2s (addr, addrlen)); |
493 | if (0 == plugin->max_connections) | 497 | if (plugin->cur_connections >= plugin->max_connections) |
494 | return GNUNET_NO; | 498 | return GNUNET_NO; |
495 | plugin->max_connections--; | 499 | plugin->cur_connections ++; |
496 | return GNUNET_YES; | 500 | return GNUNET_YES; |
497 | } | 501 | } |
498 | 502 | ||
@@ -1355,7 +1359,7 @@ tcp_plugin_get_session (void *cls, | |||
1355 | return NULL; | 1359 | return NULL; |
1356 | } | 1360 | } |
1357 | 1361 | ||
1358 | if (0 == plugin->max_connections) | 1362 | if (plugin->cur_connections >= plugin->max_connections) |
1359 | { | 1363 | { |
1360 | /* saturated */ | 1364 | /* saturated */ |
1361 | return NULL; | 1365 | return NULL; |
@@ -1408,7 +1412,7 @@ tcp_plugin_get_session (void *cls, | |||
1408 | } | 1412 | } |
1409 | 1413 | ||
1410 | /* create new outbound session */ | 1414 | /* create new outbound session */ |
1411 | GNUNET_assert (0 != plugin->max_connections); | 1415 | GNUNET_assert (plugin->cur_connections <= plugin->max_connections); |
1412 | sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs); | 1416 | sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs); |
1413 | if (sa == NULL) | 1417 | if (sa == NULL) |
1414 | { | 1418 | { |
@@ -1417,7 +1421,9 @@ tcp_plugin_get_session (void *cls, | |||
1417 | GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); | 1421 | GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); |
1418 | return NULL; | 1422 | return NULL; |
1419 | } | 1423 | } |
1420 | plugin->max_connections--; | 1424 | plugin->cur_connections++; |
1425 | if (plugin->cur_connections == plugin->max_connections) | ||
1426 | GNUNET_SERVER_suspend (plugin->server); /* Maximum number of connections rechead */ | ||
1421 | 1427 | ||
1422 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1428 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1423 | "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", | 1429 | "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", |
@@ -1436,7 +1442,7 @@ tcp_plugin_get_session (void *cls, | |||
1436 | &session->target.hashPubKey, | 1442 | &session->target.hashPubKey, |
1437 | session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 1443 | session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
1438 | inc_sessions (plugin, session, __LINE__); | 1444 | inc_sessions (plugin, session, __LINE__); |
1439 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1445 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1440 | "Creating new session for `%s' address `%s' session %p\n", | 1446 | "Creating new session for `%s' address `%s' session %p\n", |
1441 | GNUNET_i2s (&address->peer), | 1447 | GNUNET_i2s (&address->peer), |
1442 | tcp_address_to_string(NULL, address->address, address->address_length), | 1448 | tcp_address_to_string(NULL, address->address, address->address_length), |
@@ -1875,6 +1881,11 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client, | |||
1875 | else | 1881 | else |
1876 | { | 1882 | { |
1877 | GNUNET_SERVER_client_keep (client); | 1883 | GNUNET_SERVER_client_keep (client); |
1884 | if (plugin->service != NULL) /* Otherwise value is incremented in tcp_access_check */ | ||
1885 | plugin->cur_connections++; | ||
1886 | if (plugin->cur_connections == plugin->max_connections) | ||
1887 | GNUNET_SERVER_suspend (plugin->server); /* Maximum number of connections rechead */ | ||
1888 | |||
1878 | session = create_session (plugin, &wm->clientIdentity, client, GNUNET_NO); | 1889 | session = create_session (plugin, &wm->clientIdentity, client, GNUNET_NO); |
1879 | session->inbound = GNUNET_YES; | 1890 | session->inbound = GNUNET_YES; |
1880 | if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) | 1891 | if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) |
@@ -2088,11 +2099,10 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) | |||
2088 | 2099 | ||
2089 | if (client == NULL) | 2100 | if (client == NULL) |
2090 | return; | 2101 | return; |
2091 | plugin->max_connections++; | ||
2092 | session = lookup_session_by_client (plugin, client); | 2102 | session = lookup_session_by_client (plugin, client); |
2093 | if (session == NULL) | 2103 | if (session == NULL) |
2094 | return; /* unknown, nothing to do */ | 2104 | return; /* unknown, nothing to do */ |
2095 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2105 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2096 | "Destroying session of `%4s' with %s due to network-level disconnect.\n", | 2106 | "Destroying session of `%4s' with %s due to network-level disconnect.\n", |
2097 | GNUNET_i2s (&session->target), | 2107 | GNUNET_i2s (&session->target), |
2098 | (session->addr != | 2108 | (session->addr != |
@@ -2100,6 +2110,15 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) | |||
2100 | session->addr, | 2110 | session->addr, |
2101 | session->addrlen) : | 2111 | session->addrlen) : |
2102 | "*"); | 2112 | "*"); |
2113 | |||
2114 | if (plugin->cur_connections == plugin->max_connections) | ||
2115 | GNUNET_SERVER_resume (plugin->server); /* Resume server */ | ||
2116 | |||
2117 | if (plugin->cur_connections < 1) | ||
2118 | GNUNET_break (0); | ||
2119 | else | ||
2120 | plugin->cur_connections--; | ||
2121 | |||
2103 | GNUNET_STATISTICS_update (session->plugin->env->stats, | 2122 | GNUNET_STATISTICS_update (session->plugin->env->stats, |
2104 | gettext_noop | 2123 | gettext_noop |
2105 | ("# network-level TCP disconnect events"), 1, | 2124 | ("# network-level TCP disconnect events"), 1, |
@@ -2352,6 +2371,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2352 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 2371 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
2353 | plugin->sessionmap = GNUNET_CONTAINER_multihashmap_create (max_connections, GNUNET_YES); | 2372 | plugin->sessionmap = GNUNET_CONTAINER_multihashmap_create (max_connections, GNUNET_YES); |
2354 | plugin->max_connections = max_connections; | 2373 | plugin->max_connections = max_connections; |
2374 | plugin->cur_connections = 0; | ||
2355 | plugin->open_port = bport; | 2375 | plugin->open_port = bport; |
2356 | plugin->adv_port = aport; | 2376 | plugin->adv_port = aport; |
2357 | plugin->env = env; | 2377 | plugin->env = env; |
@@ -2421,6 +2441,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2421 | i < sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler); | 2441 | i < sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler); |
2422 | i++) | 2442 | i++) |
2423 | plugin->handlers[i].callback_cls = plugin; | 2443 | plugin->handlers[i].callback_cls = plugin; |
2444 | |||
2424 | GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); | 2445 | GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); |
2425 | GNUNET_SERVER_disconnect_notify (plugin->server, &disconnect_notify, plugin); | 2446 | GNUNET_SERVER_disconnect_notify (plugin->server, &disconnect_notify, plugin); |
2426 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); | 2447 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); |