aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-25 15:37:04 +0000
committerChristian Grothoff <christian@grothoff.org>2016-06-25 15:37:04 +0000
commit789c62896357697e70bc477bf2ebfc33786d580c (patch)
tree31b8be842e6e58c300b173363c3d9954681c19b5 /src/namestore
parentbc09b870c221f1d9c3c61b8ee251fa0f25c7aa22 (diff)
downloadgnunet-789c62896357697e70bc477bf2ebfc33786d580c.tar.gz
gnunet-789c62896357697e70bc477bf2ebfc33786d580c.zip
convert namestore_api_monitor to MQ
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/namestore_api_monitor.c249
1 files changed, 133 insertions, 116 deletions
diff --git a/src/namestore/namestore_api_monitor.c b/src/namestore/namestore_api_monitor.c
index 9fd45600d..85131f9cc 100644
--- a/src/namestore/namestore_api_monitor.c
+++ b/src/namestore/namestore_api_monitor.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 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 6 it under the terms of the GNU General Public License as published
@@ -48,7 +48,7 @@ struct GNUNET_NAMESTORE_ZoneMonitor
48 /** 48 /**
49 * Handle to namestore service. 49 * Handle to namestore service.
50 */ 50 */
51 struct GNUNET_CLIENT_Connection *h; 51 struct GNUNET_MQ_Handle *mq;
52 52
53 /** 53 /**
54 * Function to call on events. 54 * Function to call on events.
@@ -61,16 +61,11 @@ struct GNUNET_NAMESTORE_ZoneMonitor
61 GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb; 61 GNUNET_NAMESTORE_RecordsSynchronizedCallback sync_cb;
62 62
63 /** 63 /**
64 * Closure for 'monitor' and 'sync_cb'. 64 * Closure for @e monitor and @e sync_cb.
65 */ 65 */
66 void *cls; 66 void *cls;
67 67
68 /** 68 /**
69 * Transmission handle to client.
70 */
71 struct GNUNET_CLIENT_TransmitHandle *th;
72
73 /**
74 * Monitored zone. 69 * Monitored zone.
75 */ 70 */
76 struct GNUNET_CRYPTO_EcdsaPrivateKey zone; 71 struct GNUNET_CRYPTO_EcdsaPrivateKey zone;
@@ -84,55 +79,42 @@ struct GNUNET_NAMESTORE_ZoneMonitor
84 79
85 80
86/** 81/**
87 * Send our request to start monitoring to the service. 82 * Reconnect to the namestore service.
88 * 83 *
89 * @param cls the monitor handle 84 * @param zm monitor to reconnect
90 * @param size number of bytes available in buf
91 * @param buf where to copy the message to the service
92 * @return number of bytes copied to buf
93 */ 85 */
94static size_t 86static void
95transmit_monitor_message (void *cls, 87reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm);
96 size_t size,
97 void *buf);
98 88
99 89
100/** 90/**
101 * Reconnect to the namestore service. 91 * Handle SYNC message from the namestore service.
102 * 92 *
103 * @param zm monitor to reconnect 93 * @param cls the monitor
94 * @param msg the sync message
104 */ 95 */
105static void 96static void
106reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm) 97handle_sync (void *cls,
98 const struct GNUNET_MessageHeader *msg)
107{ 99{
108 if (NULL != zm->h) 100 struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
109 GNUNET_CLIENT_disconnect (zm->h); 101
110 zm->monitor (zm->cls, 102 if (NULL != zm->sync_cb)
111 NULL, 103 zm->sync_cb (zm->cls);
112 NULL, 0, NULL);
113 GNUNET_assert (NULL != (zm->h = GNUNET_CLIENT_connect ("namestore", zm->cfg)));
114 zm->th = GNUNET_CLIENT_notify_transmit_ready (zm->h,
115 sizeof (struct ZoneMonitorStartMessage),
116 GNUNET_TIME_UNIT_FOREVER_REL,
117 GNUNET_YES,
118 &transmit_monitor_message,
119 zm);
120} 104}
121 105
122 106
123/** 107/**
124 * We've received a notification about a change to our zone. 108 * We've received a notification about a change to our zone.
125 * Forward to monitor callback. 109 * Check that it is well-formed.
126 * 110 *
127 * @param cls the zone monitor handle 111 * @param cls the zone monitor handle
128 * @param msg the message from the service. 112 * @param lrm the message from the service.
129 */ 113 */
130static void 114static int
131handle_updates (void *cls, 115check_result (void *cls,
132 const struct GNUNET_MessageHeader *msg) 116 const struct RecordResultMessage *lrm)
133{ 117{
134 struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
135 const struct RecordResultMessage *lrm;
136 size_t lrm_len; 118 size_t lrm_len;
137 size_t exp_lrm_len; 119 size_t exp_lrm_len;
138 size_t name_len; 120 size_t name_len;
@@ -141,30 +123,6 @@ handle_updates (void *cls,
141 const char *name_tmp; 123 const char *name_tmp;
142 const char *rd_ser_tmp; 124 const char *rd_ser_tmp;
143 125
144 if (NULL == msg)
145 {
146 reconnect (zm);
147 return;
148 }
149 if ( (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader)) &&
150 (GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC == ntohs (msg->type) ) )
151 {
152 GNUNET_CLIENT_receive (zm->h,
153 &handle_updates,
154 zm,
155 GNUNET_TIME_UNIT_FOREVER_REL);
156 if (NULL != zm->sync_cb)
157 zm->sync_cb (zm->cls);
158 return;
159 }
160 if ( (ntohs (msg->size) < sizeof (struct RecordResultMessage)) ||
161 (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT != ntohs (msg->type) ) )
162 {
163 GNUNET_break (0);
164 reconnect (zm);
165 return;
166 }
167 lrm = (const struct RecordResultMessage *) msg;
168 lrm_len = ntohs (lrm->gns_header.header.size); 126 lrm_len = ntohs (lrm->gns_header.header.size);
169 rd_len = ntohs (lrm->rd_len); 127 rd_len = ntohs (lrm->rd_len);
170 rd_count = ntohs (lrm->rd_count); 128 rd_count = ntohs (lrm->rd_count);
@@ -173,79 +131,143 @@ handle_updates (void *cls,
173 if (lrm_len != exp_lrm_len) 131 if (lrm_len != exp_lrm_len)
174 { 132 {
175 GNUNET_break (0); 133 GNUNET_break (0);
176 reconnect (zm); 134 return GNUNET_SYSERR;
177 return;
178 } 135 }
179 if (0 == name_len) 136 if (0 == name_len)
180 { 137 {
181 GNUNET_break (0); 138 GNUNET_break (0);
182 reconnect (zm); 139 return GNUNET_SYSERR;
183 return;
184 } 140 }
185 name_tmp = (const char *) &lrm[1]; 141 name_tmp = (const char *) &lrm[1];
186 if ((name_tmp[name_len -1] != '\0') || (name_len > MAX_NAME_LEN)) 142 if ((name_tmp[name_len -1] != '\0') || (name_len > MAX_NAME_LEN))
187 { 143 {
188 GNUNET_break (0); 144 GNUNET_break (0);
189 reconnect (zm); 145 return GNUNET_SYSERR;
190 return;
191 } 146 }
192 rd_ser_tmp = (const char *) &name_tmp[name_len]; 147 rd_ser_tmp = (const char *) &name_tmp[name_len];
193 { 148 {
194 struct GNUNET_GNSRECORD_Data rd[rd_count]; 149 struct GNUNET_GNSRECORD_Data rd[rd_count];
195 150
196 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd)) 151 if (GNUNET_OK !=
152 GNUNET_GNSRECORD_records_deserialize (rd_len,
153 rd_ser_tmp,
154 rd_count,
155 rd))
197 { 156 {
198 GNUNET_break (0); 157 GNUNET_break (0);
199 reconnect (zm); 158 return GNUNET_SYSERR;
200 return;
201 } 159 }
202 GNUNET_CLIENT_receive (zm->h, 160 }
203 &handle_updates, 161 return GNUNET_OK;
204 zm, 162}
205 GNUNET_TIME_UNIT_FOREVER_REL); 163
164
165/**
166 * We've received a notification about a change to our zone.
167 * Forward to monitor callback.
168 *
169 * @param cls the zone monitor handle
170 * @param lrm the message from the service.
171 */
172static void
173handle_result (void *cls,
174 const struct RecordResultMessage *lrm)
175{
176 struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
177 size_t name_len;
178 size_t rd_len;
179 unsigned rd_count;
180 const char *name_tmp;
181 const char *rd_ser_tmp;
182
183 rd_len = ntohs (lrm->rd_len);
184 rd_count = ntohs (lrm->rd_count);
185 name_len = ntohs (lrm->name_len);
186 name_tmp = (const char *) &lrm[1];
187 rd_ser_tmp = (const char *) &name_tmp[name_len];
188 {
189 struct GNUNET_GNSRECORD_Data rd[rd_count];
190
191 GNUNET_assert (GNUNET_OK ==
192 GNUNET_GNSRECORD_records_deserialize (rd_len,
193 rd_ser_tmp,
194 rd_count,
195 rd));
206 zm->monitor (zm->cls, 196 zm->monitor (zm->cls,
207 &lrm->private_key, 197 &lrm->private_key,
208 name_tmp, 198 name_tmp,
209 rd_count, rd); 199 rd_count,
200 rd);
210 } 201 }
211} 202}
212 203
213 204
214/** 205/**
215 * Send our request to start monitoring to the service. 206 * Generic error handler, called with the appropriate error code and
207 * the same closure specified at the creation of the message queue.
208 * Not every message queue implementation supports an error handler.
216 * 209 *
217 * @param cls the monitor handle 210 * @param cls closure with the `struct GNUNET_NAMESTORE_ZoneMonitor *`
218 * @param size number of bytes available in buf 211 * @param error error code
219 * @param buf where to copy the message to the service
220 * @return number of bytes copied to buf
221 */ 212 */
222static size_t 213static void
223transmit_monitor_message (void *cls, 214mq_error_handler (void *cls,
224 size_t size, 215 enum GNUNET_MQ_Error error)
225 void *buf)
226{ 216{
227 struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls; 217 struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
228 struct ZoneMonitorStartMessage sm;
229 218
230 zm->th = NULL; 219 reconnect (zm);
231 if (size < sizeof (struct ZoneMonitorStartMessage)) 220}
221
222
223/**
224 * Reconnect to the namestore service.
225 *
226 * @param zm monitor to reconnect
227 */
228static void
229reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm)
230{
231 GNUNET_MQ_hd_fixed_size (sync,
232 GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC,
233 struct GNUNET_MessageHeader);
234 GNUNET_MQ_hd_var_size (result,
235 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT,
236 struct RecordResultMessage);
237 struct GNUNET_MQ_MessageHandler handlers[] = {
238 make_sync_handler (zm),
239 make_result_handler (zm),
240 GNUNET_MQ_handler_end ()
241 };
242 struct GNUNET_MQ_Envelope *env;
243 struct ZoneMonitorStartMessage *sm;
244
245 if (NULL != zm->mq)
232 { 246 {
233 reconnect (zm); 247 GNUNET_MQ_destroy (zm->mq);
234 return 0; 248 zm->monitor (zm->cls,
249 NULL,
250 NULL,
251 0,
252 NULL);
235 } 253 }
236 sm.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START); 254 zm->mq = GNUNET_CLIENT_connecT (zm->cfg,
237 sm.header.size = htons (sizeof (struct ZoneMonitorStartMessage)); 255 "namestore",
238 sm.iterate_first = htonl (zm->iterate_first); 256 handlers,
239 sm.zone = zm->zone; 257 &mq_error_handler,
240 memcpy (buf, &sm, sizeof (sm)); 258 zm);
241 GNUNET_CLIENT_receive (zm->h, 259 if (NULL == zm->mq)
242 &handle_updates, 260 return;
243 zm, 261 env = GNUNET_MQ_msg (sm,
244 GNUNET_TIME_UNIT_FOREVER_REL); 262 GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START);
245 return sizeof (sm); 263 sm->iterate_first = htonl (zm->iterate_first);
264 sm->zone = zm->zone;
265 GNUNET_MQ_send (zm->mq,
266 env);
246} 267}
247 268
248 269
270
249/** 271/**
250 * Begin monitoring a zone for changes. If @a iterate_first is set, 272 * Begin monitoring a zone for changes. If @a iterate_first is set,
251 * we Will first call the @a monitor function on all existing records 273 * we Will first call the @a monitor function on all existing records
@@ -270,25 +292,21 @@ GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *c
270 void *cls) 292 void *cls)
271{ 293{
272 struct GNUNET_NAMESTORE_ZoneMonitor *zm; 294 struct GNUNET_NAMESTORE_ZoneMonitor *zm;
273 struct GNUNET_CLIENT_Connection *client;
274 295
275 if (NULL == (client = GNUNET_CLIENT_connect ("namestore", cfg)))
276 return NULL;
277 zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor); 296 zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor);
278 zm->cfg = cfg;
279 zm->h = client;
280 if (NULL != zone) 297 if (NULL != zone)
281 zm->zone = *zone; 298 zm->zone = *zone;
282 zm->iterate_first = iterate_first; 299 zm->iterate_first = iterate_first;
283 zm->monitor = monitor; 300 zm->monitor = monitor;
284 zm->sync_cb = sync_cb; 301 zm->sync_cb = sync_cb;
285 zm->cls = cls; 302 zm->cls = cls;
286 zm->th = GNUNET_CLIENT_notify_transmit_ready (zm->h, 303 zm->cfg = cfg;
287 sizeof (struct ZoneMonitorStartMessage), 304 reconnect (zm);
288 GNUNET_TIME_UNIT_FOREVER_REL, 305 if (NULL == zm->mq)
289 GNUNET_YES, 306 {
290 &transmit_monitor_message, 307 GNUNET_free (zm);
291 zm); 308 return NULL;
309 }
292 return zm; 310 return zm;
293} 311}
294 312
@@ -301,12 +319,11 @@ GNUNET_NAMESTORE_zone_monitor_start (const struct GNUNET_CONFIGURATION_Handle *c
301void 319void
302GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm) 320GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm)
303{ 321{
304 if (NULL != zm->th) 322 if (NULL != zm->mq)
305 { 323 {
306 GNUNET_CLIENT_notify_transmit_ready_cancel (zm->th); 324 GNUNET_MQ_destroy (zm->mq);
307 zm->th = NULL; 325 zm->mq = NULL;
308 } 326 }
309 GNUNET_CLIENT_disconnect (zm->h);
310 GNUNET_free (zm); 327 GNUNET_free (zm);
311} 328}
312 329