2 This file is part of GNUnet.
3 (C) 2010, 2011, 2012 Christian Grothoff
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.
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.
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.
22 * @file mesh/gnunet-service-regexprofiler.c
23 * @brief service 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
30 #include "gnunet_mesh_service.h"
31 #include "gnunet_statistics_service.h"
34 * Return value from 'main'.
36 static int global_ret;
39 * Configuration we use.
41 static const struct GNUNET_CONFIGURATION_Handle *cfg;
46 static struct GNUNET_SERVER_Handle *server_handle;
49 * Handle to the statistics service.
51 static struct GNUNET_STATISTICS_Handle *stats_handle;
56 struct GNUNET_MESH_Handle *mesh_handle;
59 * Peer's mesh tunnel handle.
61 struct GNUNET_MESH_Tunnel *mesh_tunnel_handle;
64 * Maximal path compression length for regex announcing.
66 static unsigned long long max_path_compression;
69 * Name of the file containing policies that this peer should announce. One
72 static char * policy_filename;
76 * Task run during shutdown.
82 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
84 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
86 if (NULL != mesh_tunnel_handle)
88 GNUNET_MESH_tunnel_destroy (mesh_tunnel_handle);
89 mesh_tunnel_handle = NULL;
92 if (NULL != mesh_handle)
94 GNUNET_MESH_disconnect (mesh_handle);
98 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
103 * Method called whenever a peer has disconnected from the tunnel.
104 * Implementations of this callback must NOT call
105 * GNUNET_MESH_tunnel_destroy immediately, but instead schedule those
106 * to run in some other task later. However, calling
107 * "GNUNET_MESH_notify_transmit_ready_cancel" is allowed.
110 * @param peer_id peer identity the tunnel stopped working with
113 mesh_peer_disconnect_handler (void *cls,
114 const struct GNUNET_PeerIdentity * peer_id)
116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh peer disconnect handler.\n");
117 GNUNET_STATISTICS_update (stats_handle, "# peers disconnected", 1, GNUNET_NO);
122 * Method called whenever a peer has connected to the tunnel.
125 * @param peer_id peer identity the tunnel was created to, NULL on timeout
126 * @param atsi performance data for the connection
130 mesh_peer_connect_handler (void *cls,
131 const struct GNUNET_PeerIdentity* peer_id,
132 const struct GNUNET_ATS_Information * atsi)
134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh peer connect handler.\n");
135 GNUNET_STATISTICS_update (stats_handle, "# peers connected", 1, GNUNET_NO);
140 * Announce the given regular expression using Mesh and the path compression
141 * length read from config.
143 * @param regex regular expression to announce on this peer's mesh.
146 announce_regex (const char * regex)
148 if (NULL == regex || 0 == strlen (regex))
150 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot announce empty regex\n");
154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Announcing regex: %s\n", regex);
155 GNUNET_STATISTICS_update (stats_handle, "# regexes announced", 1, GNUNET_NO);
156 GNUNET_MESH_announce_regex (mesh_handle, regex, (unsigned int)max_path_compression);
161 * Main function that will be run by the scheduler.
164 * @param server the initialized server
165 * @param cfg_ configuration
169 struct GNUNET_SERVER_Handle *server,
170 const struct GNUNET_CONFIGURATION_Handle *cfg_)
177 GNUNET_MESH_ApplicationType app;
179 static struct GNUNET_MESH_MessageHandler handlers[] = {
186 GNUNET_CONFIGURATION_get_value_number (cfg, "REGEXPROFILER", "MAX_PATH_COMPRESSION",
187 &max_path_compression))
189 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
191 ("%s service is lacking key configuration settings (%s). Exiting.\n"),
192 "regexprofiler", "max_path_compression");
193 global_ret = GNUNET_SYSERR;
194 GNUNET_SCHEDULER_shutdown ();
199 GNUNET_CONFIGURATION_get_value_filename (cfg, "REGEXPROFILER", "POLICY_FILE",
202 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
204 ("%s service is lacking key configuration settings (%s). Exiting.\n"),
205 "regexprofiler", "policy_file");
206 global_ret = GNUNET_SYSERR;
207 GNUNET_SCHEDULER_shutdown ();
211 stats_handle = GNUNET_STATISTICS_create ("regexprofiler", cfg);
213 app = (GNUNET_MESH_ApplicationType)0;
215 mesh_tunnel_handle = GNUNET_MESH_tunnel_create (mesh_handle,
217 &mesh_peer_connect_handler,
218 &mesh_peer_disconnect_handler,
222 GNUNET_MESH_connect (cfg, mesh_tunnel_handle, NULL, NULL, handlers, &app);
224 /* Announcing regexes from policy_filename */
225 if (GNUNET_YES != GNUNET_DISK_file_test (policy_filename))
227 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
228 "Could not find policy file %s\n", policy_filename);
231 if (GNUNET_OK != GNUNET_DISK_file_size (policy_filename, &filesize, GNUNET_YES, GNUNET_YES))
235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Policy file %s is empty.\n", policy_filename);
238 data = GNUNET_malloc (filesize);
239 if (filesize != GNUNET_DISK_fn_read (policy_filename, data, filesize))
242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not read policy file %s.\n",
249 while (offset < (filesize - 1))
252 if (((data[offset] == '\n')) && (buf != &data[offset]))
256 GNUNET_assert (NULL != regex);
257 announce_regex (regex);
258 buf = &data[offset + 1];
260 else if ((data[offset] == '\n') || (data[offset] == '\0'))
261 buf = &data[offset + 1];
266 GNUNET_SERVER_suspend (server_handle);
267 /* Scheduled the task to clean up when shutdown is called */
268 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
274 * The main function of the regexprofiler service.
276 * @param argc number of arguments from the command line
277 * @param argv command line arguments
278 * @return 0 ok, 1 on error
281 main (int argc, char *const *argv)
284 GNUNET_SERVICE_run (argc, argv, "regexprofiler",
285 GNUNET_SERVICE_OPTION_NONE,
286 &run, NULL)) ? global_ret : 1;
289 /* end of gnunet-service-regexprofiler.c */