diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-05-15 12:44:13 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-05-15 12:44:13 +0000 |
commit | 96df23b5f90ca2cbbd322eb05a544518075243aa (patch) | |
tree | 0a9ddc74ce31aa138efa5c6789bb7e9750877a8a /src/arm | |
parent | 0c202c803c33bd2ffac9f19a051e8e0bb757bd35 (diff) | |
download | gnunet-96df23b5f90ca2cbbd322eb05a544518075243aa.tar.gz gnunet-96df23b5f90ca2cbbd322eb05a544518075243aa.zip |
misc fixes
Diffstat (limited to 'src/arm')
-rw-r--r-- | src/arm/gnunet-service-arm.c | 51 | ||||
-rw-r--r-- | src/arm/gnunet-service-manager.c | 546 | ||||
-rw-r--r-- | src/arm/gnunet_service_arm_.h | 9 | ||||
-rw-r--r-- | src/arm/test_arm_api_data.conf | 28 | ||||
-rw-r--r-- | src/arm/test_gnunet_service_manager.c | 15 |
5 files changed, 396 insertions, 253 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index aa4f89bdb..a04d5407d 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2009, 2010 Christian Grothoff (and other contributing authors) |
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 |
@@ -24,10 +24,6 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | 25 | * |
26 | * TODO: | 26 | * TODO: |
27 | * - multiple start-stop requests with RC>1 can result | ||
28 | * in UP/DOWN signals based on "pending" that are inaccurate... | ||
29 | * => have list of clients waiting for a resolution instead of | ||
30 | * giving instant (but incorrect) replies | ||
31 | * - need to test auto-restart code on configuration changes; | 27 | * - need to test auto-restart code on configuration changes; |
32 | * - should refine restart code to check if *relevant* parts of the | 28 | * - should refine restart code to check if *relevant* parts of the |
33 | * configuration were changed (anything in the section for the service) | 29 | * configuration were changed (anything in the section for the service) |
@@ -115,15 +111,6 @@ struct ServiceList | |||
115 | */ | 111 | */ |
116 | struct GNUNET_TIME_Absolute restartAt; | 112 | struct GNUNET_TIME_Absolute restartAt; |
117 | 113 | ||
118 | #if RC | ||
119 | /** | ||
120 | * Reference counter (counts how many times we've been | ||
121 | * asked to start the service). We only actually stop | ||
122 | * it once rc hits zero. | ||
123 | */ | ||
124 | unsigned int rc; | ||
125 | #endif | ||
126 | |||
127 | }; | 114 | }; |
128 | 115 | ||
129 | /** | 116 | /** |
@@ -469,16 +456,11 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename) | |||
469 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); | 456 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
470 | return; | 457 | return; |
471 | } | 458 | } |
472 | stop_listening (servicename); | ||
473 | sl = find_name (servicename); | 459 | sl = find_name (servicename); |
474 | if (sl != NULL) | 460 | if (sl != NULL) |
475 | { | 461 | { |
476 | /* already running, just increment RC */ | ||
477 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 462 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
478 | _("Service `%s' already running.\n"), servicename); | 463 | _("Service `%s' already running.\n"), servicename); |
479 | #if RC | ||
480 | sl->rc++; | ||
481 | #endif | ||
482 | sl->next = running; | 464 | sl->next = running; |
483 | running = sl; | 465 | running = sl; |
484 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); | 466 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); |
@@ -509,12 +491,10 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename) | |||
509 | GNUNET_free_non_null (config); | 491 | GNUNET_free_non_null (config); |
510 | return; | 492 | return; |
511 | } | 493 | } |
494 | (void) stop_listening (servicename); | ||
512 | sl = GNUNET_malloc (sizeof (struct ServiceList)); | 495 | sl = GNUNET_malloc (sizeof (struct ServiceList)); |
513 | sl->name = GNUNET_strdup (servicename); | 496 | sl->name = GNUNET_strdup (servicename); |
514 | sl->next = running; | 497 | sl->next = running; |
515 | #if RC | ||
516 | sl->rc = 1; | ||
517 | #endif | ||
518 | sl->binary = binary; | 498 | sl->binary = binary; |
519 | sl->config = config; | 499 | sl->config = config; |
520 | sl->mtime = sbuf.st_mtime; | 500 | sl->mtime = sbuf.st_mtime; |
@@ -535,7 +515,8 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename) | |||
535 | * @param servicename name of the service to stop | 515 | * @param servicename name of the service to stop |
536 | */ | 516 | */ |
537 | static void | 517 | static void |
538 | stop_service (struct GNUNET_SERVER_Client *client, const char *servicename) | 518 | stop_service (struct GNUNET_SERVER_Client *client, |
519 | const char *servicename) | ||
539 | { | 520 | { |
540 | struct ServiceList *pos; | 521 | struct ServiceList *pos; |
541 | 522 | ||
@@ -544,29 +525,13 @@ stop_service (struct GNUNET_SERVER_Client *client, const char *servicename) | |||
544 | pos = find_name (servicename); | 525 | pos = find_name (servicename); |
545 | if (pos == NULL) | 526 | if (pos == NULL) |
546 | { | 527 | { |
547 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UNKNOWN); | 528 | if (GNUNET_OK == stop_listening (servicename)) |
548 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 529 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); |
549 | return; | 530 | else |
550 | } | 531 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UNKNOWN); |
551 | #if RC | ||
552 | if (pos->rc > 1) | ||
553 | { | ||
554 | /* RC>1, just decrement RC */ | ||
555 | pos->rc--; | ||
556 | pos->next = running; | ||
557 | running = pos; | ||
558 | #if DEBUG_ARM | ||
559 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
560 | "Service `%s' still used by %u clients, will keep it running!\n", | ||
561 | servicename, pos->rc); | ||
562 | #endif | ||
563 | signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_UP); | ||
564 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 532 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
565 | return; | 533 | return; |
566 | } | 534 | } |
567 | if (pos->rc == 1) | ||
568 | pos->rc--; /* decrement RC to zero */ | ||
569 | #endif | ||
570 | if (pos->killing_client != NULL) | 535 | if (pos->killing_client != NULL) |
571 | { | 536 | { |
572 | /* killing already in progress */ | 537 | /* killing already in progress */ |
diff --git a/src/arm/gnunet-service-manager.c b/src/arm/gnunet-service-manager.c index be8aa3246..e922bb3a2 100644 --- a/src/arm/gnunet-service-manager.c +++ b/src/arm/gnunet-service-manager.c | |||
@@ -23,42 +23,80 @@ | |||
23 | * start services for which incoming an incoming connection occur, | 23 | * start services for which incoming an incoming connection occur, |
24 | * and relay communication between the client and the service for | 24 | * and relay communication between the client and the service for |
25 | * that first incoming connection. | 25 | * that first incoming connection. |
26 | * | ||
26 | * @author Safey Abdel Halim | 27 | * @author Safey Abdel Halim |
28 | * @author Christian Grothoff | ||
27 | */ | 29 | */ |
28 | 30 | ||
29 | #include "platform.h" | 31 | #include "platform.h" |
30 | #include "gnunet_service_lib.h" | 32 | #include "gnunet_service_lib.h" |
31 | #include "gnunet_configuration_lib.h" | 33 | #include "gnunet_configuration_lib.h" |
34 | #include "gnunet_constants.h" | ||
32 | #include "gnunet_client_lib.h" | 35 | #include "gnunet_client_lib.h" |
33 | #include "gnunet_container_lib.h" | 36 | #include "gnunet_container_lib.h" |
34 | #include "gnunet_service_arm_.h" | 37 | #include "gnunet_service_arm_.h" |
35 | 38 | ||
36 | 39 | ||
37 | #define DEBUG_SERVICE_MANAGER GNUNET_NO | 40 | #define DEBUG_SERVICE_MANAGER GNUNET_YES |
38 | 41 | ||
39 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | 42 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) |
40 | 43 | ||
41 | #define BUFFER_SIZE (63 * 1024) | 44 | #define BUFFER_SIZE (64 * 1024) |
42 | 45 | ||
43 | #define REASON_CLIENT 1 | 46 | /** |
47 | * Problem forwarding from client to service. | ||
48 | */ | ||
49 | #define REASON_CLIENT_TO_SERVICE 1 | ||
44 | 50 | ||
45 | #define REASON_SERVICE 2 | 51 | /** |
52 | * Problem forwarding from service to client. | ||
53 | */ | ||
54 | #define REASON_SERVICE_TO_CLIENT 2 | ||
55 | |||
56 | /** | ||
57 | * Problem in both directions. | ||
58 | */ | ||
59 | #define REASON_ERROR 3 | ||
46 | 60 | ||
47 | 61 | ||
62 | /** | ||
63 | * | ||
64 | */ | ||
48 | struct ServiceListeningInfo | 65 | struct ServiceListeningInfo |
49 | { | 66 | { |
67 | /** | ||
68 | * This is a linked list. | ||
69 | */ | ||
50 | struct ServiceListeningInfo *next; | 70 | struct ServiceListeningInfo *next; |
51 | 71 | ||
72 | /** | ||
73 | * This is a linked list. | ||
74 | */ | ||
52 | struct ServiceListeningInfo *prev; | 75 | struct ServiceListeningInfo *prev; |
53 | 76 | ||
77 | /** | ||
78 | * Name of the service being forwarded. | ||
79 | */ | ||
54 | char *serviceName; | 80 | char *serviceName; |
55 | 81 | ||
82 | /** | ||
83 | * | ||
84 | */ | ||
56 | struct sockaddr *service_addr; | 85 | struct sockaddr *service_addr; |
57 | 86 | ||
87 | /** | ||
88 | * | ||
89 | */ | ||
58 | socklen_t service_addr_len; | 90 | socklen_t service_addr_len; |
59 | 91 | ||
92 | /** | ||
93 | * Our listening socket. | ||
94 | */ | ||
60 | struct GNUNET_NETWORK_Handle *listeningSocket; | 95 | struct GNUNET_NETWORK_Handle *listeningSocket; |
61 | 96 | ||
97 | /** | ||
98 | * Task doing the accepting. | ||
99 | */ | ||
62 | GNUNET_SCHEDULER_TaskIdentifier acceptTask; | 100 | GNUNET_SCHEDULER_TaskIdentifier acceptTask; |
63 | }; | 101 | }; |
64 | 102 | ||
@@ -67,60 +105,115 @@ struct ServiceListeningInfo | |||
67 | */ | 105 | */ |
68 | struct ForwardedConnection | 106 | struct ForwardedConnection |
69 | { | 107 | { |
108 | /** | ||
109 | * | ||
110 | */ | ||
70 | struct GNUNET_NETWORK_Handle *armClientSocket; | 111 | struct GNUNET_NETWORK_Handle *armClientSocket; |
71 | 112 | ||
113 | /** | ||
114 | * | ||
115 | */ | ||
72 | struct GNUNET_NETWORK_Handle *armServiceSocket; | 116 | struct GNUNET_NETWORK_Handle *armServiceSocket; |
73 | 117 | ||
118 | /** | ||
119 | * | ||
120 | */ | ||
74 | struct ServiceListeningInfo *listen_info; | 121 | struct ServiceListeningInfo *listen_info; |
75 | 122 | ||
76 | char serviceBuffer[BUFFER_SIZE]; | 123 | /** |
124 | * | ||
125 | */ | ||
126 | char service_to_client_buffer[BUFFER_SIZE]; | ||
77 | 127 | ||
78 | char clientBuffer[BUFFER_SIZE]; | 128 | /** |
129 | * | ||
130 | */ | ||
131 | char client_to_service_buffer[BUFFER_SIZE]; | ||
79 | 132 | ||
133 | /** | ||
134 | * | ||
135 | */ | ||
80 | char client_addr[32]; | 136 | char client_addr[32]; |
81 | 137 | ||
82 | char *clientBufferPos; | 138 | /** |
139 | * | ||
140 | */ | ||
141 | const char *client_to_service_bufferPos; | ||
83 | 142 | ||
84 | char *serviceBufferPos; | 143 | /** |
85 | 144 | * | |
86 | GNUNET_SCHEDULER_TaskIdentifier clientReceivingTask; | 145 | */ |
87 | 146 | const char *service_to_client_bufferPos; | |
88 | GNUNET_SCHEDULER_TaskIdentifier serviceReceivingTask; | ||
89 | |||
90 | ssize_t clientBufferDataLength; | ||
91 | |||
92 | ssize_t serviceBufferDataLength; | ||
93 | 147 | ||
148 | /** | ||
149 | * Timeout for forwarding. | ||
150 | */ | ||
151 | struct GNUNET_TIME_Absolute timeout; | ||
152 | |||
153 | /** | ||
154 | * Current back-off value. | ||
155 | */ | ||
156 | struct GNUNET_TIME_Relative back_off; | ||
157 | |||
158 | /** | ||
159 | * | ||
160 | */ | ||
161 | GNUNET_SCHEDULER_TaskIdentifier client_to_service_task; | ||
162 | |||
163 | /** | ||
164 | * | ||
165 | */ | ||
166 | GNUNET_SCHEDULER_TaskIdentifier service_to_client_task; | ||
167 | |||
168 | /** | ||
169 | * | ||
170 | */ | ||
171 | ssize_t client_to_service_bufferDataLength; | ||
172 | |||
173 | /** | ||
174 | * | ||
175 | */ | ||
176 | ssize_t service_to_client_bufferDataLength; | ||
177 | |||
178 | /** | ||
179 | * | ||
180 | */ | ||
94 | socklen_t client_addr_len; | 181 | socklen_t client_addr_len; |
95 | 182 | ||
96 | }; | 183 | }; |
97 | 184 | ||
98 | 185 | ||
186 | /** | ||
187 | * Array with the names of the services started by default. | ||
188 | */ | ||
99 | static char **defaultServicesList; | 189 | static char **defaultServicesList; |
100 | 190 | ||
191 | /** | ||
192 | * Size of the defaultServicesList array. | ||
193 | */ | ||
101 | static unsigned int numDefaultServices; | 194 | static unsigned int numDefaultServices; |
102 | 195 | ||
196 | /** | ||
197 | * | ||
198 | */ | ||
103 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 199 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
104 | 200 | ||
201 | /** | ||
202 | * | ||
203 | */ | ||
105 | static struct GNUNET_SCHEDULER_Handle *scheduler; | 204 | static struct GNUNET_SCHEDULER_Handle *scheduler; |
106 | 205 | ||
206 | /** | ||
207 | * | ||
208 | */ | ||
107 | static struct ServiceListeningInfo *serviceListeningInfoList_head; | 209 | static struct ServiceListeningInfo *serviceListeningInfoList_head; |
108 | 210 | ||
211 | /** | ||
212 | * | ||
213 | */ | ||
109 | static struct ServiceListeningInfo *serviceListeningInfoList_tail; | 214 | static struct ServiceListeningInfo *serviceListeningInfoList_tail; |
110 | 215 | ||
111 | 216 | ||
112 | #if DEBUG_SERVICE_MANAGER | ||
113 | static void | ||
114 | printDefaultServicesList () | ||
115 | { | ||
116 | unsigned int i; | ||
117 | for (i = 0; i < numDefaultServices; i++) | ||
118 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Service: %s\n", | ||
119 | defaultServicesList[i]); | ||
120 | } | ||
121 | #endif | ||
122 | |||
123 | |||
124 | /** | 217 | /** |
125 | * Put the default services represented by a space separated string into an array of strings | 218 | * Put the default services represented by a space separated string into an array of strings |
126 | * | 219 | * |
@@ -129,8 +222,8 @@ printDefaultServicesList () | |||
129 | static void | 222 | static void |
130 | addDefaultServicesToList (const char *services) | 223 | addDefaultServicesToList (const char *services) |
131 | { | 224 | { |
132 | unsigned int i = 0; | 225 | unsigned int i; |
133 | char *token; | 226 | const char *token; |
134 | char *s; | 227 | char *s; |
135 | 228 | ||
136 | if (strlen (services) == 0) | 229 | if (strlen (services) == 0) |
@@ -161,6 +254,7 @@ addDefaultServicesToList (const char *services) | |||
161 | * Checks whether the serviceName is in the list of default services | 254 | * Checks whether the serviceName is in the list of default services |
162 | * | 255 | * |
163 | * @param serviceName string to check its existance in the list | 256 | * @param serviceName string to check its existance in the list |
257 | * @return GNUNET_YES if the service is started by default | ||
164 | */ | 258 | */ |
165 | static int | 259 | static int |
166 | isInDefaultList (const char *serviceName) | 260 | isInDefaultList (const char *serviceName) |
@@ -173,24 +267,57 @@ isInDefaultList (const char *serviceName) | |||
173 | } | 267 | } |
174 | 268 | ||
175 | 269 | ||
270 | /** | ||
271 | * Close forwarded connection (partial or full). | ||
272 | * | ||
273 | * @param fc connection to close | ||
274 | * @param reason which direction to close | ||
275 | */ | ||
176 | static void | 276 | static void |
177 | closeClientAndServiceSockets (struct ForwardedConnection *fc, int reason) | 277 | closeClientAndServiceSockets (struct ForwardedConnection *fc, |
278 | int reason) | ||
178 | { | 279 | { |
179 | if ( (0 != (REASON_SERVICE & reason)) && | 280 | if (0 != (REASON_SERVICE_TO_CLIENT & reason)) |
180 | (fc->clientReceivingTask != GNUNET_SCHEDULER_NO_TASK) ) | 281 | { |
181 | { | 282 | #if DEBUG_SERVICE_MANAGER |
182 | GNUNET_SCHEDULER_cancel (scheduler, fc->clientReceivingTask); | 283 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
183 | fc->clientReceivingTask = GNUNET_SCHEDULER_NO_TASK; | 284 | "Stopping forwarding from service to client\n", |
285 | fc->listen_info->serviceName); | ||
286 | #endif | ||
287 | if (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK) | ||
288 | { | ||
289 | GNUNET_SCHEDULER_cancel (scheduler, fc->service_to_client_task); | ||
290 | fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK; | ||
291 | } | ||
292 | if (fc->armClientSocket != NULL) | ||
293 | GNUNET_NETWORK_socket_shutdown (fc->armClientSocket, | ||
294 | SHUT_WR); | ||
295 | if (fc->armServiceSocket != NULL) | ||
296 | GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket, | ||
297 | SHUT_RD); | ||
184 | } | 298 | } |
185 | if ( (0 != (REASON_CLIENT & reason)) && | 299 | if (0 != (REASON_CLIENT_TO_SERVICE & reason)) |
186 | (fc->serviceReceivingTask != GNUNET_SCHEDULER_NO_TASK) ) | ||
187 | { | 300 | { |
188 | GNUNET_SCHEDULER_cancel (scheduler, | 301 | #if DEBUG_SERVICE_MANAGER |
189 | fc->serviceReceivingTask); | 302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
190 | fc->serviceReceivingTask = GNUNET_SCHEDULER_NO_TASK; | 303 | "Stopping forwarding from client to service\n", |
304 | fc->listen_info->serviceName); | ||
305 | #endif | ||
306 | if (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) | ||
307 | { | ||
308 | GNUNET_SCHEDULER_cancel (scheduler, | ||
309 | fc->client_to_service_task); | ||
310 | fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK; | ||
311 | } | ||
312 | if (fc->armClientSocket != NULL) | ||
313 | GNUNET_NETWORK_socket_shutdown (fc->armClientSocket, | ||
314 | SHUT_RD); | ||
315 | if (fc->armServiceSocket != NULL) | ||
316 | GNUNET_NETWORK_socket_shutdown (fc->armServiceSocket, | ||
317 | SHUT_WR); | ||
191 | } | 318 | } |
192 | if ( (fc->clientReceivingTask != GNUNET_SCHEDULER_NO_TASK) || | 319 | if ( (fc->client_to_service_task != GNUNET_SCHEDULER_NO_TASK) || |
193 | (fc->serviceReceivingTask != GNUNET_SCHEDULER_NO_TASK) ) | 320 | (fc->service_to_client_task != GNUNET_SCHEDULER_NO_TASK) ) |
194 | return; | 321 | return; |
195 | #if DEBUG_SERVICE_MANAGER | 322 | #if DEBUG_SERVICE_MANAGER |
196 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 323 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -211,9 +338,16 @@ closeClientAndServiceSockets (struct ForwardedConnection *fc, int reason) | |||
211 | } | 338 | } |
212 | 339 | ||
213 | 340 | ||
341 | /** | ||
342 | * | ||
343 | */ | ||
214 | static void | 344 | static void |
215 | receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 345 | receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
216 | 346 | ||
347 | |||
348 | /** | ||
349 | * | ||
350 | */ | ||
217 | static void | 351 | static void |
218 | receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 352 | receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
219 | 353 | ||
@@ -230,57 +364,54 @@ forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
230 | struct ForwardedConnection *fc = cls; | 364 | struct ForwardedConnection *fc = cls; |
231 | ssize_t numberOfBytesSent; | 365 | ssize_t numberOfBytesSent; |
232 | 366 | ||
233 | fc->serviceReceivingTask = GNUNET_SCHEDULER_NO_TASK; | 367 | fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK; |
234 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 368 | if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready, |
369 | fc->armClientSocket)) | ||
235 | { | 370 | { |
236 | /* Ignore shutdown signal, reschedule yourself */ | 371 | fc->service_to_client_task = |
237 | fc->serviceReceivingTask = | 372 | GNUNET_SCHEDULER_add_write_net (scheduler, |
238 | GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | 373 | GNUNET_TIME_UNIT_FOREVER_REL, |
239 | fc->armClientSocket, | 374 | fc->armClientSocket, |
240 | &forwardToClient, fc); | 375 | &forwardToClient, fc); |
241 | return; | 376 | return; |
242 | } | 377 | } |
243 | |||
244 | /* Forwarding service response to client */ | 378 | /* Forwarding service response to client */ |
245 | numberOfBytesSent = | 379 | numberOfBytesSent = |
246 | GNUNET_NETWORK_socket_send (fc->armClientSocket, | 380 | GNUNET_NETWORK_socket_send (fc->armClientSocket, |
247 | fc->serviceBufferPos, | 381 | fc->service_to_client_bufferPos, |
248 | fc->serviceBufferDataLength); | 382 | fc->service_to_client_bufferDataLength); |
383 | if (numberOfBytesSent <= 0) | ||
384 | { | ||
385 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
386 | "Failed to forward data to client: %s\n", | ||
387 | STRERROR (errno)); | ||
388 | closeClientAndServiceSockets (fc, | ||
389 | REASON_SERVICE_TO_CLIENT); | ||
390 | return; | ||
391 | } | ||
249 | #if DEBUG_SERVICE_MANAGER | 392 | #if DEBUG_SERVICE_MANAGER |
250 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 393 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
251 | "Forwarded %d bytes to client\n", | 394 | "Forwarded %d bytes to client\n", |
252 | numberOfBytesSent); | 395 | numberOfBytesSent); |
253 | #endif | 396 | #endif |
254 | if ((numberOfBytesSent == GNUNET_SYSERR) || (numberOfBytesSent == 0)) | 397 | if (numberOfBytesSent < fc->service_to_client_bufferDataLength) |
255 | { | ||
256 | /* Error occured or connection closed by client */ | ||
257 | closeClientAndServiceSockets (fc, | ||
258 | (REASON_CLIENT & REASON_SERVICE)); | ||
259 | return; | ||
260 | } | ||
261 | else if (numberOfBytesSent < fc->serviceBufferDataLength) | ||
262 | { | 398 | { |
263 | /* Not all service data were sent to client */ | 399 | fc->service_to_client_bufferPos += numberOfBytesSent; |
264 | fc->serviceBufferPos += numberOfBytesSent; | 400 | fc->service_to_client_bufferDataLength -= numberOfBytesSent; |
265 | fc->serviceBufferDataLength -= numberOfBytesSent; | 401 | fc->service_to_client_task = |
266 | 402 | GNUNET_SCHEDULER_add_write_net (scheduler, | |
267 | /* Scheduling writing again for completing the remaining data to be sent */ | 403 | GNUNET_TIME_UNIT_FOREVER_REL, |
268 | fc->serviceReceivingTask = | ||
269 | GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | ||
270 | fc->armClientSocket, | 404 | fc->armClientSocket, |
271 | &forwardToClient, fc); | 405 | &forwardToClient, |
272 | } | 406 | fc); |
273 | else | 407 | return; |
274 | { | ||
275 | /* Data completely sent */ | ||
276 | fc->serviceBufferPos = fc->serviceBuffer; | ||
277 | } | 408 | } |
278 | 409 | fc->service_to_client_task = | |
279 | /* Now we are ready to receive more data, rescheduling receiving from Service */ | 410 | GNUNET_SCHEDULER_add_read_net (scheduler, |
280 | fc->serviceReceivingTask = | 411 | GNUNET_TIME_UNIT_FOREVER_REL, |
281 | GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | ||
282 | fc->armServiceSocket, | 412 | fc->armServiceSocket, |
283 | &receiveFromService, fc); | 413 | &receiveFromService, |
414 | fc); | ||
284 | } | 415 | } |
285 | 416 | ||
286 | 417 | ||
@@ -288,58 +419,59 @@ forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
288 | * Receive service messages sent by the service and forward it to client | 419 | * Receive service messages sent by the service and forward it to client |
289 | * | 420 | * |
290 | * @param cls callback data, struct ForwardedConnection for the communication between client and service | 421 | * @param cls callback data, struct ForwardedConnection for the communication between client and service |
291 | * @param tc context | 422 | * @param tc scheduler context |
292 | */ | 423 | */ |
293 | static void | 424 | static void |
294 | receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 425 | receiveFromService (void *cls, |
426 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
295 | { | 427 | { |
296 | struct ForwardedConnection *fc = cls; | 428 | struct ForwardedConnection *fc = cls; |
297 | 429 | ||
298 | fc->serviceReceivingTask = GNUNET_SCHEDULER_NO_TASK; | 430 | fc->service_to_client_task = GNUNET_SCHEDULER_NO_TASK; |
299 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 431 | if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready, |
432 | fc->armServiceSocket)) | ||
300 | { | 433 | { |
301 | /* Neglect shutdown signal, reschedule yourself */ | 434 | fc->service_to_client_task = |
302 | fc->serviceReceivingTask = | ||
303 | GNUNET_SCHEDULER_add_read_net (scheduler, | 435 | GNUNET_SCHEDULER_add_read_net (scheduler, |
304 | GNUNET_TIME_UNIT_FOREVER_REL, | 436 | GNUNET_TIME_UNIT_FOREVER_REL, |
305 | fc->armServiceSocket, | 437 | fc->armServiceSocket, |
306 | &receiveFromService, fc); | 438 | &receiveFromService, fc); |
307 | return; | 439 | return; |
308 | } | 440 | } |
309 | 441 | fc->service_to_client_bufferPos = fc->service_to_client_buffer; | |
310 | fc->serviceBufferDataLength = | 442 | fc->service_to_client_bufferDataLength = |
311 | GNUNET_NETWORK_socket_recv (fc->armServiceSocket, | 443 | GNUNET_NETWORK_socket_recv (fc->armServiceSocket, |
312 | fc->serviceBuffer, BUFFER_SIZE); | 444 | fc->service_to_client_buffer, |
313 | 445 | BUFFER_SIZE); | |
314 | #if DEBUG_SERVICE_MANAGER | 446 | if (fc->service_to_client_bufferDataLength <= 0) |
315 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
316 | "Received %d bytes for client\n", | ||
317 | fc->serviceBufferDataLength); | ||
318 | #endif | ||
319 | if (fc->serviceBufferDataLength <= 0) | ||
320 | { | 447 | { |
321 | /* The service has closed the connection or an error occured */ | 448 | if (fc->service_to_client_bufferDataLength == 0) |
322 | if (fc->serviceBufferDataLength == 0) | ||
323 | { | 449 | { |
324 | #if DEBUG_SERVICE_MANAGER | 450 | #if DEBUG_SERVICE_MANAGER |
325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 451 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
326 | _("Service `%s' closed connection! \n"), | 452 | "Service `%s' stopped sending data.\n", |
327 | fc->listen_info->serviceName); | 453 | fc->listen_info->serviceName); |
328 | #endif | 454 | #endif |
329 | } | 455 | } |
330 | else | 456 | else |
331 | { | 457 | { |
332 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 458 | #if DEBUG_SERVICE_MANAGER |
333 | _("Error receiving from service: %s\n"), | 459 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
460 | "Error receiving from service: %s\n", | ||
334 | STRERROR (errno)); | 461 | STRERROR (errno)); |
462 | #endif | ||
335 | } | 463 | } |
336 | closeClientAndServiceSockets (fc, REASON_SERVICE); | 464 | closeClientAndServiceSockets (fc, REASON_SERVICE_TO_CLIENT); |
337 | return; | 465 | return; |
338 | } | 466 | } |
339 | 467 | #if DEBUG_SERVICE_MANAGER | |
340 | /* Forwarding Service data to Client */ | 468 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
341 | fc->serviceReceivingTask = | 469 | "Received %d bytes for client\n", |
342 | GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | 470 | fc->service_to_client_bufferDataLength); |
471 | #endif | ||
472 | fc->service_to_client_task = | ||
473 | GNUNET_SCHEDULER_add_write_net (scheduler, | ||
474 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
343 | fc->armClientSocket, | 475 | fc->armClientSocket, |
344 | &forwardToClient, fc); | 476 | &forwardToClient, fc); |
345 | } | 477 | } |
@@ -349,73 +481,65 @@ receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
349 | * Forward client message to service | 481 | * Forward client message to service |
350 | * | 482 | * |
351 | * @param cls callback data, struct ForwardedConnection for the communication between client and service | 483 | * @param cls callback data, struct ForwardedConnection for the communication between client and service |
352 | * @param tc context | 484 | * @param tc scheduler context |
353 | */ | 485 | */ |
354 | static void | 486 | static void |
355 | forwardToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 487 | forwardToService (void *cls, |
488 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
356 | { | 489 | { |
357 | struct ForwardedConnection *fc = cls; | 490 | struct ForwardedConnection *fc = cls; |
358 | ssize_t numberOfBytesSent; | 491 | ssize_t numberOfBytesSent; |
359 | 492 | ||
360 | fc->clientReceivingTask = GNUNET_SCHEDULER_NO_TASK; | 493 | fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK; |
361 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 494 | if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->write_ready, |
495 | fc->armServiceSocket)) | ||
362 | { | 496 | { |
363 | /* Neglect shutdown signal, reschedule ourself */ | 497 | fc->client_to_service_task = |
364 | fc->clientReceivingTask = | 498 | GNUNET_SCHEDULER_add_write_net (scheduler, |
365 | GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | 499 | GNUNET_TIME_UNIT_FOREVER_REL, |
366 | fc->armServiceSocket, | 500 | fc->armServiceSocket, |
367 | &forwardToService, fc); | 501 | &forwardToService, fc); |
368 | return; | 502 | return; |
369 | } | 503 | } |
370 | |||
371 | |||
372 | /* Forwarding client's message to service */ | ||
373 | numberOfBytesSent = | 504 | numberOfBytesSent = |
374 | GNUNET_NETWORK_socket_send (fc->armServiceSocket, | 505 | GNUNET_NETWORK_socket_send (fc->armServiceSocket, |
375 | fc->clientBufferPos, | 506 | fc->client_to_service_bufferPos, |
376 | fc->clientBufferDataLength); | 507 | fc->client_to_service_bufferDataLength); |
508 | if (numberOfBytesSent <= 0) | ||
509 | { | ||
510 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
511 | "Failed to forward data to service: %s\n", | ||
512 | STRERROR (errno)); | ||
513 | closeClientAndServiceSockets (fc, | ||
514 | REASON_CLIENT_TO_SERVICE); | ||
515 | return; | ||
516 | } | ||
377 | #if DEBUG_SERVICE_MANAGER | 517 | #if DEBUG_SERVICE_MANAGER |
378 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 518 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
379 | "Forwarded %d bytes to service\n", | 519 | "Forwarded %d bytes to service\n", |
380 | numberOfBytesSent); | 520 | numberOfBytesSent); |
381 | #endif | 521 | #endif |
382 | if ((numberOfBytesSent == GNUNET_SYSERR) || (numberOfBytesSent == 0)) | 522 | if (numberOfBytesSent < fc->client_to_service_bufferDataLength) |
383 | { | 523 | { |
384 | /* Error occured or connection closed by service */ | 524 | fc->client_to_service_bufferPos += numberOfBytesSent; |
385 | closeClientAndServiceSockets (fc, | 525 | fc->client_to_service_bufferDataLength -= numberOfBytesSent; |
386 | (REASON_CLIENT & REASON_SERVICE)); | 526 | fc->client_to_service_task = |
387 | return; | 527 | GNUNET_SCHEDULER_add_write_net (scheduler, |
388 | } | 528 | GNUNET_TIME_UNIT_FOREVER_REL, |
389 | if (numberOfBytesSent < fc->clientBufferDataLength) | ||
390 | { | ||
391 | /* Not all client data were sent to the service */ | ||
392 | fc->clientBufferPos += numberOfBytesSent; | ||
393 | fc->clientBufferDataLength -= numberOfBytesSent; | ||
394 | |||
395 | /* Scheduling writing again for completing the remaining data to be sent */ | ||
396 | fc->clientReceivingTask = | ||
397 | GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | ||
398 | fc->armServiceSocket, | 529 | fc->armServiceSocket, |
399 | &forwardToService, fc); | 530 | &forwardToService, fc); |
531 | return; | ||
400 | } | 532 | } |
401 | else | 533 | fc->client_to_service_task = |
402 | { | 534 | GNUNET_SCHEDULER_add_read_net (scheduler, |
403 | /* Data completely sent */ | 535 | GNUNET_TIME_UNIT_FOREVER_REL, |
404 | fc->clientBufferPos = fc->clientBuffer; | ||
405 | } | ||
406 | |||
407 | /* Now, we are ready to receive more data. Rescheduling the receiving from client */ | ||
408 | fc->clientReceivingTask = | ||
409 | GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | ||
410 | fc->armClientSocket, | 536 | fc->armClientSocket, |
411 | &receiveFromClient, fc); | 537 | &receiveFromClient, fc); |
412 | } | 538 | } |
413 | 539 | ||
414 | 540 | ||
415 | |||
416 | /** | 541 | /** |
417 | * Message sent from client to service (faked by ARM, since it's the first connection), | 542 | * Read data from the client and then forward it to the service. |
418 | * ARM will receive the message and forward it to the running service | ||
419 | * | 543 | * |
420 | * @param cls callback data, struct ForwardedConnection for the communication between client and service | 544 | * @param cls callback data, struct ForwardedConnection for the communication between client and service |
421 | * @param tc context | 545 | * @param tc context |
@@ -425,77 +549,76 @@ receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
425 | { | 549 | { |
426 | struct ForwardedConnection *fc = cls; | 550 | struct ForwardedConnection *fc = cls; |
427 | 551 | ||
428 | fc->clientReceivingTask = GNUNET_SCHEDULER_NO_TASK; | 552 | fc->client_to_service_task = GNUNET_SCHEDULER_NO_TASK; |
429 | if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) | 553 | if (GNUNET_YES != GNUNET_NETWORK_fdset_isset (tc->read_ready, |
554 | fc->armClientSocket)) | ||
430 | { | 555 | { |
431 | /* Neglect the shutdown signal, schedule ourselves */ | 556 | fc->client_to_service_task = |
432 | fc->clientReceivingTask = | ||
433 | GNUNET_SCHEDULER_add_read_net (scheduler, | 557 | GNUNET_SCHEDULER_add_read_net (scheduler, |
434 | GNUNET_TIME_UNIT_FOREVER_REL, | 558 | GNUNET_TIME_UNIT_FOREVER_REL, |
435 | fc->armClientSocket, | 559 | fc->armClientSocket, |
436 | &receiveFromClient, fc); | 560 | &receiveFromClient, fc); |
437 | return; | 561 | return; |
438 | } | 562 | } |
439 | 563 | fc->client_to_service_bufferPos = fc->client_to_service_buffer; | |
440 | /* Receive client's message */ | 564 | fc->client_to_service_bufferDataLength = |
441 | fc->clientBufferDataLength = | ||
442 | GNUNET_NETWORK_socket_recv (fc->armClientSocket, | 565 | GNUNET_NETWORK_socket_recv (fc->armClientSocket, |
443 | fc->clientBuffer, BUFFER_SIZE); | 566 | fc->client_to_service_buffer, |
444 | #if DEBUG_SERVICE_MANAGER | 567 | BUFFER_SIZE); |
445 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 568 | if (fc->client_to_service_bufferDataLength <= 0) |
446 | "Received %d bytes for service\n", | ||
447 | fc->clientBufferDataLength); | ||
448 | #endif | ||
449 | if (fc->clientBufferDataLength <= 0) | ||
450 | { | 569 | { |
451 | /* The client has closed the connection or and error occured */ | 570 | if (fc->client_to_service_bufferDataLength == 0) |
452 | if (fc->clientBufferDataLength == 0) | ||
453 | { | 571 | { |
454 | #if DEBUG_SERVICE_MANAGER | 572 | #if DEBUG_SERVICE_MANAGER |
455 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 573 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
456 | _("Client closed connection with service:`%s'\n"), | 574 | "Client closed connection with service `%s'\n", |
457 | fc->listen_info->serviceName); | 575 | fc->listen_info->serviceName); |
458 | #endif | 576 | #endif |
459 | } | 577 | } |
460 | else | 578 | else |
461 | { | 579 | { |
580 | #if DEBUG_SERVICE_MANAGER | ||
462 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 581 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
463 | _("Error receiving from client: %s \n"), | 582 | "Error receiving from client: %s\n", |
464 | STRERROR (errno)); | 583 | STRERROR (errno)); |
584 | #endif | ||
465 | } | 585 | } |
466 | closeClientAndServiceSockets (fc, REASON_CLIENT); | 586 | closeClientAndServiceSockets (fc, REASON_CLIENT_TO_SERVICE); |
467 | return; | 587 | return; |
468 | } | 588 | } |
469 | 589 | #if DEBUG_SERVICE_MANAGER | |
470 | /* Forwarding request to service */ | 590 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
471 | fc->clientReceivingTask = | 591 | "Received %d bytes for service\n", |
472 | GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, | 592 | fc->client_to_service_bufferDataLength); |
593 | #endif | ||
594 | fc->client_to_service_task = | ||
595 | GNUNET_SCHEDULER_add_write_net (scheduler, | ||
596 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
473 | fc->armServiceSocket, | 597 | fc->armServiceSocket, |
474 | &forwardToService, fc); | 598 | &forwardToService, fc); |
475 | } | 599 | } |
476 | 600 | ||
477 | 601 | ||
602 | /** | ||
603 | * | ||
604 | */ | ||
478 | static void | 605 | static void |
479 | start_forwarding (void *cls, | 606 | start_forwarding (void *cls, |
480 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 607 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
481 | { | 608 | { |
482 | struct ForwardedConnection *fc = cls; | 609 | struct ForwardedConnection *fc = cls; |
610 | struct GNUNET_TIME_Relative rem; | ||
483 | 611 | ||
484 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) | 612 | if ( (NULL != tc) && |
613 | (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) ) | ||
485 | { | 614 | { |
486 | /* Service is not up. Unable to proceed */ | 615 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
487 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 616 | _("Unable to forward to service `%s': shutdown\n"), |
488 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 617 | fc->listen_info->serviceName); |
489 | _("Unable to start service `%s': timeout\n"), | 618 | closeClientAndServiceSockets (fc, REASON_ERROR); |
490 | fc->listen_info->serviceName); | ||
491 | closeClientAndServiceSockets (fc, | ||
492 | (REASON_CLIENT & REASON_SERVICE)); | ||
493 | return; | 619 | return; |
494 | } | 620 | } |
495 | #if DEBUG_SERVICE_MANAGER | 621 | rem = GNUNET_TIME_absolute_get_remaining (fc->timeout); |
496 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
497 | _("Connection to service to start forwarding\n")); | ||
498 | #endif | ||
499 | fc->armServiceSocket = | 622 | fc->armServiceSocket = |
500 | GNUNET_NETWORK_socket_create (fc->listen_info->service_addr->sa_family, | 623 | GNUNET_NETWORK_socket_create (fc->listen_info->service_addr->sa_family, |
501 | SOCK_STREAM, 0); | 624 | SOCK_STREAM, 0); |
@@ -505,29 +628,40 @@ start_forwarding (void *cls, | |||
505 | _ ("Unable to start service `%s': %s\n"), | 628 | _ ("Unable to start service `%s': %s\n"), |
506 | fc->listen_info->serviceName, | 629 | fc->listen_info->serviceName, |
507 | STRERROR (errno)); | 630 | STRERROR (errno)); |
508 | closeClientAndServiceSockets (fc, | 631 | closeClientAndServiceSockets (fc, REASON_ERROR); |
509 | (REASON_CLIENT & REASON_SERVICE)); | ||
510 | return; | 632 | return; |
511 | } | 633 | } |
512 | if ((GNUNET_SYSERR == | 634 | if ((GNUNET_SYSERR == |
513 | GNUNET_NETWORK_socket_connect (fc->armServiceSocket, | 635 | GNUNET_NETWORK_socket_connect (fc->armServiceSocket, |
514 | fc->listen_info->service_addr, | 636 | fc->listen_info->service_addr, |
515 | fc->listen_info->service_addr_len)) | 637 | fc->listen_info->service_addr_len)) && |
516 | && (EINPROGRESS != errno)) | 638 | (EINPROGRESS != errno) ) |
517 | { | 639 | { |
518 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 640 | if (rem.value == 0) |
519 | _("Unable to start service `%s': failed to connect\n"), | 641 | { |
520 | fc->listen_info->serviceName); | 642 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
521 | closeClientAndServiceSockets (fc, | 643 | _("Unable to forward to service `%s': timeout before connect\n"), |
522 | (REASON_CLIENT & REASON_SERVICE)); | 644 | fc->listen_info->serviceName); |
523 | return; | 645 | closeClientAndServiceSockets (fc, REASON_ERROR); |
646 | return; | ||
647 | } | ||
648 | fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2); | ||
649 | GNUNET_SCHEDULER_add_delayed (scheduler, | ||
650 | GNUNET_TIME_relative_min (fc->back_off, | ||
651 | rem), | ||
652 | &start_forwarding, | ||
653 | fc); | ||
524 | } | 654 | } |
525 | fc->clientReceivingTask = | 655 | #if DEBUG_SERVICE_MANAGER |
656 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
657 | "Connected to service, now starting forwarding\n"); | ||
658 | #endif | ||
659 | fc->client_to_service_task = | ||
526 | GNUNET_SCHEDULER_add_read_net (scheduler, | 660 | GNUNET_SCHEDULER_add_read_net (scheduler, |
527 | GNUNET_TIME_UNIT_FOREVER_REL, | 661 | GNUNET_TIME_UNIT_FOREVER_REL, |
528 | fc->armClientSocket, | 662 | fc->armClientSocket, |
529 | &receiveFromClient, fc); | 663 | &receiveFromClient, fc); |
530 | fc->serviceReceivingTask = | 664 | fc->service_to_client_task = |
531 | GNUNET_SCHEDULER_add_read_net (scheduler, | 665 | GNUNET_SCHEDULER_add_read_net (scheduler, |
532 | GNUNET_TIME_UNIT_FOREVER_REL, | 666 | GNUNET_TIME_UNIT_FOREVER_REL, |
533 | fc->armServiceSocket, | 667 | fc->armServiceSocket, |
@@ -553,7 +687,7 @@ connectToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
553 | _("Unable to start service `%s': shutdown\n"), | 687 | _("Unable to start service `%s': shutdown\n"), |
554 | fc->listen_info->serviceName); | 688 | fc->listen_info->serviceName); |
555 | closeClientAndServiceSockets (fc, | 689 | closeClientAndServiceSockets (fc, |
556 | (REASON_CLIENT & REASON_SERVICE)); | 690 | (REASON_CLIENT_TO_SERVICE & REASON_SERVICE_TO_CLIENT)); |
557 | return; | 691 | return; |
558 | } | 692 | } |
559 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) | 693 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) |
@@ -563,27 +697,30 @@ connectToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
563 | _("Unable to start service `%s': timeout\n"), | 697 | _("Unable to start service `%s': timeout\n"), |
564 | fc->listen_info->serviceName); | 698 | fc->listen_info->serviceName); |
565 | closeClientAndServiceSockets (fc, | 699 | closeClientAndServiceSockets (fc, |
566 | (REASON_CLIENT & REASON_SERVICE)); | 700 | (REASON_CLIENT_TO_SERVICE & REASON_SERVICE_TO_CLIENT)); |
567 | return; | 701 | return; |
568 | } | 702 | } |
569 | GNUNET_break (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); | 703 | GNUNET_break (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); |
570 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 704 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
571 | _("Service `%s' started\n"), | 705 | _("Service `%s' started\n"), |
572 | fc->listen_info->serviceName); | 706 | fc->listen_info->serviceName); |
573 | GNUNET_CLIENT_service_test (scheduler, | 707 | fc->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_SERVICE_TIMEOUT); |
574 | fc->listen_info->serviceName, | 708 | fc->back_off = GNUNET_TIME_UNIT_MILLISECONDS; |
575 | cfg, | 709 | start_forwarding (fc, NULL); |
576 | TIMEOUT, | ||
577 | &start_forwarding, | ||
578 | fc); | ||
579 | } | 710 | } |
580 | 711 | ||
581 | 712 | ||
582 | void stop_listening (const char *serviceName) | 713 | /** |
714 | * | ||
715 | */ | ||
716 | int | ||
717 | stop_listening (const char *serviceName) | ||
583 | { | 718 | { |
584 | struct ServiceListeningInfo *pos; | 719 | struct ServiceListeningInfo *pos; |
585 | struct ServiceListeningInfo *next; | 720 | struct ServiceListeningInfo *next; |
586 | 721 | int ret; | |
722 | |||
723 | ret = GNUNET_NO; | ||
587 | next = serviceListeningInfoList_head; | 724 | next = serviceListeningInfoList_head; |
588 | while (NULL != (pos = next)) | 725 | while (NULL != (pos = next)) |
589 | { | 726 | { |
@@ -599,8 +736,10 @@ void stop_listening (const char *serviceName) | |||
599 | pos); | 736 | pos); |
600 | GNUNET_free (pos->serviceName); | 737 | GNUNET_free (pos->serviceName); |
601 | GNUNET_free (pos->service_addr); | 738 | GNUNET_free (pos->service_addr); |
602 | GNUNET_free (pos); | 739 | GNUNET_free (pos); |
740 | ret = GNUNET_OK; | ||
603 | } | 741 | } |
742 | return ret; | ||
604 | } | 743 | } |
605 | 744 | ||
606 | 745 | ||
@@ -622,8 +761,8 @@ acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
622 | return; | 761 | return; |
623 | fc = GNUNET_malloc (sizeof (struct ForwardedConnection)); | 762 | fc = GNUNET_malloc (sizeof (struct ForwardedConnection)); |
624 | fc->listen_info = serviceListeningInfo; | 763 | fc->listen_info = serviceListeningInfo; |
625 | fc->serviceBufferPos = fc->serviceBuffer; | 764 | fc->service_to_client_bufferPos = fc->service_to_client_buffer; |
626 | fc->clientBufferPos = fc->clientBuffer; | 765 | fc->client_to_service_bufferPos = fc->client_to_service_buffer; |
627 | fc->client_addr_len = sizeof (fc->client_addr); | 766 | fc->client_addr_len = sizeof (fc->client_addr); |
628 | fc->armClientSocket = GNUNET_NETWORK_socket_accept (serviceListeningInfo->listeningSocket, | 767 | fc->armClientSocket = GNUNET_NETWORK_socket_accept (serviceListeningInfo->listeningSocket, |
629 | (struct sockaddr*) fc->client_addr, | 768 | (struct sockaddr*) fc->client_addr, |
@@ -804,9 +943,6 @@ prepareServices (const struct GNUNET_CONFIGURATION_Handle | |||
804 | { | 943 | { |
805 | addDefaultServicesToList (defaultServicesString); | 944 | addDefaultServicesToList (defaultServicesString); |
806 | GNUNET_free (defaultServicesString); | 945 | GNUNET_free (defaultServicesString); |
807 | #if DEBUG_SERVICE_MANAGER | ||
808 | printDefaultServicesList (); | ||
809 | #endif | ||
810 | } | 946 | } |
811 | /* Spot the services from the configuration and create a listening | 947 | /* Spot the services from the configuration and create a listening |
812 | socket for each */ | 948 | socket for each */ |
diff --git a/src/arm/gnunet_service_arm_.h b/src/arm/gnunet_service_arm_.h index d44f22864..1e55051e0 100644 --- a/src/arm/gnunet_service_arm_.h +++ b/src/arm/gnunet_service_arm_.h | |||
@@ -30,7 +30,14 @@ | |||
30 | void start_service (struct GNUNET_SERVER_Client *client, | 30 | void start_service (struct GNUNET_SERVER_Client *client, |
31 | const char *servicename); | 31 | const char *servicename); |
32 | 32 | ||
33 | void stop_listening (const char *serviceName); | 33 | /** |
34 | * Stop listening for connections to a service. | ||
35 | * | ||
36 | * @param serviceName name of service to stop listening for | ||
37 | * @return GNUNET_OK if we stopped to listen, GNUNET_NO if we were | ||
38 | * not listening | ||
39 | */ | ||
40 | int stop_listening (const char *serviceName); | ||
34 | 41 | ||
35 | void prepareServices (const struct GNUNET_CONFIGURATION_Handle | 42 | void prepareServices (const struct GNUNET_CONFIGURATION_Handle |
36 | *configurationHandle, | 43 | *configurationHandle, |
diff --git a/src/arm/test_arm_api_data.conf b/src/arm/test_arm_api_data.conf index d4e8d6dbd..8ab08247c 100644 --- a/src/arm/test_arm_api_data.conf +++ b/src/arm/test_arm_api_data.conf | |||
@@ -7,14 +7,17 @@ PORT = 23354 | |||
7 | DEFAULTSERVICES = | 7 | DEFAULTSERVICES = |
8 | BINARY = gnunet-service-arm | 8 | BINARY = gnunet-service-arm |
9 | OPTIONS = -L ERROR | 9 | OPTIONS = -L ERROR |
10 | #DEBUG = YES | 10 | # DEBUG = YES |
11 | #PREFIX = valgrind --tool=memcheck --leak-check=yes | ||
11 | 12 | ||
12 | [resolver] | 13 | [resolver] |
13 | #DEBUG = YES | 14 | # DEBUG = YES |
14 | PORT = 23355 | 15 | PORT = 23355 |
15 | 16 | ||
17 | |||
16 | [do-nothing] | 18 | [do-nothing] |
17 | #DEBUG = YES | 19 | #DEBUG = YES |
20 | AUTOSTART = NO | ||
18 | PORT = 2223 | 21 | PORT = 2223 |
19 | HOSTNAME = localhost | 22 | HOSTNAME = localhost |
20 | HOME = $SERVICEHOME | 23 | HOME = $SERVICEHOME |
@@ -22,3 +25,24 @@ CONFIG = $DEFAULTCONFIG | |||
22 | BINARY = mockup-service | 25 | BINARY = mockup-service |
23 | ACCEPT_FROM = 127.0.0.1; | 26 | ACCEPT_FROM = 127.0.0.1; |
24 | ACCEPT_FROM6 = ::1; | 27 | ACCEPT_FROM6 = ::1; |
28 | |||
29 | |||
30 | [fs] | ||
31 | AUTOSTART = NO | ||
32 | |||
33 | [datastore] | ||
34 | AUTOSTART = NO | ||
35 | |||
36 | [core] | ||
37 | AUTOSTART = NO | ||
38 | |||
39 | [transport] | ||
40 | AUTOSTART = NO | ||
41 | |||
42 | [peerinfo] | ||
43 | AUTOSTART = NO | ||
44 | |||
45 | [statistics] | ||
46 | AUTOSTART = YES | ||
47 | # DEBUG = NO | ||
48 | |||
diff --git a/src/arm/test_gnunet_service_manager.c b/src/arm/test_gnunet_service_manager.c index 454fa0e98..ac2544e58 100644 --- a/src/arm/test_gnunet_service_manager.c +++ b/src/arm/test_gnunet_service_manager.c | |||
@@ -58,8 +58,15 @@ arm_stopped (void *cls, int success) | |||
58 | GNUNET_break (0); | 58 | GNUNET_break (0); |
59 | ret = 4; | 59 | ret = 4; |
60 | } | 60 | } |
61 | else | ||
62 | { | ||
63 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
64 | "ARM stopped\n"); | ||
65 | } | ||
66 | #if START_ARM | ||
61 | GNUNET_ARM_disconnect (arm); | 67 | GNUNET_ARM_disconnect (arm); |
62 | arm = NULL; | 68 | arm = NULL; |
69 | #endif | ||
63 | } | 70 | } |
64 | 71 | ||
65 | static void | 72 | static void |
@@ -79,6 +86,8 @@ hostNameResolveCB(void *cls, | |||
79 | ret = 3; | 86 | ret = 3; |
80 | return; | 87 | return; |
81 | } | 88 | } |
89 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
90 | "Resolved hostname, now stopping ARM\n"); | ||
82 | ret = 0; | 91 | ret = 0; |
83 | #if START_ARM | 92 | #if START_ARM |
84 | GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, &arm_stopped, NULL); | 93 | GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, &arm_stopped, NULL); |
@@ -95,6 +104,8 @@ arm_notify (void *cls, int success) | |||
95 | ret = 1; | 104 | ret = 1; |
96 | return; | 105 | return; |
97 | } | 106 | } |
107 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
108 | "Trying to resolve our own hostname!\n"); | ||
98 | /* connect to the resolver service */ | 109 | /* connect to the resolver service */ |
99 | if (NULL == GNUNET_RESOLVER_hostname_resolve (sched, | 110 | if (NULL == GNUNET_RESOLVER_hostname_resolve (sched, |
100 | cfg, AF_UNSPEC, | 111 | cfg, AF_UNSPEC, |
@@ -102,8 +113,8 @@ arm_notify (void *cls, int success) | |||
102 | &hostNameResolveCB, | 113 | &hostNameResolveCB, |
103 | NULL)) | 114 | NULL)) |
104 | { | 115 | { |
105 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 116 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
106 | "Unable to resolve our own hostname!\n"); | 117 | "Unable initiate connection to resolver service\n"); |
107 | ret = 2; | 118 | ret = 2; |
108 | #if START_ARM | 119 | #if START_ARM |
109 | GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, &arm_stopped, NULL); | 120 | GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, &arm_stopped, NULL); |