aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-06-16 08:18:06 +0000
committerChristian Grothoff <christian@grothoff.org>2011-06-16 08:18:06 +0000
commit94c41ff98d293d8c041c4bbbe8d19dbf8ccd6f3f (patch)
treef9128a5bffcb9e2bf5abf4d2a74c5c0ddecec276
parent29e0d43e92d47ec5e6b632184939518546b74520 (diff)
downloadgnunet-94c41ff98d293d8c041c4bbbe8d19dbf8ccd6f3f.tar.gz
gnunet-94c41ff98d293d8c041c4bbbe8d19dbf8ccd6f3f.zip
add connection limit to TCP
-rw-r--r--src/transport/plugin_transport_tcp.c48
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 */
527static int
528plugin_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));