aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO22
-rw-r--r--src/nat/gnunet-nat-client-windows.c6
-rw-r--r--src/nat/gnunet-nat-client.c2
-rw-r--r--src/nat/gnunet-nat-server-windows.c2
-rw-r--r--src/nat/gnunet-nat-server.c2
-rw-r--r--src/nat/nat.c169
-rw-r--r--src/transport/gnunet-service-transport.c37
7 files changed, 197 insertions, 43 deletions
diff --git a/TODO b/TODO
index 9bfde8893..99b091aca 100644
--- a/TODO
+++ b/TODO
@@ -1,17 +1,15 @@
10.9.0pre3: 10.9.0pre3:
2* clean buildbots 2* clean buildbots
3 3
40.9.0: 40.9.0pre4:
5* new webpage: 5* NAT library: [CG/MW]
6 - write chapter on DHT/block [Nate] 6 - UPnP support
7 - make a NICE download page 7 - testcase
8* NAT/UPNP: [CG/MW] 8 - more testing
9 - write NAT library
10* Transport: 9* Transport:
11 - UDP fragmentation [MW] 10 - UDP fragmentation [MW]
12 - decide how to deal with 'DISABLEV6' option (where does it live?) 11 - decide how to deal with 'DISABLEV6' option (where does it live?)
13 - integration of new NAT/plugin API with HTTP/HTTPS plugin 12 - integration of new NAT/plugin API with HTTP/HTTPS plugin
14 - fix WLAN plugin for new plugin API (easy)
15 - testing (again) 13 - testing (again)
16* GNUNET-GTK: [CG] 14* GNUNET-GTK: [CG]
17 - figure out where in the GUI we should show active upload operations and allow aborts 15 - figure out where in the GUI we should show active upload operations and allow aborts
@@ -24,6 +22,11 @@
24 + insert 22 + insert
25 + download 23 + download
26 + search 24 + search
25
260.9.0:
27* new webpage:
28 - write chapter on DHT/block [Nate]
29 - make a NICE download page
27* big code review 30* big code review
28* Determine RC bugs and fix those (release should have no known real bugs) 31* Determine RC bugs and fix those (release should have no known real bugs)
29 32
@@ -71,11 +74,6 @@
71 - better tracking of which config changes actually need to cause process restarts by ARM. 74 - better tracking of which config changes actually need to cause process restarts by ARM.
72 - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?) 75 - handle gnunet-arm -k in combination with auto-start magic (what is the right thing here?)
73 - discover dependencies between services 76 - discover dependencies between services
74* MONKEY: [Safey]
75 - better crash management (attach debugging support, capture and analyze
76 debug output, detect random vs. deterministic crashes)
77 - '-m EMAIL' option for alternative e-mail TO
78 - '-f FILENAME' option to write report to file instead of e-mail (for testing!)
79 77
800.9.2: 780.9.2:
81* PEERINFO: [NN] 79* PEERINFO: [NN]
diff --git a/src/nat/gnunet-nat-client-windows.c b/src/nat/gnunet-nat-client-windows.c
index 2e7c8a86e..2fe3643ac 100644
--- a/src/nat/gnunet-nat-client-windows.c
+++ b/src/nat/gnunet-nat-client-windows.c
@@ -19,10 +19,10 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file src/transport/gnunet-nat-client-windows.c 22 * @file src/nat/gnunet-nat-client-windows.c
23 * @brief Tool to help bypass NATs using ICMP method; must run as 23 * @brief Tool to help bypass NATs using ICMP method; must run as
24 * root (SUID will do) or administrator on W32 24 * administrator on W32
25 * This code will work under GNU/Linux or W32. 25 * This code is forx W32.
26 * @author Nathan Evans 26 * @author Nathan Evans
27 * 27 *
28 * This program will send ONE ICMP message using RAW sockets 28 * This program will send ONE ICMP message using RAW sockets
diff --git a/src/nat/gnunet-nat-client.c b/src/nat/gnunet-nat-client.c
index 3e35aa8f4..5f54f729b 100644
--- a/src/nat/gnunet-nat-client.c
+++ b/src/nat/gnunet-nat-client.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file src/transport/gnunet-nat-client.c 22 * @file src/nat/gnunet-nat-client.c
23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do) 23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do)
24 * This code will work under GNU/Linux only. 24 * This code will work under GNU/Linux only.
25 * @author Christian Grothoff 25 * @author Christian Grothoff
diff --git a/src/nat/gnunet-nat-server-windows.c b/src/nat/gnunet-nat-server-windows.c
index 8cfad2ff2..6c4c7d7a1 100644
--- a/src/nat/gnunet-nat-server-windows.c
+++ b/src/nat/gnunet-nat-server-windows.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file src/transport/gnunet-nat-server-windows.c 22 * @file src/nat/gnunet-nat-server-windows.c
23 * @brief Windows tool to help bypass NATs using ICMP method 23 * @brief Windows tool to help bypass NATs using ICMP method
24 * This code will work under W32 only 24 * This code will work under W32 only
25 * @author Christian Grothoff 25 * @author Christian Grothoff
diff --git a/src/nat/gnunet-nat-server.c b/src/nat/gnunet-nat-server.c
index ab99b5f28..ffc570146 100644
--- a/src/nat/gnunet-nat-server.c
+++ b/src/nat/gnunet-nat-server.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file src/transport/gnunet-nat-server.c 22 * @file src/nat/gnunet-nat-server.c
23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do) 23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do)
24 * This code will work under GNU/Linux only (or maybe BSDs, but never W32) 24 * This code will work under GNU/Linux only (or maybe BSDs, but never W32)
25 * @author Christian Grothoff 25 * @author Christian Grothoff
diff --git a/src/nat/nat.c b/src/nat/nat.c
index c4a4c75cb..e5a3e0e0f 100644
--- a/src/nat/nat.c
+++ b/src/nat/nat.c
@@ -27,13 +27,32 @@
27 * 27 *
28 * TODO: 28 * TODO:
29 * - implement UPnP/PMP support 29 * - implement UPnP/PMP support
30 * - repeatedly perform certain checks again to notice changes 30 * - make frequency of checks configurable
31 */ 31 */
32#include "platform.h" 32#include "platform.h"
33#include "gnunet_util_lib.h" 33#include "gnunet_util_lib.h"
34#include "gnunet_resolver_service.h" 34#include "gnunet_resolver_service.h"
35#include "gnunet_nat_lib.h" 35#include "gnunet_nat_lib.h"
36 36
37/**
38 * How often do we scan for changes in our IP address from our local
39 * interfaces?
40 * FIXME: make this configurable...
41 */
42#define IFC_SCAN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
43
44/**
45 * How often do we scan for changes in how our hostname resolves?
46 * FIXME: make this configurable...
47 */
48#define HOSTNAME_DNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 20)
49
50
51/**
52 * How often do we scan for changes in how our external (dyndns) hostname resolves?
53 * FIXME: make this configurable...
54 */
55#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 7)
37 56
38/** 57/**
39 * How long until we give up on transmitting the welcome message? 58 * How long until we give up on transmitting the welcome message?
@@ -52,20 +71,17 @@ enum LocalAddressSource
52 /** 71 /**
53 * Address was obtained by DNS resolution of the external hostname 72 * Address was obtained by DNS resolution of the external hostname
54 * given in the configuration (i.e. hole-punched DynDNS setup). 73 * given in the configuration (i.e. hole-punched DynDNS setup).
55 * FIXME: repeatedly do the lookup to notice changes!
56 */ 74 */
57 LAL_EXTERNAL_IP, 75 LAL_EXTERNAL_IP,
58 76
59 /** 77 /**
60 * Address was obtained by looking up our own hostname in DNS. 78 * Address was obtained by looking up our own hostname in DNS.
61 * FIXME: repeatedly do the lookup to notice changes!
62 */ 79 */
63 LAL_HOSTNAME_DNS, 80 LAL_HOSTNAME_DNS,
64 81
65 /** 82 /**
66 * Address was obtained by scanning our hosts's network interfaces 83 * Address was obtained by scanning our hosts's network interfaces
67 * and taking their address (no DNS involved). 84 * and taking their address (no DNS involved).
68 * FIXME: repeatedly do the lookup to notice changes!
69 */ 85 */
70 LAL_INTERFACE_ADDRESS, 86 LAL_INTERFACE_ADDRESS,
71 87
@@ -183,6 +199,16 @@ struct GNUNET_NAT_Handle
183 GNUNET_SCHEDULER_TaskIdentifier ifc_task; 199 GNUNET_SCHEDULER_TaskIdentifier ifc_task;
184 200
185 /** 201 /**
202 * ID of hostname DNS lookup task
203 */
204 GNUNET_SCHEDULER_TaskIdentifier hostname_task;
205
206 /**
207 * ID of DynDNS lookup task
208 */
209 GNUNET_SCHEDULER_TaskIdentifier dns_task;
210
211 /**
186 * The process id of the server process (if behind NAT) 212 * The process id of the server process (if behind NAT)
187 */ 213 */
188 struct GNUNET_OS_Process *server_proc; 214 struct GNUNET_OS_Process *server_proc;
@@ -271,6 +297,38 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
271 297
272 298
273/** 299/**
300 * Remove all addresses from the list of 'local' addresses
301 * that originated from the given source.
302 *
303 * @param plugin the plugin
304 * @param src source that identifies addresses to remove
305 */
306static void
307remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h,
308 enum LocalAddressSource src)
309{
310 struct LocalAddressList *pos;
311 struct LocalAddressList *next;
312
313 next = h->lal_head;
314 while (NULL != (pos = next))
315 {
316 next = pos->next;
317 if (pos->source != src)
318 continue;
319 GNUNET_CONTAINER_DLL_remove (h->lal_head,
320 h->lal_tail,
321 pos);
322 h->address_callback (h->callback_cls,
323 GNUNET_NO,
324 (const struct sockaddr* ) &pos[1],
325 pos->addrlen);
326 GNUNET_free (pos);
327 }
328}
329
330
331/**
274 * Add the given address to the list of 'local' addresses, thereby 332 * Add the given address to the list of 'local' addresses, thereby
275 * making it a 'legal' address for this peer to have. 333 * making it a 'legal' address for this peer to have.
276 * 334 *
@@ -438,6 +496,18 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
438 496
439 497
440/** 498/**
499 * Task to do DNS lookup on our external hostname to
500 * get DynDNS-IP addresses.
501 *
502 * @param cls the NAT handle
503 * @param tc scheduler context
504 */
505static void
506resolve_dns (void *cls,
507 const struct GNUNET_SCHEDULER_TaskContext *tc);
508
509
510/**
441 * Our (external) hostname was resolved and the configuration says that 511 * Our (external) hostname was resolved and the configuration says that
442 * the NAT was hole-punched. 512 * the NAT was hole-punched.
443 * 513 *
@@ -455,9 +525,8 @@ process_external_ip (void *cls,
455 if (addr == NULL) 525 if (addr == NULL)
456 { 526 {
457 h->ext_dns = NULL; 527 h->ext_dns = NULL;
458 /* FIXME: schedule task to resolve IP again in the 528 h->dns_task = GNUNET_SCHEDULER_add_delayed (DYNDNS_FREQUENCY,
459 future, and if the result changes, update the 529 &resolve_dns, h);
460 local address list accordingly */
461 return; 530 return;
462 } 531 }
463 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen); 532 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen);
@@ -465,6 +534,17 @@ process_external_ip (void *cls,
465 534
466 535
467/** 536/**
537 * Task to do a lookup on our hostname for IP addresses.
538 *
539 * @param cls the NAT handle
540 * @param tc scheduler context
541 */
542static void
543resolve_hostname (void *cls,
544 const struct GNUNET_SCHEDULER_TaskContext *tc);
545
546
547/**
468 * Function called by the resolver for each address obtained from DNS 548 * Function called by the resolver for each address obtained from DNS
469 * for our own hostname. Add the addresses to the list of our IP 549 * for our own hostname. Add the addresses to the list of our IP
470 * addresses. 550 * addresses.
@@ -482,9 +562,8 @@ process_hostname_ip (void *cls,
482 if (addr == NULL) 562 if (addr == NULL)
483 { 563 {
484 h->hostname_dns = NULL; 564 h->hostname_dns = NULL;
485 /* FIXME: schedule task to resolve IP again in the 565 h->hostname_task = GNUNET_SCHEDULER_add_delayed (HOSTNAME_DNS_FREQUENCY,
486 future, and if the result changes, update the 566 &resolve_hostname, h);
487 address list accordingly */
488 return; 567 return;
489 } 568 }
490 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen); 569 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen);
@@ -874,11 +953,54 @@ list_interfaces (void *cls,
874 struct GNUNET_NAT_Handle *h = cls; 953 struct GNUNET_NAT_Handle *h = cls;
875 954
876 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 955 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
956 remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS);
877 GNUNET_OS_network_interfaces_list (&process_interfaces, h); 957 GNUNET_OS_network_interfaces_list (&process_interfaces, h);
878#if 0 958 h->ifc_task = GNUNET_SCHEDULER_add_delayed (IFC_SCAN_FREQUENCY,
879 h->ifc_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FIXME,
880 &list_interfaces, h); 959 &list_interfaces, h);
881#endif 960}
961
962
963/**
964 * Task to do a lookup on our hostname for IP addresses.
965 *
966 * @param cls the NAT handle
967 * @param tc scheduler context
968 */
969static void
970resolve_hostname (void *cls,
971 const struct GNUNET_SCHEDULER_TaskContext *tc)
972{
973 struct GNUNET_NAT_Handle *h = cls;
974
975 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
976 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS);
977 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
978 HOSTNAME_RESOLVE_TIMEOUT,
979 &process_hostname_ip,
980 h);
981}
982
983
984/**
985 * Task to do DNS lookup on our external hostname to
986 * get DynDNS-IP addresses.
987 *
988 * @param cls the NAT handle
989 * @param tc scheduler context
990 */
991static void
992resolve_dns (void *cls,
993 const struct GNUNET_SCHEDULER_TaskContext *tc)
994{
995 struct GNUNET_NAT_Handle *h = cls;
996
997 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
998 remove_from_address_list_by_source (h, LAL_EXTERNAL_IP);
999 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address,
1000 AF_INET,
1001 GNUNET_TIME_UNIT_MINUTES,
1002 &process_external_ip,
1003 h);
882} 1004}
883 1005
884 1006
@@ -1014,11 +1136,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1014 (h->external_address != NULL) && 1136 (h->external_address != NULL) &&
1015 (h->nat_punched == GNUNET_YES) ) 1137 (h->nat_punched == GNUNET_YES) )
1016 { 1138 {
1017 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address, 1139 h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h);
1018 AF_INET,
1019 GNUNET_TIME_UNIT_MINUTES,
1020 &process_external_ip,
1021 h);
1022 h->enable_nat_server = GNUNET_NO; 1140 h->enable_nat_server = GNUNET_NO;
1023 h->enable_upnp = GNUNET_NO; 1141 h->enable_upnp = GNUNET_NO;
1024 } 1142 }
@@ -1049,10 +1167,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1049 if (NULL != h->address_callback) 1167 if (NULL != h->address_callback)
1050 { 1168 {
1051 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); 1169 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h);
1052 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, 1170 h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h);
1053 HOSTNAME_RESOLVE_TIMEOUT,
1054 &process_hostname_ip,
1055 h);
1056 } 1171 }
1057 return h; 1172 return h;
1058} 1173}
@@ -1090,6 +1205,16 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1090 GNUNET_SCHEDULER_cancel (h->ifc_task); 1205 GNUNET_SCHEDULER_cancel (h->ifc_task);
1091 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 1206 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
1092 } 1207 }
1208 if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task)
1209 {
1210 GNUNET_SCHEDULER_cancel (h->hostname_task);
1211 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
1212 }
1213 if (GNUNET_SCHEDULER_NO_TASK != h->dns_task)
1214 {
1215 GNUNET_SCHEDULER_cancel (h->dns_task);
1216 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
1217 }
1093 if (NULL != h->server_proc) 1218 if (NULL != h->server_proc)
1094 { 1219 {
1095 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) 1220 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM))
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 427b8dabd..2e90bcf3e 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -1218,6 +1218,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *validation_map;
1218static struct GNUNET_STATISTICS_Handle *stats; 1218static struct GNUNET_STATISTICS_Handle *stats;
1219 1219
1220/** 1220/**
1221 * Identifier of 'refresh_hello' task.
1222 */
1223static GNUNET_SCHEDULER_TaskIdentifier hello_task;
1224
1225/**
1221 * Is transport service shutting down ? 1226 * Is transport service shutting down ?
1222 */ 1227 */
1223static int shutdown_in_progress; 1228static int shutdown_in_progress;
@@ -2448,15 +2453,20 @@ address_generator (void *cls, size_t max, void *buf)
2448/** 2453/**
2449 * Construct our HELLO message from all of the addresses of 2454 * Construct our HELLO message from all of the addresses of
2450 * all of the transports. 2455 * all of the transports.
2456 *
2457 * @param cls unused
2458 * @param tc scheduler context
2451 */ 2459 */
2452static void 2460static void
2453refresh_hello () 2461refresh_hello_task (void *cls,
2462 const struct GNUNET_SCHEDULER_TaskContext *tc)
2454{ 2463{
2455 struct GNUNET_HELLO_Message *hello; 2464 struct GNUNET_HELLO_Message *hello;
2456 struct TransportClient *cpos; 2465 struct TransportClient *cpos;
2457 struct NeighbourList *npos; 2466 struct NeighbourList *npos;
2458 struct GeneratorContext gc; 2467 struct GeneratorContext gc;
2459 2468
2469 hello_task = GNUNET_SCHEDULER_NO_TASK;
2460 gc.plug_pos = plugins; 2470 gc.plug_pos = plugins;
2461 gc.addr_pos = plugins != NULL ? plugins->addresses : NULL; 2471 gc.addr_pos = plugins != NULL ? plugins->addresses : NULL;
2462 gc.expiration = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); 2472 gc.expiration = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
@@ -2504,6 +2514,21 @@ refresh_hello ()
2504 2514
2505 2515
2506/** 2516/**
2517 * Schedule task to refresh hello (unless such a
2518 * task exists already).
2519 */
2520static void
2521refresh_hello ()
2522{
2523 if (hello_task != GNUNET_SCHEDULER_NO_TASK)
2524 return;
2525 hello_task
2526 = GNUNET_SCHEDULER_add_now (&refresh_hello_task,
2527 NULL);
2528}
2529
2530
2531/**
2507 * Iterator over hash map entries that NULLs the session of validation 2532 * Iterator over hash map entries that NULLs the session of validation
2508 * entries that match the given session. 2533 * entries that match the given session.
2509 * 2534 *
@@ -4548,7 +4573,7 @@ transmit_hello_and_ping (void *cls,
4548 return; 4573 return;
4549 } 4574 }
4550 if (NULL == our_hello) 4575 if (NULL == our_hello)
4551 refresh_hello (); 4576 refresh_hello_task (NULL, NULL);
4552 hello_size = GNUNET_HELLO_size(our_hello); 4577 hello_size = GNUNET_HELLO_size(our_hello);
4553 slen = strlen(va->transport_name) + 1; 4578 slen = strlen(va->transport_name) + 1;
4554 tsize = sizeof(struct TransportPingMessage) + hello_size + va->addrlen + slen; 4579 tsize = sizeof(struct TransportPingMessage) + hello_size + va->addrlen + slen;
@@ -6302,6 +6327,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
6302 GNUNET_PEERINFO_disconnect (peerinfo); 6327 GNUNET_PEERINFO_disconnect (peerinfo);
6303 peerinfo = NULL; 6328 peerinfo = NULL;
6304 } 6329 }
6330 if (GNUNET_SCHEDULER_NO_TASK != hello_task)
6331 {
6332 GNUNET_SCHEDULER_cancel (hello_task);
6333 hello_task = GNUNET_SCHEDULER_NO_TASK;
6334 }
6305 /* Can we assume those are gone by now, or do we need to clean up 6335 /* Can we assume those are gone by now, or do we need to clean up
6306 explicitly!? */ 6336 explicitly!? */
6307 GNUNET_break (bl_head == NULL); 6337 GNUNET_break (bl_head == NULL);
@@ -7743,7 +7773,8 @@ run (void *cls,
7743 ats_init(); 7773 ats_init();
7744 7774
7745#if DEBUG_TRANSPORT 7775#if DEBUG_TRANSPORT
7746 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transport service ready.\n")); 7776 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
7777 _("Transport service ready.\n"));
7747#endif 7778#endif
7748 /* If we have a blacklist file, read from it */ 7779 /* If we have a blacklist file, read from it */
7749 read_blacklist_file(cfg); 7780 read_blacklist_file(cfg);