GNUnet  0.11.x
Data Structures | Functions | Variables
gnunet-service-regex.c File Reference

service to advertise capabilities described as regex and to lookup capabilities by regex More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "regex_internal_lib.h"
#include "regex_ipc.h"
Include dependency graph for gnunet-service-regex.c:

Go to the source code of this file.

Data Structures

struct  ClientEntry
 Information about one of our clients. More...
 

Functions

static void cleanup_task (void *cls)
 Task run during shutdown. More...
 
static void reannounce (void *cls)
 Periodic task to refresh our announcement of the regex. More...
 
static int check_announce (void *cls, const struct AnnounceMessage *am)
 Check ANNOUNCE message. More...
 
static void handle_announce (void *cls, const struct AnnounceMessage *am)
 Handle ANNOUNCE message. More...
 
static void handle_search_result (void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length)
 Handle result, pass it back to the client. More...
 
static int check_search (void *cls, const struct RegexSearchMessage *sm)
 Check SEARCH message. More...
 
static void handle_search (void *cls, const struct RegexSearchMessage *sm)
 Handle SEARCH message. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
 Process regex requests. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
 Callback called when a client connects to the service. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
 Callback called when a client disconnected from the service. More...
 
 GNUNET_SERVICE_MAIN ("regex", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(announce, GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE, struct AnnounceMessage, NULL), GNUNET_MQ_hd_var_size(search, GNUNET_MESSAGE_TYPE_REGEX_SEARCH, struct RegexSearchMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static struct GNUNET_DHT_Handledht
 Connection to the DHT. More...
 
static struct GNUNET_STATISTICS_Handlestats
 Handle for doing statistics. More...
 
static struct GNUNET_CRYPTO_EddsaPrivateKeymy_private_key
 Private key for this peer. More...
 

Detailed Description

service to advertise capabilities described as regex and to lookup capabilities by regex

Author
Christian Grothoff

Definition in file gnunet-service-regex.c.

Function Documentation

◆ cleanup_task()

static void cleanup_task ( void *  cls)
static

Task run during shutdown.

Parameters
clsunused

Definition at line 92 of file gnunet-service-regex.c.

References GNUNET_DHT_disconnect(), GNUNET_free, GNUNET_NO, and GNUNET_STATISTICS_destroy().

Referenced by run().

93 {
95  dht = NULL;
97  GNUNET_NO);
98  stats = NULL;
100  my_private_key = NULL;
101 }
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
static struct GNUNET_STATISTICS_Handle * stats
Handle for doing statistics.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Private key for this peer.
static struct GNUNET_DHT_Handle * dht
Connection to the DHT.
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:918
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reannounce()

static void reannounce ( void *  cls)
static

Periodic task to refresh our announcement of the regex.

Parameters
clsthe struct ClientEntry * of the client that triggered the announcement

Definition at line 111 of file gnunet-service-regex.c.

References ClientEntry::ah, ClientEntry::frequency, GNUNET_SCHEDULER_add_delayed(), ClientEntry::refresh_task, and REGEX_INTERNAL_reannounce().

Referenced by handle_announce().

112 {
113  struct ClientEntry *ce = cls;
114 
117  &reannounce,
118  ce);
119 }
struct REGEX_INTERNAL_Announcement * ah
Announcement handle (if this client is announcing).
struct GNUNET_TIME_Relative frequency
Refresh frequency for announcements.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
Information about one of our clients.
static void reannounce(void *cls)
Periodic task to refresh our announcement of the regex.
struct GNUNET_SCHEDULER_Task * refresh_task
Task for re-announcing.
void REGEX_INTERNAL_reannounce(struct REGEX_INTERNAL_Announcement *h)
Announce again a regular expression previously announced.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_announce()

static int check_announce ( void *  cls,
const struct AnnounceMessage am 
)
static

Check ANNOUNCE message.

Parameters
clsidentification of the client
amthe actual message
Returns
GNUNET_OK if is well-formed

Definition at line 130 of file gnunet-service-regex.c.

References ClientEntry::ah, GNUNET_break, GNUNET_MQ_check_zero_termination, GNUNET_OK, and GNUNET_SYSERR.

132 {
133  struct ClientEntry *ce = cls;
134 
136  if (NULL != ce->ah)
137  {
138  /* only one announcement per client allowed */
139  GNUNET_break (0);
140  return GNUNET_SYSERR;
141  }
142  return GNUNET_OK;
143 }
struct REGEX_INTERNAL_Announcement * ah
Announcement handle (if this client is announcing).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MQ_check_zero_termination(m)
Insert code for a "check_" function that verifies that a given variable-length message received over ...
Information about one of our clients.

◆ handle_announce()

static void handle_announce ( void *  cls,
const struct AnnounceMessage am 
)
static

Handle ANNOUNCE message.

Parameters
clsidentification of the client
amthe actual message

Definition at line 153 of file gnunet-service-regex.c.

References ClientEntry::ah, ClientEntry::client, AnnounceMessage::compression, ClientEntry::frequency, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_relative_ntoh(), reannounce(), AnnounceMessage::refresh_delay, ClientEntry::refresh_task, and REGEX_INTERNAL_announce().

155 {
156  struct ClientEntry *ce = cls;
157  const char *regex;
158 
159  regex = (const char *) &am[1];
162  &reannounce,
163  ce);
165  "Starting to announce regex `%s' every %s\n",
166  regex,
168  GNUNET_NO));
171  regex,
172  ntohs (am->compression),
173  stats);
174  if (NULL == ce->ah)
175  {
176  GNUNET_break (0);
178  ce->refresh_task = NULL;
180  return;
181  }
183 }
uint16_t compression
How many characters can we squeeze per edge?
Definition: regex_ipc.h:44
struct REGEX_INTERNAL_Announcement * ah
Announcement handle (if this client is announcing).
struct GNUNET_TIME_Relative frequency
Refresh frequency for announcements.
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1269
Information about one of our clients.
static void reannounce(void *cls)
Periodic task to refresh our announcement of the regex.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:701
static struct GNUNET_STATISTICS_Handle * stats
Handle for doing statistics.
struct GNUNET_SCHEDULER_Task * refresh_task
Task for re-announcing.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Private key for this peer.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh(struct GNUNET_TIME_RelativeNBO a)
Convert relative time from network byte order.
Definition: time.c:641
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2323
static struct GNUNET_DHT_Handle * dht
Connection to the DHT.
struct REGEX_INTERNAL_Announcement * REGEX_INTERNAL_announce(struct GNUNET_DHT_Handle *dht, const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const char *regex, uint16_t compression, struct GNUNET_STATISTICS_Handle *stats)
Announce a regular expression: put all states of the automaton in the DHT.
#define GNUNET_log(kind,...)
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2242
struct GNUNET_TIME_RelativeNBO refresh_delay
Delay between repeated announcements.
Definition: regex_ipc.h:54
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
Here is the call graph for this function:

◆ handle_search_result()

static void handle_search_result ( void *  cls,
const struct GNUNET_PeerIdentity id,
const struct GNUNET_PeerIdentity get_path,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity put_path,
unsigned int  put_path_length 
)
static

Handle result, pass it back to the client.

Parameters
clsthe struct ClientEntry of the client searching
idPeer providing a regex that matches the string.
get_pathPath of the get request.
get_path_lengthLenght of get_path.
put_pathPath of the put request.
put_path_lengthLength of the put_path.

Definition at line 197 of file gnunet-service-regex.c.

References env, ResultMessage::get_path_length, GNUNET_break, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_REGEX_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), ResultMessage::id, id, ClientEntry::mq, ResultMessage::put_path_length, result, and size.

Referenced by handle_search().

203 {
204  struct ClientEntry *ce = cls;
205  struct GNUNET_MQ_Envelope *env;
206  struct ResultMessage *result;
207  struct GNUNET_PeerIdentity *gp;
208  uint16_t size;
209 
210  if ((get_path_length >= 65536) ||
211  (put_path_length >= 65536) ||
212  ( ((get_path_length + put_path_length) * sizeof(struct
214  + sizeof(struct ResultMessage) >= GNUNET_MAX_MESSAGE_SIZE) )
215  {
216  GNUNET_break (0);
217  return;
218  }
219  size = (get_path_length + put_path_length) * sizeof(struct
221  env = GNUNET_MQ_msg_extra (result,
222  size,
224  result->get_path_length = htons ((uint16_t) get_path_length);
225  result->put_path_length = htons ((uint16_t) put_path_length);
226  result->id = *id;
227  gp = &result->id;
228  GNUNET_memcpy (&gp[1],
229  get_path,
230  get_path_length * sizeof(struct GNUNET_PeerIdentity));
231  GNUNET_memcpy (&gp[1 + get_path_length],
232  put_path,
233  put_path_length * sizeof(struct GNUNET_PeerIdentity));
234  GNUNET_MQ_send (ce->mq,
235  env);
236 }
Result from regex search.
Definition: regex_ipc.h:77
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_REGEX_RESULT
Result in response to regex search.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
uint16_t put_path_length
Number of entries in the PUT path.
Definition: regex_ipc.h:92
Information about one of our clients.
static int result
Global testing status.
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
struct GNUNET_PeerIdentity id
Identity of the peer that was found.
Definition: regex_ipc.h:97
The identity of the host (wraps the signing key of the peer).
uint16_t get_path_length
Number of entries in the GET path.
Definition: regex_ipc.h:87
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:355
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_search()

static int check_search ( void *  cls,
const struct RegexSearchMessage sm 
)
static

Check SEARCH message.

Parameters
clsidentification of the client
messagethe actual message

Definition at line 246 of file gnunet-service-regex.c.

References GNUNET_break, GNUNET_OK, GNUNET_SYSERR, RegexSearchMessage::header, ClientEntry::sh, size, and GNUNET_MessageHeader::size.

248 {
249  struct ClientEntry *ce = cls;
250  const char *string;
251  uint16_t size;
252 
253  size = ntohs (sm->header.size) - sizeof(*sm);
254  string = (const char *) &sm[1];
255  if ('\0' != string[size - 1])
256  {
257  GNUNET_break (0);
258  return GNUNET_SYSERR;
259  }
260  if (NULL != ce->sh)
261  {
262  /* only one search allowed per client */
263  GNUNET_break (0);
264  return GNUNET_SYSERR;
265  }
266  return GNUNET_OK;
267 }
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_REGEX_SEARCH.
Definition: regex_ipc.h:68
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct REGEX_INTERNAL_Search * sh
Search handle (if this client is searching).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Information about one of our clients.
static unsigned int size
Size of the "table".
Definition: peer.c:67

◆ handle_search()

static void handle_search ( void *  cls,
const struct RegexSearchMessage sm 
)
static

Handle SEARCH message.

Parameters
clsidentification of the client
messagethe actual message

Definition at line 277 of file gnunet-service-regex.c.

References ClientEntry::client, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), handle_search_result(), REGEX_INTERNAL_search(), and ClientEntry::sh.

279 {
280  struct ClientEntry *ce = cls;
281  const char *string;
282 
283  string = (const char *) &sm[1];
285  "Starting to search for `%s'\n",
286  string);
288  string,
290  ce,
291  stats);
292  if (NULL == ce->sh)
293  {
294  GNUNET_break (0);
296  return;
297  }
299 }
static void handle_search_result(void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length)
Handle result, pass it back to the client.
struct REGEX_INTERNAL_Search * sh
Search handle (if this client is searching).
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Information about one of our clients.
static struct GNUNET_STATISTICS_Handle * stats
Handle for doing statistics.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2323
static struct GNUNET_DHT_Handle * dht
Connection to the DHT.
struct REGEX_INTERNAL_Search * REGEX_INTERNAL_search(struct GNUNET_DHT_Handle *dht, const char *string, REGEX_INTERNAL_Found callback, void *callback_cls, struct GNUNET_STATISTICS_Handle *stats)
Search for a peer offering a regex matching certain string in the DHT.
#define GNUNET_log(kind,...)
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2242
Here is the call graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle cfg,
struct GNUNET_SERVICE_Handle service 
)
static

Process regex requests.

Parameters
clsclosure
cfgconfiguration to use
servicethe initialized service

Definition at line 310 of file gnunet-service-regex.c.

References cleanup_task(), GNUNET_CRYPTO_eddsa_key_create_from_configuration(), GNUNET_DHT_connect(), GNUNET_free, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), and GNUNET_STATISTICS_create().

Referenced by client_disconnect_cb().

313 {
315  if (NULL == my_private_key)
316  {
318  return;
319  }
320  dht = GNUNET_DHT_connect (cfg, 1024);
321  if (NULL == dht)
322  {
324  my_private_key = NULL;
326  return;
327  }
329  NULL);
330  stats = GNUNET_STATISTICS_create ("regex", cfg);
331 }
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1331
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
static struct GNUNET_STATISTICS_Handle * stats
Handle for doing statistics.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Private key for this peer.
static struct GNUNET_DHT_Handle * dht
Connection to the DHT.
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:890
static void cleanup_task(void *cls)
Task run during shutdown.
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration...
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_connect_cb()

static void* client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
struct GNUNET_MQ_Handle mq 
)
static

Callback called when a client connects to the service.

Parameters
clsclosure for the service
cthe new client that connected to the service
mqthe message queue used to send messages to the client
Returns
c

Definition at line 343 of file gnunet-service-regex.c.

References ClientEntry::client, GNUNET_new, and ClientEntry::mq.

Referenced by client_disconnect_cb().

346 {
347  struct ClientEntry *ce;
348 
349  ce = GNUNET_new (struct ClientEntry);
350  ce->client = c;
351  ce->mq = mq;
352  return ce;
353 }
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_SERVICE_Client * client
Handle identifying the client.
Information about one of our clients.
struct GNUNET_MQ_Handle * mq
Queue for transmissions to client.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Here is the caller graph for this function:

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
void *  internal_cls 
)
static

Callback called when a client disconnected from the service.

Parameters
clsclosure for the service
cthe client that disconnected
internal_clsshould be equal to c

Definition at line 364 of file gnunet-service-regex.c.

References ClientEntry::ah, client_connect_cb(), GNUNET_free, GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE, GNUNET_MESSAGE_TYPE_REGEX_SEARCH, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_SCHEDULER_cancel(), GNUNET_SERVICE_MAIN(), GNUNET_SERVICE_OPTION_NONE, ClientEntry::refresh_task, REGEX_INTERNAL_announce_cancel(), REGEX_INTERNAL_search_cancel(), run(), and ClientEntry::sh.

367 {
368  struct ClientEntry *ce = internal_cls;
369 
370  if (NULL != ce->refresh_task)
371  {
373  ce->refresh_task = NULL;
374  }
375  if (NULL != ce->ah)
376  {
378  ce->ah = NULL;
379  }
380  if (NULL != ce->sh)
381  {
383  ce->sh = NULL;
384  }
385  GNUNET_free (ce);
386 }
void REGEX_INTERNAL_announce_cancel(struct REGEX_INTERNAL_Announcement *h)
Clear all cached data used by a regex announce.
struct REGEX_INTERNAL_Announcement * ah
Announcement handle (if this client is announcing).
struct REGEX_INTERNAL_Search * sh
Search handle (if this client is searching).
Information about one of our clients.
struct GNUNET_SCHEDULER_Task * refresh_task
Task for re-announcing.
void REGEX_INTERNAL_search_cancel(struct REGEX_INTERNAL_Search *h)
Cancel an ongoing regex search in the DHT and free all resources.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( "regex"  ,
GNUNET_SERVICE_OPTION_NONE  ,
run,
client_connect_cb,
client_disconnect_cb,
NULL  ,
GNUNET_MQ_hd_var_size(announce, GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE, struct AnnounceMessage, NULL)  ,
GNUNET_MQ_hd_var_size(search, GNUNET_MESSAGE_TYPE_REGEX_SEARCH, struct RegexSearchMessage, NULL)  ,
GNUNET_MQ_handler_end()   
)

Define "main" method using service macro.

Referenced by client_disconnect_cb().

Here is the caller graph for this function:

Variable Documentation

◆ dht

struct GNUNET_DHT_Handle* dht
static

Connection to the DHT.

Definition at line 73 of file gnunet-service-regex.c.

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

Handle for doing statistics.

Definition at line 78 of file gnunet-service-regex.c.

◆ my_private_key

struct GNUNET_CRYPTO_EddsaPrivateKey* my_private_key
static

Private key for this peer.

Definition at line 83 of file gnunet-service-regex.c.