diff options
author | Bart Polot <bart@net.in.tum.de> | 2013-01-24 15:46:53 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2013-01-24 15:46:53 +0000 |
commit | 311a626e040a397213609434fc506d14880a454f (patch) | |
tree | 62a478bc42bd2ccbb8731390fd2896435635d567 /src/mesh | |
parent | 74c58d3c492508ab3204ac06577dcdb2af2a8d11 (diff) | |
download | gnunet-311a626e040a397213609434fc506d14880a454f.tar.gz gnunet-311a626e040a397213609434fc506d14880a454f.zip |
Moved regex profiler and profiler daemon from mesh to regex, adaped to regex dht lib
Diffstat (limited to 'src/mesh')
-rw-r--r-- | src/mesh/Makefile.am | 24 | ||||
-rw-r--r-- | src/mesh/gnunet-daemon-regexprofiler.c | 318 | ||||
-rw-r--r-- | src/mesh/gnunet-regex-profiler.c | 1903 | ||||
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 7 |
4 files changed, 0 insertions, 2252 deletions
diff --git a/src/mesh/Makefile.am b/src/mesh/Makefile.am index 5db9868ab..cc4531ad2 100644 --- a/src/mesh/Makefile.am +++ b/src/mesh/Makefile.am | |||
@@ -108,30 +108,6 @@ gnunet_service_mesh_new_LDFLAGS = -lrt | |||
108 | endif | 108 | endif |
109 | 109 | ||
110 | 110 | ||
111 | noinst_PROGRAMS = \ | ||
112 | gnunet-regex-profiler \ | ||
113 | gnunet-daemon-regexprofiler | ||
114 | |||
115 | gnunet_regex_profiler_SOURCES = \ | ||
116 | gnunet-regex-profiler.c | ||
117 | gnunet_regex_profiler_LDADD = \ | ||
118 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
119 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
120 | $(top_builddir)/src/mesh/libgnunetmesh.la \ | ||
121 | $(top_builddir)/src/regex/libgnunetregex.la \ | ||
122 | $(top_builddir)/src/statistics/libgnunetstatistics.la | ||
123 | gnunet_regex_profiler_DEPENDENCIES = \ | ||
124 | libgnunetmesh.la | ||
125 | |||
126 | gnunet_daemon_regexprofiler_SOURCES = \ | ||
127 | gnunet-daemon-regexprofiler.c | ||
128 | gnunet_daemon_regexprofiler_LDADD = \ | ||
129 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
130 | $(top_builddir)/src/mesh/libgnunetmesh.la \ | ||
131 | $(top_builddir)/src/statistics/libgnunetstatistics.la | ||
132 | gnunet_daemon_regexprofiler_DEPENDENCIES = \ | ||
133 | libgnunetmesh.la | ||
134 | |||
135 | noinst_LIBRARIES = libgnunetmeshtest.a | 111 | noinst_LIBRARIES = libgnunetmeshtest.a |
136 | 112 | ||
137 | libgnunetmeshtest_a_SOURCES = \ | 113 | libgnunetmeshtest_a_SOURCES = \ |
diff --git a/src/mesh/gnunet-daemon-regexprofiler.c b/src/mesh/gnunet-daemon-regexprofiler.c deleted file mode 100644 index 84e18b898..000000000 --- a/src/mesh/gnunet-daemon-regexprofiler.c +++ /dev/null | |||
@@ -1,318 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010, 2011, 2012 Christian Grothoff | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file mesh/gnunet-daemon-regexprofiler.c | ||
23 | * @brief daemon that uses mesh to announce a regular expression. Used in | ||
24 | * conjunction with gnunet-regex-profiler to announce regexes on serveral peers | ||
25 | * without the need to explicitly connect to the mesh service running on the | ||
26 | * peer from within the profiler. | ||
27 | * @author Maximilian Szengel | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include "gnunet_mesh_service.h" | ||
31 | #include "gnunet_statistics_service.h" | ||
32 | |||
33 | /** | ||
34 | * Return value from 'main'. | ||
35 | */ | ||
36 | static int global_ret; | ||
37 | |||
38 | /** | ||
39 | * Configuration we use. | ||
40 | */ | ||
41 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
42 | |||
43 | /** | ||
44 | * Handle to the statistics service. | ||
45 | */ | ||
46 | static struct GNUNET_STATISTICS_Handle *stats_handle; | ||
47 | |||
48 | /** | ||
49 | * Peer's mesh handle. | ||
50 | */ | ||
51 | struct GNUNET_MESH_Handle *mesh_handle; | ||
52 | |||
53 | /** | ||
54 | * Peer's mesh tunnel handle. | ||
55 | */ | ||
56 | struct GNUNET_MESH_Tunnel *mesh_tunnel_handle; | ||
57 | |||
58 | /** | ||
59 | * Maximal path compression length for regex announcing. | ||
60 | */ | ||
61 | static unsigned long long max_path_compression; | ||
62 | |||
63 | /** | ||
64 | * Name of the file containing policies that this peer should announce. One | ||
65 | * policy per line. | ||
66 | */ | ||
67 | static char * policy_filename; | ||
68 | |||
69 | /** | ||
70 | * Prefix to add before every regex we're announcing. | ||
71 | */ | ||
72 | static char * regex_prefix; | ||
73 | |||
74 | /** | ||
75 | * Task run during shutdown. | ||
76 | * | ||
77 | * @param cls unused | ||
78 | * @param tc unused | ||
79 | */ | ||
80 | static void | ||
81 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
82 | { | ||
83 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n"); | ||
84 | |||
85 | if (NULL != mesh_tunnel_handle) | ||
86 | { | ||
87 | GNUNET_MESH_tunnel_destroy (mesh_tunnel_handle); | ||
88 | mesh_tunnel_handle = NULL; | ||
89 | } | ||
90 | |||
91 | if (NULL != mesh_handle) | ||
92 | { | ||
93 | GNUNET_MESH_disconnect (mesh_handle); | ||
94 | mesh_handle = NULL; | ||
95 | } | ||
96 | |||
97 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n"); | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * Announce the given regular expression using Mesh and the path compression | ||
103 | * length read from config. | ||
104 | * | ||
105 | * @param regex regular expression to announce on this peer's mesh. | ||
106 | */ | ||
107 | static void | ||
108 | announce_regex (const char * regex) | ||
109 | { | ||
110 | if (NULL == regex || 0 == strlen (regex)) | ||
111 | { | ||
112 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot announce empty regex\n"); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Announcing regex: %s\n", regex); | ||
117 | GNUNET_STATISTICS_update (stats_handle, "# regexes announced", 1, GNUNET_NO); | ||
118 | GNUNET_MESH_announce_regex (mesh_handle, regex, (unsigned int)max_path_compression); | ||
119 | } | ||
120 | |||
121 | |||
122 | /** | ||
123 | * Load regular expressions from filename into 'rxes' array. Array needs to be freed. | ||
124 | * | ||
125 | * @param filename filename of the file containing the regexes, one per line. | ||
126 | * @param rx string with the union of all regular expressions. | ||
127 | * @return number of regular expressions read from filename and in rxes array. | ||
128 | */ | ||
129 | static unsigned int | ||
130 | load_regexes (const char *filename, char **rx) | ||
131 | { | ||
132 | char *data; | ||
133 | char *buf; | ||
134 | uint64_t filesize; | ||
135 | unsigned int offset; | ||
136 | unsigned int rx_cnt; | ||
137 | |||
138 | if (GNUNET_YES != GNUNET_DISK_file_test (policy_filename)) | ||
139 | { | ||
140 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
141 | "Could not find policy file %s\n", policy_filename); | ||
142 | return 0; | ||
143 | } | ||
144 | if (GNUNET_OK != GNUNET_DISK_file_size (policy_filename, &filesize, GNUNET_YES, GNUNET_YES)) | ||
145 | filesize = 0; | ||
146 | if (0 == filesize) | ||
147 | { | ||
148 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Policy file %s is empty.\n", policy_filename); | ||
149 | return 0; | ||
150 | } | ||
151 | data = GNUNET_malloc (filesize); | ||
152 | if (filesize != GNUNET_DISK_fn_read (policy_filename, data, filesize)) | ||
153 | { | ||
154 | GNUNET_free (data); | ||
155 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not read policy file %s.\n", | ||
156 | policy_filename); | ||
157 | return 0; | ||
158 | } | ||
159 | buf = data; | ||
160 | offset = 0; | ||
161 | rx_cnt = 0; | ||
162 | while (offset < (filesize - 1)) | ||
163 | { | ||
164 | offset++; | ||
165 | if ((data[offset] == '\n') && (buf != &data[offset])) | ||
166 | { | ||
167 | data[offset] = '|'; | ||
168 | buf = &data[offset + 1]; | ||
169 | rx_cnt++; | ||
170 | } | ||
171 | else if ((data[offset] == '\n') || (data[offset] == '\0')) | ||
172 | buf = &data[offset + 1]; | ||
173 | } | ||
174 | data[offset] = '\0'; | ||
175 | *rx = data; | ||
176 | |||
177 | return rx_cnt; | ||
178 | } | ||
179 | |||
180 | |||
181 | /** | ||
182 | * @brief Main function that will be run by the scheduler. | ||
183 | * | ||
184 | * @param cls closure | ||
185 | * @param args remaining command-line arguments | ||
186 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
187 | * @param cfg_ configuration | ||
188 | */ | ||
189 | static void | ||
190 | run (void *cls, char *const *args GNUNET_UNUSED, | ||
191 | const char *cfgfile GNUNET_UNUSED, | ||
192 | const struct GNUNET_CONFIGURATION_Handle *cfg_) | ||
193 | { | ||
194 | char *regex = NULL; | ||
195 | char *rx_with_pfx; | ||
196 | const GNUNET_MESH_ApplicationType app = (GNUNET_MESH_ApplicationType)0; | ||
197 | static struct GNUNET_MESH_MessageHandler handlers[] = { | ||
198 | {NULL, 0, 0} | ||
199 | }; | ||
200 | |||
201 | cfg = cfg_; | ||
202 | |||
203 | if (GNUNET_OK != | ||
204 | GNUNET_CONFIGURATION_get_value_number (cfg, "REGEXPROFILER", "MAX_PATH_COMPRESSION", | ||
205 | &max_path_compression)) | ||
206 | { | ||
207 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
208 | _ | ||
209 | ("%s service is lacking key configuration settings (%s). Exiting.\n"), | ||
210 | "regexprofiler", "max_path_compression"); | ||
211 | global_ret = GNUNET_SYSERR; | ||
212 | GNUNET_SCHEDULER_shutdown (); | ||
213 | return; | ||
214 | } | ||
215 | |||
216 | if (GNUNET_OK != | ||
217 | GNUNET_CONFIGURATION_get_value_filename (cfg, "REGEXPROFILER", "POLICY_FILE", | ||
218 | &policy_filename)) | ||
219 | { | ||
220 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
221 | _ | ||
222 | ("%s service is lacking key configuration settings (%s). Exiting.\n"), | ||
223 | "regexprofiler", "policy_file"); | ||
224 | global_ret = GNUNET_SYSERR; | ||
225 | GNUNET_SCHEDULER_shutdown (); | ||
226 | return; | ||
227 | } | ||
228 | |||
229 | if (GNUNET_OK != | ||
230 | GNUNET_CONFIGURATION_get_value_string (cfg, "REGEXPROFILER", "REGEX_PREFIX", | ||
231 | ®ex_prefix)) | ||
232 | { | ||
233 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
234 | _ | ||
235 | ("%s service is lacking key configuration settings (%s). Exiting.\n"), | ||
236 | "regexprofiler", "regex_prefix"); | ||
237 | global_ret = GNUNET_SYSERR; | ||
238 | GNUNET_SCHEDULER_shutdown (); | ||
239 | return; | ||
240 | } | ||
241 | |||
242 | stats_handle = GNUNET_STATISTICS_create ("regexprofiler", cfg); | ||
243 | |||
244 | mesh_handle = | ||
245 | GNUNET_MESH_connect (cfg, NULL, NULL, NULL, handlers, &app); | ||
246 | |||
247 | if (NULL == mesh_handle) | ||
248 | { | ||
249 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not acquire mesh handle. Exiting.\n"); | ||
250 | global_ret = GNUNET_SYSERR; | ||
251 | GNUNET_SCHEDULER_shutdown (); | ||
252 | return; | ||
253 | } | ||
254 | |||
255 | /* Read regexes from policy files */ | ||
256 | if (0 == load_regexes (policy_filename, ®ex)) | ||
257 | { | ||
258 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
259 | "Policy file %s contains no policies. Exiting.\n", | ||
260 | policy_filename); | ||
261 | global_ret = GNUNET_SYSERR; | ||
262 | GNUNET_SCHEDULER_shutdown (); | ||
263 | return; | ||
264 | } | ||
265 | |||
266 | /* Announcing regexes from policy_filename */ | ||
267 | GNUNET_asprintf (&rx_with_pfx, "%s(%s)", regex_prefix, regex); | ||
268 | announce_regex (rx_with_pfx); | ||
269 | GNUNET_free (rx_with_pfx); | ||
270 | GNUNET_free (regex); | ||
271 | |||
272 | /* Scheduled the task to clean up when shutdown is called */ | ||
273 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, | ||
274 | NULL); | ||
275 | } | ||
276 | |||
277 | |||
278 | /** | ||
279 | * The main function of the regexprofiler service. | ||
280 | * | ||
281 | * @param argc number of arguments from the command line | ||
282 | * @param argv command line arguments | ||
283 | * @return 0 ok, 1 on error | ||
284 | */ | ||
285 | int | ||
286 | main (int argc, char *const *argv) | ||
287 | { | ||
288 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
289 | GNUNET_GETOPT_OPTION_END | ||
290 | }; | ||
291 | |||
292 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
293 | return 2; | ||
294 | sleep (60); | ||
295 | return (GNUNET_OK == | ||
296 | GNUNET_PROGRAM_run (argc, argv, "regexprofiler", | ||
297 | gettext_noop | ||
298 | ("Daemon to announce regular expressions for the peer using mesh."), | ||
299 | options, &run, NULL)) ? global_ret : 1; | ||
300 | } | ||
301 | |||
302 | |||
303 | #ifdef LINUX | ||
304 | #include <malloc.h> | ||
305 | |||
306 | /** | ||
307 | * MINIMIZE heap size (way below 128k) since this process doesn't need much. | ||
308 | */ | ||
309 | void __attribute__ ((constructor)) GNUNET_ARM_memory_init () | ||
310 | { | ||
311 | mallopt (M_TRIM_THRESHOLD, 4 * 1024); | ||
312 | mallopt (M_TOP_PAD, 1 * 1024); | ||
313 | malloc_trim (0); | ||
314 | } | ||
315 | #endif | ||
316 | |||
317 | |||
318 | /* end of gnunet-daemon-regexprofiler.c */ | ||
diff --git a/src/mesh/gnunet-regex-profiler.c b/src/mesh/gnunet-regex-profiler.c deleted file mode 100644 index f431d6484..000000000 --- a/src/mesh/gnunet-regex-profiler.c +++ /dev/null | |||
@@ -1,1903 +0,0 @@ | |||
1 | /** | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2011, 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file mesh/gnunet-regex-profiler.c | ||
23 | * @brief Regex profiler for testing distributed regex use. | ||
24 | * @author Bart Polot | ||
25 | * @author Max Szengel | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include <string.h> | ||
30 | |||
31 | #include "platform.h" | ||
32 | #include "gnunet_applications.h" | ||
33 | #include "gnunet_util_lib.h" | ||
34 | #include "gnunet_mesh_service.h" | ||
35 | #include "gnunet_stream_lib.h" | ||
36 | #include "gnunet_testbed_service.h" | ||
37 | |||
38 | /** | ||
39 | * DLL of operations | ||
40 | */ | ||
41 | struct DLLOperation | ||
42 | { | ||
43 | /** | ||
44 | * The testbed operation handle | ||
45 | */ | ||
46 | struct GNUNET_TESTBED_Operation *op; | ||
47 | |||
48 | /** | ||
49 | * Closure | ||
50 | */ | ||
51 | void *cls; | ||
52 | |||
53 | /** | ||
54 | * The next pointer for DLL | ||
55 | */ | ||
56 | struct DLLOperation *next; | ||
57 | |||
58 | /** | ||
59 | * The prev pointer for DLL | ||
60 | */ | ||
61 | struct DLLOperation *prev; | ||
62 | }; | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Available states during profiling | ||
67 | */ | ||
68 | enum State | ||
69 | { | ||
70 | /** | ||
71 | * Initial state | ||
72 | */ | ||
73 | STATE_INIT = 0, | ||
74 | |||
75 | /** | ||
76 | * Starting slaves | ||
77 | */ | ||
78 | STATE_SLAVES_STARTING, | ||
79 | |||
80 | /** | ||
81 | * Creating peers | ||
82 | */ | ||
83 | STATE_PEERS_CREATING, | ||
84 | |||
85 | /** | ||
86 | * Starting peers | ||
87 | */ | ||
88 | STATE_PEERS_STARTING, | ||
89 | |||
90 | /** | ||
91 | * Linking peers | ||
92 | */ | ||
93 | STATE_PEERS_LINKING, | ||
94 | |||
95 | /** | ||
96 | * Matching strings against announced regexes | ||
97 | */ | ||
98 | STATE_SEARCH_REGEX, | ||
99 | |||
100 | /** | ||
101 | * Destroying peers; we can do this as the controller takes care of stopping a | ||
102 | * peer if it is running | ||
103 | */ | ||
104 | STATE_PEERS_DESTROYING | ||
105 | }; | ||
106 | |||
107 | |||
108 | /** | ||
109 | * Peer handles. | ||
110 | */ | ||
111 | struct RegexPeer | ||
112 | { | ||
113 | /** | ||
114 | * Peer id. | ||
115 | */ | ||
116 | unsigned int id; | ||
117 | |||
118 | /** | ||
119 | * Peer configuration handle. | ||
120 | */ | ||
121 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
122 | |||
123 | /** | ||
124 | * The actual testbed peer handle. | ||
125 | */ | ||
126 | struct GNUNET_TESTBED_Peer *peer_handle; | ||
127 | |||
128 | /** | ||
129 | * Host on which the peer is running. | ||
130 | */ | ||
131 | struct GNUNET_TESTBED_Host *host_handle; | ||
132 | |||
133 | /** | ||
134 | * Filename of the peer's policy file. | ||
135 | */ | ||
136 | char *policy_file; | ||
137 | |||
138 | /** | ||
139 | * Peers search string. | ||
140 | */ | ||
141 | const char *search_str; | ||
142 | |||
143 | /** | ||
144 | * Set to GNUNET_YES if the peer successfully matched the above | ||
145 | * search string. GNUNET_NO if the string could not be matched | ||
146 | * during the profiler run. GNUNET_SYSERR if the string matching | ||
147 | * timed out. Undefined if search_str is NULL | ||
148 | */ | ||
149 | int search_str_matched; | ||
150 | |||
151 | /** | ||
152 | * Peer's mesh handle. | ||
153 | */ | ||
154 | struct GNUNET_MESH_Handle *mesh_handle; | ||
155 | |||
156 | /** | ||
157 | * Peer's mesh tunnel handle. | ||
158 | */ | ||
159 | struct GNUNET_MESH_Tunnel *mesh_tunnel_handle; | ||
160 | |||
161 | /** | ||
162 | * Testbed operation handle for the mesh service. | ||
163 | */ | ||
164 | struct GNUNET_TESTBED_Operation *mesh_op_handle; | ||
165 | |||
166 | /** | ||
167 | * Peers's statistics handle. | ||
168 | */ | ||
169 | struct GNUNET_STATISTICS_Handle *stats_handle; | ||
170 | |||
171 | /** | ||
172 | * Testbed operation handle for the statistics service. | ||
173 | */ | ||
174 | struct GNUNET_TESTBED_Operation *stats_op_handle; | ||
175 | |||
176 | /** | ||
177 | * The starting time of a profiling step. | ||
178 | */ | ||
179 | struct GNUNET_TIME_Absolute prof_start_time; | ||
180 | }; | ||
181 | |||
182 | |||
183 | /** | ||
184 | * An array of hosts loaded from the hostkeys file | ||
185 | */ | ||
186 | static struct GNUNET_TESTBED_Host **hosts; | ||
187 | |||
188 | /** | ||
189 | * Array of peer handles used to pass to | ||
190 | * GNUNET_TESTBED_overlay_configure_topology | ||
191 | */ | ||
192 | static struct GNUNET_TESTBED_Peer **peer_handles; | ||
193 | |||
194 | /** | ||
195 | * The array of peers; we fill this as the peers are given to us by the testbed | ||
196 | */ | ||
197 | static struct RegexPeer *peers; | ||
198 | |||
199 | /** | ||
200 | * Host registration handle | ||
201 | */ | ||
202 | static struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle; | ||
203 | |||
204 | /** | ||
205 | * Handle to the master controller process | ||
206 | */ | ||
207 | static struct GNUNET_TESTBED_ControllerProc *mc_proc; | ||
208 | |||
209 | /** | ||
210 | * Handle to the master controller | ||
211 | */ | ||
212 | static struct GNUNET_TESTBED_Controller *mc; | ||
213 | |||
214 | /** | ||
215 | * Handle to global configuration | ||
216 | */ | ||
217 | static struct GNUNET_CONFIGURATION_Handle *cfg; | ||
218 | |||
219 | /** | ||
220 | * Head of the operations list | ||
221 | */ | ||
222 | static struct DLLOperation *dll_op_head; | ||
223 | |||
224 | /** | ||
225 | * Tail of the operations list | ||
226 | */ | ||
227 | static struct DLLOperation *dll_op_tail; | ||
228 | |||
229 | /** | ||
230 | * Peer linking - topology operation | ||
231 | */ | ||
232 | static struct GNUNET_TESTBED_Operation *topology_op; | ||
233 | |||
234 | /** | ||
235 | * The handle for whether a host is habitable or not | ||
236 | */ | ||
237 | struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handles; | ||
238 | |||
239 | /** | ||
240 | * Abort task identifier | ||
241 | */ | ||
242 | static GNUNET_SCHEDULER_TaskIdentifier abort_task; | ||
243 | |||
244 | /** | ||
245 | * Shutdown task identifier | ||
246 | */ | ||
247 | static GNUNET_SCHEDULER_TaskIdentifier shutdown_task; | ||
248 | |||
249 | /** | ||
250 | * Host registration task identifier | ||
251 | */ | ||
252 | static GNUNET_SCHEDULER_TaskIdentifier register_hosts_task; | ||
253 | |||
254 | /** | ||
255 | * Global event mask for all testbed events | ||
256 | */ | ||
257 | static uint64_t event_mask; | ||
258 | |||
259 | /** | ||
260 | * The starting time of a profiling step | ||
261 | */ | ||
262 | static struct GNUNET_TIME_Absolute prof_start_time; | ||
263 | |||
264 | /** | ||
265 | * Duration profiling step has taken | ||
266 | */ | ||
267 | static struct GNUNET_TIME_Relative prof_time; | ||
268 | |||
269 | /** | ||
270 | * Number of peers to be started by the profiler | ||
271 | */ | ||
272 | static unsigned int num_peers; | ||
273 | |||
274 | /** | ||
275 | * Number of hosts in the hosts array | ||
276 | */ | ||
277 | static unsigned int num_hosts; | ||
278 | |||
279 | /** | ||
280 | * Factor of number of links. num_links = num_peers * linking_factor. | ||
281 | */ | ||
282 | static unsigned int linking_factor; | ||
283 | |||
284 | /** | ||
285 | * Number of random links to be established between peers | ||
286 | */ | ||
287 | static unsigned int num_links; | ||
288 | |||
289 | /** | ||
290 | * Number of times we try overlay connect operations | ||
291 | */ | ||
292 | static unsigned int retry_links; | ||
293 | |||
294 | /** | ||
295 | * Continuous failures during overlay connect operations | ||
296 | */ | ||
297 | static unsigned int cont_fails; | ||
298 | |||
299 | /** | ||
300 | * Global testing status | ||
301 | */ | ||
302 | static int result; | ||
303 | |||
304 | /** | ||
305 | * current state of profiling | ||
306 | */ | ||
307 | enum State state; | ||
308 | |||
309 | /** | ||
310 | * Folder where policy files are stored. | ||
311 | */ | ||
312 | static char * policy_dir; | ||
313 | |||
314 | /** | ||
315 | * Search strings. | ||
316 | */ | ||
317 | static char **search_strings; | ||
318 | |||
319 | /** | ||
320 | * Number of search strings. | ||
321 | */ | ||
322 | static int num_search_strings; | ||
323 | |||
324 | /** | ||
325 | * Number of peers found with search strings. | ||
326 | */ | ||
327 | static unsigned int peers_found; | ||
328 | |||
329 | /** | ||
330 | * Search task identifier | ||
331 | */ | ||
332 | static GNUNET_SCHEDULER_TaskIdentifier search_task; | ||
333 | |||
334 | /** | ||
335 | * Search timeout task identifier. | ||
336 | */ | ||
337 | static GNUNET_SCHEDULER_TaskIdentifier search_timeout_task; | ||
338 | |||
339 | /** | ||
340 | * Search timeout in seconds. | ||
341 | */ | ||
342 | static struct GNUNET_TIME_Relative search_timeout = { 60000 }; | ||
343 | |||
344 | /** | ||
345 | * How long do we wait before starting the search? | ||
346 | * Default: 1 m. | ||
347 | */ | ||
348 | static struct GNUNET_TIME_Relative search_delay = { 60000 }; | ||
349 | |||
350 | /** | ||
351 | * File to log statistics to. | ||
352 | */ | ||
353 | static struct GNUNET_DISK_FileHandle *data_file; | ||
354 | |||
355 | /** | ||
356 | * Filename to log statistics to. | ||
357 | */ | ||
358 | static char *data_filename; | ||
359 | |||
360 | /** | ||
361 | * Maximal path compression length. | ||
362 | */ | ||
363 | static unsigned int max_path_compression; | ||
364 | |||
365 | /** | ||
366 | * If we should distribute the search evenly throught all peers (each | ||
367 | * peer searches for a string) or if only one peer should search for | ||
368 | * all strings. | ||
369 | */ | ||
370 | static int no_distributed_search; | ||
371 | |||
372 | /** | ||
373 | * Prefix used for regex announcing. We need to prefix the search | ||
374 | * strings with it, in order to find something. | ||
375 | */ | ||
376 | static char * regex_prefix; | ||
377 | |||
378 | |||
379 | /******************************************************************************/ | ||
380 | /****************************** DECLARATIONS ********************************/ | ||
381 | /******************************************************************************/ | ||
382 | |||
383 | |||
384 | /** | ||
385 | * Method called whenever a peer has connected to the tunnel. | ||
386 | * | ||
387 | * @param cls closure | ||
388 | * @param peer_id peer identity the tunnel was created to, NULL on timeout | ||
389 | * @param atsi performance data for the connection | ||
390 | * | ||
391 | */ | ||
392 | static void | ||
393 | mesh_peer_connect_handler (void *cls, | ||
394 | const struct GNUNET_PeerIdentity* peer_id, | ||
395 | const struct GNUNET_ATS_Information * atsi); | ||
396 | |||
397 | |||
398 | /** | ||
399 | * Method called whenever a peer has disconnected from the tunnel. | ||
400 | * Implementations of this callback must NOT call | ||
401 | * GNUNET_MESH_tunnel_destroy immediately, but instead schedule those | ||
402 | * to run in some other task later. However, calling | ||
403 | * "GNUNET_MESH_notify_transmit_ready_cancel" is allowed. | ||
404 | * | ||
405 | * @param cls closure | ||
406 | * @param peer_id peer identity the tunnel stopped working with | ||
407 | */ | ||
408 | static void | ||
409 | mesh_peer_disconnect_handler (void *cls, | ||
410 | const struct GNUNET_PeerIdentity * peer_id); | ||
411 | |||
412 | /** | ||
413 | * Mesh connect callback. | ||
414 | * | ||
415 | * @param cls internal peer id. | ||
416 | * @param op operation handle. | ||
417 | * @param ca_result connect adapter result. | ||
418 | * @param emsg error message. | ||
419 | */ | ||
420 | static void | ||
421 | mesh_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
422 | void *ca_result, const char *emsg); | ||
423 | |||
424 | /** | ||
425 | * Mesh connect adapter. | ||
426 | * | ||
427 | * @param cls not used. | ||
428 | * @param cfg configuration handle. | ||
429 | * | ||
430 | * @return | ||
431 | */ | ||
432 | static void * | ||
433 | mesh_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg); | ||
434 | |||
435 | |||
436 | /** | ||
437 | * Adapter function called to destroy a connection to | ||
438 | * the mesh service | ||
439 | * | ||
440 | * @param cls closure | ||
441 | * @param op_result service handle returned from the connect adapter | ||
442 | */ | ||
443 | static void | ||
444 | mesh_da (void *cls, void *op_result); | ||
445 | |||
446 | |||
447 | /** | ||
448 | * Function called by testbed once we are connected to stats | ||
449 | * service. Get the statistics for the services of interest. | ||
450 | * | ||
451 | * @param cls the 'struct RegexPeer' for which we connected to stats | ||
452 | * @param op connect operation handle | ||
453 | * @param ca_result handle to stats service | ||
454 | * @param emsg error message on failure | ||
455 | */ | ||
456 | static void | ||
457 | stats_connect_cb (void *cls, | ||
458 | struct GNUNET_TESTBED_Operation *op, | ||
459 | void *ca_result, | ||
460 | const char *emsg); | ||
461 | |||
462 | |||
463 | /** | ||
464 | * Task to collect all statistics from all peers, will shutdown the | ||
465 | * profiler, when done. | ||
466 | * | ||
467 | * @param cls NULL | ||
468 | * @param tc the task context | ||
469 | */ | ||
470 | static void | ||
471 | do_collect_stats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
472 | |||
473 | |||
474 | /******************************************************************************/ | ||
475 | /******************************** SHUTDOWN **********************************/ | ||
476 | /******************************************************************************/ | ||
477 | |||
478 | |||
479 | /** | ||
480 | * Shutdown nicely | ||
481 | * | ||
482 | * @param cls NULL | ||
483 | * @param tc the task context | ||
484 | */ | ||
485 | static void | ||
486 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
487 | { | ||
488 | struct DLLOperation *dll_op; | ||
489 | struct RegexPeer *peer; | ||
490 | unsigned int nhost; | ||
491 | unsigned int peer_cnt; | ||
492 | unsigned int search_str_cnt; | ||
493 | char output_buffer[512]; | ||
494 | size_t size; | ||
495 | |||
496 | shutdown_task = GNUNET_SCHEDULER_NO_TASK; | ||
497 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
498 | GNUNET_SCHEDULER_cancel (abort_task); | ||
499 | if (NULL != hc_handles) | ||
500 | { | ||
501 | for (nhost = 0; nhost < num_hosts; nhost++) | ||
502 | if (NULL != hc_handles[nhost]) | ||
503 | GNUNET_TESTBED_is_host_habitable_cancel (hc_handles[nhost]); | ||
504 | GNUNET_free (hc_handles); | ||
505 | hc_handles = NULL; | ||
506 | } | ||
507 | if (GNUNET_SCHEDULER_NO_TASK != register_hosts_task) | ||
508 | GNUNET_SCHEDULER_cancel (register_hosts_task); | ||
509 | |||
510 | for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++) | ||
511 | { | ||
512 | peer = &peers[peer_cnt]; | ||
513 | |||
514 | if (GNUNET_YES != peer->search_str_matched && NULL != data_file) | ||
515 | { | ||
516 | prof_time = GNUNET_TIME_absolute_get_duration (peer->prof_start_time); | ||
517 | size = | ||
518 | GNUNET_snprintf (output_buffer, | ||
519 | sizeof (output_buffer), | ||
520 | "%p Search string not found: %s (%d)\n%p On peer: %u (%p)\n%p With policy file: %s\n%p After: %s\n", | ||
521 | peer, | ||
522 | peer->search_str, | ||
523 | peer->search_str_matched, | ||
524 | peer, | ||
525 | peer->id, | ||
526 | peer, | ||
527 | peer, | ||
528 | peer->policy_file, | ||
529 | peer, | ||
530 | GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); | ||
531 | if (size != GNUNET_DISK_file_write (data_file, output_buffer, size)) | ||
532 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n"); | ||
533 | } | ||
534 | |||
535 | if (NULL != peers[peer_cnt].mesh_op_handle) | ||
536 | GNUNET_TESTBED_operation_done (peers[peer_cnt].mesh_op_handle); | ||
537 | if (NULL != peers[peer_cnt].stats_op_handle) | ||
538 | GNUNET_TESTBED_operation_done (peers[peer_cnt].stats_op_handle); | ||
539 | } | ||
540 | |||
541 | if (NULL != data_file) | ||
542 | GNUNET_DISK_file_close (data_file); | ||
543 | |||
544 | for (search_str_cnt = 0; | ||
545 | search_str_cnt < num_search_strings && NULL != search_strings; | ||
546 | search_str_cnt++) | ||
547 | { | ||
548 | GNUNET_free_non_null (search_strings[search_str_cnt]); | ||
549 | } | ||
550 | GNUNET_free_non_null (search_strings); | ||
551 | |||
552 | if (NULL != reg_handle) | ||
553 | GNUNET_TESTBED_cancel_registration (reg_handle); | ||
554 | if (NULL != topology_op) | ||
555 | GNUNET_TESTBED_operation_done (topology_op); | ||
556 | for (nhost = 0; nhost < num_hosts; nhost++) | ||
557 | if (NULL != hosts[nhost]) | ||
558 | GNUNET_TESTBED_host_destroy (hosts[nhost]); | ||
559 | GNUNET_free_non_null (hosts); | ||
560 | |||
561 | while (NULL != (dll_op = dll_op_head)) | ||
562 | { | ||
563 | GNUNET_TESTBED_operation_done (dll_op->op); | ||
564 | GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); | ||
565 | GNUNET_free (dll_op); | ||
566 | } | ||
567 | if (NULL != mc) | ||
568 | GNUNET_TESTBED_controller_disconnect (mc); | ||
569 | if (NULL != mc_proc) | ||
570 | GNUNET_TESTBED_controller_stop (mc_proc); | ||
571 | if (NULL != cfg) | ||
572 | GNUNET_CONFIGURATION_destroy (cfg); | ||
573 | |||
574 | GNUNET_SCHEDULER_shutdown (); /* Stop scheduler to shutdown testbed run */ | ||
575 | } | ||
576 | |||
577 | |||
578 | /** | ||
579 | * abort task to run on test timed out | ||
580 | * | ||
581 | * @param cls NULL | ||
582 | * @param tc the task context | ||
583 | */ | ||
584 | static void | ||
585 | do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
586 | { | ||
587 | unsigned long i = (unsigned long) cls; | ||
588 | |||
589 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Aborting %lu...\n", i); | ||
590 | abort_task = GNUNET_SCHEDULER_NO_TASK; | ||
591 | result = GNUNET_SYSERR; | ||
592 | if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) | ||
593 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
594 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
595 | } | ||
596 | |||
597 | |||
598 | /******************************************************************************/ | ||
599 | /********************* STATISTICS SERVICE CONNECTIONS ***********************/ | ||
600 | /******************************************************************************/ | ||
601 | |||
602 | /** | ||
603 | * Adapter function called to establish a connection to | ||
604 | * statistics service. | ||
605 | * | ||
606 | * @param cls closure | ||
607 | * @param cfg configuration of the peer to connect to; will be available until | ||
608 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
609 | * from GNUNET_TESTBED_service_connect() | ||
610 | * @return service handle to return in 'op_result', NULL on error | ||
611 | */ | ||
612 | static void * | ||
613 | stats_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
614 | { | ||
615 | return GNUNET_STATISTICS_create ("<driver>", cfg); | ||
616 | } | ||
617 | |||
618 | |||
619 | /** | ||
620 | * Adapter function called to destroy a connection to | ||
621 | * statistics service. | ||
622 | * | ||
623 | * @param cls closure | ||
624 | * @param op_result service handle returned from the connect adapter | ||
625 | */ | ||
626 | static void | ||
627 | stats_da (void *cls, void *op_result) | ||
628 | { | ||
629 | struct RegexPeer *peer = cls; | ||
630 | |||
631 | GNUNET_assert (op_result == peer->stats_handle); | ||
632 | |||
633 | GNUNET_STATISTICS_destroy (peer->stats_handle, GNUNET_NO); | ||
634 | peer->stats_handle = NULL; | ||
635 | } | ||
636 | |||
637 | |||
638 | /** | ||
639 | * Process statistic values. Write all values to global 'data_file', if present. | ||
640 | * | ||
641 | * @param cls closure | ||
642 | * @param subsystem name of subsystem that created the statistic | ||
643 | * @param name the name of the datum | ||
644 | * @param value the current value | ||
645 | * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not | ||
646 | * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration | ||
647 | */ | ||
648 | static int | ||
649 | stats_iterator (void *cls, const char *subsystem, const char *name, | ||
650 | uint64_t value, int is_persistent) | ||
651 | { | ||
652 | struct RegexPeer *peer = cls; | ||
653 | char output_buffer[512]; | ||
654 | size_t size; | ||
655 | |||
656 | if (NULL == data_file) | ||
657 | { | ||
658 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
659 | "%p -> %s [%s]: %llu\n", | ||
660 | peer, subsystem, name, value); | ||
661 | return GNUNET_OK; | ||
662 | } | ||
663 | size = | ||
664 | GNUNET_snprintf (output_buffer, | ||
665 | sizeof (output_buffer), | ||
666 | "%p [%s] %llu %s\n", | ||
667 | peer, | ||
668 | subsystem, value, name); | ||
669 | if (size != GNUNET_DISK_file_write (data_file, output_buffer, size)) | ||
670 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n"); | ||
671 | |||
672 | return GNUNET_OK; | ||
673 | } | ||
674 | |||
675 | |||
676 | /** | ||
677 | * Stats callback. Finish the stats testbed operation and when all stats have | ||
678 | * been iterated, shutdown the profiler. | ||
679 | * | ||
680 | * @param cls closure | ||
681 | * @param success GNUNET_OK if statistics were | ||
682 | * successfully obtained, GNUNET_SYSERR if not. | ||
683 | */ | ||
684 | static void | ||
685 | stats_cb (void *cls, | ||
686 | int success) | ||
687 | { | ||
688 | static unsigned int peer_cnt; | ||
689 | struct RegexPeer *peer = cls; | ||
690 | |||
691 | if (GNUNET_OK != success) | ||
692 | { | ||
693 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
694 | "Getting statistics for peer %u failed!\n", | ||
695 | peer->id); | ||
696 | return; | ||
697 | } | ||
698 | |||
699 | GNUNET_assert (NULL != peer->stats_op_handle); | ||
700 | |||
701 | GNUNET_TESTBED_operation_done (peer->stats_op_handle); | ||
702 | peer->stats_op_handle = NULL; | ||
703 | |||
704 | peer_cnt++; | ||
705 | peer = &peers[peer_cnt]; | ||
706 | |||
707 | if (peer_cnt == num_peers) | ||
708 | { | ||
709 | struct GNUNET_TIME_Relative delay = { 100 }; | ||
710 | shutdown_task = GNUNET_SCHEDULER_add_delayed (delay, &do_shutdown, NULL); | ||
711 | } | ||
712 | else | ||
713 | { | ||
714 | peer->stats_op_handle = | ||
715 | GNUNET_TESTBED_service_connect (NULL, | ||
716 | peer->peer_handle, | ||
717 | "statistics", | ||
718 | &stats_connect_cb, | ||
719 | peer, | ||
720 | &stats_ca, | ||
721 | &stats_da, | ||
722 | peer); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | |||
727 | /** | ||
728 | * Function called by testbed once we are connected to stats | ||
729 | * service. Get the statistics for the services of interest. | ||
730 | * | ||
731 | * @param cls the 'struct RegexPeer' for which we connected to stats | ||
732 | * @param op connect operation handle | ||
733 | * @param ca_result handle to stats service | ||
734 | * @param emsg error message on failure | ||
735 | */ | ||
736 | static void | ||
737 | stats_connect_cb (void *cls, | ||
738 | struct GNUNET_TESTBED_Operation *op, | ||
739 | void *ca_result, | ||
740 | const char *emsg) | ||
741 | { | ||
742 | struct RegexPeer *peer = cls; | ||
743 | |||
744 | if (NULL == ca_result || NULL != emsg) | ||
745 | { | ||
746 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
747 | "Failed to connect to statistics service on peer %u: %s\n", | ||
748 | peer->id, emsg); | ||
749 | |||
750 | peer->stats_handle = NULL; | ||
751 | return; | ||
752 | } | ||
753 | |||
754 | peer->stats_handle = ca_result; | ||
755 | |||
756 | if (NULL == GNUNET_STATISTICS_get (peer->stats_handle, NULL, NULL, | ||
757 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
758 | &stats_cb, | ||
759 | &stats_iterator, peer)) | ||
760 | { | ||
761 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
762 | "Could not get statistics of peer %u!\n", peer->id); | ||
763 | } | ||
764 | } | ||
765 | |||
766 | |||
767 | /** | ||
768 | * Task to collect all statistics from all peers, will shutdown the | ||
769 | * profiler, when done. | ||
770 | * | ||
771 | * @param cls NULL | ||
772 | * @param tc the task context | ||
773 | */ | ||
774 | static void | ||
775 | do_collect_stats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
776 | { | ||
777 | struct RegexPeer *peer = &peers[0]; | ||
778 | |||
779 | GNUNET_assert (NULL != peer->peer_handle); | ||
780 | |||
781 | peer->stats_op_handle = | ||
782 | GNUNET_TESTBED_service_connect (NULL, | ||
783 | peer->peer_handle, | ||
784 | "statistics", | ||
785 | &stats_connect_cb, | ||
786 | peer, | ||
787 | &stats_ca, | ||
788 | &stats_da, | ||
789 | peer); | ||
790 | } | ||
791 | |||
792 | |||
793 | /******************************************************************************/ | ||
794 | /************************ MESH SERVICE CONNECTIONS **************************/ | ||
795 | /******************************************************************************/ | ||
796 | |||
797 | /** | ||
798 | * Method called whenever a peer has disconnected from the tunnel. | ||
799 | * Implementations of this callback must NOT call | ||
800 | * GNUNET_MESH_tunnel_destroy immediately, but instead schedule those | ||
801 | * to run in some other task later. However, calling | ||
802 | * "GNUNET_MESH_notify_transmit_ready_cancel" is allowed. | ||
803 | * | ||
804 | * @param cls closure | ||
805 | * @param peer_id peer identity the tunnel stopped working with | ||
806 | */ | ||
807 | static void | ||
808 | mesh_peer_disconnect_handler (void *cls, | ||
809 | const struct GNUNET_PeerIdentity * peer_id) | ||
810 | { | ||
811 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh peer disconnect handler.\n"); | ||
812 | } | ||
813 | |||
814 | |||
815 | /** | ||
816 | * Method called when the mesh connection succeeded (or timed out), which means | ||
817 | * we've found a peer that announced a regex that matches our search string. Now | ||
818 | * get the statistics. | ||
819 | * | ||
820 | * @param cls closure | ||
821 | * @param peer_id peer identity the tunnel was created to, NULL on timeout | ||
822 | * @param atsi performance data for the connection | ||
823 | * | ||
824 | */ | ||
825 | static void | ||
826 | mesh_peer_connect_handler (void *cls, | ||
827 | const struct GNUNET_PeerIdentity* peer_id, | ||
828 | const struct GNUNET_ATS_Information * atsi) | ||
829 | { | ||
830 | struct RegexPeer *peer = cls; | ||
831 | char output_buffer[512]; | ||
832 | size_t size; | ||
833 | |||
834 | if (GNUNET_YES == peer->search_str_matched) | ||
835 | { | ||
836 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
837 | "String %s on peer %u already matched!\n", | ||
838 | peer->search_str, peer->id); | ||
839 | return; | ||
840 | } | ||
841 | |||
842 | peers_found++; | ||
843 | |||
844 | if (NULL == peer_id) | ||
845 | { | ||
846 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
847 | "String matching timed out for string %s on peer %u (%i/%i)\n", | ||
848 | peer->search_str, peer->id, peers_found, num_search_strings); | ||
849 | |||
850 | printf ("String matching timed out for string %s on peer %u (%i/%i)\n", | ||
851 | peer->search_str, peer->id, peers_found, num_search_strings); | ||
852 | |||
853 | peer->search_str_matched = GNUNET_SYSERR; | ||
854 | } | ||
855 | else | ||
856 | { | ||
857 | prof_time = GNUNET_TIME_absolute_get_duration (peer->prof_start_time); | ||
858 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
859 | "String %s successfully matched on peer %u after %s (%i/%i)\n", | ||
860 | peer->search_str, peer->id, GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO), | ||
861 | peers_found, num_search_strings); | ||
862 | |||
863 | printf ("String %s successfully matched on peer %u after %s (%i/%i)\n", | ||
864 | peer->search_str, peer->id, GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO), | ||
865 | peers_found, num_search_strings); | ||
866 | fflush (stdout); | ||
867 | |||
868 | peer->search_str_matched = GNUNET_YES; | ||
869 | |||
870 | if (NULL != data_file) | ||
871 | { | ||
872 | size = | ||
873 | GNUNET_snprintf (output_buffer, | ||
874 | sizeof (output_buffer), | ||
875 | "%p Peer: %u\n%p Host: %s\n%p Policy file: %s\n%p Search string: %s\n%p Search duration: %s\n\n", | ||
876 | peer, | ||
877 | peer->id, | ||
878 | peer, | ||
879 | GNUNET_TESTBED_host_get_hostname (peer->host_handle), | ||
880 | peer, | ||
881 | peer->policy_file, | ||
882 | peer, | ||
883 | peer->search_str, | ||
884 | peer, | ||
885 | GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); | ||
886 | |||
887 | if (size != GNUNET_DISK_file_write (data_file, output_buffer, size)) | ||
888 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n"); | ||
889 | } | ||
890 | } | ||
891 | |||
892 | GNUNET_TESTBED_operation_done (peer->mesh_op_handle); | ||
893 | peer->mesh_op_handle = NULL; | ||
894 | |||
895 | if (peers_found == num_search_strings) | ||
896 | { | ||
897 | prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); | ||
898 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
899 | "All strings successfully matched in %s\n", | ||
900 | GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); | ||
901 | printf ("All strings successfully matched.\n"); | ||
902 | fflush (stdout); | ||
903 | |||
904 | if (GNUNET_SCHEDULER_NO_TASK != search_timeout_task) | ||
905 | GNUNET_SCHEDULER_cancel (search_timeout_task); | ||
906 | |||
907 | printf ("Collecting stats and shutting down.\n"); | ||
908 | GNUNET_SCHEDULER_add_now (&do_collect_stats, NULL); | ||
909 | } | ||
910 | } | ||
911 | |||
912 | |||
913 | /** | ||
914 | * Connect by string timeout task. This will cancel the profiler after the | ||
915 | * specified timeout 'search_timeout'. | ||
916 | * | ||
917 | * @param cls NULL | ||
918 | * @param tc the task context | ||
919 | */ | ||
920 | static void | ||
921 | do_connect_by_string_timeout (void *cls, | ||
922 | const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
923 | { | ||
924 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
925 | "Finding matches to all strings did not succeed after %s.\n", | ||
926 | GNUNET_STRINGS_relative_time_to_string (search_timeout, GNUNET_NO)); | ||
927 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
928 | "Found %i of %i strings\n", peers_found, num_search_strings); | ||
929 | |||
930 | printf ("Search timed out after %s. Collecting stats and shutting down.\n", | ||
931 | GNUNET_STRINGS_relative_time_to_string (search_timeout, GNUNET_NO)); | ||
932 | fflush (stdout); | ||
933 | |||
934 | GNUNET_SCHEDULER_add_now (&do_collect_stats, NULL); | ||
935 | } | ||
936 | |||
937 | |||
938 | /** | ||
939 | * Connect by string task that is run to search for a string in the | ||
940 | * NFA. It first connects to the mesh service and when a connection is | ||
941 | * established it starts to search for the string. | ||
942 | * | ||
943 | * @param cls NULL | ||
944 | * @param tc the task context | ||
945 | */ | ||
946 | static void | ||
947 | do_connect_by_string (void *cls, | ||
948 | const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
949 | { | ||
950 | printf ("Starting string search.\n"); | ||
951 | fflush (stdout); | ||
952 | |||
953 | peers[0].search_str = search_strings[0]; | ||
954 | peers[0].search_str_matched = GNUNET_NO; | ||
955 | |||
956 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
957 | "Searching for string \"%s\" on peer %d with file %s\n", | ||
958 | peers[0].search_str, 0, peers[0].policy_file); | ||
959 | |||
960 | /* First connect to mesh service, then search for string. Next | ||
961 | connect will be in mesh_connect_cb */ | ||
962 | peers[0].mesh_op_handle = | ||
963 | GNUNET_TESTBED_service_connect (NULL, | ||
964 | peers[0].peer_handle, | ||
965 | "mesh", | ||
966 | &mesh_connect_cb, | ||
967 | &peers[0], | ||
968 | &mesh_ca, | ||
969 | &mesh_da, | ||
970 | &peers[0]); | ||
971 | |||
972 | search_timeout_task = GNUNET_SCHEDULER_add_delayed (search_timeout, | ||
973 | &do_connect_by_string_timeout, NULL); | ||
974 | } | ||
975 | |||
976 | |||
977 | /** | ||
978 | * Mesh connect callback. Called when we are connected to the mesh service for | ||
979 | * the peer in 'cls'. If successfull we connect to the stats service of this | ||
980 | * peer and then try to match the search string of this peer. | ||
981 | * | ||
982 | * @param cls internal peer id. | ||
983 | * @param op operation handle. | ||
984 | * @param ca_result connect adapter result. | ||
985 | * @param emsg error message. | ||
986 | */ | ||
987 | static void | ||
988 | mesh_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, | ||
989 | void *ca_result, const char *emsg) | ||
990 | { | ||
991 | struct RegexPeer *peer = (struct RegexPeer *) cls; | ||
992 | static unsigned int peer_cnt; | ||
993 | unsigned int next_p; | ||
994 | |||
995 | if (NULL != emsg || NULL == op || NULL == ca_result) | ||
996 | { | ||
997 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Mesh connect failed: %s\n", emsg); | ||
998 | GNUNET_assert (0); | ||
999 | } | ||
1000 | |||
1001 | GNUNET_assert (NULL != peer->mesh_handle); | ||
1002 | GNUNET_assert (peer->mesh_op_handle == op); | ||
1003 | GNUNET_assert (peer->mesh_handle == ca_result); | ||
1004 | |||
1005 | peer->mesh_tunnel_handle = | ||
1006 | GNUNET_MESH_tunnel_create (peer->mesh_handle, | ||
1007 | NULL, | ||
1008 | &mesh_peer_connect_handler, | ||
1009 | &mesh_peer_disconnect_handler, | ||
1010 | peer); | ||
1011 | |||
1012 | peer->prof_start_time = GNUNET_TIME_absolute_get (); | ||
1013 | |||
1014 | peer->search_str_matched = GNUNET_NO; | ||
1015 | GNUNET_MESH_peer_request_connect_by_string (peer->mesh_tunnel_handle, | ||
1016 | peer->search_str); | ||
1017 | |||
1018 | if (peer_cnt < (num_search_strings - 1)) | ||
1019 | { | ||
1020 | if (GNUNET_YES == no_distributed_search) | ||
1021 | next_p = 0; | ||
1022 | else | ||
1023 | next_p = (++peer_cnt % num_peers); | ||
1024 | |||
1025 | peers[next_p].search_str = search_strings[next_p]; | ||
1026 | peers[next_p].search_str_matched = GNUNET_NO; | ||
1027 | |||
1028 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1029 | "Searching for string \"%s\" on peer %d with file %s\n", | ||
1030 | peers[next_p].search_str, next_p, peers[next_p].policy_file); | ||
1031 | |||
1032 | peers[next_p].mesh_op_handle = | ||
1033 | GNUNET_TESTBED_service_connect (NULL, | ||
1034 | peers[next_p].peer_handle, | ||
1035 | "mesh", | ||
1036 | &mesh_connect_cb, | ||
1037 | &peers[next_p], | ||
1038 | &mesh_ca, | ||
1039 | &mesh_da, | ||
1040 | &peers[next_p]); | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | |||
1045 | /** | ||
1046 | * Mesh connect adapter. Opens a connection to the mesh service. | ||
1047 | * | ||
1048 | * @param cls not used. | ||
1049 | * @param cfg configuration handle. | ||
1050 | * | ||
1051 | * @return | ||
1052 | */ | ||
1053 | static void * | ||
1054 | mesh_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
1055 | { | ||
1056 | GNUNET_MESH_ApplicationType app; | ||
1057 | struct RegexPeer *peer = cls; | ||
1058 | |||
1059 | static struct GNUNET_MESH_MessageHandler handlers[] = { | ||
1060 | {NULL, 0, 0} | ||
1061 | }; | ||
1062 | |||
1063 | app = (GNUNET_MESH_ApplicationType)0; | ||
1064 | |||
1065 | peer->mesh_handle = | ||
1066 | GNUNET_MESH_connect (cfg, peer, NULL, NULL, handlers, &app); | ||
1067 | |||
1068 | return peer->mesh_handle; | ||
1069 | } | ||
1070 | |||
1071 | |||
1072 | /** | ||
1073 | * Adapter function called to destroy a connection to | ||
1074 | * the mesh service | ||
1075 | * | ||
1076 | * @param cls closure | ||
1077 | * @param op_result service handle returned from the connect adapter | ||
1078 | */ | ||
1079 | static void | ||
1080 | mesh_da (void *cls, void *op_result) | ||
1081 | { | ||
1082 | struct RegexPeer *peer = (struct RegexPeer *) cls; | ||
1083 | |||
1084 | GNUNET_assert (peer->mesh_handle == op_result); | ||
1085 | |||
1086 | if (NULL != peer->mesh_tunnel_handle) | ||
1087 | { | ||
1088 | GNUNET_MESH_tunnel_destroy (peer->mesh_tunnel_handle); | ||
1089 | peer->mesh_tunnel_handle = NULL; | ||
1090 | } | ||
1091 | |||
1092 | if (NULL != peer->mesh_handle) | ||
1093 | { | ||
1094 | GNUNET_MESH_disconnect (peer->mesh_handle); | ||
1095 | peer->mesh_handle = NULL; | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | |||
1100 | /******************************************************************************/ | ||
1101 | /*************************** TESTBED PEER SETUP *****************************/ | ||
1102 | /******************************************************************************/ | ||
1103 | |||
1104 | |||
1105 | /** | ||
1106 | * Configure the peer overlay topology. | ||
1107 | * | ||
1108 | * @param cls NULL | ||
1109 | * @param tc the task context | ||
1110 | */ | ||
1111 | static void | ||
1112 | do_configure_topology (void *cls, | ||
1113 | const struct GNUNET_SCHEDULER_TaskContext * tc) | ||
1114 | { | ||
1115 | /* | ||
1116 | if (0 == linking_factor) | ||
1117 | linking_factor = 1; | ||
1118 | num_links = linking_factor * num_peers; | ||
1119 | */ | ||
1120 | /* num_links = num_peers - 1; */ | ||
1121 | num_links = linking_factor; | ||
1122 | |||
1123 | /* Do overlay connect */ | ||
1124 | prof_start_time = GNUNET_TIME_absolute_get (); | ||
1125 | topology_op = | ||
1126 | GNUNET_TESTBED_overlay_configure_topology (NULL, num_peers, peer_handles, | ||
1127 | NULL, | ||
1128 | GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, | ||
1129 | num_links, | ||
1130 | GNUNET_TESTBED_TOPOLOGY_DISABLE_AUTO_RETRY, | ||
1131 | GNUNET_TESTBED_TOPOLOGY_OPTION_END); | ||
1132 | if (NULL == topology_op) | ||
1133 | { | ||
1134 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1135 | "Cannot create topology, op handle was NULL\n"); | ||
1136 | GNUNET_assert (0); | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | |||
1141 | /** | ||
1142 | * Functions of this signature are called when a peer has been successfully | ||
1143 | * started or stopped. | ||
1144 | * | ||
1145 | * @param cls the closure from GNUNET_TESTBED_peer_start/stop() | ||
1146 | * @param emsg NULL on success; otherwise an error description | ||
1147 | */ | ||
1148 | static void | ||
1149 | peer_churn_cb (void *cls, const char *emsg) | ||
1150 | { | ||
1151 | struct DLLOperation *dll_op = cls; | ||
1152 | struct GNUNET_TESTBED_Operation *op; | ||
1153 | static unsigned int started_peers; | ||
1154 | unsigned int peer_cnt; | ||
1155 | |||
1156 | op = dll_op->op; | ||
1157 | GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); | ||
1158 | GNUNET_free (dll_op); | ||
1159 | if (NULL != emsg) | ||
1160 | { | ||
1161 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1162 | _("An operation has failed while starting peers\n")); | ||
1163 | GNUNET_TESTBED_operation_done (op); | ||
1164 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
1165 | GNUNET_SCHEDULER_cancel (abort_task); | ||
1166 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); | ||
1167 | return; | ||
1168 | } | ||
1169 | GNUNET_TESTBED_operation_done (op); | ||
1170 | if (++started_peers == num_peers) | ||
1171 | { | ||
1172 | prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); | ||
1173 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1174 | "All peers started successfully in %s\n", | ||
1175 | GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); | ||
1176 | result = GNUNET_OK; | ||
1177 | |||
1178 | peer_handles = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Peer *) * num_peers); | ||
1179 | for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++) | ||
1180 | peer_handles[peer_cnt] = peers[peer_cnt].peer_handle; | ||
1181 | |||
1182 | state = STATE_PEERS_LINKING; | ||
1183 | GNUNET_SCHEDULER_add_now (&do_configure_topology, NULL); | ||
1184 | } | ||
1185 | } | ||
1186 | |||
1187 | |||
1188 | /** | ||
1189 | * Functions of this signature are called when a peer has been successfully | ||
1190 | * created | ||
1191 | * | ||
1192 | * @param cls the closure from GNUNET_TESTBED_peer_create() | ||
1193 | * @param peer the handle for the created peer; NULL on any error during | ||
1194 | * creation | ||
1195 | * @param emsg NULL if peer is not NULL; else MAY contain the error description | ||
1196 | */ | ||
1197 | static void | ||
1198 | peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg) | ||
1199 | { | ||
1200 | struct DLLOperation *dll_op = cls; | ||
1201 | struct RegexPeer *peer_ptr; | ||
1202 | static unsigned int created_peers; | ||
1203 | unsigned int peer_cnt; | ||
1204 | |||
1205 | if (NULL != emsg) | ||
1206 | { | ||
1207 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1208 | _("Creating a peer failed. Error: %s\n"), emsg); | ||
1209 | GNUNET_TESTBED_operation_done (dll_op->op); | ||
1210 | GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); | ||
1211 | GNUNET_free (dll_op); | ||
1212 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
1213 | GNUNET_SCHEDULER_cancel (abort_task); | ||
1214 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); | ||
1215 | return; | ||
1216 | } | ||
1217 | |||
1218 | peer_ptr = dll_op->cls; | ||
1219 | GNUNET_assert (NULL == peer_ptr->peer_handle); | ||
1220 | GNUNET_CONFIGURATION_destroy (peer_ptr->cfg); | ||
1221 | peer_ptr->cfg = NULL; | ||
1222 | peer_ptr->peer_handle = peer; | ||
1223 | GNUNET_TESTBED_operation_done (dll_op->op); | ||
1224 | GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); | ||
1225 | GNUNET_free (dll_op); | ||
1226 | |||
1227 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %i created on host %s\n", | ||
1228 | peer_ptr->id, | ||
1229 | GNUNET_TESTBED_host_get_hostname (peer_ptr->host_handle)); | ||
1230 | |||
1231 | if (++created_peers == num_peers) | ||
1232 | { | ||
1233 | prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); | ||
1234 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1235 | "All peers created successfully in %s\n", | ||
1236 | GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); | ||
1237 | /* Now peers are to be started */ | ||
1238 | state = STATE_PEERS_STARTING; | ||
1239 | prof_start_time = GNUNET_TIME_absolute_get (); | ||
1240 | for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++) | ||
1241 | { | ||
1242 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
1243 | dll_op->op = GNUNET_TESTBED_peer_start (dll_op, peers[peer_cnt].peer_handle, | ||
1244 | &peer_churn_cb, dll_op); | ||
1245 | GNUNET_CONTAINER_DLL_insert_tail (dll_op_head, dll_op_tail, dll_op); | ||
1246 | } | ||
1247 | } | ||
1248 | } | ||
1249 | |||
1250 | |||
1251 | /** | ||
1252 | * Function called with a filename for each file in the policy directory. Create | ||
1253 | * a peer for each filename and update the peer's configuration to include the | ||
1254 | * max_path_compression specified as a command line argument as well as the | ||
1255 | * policy_file for this peer. The gnunet-service-regexprofiler service is | ||
1256 | * automatically started on this peer. The service reads the configurration and | ||
1257 | * announces the regexes stored in the policy file 'filename'. | ||
1258 | * | ||
1259 | * @param cls closure | ||
1260 | * @param filename complete filename (absolute path) | ||
1261 | * @return GNUNET_OK to continue to iterate, | ||
1262 | * GNUNET_SYSERR to abort iteration with error! | ||
1263 | */ | ||
1264 | static int | ||
1265 | policy_filename_cb (void *cls, const char *filename) | ||
1266 | { | ||
1267 | static unsigned int peer_cnt; | ||
1268 | struct DLLOperation *dll_op; | ||
1269 | struct RegexPeer *peer = &peers[peer_cnt]; | ||
1270 | |||
1271 | GNUNET_assert (NULL != peer); | ||
1272 | |||
1273 | peer->policy_file = GNUNET_strdup (filename); | ||
1274 | |||
1275 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Creating peer %i on host %s for policy file %s\n", | ||
1276 | peer->id, | ||
1277 | GNUNET_TESTBED_host_get_hostname (peer->host_handle), | ||
1278 | filename); | ||
1279 | |||
1280 | /* Set configuration options specific for this peer | ||
1281 | (max_path_compression and policy_file */ | ||
1282 | peer->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
1283 | GNUNET_CONFIGURATION_set_value_number (peer->cfg, "REGEXPROFILER", | ||
1284 | "MAX_PATH_COMPRESSION", | ||
1285 | (unsigned long long)max_path_compression); | ||
1286 | GNUNET_CONFIGURATION_set_value_string (peer->cfg, "REGEXPROFILER", | ||
1287 | "POLICY_FILE", filename); | ||
1288 | |||
1289 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
1290 | dll_op->cls = &peers[peer_cnt]; | ||
1291 | dll_op->op = GNUNET_TESTBED_peer_create (mc, | ||
1292 | peer->host_handle, | ||
1293 | peer->cfg, | ||
1294 | &peer_create_cb, | ||
1295 | dll_op); | ||
1296 | GNUNET_CONTAINER_DLL_insert_tail (dll_op_head, dll_op_tail, dll_op); | ||
1297 | |||
1298 | peer_cnt++; | ||
1299 | |||
1300 | return GNUNET_OK; | ||
1301 | } | ||
1302 | |||
1303 | |||
1304 | /** | ||
1305 | * Controller event callback. | ||
1306 | * | ||
1307 | * @param cls NULL | ||
1308 | * @param event the controller event | ||
1309 | */ | ||
1310 | static void | ||
1311 | controller_event_cb (void *cls, | ||
1312 | const struct GNUNET_TESTBED_EventInformation *event) | ||
1313 | { | ||
1314 | struct DLLOperation *dll_op; | ||
1315 | struct GNUNET_TESTBED_Operation *op; | ||
1316 | int ret; | ||
1317 | |||
1318 | switch (state) | ||
1319 | { | ||
1320 | case STATE_SLAVES_STARTING: | ||
1321 | switch (event->type) | ||
1322 | { | ||
1323 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
1324 | { | ||
1325 | static unsigned int slaves_started; | ||
1326 | unsigned int peer_cnt; | ||
1327 | |||
1328 | dll_op = event->details.operation_finished.op_cls; | ||
1329 | GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); | ||
1330 | GNUNET_free (dll_op); | ||
1331 | op = event->details.operation_finished.operation; | ||
1332 | if (NULL != event->details.operation_finished.emsg) | ||
1333 | { | ||
1334 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1335 | _("An operation has failed while starting slaves\n")); | ||
1336 | GNUNET_TESTBED_operation_done (op); | ||
1337 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
1338 | GNUNET_SCHEDULER_cancel (abort_task); | ||
1339 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); | ||
1340 | return; | ||
1341 | } | ||
1342 | GNUNET_TESTBED_operation_done (op); | ||
1343 | /* Proceed to start peers */ | ||
1344 | if (++slaves_started == num_hosts - 1) | ||
1345 | { | ||
1346 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1347 | "All slaves started successfully\n"); | ||
1348 | |||
1349 | state = STATE_PEERS_CREATING; | ||
1350 | prof_start_time = GNUNET_TIME_absolute_get (); | ||
1351 | |||
1352 | if (-1 == (ret = GNUNET_DISK_directory_scan (policy_dir, | ||
1353 | NULL, | ||
1354 | NULL))) | ||
1355 | { | ||
1356 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1357 | _("No files found in `%s'\n"), | ||
1358 | policy_dir); | ||
1359 | GNUNET_SCHEDULER_shutdown (); | ||
1360 | return; | ||
1361 | } | ||
1362 | num_peers = (unsigned int) ret; | ||
1363 | peers = GNUNET_malloc (sizeof (struct RegexPeer) * num_peers); | ||
1364 | |||
1365 | /* Initialize peers */ | ||
1366 | for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++) | ||
1367 | { | ||
1368 | struct RegexPeer *peer = &peers[peer_cnt]; | ||
1369 | peer->id = peer_cnt; | ||
1370 | peer->policy_file = NULL; | ||
1371 | /* Do not start peers on hosts[0] (master controller) */ | ||
1372 | peer->host_handle = hosts[1 + (peer_cnt % (num_hosts -1))]; | ||
1373 | peer->mesh_handle = NULL; | ||
1374 | peer->mesh_tunnel_handle = NULL; | ||
1375 | peer->stats_handle = NULL; | ||
1376 | peer->stats_op_handle = NULL; | ||
1377 | peer->search_str = NULL; | ||
1378 | peer->search_str_matched = GNUNET_NO; | ||
1379 | } | ||
1380 | |||
1381 | GNUNET_DISK_directory_scan (policy_dir, | ||
1382 | &policy_filename_cb, | ||
1383 | NULL); | ||
1384 | } | ||
1385 | } | ||
1386 | break; | ||
1387 | default: | ||
1388 | GNUNET_assert (0); | ||
1389 | } | ||
1390 | break; | ||
1391 | case STATE_PEERS_STARTING: | ||
1392 | switch (event->type) | ||
1393 | { | ||
1394 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
1395 | /* Control reaches here when peer start fails */ | ||
1396 | case GNUNET_TESTBED_ET_PEER_START: | ||
1397 | /* we handle peer starts in peer_churn_cb */ | ||
1398 | break; | ||
1399 | default: | ||
1400 | GNUNET_assert (0); | ||
1401 | } | ||
1402 | break; | ||
1403 | case STATE_PEERS_LINKING: | ||
1404 | switch (event->type) | ||
1405 | { | ||
1406 | static unsigned int established_links; | ||
1407 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
1408 | /* Control reaches here when a peer linking operation fails */ | ||
1409 | if (NULL != event->details.operation_finished.emsg) | ||
1410 | { | ||
1411 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1412 | _("An operation has failed while linking\n")); | ||
1413 | printf ("F"); | ||
1414 | fflush (stdout); | ||
1415 | retry_links++; | ||
1416 | } | ||
1417 | /* We do no retries, consider this link as established */ | ||
1418 | /* break; */ | ||
1419 | case GNUNET_TESTBED_ET_CONNECT: | ||
1420 | { | ||
1421 | char output_buffer[512]; | ||
1422 | size_t size; | ||
1423 | |||
1424 | if (0 == established_links) | ||
1425 | printf ("Establishing links ."); | ||
1426 | else | ||
1427 | { | ||
1428 | printf ("."); | ||
1429 | fflush (stdout); | ||
1430 | } | ||
1431 | if (++established_links == num_links) | ||
1432 | { | ||
1433 | fflush (stdout); | ||
1434 | prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); | ||
1435 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1436 | "%u links established in %s\n", | ||
1437 | num_links, | ||
1438 | GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); | ||
1439 | result = GNUNET_OK; | ||
1440 | GNUNET_free (peer_handles); | ||
1441 | |||
1442 | if (NULL != data_file) | ||
1443 | { | ||
1444 | size = | ||
1445 | GNUNET_snprintf (output_buffer, | ||
1446 | sizeof (output_buffer), | ||
1447 | "# of peers: %u\n# of links established: %u\n" | ||
1448 | "Time to establish links: %s\nLinking failures: %u\n" | ||
1449 | "path compression length: %u\n# of search strings: %u\n", | ||
1450 | num_peers, | ||
1451 | (established_links - cont_fails), | ||
1452 | GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO), | ||
1453 | cont_fails, | ||
1454 | max_path_compression, | ||
1455 | num_search_strings); | ||
1456 | |||
1457 | if (size != GNUNET_DISK_file_write (data_file, output_buffer, size)) | ||
1458 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n"); | ||
1459 | } | ||
1460 | |||
1461 | printf ("\nWaiting %s before starting to search.\n", | ||
1462 | GNUNET_STRINGS_relative_time_to_string (search_delay, GNUNET_YES)); | ||
1463 | fflush (stdout); | ||
1464 | |||
1465 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1466 | "Waiting %s before starting to search.\n", | ||
1467 | GNUNET_STRINGS_relative_time_to_string (search_delay, GNUNET_NO)); | ||
1468 | |||
1469 | state = STATE_SEARCH_REGEX; | ||
1470 | |||
1471 | search_task = GNUNET_SCHEDULER_add_delayed (search_delay, | ||
1472 | &do_connect_by_string, NULL); | ||
1473 | } | ||
1474 | } | ||
1475 | break; | ||
1476 | default: | ||
1477 | GNUNET_assert (0); | ||
1478 | } | ||
1479 | break; | ||
1480 | case STATE_SEARCH_REGEX: | ||
1481 | { | ||
1482 | /* Handled in service connect callback */ | ||
1483 | break; | ||
1484 | } | ||
1485 | default: | ||
1486 | switch (state) | ||
1487 | { | ||
1488 | case STATE_PEERS_CREATING: | ||
1489 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create peer\n"); | ||
1490 | break; | ||
1491 | default: | ||
1492 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1493 | "Unexpected controller_cb with state %i!\n", state); | ||
1494 | } | ||
1495 | GNUNET_assert (0); | ||
1496 | } | ||
1497 | } | ||
1498 | |||
1499 | |||
1500 | /** | ||
1501 | * Task to register all hosts available in the global host list. | ||
1502 | * | ||
1503 | * @param cls NULL | ||
1504 | * @param tc the scheduler task context | ||
1505 | */ | ||
1506 | static void | ||
1507 | register_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
1508 | |||
1509 | |||
1510 | /** | ||
1511 | * Callback which will be called to after a host registration succeeded or failed | ||
1512 | * | ||
1513 | * @param cls the closure | ||
1514 | * @param emsg the error message; NULL if host registration is successful | ||
1515 | */ | ||
1516 | static void | ||
1517 | host_registration_completion (void *cls, const char *emsg) | ||
1518 | { | ||
1519 | reg_handle = NULL; | ||
1520 | if (NULL != emsg) | ||
1521 | { | ||
1522 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1523 | _("Host registration failed for a host. Error: %s\n"), emsg); | ||
1524 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
1525 | GNUNET_SCHEDULER_cancel (abort_task); | ||
1526 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); | ||
1527 | return; | ||
1528 | } | ||
1529 | register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, NULL); | ||
1530 | } | ||
1531 | |||
1532 | |||
1533 | /** | ||
1534 | * Task to register all hosts available in the global host list. | ||
1535 | * | ||
1536 | * @param cls NULL | ||
1537 | * @param tc the scheduler task context | ||
1538 | */ | ||
1539 | static void | ||
1540 | register_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1541 | { | ||
1542 | struct DLLOperation *dll_op; | ||
1543 | static unsigned int reg_host; | ||
1544 | unsigned int slave; | ||
1545 | |||
1546 | register_hosts_task = GNUNET_SCHEDULER_NO_TASK; | ||
1547 | if (reg_host == num_hosts - 1) | ||
1548 | { | ||
1549 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1550 | "All hosts successfully registered\n"); | ||
1551 | /* Start slaves */ | ||
1552 | state = STATE_SLAVES_STARTING; | ||
1553 | for (slave = 1; slave < num_hosts; slave++) | ||
1554 | { | ||
1555 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
1556 | dll_op->op = GNUNET_TESTBED_controller_link (dll_op, | ||
1557 | mc, | ||
1558 | hosts[slave], | ||
1559 | hosts[0], | ||
1560 | cfg, | ||
1561 | GNUNET_YES); | ||
1562 | GNUNET_CONTAINER_DLL_insert_tail (dll_op_head, dll_op_tail, dll_op); | ||
1563 | } | ||
1564 | return; | ||
1565 | } | ||
1566 | reg_handle = GNUNET_TESTBED_register_host (mc, hosts[++reg_host], | ||
1567 | host_registration_completion, | ||
1568 | NULL); | ||
1569 | } | ||
1570 | |||
1571 | |||
1572 | /** | ||
1573 | * Callback to signal successfull startup of the controller process. | ||
1574 | * | ||
1575 | * @param cls the closure from GNUNET_TESTBED_controller_start() | ||
1576 | * @param config the configuration with which the controller has been started; | ||
1577 | * NULL if status is not GNUNET_OK | ||
1578 | * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not, | ||
1579 | * GNUNET_TESTBED_controller_stop() shouldn't be called in this case | ||
1580 | */ | ||
1581 | static void | ||
1582 | status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, int status) | ||
1583 | { | ||
1584 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
1585 | GNUNET_SCHEDULER_cancel (abort_task); | ||
1586 | if (GNUNET_OK != status) | ||
1587 | { | ||
1588 | mc_proc = NULL; | ||
1589 | printf("CRAPPP\n"); | ||
1590 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); | ||
1591 | return; | ||
1592 | } | ||
1593 | event_mask = 0; | ||
1594 | event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START); | ||
1595 | event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP); | ||
1596 | event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); | ||
1597 | event_mask |= (1LL << GNUNET_TESTBED_ET_DISCONNECT); | ||
1598 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
1599 | mc = GNUNET_TESTBED_controller_connect (config, hosts[0], event_mask, | ||
1600 | &controller_event_cb, NULL); | ||
1601 | if (NULL == mc) | ||
1602 | { | ||
1603 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1604 | _("Unable to connect to master controller -- Check config\n")); | ||
1605 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); | ||
1606 | return; | ||
1607 | } | ||
1608 | register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, NULL); | ||
1609 | abort_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1610 | &do_abort, (void*) __LINE__); | ||
1611 | } | ||
1612 | |||
1613 | |||
1614 | /** | ||
1615 | * Load search strings from given filename. One search string per line. | ||
1616 | * | ||
1617 | * @param filename filename of the file containing the search strings. | ||
1618 | * @param strings set of strings loaded from file. Caller needs to free this | ||
1619 | * if number returned is greater than zero. | ||
1620 | * @param limit upper limit on the number of strings read from the file | ||
1621 | * @return number of strings found in the file. GNUNET_SYSERR on error. | ||
1622 | */ | ||
1623 | static int | ||
1624 | load_search_strings (const char *filename, char ***strings, unsigned int limit) | ||
1625 | { | ||
1626 | char *data; | ||
1627 | char *buf; | ||
1628 | uint64_t filesize; | ||
1629 | unsigned int offset; | ||
1630 | int str_cnt; | ||
1631 | unsigned int i; | ||
1632 | |||
1633 | if (NULL == filename) | ||
1634 | { | ||
1635 | return GNUNET_SYSERR; | ||
1636 | } | ||
1637 | |||
1638 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
1639 | { | ||
1640 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1641 | "Could not find search strings file %s\n", filename); | ||
1642 | return GNUNET_SYSERR; | ||
1643 | } | ||
1644 | if (GNUNET_OK != GNUNET_DISK_file_size (filename, &filesize, GNUNET_YES, GNUNET_YES)) | ||
1645 | filesize = 0; | ||
1646 | if (0 == filesize) | ||
1647 | { | ||
1648 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Search strings file %s is empty.\n", filename); | ||
1649 | return GNUNET_SYSERR; | ||
1650 | } | ||
1651 | data = GNUNET_malloc (filesize); | ||
1652 | if (filesize != GNUNET_DISK_fn_read (filename, data, filesize)) | ||
1653 | { | ||
1654 | GNUNET_free (data); | ||
1655 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Could not read search strings file %s.\n", | ||
1656 | filename); | ||
1657 | return GNUNET_SYSERR; | ||
1658 | } | ||
1659 | buf = data; | ||
1660 | offset = 0; | ||
1661 | str_cnt = 0; | ||
1662 | while (offset < (filesize - 1) && str_cnt < limit) | ||
1663 | { | ||
1664 | offset++; | ||
1665 | if (((data[offset] == '\n')) && (buf != &data[offset])) | ||
1666 | { | ||
1667 | data[offset] = '\0'; | ||
1668 | str_cnt++; | ||
1669 | buf = &data[offset + 1]; | ||
1670 | } | ||
1671 | else if ((data[offset] == '\n') || (data[offset] == '\0')) | ||
1672 | buf = &data[offset + 1]; | ||
1673 | } | ||
1674 | *strings = GNUNET_malloc (sizeof (char *) * str_cnt); | ||
1675 | offset = 0; | ||
1676 | for (i = 0; i < str_cnt; i++) | ||
1677 | { | ||
1678 | GNUNET_asprintf (&(*strings)[i], "%s%s", regex_prefix, &data[offset]); | ||
1679 | offset += strlen (&data[offset]) + 1; | ||
1680 | } | ||
1681 | GNUNET_free (data); | ||
1682 | return str_cnt; | ||
1683 | } | ||
1684 | |||
1685 | |||
1686 | /** | ||
1687 | * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to | ||
1688 | * inform whether the given host is habitable or not. The Handle returned by | ||
1689 | * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called | ||
1690 | * | ||
1691 | * @param cls NULL | ||
1692 | * @param host the host whose status is being reported; will be NULL if the host | ||
1693 | * given to GNUNET_TESTBED_is_host_habitable() is NULL | ||
1694 | * @param status GNUNET_YES if it is habitable; GNUNET_NO if not | ||
1695 | */ | ||
1696 | static void | ||
1697 | host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *host, int status) | ||
1698 | { | ||
1699 | struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handle = cls; | ||
1700 | static unsigned int hosts_checked; | ||
1701 | |||
1702 | *hc_handle = NULL; | ||
1703 | if (GNUNET_NO == status) | ||
1704 | { | ||
1705 | if ((NULL != host) && (NULL != GNUNET_TESTBED_host_get_hostname (host))) | ||
1706 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Host %s cannot start testbed\n"), | ||
1707 | GNUNET_TESTBED_host_get_hostname (host)); | ||
1708 | else | ||
1709 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Testbed cannot be started on localhost\n")); | ||
1710 | GNUNET_SCHEDULER_cancel (abort_task); | ||
1711 | abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); | ||
1712 | return; | ||
1713 | } | ||
1714 | hosts_checked++; | ||
1715 | /* printf (_("\rChecked %u hosts"), hosts_checked); */ | ||
1716 | /* fflush (stdout); */ | ||
1717 | if (hosts_checked < num_hosts) | ||
1718 | return; | ||
1719 | /* printf (_("\nAll hosts can start testbed. Creating peers\n")); */ | ||
1720 | GNUNET_free (hc_handles); | ||
1721 | hc_handles = NULL; | ||
1722 | mc_proc = | ||
1723 | GNUNET_TESTBED_controller_start (GNUNET_TESTBED_host_get_hostname | ||
1724 | (hosts[0]), | ||
1725 | hosts[0], | ||
1726 | cfg, | ||
1727 | status_cb, | ||
1728 | NULL); | ||
1729 | } | ||
1730 | |||
1731 | |||
1732 | /** | ||
1733 | * Main function that will be run by the scheduler. | ||
1734 | * | ||
1735 | * @param cls closure | ||
1736 | * @param args remaining command-line arguments | ||
1737 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
1738 | * @param config configuration | ||
1739 | */ | ||
1740 | static void | ||
1741 | run (void *cls, char *const *args, const char *cfgfile, | ||
1742 | const struct GNUNET_CONFIGURATION_Handle *config) | ||
1743 | { | ||
1744 | unsigned int nhost; | ||
1745 | unsigned int nsearchstrs; | ||
1746 | |||
1747 | if (NULL == args[0]) | ||
1748 | { | ||
1749 | fprintf (stderr, _("No hosts-file specified on command line. Exiting.\n")); | ||
1750 | return; | ||
1751 | } | ||
1752 | if (NULL == args[1]) | ||
1753 | { | ||
1754 | fprintf (stderr, _("No policy directory specified on command line. Exiting.\n")); | ||
1755 | return; | ||
1756 | } | ||
1757 | num_hosts = GNUNET_TESTBED_hosts_load_from_file (args[0], &hosts); | ||
1758 | if (0 == num_hosts) | ||
1759 | { | ||
1760 | fprintf (stderr, _("No hosts loaded. Need at least one host\n")); | ||
1761 | return; | ||
1762 | } | ||
1763 | printf (_("Checking whether given hosts can start testbed. Please wait\n")); | ||
1764 | hc_handles = GNUNET_malloc (sizeof (struct | ||
1765 | GNUNET_TESTBED_HostHabitableCheckHandle *) | ||
1766 | * num_hosts); | ||
1767 | for (nhost = 0; nhost < num_hosts; nhost++) | ||
1768 | { | ||
1769 | if (NULL == (hc_handles[nhost] = GNUNET_TESTBED_is_host_habitable (hosts[nhost], config, | ||
1770 | &host_habitable_cb, | ||
1771 | &hc_handles[nhost]))) | ||
1772 | { | ||
1773 | GNUNET_break (0); | ||
1774 | for (nhost = 0; nhost < num_hosts; nhost++) | ||
1775 | if (NULL != hc_handles[nhost]) | ||
1776 | GNUNET_TESTBED_is_host_habitable_cancel (hc_handles[nhost]); | ||
1777 | GNUNET_free (hc_handles); | ||
1778 | hc_handles = NULL; | ||
1779 | break; | ||
1780 | } | ||
1781 | } | ||
1782 | if (num_hosts != nhost) | ||
1783 | { | ||
1784 | fprintf (stderr, _("Exiting\n")); | ||
1785 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1786 | return; | ||
1787 | } | ||
1788 | if (NULL == config) | ||
1789 | { | ||
1790 | fprintf (stderr, _("No configuration file given. Exiting\n")); | ||
1791 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1792 | return; | ||
1793 | } | ||
1794 | |||
1795 | if (GNUNET_OK != | ||
1796 | GNUNET_CONFIGURATION_get_value_string (config, "REGEXPROFILER", "REGEX_PREFIX", | ||
1797 | ®ex_prefix)) | ||
1798 | { | ||
1799 | fprintf (stderr, _("Configuration option (regex_prefix) missing. Exiting\n")); | ||
1800 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1801 | return; | ||
1802 | } | ||
1803 | |||
1804 | if ( (NULL != data_filename) && | ||
1805 | (NULL == (data_file = | ||
1806 | GNUNET_DISK_file_open (data_filename, | ||
1807 | GNUNET_DISK_OPEN_READWRITE | | ||
1808 | GNUNET_DISK_OPEN_TRUNCATE | | ||
1809 | GNUNET_DISK_OPEN_CREATE, | ||
1810 | GNUNET_DISK_PERM_USER_READ | | ||
1811 | GNUNET_DISK_PERM_USER_WRITE))) ) | ||
1812 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | ||
1813 | "open", | ||
1814 | data_filename); | ||
1815 | if (GNUNET_YES != GNUNET_DISK_directory_test (args[1], GNUNET_YES)) | ||
1816 | { | ||
1817 | fprintf (stderr, _("Specified policies directory does not exist. Exiting.\n")); | ||
1818 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1819 | return; | ||
1820 | } | ||
1821 | policy_dir = args[1]; | ||
1822 | if (GNUNET_YES != GNUNET_DISK_file_test (args[2])) | ||
1823 | { | ||
1824 | fprintf (stderr, _("No search strings file given. Exiting.\n")); | ||
1825 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1826 | return; | ||
1827 | } | ||
1828 | nsearchstrs = load_search_strings (args[2], &search_strings, num_search_strings); | ||
1829 | if (num_search_strings != nsearchstrs) | ||
1830 | { | ||
1831 | num_search_strings = nsearchstrs; | ||
1832 | fprintf (stderr, _("Error loading search strings. Given file does not contain enough strings. Exiting.\n")); | ||
1833 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1834 | return; | ||
1835 | } | ||
1836 | if (0 >= num_search_strings || NULL == search_strings) | ||
1837 | { | ||
1838 | fprintf (stderr, _("Error loading search strings. Exiting.\n")); | ||
1839 | shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1840 | return; | ||
1841 | } | ||
1842 | unsigned int i; | ||
1843 | for (i = 0; i < num_search_strings; i++) | ||
1844 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "search string: %s\n", search_strings[i]); | ||
1845 | cfg = GNUNET_CONFIGURATION_dup (config); | ||
1846 | abort_task = | ||
1847 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
1848 | (GNUNET_TIME_UNIT_SECONDS, 5), &do_abort, | ||
1849 | (void*) __LINE__); | ||
1850 | } | ||
1851 | |||
1852 | |||
1853 | /** | ||
1854 | * Main function. | ||
1855 | * | ||
1856 | * @param argc argument count | ||
1857 | * @param argv argument values | ||
1858 | * @return 0 on success | ||
1859 | */ | ||
1860 | int | ||
1861 | main (int argc, char *const *argv) | ||
1862 | { | ||
1863 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
1864 | {'d', "details", "FILENAME", | ||
1865 | gettext_noop ("name of the file for writing statistics"), | ||
1866 | 1, &GNUNET_GETOPT_set_string, &data_filename}, | ||
1867 | {'n', "num-links", "COUNT", | ||
1868 | gettext_noop ("create COUNT number of random links between peers"), | ||
1869 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &linking_factor }, | ||
1870 | {'t', "matching-timeout", "TIMEOUT", | ||
1871 | gettext_noop ("wait TIMEOUT before considering a string match as failed"), | ||
1872 | GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &search_timeout }, | ||
1873 | {'s', "search-delay", "DELAY", | ||
1874 | gettext_noop ("wait DELAY before starting string search"), | ||
1875 | GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &search_delay }, | ||
1876 | {'a', "num-search-strings", "COUNT", | ||
1877 | gettext_noop ("number of search strings to read from search strings file"), | ||
1878 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_search_strings }, | ||
1879 | {'p', "max-path-compression", "MAX_PATH_COMPRESSION", | ||
1880 | gettext_noop ("maximum path compression length"), | ||
1881 | 1, &GNUNET_GETOPT_set_uint, &max_path_compression}, | ||
1882 | {'i', "no-distributed-search", "", | ||
1883 | gettext_noop ("if this option is set, only one peer is responsible for searching all strings"), | ||
1884 | 0, &GNUNET_GETOPT_set_one, &no_distributed_search}, | ||
1885 | GNUNET_GETOPT_OPTION_END | ||
1886 | }; | ||
1887 | int ret; | ||
1888 | |||
1889 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
1890 | return 2; | ||
1891 | |||
1892 | result = GNUNET_SYSERR; | ||
1893 | ret = | ||
1894 | GNUNET_PROGRAM_run (argc, argv, "gnunet-regex-profiler [OPTIONS] hosts-file policy-dir search-strings-file", | ||
1895 | _("Profiler for regex/mesh"), | ||
1896 | options, &run, NULL); | ||
1897 | |||
1898 | if (GNUNET_OK != ret) | ||
1899 | return ret; | ||
1900 | if (GNUNET_OK != result) | ||
1901 | return 1; | ||
1902 | return 0; | ||
1903 | } | ||
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index f5d323a35..2ee5b9d3f 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -8243,13 +8243,6 @@ key_generation_cb (void *cls, | |||
8243 | "Mesh for peer [%s] starting\n", | 8243 | "Mesh for peer [%s] starting\n", |
8244 | GNUNET_i2s(&my_full_id)); | 8244 | GNUNET_i2s(&my_full_id)); |
8245 | 8245 | ||
8246 | // transport_handle = GNUNET_TRANSPORT_connect(c, | ||
8247 | // &my_full_id, | ||
8248 | // NULL, | ||
8249 | // NULL, | ||
8250 | // NULL, | ||
8251 | // NULL); | ||
8252 | |||
8253 | core_handle = GNUNET_CORE_connect (c, /* Main configuration */ | 8246 | core_handle = GNUNET_CORE_connect (c, /* Main configuration */ |
8254 | NULL, /* Closure passed to MESH functions */ | 8247 | NULL, /* Closure passed to MESH functions */ |
8255 | &core_init, /* Call core_init once connected */ | 8248 | &core_init, /* Call core_init once connected */ |