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