glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / regex / regex_api_announce.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2012, 2013, 2016 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14 */
15 /**
16  * @file regex/regex_api_announce.c
17  * @brief access regex service to advertise capabilities via regex
18  * @author Maximilian Szengel
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_protocols.h"
23 #include "gnunet_util_lib.h"
24 #include "gnunet_regex_service.h"
25 #include "regex_ipc.h"
26
27 #define LOG(kind,...) GNUNET_log_from (kind, "regex-api",__VA_ARGS__)
28
29 /**
30  * Handle to store cached data about a regex announce.
31  */
32 struct GNUNET_REGEX_Announcement
33 {
34   /**
35    * Connection to the regex service.
36    */
37   struct GNUNET_MQ_Handle *mq;
38
39   /**
40    * Our configuration.
41    */
42   const struct GNUNET_CONFIGURATION_Handle *cfg;
43
44   /**
45    * Message we're sending to the service.
46    */
47   char *regex;
48
49   /**
50    * Frequency of announcements.
51    */
52   struct GNUNET_TIME_Relative refresh_delay;
53
54   /**
55    * Number of characters per edge.
56    */
57   uint16_t compression;
58 };
59
60
61
62 /**
63  * (Re)connect to the REGEX service with the given announcement @a a.
64  *
65  * @param a REGEX to announce.
66  */
67 static void
68 announce_reconnect (struct GNUNET_REGEX_Announcement *a);
69
70
71 /**
72  * We got a disconnect after asking regex to do the announcement.
73  * Retry.
74  *
75  * @param cls the `struct GNUNET_REGEX_Announcement` to retry
76  * @param error error code
77  */
78 static void
79 announce_mq_error_handler (void *cls,
80                            enum GNUNET_MQ_Error error)
81 {
82   struct GNUNET_REGEX_Announcement *a = cls;
83
84   GNUNET_MQ_destroy (a->mq);
85   a->mq = NULL;
86   announce_reconnect (a);
87 }
88
89
90 /**
91  * (Re)connect to the REGEX service with the given announcement @a a.
92  *
93  * @param a REGEX to announce.
94  */
95 static void
96 announce_reconnect (struct GNUNET_REGEX_Announcement *a)
97 {
98   struct GNUNET_MQ_Envelope *env;
99   struct AnnounceMessage *am;
100   size_t slen;
101
102   a->mq = GNUNET_CLIENT_connect (a->cfg,
103                                  "regex",
104                                  NULL,
105                                  &announce_mq_error_handler,
106                                  a);
107   if (NULL == a->mq)
108     return;
109   slen = strlen (a->regex) + 1;
110   env = GNUNET_MQ_msg_extra (am,
111                              slen,
112                              GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE);
113   am->compression = htons (a->compression);
114   am->reserved = htons (0);
115   am->refresh_delay = GNUNET_TIME_relative_hton (a->refresh_delay);
116   GNUNET_memcpy (&am[1],
117           a->regex,
118           slen);
119   GNUNET_MQ_send (a->mq,
120                   env);
121 }
122
123
124 /**
125  * Announce the given peer under the given regular expression.
126  *
127  * @param cfg configuration to use
128  * @param regex Regular expression to announce.
129  * @param refresh_delay after what delay should the announcement be repeated?
130  * @param compression How many characters per edge can we squeeze?
131  * @return Handle to reuse o free cached resources.
132  *         Must be freed by calling #GNUNET_REGEX_announce_cancel().
133  */
134 struct GNUNET_REGEX_Announcement *
135 GNUNET_REGEX_announce (const struct GNUNET_CONFIGURATION_Handle *cfg,
136                        const char *regex,
137                        struct GNUNET_TIME_Relative refresh_delay,
138                        uint16_t compression)
139 {
140   struct GNUNET_REGEX_Announcement *a;
141   size_t slen;
142
143   slen = strlen (regex) + 1;
144   if (slen + sizeof (struct AnnounceMessage) >= GNUNET_MAX_MESSAGE_SIZE)
145   {
146     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
147                 _("Regex `%s' is too long!\n"),
148                 regex);
149     GNUNET_break (0);
150     return NULL;
151   }
152   a = GNUNET_new (struct GNUNET_REGEX_Announcement);
153   a->cfg = cfg;
154   a->refresh_delay = refresh_delay;
155   a->compression = compression;
156   a->regex = GNUNET_strdup (regex);
157   announce_reconnect (a);
158   if (NULL == a->mq)
159   {
160     GNUNET_free (a->regex);
161     GNUNET_free (a);
162     return NULL;
163   }
164   return a;
165 }
166
167
168 /**
169  * Stop announcing the regex specified by the given handle.
170  *
171  * @param a handle returned by a previous #GNUNET_REGEX_announce() call.
172  */
173 void
174 GNUNET_REGEX_announce_cancel (struct GNUNET_REGEX_Announcement *a)
175 {
176   GNUNET_MQ_destroy (a->mq);
177   GNUNET_free (a->regex);
178   GNUNET_free (a);
179 }
180
181 /* end of regex_api_announce.c */