aboutsummaryrefslogtreecommitdiff
path: root/src/arm/gnunet-service-arm_interceptor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm/gnunet-service-arm_interceptor.c')
-rw-r--r--src/arm/gnunet-service-arm_interceptor.c1055
1 files changed, 497 insertions, 558 deletions
diff --git a/src/arm/gnunet-service-arm_interceptor.c b/src/arm/gnunet-service-arm_interceptor.c
index 8f4a4731c..b99b076da 100644
--- a/src/arm/gnunet-service-arm_interceptor.c
+++ b/src/arm/gnunet-service-arm_interceptor.c
@@ -153,12 +153,12 @@ struct ForwardedConnection
153 * Timeout for forwarding. 153 * Timeout for forwarding.
154 */ 154 */
155 struct GNUNET_TIME_Absolute timeout; 155 struct GNUNET_TIME_Absolute timeout;
156 156
157 /** 157 /**
158 * Current back-off value. 158 * Current back-off value.
159 */ 159 */
160 struct GNUNET_TIME_Relative back_off; 160 struct GNUNET_TIME_Relative back_off;
161 161
162 /** 162 /**
163 * Task that tries to initiate forwarding. 163 * Task that tries to initiate forwarding.
164 */ 164 */
@@ -243,10 +243,10 @@ addDefaultServicesToList (const char *services)
243 s = GNUNET_strdup (services); 243 s = GNUNET_strdup (services);
244 token = strtok (s, " "); 244 token = strtok (s, " ");
245 while (NULL != token) 245 while (NULL != token)
246 { 246 {
247 numDefaultServices++; 247 numDefaultServices++;
248 token = strtok (NULL, " "); 248 token = strtok (NULL, " ");
249 } 249 }
250 GNUNET_free (s); 250 GNUNET_free (s);
251 251
252 defaultServicesList = GNUNET_malloc (numDefaultServices * sizeof (char *)); 252 defaultServicesList = GNUNET_malloc (numDefaultServices * sizeof (char *));
@@ -254,10 +254,10 @@ addDefaultServicesToList (const char *services)
254 s = GNUNET_strdup (services); 254 s = GNUNET_strdup (services);
255 token = strtok (s, " "); 255 token = strtok (s, " ");
256 while (NULL != token) 256 while (NULL != token)
257 { 257 {
258 defaultServicesList[i++] = GNUNET_strdup (token); 258 defaultServicesList[i++] = GNUNET_strdup (token);
259 token = strtok (NULL, " "); 259 token = strtok (NULL, " ");
260 } 260 }
261 GNUNET_free (s); 261 GNUNET_free (s);
262 GNUNET_assert (i == numDefaultServices); 262 GNUNET_assert (i == numDefaultServices);
263} 263}
@@ -272,9 +272,10 @@ static int
272isInDefaultList (const char *serviceName) 272isInDefaultList (const char *serviceName)
273{ 273{
274 unsigned int i; 274 unsigned int i;
275
275 for (i = 0; i < numDefaultServices; i++) 276 for (i = 0; i < numDefaultServices; i++)
276 if (strcmp (serviceName, defaultServicesList[i]) == 0) 277 if (strcmp (serviceName, defaultServicesList[i]) == 0)
277 return GNUNET_YES; 278 return GNUNET_YES;
278 return GNUNET_NO; 279 return GNUNET_NO;
279} 280}
280 281
@@ -286,52 +287,45 @@ isInDefaultList (const char *serviceName)
286 * @param reason which direction to close 287 * @param reason which direction to close
287 */ 288 */
288static void 289static void
289closeClientAndServiceSockets (struct ForwardedConnection *fc, 290closeClientAndServiceSockets (struct ForwardedConnection *fc, int reason)
290 int reason)
291{ 291{
292 if (0 != (REASON_SERVICE_TO_CLIENT & reason)) 292 if (0 != (REASON_SERVICE_TO_CLIENT & reason))
293 { 293 {
294#if DEBUG_SERVICE_MANAGER 294#if DEBUG_SERVICE_MANAGER
295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
296 "Stopping forwarding from service to client\n"); 296 "Stopping forwarding from service to client\n");
297#endif 297#endif
298 if (fc->armClientSocket != NULL) 298 if (fc->armClientSocket != NULL)
299 GNUNET_NETWORK_socket_shutdown (fc->armClientSocket, 299 GNUNET_NETWORK_socket_shutdown (fc->armClientSocket, SHUT_WR);
300 SHUT_WR); 300 if (fc->armServiceSocket != NULL)
301 if (fc->armServiceSocket != NULL) 301 GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket, SHUT_RD);
302 GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket, 302 }
303 SHUT_RD); 303 if (0 != (REASON_CLIENT_TO_SERVICE & reason))
304 } 304 {
305 if (0 != (REASON_CLIENT_TO_SERVICE & reason))
306 {
307#if DEBUG_SERVICE_MANAGER 305#if DEBUG_SERVICE_MANAGER
308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 306 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
309 "Stopping forwarding from client to service\n"); 307 "Stopping forwarding from client to service\n");
310#endif 308#endif
311 if (fc->armClientSocket != NULL) 309 if (fc->armClientSocket != NULL)
312 GNUNET_NETWORK_socket_shutdown (fc->armClientSocket, 310 GNUNET_NETWORK_socket_shutdown (fc->armClientSocket, SHUT_RD);
313 SHUT_RD); 311 if (fc->armServiceSocket != NULL)
314 if (fc->armServiceSocket != NULL) 312 GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket, SHUT_WR);
315 GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket, 313 }
316 SHUT_WR);
317 }
318#if DEBUG_SERVICE_MANAGER 314#if DEBUG_SERVICE_MANAGER
319 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 315 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
320 "Closing forwarding connection (done with both directions)\n"); 316 "Closing forwarding connection (done with both directions)\n");
321#endif 317#endif
322 fc->reference_count -= 1; 318 fc->reference_count -= 1;
323 if (fc->reference_count <= 0) 319 if (fc->reference_count <= 0)
324 { 320 {
325 if ( (NULL != fc->armClientSocket) && 321 if ((NULL != fc->armClientSocket) &&
326 (GNUNET_SYSERR == 322 (GNUNET_SYSERR == GNUNET_NETWORK_socket_close (fc->armClientSocket)))
327 GNUNET_NETWORK_socket_close (fc->armClientSocket)) )
328 { 323 {
329 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close"); 324 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
330 fc->armClientSocket = NULL; 325 fc->armClientSocket = NULL;
331 } 326 }
332 if ( (NULL != fc->armServiceSocket) && 327 if ((NULL != fc->armServiceSocket) &&
333 (GNUNET_SYSERR == 328 (GNUNET_SYSERR == GNUNET_NETWORK_socket_close (fc->armServiceSocket)))
334 GNUNET_NETWORK_socket_close (fc->armServiceSocket)) )
335 { 329 {
336 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close"); 330 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
337 fc->armServiceSocket = NULL; 331 fc->armServiceSocket = NULL;
@@ -380,8 +374,7 @@ receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
380 * 374 *
381 */ 375 */
382static void 376static void
383start_forwarding (void *cls, 377start_forwarding (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
384 const struct GNUNET_SCHEDULER_TaskContext *tc);
385 378
386 379
387 380
@@ -399,54 +392,46 @@ forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
399 392
400 fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK; 393 fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
401 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready, 394 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready,
402 fc->armClientSocket)) 395 fc->armClientSocket))
403 { 396 {
404 fc->service_to_client_task = 397 fc->service_to_client_task =
405 GNUNET_SCHEDULER_add_write_net ( 398 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
406 GNUNET_TIME_UNIT_FOREVER_REL, 399 fc->armClientSocket,
407 fc->armClientSocket, 400 &forwardToClient, fc);
408 &forwardToClient, fc); 401 return;
409 return; 402 }
410 }
411 /* Forwarding service response to client */ 403 /* Forwarding service response to client */
412 numberOfBytesSent = 404 numberOfBytesSent =
413 GNUNET_NETWORK_socket_send (fc->armClientSocket, 405 GNUNET_NETWORK_socket_send (fc->armClientSocket,
414 fc->service_to_client_bufferPos, 406 fc->service_to_client_bufferPos,
415 fc->service_to_client_bufferDataLength); 407 fc->service_to_client_bufferDataLength);
416 if (numberOfBytesSent <= 0) 408 if (numberOfBytesSent <= 0)
417 { 409 {
418 if ( (errno != EPIPE) && 410 if ((errno != EPIPE) && (errno != ECONNRESET))
419 (errno != ECONNRESET) ) 411 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
420 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 412 "Failed to forward %u bytes of data to client: %s\n",
421 "Failed to forward %u bytes of data to client: %s\n", 413 fc->service_to_client_bufferDataLength, STRERROR (errno));
422 fc->service_to_client_bufferDataLength, 414 closeClientAndServiceSockets (fc, REASON_SERVICE_TO_CLIENT);
423 STRERROR (errno)); 415 return;
424 closeClientAndServiceSockets (fc, 416 }
425 REASON_SERVICE_TO_CLIENT);
426 return;
427 }
428#if DEBUG_SERVICE_MANAGER 417#if DEBUG_SERVICE_MANAGER
429 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
430 "Forwarded %d bytes to client\n", 419 "Forwarded %d bytes to client\n", numberOfBytesSent);
431 numberOfBytesSent);
432#endif 420#endif
433 if (numberOfBytesSent < fc->service_to_client_bufferDataLength) 421 if (numberOfBytesSent < fc->service_to_client_bufferDataLength)
434 { 422 {
435 fc->service_to_client_bufferPos += numberOfBytesSent; 423 fc->service_to_client_bufferPos += numberOfBytesSent;
436 fc->service_to_client_bufferDataLength -= numberOfBytesSent; 424 fc->service_to_client_bufferDataLength -= numberOfBytesSent;
437 fc->service_to_client_task = 425 fc->service_to_client_task =
438 GNUNET_SCHEDULER_add_write_net ( 426 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
439 GNUNET_TIME_UNIT_FOREVER_REL, 427 fc->armClientSocket,
440 fc->armClientSocket, 428 &forwardToClient, fc);
441 &forwardToClient, 429 return;
442 fc); 430 }
443 return;
444 }
445 fc->service_to_client_task = 431 fc->service_to_client_task =
446 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 432 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
447 fc->armServiceSocket, 433 fc->armServiceSocket,
448 &receiveFromService, 434 &receiveFromService, fc);
449 fc);
450} 435}
451 436
452 437
@@ -457,98 +442,92 @@ forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
457 * @param tc scheduler context 442 * @param tc scheduler context
458 */ 443 */
459static void 444static void
460receiveFromService (void *cls, 445receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
461 const struct GNUNET_SCHEDULER_TaskContext *tc)
462{ 446{
463 struct ForwardedConnection *fc = cls; 447 struct ForwardedConnection *fc = cls;
464 struct GNUNET_TIME_Relative rem; 448 struct GNUNET_TIME_Relative rem;
465 449
466 fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK; 450 fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
467 if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && 451 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
468 (fc->first_write_done != GNUNET_YES) ) 452 (fc->first_write_done != GNUNET_YES))
469 { 453 {
470 closeClientAndServiceSockets (fc, REASON_ERROR); 454 closeClientAndServiceSockets (fc, REASON_ERROR);
471 return; 455 return;
472 } 456 }
473 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready, 457 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready,
474 fc->armServiceSocket)) 458 fc->armServiceSocket))
475 { 459 {
476 fc->service_to_client_task = 460 fc->service_to_client_task =
477 GNUNET_SCHEDULER_add_read_net ( 461 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
478 GNUNET_TIME_UNIT_FOREVER_REL, 462 fc->armServiceSocket,
479 fc->armServiceSocket, 463 &receiveFromService, fc);
480 &receiveFromService, fc); 464 return;
481 return; 465 }
482 }
483 fc->service_to_client_bufferPos = fc->service_to_client_buffer; 466 fc->service_to_client_bufferPos = fc->service_to_client_buffer;
484 fc->service_to_client_bufferDataLength = 467 fc->service_to_client_bufferDataLength =
485 GNUNET_NETWORK_socket_recv (fc->armServiceSocket, 468 GNUNET_NETWORK_socket_recv (fc->armServiceSocket,
486 fc->service_to_client_buffer, 469 fc->service_to_client_buffer, BUFFER_SIZE);
487 BUFFER_SIZE);
488 if (fc->service_to_client_bufferDataLength <= 0) 470 if (fc->service_to_client_bufferDataLength <= 0)
489 { 471 {
490#if DEBUG_SERVICE_MANAGER 472#if DEBUG_SERVICE_MANAGER
491 if (fc->service_to_client_bufferDataLength == 0) 473 if (fc->service_to_client_bufferDataLength == 0)
492 { 474 {
493 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 475 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
494 "Service `%s' stopped sending data.\n", 476 "Service `%s' stopped sending data.\n",
495 fc->listen_info->serviceName); 477 fc->listen_info->serviceName);
496 } 478 }
497#endif 479#endif
498 if (fc->first_write_done != GNUNET_YES) 480 if (fc->first_write_done != GNUNET_YES)
499 { 481 {
500 fc->service_to_client_bufferDataLength = 0; 482 fc->service_to_client_bufferDataLength = 0;
501 GNUNET_break (GNUNET_OK == 483 GNUNET_break (GNUNET_OK ==
502 GNUNET_NETWORK_socket_close (fc->armServiceSocket)); 484 GNUNET_NETWORK_socket_close (fc->armServiceSocket));
503 fc->armServiceSocket = NULL; 485 fc->armServiceSocket = NULL;
504 if ( (fc->client_to_service_bufferDataLength > 0) && 486 if ((fc->client_to_service_bufferDataLength > 0) &&
505 (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) ) 487 (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK))
506 { 488 {
507 GNUNET_SCHEDULER_cancel (fc->client_to_service_task); 489 GNUNET_SCHEDULER_cancel (fc->client_to_service_task);
508 fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK; 490 fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
509 } 491 }
510 fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2); 492 fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
511#if DEBUG_SERVICE_MANAGER 493#if DEBUG_SERVICE_MANAGER
512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
513 "Failed to connected to service `%s' at `%s', will try again in %llu ms\n", 495 "Failed to connected to service `%s' at `%s', will try again in %llu ms\n",
514 fc->listen_info->serviceName, 496 fc->listen_info->serviceName,
515 GNUNET_a2s (fc->listen_info->service_addr, 497 GNUNET_a2s (fc->listen_info->service_addr,
516 fc->listen_info->service_addr_len), 498 fc->listen_info->service_addr_len),
517 (unsigned long long) GNUNET_TIME_relative_min (fc->back_off, 499 (unsigned long long) GNUNET_TIME_relative_min (fc->back_off,
518 rem).rel_value); 500 rem).rel_value);
519#endif 501#endif
520 rem = GNUNET_TIME_absolute_get_remaining (fc->timeout); 502 rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
521 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task); 503 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
522 fc->start_task 504 fc->start_task
523 = GNUNET_SCHEDULER_add_delayed ( 505 =
524 GNUNET_TIME_relative_min (fc->back_off, 506 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_min
525 rem), 507 (fc->back_off, rem), &start_forwarding,
526 &start_forwarding, 508 fc);
527 fc); 509 }
528 } 510 else
529 else 511 {
530 {
531#if DEBUG_SERVICE_MANAGER 512#if DEBUG_SERVICE_MANAGER
532 if (fc->service_to_client_bufferDataLength != 0) 513 if (fc->service_to_client_bufferDataLength != 0)
533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
534 "Error receiving from service: %s\n", 515 "Error receiving from service: %s\n", STRERROR (errno));
535 STRERROR (errno));
536#endif 516#endif
537 closeClientAndServiceSockets (fc, REASON_SERVICE_TO_CLIENT); 517 closeClientAndServiceSockets (fc, REASON_SERVICE_TO_CLIENT);
538 }
539 return;
540 } 518 }
519 return;
520 }
541 fc->first_write_done = GNUNET_YES; 521 fc->first_write_done = GNUNET_YES;
542#if DEBUG_SERVICE_MANAGER 522#if DEBUG_SERVICE_MANAGER
543 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
544 "Received %d bytes for client\n", 524 "Received %d bytes for client\n",
545 fc->service_to_client_bufferDataLength); 525 fc->service_to_client_bufferDataLength);
546#endif 526#endif
547 fc->service_to_client_task = 527 fc->service_to_client_task =
548 GNUNET_SCHEDULER_add_write_net ( 528 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
549 GNUNET_TIME_UNIT_FOREVER_REL, 529 fc->armClientSocket,
550 fc->armClientSocket, 530 &forwardToClient, fc);
551 &forwardToClient, fc);
552} 531}
553 532
554 533
@@ -559,98 +538,92 @@ receiveFromService (void *cls,
559 * @param tc scheduler context 538 * @param tc scheduler context
560 */ 539 */
561static void 540static void
562forwardToService (void *cls, 541forwardToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
563 const struct GNUNET_SCHEDULER_TaskContext *tc)
564{ 542{
565 struct ForwardedConnection *fc = cls; 543 struct ForwardedConnection *fc = cls;
566 ssize_t numberOfBytesSent; 544 ssize_t numberOfBytesSent;
567 struct GNUNET_TIME_Relative rem; 545 struct GNUNET_TIME_Relative rem;
568 546
569 fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK; 547 fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
570 if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) && 548 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) &&
571 (fc->first_write_done != GNUNET_YES) ) 549 (fc->first_write_done != GNUNET_YES))
572 { 550 {
573 closeClientAndServiceSockets (fc, REASON_ERROR); 551 closeClientAndServiceSockets (fc, REASON_ERROR);
574 return; 552 return;
575 } 553 }
576 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready, 554 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready,
577 fc->armServiceSocket)) 555 fc->armServiceSocket))
578 { 556 {
579 fc->client_to_service_task = 557 fc->client_to_service_task =
580 GNUNET_SCHEDULER_add_write_net ( 558 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
581 GNUNET_TIME_UNIT_FOREVER_REL, 559 fc->armServiceSocket,
582 fc->armServiceSocket, 560 &forwardToService, fc);
583 &forwardToService, fc); 561 return;
584 return; 562 }
585 }
586 numberOfBytesSent = 563 numberOfBytesSent =
587 GNUNET_NETWORK_socket_send (fc->armServiceSocket, 564 GNUNET_NETWORK_socket_send (fc->armServiceSocket,
588 fc->client_to_service_bufferPos, 565 fc->client_to_service_bufferPos,
589 fc->client_to_service_bufferDataLength); 566 fc->client_to_service_bufferDataLength);
590 if (numberOfBytesSent <= 0) 567 if (numberOfBytesSent <= 0)
568 {
569 if (GNUNET_YES != fc->first_write_done)
591 { 570 {
592 if (GNUNET_YES != fc->first_write_done) 571 GNUNET_break (GNUNET_OK ==
593 { 572 GNUNET_NETWORK_socket_close (fc->armServiceSocket));
594 GNUNET_break (GNUNET_OK == 573 fc->armServiceSocket = NULL;
595 GNUNET_NETWORK_socket_close (fc->armServiceSocket)); 574 if ((fc->service_to_client_bufferDataLength == 0) &&
596 fc->armServiceSocket = NULL; 575 (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK))
597 if ( (fc->service_to_client_bufferDataLength == 0) && 576 {
598 (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK) ) 577 GNUNET_SCHEDULER_cancel (fc->service_to_client_task);
599 { 578 fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK;
600 GNUNET_SCHEDULER_cancel (fc->service_to_client_task); 579 }
601 fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK; 580 fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
602 }
603 fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
604#if DEBUG_SERVICE_MANAGER 581#if DEBUG_SERVICE_MANAGER
605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
606 "Failed to connect to service `%s' at `%s', will try again in %llu ms\n", 583 "Failed to connect to service `%s' at `%s', will try again in %llu ms\n",
607 fc->listen_info->serviceName, 584 fc->listen_info->serviceName,
608 GNUNET_a2s (fc->listen_info->service_addr, 585 GNUNET_a2s (fc->listen_info->service_addr,
609 fc->listen_info->service_addr_len), 586 fc->listen_info->service_addr_len),
610 (unsigned long long) GNUNET_TIME_relative_min (fc->back_off, 587 (unsigned long long) GNUNET_TIME_relative_min (fc->back_off,
611 rem).rel_value); 588 rem).rel_value);
612#endif 589#endif
613 rem = GNUNET_TIME_absolute_get_remaining (fc->timeout); 590 rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
614 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task); 591 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
615 fc->start_task 592 fc->start_task
616 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_min (fc->back_off, 593 =
617 rem), 594 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_min
618 &start_forwarding, 595 (fc->back_off, rem), &start_forwarding,
619 fc); 596 fc);
620 } 597 }
621 else 598 else
622 { 599 {
623 if ( (errno != EPIPE) && 600 if ((errno != EPIPE) && (errno != ECONNRESET))
624 (errno != ECONNRESET) ) 601 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
625 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 602 "Failed to forward data to service: %s\n",
626 "Failed to forward data to service: %s\n", 603 STRERROR (errno));
627 STRERROR (errno)); 604 closeClientAndServiceSockets (fc, REASON_CLIENT_TO_SERVICE);
628 closeClientAndServiceSockets (fc,
629 REASON_CLIENT_TO_SERVICE);
630 }
631 return;
632 } 605 }
606 return;
607 }
633#if DEBUG_SERVICE_MANAGER 608#if DEBUG_SERVICE_MANAGER
634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 609 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
635 "Forwarded %d bytes to service\n", 610 "Forwarded %d bytes to service\n", numberOfBytesSent);
636 numberOfBytesSent);
637#endif 611#endif
638 fc->first_write_done = GNUNET_YES; 612 fc->first_write_done = GNUNET_YES;
639 if (numberOfBytesSent < fc->client_to_service_bufferDataLength) 613 if (numberOfBytesSent < fc->client_to_service_bufferDataLength)
640 { 614 {
641 fc->client_to_service_bufferPos += numberOfBytesSent; 615 fc->client_to_service_bufferPos += numberOfBytesSent;
642 fc->client_to_service_bufferDataLength -= numberOfBytesSent; 616 fc->client_to_service_bufferDataLength -= numberOfBytesSent;
643 fc->client_to_service_task = 617 fc->client_to_service_task =
644 GNUNET_SCHEDULER_add_write_net ( 618 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
645 GNUNET_TIME_UNIT_FOREVER_REL, 619 fc->armServiceSocket,
646 fc->armServiceSocket, 620 &forwardToService, fc);
647 &forwardToService, fc); 621 return;
648 return; 622 }
649 }
650 fc->client_to_service_task = 623 fc->client_to_service_task =
651 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 624 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
652 fc->armClientSocket, 625 fc->armClientSocket,
653 &receiveFromClient, fc); 626 &receiveFromClient, fc);
654} 627}
655 628
656 629
@@ -667,76 +640,73 @@ receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
667 640
668 fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK; 641 fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK;
669 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready, 642 if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready,
670 fc->armClientSocket)) 643 fc->armClientSocket))
671 { 644 {
672 fc->client_to_service_task = 645 fc->client_to_service_task =
673 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 646 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
674 fc->armClientSocket, 647 fc->armClientSocket,
675 &receiveFromClient, fc); 648 &receiveFromClient, fc);
676 return; 649 return;
677 } 650 }
678 fc->client_to_service_bufferPos = fc->client_to_service_buffer; 651 fc->client_to_service_bufferPos = fc->client_to_service_buffer;
679 fc->client_to_service_bufferDataLength = 652 fc->client_to_service_bufferDataLength =
680 GNUNET_NETWORK_socket_recv (fc->armClientSocket, 653 GNUNET_NETWORK_socket_recv (fc->armClientSocket,
681 fc->client_to_service_buffer, 654 fc->client_to_service_buffer, BUFFER_SIZE);
682 BUFFER_SIZE);
683 if (fc->client_to_service_bufferDataLength <= 0) 655 if (fc->client_to_service_bufferDataLength <= 0)
656 {
657 if (fc->client_to_service_bufferDataLength == 0)
684 { 658 {
685 if (fc->client_to_service_bufferDataLength == 0)
686 {
687#if DEBUG_SERVICE_MANAGER 659#if DEBUG_SERVICE_MANAGER
688 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
689 "Client closed connection with service `%s'\n", 661 "Client closed connection with service `%s'\n",
690 fc->listen_info->serviceName); 662 fc->listen_info->serviceName);
691#endif 663#endif
692 } 664 }
693 else 665 else
694 { 666 {
695#if DEBUG_SERVICE_MANAGER 667#if DEBUG_SERVICE_MANAGER
696 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 668 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
697 "Error receiving from client: %s\n", 669 "Error receiving from client: %s\n", STRERROR (errno));
698 STRERROR (errno));
699#endif 670#endif
700 }
701 closeClientAndServiceSockets (fc, REASON_CLIENT_TO_SERVICE);
702 return;
703 } 671 }
672 closeClientAndServiceSockets (fc, REASON_CLIENT_TO_SERVICE);
673 return;
674 }
704#if DEBUG_SERVICE_MANAGER 675#if DEBUG_SERVICE_MANAGER
705 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 676 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
706 "Received %d bytes for service\n", 677 "Received %d bytes for service\n",
707 fc->client_to_service_bufferDataLength); 678 fc->client_to_service_bufferDataLength);
708#endif 679#endif
709 if (fc->armServiceSocket != NULL) 680 if (fc->armServiceSocket != NULL)
710 fc->client_to_service_task = 681 fc->client_to_service_task =
711 GNUNET_SCHEDULER_add_write_net ( 682 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
712 GNUNET_TIME_UNIT_FOREVER_REL, 683 fc->armServiceSocket,
713 fc->armServiceSocket, 684 &forwardToService, fc);
714 &forwardToService, fc);
715 else 685 else
716 /* We have not added any task with fc as a closure, so we're 686 /* We have not added any task with fc as a closure, so we're
717 * dropping our reference to fc 687 * dropping our reference to fc
718 */ 688 */
719 fc->reference_count -= 1; 689 fc->reference_count -= 1;
720} 690}
721 691
722 692
723static void 693static void
724fc_acceptConnection (void *cls, 694fc_acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
725 const struct GNUNET_SCHEDULER_TaskContext *tc)
726{ 695{
727 struct ServiceListeningInfo *sli = cls; 696 struct ServiceListeningInfo *sli = cls;
728 struct ForwardedConnection *fc = sli->fc; 697 struct ForwardedConnection *fc = sli->fc;
729 698
730 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) 699 if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))
731 { 700 {
732 GNUNET_assert (GNUNET_OK == GNUNET_NETWORK_socket_close (sli->listeningSocket)); 701 GNUNET_assert (GNUNET_OK ==
733 closeClientAndServiceSockets (fc, REASON_ERROR); 702 GNUNET_NETWORK_socket_close (sli->listeningSocket));
734 GNUNET_free (sli); 703 closeClientAndServiceSockets (fc, REASON_ERROR);
735 return; 704 GNUNET_free (sli);
736 } 705 return;
706 }
737#if DEBUG_SERVICE_MANAGER 707#if DEBUG_SERVICE_MANAGER
738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 708 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
739 "Connected to service, now starting forwarding\n"); 709 "Connected to service, now starting forwarding\n");
740#endif 710#endif
741 fc->armServiceSocket = sli->listeningSocket; 711 fc->armServiceSocket = sli->listeningSocket;
742 GNUNET_free (fc->listen_info->service_addr); 712 GNUNET_free (fc->listen_info->service_addr);
@@ -749,72 +719,70 @@ fc_acceptConnection (void *cls,
749 */ 719 */
750 fc->reference_count -= 1; 720 fc->reference_count -= 1;
751 if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK) 721 if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK)
752 { 722 {
753 if (fc->client_to_service_bufferDataLength == 0) 723 if (fc->client_to_service_bufferDataLength == 0)
754 fc->client_to_service_task = 724 fc->client_to_service_task =
755 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 725 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
756 fc->armClientSocket, 726 fc->armClientSocket,
757 &receiveFromClient, fc); 727 &receiveFromClient, fc);
758 else 728 else
759 fc->client_to_service_task = 729 fc->client_to_service_task =
760 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 730 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
761 fc->armServiceSocket, 731 fc->armServiceSocket,
762 &forwardToService, fc); 732 &forwardToService, fc);
763 fc->reference_count += 1; 733 fc->reference_count += 1;
764 } 734 }
765 if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK) 735 if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK)
766 { 736 {
767 if (fc->service_to_client_bufferDataLength == 0) 737 if (fc->service_to_client_bufferDataLength == 0)
768 fc->service_to_client_task = 738 fc->service_to_client_task =
769 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 739 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
770 fc->armServiceSocket, 740 fc->armServiceSocket,
771 &receiveFromService, fc); 741 &receiveFromService, fc);
772 else 742 else
773 fc->service_to_client_task = 743 fc->service_to_client_task =
774 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 744 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
775 fc->armClientSocket, 745 fc->armClientSocket,
776 &forwardToClient, fc); 746 &forwardToClient, fc);
777 fc->reference_count += 1; 747 fc->reference_count += 1;
778 } 748 }
779 GNUNET_free (sli); 749 GNUNET_free (sli);
780} 750}
781 751
782 752
783static struct ServiceListeningInfo * 753static struct ServiceListeningInfo *
784service_try_to_connect (const struct sockaddr *addr, 754service_try_to_connect (const struct sockaddr *addr,
785 int pf, 755 int pf,
786 socklen_t addrlen, 756 socklen_t addrlen, struct ForwardedConnection *fc)
787 struct ForwardedConnection *fc)
788{ 757{
789 struct GNUNET_NETWORK_Handle *sock; 758 struct GNUNET_NETWORK_Handle *sock;
790 struct ServiceListeningInfo *serviceListeningInfo; 759 struct ServiceListeningInfo *serviceListeningInfo;
791 760
792 sock = GNUNET_NETWORK_socket_create (pf, SOCK_STREAM, 0); 761 sock = GNUNET_NETWORK_socket_create (pf, SOCK_STREAM, 0);
793 if (sock == NULL) 762 if (sock == NULL)
794 { 763 {
795 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); 764 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
796 return NULL; 765 return NULL;
797 } 766 }
798 if ( (GNUNET_SYSERR == GNUNET_NETWORK_socket_connect (sock, addr, addrlen)) && 767 if ((GNUNET_SYSERR == GNUNET_NETWORK_socket_connect (sock, addr, addrlen)) &&
799 (errno != EINPROGRESS) ) 768 (errno != EINPROGRESS))
800 { 769 {
801 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect"); 770 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect");
802 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 771 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
803 return NULL; 772 return NULL;
804 } 773 }
805 serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo)); 774 serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo));
806 serviceListeningInfo->serviceName = NULL; 775 serviceListeningInfo->serviceName = NULL;
807 serviceListeningInfo->service_addr = GNUNET_malloc (addrlen); 776 serviceListeningInfo->service_addr = GNUNET_malloc (addrlen);
808 memcpy (serviceListeningInfo->service_addr, 777 memcpy (serviceListeningInfo->service_addr, addr, addrlen);
809 addr,
810 addrlen);
811 serviceListeningInfo->service_addr_len = addrlen; 778 serviceListeningInfo->service_addr_len = addrlen;
812 serviceListeningInfo->listeningSocket = sock; 779 serviceListeningInfo->listeningSocket = sock;
813 serviceListeningInfo->fc = fc; 780 serviceListeningInfo->fc = fc;
814 serviceListeningInfo->acceptTask = 781 serviceListeningInfo->acceptTask =
815 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 782 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
816 serviceListeningInfo->listeningSocket, 783 serviceListeningInfo->listeningSocket,
817 &fc_acceptConnection, serviceListeningInfo); 784 &fc_acceptConnection,
785 serviceListeningInfo);
818 return serviceListeningInfo; 786 return serviceListeningInfo;
819} 787}
820 788
@@ -823,8 +791,7 @@ service_try_to_connect (const struct sockaddr *addr,
823 * 791 *
824 */ 792 */
825static void 793static void
826start_forwarding (void *cls, 794start_forwarding (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
827 const struct GNUNET_SCHEDULER_TaskContext *tc)
828{ 795{
829 struct ForwardedConnection *fc = cls; 796 struct ForwardedConnection *fc = cls;
830 struct ServiceListeningInfo *sc; 797 struct ServiceListeningInfo *sc;
@@ -835,91 +802,80 @@ start_forwarding (void *cls,
835 char listen_address[INET6_ADDRSTRLEN]; 802 char listen_address[INET6_ADDRSTRLEN];
836 803
837 fc->start_task = GNUNET_SCHEDULER_NO_TASK; 804 fc->start_task = GNUNET_SCHEDULER_NO_TASK;
838 if ( (NULL != tc) && 805 if ((NULL != tc) && (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)))
839 (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) ) 806 {
840 { 807 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
841 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 808 _("Unable to forward to service `%s': shutdown\n"),
842 _("Unable to forward to service `%s': shutdown\n"), 809 fc->listen_info->serviceName);
843 fc->listen_info->serviceName); 810 closeClientAndServiceSockets (fc, REASON_ERROR);
844 closeClientAndServiceSockets (fc, REASON_ERROR); 811 return;
845 return; 812 }
846 }
847 if (0 == GNUNET_TIME_absolute_get_remaining (fc->timeout).rel_value) 813 if (0 == GNUNET_TIME_absolute_get_remaining (fc->timeout).rel_value)
848 { 814 {
849 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 815 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
850 _("Unable to forward to service `%s': timeout before connect\n"), 816 _
851 fc->listen_info->serviceName); 817 ("Unable to forward to service `%s': timeout before connect\n"),
852 closeClientAndServiceSockets (fc, REASON_ERROR); 818 fc->listen_info->serviceName);
853 return; 819 closeClientAndServiceSockets (fc, REASON_ERROR);
854 } 820 return;
821 }
855 switch (fc->listen_info->service_addr->sa_family) 822 switch (fc->listen_info->service_addr->sa_family)
823 {
824 case AF_UNSPEC:
825 GNUNET_break (0);
826 closeClientAndServiceSockets (fc, REASON_ERROR);
827 return;
828 case AF_INET:
829 v4 = (const struct sockaddr_in *) fc->listen_info->service_addr;
830 inet_ntop (fc->listen_info->service_addr->sa_family,
831 (const void *) &v4->sin_addr, listen_address, INET_ADDRSTRLEN);
832 if (0 == strncmp (listen_address, "0.0.0.0", 7))
856 { 833 {
857 case AF_UNSPEC: 834 /* connect to [::1] and 127.0.0.1 instead of [::] and 0.0.0.0 */
858 GNUNET_break (0); 835 memset (&target_ipv4, 0, sizeof (target_ipv4));
859 closeClientAndServiceSockets (fc, REASON_ERROR); 836 GNUNET_assert (1 ==
860 return; 837 inet_pton (AF_INET, "127.0.0.1", &target_ipv4.sin_addr));
861 case AF_INET: 838 target_ipv4.sin_family = AF_INET;
862 v4 = (const struct sockaddr_in *) fc->listen_info->service_addr; 839 target_ipv4.sin_port = v4->sin_port;
863 inet_ntop (fc->listen_info->service_addr->sa_family, 840 v4 = &target_ipv4;
864 (const void *) &v4->sin_addr, 841 }
865 listen_address, 842 sc = service_try_to_connect ((const struct sockaddr *) v4,
866 INET_ADDRSTRLEN); 843 PF_INET, sizeof (struct sockaddr_in), fc);
867 if (0 == strncmp (listen_address, "0.0.0.0", 7)) 844 break;
868 { 845 case AF_INET6:
869 /* connect to [::1] and 127.0.0.1 instead of [::] and 0.0.0.0 */ 846 v6 = (struct sockaddr_in6 *) fc->listen_info->service_addr;
870 memset (&target_ipv4, 0, sizeof (target_ipv4)); 847 inet_ntop (fc->listen_info->service_addr->sa_family,
871 GNUNET_assert (1 == 848 (const void *) &v6->sin6_addr, listen_address, INET6_ADDRSTRLEN);
872 inet_pton (AF_INET, 849 if ((strncmp (listen_address, "[::]:", 5) == 0) ||
873 "127.0.0.1", 850 (strncmp (listen_address, "::", 2) == 0))
874 &target_ipv4.sin_addr));
875 target_ipv4.sin_family = AF_INET;
876 target_ipv4.sin_port = v4->sin_port;
877 v4 = &target_ipv4;
878 }
879 sc = service_try_to_connect ((const struct sockaddr*) v4,
880 PF_INET,
881 sizeof (struct sockaddr_in),
882 fc);
883 break;
884 case AF_INET6:
885 v6 = (struct sockaddr_in6 *)fc->listen_info->service_addr;
886 inet_ntop (fc->listen_info->service_addr->sa_family,
887 (const void *) &v6->sin6_addr,
888 listen_address,
889 INET6_ADDRSTRLEN);
890 if ( (strncmp (listen_address, "[::]:", 5) == 0) || (strncmp (listen_address, "::", 2) == 0) )
891 {
892 memset (&target_ipv6, 0, sizeof (target_ipv6));
893 target_ipv6.sin6_addr = in6addr_loopback;
894 target_ipv6.sin6_family = AF_INET6;
895 target_ipv6.sin6_port = v6->sin6_port;
896 v6 = &target_ipv6;
897 }
898 sc = service_try_to_connect ((const struct sockaddr*) v6,
899 PF_INET6,
900 sizeof (struct sockaddr_in6),
901 fc);
902 break;
903 case AF_UNIX:
904 sc = service_try_to_connect (fc->listen_info->service_addr,
905 PF_UNIX,
906 fc->listen_info->service_addr_len,
907 fc);
908 break;
909 default:
910 GNUNET_break (0);
911 closeClientAndServiceSockets (fc, REASON_ERROR);
912 return;
913 }
914 if (NULL == sc)
915 { 851 {
916 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 852 memset (&target_ipv6, 0, sizeof (target_ipv6));
917 _ ("Unable to start service `%s': %s\n"), 853 target_ipv6.sin6_addr = in6addr_loopback;
918 fc->listen_info->serviceName, 854 target_ipv6.sin6_family = AF_INET6;
919 STRERROR (errno)); 855 target_ipv6.sin6_port = v6->sin6_port;
920 closeClientAndServiceSockets (fc, REASON_ERROR); 856 v6 = &target_ipv6;
921 return;
922 } 857 }
858 sc = service_try_to_connect ((const struct sockaddr *) v6,
859 PF_INET6, sizeof (struct sockaddr_in6), fc);
860 break;
861 case AF_UNIX:
862 sc = service_try_to_connect (fc->listen_info->service_addr,
863 PF_UNIX,
864 fc->listen_info->service_addr_len, fc);
865 break;
866 default:
867 GNUNET_break (0);
868 closeClientAndServiceSockets (fc, REASON_ERROR);
869 return;
870 }
871 if (NULL == sc)
872 {
873 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
874 _("Unable to start service `%s': %s\n"),
875 fc->listen_info->serviceName, STRERROR (errno));
876 closeClientAndServiceSockets (fc, REASON_ERROR);
877 return;
878 }
923} 879}
924 880
925 881
@@ -932,27 +888,25 @@ stop_listening (const char *serviceName)
932 struct ServiceListeningInfo *pos; 888 struct ServiceListeningInfo *pos;
933 struct ServiceListeningInfo *next; 889 struct ServiceListeningInfo *next;
934 int ret; 890 int ret;
935 891
936 ret = GNUNET_NO; 892 ret = GNUNET_NO;
937 next = serviceListeningInfoList_head; 893 next = serviceListeningInfoList_head;
938 while (NULL != (pos = next)) 894 while (NULL != (pos = next))
939 { 895 {
940 next = pos->next; 896 next = pos->next;
941 if ( (serviceName != NULL) && 897 if ((serviceName != NULL) && (strcmp (pos->serviceName, serviceName) != 0))
942 (strcmp (pos->serviceName, serviceName) != 0) ) 898 continue;
943 continue; 899 if (pos->acceptTask != GNUNET_SCHEDULER_NO_TASK)
944 if (pos->acceptTask != GNUNET_SCHEDULER_NO_TASK) 900 GNUNET_SCHEDULER_cancel (pos->acceptTask);
945 GNUNET_SCHEDULER_cancel (pos->acceptTask); 901 GNUNET_break (GNUNET_OK ==
946 GNUNET_break (GNUNET_OK == 902 GNUNET_NETWORK_socket_close (pos->listeningSocket));
947 GNUNET_NETWORK_socket_close (pos->listeningSocket)); 903 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
948 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head, 904 serviceListeningInfoList_tail, pos);
949 serviceListeningInfoList_tail, 905 GNUNET_free (pos->serviceName);
950 pos); 906 GNUNET_free (pos->service_addr);
951 GNUNET_free (pos->serviceName); 907 GNUNET_free (pos);
952 GNUNET_free (pos->service_addr); 908 ret = GNUNET_OK;
953 GNUNET_free (pos); 909 }
954 ret = GNUNET_OK;
955 }
956 return ret; 910 return ret;
957} 911}
958 912
@@ -978,46 +932,44 @@ accept_and_forward (struct ServiceListeningInfo *serviceListeningInfo)
978 fc->service_to_client_bufferPos = fc->service_to_client_buffer; 932 fc->service_to_client_bufferPos = fc->service_to_client_buffer;
979 fc->client_to_service_bufferPos = fc->client_to_service_buffer; 933 fc->client_to_service_bufferPos = fc->client_to_service_buffer;
980 fc->client_addr_len = sizeof (fc->client_addr); 934 fc->client_addr_len = sizeof (fc->client_addr);
981 fc->armClientSocket = GNUNET_NETWORK_socket_accept (serviceListeningInfo->listeningSocket, 935 fc->armClientSocket =
982 (struct sockaddr*) fc->client_addr, 936 GNUNET_NETWORK_socket_accept (serviceListeningInfo->listeningSocket,
983 &fc->client_addr_len); 937 (struct sockaddr *) fc->client_addr,
938 &fc->client_addr_len);
984 if (NULL == fc->armClientSocket) 939 if (NULL == fc->armClientSocket)
985 { 940 {
986 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 941 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
987 _("Unable to accept connection for service `%s': %s\n"), 942 _("Unable to accept connection for service `%s': %s\n"),
988 serviceListeningInfo->serviceName, 943 serviceListeningInfo->serviceName, STRERROR (errno));
989 STRERROR (errno)); 944 GNUNET_free (fc);
990 GNUNET_free (fc); 945 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
991 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head, 946 serviceListeningInfoList_tail,
992 serviceListeningInfoList_tail, 947 serviceListeningInfo);
993 serviceListeningInfo); 948 serviceListeningInfo->acceptTask =
994 serviceListeningInfo->acceptTask = 949 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
995 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 950 serviceListeningInfo->listeningSocket,
996 serviceListeningInfo->listeningSocket, 951 &acceptConnection, serviceListeningInfo);
997 &acceptConnection, 952 return;
998 serviceListeningInfo); 953 }
999 return;
1000 }
1001 GNUNET_break (GNUNET_OK == 954 GNUNET_break (GNUNET_OK ==
1002 GNUNET_NETWORK_socket_close (serviceListeningInfo->listeningSocket)); 955 GNUNET_NETWORK_socket_close
956 (serviceListeningInfo->listeningSocket));
1003 start_service (NULL, serviceListeningInfo->serviceName, NULL); 957 start_service (NULL, serviceListeningInfo->serviceName, NULL);
1004 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 958 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1005 _("Service `%s' started\n"), 959 _("Service `%s' started\n"), fc->listen_info->serviceName);
1006 fc->listen_info->serviceName); 960 fc->timeout =
1007 fc->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_SERVICE_TIMEOUT); 961 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_SERVICE_TIMEOUT);
1008 fc->back_off = GNUNET_TIME_UNIT_MILLISECONDS; 962 fc->back_off = GNUNET_TIME_UNIT_MILLISECONDS;
1009 fc->client_to_service_task = 963 fc->client_to_service_task =
1010 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 964 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1011 fc->armClientSocket, 965 fc->armClientSocket,
1012 &receiveFromClient, fc); 966 &receiveFromClient, fc);
1013 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task); 967 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
1014 /* We're creating another chain of tasks for this fc that 968 /* We're creating another chain of tasks for this fc that
1015 * will have its own reference to it. 969 * will have its own reference to it.
1016 */ 970 */
1017 fc->reference_count += 1; 971 fc->reference_count += 1;
1018 fc->start_task 972 fc->start_task = GNUNET_SCHEDULER_add_now (&start_forwarding, fc);
1019 = GNUNET_SCHEDULER_add_now (&start_forwarding,
1020 fc);
1021} 973}
1022 974
1023 975
@@ -1042,59 +994,54 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1042 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) 994 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1043 return; 995 return;
1044 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head, 996 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
1045 serviceListeningInfoList_tail, 997 serviceListeningInfoList_tail, sli);
1046 sli);
1047#ifndef MINGW 998#ifndef MINGW
1048 use_lsocks = GNUNET_NO; 999 use_lsocks = GNUNET_NO;
1049 if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, 1000 if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg,
1050 sli->serviceName, 1001 sli->serviceName,
1051 "DISABLE_SOCKET_FORWARDING")) 1002 "DISABLE_SOCKET_FORWARDING"))
1052 use_lsocks = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1003 use_lsocks = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1053 sli->serviceName, 1004 sli->serviceName,
1054 "DISABLE_SOCKET_FORWARDING"); 1005 "DISABLE_SOCKET_FORWARDING");
1055#else 1006#else
1056 use_lsocks = GNUNET_YES; 1007 use_lsocks = GNUNET_YES;
1057#endif 1008#endif
1058 if (GNUNET_NO != use_lsocks) 1009 if (GNUNET_NO != use_lsocks)
1059 { 1010 {
1060 accept_and_forward (sli); 1011 accept_and_forward (sli);
1061 return; 1012 return;
1062 } 1013 }
1063 lsocks = NULL; 1014 lsocks = NULL;
1064 ls = 0; 1015 ls = 0;
1065 next = serviceListeningInfoList_head; 1016 next = serviceListeningInfoList_head;
1066 while (NULL != (pos = next)) 1017 while (NULL != (pos = next))
1018 {
1019 next = pos->next;
1020 if (0 == strcmp (pos->serviceName, sli->serviceName))
1067 { 1021 {
1068 next = pos->next; 1022 GNUNET_array_append (lsocks, ls,
1069 if (0 == strcmp (pos->serviceName, 1023 GNUNET_NETWORK_get_fd (pos->listeningSocket));
1070 sli->serviceName)) 1024 GNUNET_free (pos->listeningSocket); /* deliberately no closing! */
1071 { 1025 GNUNET_free (pos->service_addr);
1072 GNUNET_array_append (lsocks, ls, 1026 GNUNET_free (pos->serviceName);
1073 GNUNET_NETWORK_get_fd (pos->listeningSocket)); 1027 GNUNET_SCHEDULER_cancel (pos->acceptTask);
1074 GNUNET_free (pos->listeningSocket); /* deliberately no closing! */ 1028 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
1075 GNUNET_free (pos->service_addr); 1029 serviceListeningInfoList_tail, pos);
1076 GNUNET_free (pos->serviceName); 1030 GNUNET_free (pos);
1077 GNUNET_SCHEDULER_cancel (pos->acceptTask);
1078 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
1079 serviceListeningInfoList_tail,
1080 pos);
1081 GNUNET_free (pos);
1082 }
1083 } 1031 }
1084 GNUNET_array_append (lsocks, ls, 1032 }
1085 GNUNET_NETWORK_get_fd (sli->listeningSocket)); 1033 GNUNET_array_append (lsocks, ls,
1086 GNUNET_free (sli->listeningSocket); /* deliberately no closing! */ 1034 GNUNET_NETWORK_get_fd (sli->listeningSocket));
1035 GNUNET_free (sli->listeningSocket); /* deliberately no closing! */
1087 GNUNET_free (sli->service_addr); 1036 GNUNET_free (sli->service_addr);
1088 GNUNET_array_append (lsocks, ls, -1); 1037 GNUNET_array_append (lsocks, ls, -1);
1089 start_service (NULL, 1038 start_service (NULL, sli->serviceName, lsocks);
1090 sli->serviceName,
1091 lsocks);
1092 ls = 0; 1039 ls = 0;
1093 while (lsocks[ls] != -1) 1040 while (lsocks[ls] != -1)
1094 GNUNET_break (0 == close (lsocks[ls++])); 1041 GNUNET_break (0 == close (lsocks[ls++]));
1095 GNUNET_array_grow (lsocks, ls, 0); 1042 GNUNET_array_grow (lsocks, ls, 0);
1096 GNUNET_free (sli->serviceName); 1043 GNUNET_free (sli->serviceName);
1097 GNUNET_free (sli); 1044 GNUNET_free (sli);
1098} 1045}
1099 1046
1100 1047
@@ -1107,89 +1054,84 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1107 * @param serviceName the name of the service in question 1054 * @param serviceName the name of the service in question
1108 */ 1055 */
1109static void 1056static void
1110createListeningSocket(struct sockaddr *sa, socklen_t addr_len, 1057createListeningSocket (struct sockaddr *sa, socklen_t addr_len,
1111 const char *serviceName) 1058 const char *serviceName)
1112{ 1059{
1113 const static int on = 1; 1060 const static int on = 1;
1114 struct GNUNET_NETWORK_Handle *sock; 1061 struct GNUNET_NETWORK_Handle *sock;
1115 struct ServiceListeningInfo *serviceListeningInfo; 1062 struct ServiceListeningInfo *serviceListeningInfo;
1116 1063
1117 switch (sa->sa_family) 1064 switch (sa->sa_family)
1118 { 1065 {
1119 case AF_INET: 1066 case AF_INET:
1120 sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0); 1067 sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0);
1121 break; 1068 break;
1122 case AF_INET6: 1069 case AF_INET6:
1123 sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); 1070 sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
1124 break; 1071 break;
1125 case AF_UNIX: 1072 case AF_UNIX:
1126 if (strcmp(GNUNET_a2s (sa, addr_len), "@") == 0) /* Do not bind to blank UNIX path! */ 1073 if (strcmp (GNUNET_a2s (sa, addr_len), "@") == 0) /* Do not bind to blank UNIX path! */
1127 return;
1128 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
1129 break;
1130 default:
1131 GNUNET_break (0);
1132 sock = NULL;
1133 errno = EAFNOSUPPORT;
1134 break;
1135 }
1136 if (NULL == sock)
1137 {
1138 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1139 _("Unable to create socket for service `%s': %s\n"),
1140 serviceName,
1141 STRERROR (errno));
1142 GNUNET_free (sa);
1143 return; 1074 return;
1144 } 1075 sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
1076 break;
1077 default:
1078 GNUNET_break (0);
1079 sock = NULL;
1080 errno = EAFNOSUPPORT;
1081 break;
1082 }
1083 if (NULL == sock)
1084 {
1085 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1086 _("Unable to create socket for service `%s': %s\n"),
1087 serviceName, STRERROR (errno));
1088 GNUNET_free (sa);
1089 return;
1090 }
1145 if (GNUNET_NETWORK_socket_setsockopt 1091 if (GNUNET_NETWORK_socket_setsockopt
1146 (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK) 1092 (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
1147 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1093 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1148 "setsockopt"); 1094 "setsockopt");
1149#ifdef IPV6_V6ONLY 1095#ifdef IPV6_V6ONLY
1150 if ( (sa->sa_family == AF_INET6) && 1096 if ((sa->sa_family == AF_INET6) &&
1151 (GNUNET_NETWORK_socket_setsockopt 1097 (GNUNET_NETWORK_socket_setsockopt
1152 (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK)) 1098 (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)) != GNUNET_OK))
1153 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 1099 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1154 "setsockopt"); 1100 "setsockopt");
1155#endif 1101#endif
1156 1102
1157 if (GNUNET_NETWORK_socket_bind 1103 if (GNUNET_NETWORK_socket_bind
1158 (sock, (const struct sockaddr *) sa, addr_len) != GNUNET_OK) 1104 (sock, (const struct sockaddr *) sa, addr_len) != GNUNET_OK)
1159 { 1105 {
1160 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1106 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1161 _("Unable to bind listening socket for service `%s' to address `%s': %s\n"), 1107 _
1162 serviceName, 1108 ("Unable to bind listening socket for service `%s' to address `%s': %s\n"),
1163 GNUNET_a2s (sa, addr_len), 1109 serviceName, GNUNET_a2s (sa, addr_len), STRERROR (errno));
1164 STRERROR (errno)); 1110 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1165 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 1111 GNUNET_free (sa);
1166 GNUNET_free (sa); 1112 return;
1167 return; 1113 }
1168 }
1169 if (GNUNET_NETWORK_socket_listen (sock, 5) != GNUNET_OK) 1114 if (GNUNET_NETWORK_socket_listen (sock, 5) != GNUNET_OK)
1170 { 1115 {
1171 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 1116 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
1172 "listen"); 1117 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
1173 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); 1118 GNUNET_free (sa);
1174 GNUNET_free (sa); 1119 return;
1175 return; 1120 }
1176 }
1177 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1121 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1178 _("ARM now monitors connections to service `%s' at `%s'\n"), 1122 _("ARM now monitors connections to service `%s' at `%s'\n"),
1179 serviceName, 1123 serviceName, GNUNET_a2s (sa, addr_len));
1180 GNUNET_a2s (sa, addr_len));
1181 serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo)); 1124 serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo));
1182 serviceListeningInfo->serviceName = GNUNET_strdup (serviceName); 1125 serviceListeningInfo->serviceName = GNUNET_strdup (serviceName);
1183 serviceListeningInfo->service_addr = sa; 1126 serviceListeningInfo->service_addr = sa;
1184 serviceListeningInfo->service_addr_len = addr_len; 1127 serviceListeningInfo->service_addr_len = addr_len;
1185 serviceListeningInfo->listeningSocket = sock; 1128 serviceListeningInfo->listeningSocket = sock;
1186 serviceListeningInfo->acceptTask = 1129 serviceListeningInfo->acceptTask =
1187 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, sock, 1130 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, sock,
1188 &acceptConnection, 1131 &acceptConnection, serviceListeningInfo);
1189 serviceListeningInfo);
1190 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head, 1132 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
1191 serviceListeningInfoList_tail, 1133 serviceListeningInfoList_tail,
1192 serviceListeningInfo); 1134 serviceListeningInfo);
1193} 1135}
1194 1136
1195 1137
@@ -1204,22 +1146,20 @@ createListeningSocket(struct sockaddr *sa, socklen_t addr_len,
1204 */ 1146 */
1205static void 1147static void
1206checkPortNumberCB (void *cls, 1148checkPortNumberCB (void *cls,
1207 const char *section, 1149 const char *section, const char *option, const char *value)
1208 const char *option,
1209 const char *value)
1210{ 1150{
1211 struct sockaddr **addrs; 1151 struct sockaddr **addrs;
1212 socklen_t *addr_lens; 1152 socklen_t *addr_lens;
1213 int ret; 1153 int ret;
1214 unsigned int i; 1154 unsigned int i;
1215 1155
1216 if ( (strcasecmp (section, "arm") == 0) || 1156 if ((strcasecmp (section, "arm") == 0) ||
1217 (strcasecmp (option, "AUTOSTART") != 0) || 1157 (strcasecmp (option, "AUTOSTART") != 0) ||
1218 (strcasecmp (value, "YES") != 0) || 1158 (strcasecmp (value, "YES") != 0) ||
1219 (isInDefaultList (section) == GNUNET_YES) ) 1159 (isInDefaultList (section) == GNUNET_YES))
1220 return; 1160 return;
1221 if (0 >= (ret = GNUNET_SERVICE_get_server_addresses (section, cfg, &addrs, 1161 if (0 >= (ret = GNUNET_SERVICE_get_server_addresses (section, cfg, &addrs,
1222 &addr_lens))) 1162 &addr_lens)))
1223 return; 1163 return;
1224 /* this will free (or capture) addrs[i] */ 1164 /* this will free (or capture) addrs[i] */
1225 for (i = 0; i < ret; i++) 1165 for (i = 0; i < ret; i++)
@@ -1235,8 +1175,7 @@ checkPortNumberCB (void *cls,
1235 * @param configurationHandle configuration to use to get services 1175 * @param configurationHandle configuration to use to get services
1236 */ 1176 */
1237void 1177void
1238prepareServices (const struct GNUNET_CONFIGURATION_Handle 1178prepareServices (const struct GNUNET_CONFIGURATION_Handle *configurationHandle)
1239 *configurationHandle)
1240{ 1179{
1241 char *defaultServicesString; 1180 char *defaultServicesString;
1242 1181
@@ -1244,13 +1183,13 @@ prepareServices (const struct GNUNET_CONFIGURATION_Handle
1244 /* Split the default services into a list */ 1183 /* Split the default services into a list */
1245 if (GNUNET_OK == 1184 if (GNUNET_OK ==
1246 GNUNET_CONFIGURATION_get_value_string (cfg, "arm", "DEFAULTSERVICES", 1185 GNUNET_CONFIGURATION_get_value_string (cfg, "arm", "DEFAULTSERVICES",
1247 &defaultServicesString)) 1186 &defaultServicesString))
1248 { 1187 {
1249 addDefaultServicesToList (defaultServicesString); 1188 addDefaultServicesToList (defaultServicesString);
1250 GNUNET_free (defaultServicesString); 1189 GNUNET_free (defaultServicesString);
1251 } 1190 }
1252 /* Spot the services from the configuration and create a listening 1191 /* Spot the services from the configuration and create a listening
1253 socket for each */ 1192 * socket for each */
1254 GNUNET_CONFIGURATION_iterate (cfg, &checkPortNumberCB, NULL); 1193 GNUNET_CONFIGURATION_iterate (cfg, &checkPortNumberCB, NULL);
1255} 1194}
1256 1195