diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2010-07-16 12:14:53 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2010-07-16 12:14:53 +0000 |
commit | f1697576ebc149465aa5b326bbc6152cd38d08fe (patch) | |
tree | c97f795a0f0e8e69e8134064fa21c961a7e90602 /src/transport | |
parent | c627f052adb2151d4ec4b5dbefb8c9f1849598a7 (diff) | |
download | gnunet-f1697576ebc149465aa5b326bbc6152cd38d08fe.tar.gz gnunet-f1697576ebc149465aa5b326bbc6152cd38d08fe.zip |
completed code for binding to a specified port
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_http.c | 155 | ||||
-rw-r--r-- | src/transport/test_plugin_transport_data_http.conf | 1 | ||||
-rw-r--r-- | src/transport/test_transport_api_http_peer1.conf | 4 | ||||
-rw-r--r-- | src/transport/test_transport_api_http_peer2.conf | 4 |
4 files changed, 107 insertions, 57 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index 3faa55627..a4ebb5087 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c | |||
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | #define DEBUG_HTTP GNUNET_YES | 43 | #define DEBUG_HTTP GNUNET_YES |
44 | #define DEBUG_CURL GNUNET_NO | 44 | #define DEBUG_CURL GNUNET_NO |
45 | #define DEBUG_CONNECTIONS GNUNET_NO | 45 | #define DEBUG_CONNECTIONS GNUNET_YES |
46 | #define DEBUG_SESSION_SELECTION GNUNET_NO | 46 | #define DEBUG_SESSION_SELECTION GNUNET_NO |
47 | 47 | ||
48 | #define INBOUND GNUNET_NO | 48 | #define INBOUND GNUNET_NO |
@@ -356,7 +356,9 @@ struct Plugin | |||
356 | */ | 356 | */ |
357 | struct GNUNET_CRYPTO_HashAsciiEncoded my_ascii_hash_ident; | 357 | struct GNUNET_CRYPTO_HashAsciiEncoded my_ascii_hash_ident; |
358 | 358 | ||
359 | struct in_addr * bind_address; | 359 | struct sockaddr_in * bind4_address; |
360 | struct sockaddr_in6 * bind6_address; | ||
361 | char * bind_hostname; | ||
360 | int use_ipv6; | 362 | int use_ipv6; |
361 | }; | 363 | }; |
362 | 364 | ||
@@ -539,12 +541,14 @@ process_interfaces (void *cls, | |||
539 | struct IPv4HttpAddress * t4; | 541 | struct IPv4HttpAddress * t4; |
540 | struct IPv6HttpAddress * t6; | 542 | struct IPv6HttpAddress * t6; |
541 | int af; | 543 | int af; |
542 | struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr; | 544 | |
543 | 545 | ||
544 | GNUNET_assert(cls !=NULL); | 546 | GNUNET_assert(cls !=NULL); |
545 | af = addr->sa_family; | 547 | af = addr->sa_family; |
546 | if (af == AF_INET) | 548 | if ((af == AF_INET) && (plugin->bind6_address == NULL)) |
547 | { | 549 | { |
550 | struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr; | ||
551 | |||
548 | t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress)); | 552 | t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress)); |
549 | /* Not skipping loopback addresses | 553 | /* Not skipping loopback addresses |
550 | if (INADDR_LOOPBACK == ntohl(((struct sockaddr_in *) addr)->sin_addr.s_addr)) | 554 | if (INADDR_LOOPBACK == ntohl(((struct sockaddr_in *) addr)->sin_addr.s_addr)) |
@@ -555,9 +559,9 @@ process_interfaces (void *cls, | |||
555 | */ | 559 | */ |
556 | t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 560 | t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
557 | t4->u_port = htons (plugin->port_inbound); | 561 | t4->u_port = htons (plugin->port_inbound); |
558 | if (plugin->bind_address != NULL) | 562 | if (plugin->bind4_address != NULL) |
559 | { | 563 | { |
560 | if (0 == memcmp(plugin->bind_address, &bnd_cmp, sizeof (struct in_addr))) | 564 | if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr))) |
561 | { | 565 | { |
562 | plugin->env->notify_address(plugin->env->cls,"http",t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); | 566 | plugin->env->notify_address(plugin->env->cls,"http",t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); |
563 | } | 567 | } |
@@ -568,26 +572,34 @@ process_interfaces (void *cls, | |||
568 | } | 572 | } |
569 | GNUNET_free (t4); | 573 | GNUNET_free (t4); |
570 | } | 574 | } |
571 | else if ((af == AF_INET6) && (plugin->use_ipv6==GNUNET_YES) && (plugin->bind_address == NULL)) | 575 | else if ((af == AF_INET6) && (plugin->use_ipv6==GNUNET_YES) && (plugin->bind4_address == NULL)) |
572 | { | 576 | { |
577 | struct in6_addr bnd_cmp6 = ((struct sockaddr_in6 *) addr)->sin6_addr; | ||
573 | t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress)); | 578 | t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress)); |
574 | if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) | 579 | if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) |
575 | { | 580 | { |
576 | /* skip link local addresses */ | ||
577 | return GNUNET_OK; | 581 | return GNUNET_OK; |
578 | } | 582 | } |
579 | /* Not skipping loopback addresses | ||
580 | if (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
581 | { | ||
582 | 583 | ||
583 | return GNUNET_OK; | 584 | if (plugin->bind6_address != NULL) |
584 | } | 585 | { |
585 | */ | 586 | if (0 == memcmp(&plugin->bind6_address->sin6_addr, &bnd_cmp6, sizeof (struct in6_addr))) |
586 | memcpy (&t6->ipv6_addr, | 587 | { |
587 | &((struct sockaddr_in6 *) addr)->sin6_addr, | 588 | memcpy (&t6->ipv6_addr, |
588 | sizeof (struct in6_addr)); | 589 | &((struct sockaddr_in6 *) addr)->sin6_addr, |
589 | t6->u6_port = htons (plugin->port_inbound); | 590 | sizeof (struct in6_addr)); |
590 | plugin->env->notify_address(plugin->env->cls,"http",t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); | 591 | t6->u6_port = htons (plugin->port_inbound); |
592 | plugin->env->notify_address(plugin->env->cls,"http",t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); | ||
593 | } | ||
594 | } | ||
595 | else | ||
596 | { | ||
597 | memcpy (&t6->ipv6_addr, | ||
598 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
599 | sizeof (struct in6_addr)); | ||
600 | t6->u6_port = htons (plugin->port_inbound); | ||
601 | plugin->env->notify_address(plugin->env->cls,"http",t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); | ||
602 | } | ||
591 | GNUNET_free (t6); | 603 | GNUNET_free (t6); |
592 | } | 604 | } |
593 | //return GNUNET_NO; | 605 | //return GNUNET_NO; |
@@ -2211,7 +2223,9 @@ libgnunet_plugin_transport_http_done (void *cls) | |||
2211 | plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; | 2223 | plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; |
2212 | } | 2224 | } |
2213 | 2225 | ||
2214 | GNUNET_free_non_null (plugin->bind_address); | 2226 | GNUNET_free_non_null (plugin->bind4_address); |
2227 | GNUNET_free_non_null (plugin->bind6_address); | ||
2228 | GNUNET_free_non_null(plugin->bind_hostname); | ||
2215 | GNUNET_free (plugin); | 2229 | GNUNET_free (plugin); |
2216 | GNUNET_free (api); | 2230 | GNUNET_free (api); |
2217 | #if DEBUG_HTTP | 2231 | #if DEBUG_HTTP |
@@ -2233,11 +2247,6 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2233 | struct GNUNET_TIME_Relative gn_timeout; | 2247 | struct GNUNET_TIME_Relative gn_timeout; |
2234 | long long unsigned int port; | 2248 | long long unsigned int port; |
2235 | 2249 | ||
2236 | char * hostname = NULL; | ||
2237 | //struct sockaddr_in b4_addr; | ||
2238 | //struct sockaddr_in6 b6_addr; | ||
2239 | |||
2240 | |||
2241 | GNUNET_assert(cls !=NULL); | 2250 | GNUNET_assert(cls !=NULL); |
2242 | #if DEBUG_HTTP | 2251 | #if DEBUG_HTTP |
2243 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting http plugin...\n"); | 2252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting http plugin...\n"); |
@@ -2247,7 +2256,7 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2247 | plugin->stats = env->stats; | 2256 | plugin->stats = env->stats; |
2248 | plugin->env = env; | 2257 | plugin->env = env; |
2249 | plugin->peers = NULL; | 2258 | plugin->peers = NULL; |
2250 | plugin->bind_address = NULL; | 2259 | plugin->bind4_address = NULL; |
2251 | plugin->use_ipv6 = GNUNET_YES; | 2260 | plugin->use_ipv6 = GNUNET_YES; |
2252 | 2261 | ||
2253 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 2262 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
@@ -2272,8 +2281,6 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2272 | 2281 | ||
2273 | 2282 | ||
2274 | } | 2283 | } |
2275 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2276 | "IPV6 is %u\n",plugin->use_ipv6 ); | ||
2277 | /* Reading port number from config file */ | 2284 | /* Reading port number from config file */ |
2278 | if ((GNUNET_OK != | 2285 | if ((GNUNET_OK != |
2279 | GNUNET_CONFIGURATION_get_value_number (env->cfg, | 2286 | GNUNET_CONFIGURATION_get_value_number (env->cfg, |
@@ -2290,34 +2297,76 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2290 | return NULL; | 2297 | return NULL; |
2291 | } | 2298 | } |
2292 | 2299 | ||
2293 | /* Reading port number from config file */ | 2300 | /* Reading ipv4 addresse to bind to from config file */ |
2294 | if (GNUNET_CONFIGURATION_have_value (env->cfg, | 2301 | if (GNUNET_CONFIGURATION_have_value (env->cfg, |
2295 | "transport-http", "BINDTO")) | 2302 | "transport-http", "BINDTO4")) |
2296 | { | 2303 | { |
2297 | GNUNET_break (GNUNET_OK == | 2304 | GNUNET_break (GNUNET_OK == |
2298 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | 2305 | GNUNET_CONFIGURATION_get_value_string (env->cfg, |
2299 | "transport-http", | 2306 | "transport-http", |
2300 | "BINDTO", | 2307 | "BINDTO4", |
2301 | &hostname)); | 2308 | &plugin->bind_hostname)); |
2302 | plugin->bind_address = GNUNET_malloc(sizeof(struct in_addr*)); | 2309 | plugin->bind4_address = GNUNET_malloc(sizeof(struct sockaddr_in)); |
2303 | if (inet_aton(hostname, plugin->bind_address)==0) | 2310 | plugin->bind4_address->sin_family = AF_INET; |
2304 | { | 2311 | plugin->bind4_address->sin_port = htons (port); |
2305 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 2312 | |
2306 | "http", | 2313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"v4 Hostname `%s'!\n",plugin->bind_hostname); |
2307 | _("Misconfigured address to bind to in configuration!\n"), | 2314 | |
2308 | "transport-http"); | 2315 | if (inet_pton(AF_INET,plugin->bind_hostname, &plugin->bind4_address->sin_addr)<=0) |
2309 | GNUNET_free(plugin->bind_address); | 2316 | { |
2310 | plugin->bind_address = NULL; | 2317 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, |
2311 | } | 2318 | "http", |
2312 | GNUNET_free_non_null (hostname); | 2319 | _("Misconfigured address to bind to in configuration!\n"), |
2313 | } | 2320 | "transport-http"); |
2321 | GNUNET_free(plugin->bind4_address); | ||
2322 | GNUNET_free(plugin->bind_hostname); | ||
2323 | plugin->bind_hostname = NULL; | ||
2324 | plugin->bind4_address = NULL; | ||
2325 | } | ||
2326 | } | ||
2327 | |||
2328 | /* Reading ipv4 addresse to bind to from config file */ | ||
2329 | if (GNUNET_CONFIGURATION_have_value (env->cfg, | ||
2330 | "transport-http", "BINDTO6")) | ||
2331 | { | ||
2332 | GNUNET_break (GNUNET_OK == | ||
2333 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | ||
2334 | "transport-http", | ||
2335 | "BINDTO6", | ||
2336 | &plugin->bind_hostname)); | ||
2337 | |||
2338 | plugin->bind6_address = GNUNET_malloc(sizeof(struct sockaddr_in6)); | ||
2339 | plugin->bind6_address->sin6_family = AF_INET6; | ||
2340 | plugin->bind6_address->sin6_port = htons (port); | ||
2341 | |||
2342 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"v6 Hostname `%s'!\n",plugin->bind_hostname); | ||
2343 | |||
2344 | if (inet_pton(AF_INET6,plugin->bind_hostname, &plugin->bind6_address->sin6_addr)<=0) | ||
2345 | { | ||
2346 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2347 | "http", | ||
2348 | _("Misconfigured address to bind to in configuration!\n"), | ||
2349 | "transport-http"); | ||
2350 | GNUNET_free(plugin->bind6_address); | ||
2351 | GNUNET_free(plugin->bind_hostname); | ||
2352 | plugin->bind_hostname = NULL; | ||
2353 | plugin->bind6_address = NULL; | ||
2354 | |||
2355 | } | ||
2356 | |||
2357 | char * tmp = GNUNET_malloc(50); | ||
2358 | inet_ntop(AF_INET6,&plugin->bind6_address->sin6_addr,tmp,50); | ||
2359 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"v6 Hostname reverse `%s'!\n",tmp); | ||
2360 | GNUNET_free(tmp); | ||
2361 | } | ||
2362 | |||
2314 | GNUNET_assert ((port > 0) && (port <= 65535)); | 2363 | GNUNET_assert ((port > 0) && (port <= 65535)); |
2315 | plugin->port_inbound = port; | 2364 | plugin->port_inbound = port; |
2316 | gn_timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; | 2365 | gn_timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; |
2317 | unsigned int timeout = (gn_timeout.value) / 1000; | 2366 | unsigned int timeout = (gn_timeout.value) / 1000; |
2318 | if ((plugin->http_server_daemon_v6 == NULL) && (plugin->use_ipv6 == GNUNET_YES) && (port != 0)) | 2367 | if ((plugin->http_server_daemon_v6 == NULL) && (plugin->use_ipv6 == GNUNET_YES) && (port != 0)) |
2319 | { | 2368 | { |
2320 | 2369 | struct sockaddr * tmp = (struct sockaddr *) plugin->bind6_address; | |
2321 | plugin->http_server_daemon_v6 = MHD_start_daemon ( | 2370 | plugin->http_server_daemon_v6 = MHD_start_daemon ( |
2322 | #if DEBUG_CONNECTIONS | 2371 | #if DEBUG_CONNECTIONS |
2323 | MHD_USE_DEBUG | | 2372 | MHD_USE_DEBUG | |
@@ -2326,7 +2375,7 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2326 | port, | 2375 | port, |
2327 | &mhd_accept_cb, | 2376 | &mhd_accept_cb, |
2328 | plugin , &mdh_access_cb, plugin, | 2377 | plugin , &mdh_access_cb, plugin, |
2329 | //MHD_OPTION_SOCK_ADDR, (struct sockaddr *) &b6_addr, | 2378 | MHD_OPTION_SOCK_ADDR, tmp, |
2330 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, | 2379 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, |
2331 | MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, | 2380 | MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, |
2332 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, | 2381 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, |
@@ -2344,7 +2393,7 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2344 | port, | 2393 | port, |
2345 | &mhd_accept_cb, | 2394 | &mhd_accept_cb, |
2346 | plugin , &mdh_access_cb, plugin, | 2395 | plugin , &mdh_access_cb, plugin, |
2347 | //MHD_OPTION_SOCK_ADDR, (struct sockaddr *) &b4_addr, | 2396 | MHD_OPTION_SOCK_ADDR, (struct sockaddr_in *)plugin->bind4_address, |
2348 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, | 2397 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, |
2349 | MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, | 2398 | MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, |
2350 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, | 2399 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, |
@@ -2361,13 +2410,13 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2361 | if (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) | 2410 | if (plugin->http_server_task_v4 != GNUNET_SCHEDULER_NO_TASK) |
2362 | { | 2411 | { |
2363 | #if DEBUG_HTTP | 2412 | #if DEBUG_HTTP |
2364 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD with IPv4 on port %u\n",port); | 2413 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD with IPv4 bound to %s with port %u\n",(plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address",port); |
2365 | #endif | 2414 | #endif |
2366 | } | 2415 | } |
2367 | else if (plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) | 2416 | else if (plugin->http_server_task_v6 != GNUNET_SCHEDULER_NO_TASK) |
2368 | { | 2417 | { |
2369 | #if DEBUG_HTTP | 2418 | #if DEBUG_HTTP |
2370 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD with IPv4 and IPv6 on port %u\n",port); | 2419 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting MHD with IPv4 and IPv6 bound to %s with port %u\n",(plugin->bind_hostname!=NULL) ? plugin->bind_hostname : "every address", port); |
2371 | #endif | 2420 | #endif |
2372 | } | 2421 | } |
2373 | else | 2422 | else |
diff --git a/src/transport/test_plugin_transport_data_http.conf b/src/transport/test_plugin_transport_data_http.conf index f17627776..d03f4e840 100644 --- a/src/transport/test_plugin_transport_data_http.conf +++ b/src/transport/test_plugin_transport_data_http.conf | |||
@@ -9,6 +9,7 @@ WEAKRANDOM = YES | |||
9 | PORT = 12389 | 9 | PORT = 12389 |
10 | DEBUG = NO | 10 | DEBUG = NO |
11 | USE_IPv6 = YES | 11 | USE_IPv6 = YES |
12 | #USE_IPv6 = NO | ||
12 | #BINDTO4 = 127.0.0.1 | 13 | #BINDTO4 = 127.0.0.1 |
13 | #BINDTO6 = ::1 | 14 | #BINDTO6 = ::1 |
14 | 15 | ||
diff --git a/src/transport/test_transport_api_http_peer1.conf b/src/transport/test_transport_api_http_peer1.conf index 9521999ee..b7e8fb536 100644 --- a/src/transport/test_transport_api_http_peer1.conf +++ b/src/transport/test_transport_api_http_peer1.conf | |||
@@ -1,8 +1,8 @@ | |||
1 | [transport-http] | 1 | [transport-http] |
2 | PORT = 12389 | 2 | PORT = 12389 |
3 | DEBUG = NO | 3 | DEBUG = NO |
4 | USE_IPv6 = YES | 4 | USE_IPv6 = NO |
5 | #BINDTO4 = 127.0.0.1 | 5 | BINDTO4 = 127.0.0.1 |
6 | #BINDTO6 = ::1 | 6 | #BINDTO6 = ::1 |
7 | 7 | ||
8 | 8 | ||
diff --git a/src/transport/test_transport_api_http_peer2.conf b/src/transport/test_transport_api_http_peer2.conf index ad8e2fb90..6cdd84fe7 100644 --- a/src/transport/test_transport_api_http_peer2.conf +++ b/src/transport/test_transport_api_http_peer2.conf | |||
@@ -1,8 +1,8 @@ | |||
1 | [transport-http] | 1 | [transport-http] |
2 | PORT = 22368 | 2 | PORT = 22368 |
3 | DEBUG = NO | 3 | DEBUG = NO |
4 | USE_IPv6 = YES | 4 | USE_IPv6 = NO |
5 | #BINDTO4 = 127.0.0.1 | 5 | BINDTO4 = 127.0.0.1 |
6 | #BINDTO6 = ::1 | 6 | #BINDTO6 = ::1 |
7 | 7 | ||
8 | [fs] | 8 | [fs] |