log: add \n
[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
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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
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   /**
40    * Connection to the regex service.
41    */
42   struct GNUNET_MQ_Handle *mq;
43
44   /**
45    * Our configuration.
46    */
47   const struct GNUNET_CONFIGURATION_Handle *cfg;
48
49   /**
50    * Message we're sending to the service.
51    */
52   char *regex;
53
54   /**
55    * Frequency of announcements.
56    */
57   struct GNUNET_TIME_Relative refresh_delay;
58
59   /**
60    * Number of characters per edge.
61    */
62   uint16_t compression;
63 };
64
65
66
67 /**
68  * (Re)connect to the REGEX service with the given announcement @a a.
69  *
70  * @param a REGEX to announce.
71  */
72 static void
73 announce_reconnect (struct GNUNET_REGEX_Announcement *a);
74
75
76 /**
77  * We got a disconnect after asking regex to do the announcement.
78  * Retry.
79  *
80  * @param cls the `struct GNUNET_REGEX_Announcement` to retry
81  * @param error error code
82  */
83 static void
84 announce_mq_error_handler (void *cls,
85                            enum GNUNET_MQ_Error error)
86 {
87   struct GNUNET_REGEX_Announcement *a = cls;
88
89   GNUNET_MQ_destroy (a->mq);
90   a->mq = NULL;
91   announce_reconnect (a);
92 }
93
94
95 /**
96  * (Re)connect to the REGEX service with the given announcement @a a.
97  *
98  * @param a REGEX to announce.
99  */
100 static void
101 announce_reconnect (struct GNUNET_REGEX_Announcement *a)
102 {
103   struct GNUNET_MQ_Envelope *env;
104   struct AnnounceMessage *am;
105   size_t slen;
106
107   a->mq = GNUNET_CLIENT_connecT (a->cfg,
108                                  "regex",
109                                  NULL,
110                                  &announce_mq_error_handler,
111                                  a);
112   if (NULL == a->mq)
113     return;
114   slen = strlen (a->regex) + 1;
115   env = GNUNET_MQ_msg_extra (am,
116                              slen,
117                              GNUNET_MESSAGE_TYPE_REGEX_ANNOUNCE);
118   am->compression = htons (a->compression);
119   am->reserved = htons (0);
120   am->refresh_delay = GNUNET_TIME_relative_hton (a->refresh_delay);
121   GNUNET_memcpy (&am[1],
122           a->regex,
123           slen);
124   GNUNET_MQ_send (a->mq,
125                   env);
126 }
127
128
129 /**
130  * Announce the given peer under the given regular expression.
131  *
132  * @param cfg configuration to use
133  * @param regex Regular expression to announce.
134  * @param refresh_delay after what delay should the announcement be repeated?
135  * @param compression How many characters per edge can we squeeze?
136  * @return Handle to reuse o free cached resources.
137  *         Must be freed by calling #GNUNET_REGEX_announce_cancel().
138  */
139 struct GNUNET_REGEX_Announcement *
140 GNUNET_REGEX_announce (const struct GNUNET_CONFIGURATION_Handle *cfg,
141                        const char *regex,
142                        struct GNUNET_TIME_Relative refresh_delay,
143                        uint16_t compression)
144 {
145   struct GNUNET_REGEX_Announcement *a;
146   size_t slen;
147
148   slen = strlen (regex) + 1;
149   if (slen + sizeof (struct AnnounceMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
150   {
151     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
152                 _("Regex `%s' is too long!\n"),
153                 regex);
154     GNUNET_break (0);
155     return NULL;
156   }
157   a = GNUNET_new (struct GNUNET_REGEX_Announcement);
158   a->cfg = cfg;
159   a->refresh_delay = refresh_delay;
160   a->compression = compression;
161   a->regex = GNUNET_strdup (regex);
162   announce_reconnect (a);
163   if (NULL == a->mq)
164   {
165     GNUNET_free (a->regex);
166     GNUNET_free (a);
167     return NULL;
168   }
169   return a;
170 }
171
172
173 /**
174  * Stop announcing the regex specified by the given handle.
175  *
176  * @param a handle returned by a previous #GNUNET_REGEX_announce() call.
177  */
178 void
179 GNUNET_REGEX_announce_cancel (struct GNUNET_REGEX_Announcement *a)
180 {
181   GNUNET_MQ_destroy (a->mq);
182   GNUNET_free (a->regex);
183   GNUNET_free (a);
184 }
185
186 /* end of regex_api_announce.c */