aboutsummaryrefslogtreecommitdiff
path: root/src/peerinfo
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-06-16 11:26:01 +0000
committerChristian Grothoff <christian@grothoff.org>2011-06-16 11:26:01 +0000
commita25e91fe64981bad87d8a2a438b87a60a86041a3 (patch)
tree4ac54fe958c87175fc37edc09c89f0fdac603532 /src/peerinfo
parent66aac17afcd7e0ea706cfd4ca0d91892d10dadcc (diff)
downloadgnunet-a25e91fe64981bad87d8a2a438b87a60a86041a3.tar.gz
gnunet-a25e91fe64981bad87d8a2a438b87a60a86041a3.zip
make code more tolerant to re-connect failures, i.e. due to being out of sockets
Diffstat (limited to 'src/peerinfo')
-rw-r--r--src/peerinfo/peerinfo_api.c96
1 files changed, 77 insertions, 19 deletions
diff --git a/src/peerinfo/peerinfo_api.c b/src/peerinfo/peerinfo_api.c
index 95745a2bd..4db776b55 100644
--- a/src/peerinfo/peerinfo_api.c
+++ b/src/peerinfo/peerinfo_api.c
@@ -111,6 +111,11 @@ struct GNUNET_PEERINFO_Handle
111 struct GNUNET_CLIENT_TransmitHandle *th; 111 struct GNUNET_CLIENT_TransmitHandle *th;
112 112
113 /** 113 /**
114 * ID for a reconnect task.
115 */
116 GNUNET_SCHEDULER_TaskIdentifier r_task;
117
118 /**
114 * Set to GNUNET_YES if we are currently receiving replies from the 119 * Set to GNUNET_YES if we are currently receiving replies from the
115 * service. 120 * service.
116 */ 121 */
@@ -129,14 +134,10 @@ struct GNUNET_PEERINFO_Handle
129struct GNUNET_PEERINFO_Handle * 134struct GNUNET_PEERINFO_Handle *
130GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) 135GNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
131{ 136{
132 struct GNUNET_CLIENT_Connection *client;
133 struct GNUNET_PEERINFO_Handle *ret; 137 struct GNUNET_PEERINFO_Handle *ret;
134 138
135 client = GNUNET_CLIENT_connect ("peerinfo", cfg);
136 if (client == NULL)
137 return NULL;
138 ret = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle)); 139 ret = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_Handle));
139 ret->client = client; 140 ret->client = GNUNET_CLIENT_connect ("peerinfo", cfg);
140 ret->cfg = cfg; 141 ret->cfg = cfg;
141 return ret; 142 return ret;
142} 143}
@@ -170,7 +171,16 @@ GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
170 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 171 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
171 h->th = NULL; 172 h->th = NULL;
172 } 173 }
173 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); 174 if (NULL != h->client)
175 {
176 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
177 h->client = NULL;
178 }
179 if (GNUNET_SCHEDULER_NO_TASK != h->r_task)
180 {
181 GNUNET_SCHEDULER_cancel (h->r_task);
182 h->r_task = GNUNET_SCHEDULER_NO_TASK;
183 }
174 GNUNET_free (h); 184 GNUNET_free (h);
175} 185}
176 186
@@ -191,12 +201,57 @@ trigger_transmit (struct GNUNET_PEERINFO_Handle *h);
191 * @param h handle to the service 201 * @param h handle to the service
192 */ 202 */
193static void 203static void
204reconnect (struct GNUNET_PEERINFO_Handle *h);
205
206/**
207 * Task scheduled to re-try connecting to the peerinfo service.
208 *
209 * @param cls the 'struct GNUNET_PEERINFO_Handle'
210 * @param ts scheduler context
211 */
212static void
213reconnect_task (void *cls,
214 const struct GNUNET_SCHEDULER_TaskContext *tc)
215{
216 struct GNUNET_PEERINFO_Handle *h = cls;
217
218 h->r_task = GNUNET_SCHEDULER_NO_TASK;
219 reconnect (h);
220}
221
222
223/**
224 * Close the existing connection to PEERINFO and reconnect.
225 *
226 * @param h handle to the service
227 */
228static void
194reconnect (struct GNUNET_PEERINFO_Handle *h) 229reconnect (struct GNUNET_PEERINFO_Handle *h)
195{ 230{
196 GNUNET_CLIENT_disconnect (h->client, GNUNET_SYSERR); 231 if (h->r_task != GNUNET_SCHEDULER_NO_TASK)
197 h->th = NULL; 232 {
233 GNUNET_SCHEDULER_cancel (h->r_task);
234 h->r_task = GNUNET_SCHEDULER_NO_TASK;
235 }
236 if (NULL != h->th)
237 {
238 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
239 h->th = NULL;
240 }
241 if (NULL != h->client)
242 {
243 GNUNET_CLIENT_disconnect (h->client, GNUNET_SYSERR);
244 h->client = NULL;
245 }
198 h->client = GNUNET_CLIENT_connect ("peerinfo", h->cfg); 246 h->client = GNUNET_CLIENT_connect ("peerinfo", h->cfg);
199 GNUNET_assert (h->client != NULL); 247 if (NULL == h->client)
248 {
249 h->r_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
250 &reconnect_task,
251 h);
252 return;
253 }
254 trigger_transmit (h);
200} 255}
201 256
202 257
@@ -227,7 +282,6 @@ do_transmit (void *cls, size_t size, void *buf)
227 h->tq_tail, 282 h->tq_tail,
228 tqe); 283 tqe);
229 reconnect (h); 284 reconnect (h);
230 trigger_transmit (h);
231 if (tqe != NULL) 285 if (tqe != NULL)
232 { 286 {
233 if (tqe->cont != NULL) 287 if (tqe->cont != NULL)
@@ -278,6 +332,11 @@ trigger_transmit (struct GNUNET_PEERINFO_Handle *h)
278 return; 332 return;
279 if (h->in_receive == GNUNET_YES) 333 if (h->in_receive == GNUNET_YES)
280 return; 334 return;
335 if (NULL == h->client)
336 {
337 reconnect (h);
338 return;
339 }
281 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, 340 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client,
282 tqe->size, 341 tqe->size,
283 GNUNET_TIME_absolute_get_remaining (tqe->timeout), 342 GNUNET_TIME_absolute_get_remaining (tqe->timeout),
@@ -375,7 +434,8 @@ struct GNUNET_PEERINFO_IteratorContext
375 * @param msg message received, NULL on timeout or fatal error 434 * @param msg message received, NULL on timeout or fatal error
376 */ 435 */
377static void 436static void
378peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg) 437peerinfo_handler (void *cls,
438 const struct GNUNET_MessageHeader *msg)
379{ 439{
380 struct GNUNET_PEERINFO_IteratorContext *ic = cls; 440 struct GNUNET_PEERINFO_IteratorContext *ic = cls;
381 const struct InfoMessage *im; 441 const struct InfoMessage *im;
@@ -391,7 +451,6 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
391 "PEERINFO"); 451 "PEERINFO");
392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", err_msg); 452 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", err_msg);
393 reconnect (ic->h); 453 reconnect (ic->h);
394 trigger_transmit (ic->h);
395 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 454 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
396 GNUNET_SCHEDULER_cancel (ic->timeout_task); 455 GNUNET_SCHEDULER_cancel (ic->timeout_task);
397 if (ic->callback != NULL) 456 if (ic->callback != NULL)
@@ -424,7 +483,6 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
424 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,err_msg); 483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,err_msg);
425 GNUNET_break (0); 484 GNUNET_break (0);
426 reconnect (ic->h); 485 reconnect (ic->h);
427 trigger_transmit (ic->h);
428 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 486 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
429 GNUNET_SCHEDULER_cancel (ic->timeout_task); 487 GNUNET_SCHEDULER_cancel (ic->timeout_task);
430 if (ic->callback != NULL) 488 if (ic->callback != NULL)
@@ -441,18 +499,19 @@ peerinfo_handler (void *cls, const struct GNUNET_MessageHeader *msg)
441 hello = (const struct GNUNET_HELLO_Message *) &im[1]; 499 hello = (const struct GNUNET_HELLO_Message *) &im[1];
442 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello)) 500 if (ms != sizeof (struct InfoMessage) + GNUNET_HELLO_size (hello))
443 { 501 {
444 char * err_msg; 502 char * err_msg;
445 GNUNET_asprintf(&err_msg,_("Received invalid message from `%s' service.\n"),"PEERINFO"); 503 GNUNET_asprintf (&err_msg,
446 GNUNET_break (0); 504 _("Received invalid message from `%s' service.\n"),
505 "PEERINFO");
506 GNUNET_break (0);
447 reconnect (ic->h); 507 reconnect (ic->h);
448 trigger_transmit (ic->h);
449 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK) 508 if (ic->timeout_task != GNUNET_SCHEDULER_NO_TASK)
450 GNUNET_SCHEDULER_cancel (ic->timeout_task); 509 GNUNET_SCHEDULER_cancel (ic->timeout_task);
451 if (ic->callback != NULL) 510 if (ic->callback != NULL)
452 ic->callback (ic->callback_cls, NULL, NULL, err_msg); 511 ic->callback (ic->callback_cls, NULL, NULL, err_msg);
453 GNUNET_free (ic); 512 GNUNET_free (ic);
454 GNUNET_free (err_msg); 513 GNUNET_free (err_msg);
455 return; 514 return;
456 } 515 }
457 } 516 }
458#if DEBUG_PEERINFO 517#if DEBUG_PEERINFO
@@ -497,7 +556,6 @@ iterator_start_receive (void *cls,
497 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK; 556 ic->timeout_task = GNUNET_SCHEDULER_NO_TASK;
498 } 557 }
499 reconnect (ic->h); 558 reconnect (ic->h);
500 trigger_transmit (ic->h);
501 if (ic->callback != NULL) 559 if (ic->callback != NULL)
502 ic->callback (ic->callback_cls, NULL, NULL, err_msg); 560 ic->callback (ic->callback_cls, NULL, NULL, err_msg);
503 GNUNET_free (err_msg); 561 GNUNET_free (err_msg);