diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-06-25 15:37:04 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-06-25 15:37:04 +0000 |
commit | 789c62896357697e70bc477bf2ebfc33786d580c (patch) | |
tree | 31b8be842e6e58c300b173363c3d9954681c19b5 /src/namestore | |
parent | bc09b870c221f1d9c3c61b8ee251fa0f25c7aa22 (diff) | |
download | gnunet-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.c | 249 |
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 | */ |
94 | static size_t | 86 | static void |
95 | transmit_monitor_message (void *cls, | 87 | reconnect (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 | */ |
105 | static void | 96 | static void |
106 | reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm) | 97 | handle_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 | */ |
130 | static void | 114 | static int |
131 | handle_updates (void *cls, | 115 | check_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 | */ | ||
172 | static void | ||
173 | handle_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 | */ |
222 | static size_t | 213 | static void |
223 | transmit_monitor_message (void *cls, | 214 | mq_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 | */ | ||
228 | static void | ||
229 | reconnect (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 | |||
301 | void | 319 | void |
302 | GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm) | 320 | GNUNET_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 | ||