aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-05-11 08:26:46 +0000
committerChristian Grothoff <christian@grothoff.org>2010-05-11 08:26:46 +0000
commit33890e032acc7c284e2ab82f2ccbc72ae8c2092f (patch)
treef4b00a25bc17cf66530005f166c3fe405d203710 /src
parentb0036678adbb776b8e4d8be81bd271905b36a223 (diff)
downloadgnunet-33890e032acc7c284e2ab82f2ccbc72ae8c2092f.tar.gz
gnunet-33890e032acc7c284e2ab82f2ccbc72ae8c2092f.zip
arm fix
Diffstat (limited to 'src')
-rw-r--r--src/arm/gnunet-service-arm.c12
-rw-r--r--src/arm/gnunet-service-manager.c699
-rw-r--r--src/arm/gnunet_service_arm_.h23
-rw-r--r--src/statistics/test_statistics_api_data.conf4
-rw-r--r--src/util/server.c2
5 files changed, 346 insertions, 394 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c
index a630f5b1a..f38b6b044 100644
--- a/src/arm/gnunet-service-arm.c
+++ b/src/arm/gnunet-service-arm.c
@@ -469,6 +469,7 @@ start_service (struct GNUNET_SERVER_Client *client, const char *servicename)
469 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN); 469 signal_result (client, servicename, GNUNET_MESSAGE_TYPE_ARM_IS_DOWN);
470 return; 470 return;
471 } 471 }
472 stop_listening (servicename);
472 sl = find_name (servicename); 473 sl = find_name (servicename);
473 if (sl != NULL) 474 if (sl != NULL)
474 { 475 {
@@ -1047,11 +1048,14 @@ run (void *cls,
1047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1048 "Starting default services `%s'\n", defaultservices); 1049 "Starting default services `%s'\n", defaultservices);
1049#endif 1050#endif
1050 pos = strtok (defaultservices, " "); 1051 if (0 < strlen (defaultservices))
1051 while (pos != NULL)
1052 { 1052 {
1053 start_service (NULL, pos); 1053 pos = strtok (defaultservices, " ");
1054 pos = strtok (NULL, " "); 1054 while (pos != NULL)
1055 {
1056 start_service (NULL, pos);
1057 pos = strtok (NULL, " ");
1058 }
1055 } 1059 }
1056 GNUNET_free (defaultservices); 1060 GNUNET_free (defaultservices);
1057 } 1061 }
diff --git a/src/arm/gnunet-service-manager.c b/src/arm/gnunet-service-manager.c
index 01ede9f33..c80c12aa5 100644
--- a/src/arm/gnunet-service-manager.c
+++ b/src/arm/gnunet-service-manager.c
@@ -35,111 +35,85 @@
35 35
36 36
37#define DEBUG_SERVICE_MANAGER GNUNET_NO 37#define DEBUG_SERVICE_MANAGER GNUNET_NO
38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
39#define BUFFER_SIZE (63 * 1024)
40#define REASON_CLIENT 1
41#define REASON_SERVICE 2
42
43static char **defaultServicesList;
44static int numDefaultServices = 0;
45static const struct GNUNET_CONFIGURATION_Handle *cfg;
46static struct GNUNET_SCHEDULER_Handle *scheduler;
47 38
48struct StartedService 39#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
49{
50 const char *serviceName;
51 struct StartedService *next;
52};
53 40
54static struct StartedService *startedServices = NULL; 41#define BUFFER_SIZE (63 * 1024)
55 42
43#define REASON_CLIENT 1
56 44
57/* Functions prototypes */ 45#define REASON_SERVICE 2
58static void
59receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
60static void
61receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
62 46
63 47
64struct ServiceListeningInfo 48struct ServiceListeningInfo
65{ 49{
66 struct ServiceListeningInfo *next; 50 struct ServiceListeningInfo *next;
51
67 struct ServiceListeningInfo *prev; 52 struct ServiceListeningInfo *prev;
68 const char *serviceName; 53
54 char *serviceName;
55
69 struct sockaddr *service_addr; 56 struct sockaddr *service_addr;
57
70 socklen_t service_addr_len; 58 socklen_t service_addr_len;
71 struct sockaddr client_addr; 59
72 socklen_t client_addr_len;
73 struct GNUNET_NETWORK_Handle *listeningSocket; 60 struct GNUNET_NETWORK_Handle *listeningSocket;
61
74 GNUNET_SCHEDULER_TaskIdentifier acceptTask; 62 GNUNET_SCHEDULER_TaskIdentifier acceptTask;
75}; 63};
76 64
77static struct ServiceListeningInfo *serviceListeningInfoList_head;
78static struct ServiceListeningInfo *serviceListeningInfoList_tail;
79
80/** 65/**
81 * Information of the connection: client-arm-service 66 * Information of the connection: client-arm-service
82 */ 67 */
83struct ServiceInfo 68struct ForwardedConnection
84{ 69{
85 const char *serviceName;
86 struct GNUNET_NETWORK_Handle *armClientSocket; 70 struct GNUNET_NETWORK_Handle *armClientSocket;
71
87 struct GNUNET_NETWORK_Handle *armServiceSocket; 72 struct GNUNET_NETWORK_Handle *armServiceSocket;
88 struct sockaddr *service_addr; 73
89 socklen_t service_addr_len; 74 struct ServiceListeningInfo *listen_info;
75
76 char serviceBuffer[BUFFER_SIZE];
77
90 char clientBuffer[BUFFER_SIZE]; 78 char clientBuffer[BUFFER_SIZE];
91 ssize_t clientBufferDataLength; 79
80 char client_addr[32];
81
92 char *clientBufferPos; 82 char *clientBufferPos;
93 char serviceBuffer[BUFFER_SIZE]; 83
94 ssize_t serviceBufferDataLength;
95 char *serviceBufferPos; 84 char *serviceBufferPos;
85
96 GNUNET_SCHEDULER_TaskIdentifier clientReceivingTask; 86 GNUNET_SCHEDULER_TaskIdentifier clientReceivingTask;
87
97 GNUNET_SCHEDULER_TaskIdentifier serviceReceivingTask; 88 GNUNET_SCHEDULER_TaskIdentifier serviceReceivingTask;
98 GNUNET_SCHEDULER_TaskIdentifier acceptTask; 89
90 ssize_t clientBufferDataLength;
91
92 ssize_t serviceBufferDataLength;
93
94 socklen_t client_addr_len;
95
99}; 96};
100 97
101 98
102static struct ServiceInfo * 99static char **defaultServicesList;
103newServiceInfo (const char *serviceName, struct sockaddr *service_addr,
104 socklen_t service_addr_len)
105{
106 struct ServiceInfo *serviceInfo =
107 GNUNET_malloc (sizeof (struct ServiceInfo));
108 serviceInfo->serviceName = serviceName;
109 serviceInfo->service_addr = service_addr;
110 serviceInfo->service_addr_len = service_addr_len;
111 serviceInfo->serviceBufferPos = serviceInfo->serviceBuffer;
112 serviceInfo->clientBufferPos = serviceInfo->clientBuffer;
113 return serviceInfo;
114}
115 100
101static unsigned int numDefaultServices;
116 102
117static struct ServiceListeningInfo * 103static const struct GNUNET_CONFIGURATION_Handle *cfg;
118newServiceListeningInfo (const char *serviceName,
119 struct sockaddr *sa, socklen_t service_addr_len,
120 struct GNUNET_NETWORK_Handle *listeningSocket)
121{
122 struct ServiceListeningInfo *serviceListeningInfo =
123 GNUNET_malloc (sizeof (struct ServiceListeningInfo));
124 104
125 serviceListeningInfo->client_addr_len = 105static struct GNUNET_SCHEDULER_Handle *scheduler;
126 sizeof (serviceListeningInfo->client_addr); 106
127 serviceListeningInfo->serviceName = serviceName; 107static struct ServiceListeningInfo *serviceListeningInfoList_head;
128 serviceListeningInfo->service_addr = sa; 108
129 serviceListeningInfo->service_addr_len = service_addr_len; 109static struct ServiceListeningInfo *serviceListeningInfoList_tail;
130 serviceListeningInfo->listeningSocket = listeningSocket;
131 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
132 serviceListeningInfoList_tail,
133 serviceListeningInfo);
134 return serviceListeningInfo;
135}
136 110
137 111
138#if DEBUG_SERVICE_MANAGER 112#if DEBUG_SERVICE_MANAGER
139static void 113static void
140printDefaultServicesList () 114printDefaultServicesList ()
141{ 115{
142 int i; 116 unsigned int i;
143 for (i = 0; i < numDefaultServices; i++) 117 for (i = 0; i < numDefaultServices; i++)
144 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Service: %s\n", 118 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Service: %s\n",
145 defaultServicesList[i]); 119 defaultServicesList[i]);
@@ -153,30 +127,34 @@ printDefaultServicesList ()
153 * @param services space separated string of default services 127 * @param services space separated string of default services
154 */ 128 */
155static void 129static void
156addDefaultServicesToList (char *services) 130addDefaultServicesToList (const char *services)
157{ 131{
158 int i = 0; 132 unsigned int i = 0;
159 char *token; 133 char *token;
134 char *s;
160 135
161 /* How many services are there */ 136 if (strlen (services) == 0)
162 while (services[i] != '\0') 137 return;
138 s = GNUNET_strdup (services);
139 token = strtok (s, " ");
140 while (NULL != token)
163 { 141 {
164 if (services[i] == ' ') 142 numDefaultServices++;
165 { 143 token = strtok (NULL, " ");
166 numDefaultServices++;
167 }
168 i++;
169 } 144 }
170 numDefaultServices++; 145 GNUNET_free (s);
171 defaultServicesList = GNUNET_malloc (numDefaultServices * sizeof (char *));
172 token = strtok ((char *) services, " ");
173 146
147 defaultServicesList = GNUNET_malloc (numDefaultServices * sizeof (char *));
174 i = 0; 148 i = 0;
149 s = GNUNET_strdup (services);
150 token = strtok (s, " ");
175 while (NULL != token) 151 while (NULL != token)
176 { 152 {
177 defaultServicesList[i++] = token; 153 defaultServicesList[i++] = GNUNET_strdup (token);
178 token = strtok (NULL, " "); 154 token = strtok (NULL, " ");
179 } 155 }
156 GNUNET_free (s);
157 GNUNET_assert (i == numDefaultServices);
180} 158}
181 159
182/** 160/**
@@ -187,245 +165,217 @@ addDefaultServicesToList (char *services)
187static int 165static int
188isInDefaultList (const char *serviceName) 166isInDefaultList (const char *serviceName)
189{ 167{
190 int i; 168 unsigned int i;
191 for (i = 0; i < numDefaultServices; i++) 169 for (i = 0; i < numDefaultServices; i++)
192 { 170 if (strcmp (serviceName, defaultServicesList[i]) == 0)
193 if (strcmp (serviceName, defaultServicesList[i]) == 0) 171 return GNUNET_YES;
194 return GNUNET_YES;
195 }
196 return GNUNET_NO;
197}
198
199
200static int
201isServiceAlreadyStarted (const char *serviceName)
202{
203 struct StartedService *service;
204 service = startedServices;
205 while (NULL != service)
206 {
207 if (strcmp (service->serviceName, serviceName) == 0)
208 return GNUNET_OK;
209 service = service->next;
210 }
211 return GNUNET_NO; 172 return GNUNET_NO;
212} 173}
213 174
214 175
215static void 176static void
216setStartedService (const char *serviceName) 177closeClientAndServiceSockets (struct ForwardedConnection *fc, int reason)
217{
218 if (startedServices == NULL)
219 {
220 startedServices = GNUNET_malloc (sizeof (struct StartedService));
221 startedServices->serviceName = GNUNET_strdup (serviceName);
222 startedServices->next = NULL;
223 }
224 else
225 {
226 struct StartedService *service =
227 GNUNET_malloc (sizeof (struct StartedService));
228 service->serviceName = GNUNET_strdup (serviceName);
229 service->next = startedServices;
230 startedServices = service;
231 }
232}
233
234
235static void
236closeClientAndServiceSockets (struct ServiceInfo *serviceInfo, int reason)
237{ 178{
238 if (NULL != serviceInfo->armClientSocket) 179 if (NULL != fc->armClientSocket)
239 { 180 {
240 if (0 != (REASON_SERVICE & reason)) 181 if (0 != (REASON_SERVICE & reason))
241 GNUNET_SCHEDULER_cancel (scheduler, serviceInfo->clientReceivingTask); 182 GNUNET_SCHEDULER_cancel (scheduler, fc->clientReceivingTask);
242 if (GNUNET_SYSERR == 183 if (GNUNET_SYSERR ==
243 GNUNET_NETWORK_socket_close (serviceInfo->armClientSocket)) 184 GNUNET_NETWORK_socket_close (fc->armClientSocket))
244 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close"); 185 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
245 serviceInfo->armClientSocket = NULL; 186 fc->armClientSocket = NULL;
246 } 187 }
247 if (NULL != serviceInfo->armServiceSocket) 188 if (NULL != fc->armServiceSocket)
248 { 189 {
249 if (0 != (REASON_CLIENT & reason)) 190 if (0 != (REASON_CLIENT & reason))
250 GNUNET_SCHEDULER_cancel (scheduler, 191 GNUNET_SCHEDULER_cancel (scheduler,
251 serviceInfo->serviceReceivingTask); 192 fc->serviceReceivingTask);
252 193
253 if (GNUNET_SYSERR == 194 if (GNUNET_SYSERR ==
254 GNUNET_NETWORK_socket_close (serviceInfo->armServiceSocket)) 195 GNUNET_NETWORK_socket_close (fc->armServiceSocket))
255 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close"); 196 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "close");
256 serviceInfo->armServiceSocket = NULL; 197 fc->armServiceSocket = NULL;
257 } 198 }
258 199 GNUNET_free (fc->listen_info->serviceName);
259 GNUNET_free (serviceInfo); 200 GNUNET_free (fc->listen_info->service_addr);
201 GNUNET_free (fc->listen_info);
202 GNUNET_free (fc);
260} 203}
261 204
262 205
206static void
207receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
208
209static void
210receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
211
212
263/** 213/**
264 * Forward messages sent from service to client 214 * Forward messages sent from service to client
265 * 215 *
266 * @param cls callback data, for the communication between client and service 216 * @param cls callback data, struct ForwardedConnection for the communication between client and service
267 * @param tc context 217 * @param tc context
268 */ 218 */
269static void 219static void
270forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 220forwardToClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
271{ 221{
272 struct ServiceInfo *serviceInfo = cls; 222 struct ForwardedConnection *fc = cls;
273 ssize_t numberOfBytesSent; 223 ssize_t numberOfBytesSent;
274 224
275 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) 225 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
276 { 226 {
277 /* Ignore shutdown signal, reschedule yourself */ 227 /* Ignore shutdown signal, reschedule yourself */
278 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 228 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
279 serviceInfo->armClientSocket, 229 fc->armClientSocket,
280 &forwardToClient, serviceInfo); 230 &forwardToClient, fc);
281 return; 231 return;
282 } 232 }
283 233
284 /* Forwarding service response to client */ 234 /* Forwarding service response to client */
285 numberOfBytesSent = 235 numberOfBytesSent =
286 GNUNET_NETWORK_socket_send (serviceInfo->armClientSocket, 236 GNUNET_NETWORK_socket_send (fc->armClientSocket,
287 serviceInfo->serviceBufferPos, 237 fc->serviceBufferPos,
288 serviceInfo->serviceBufferDataLength); 238 fc->serviceBufferDataLength);
289 if ((numberOfBytesSent == GNUNET_SYSERR) || (numberOfBytesSent == 0)) 239 if ((numberOfBytesSent == GNUNET_SYSERR) || (numberOfBytesSent == 0))
290 { 240 {
291 /* Error occured or connection closed by client */ 241 /* Error occured or connection closed by client */
292 closeClientAndServiceSockets (serviceInfo, 242 closeClientAndServiceSockets (fc,
293 (REASON_CLIENT & REASON_SERVICE)); 243 (REASON_CLIENT & REASON_SERVICE));
294 return; 244 return;
295 } 245 }
296 else if (numberOfBytesSent < serviceInfo->serviceBufferDataLength) 246 else if (numberOfBytesSent < fc->serviceBufferDataLength)
297 { 247 {
298 /* Not all service data were sent to client */ 248 /* Not all service data were sent to client */
299 serviceInfo->serviceBufferPos += numberOfBytesSent; 249 fc->serviceBufferPos += numberOfBytesSent;
300 serviceInfo->serviceBufferDataLength = 250 fc->serviceBufferDataLength -= numberOfBytesSent;
301 serviceInfo->serviceBufferDataLength - numberOfBytesSent;
302 251
303 /* Scheduling writing again for completing the remaining data to be sent */ 252 /* Scheduling writing again for completing the remaining data to be sent */
304 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 253 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
305 serviceInfo->armClientSocket, 254 fc->armClientSocket,
306 &forwardToClient, serviceInfo); 255 &forwardToClient, fc);
307 } 256 }
308 else 257 else
309 { 258 {
310 /* Data completely sent */ 259 /* Data completely sent */
311 serviceInfo->serviceBufferPos = serviceInfo->serviceBuffer; 260 fc->serviceBufferPos = fc->serviceBuffer;
312 } 261 }
313 262
314 /* Now we are ready to receive more data, rescheduling receiving from Service */ 263 /* Now we are ready to receive more data, rescheduling receiving from Service */
315 serviceInfo->serviceReceivingTask = 264 fc->serviceReceivingTask =
316 GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 265 GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
317 serviceInfo->armServiceSocket, 266 fc->armServiceSocket,
318 &receiveFromService, serviceInfo); 267 &receiveFromService, fc);
319} 268}
320 269
321 270
322/** 271/**
323 * Receive service messages sent by the service and forward it to client 272 * Receive service messages sent by the service and forward it to client
324 * 273 *
325 * @param cls callback data, serviceInfo struct for the communication between client and service 274 * @param cls callback data, struct ForwardedConnection for the communication between client and service
326 * @param tc context 275 * @param tc context
327 */ 276 */
328static void 277static void
329receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 278receiveFromService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
330{ 279{
331 280 struct ForwardedConnection *fc = cls;
332 struct ServiceInfo *serviceInfo = cls;
333 281
334 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) 282 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
335 { 283 {
336 /* Neglect shutdown signal, reschedule yourself */ 284 /* Neglect shutdown signal, reschedule yourself */
337 serviceInfo->serviceReceivingTask = 285 fc->serviceReceivingTask =
338 GNUNET_SCHEDULER_add_read_net (scheduler, 286 GNUNET_SCHEDULER_add_read_net (scheduler,
339 GNUNET_TIME_UNIT_FOREVER_REL, 287 GNUNET_TIME_UNIT_FOREVER_REL,
340 serviceInfo->armServiceSocket, 288 fc->armServiceSocket,
341 &receiveFromService, serviceInfo); 289 &receiveFromService, fc);
342 return; 290 return;
343 } 291 }
344 292
345 serviceInfo->serviceBufferDataLength = 293 fc->serviceBufferDataLength =
346 GNUNET_NETWORK_socket_recv (serviceInfo->armServiceSocket, 294 GNUNET_NETWORK_socket_recv (fc->armServiceSocket,
347 serviceInfo->serviceBuffer, BUFFER_SIZE); 295 fc->serviceBuffer, BUFFER_SIZE);
348 296
349 if (serviceInfo->serviceBufferDataLength <= 0) 297 if (fc->serviceBufferDataLength <= 0)
350 { 298 {
351 /* The service has closed the connection or an error occured */ 299 /* The service has closed the connection or an error occured */
352 if (serviceInfo->serviceBufferDataLength == 0) 300 if (fc->serviceBufferDataLength == 0)
353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 301 {
354 _("Service `%s' closed connection! \n"), 302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
355 serviceInfo->serviceName); 303 _("Service `%s' closed connection! \n"),
304 fc->listen_info->serviceName);
305 }
356 else 306 else
357 { 307 {
358 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 308 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
359 _("Error receiving from service:%d\n"), errno); 309 _("Error receiving from service: %s\n"),
310 STRERROR (errno));
360 } 311 }
361 closeClientAndServiceSockets (serviceInfo, REASON_SERVICE); 312 closeClientAndServiceSockets (fc, REASON_SERVICE);
362 return; 313 return;
363 } 314 }
364 315
365 /* Forwarding Service data to Client */ 316 /* Forwarding Service data to Client */
366 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 317 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
367 serviceInfo->armClientSocket, 318 fc->armClientSocket,
368 &forwardToClient, serviceInfo); 319 &forwardToClient, fc);
369} 320}
370 321
371 322
372/** 323/**
373 * Forward client message to service 324 * Forward client message to service
374 * 325 *
375 * @param cls callback data, serviceInfo struct for the communication between client and service 326 * @param cls callback data, struct ForwardedConnection for the communication between client and service
376 * @param tc context 327 * @param tc context
377 */ 328 */
378static void 329static void
379forwardToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 330forwardToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
380{ 331{
381 struct ServiceInfo *serviceInfo = cls; 332 struct ForwardedConnection *fc = cls;
382 ssize_t numberOfBytesSent; 333 ssize_t numberOfBytesSent;
383 334
384 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) 335 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
385 { 336 {
386 /* Neglect shutdown signal, reschedule yourself */ 337 /* Neglect shutdown signal, reschedule ourself */
387 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 338 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
388 serviceInfo->armServiceSocket, 339 fc->armServiceSocket,
389 &forwardToService, serviceInfo); 340 &forwardToService, fc);
390 return; 341 return;
391 } 342 }
392 343
393 344
394 /* Forwarding client's message to service */ 345 /* Forwarding client's message to service */
395 numberOfBytesSent = 346 numberOfBytesSent =
396 GNUNET_NETWORK_socket_send (serviceInfo->armServiceSocket, 347 GNUNET_NETWORK_socket_send (fc->armServiceSocket,
397 serviceInfo->clientBufferPos, 348 fc->clientBufferPos,
398 serviceInfo->clientBufferDataLength); 349 fc->clientBufferDataLength);
399 if ((numberOfBytesSent == GNUNET_SYSERR) || (numberOfBytesSent == 0)) 350 if ((numberOfBytesSent == GNUNET_SYSERR) || (numberOfBytesSent == 0))
400 { 351 {
401 /* Error occured or connection closed by service */ 352 /* Error occured or connection closed by service */
402 closeClientAndServiceSockets (serviceInfo, 353 closeClientAndServiceSockets (fc,
403 (REASON_CLIENT & REASON_SERVICE)); 354 (REASON_CLIENT & REASON_SERVICE));
404 return; 355 return;
405 } 356 }
406 else if (numberOfBytesSent < serviceInfo->clientBufferDataLength) 357 if (numberOfBytesSent < fc->clientBufferDataLength)
407 { 358 {
408 /* Not all client data were sent to the service */ 359 /* Not all client data were sent to the service */
409 serviceInfo->clientBufferPos += numberOfBytesSent; 360 fc->clientBufferPos += numberOfBytesSent;
410 serviceInfo->clientBufferDataLength = 361 fc->clientBufferDataLength -= numberOfBytesSent;
411 serviceInfo->clientBufferDataLength - numberOfBytesSent;
412 362
413 /* Scheduling writing again for completing the remaining data to be sent */ 363 /* Scheduling writing again for completing the remaining data to be sent */
414 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 364 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
415 serviceInfo->armServiceSocket, 365 fc->armServiceSocket,
416 &forwardToService, serviceInfo); 366 &forwardToService, fc);
417 } 367 }
418 else 368 else
419 { 369 {
420 /* Data completely sent */ 370 /* Data completely sent */
421 serviceInfo->clientBufferPos = serviceInfo->clientBuffer; 371 fc->clientBufferPos = fc->clientBuffer;
422 } 372 }
423 373
424 /* Now, we are ready to receive more data. Rescheduling the receiving from client */ 374 /* Now, we are ready to receive more data. Rescheduling the receiving from client */
425 serviceInfo->clientReceivingTask = 375 fc->clientReceivingTask =
426 GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 376 GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
427 serviceInfo->armClientSocket, 377 fc->armClientSocket,
428 &receiveFromClient, serviceInfo); 378 &receiveFromClient, fc);
429} 379}
430 380
431 381
@@ -434,48 +384,49 @@ forwardToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
434 * Message sent from client to service (faked by ARM, since it's the first connection), 384 * Message sent from client to service (faked by ARM, since it's the first connection),
435 * ARM will receive the message and forward it to the running service 385 * ARM will receive the message and forward it to the running service
436 * 386 *
437 * @param cls callback data, serviceInfo struct for the communication between client and service 387 * @param cls callback data, struct ForwardedConnection for the communication between client and service
438 * @param tc context 388 * @param tc context
439 */ 389 */
440static void 390static void
441receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 391receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
442{ 392{
443 struct ServiceInfo *serviceInfo = cls; 393 struct ForwardedConnection *fc = cls;
444 394
445 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) 395 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
446 { 396 {
447 /* Neglect the shutdown signal, schedule yourself */ 397 /* Neglect the shutdown signal, schedule ourselves */
448 serviceInfo->clientReceivingTask = 398 fc->clientReceivingTask =
449 GNUNET_SCHEDULER_add_read_net (scheduler, 399 GNUNET_SCHEDULER_add_read_net (scheduler,
450 GNUNET_TIME_UNIT_FOREVER_REL, 400 GNUNET_TIME_UNIT_FOREVER_REL,
451 serviceInfo->armClientSocket, 401 fc->armClientSocket,
452 &receiveFromClient, serviceInfo); 402 &receiveFromClient, fc);
453 return; 403 return;
454 } 404 }
455 405
456 /* Receive client's message */ 406 /* Receive client's message */
457 serviceInfo->clientBufferDataLength = 407 fc->clientBufferDataLength =
458 GNUNET_NETWORK_socket_recv (serviceInfo->armClientSocket, 408 GNUNET_NETWORK_socket_recv (fc->armClientSocket,
459 serviceInfo->clientBuffer, BUFFER_SIZE); 409 fc->clientBuffer, BUFFER_SIZE);
460 410
461 if (serviceInfo->clientBufferDataLength <= 0) 411 if (fc->clientBufferDataLength <= 0)
462 { 412 {
463 /* The client has closed the connection or and error occured */ 413 /* The client has closed the connection or and error occured */
464 if (serviceInfo->clientBufferDataLength == 0) 414 if (fc->clientBufferDataLength == 0)
465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
466 _("Client closed connection with service:`%s'\n"), 416 _("Client closed connection with service:`%s'\n"),
467 serviceInfo->serviceName); 417 fc->listen_info->serviceName);
468 else 418 else
469 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
470 _("Error receiving from client!:%d \n"), errno); 420 _("Error receiving from client: %s \n"),
471 closeClientAndServiceSockets (serviceInfo, REASON_CLIENT); 421 STRERROR (errno));
422 closeClientAndServiceSockets (fc, REASON_CLIENT);
472 return; 423 return;
473 } 424 }
474 425
475 /* Forwarding request to service */ 426 /* Forwarding request to service */
476 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 427 GNUNET_SCHEDULER_add_write_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL,
477 serviceInfo->armServiceSocket, 428 fc->armServiceSocket,
478 &forwardToService, serviceInfo); 429 &forwardToService, fc);
479} 430}
480 431
481 432
@@ -483,21 +434,21 @@ receiveFromClient (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
483 * ARM connects to the just created service, 434 * ARM connects to the just created service,
484 * starts the processes for relaying messages between the client and the service 435 * starts the processes for relaying messages between the client and the service
485 * 436 *
486 * @param cls callback data, serviceInfo struct for the communication between client and service 437 * @param cls callback data, struct ForwardedConnection for the communication between client and service
487 * @param tc context 438 * @param tc context
488 */ 439 */
489static void 440static void
490connectToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 441connectToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
491{ 442{
492 struct ServiceInfo *serviceInfo = cls; 443 struct ForwardedConnection *fc = cls;
493 444
494 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) 445 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
495 { 446 {
496 /* Service is not up. Unable to proceed */ 447 /* Service is not up. Unable to proceed */
497 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 448 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
498 _("Unable to start service `%s': timeout\n"), 449 _("Unable to start service `%s': timeout\n"),
499 serviceInfo->serviceName); 450 fc->listen_info->serviceName);
500 closeClientAndServiceSockets (serviceInfo, 451 closeClientAndServiceSockets (fc,
501 (REASON_CLIENT & REASON_SERVICE)); 452 (REASON_CLIENT & REASON_SERVICE));
502 return; 453 return;
503 } 454 }
@@ -505,80 +456,72 @@ connectToService (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
505 { 456 {
506 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 457 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
507 _("Unable to start service `%s': shutdown\n"), 458 _("Unable to start service `%s': shutdown\n"),
508 serviceInfo->serviceName); 459 fc->listen_info->serviceName);
509 closeClientAndServiceSockets (serviceInfo, 460 closeClientAndServiceSockets (fc,
510 (REASON_CLIENT & REASON_SERVICE)); 461 (REASON_CLIENT & REASON_SERVICE));
511 return; 462 return;
512 } 463 }
513 GNUNET_break (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); 464 GNUNET_break (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE));
514 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Service `%s' started\n"), 465 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Service `%s' started\n"),
515 serviceInfo->serviceName); 466 fc->listen_info->serviceName);
516 467 fc->armServiceSocket =
517 /* Now service is up and running, connect to it */ 468 GNUNET_NETWORK_socket_create (fc->listen_info->service_addr->sa_family,
518 serviceInfo->armServiceSocket =
519 GNUNET_NETWORK_socket_create (serviceInfo->service_addr->sa_family,
520 SOCK_STREAM, 0); 469 SOCK_STREAM, 0);
521 if (NULL == serviceInfo->armServiceSocket) 470 if (NULL == fc->armServiceSocket)
522 { 471 {
523 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
524 _ 473 _ ("Unable to start service `%s': %s\n"),
525 ("Unable to start service `%s': failed to create socket\n"), 474 fc->listen_info->serviceName,
526 serviceInfo->serviceName); 475 STRERROR (errno));
527 closeClientAndServiceSockets (serviceInfo, 476 closeClientAndServiceSockets (fc,
528 (REASON_CLIENT & REASON_SERVICE)); 477 (REASON_CLIENT & REASON_SERVICE));
529 return; 478 return;
530 } 479 }
531
532 if ((GNUNET_SYSERR == 480 if ((GNUNET_SYSERR ==
533 GNUNET_NETWORK_socket_connect (serviceInfo->armServiceSocket, 481 GNUNET_NETWORK_socket_connect (fc->armServiceSocket,
534 serviceInfo->service_addr, 482 fc->listen_info->service_addr,
535 serviceInfo->service_addr_len)) 483 fc->listen_info->service_addr_len))
536 && (EINPROGRESS != errno)) 484 && (EINPROGRESS != errno))
537 { 485 {
538 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 486 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
539 _("Unable to start service `%s': failed to connect\n"), 487 _("Unable to start service `%s': failed to connect\n"),
540 serviceInfo->serviceName); 488 fc->listen_info->serviceName);
541 closeClientAndServiceSockets (serviceInfo, 489 closeClientAndServiceSockets (fc,
542 (REASON_CLIENT & REASON_SERVICE)); 490 (REASON_CLIENT & REASON_SERVICE));
543 return; 491 return;
544 } 492 }
545 /* Handling requests from client to service */ 493 fc->clientReceivingTask =
546 serviceInfo->clientReceivingTask = 494 GNUNET_SCHEDULER_add_read_net (scheduler,
547 GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 495 GNUNET_TIME_UNIT_FOREVER_REL,
548 serviceInfo->armClientSocket, 496 fc->armClientSocket,
549 &receiveFromClient, serviceInfo); 497 &receiveFromClient, fc);
550 498 fc->serviceReceivingTask =
551 /* Handling service responses to client */ 499 GNUNET_SCHEDULER_add_read_net (scheduler,
552 serviceInfo->serviceReceivingTask = 500 GNUNET_TIME_UNIT_FOREVER_REL,
553 GNUNET_SCHEDULER_add_read_net (scheduler, GNUNET_TIME_UNIT_FOREVER_REL, 501 fc->armServiceSocket,
554 serviceInfo->armServiceSocket, 502 &receiveFromService, fc);
555 &receiveFromService, serviceInfo);
556} 503}
557 504
558 505
559static void 506void stop_listening (const char *serviceName)
560stopServiceListeningSockets (struct ServiceListeningInfo
561 *serviceListeningInfo)
562{ 507{
563 struct ServiceListeningInfo *pos = serviceListeningInfoList_head; 508 struct ServiceListeningInfo *pos;
564 struct ServiceListeningInfo *tmp; 509 struct ServiceListeningInfo *next;
565 510
566 while (NULL != pos) 511 next = serviceListeningInfoList_head;
512 while (NULL != (pos = next))
567 { 513 {
568 if ((strcmp (pos->serviceName, serviceListeningInfo->serviceName) == 0) 514 next = pos->next;
569 && (pos != serviceListeningInfo)) 515 if (strcmp (pos->serviceName, serviceName) != 0)
570 { 516 continue;
571 GNUNET_SCHEDULER_cancel (scheduler, pos->acceptTask); 517 GNUNET_SCHEDULER_cancel (scheduler, pos->acceptTask);
572 GNUNET_NETWORK_socket_close (pos->listeningSocket); 518 GNUNET_NETWORK_socket_close (pos->listeningSocket);
573 tmp = pos; 519 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
574 pos = pos->next; 520 serviceListeningInfoList_tail,
575 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head, 521 pos);
576 serviceListeningInfoList_tail, tmp); 522 GNUNET_free (pos->serviceName);
577 GNUNET_free (tmp->service_addr); 523 GNUNET_free (pos->service_addr);
578 GNUNET_free (tmp); 524 GNUNET_free (pos);
579 continue;
580 }
581 pos = pos->next;
582 } 525 }
583} 526}
584 527
@@ -587,136 +530,124 @@ stopServiceListeningSockets (struct ServiceListeningInfo
587 * First connection has come to the listening socket associated with the service, 530 * First connection has come to the listening socket associated with the service,
588 * create the service in order to relay the incoming connection to it 531 * create the service in order to relay the incoming connection to it
589 * 532 *
590 * @param cls callback data, serviceInfo struct for the communication between client and service 533 * @param cls callback data, struct ServiceListeningInfo describing a listen socket
591 * @param tc context 534 * @param tc context
592 */ 535 */
593static void 536static void
594acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 537acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
595{ 538{
596 struct ServiceListeningInfo *serviceListeningInfo = cls; 539 struct ServiceListeningInfo *serviceListeningInfo = cls;
597 struct ServiceInfo *serviceInfo; 540 struct ForwardedConnection *fc;
598 541
542 serviceListeningInfo->acceptTask = GNUNET_SCHEDULER_NO_TASK;
599 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) 543 if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
600 return; 544 return;
601 545 fc = GNUNET_malloc (sizeof (struct ForwardedConnection));
602 if ((NULL == startedServices) 546 fc->listen_info = serviceListeningInfo;
603 || (GNUNET_NO == 547 fc->serviceBufferPos = fc->serviceBuffer;
604 isServiceAlreadyStarted (serviceListeningInfo->serviceName))) 548 fc->clientBufferPos = fc->clientBuffer;
549 fc->client_addr_len = sizeof (fc->client_addr);
550 fc->armClientSocket = GNUNET_NETWORK_socket_accept (serviceListeningInfo->listeningSocket,
551 (struct sockaddr*) fc->client_addr,
552 &fc->client_addr_len);
553 if (NULL == fc->armClientSocket)
605 { 554 {
606 /* First request to receive at all, or first request to connect to that service */ 555 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
607 /* Accept client's connection */ 556 _("Unable to accept connection for service `%s': %s\n"),
608 serviceInfo = 557 serviceListeningInfo->serviceName,
609 newServiceInfo (serviceListeningInfo->serviceName, 558 STRERROR (errno));
610 serviceListeningInfo->service_addr, 559 GNUNET_free (fc);
611 serviceListeningInfo->service_addr_len); 560 serviceListeningInfo->acceptTask =
612 serviceInfo->armClientSocket = 561 GNUNET_SCHEDULER_add_read_net (scheduler,
613 GNUNET_NETWORK_socket_accept (serviceListeningInfo->listeningSocket, 562 GNUNET_TIME_UNIT_FOREVER_REL,
614 &(serviceListeningInfo->client_addr), 563 serviceListeningInfo->listeningSocket,
615 &(serviceListeningInfo-> 564 &acceptConnection,
616 client_addr_len)); 565 serviceListeningInfo);
617 if (NULL == serviceInfo->armClientSocket) 566 return;
618 {
619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
620 _
621 ("Unable to accept connection for service `%s': Invalid socket\n"),
622 serviceListeningInfo->serviceName);
623 return;
624 }
625
626
627 /*
628 * Close listening socket, start service,
629 * and stop all listening sockets associated with that service
630 * and free their correspondent ServiceInfo objects
631 */
632 GNUNET_NETWORK_socket_close (serviceListeningInfo->listeningSocket);
633 start_service (NULL, serviceListeningInfo->serviceName);
634 setStartedService (serviceListeningInfo->serviceName);
635 stopServiceListeningSockets (serviceListeningInfo);
636
637 /* Notify me when the service is up and running */
638 GNUNET_CLIENT_service_test (scheduler,
639 serviceListeningInfo->serviceName, cfg,
640 TIMEOUT, &connectToService, serviceInfo);
641 } 567 }
568 GNUNET_NETWORK_socket_close (serviceListeningInfo->listeningSocket);
569 GNUNET_CONTAINER_DLL_remove (serviceListeningInfoList_head,
570 serviceListeningInfoList_tail,
571 serviceListeningInfo);
572 start_service (NULL, serviceListeningInfo->serviceName);
573 GNUNET_CLIENT_service_test (scheduler,
574 serviceListeningInfo->serviceName,
575 cfg,
576 TIMEOUT,
577 &connectToService,
578 fc);
642} 579}
643 580
644 581
645/** 582/**
646 * Creating a listening socket for each of the service's addresses and wait for the first incoming connection to it 583 * Creating a listening socket for each of the service's addresses and
584 * wait for the first incoming connection to it
647 * 585 *
648 * @param addrs list of addresses associated with the service 586 * @param sa address associated with the service
649 * @param addr_lens list containing length for each of the addresses in addrs 587 * @param addr_len length of sa
650 * @param numOfAddresses length of the addr_lens array
651 * @param serviceName the name of the service in question 588 * @param serviceName the name of the service in question
652 */ 589 */
653static void 590static void
654createListeningSocket (struct sockaddr **addrs, socklen_t * addr_lens, 591createListeningSocket (struct sockaddr *sa,
655 int numOfAddresses, char *serviceName) 592 socklen_t addr_len,
593 const char *serviceName)
656{ 594{
657 int i;
658 struct GNUNET_NETWORK_Handle *socket; 595 struct GNUNET_NETWORK_Handle *socket;
659 struct sockaddr *sa;
660 socklen_t addr_len;
661 struct ServiceListeningInfo *serviceListeningInfo; 596 struct ServiceListeningInfo *serviceListeningInfo;
662 597
663 for (i = 0; i < numOfAddresses; i++) 598 switch (sa->sa_family)
664 { 599 {
665 sa = addrs[i]; 600 case AF_INET:
666 addr_len = addr_lens[i]; 601 socket = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0);
667 switch (sa->sa_family) 602 break;
668 { 603 case AF_INET6:
669 case AF_INET: 604 socket = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
670 socket = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0); 605 break;
671 break; 606 default:
672 case AF_INET6: 607 socket = NULL;
673 socket = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); 608 break;
674 break; 609 }
675 default: 610 if (NULL == socket)
676 socket = NULL; 611 {
677 break; 612 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
678 } 613 "Unable to create socket for service %s", serviceName);
679 if (NULL == socket) 614 GNUNET_free (sa);
680 { 615 return;
681 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 616 }
682 "Unable to create socket for service %s", serviceName); 617 if (GNUNET_NETWORK_socket_bind
683 continue; 618 (socket, (const struct sockaddr *) sa, addr_len) != GNUNET_OK)
684 } 619 {
685 620 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
686 /* Bind */ 621 _("Unable to bind listening socket for service `%s'\n"),
687 if (GNUNET_NETWORK_socket_bind 622 serviceName);
688 (socket, (const struct sockaddr *) sa, addr_len) != GNUNET_OK) 623 GNUNET_free (sa);
689 { 624 return;
690 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 625 }
691 _("Unable to bind listening socket for service `%s'\n"), 626 if (GNUNET_NETWORK_socket_listen (socket, 5) != GNUNET_OK)
692 serviceName); 627 {
693 continue; 628 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
694 } 629 _("Error listening socket for service `%s'\n"),
695 630 serviceName);
696 /* Listen */ 631 GNUNET_NETWORK_socket_close (socket);
697 if (GNUNET_NETWORK_socket_listen (socket, 5) != GNUNET_OK) 632 GNUNET_free (sa);
698 { 633 return;
699 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
700 _("Error listening socket for service `%s'\n"),
701 serviceName);
702 }
703
704 serviceListeningInfo =
705 newServiceListeningInfo (serviceName, sa, addr_len, socket);
706 serviceListeningInfo->listeningSocket = socket;
707 serviceListeningInfo->serviceName = serviceName;
708 serviceListeningInfo->service_addr = sa;
709 serviceListeningInfo->service_addr_len = addr_len;
710
711 /* Wait for the first incoming connection */
712 serviceListeningInfo->acceptTask =
713 GNUNET_SCHEDULER_add_read_net (scheduler,
714 GNUNET_TIME_UNIT_FOREVER_REL, socket,
715 &acceptConnection,
716 serviceListeningInfo);
717 } 634 }
635 serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo));
636 serviceListeningInfo->serviceName = GNUNET_strdup (serviceName);
637 serviceListeningInfo->service_addr = sa;
638 serviceListeningInfo->service_addr_len = addr_len;
639 serviceListeningInfo->listeningSocket = socket;
640 serviceListeningInfo->acceptTask =
641 GNUNET_SCHEDULER_add_read_net (scheduler,
642 GNUNET_TIME_UNIT_FOREVER_REL, socket,
643 &acceptConnection,
644 serviceListeningInfo);
645 GNUNET_CONTAINER_DLL_insert (serviceListeningInfoList_head,
646 serviceListeningInfoList_tail,
647 serviceListeningInfo);
718} 648}
719 649
650
720/** 651/**
721 * Callback function, checks whether the current tokens are representing a service, 652 * Callback function, checks whether the current tokens are representing a service,
722 * gets its addresses and create listening socket for it. 653 * gets its addresses and create listening socket for it.
@@ -728,37 +659,30 @@ createListeningSocket (struct sockaddr **addrs, socklen_t * addr_lens,
728 */ 659 */
729static void 660static void
730checkPortNumberCB (void *cls, 661checkPortNumberCB (void *cls,
731 const char *section, const char *option, const char *value) 662 const char *section,
663 const char *option,
664 const char *value)
732{ 665{
733 /* The service shouldn't be a default service */ 666 struct sockaddr **addrs;
734 if ((strcmp (section, "arm") != 0) 667 socklen_t *addr_lens;
735 && (strcmp (option, "PORT") == 0) 668 int ret;
736 && (isInDefaultList (section) == GNUNET_NO)) 669 unsigned int i;
737 { 670
738 /* then the section is representing a service */ 671 if ( (strcmp (section, "arm") == 0) ||
739 struct sockaddr **addrs; 672 (strcmp (option, "PORT") != 0) ||
740 socklen_t *addr_lens; 673 (isInDefaultList (section) == GNUNET_YES) )
741 int ret; 674 return;
742 675 if (0 >= (ret = GNUNET_SERVICE_get_server_addresses (section, cfg, &addrs,
743 ret = 676 &addr_lens)))
744 GNUNET_SERVICE_get_server_addresses (section, cfg, &addrs, 677 return;
745 &addr_lens); 678 /* this will free (or capture) addrs[i] for i in 0..ret */
746 if (ret == GNUNET_SYSERR) 679 for (i = 0; i < ret; i++)
747 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 680 createListeningSocket (addrs[i], addr_lens[i], section);
748 _("Unable to resolve host name for service `%s'\n"), 681 GNUNET_free (addrs);
749 section); 682 GNUNET_free (addr_lens);
750 else if (ret != GNUNET_NO)
751 {
752 /* Addresses found for service */
753 createListeningSocket (addrs, addr_lens, ret, (char *) section);
754 }
755 else
756 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
757 _("No addresses for service `%s' in configuration\n"),
758 section);
759 }
760} 683}
761 684
685
762/** 686/**
763 * Entry point to the Service Manager 687 * Entry point to the Service Manager
764 * 688 *
@@ -770,18 +694,17 @@ prepareServices (const struct GNUNET_CONFIGURATION_Handle
770 *configurationHandle, struct GNUNET_SCHEDULER_Handle *sched) 694 *configurationHandle, struct GNUNET_SCHEDULER_Handle *sched)
771{ 695{
772 char *defaultServicesString; 696 char *defaultServicesString;
697
773 scheduler = sched; 698 scheduler = sched;
774 cfg = configurationHandle; 699 cfg = configurationHandle;
775
776 /* Split the default services into a list */ 700 /* Split the default services into a list */
777 GNUNET_CONFIGURATION_get_value_string (cfg, "arm", "DEFAULTSERVICES", 701 GNUNET_CONFIGURATION_get_value_string (cfg, "arm", "DEFAULTSERVICES",
778 &defaultServicesString); 702 &defaultServicesString);
779 addDefaultServicesToList (defaultServicesString); 703 addDefaultServicesToList (defaultServicesString);
780 704 GNUNET_free (defaultServicesString);
781#if DEBUG_SERVICE_MANAGER 705#if DEBUG_SERVICE_MANAGER
782 printDefaultServicesList (); 706 printDefaultServicesList ();
783#endif 707#endif
784
785 /* Spot the services from the configuration and create a listening socket for each */ 708 /* Spot the services from the configuration and create a listening socket for each */
786 GNUNET_CONFIGURATION_iterate (cfg, &checkPortNumberCB, NULL); 709 GNUNET_CONFIGURATION_iterate (cfg, &checkPortNumberCB, NULL);
787} 710}
diff --git a/src/arm/gnunet_service_arm_.h b/src/arm/gnunet_service_arm_.h
index fe31b688c..d44f22864 100644
--- a/src/arm/gnunet_service_arm_.h
+++ b/src/arm/gnunet_service_arm_.h
@@ -1,3 +1,23 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors)
4
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
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
1/** 21/**
2 * @file arm/gnunet_service_arm_.h 22 * @file arm/gnunet_service_arm_.h
3 * @brief function prototypes for gnunet_service_arm.c, and gnunet_service_manager.c 23 * @brief function prototypes for gnunet_service_arm.c, and gnunet_service_manager.c
@@ -9,6 +29,9 @@
9 29
10void start_service (struct GNUNET_SERVER_Client *client, 30void start_service (struct GNUNET_SERVER_Client *client,
11 const char *servicename); 31 const char *servicename);
32
33void stop_listening (const char *serviceName);
34
12void prepareServices (const struct GNUNET_CONFIGURATION_Handle 35void prepareServices (const struct GNUNET_CONFIGURATION_Handle
13 *configurationHandle, 36 *configurationHandle,
14 struct GNUNET_SCHEDULER_Handle *sched); 37 struct GNUNET_SCHEDULER_Handle *sched);
diff --git a/src/statistics/test_statistics_api_data.conf b/src/statistics/test_statistics_api_data.conf
index 7f69a74ad..41cfd9596 100644
--- a/src/statistics/test_statistics_api_data.conf
+++ b/src/statistics/test_statistics_api_data.conf
@@ -7,4 +7,6 @@ PORT = 22353
7 7
8[arm] 8[arm]
9PORT = 22354 9PORT = 22354
10DEFAULTSERVICES = 10DEFAULTSERVICES =
11# DEBUG = YES
12
diff --git a/src/util/server.c b/src/util/server.c
index e34897f76..832f4ed58 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -480,7 +480,7 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
480 if (j == 0) 480 if (j == 0)
481 { 481 {
482 if (errno != 0) 482 if (errno != 0)
483 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); 483 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
484 GNUNET_free (lsocks); 484 GNUNET_free (lsocks);
485 lsocks = NULL; 485 lsocks = NULL;
486 } 486 }