diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-06-16 08:18:06 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-06-16 08:18:06 +0000 |
commit | 94c41ff98d293d8c041c4bbbe8d19dbf8ccd6f3f (patch) | |
tree | f9128a5bffcb9e2bf5abf4d2a74c5c0ddecec276 | |
parent | 29e0d43e92d47ec5e6b632184939518546b74520 (diff) | |
download | gnunet-94c41ff98d293d8c041c4bbbe8d19dbf8ccd6f3f.tar.gz gnunet-94c41ff98d293d8c041c4bbbe8d19dbf8ccd6f3f.zip |
add connection limit to TCP
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index d1f45b2f7..11b7bc3f1 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -462,6 +462,11 @@ struct Plugin | |||
462 | * Handle for (DYN)DNS lookup of our external IP. | 462 | * Handle for (DYN)DNS lookup of our external IP. |
463 | */ | 463 | */ |
464 | struct GNUNET_RESOLVER_RequestHandle *ext_dns; | 464 | struct GNUNET_RESOLVER_RequestHandle *ext_dns; |
465 | |||
466 | /** | ||
467 | * How many more TCP sessions are we allowed to open right now? | ||
468 | */ | ||
469 | unsigned long long max_connections; | ||
465 | 470 | ||
466 | /** | 471 | /** |
467 | * ID of task used to update our addresses when one expires. | 472 | * ID of task used to update our addresses when one expires. |
@@ -508,6 +513,33 @@ struct Plugin | |||
508 | 513 | ||
509 | 514 | ||
510 | /** | 515 | /** |
516 | * Function to check if an inbound connection is acceptable. | ||
517 | * Mostly used to limit the total number of open connections | ||
518 | * we can have. | ||
519 | * | ||
520 | * @param cls the 'struct Plugin' | ||
521 | * @param ucred credentials, if available, otherwise NULL | ||
522 | * @param addr address | ||
523 | * @param addrlen length of address | ||
524 | * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR | ||
525 | * for unknown address family (will be denied). | ||
526 | */ | ||
527 | static int | ||
528 | plugin_tcp_access_check (void *cls, | ||
529 | const struct GNUNET_CONNECTION_Credentials *ucred, | ||
530 | const struct sockaddr *addr, | ||
531 | socklen_t addrlen) | ||
532 | { | ||
533 | struct Plugin *plugin = cls; | ||
534 | |||
535 | if (0 == plugin->max_connections) | ||
536 | return GNUNET_NO; | ||
537 | plugin->max_connections--; | ||
538 | return GNUNET_YES; | ||
539 | } | ||
540 | |||
541 | |||
542 | /** | ||
511 | * Our external IP address/port mapping has changed. | 543 | * Our external IP address/port mapping has changed. |
512 | * | 544 | * |
513 | * @param cls closure, the 'struct LocalAddrList' | 545 | * @param cls closure, the 'struct LocalAddrList' |
@@ -1387,7 +1419,8 @@ tcp_plugin_send (void *cls, | |||
1387 | 1419 | ||
1388 | if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress))) | 1420 | if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress))) |
1389 | return -1; /* NAT client only works with IPv4 addresses */ | 1421 | return -1; /* NAT client only works with IPv4 addresses */ |
1390 | 1422 | if (0 == plugin->max_connections) | |
1423 | return -1; /* saturated */ | ||
1391 | 1424 | ||
1392 | if ( (plugin->enable_nat_client == GNUNET_YES) && | 1425 | if ( (plugin->enable_nat_client == GNUNET_YES) && |
1393 | (is_natd == GNUNET_YES) && | 1426 | (is_natd == GNUNET_YES) && |
@@ -1460,6 +1493,8 @@ tcp_plugin_send (void *cls, | |||
1460 | GNUNET_NO); | 1493 | GNUNET_NO); |
1461 | return -1; | 1494 | return -1; |
1462 | } | 1495 | } |
1496 | GNUNET_assert (0 != plugin->max_connections); | ||
1497 | plugin->max_connections--; | ||
1463 | #if DEBUG_TCP_NAT | 1498 | #if DEBUG_TCP_NAT |
1464 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1499 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1465 | "tcp", | 1500 | "tcp", |
@@ -2160,6 +2195,7 @@ disconnect_notify (void *cls, | |||
2160 | 2195 | ||
2161 | if (client == NULL) | 2196 | if (client == NULL) |
2162 | return; | 2197 | return; |
2198 | plugin->max_connections++; | ||
2163 | session = find_session_by_client (plugin, client); | 2199 | session = find_session_by_client (plugin, client); |
2164 | if (session == NULL) | 2200 | if (session == NULL) |
2165 | return; /* unknown, nothing to do */ | 2201 | return; /* unknown, nothing to do */ |
@@ -2839,6 +2875,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2839 | struct GNUNET_SERVICE_Context *service; | 2875 | struct GNUNET_SERVICE_Context *service; |
2840 | unsigned long long aport; | 2876 | unsigned long long aport; |
2841 | unsigned long long bport; | 2877 | unsigned long long bport; |
2878 | unsigned long long max_connections; | ||
2842 | unsigned int i; | 2879 | unsigned int i; |
2843 | int behind_nat; | 2880 | int behind_nat; |
2844 | int nat_punched; | 2881 | int nat_punched; |
@@ -2975,6 +3012,12 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2975 | "tcp","New internal address `%s'\n", internal_address); | 3012 | "tcp","New internal address `%s'\n", internal_address); |
2976 | } | 3013 | } |
2977 | } | 3014 | } |
3015 | if (GNUNET_OK != | ||
3016 | GNUNET_CONFIGURATION_get_value_number (env->cfg, | ||
3017 | "transport-tcp", | ||
3018 | "MAX_CONNECTIONS", | ||
3019 | &max_connections)) | ||
3020 | max_connections = 128; | ||
2978 | 3021 | ||
2979 | aport = 0; | 3022 | aport = 0; |
2980 | if ( (GNUNET_OK != | 3023 | if ( (GNUNET_OK != |
@@ -3025,6 +3068,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3025 | service = NULL; | 3068 | service = NULL; |
3026 | 3069 | ||
3027 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 3070 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
3071 | plugin->max_connections = max_connections; | ||
3028 | plugin->open_port = bport; | 3072 | plugin->open_port = bport; |
3029 | plugin->adv_port = aport; | 3073 | plugin->adv_port = aport; |
3030 | plugin->bind_address = bind_address; | 3074 | plugin->bind_address = bind_address; |
@@ -3068,7 +3112,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3068 | GNUNET_free (api); | 3112 | GNUNET_free (api); |
3069 | return NULL; | 3113 | return NULL; |
3070 | } | 3114 | } |
3071 | plugin->server = GNUNET_SERVER_create_with_sockets (NULL, NULL, NULL, | 3115 | plugin->server = GNUNET_SERVER_create_with_sockets (&plugin_tcp_access_check, plugin, NULL, |
3072 | idle_timeout, GNUNET_YES); | 3116 | idle_timeout, GNUNET_YES); |
3073 | } | 3117 | } |
3074 | plugin->handlers = GNUNET_malloc (sizeof (my_handlers)); | 3118 | plugin->handlers = GNUNET_malloc (sizeof (my_handlers)); |