diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/client.c | 1000 | ||||
-rw-r--r-- | src/util/service.c | 2181 |
2 files changed, 1676 insertions, 1505 deletions
diff --git a/src/util/client.c b/src/util/client.c index e3585af2e..d431909cf 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2001-2016 GNUnet e.V. | 3 | Copyright (C) 2001-2016, 2019 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -33,7 +33,7 @@ | |||
33 | #include "gnunet_socks.h" | 33 | #include "gnunet_socks.h" |
34 | 34 | ||
35 | 35 | ||
36 | #define LOG(kind, ...) GNUNET_log_from(kind, "util-client", __VA_ARGS__) | 36 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-client", __VA_ARGS__) |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * Timeout we use on TCP connect before trying another | 39 | * Timeout we use on TCP connect before trying another |
@@ -41,7 +41,8 @@ | |||
41 | * is this value divided by the number of address families. | 41 | * is this value divided by the number of address families. |
42 | * Default is 5s. | 42 | * Default is 5s. |
43 | */ | 43 | */ |
44 | #define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5) | 44 | #define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply ( \ |
45 | GNUNET_TIME_UNIT_SECONDS, 5) | ||
45 | 46 | ||
46 | 47 | ||
47 | 48 | ||
@@ -55,7 +56,8 @@ struct ClientState; | |||
55 | * During connect, we try multiple possible IP addresses | 56 | * During connect, we try multiple possible IP addresses |
56 | * to find out which one might work. | 57 | * to find out which one might work. |
57 | */ | 58 | */ |
58 | struct AddressProbe { | 59 | struct AddressProbe |
60 | { | ||
59 | /** | 61 | /** |
60 | * This is a linked list. | 62 | * This is a linked list. |
61 | */ | 63 | */ |
@@ -96,7 +98,8 @@ struct AddressProbe { | |||
96 | /** | 98 | /** |
97 | * Internal state for a client connected to a GNUnet service. | 99 | * Internal state for a client connected to a GNUnet service. |
98 | */ | 100 | */ |
99 | struct ClientState { | 101 | struct ClientState |
102 | { | ||
100 | /** | 103 | /** |
101 | * The connection handle, NULL if not live | 104 | * The connection handle, NULL if not live |
102 | */ | 105 | */ |
@@ -205,7 +208,7 @@ struct ClientState { | |||
205 | * @param cls the `struct ClientState` to try to connect to the service | 208 | * @param cls the `struct ClientState` to try to connect to the service |
206 | */ | 209 | */ |
207 | static void | 210 | static void |
208 | start_connect(void *cls); | 211 | start_connect (void *cls); |
209 | 212 | ||
210 | 213 | ||
211 | /** | 214 | /** |
@@ -215,26 +218,26 @@ start_connect(void *cls); | |||
215 | * @param cstate the connection we tried to establish | 218 | * @param cstate the connection we tried to establish |
216 | */ | 219 | */ |
217 | static void | 220 | static void |
218 | connect_fail_continuation(struct ClientState *cstate) | 221 | connect_fail_continuation (struct ClientState *cstate) |
219 | { | 222 | { |
220 | GNUNET_break(NULL == cstate->ap_head); | 223 | GNUNET_break (NULL == cstate->ap_head); |
221 | GNUNET_break(NULL == cstate->ap_tail); | 224 | GNUNET_break (NULL == cstate->ap_tail); |
222 | GNUNET_break(NULL == cstate->dns_active); | 225 | GNUNET_break (NULL == cstate->dns_active); |
223 | GNUNET_break(NULL == cstate->sock); | 226 | GNUNET_break (NULL == cstate->sock); |
224 | GNUNET_assert(NULL == cstate->send_task); | 227 | GNUNET_assert (NULL == cstate->send_task); |
225 | GNUNET_assert(NULL == cstate->recv_task); | 228 | GNUNET_assert (NULL == cstate->recv_task); |
226 | // GNUNET_assert (NULL == cstate->proxy_handshake); | 229 | // GNUNET_assert (NULL == cstate->proxy_handshake); |
227 | 230 | ||
228 | cstate->back_off = GNUNET_TIME_STD_BACKOFF(cstate->back_off); | 231 | cstate->back_off = GNUNET_TIME_STD_BACKOFF (cstate->back_off); |
229 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 232 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
230 | "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n", | 233 | "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n", |
231 | cstate->service_name, | 234 | cstate->service_name, |
232 | GNUNET_STRINGS_relative_time_to_string(cstate->back_off, | 235 | GNUNET_STRINGS_relative_time_to_string (cstate->back_off, |
233 | GNUNET_YES)); | 236 | GNUNET_YES)); |
234 | cstate->retry_task | 237 | cstate->retry_task |
235 | = GNUNET_SCHEDULER_add_delayed(cstate->back_off, | 238 | = GNUNET_SCHEDULER_add_delayed (cstate->back_off, |
236 | &start_connect, | 239 | &start_connect, |
237 | cstate); | 240 | cstate); |
238 | } | 241 | } |
239 | 242 | ||
240 | 243 | ||
@@ -244,7 +247,7 @@ connect_fail_continuation(struct ClientState *cstate) | |||
244 | * @param cls the `struct ClientState` with the `msg` to transmit | 247 | * @param cls the `struct ClientState` with the `msg` to transmit |
245 | */ | 248 | */ |
246 | static void | 249 | static void |
247 | transmit_ready(void *cls) | 250 | transmit_ready (void *cls) |
248 | { | 251 | { |
249 | struct ClientState *cstate = cls; | 252 | struct ClientState *cstate = cls; |
250 | ssize_t ret; | 253 | ssize_t ret; |
@@ -255,56 +258,56 @@ transmit_ready(void *cls) | |||
255 | cstate->send_task = NULL; | 258 | cstate->send_task = NULL; |
256 | if (GNUNET_YES == cstate->in_destroy) | 259 | if (GNUNET_YES == cstate->in_destroy) |
257 | return; | 260 | return; |
258 | pos = (const char *)cstate->msg; | 261 | pos = (const char *) cstate->msg; |
259 | len = ntohs(cstate->msg->size); | 262 | len = ntohs (cstate->msg->size); |
260 | GNUNET_assert(cstate->msg_off < len); | 263 | GNUNET_assert (cstate->msg_off < len); |
261 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 264 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
262 | "message of type %u trying to send with socket %p (MQ: %p\n", | 265 | "message of type %u trying to send with socket %p (MQ: %p\n", |
263 | ntohs(cstate->msg->type), | 266 | ntohs (cstate->msg->type), |
264 | cstate->sock, | 267 | cstate->sock, |
265 | cstate->mq); | 268 | cstate->mq); |
266 | 269 | ||
267 | RETRY: | 270 | RETRY: |
268 | ret = GNUNET_NETWORK_socket_send(cstate->sock, | 271 | ret = GNUNET_NETWORK_socket_send (cstate->sock, |
269 | &pos[cstate->msg_off], | 272 | &pos[cstate->msg_off], |
270 | len - cstate->msg_off); | 273 | len - cstate->msg_off); |
271 | if (-1 == ret) | 274 | if (-1 == ret) |
275 | { | ||
276 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
277 | "Error during sending message of type %u\n", | ||
278 | ntohs (cstate->msg->type)); | ||
279 | if (EINTR == errno) | ||
272 | { | 280 | { |
273 | LOG(GNUNET_ERROR_TYPE_WARNING, | 281 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
274 | "Error during sending message of type %u\n", | 282 | "Retrying message of type %u\n", |
275 | ntohs(cstate->msg->type)); | 283 | ntohs (cstate->msg->type)); |
276 | if (EINTR == errno) | 284 | goto RETRY; |
277 | { | ||
278 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
279 | "Retrying message of type %u\n", | ||
280 | ntohs(cstate->msg->type)); | ||
281 | goto RETRY; | ||
282 | } | ||
283 | GNUNET_MQ_inject_error(cstate->mq, | ||
284 | GNUNET_MQ_ERROR_WRITE); | ||
285 | return; | ||
286 | } | 285 | } |
286 | GNUNET_MQ_inject_error (cstate->mq, | ||
287 | GNUNET_MQ_ERROR_WRITE); | ||
288 | return; | ||
289 | } | ||
287 | notify_in_flight = (0 == cstate->msg_off); | 290 | notify_in_flight = (0 == cstate->msg_off); |
288 | cstate->msg_off += ret; | 291 | cstate->msg_off += ret; |
289 | if (cstate->msg_off < len) | 292 | if (cstate->msg_off < len) |
290 | { | 293 | { |
291 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 294 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
292 | "rescheduling message of type %u\n", | 295 | "rescheduling message of type %u\n", |
293 | ntohs(cstate->msg->type)); | 296 | ntohs (cstate->msg->type)); |
294 | cstate->send_task | 297 | cstate->send_task |
295 | = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 298 | = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
296 | cstate->sock, | 299 | cstate->sock, |
297 | &transmit_ready, | 300 | &transmit_ready, |
298 | cstate); | 301 | cstate); |
299 | if (notify_in_flight) | 302 | if (notify_in_flight) |
300 | GNUNET_MQ_impl_send_in_flight(cstate->mq); | 303 | GNUNET_MQ_impl_send_in_flight (cstate->mq); |
301 | return; | 304 | return; |
302 | } | 305 | } |
303 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 306 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
304 | "sending message of type %u successful\n", | 307 | "sending message of type %u successful\n", |
305 | ntohs(cstate->msg->type)); | 308 | ntohs (cstate->msg->type)); |
306 | cstate->msg = NULL; | 309 | cstate->msg = NULL; |
307 | GNUNET_MQ_impl_send_continue(cstate->mq); | 310 | GNUNET_MQ_impl_send_continue (cstate->mq); |
308 | } | 311 | } |
309 | 312 | ||
310 | 313 | ||
@@ -319,20 +322,20 @@ RETRY: | |||
319 | * #GNUNET_SYSERR to stop further processing due to error | 322 | * #GNUNET_SYSERR to stop further processing due to error |
320 | */ | 323 | */ |
321 | static int | 324 | static int |
322 | recv_message(void *cls, | 325 | recv_message (void *cls, |
323 | const struct GNUNET_MessageHeader *msg) | 326 | const struct GNUNET_MessageHeader *msg) |
324 | { | 327 | { |
325 | struct ClientState *cstate = cls; | 328 | struct ClientState *cstate = cls; |
326 | 329 | ||
327 | if (GNUNET_YES == cstate->in_destroy) | 330 | if (GNUNET_YES == cstate->in_destroy) |
328 | return GNUNET_NO; | 331 | return GNUNET_NO; |
329 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 332 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
330 | "Received message of type %u and size %u from %s\n", | 333 | "Received message of type %u and size %u from %s\n", |
331 | ntohs(msg->type), | 334 | ntohs (msg->type), |
332 | ntohs(msg->size), | 335 | ntohs (msg->size), |
333 | cstate->service_name); | 336 | cstate->service_name); |
334 | GNUNET_MQ_inject_message(cstate->mq, | 337 | GNUNET_MQ_inject_message (cstate->mq, |
335 | msg); | 338 | msg); |
336 | if (GNUNET_YES == cstate->in_destroy) | 339 | if (GNUNET_YES == cstate->in_destroy) |
337 | return GNUNET_NO; | 340 | return GNUNET_NO; |
338 | return GNUNET_OK; | 341 | return GNUNET_OK; |
@@ -345,20 +348,20 @@ recv_message(void *cls, | |||
345 | * @param cstate handle of the client state to process | 348 | * @param cstate handle of the client state to process |
346 | */ | 349 | */ |
347 | static void | 350 | static void |
348 | cancel_aps(struct ClientState *cstate) | 351 | cancel_aps (struct ClientState *cstate) |
349 | { | 352 | { |
350 | struct AddressProbe *pos; | 353 | struct AddressProbe *pos; |
351 | 354 | ||
352 | while (NULL != (pos = cstate->ap_head)) | 355 | while (NULL != (pos = cstate->ap_head)) |
353 | { | 356 | { |
354 | GNUNET_break(GNUNET_OK == | 357 | GNUNET_break (GNUNET_OK == |
355 | GNUNET_NETWORK_socket_close(pos->sock)); | 358 | GNUNET_NETWORK_socket_close (pos->sock)); |
356 | GNUNET_SCHEDULER_cancel(pos->task); | 359 | GNUNET_SCHEDULER_cancel (pos->task); |
357 | GNUNET_CONTAINER_DLL_remove(cstate->ap_head, | 360 | GNUNET_CONTAINER_DLL_remove (cstate->ap_head, |
358 | cstate->ap_tail, | 361 | cstate->ap_tail, |
359 | pos); | 362 | pos); |
360 | GNUNET_free(pos); | 363 | GNUNET_free (pos); |
361 | } | 364 | } |
362 | } | 365 | } |
363 | 366 | ||
364 | 367 | ||
@@ -370,51 +373,51 @@ cancel_aps(struct ClientState *cstate) | |||
370 | * @param impl_state our `struct ClientState` | 373 | * @param impl_state our `struct ClientState` |
371 | */ | 374 | */ |
372 | static void | 375 | static void |
373 | connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, | 376 | connection_client_destroy_impl (struct GNUNET_MQ_Handle *mq, |
374 | void *impl_state) | 377 | void *impl_state) |
375 | { | 378 | { |
376 | struct ClientState *cstate = impl_state; | 379 | struct ClientState *cstate = impl_state; |
377 | 380 | ||
378 | (void)mq; | 381 | (void) mq; |
379 | if (NULL != cstate->dns_active) | 382 | if (NULL != cstate->dns_active) |
380 | { | 383 | { |
381 | GNUNET_RESOLVER_request_cancel(cstate->dns_active); | 384 | GNUNET_RESOLVER_request_cancel (cstate->dns_active); |
382 | cstate->dns_active = NULL; | 385 | cstate->dns_active = NULL; |
383 | } | 386 | } |
384 | if (NULL != cstate->send_task) | 387 | if (NULL != cstate->send_task) |
385 | { | 388 | { |
386 | GNUNET_SCHEDULER_cancel(cstate->send_task); | 389 | GNUNET_SCHEDULER_cancel (cstate->send_task); |
387 | cstate->send_task = NULL; | 390 | cstate->send_task = NULL; |
388 | } | 391 | } |
389 | if (NULL != cstate->retry_task) | 392 | if (NULL != cstate->retry_task) |
390 | { | 393 | { |
391 | GNUNET_SCHEDULER_cancel(cstate->retry_task); | 394 | GNUNET_SCHEDULER_cancel (cstate->retry_task); |
392 | cstate->retry_task = NULL; | 395 | cstate->retry_task = NULL; |
393 | } | 396 | } |
394 | if (GNUNET_SYSERR == cstate->in_destroy) | 397 | if (GNUNET_SYSERR == cstate->in_destroy) |
395 | { | 398 | { |
396 | /* defer destruction */ | 399 | /* defer destruction */ |
397 | cstate->in_destroy = GNUNET_YES; | 400 | cstate->in_destroy = GNUNET_YES; |
398 | cstate->mq = NULL; | 401 | cstate->mq = NULL; |
399 | return; | 402 | return; |
400 | } | 403 | } |
401 | if (NULL != cstate->recv_task) | 404 | if (NULL != cstate->recv_task) |
402 | { | 405 | { |
403 | GNUNET_SCHEDULER_cancel(cstate->recv_task); | 406 | GNUNET_SCHEDULER_cancel (cstate->recv_task); |
404 | cstate->recv_task = NULL; | 407 | cstate->recv_task = NULL; |
405 | } | 408 | } |
406 | if (NULL != cstate->sock) | 409 | if (NULL != cstate->sock) |
407 | { | 410 | { |
408 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 411 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
409 | "destroying socket: %p\n", | 412 | "destroying socket: %p\n", |
410 | cstate->sock); | 413 | cstate->sock); |
411 | GNUNET_NETWORK_socket_close(cstate->sock); | 414 | GNUNET_NETWORK_socket_close (cstate->sock); |
412 | } | 415 | } |
413 | cancel_aps(cstate); | 416 | cancel_aps (cstate); |
414 | GNUNET_free(cstate->service_name); | 417 | GNUNET_free (cstate->service_name); |
415 | GNUNET_free_non_null(cstate->hostname); | 418 | GNUNET_free_non_null (cstate->hostname); |
416 | GNUNET_MST_destroy(cstate->mst); | 419 | GNUNET_MST_destroy (cstate->mst); |
417 | GNUNET_free(cstate); | 420 | GNUNET_free (cstate); |
418 | } | 421 | } |
419 | 422 | ||
420 | 423 | ||
@@ -424,39 +427,39 @@ connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq, | |||
424 | * @param cls `struct ClientState` with connection to read from | 427 | * @param cls `struct ClientState` with connection to read from |
425 | */ | 428 | */ |
426 | static void | 429 | static void |
427 | receive_ready(void *cls) | 430 | receive_ready (void *cls) |
428 | { | 431 | { |
429 | struct ClientState *cstate = cls; | 432 | struct ClientState *cstate = cls; |
430 | int ret; | 433 | int ret; |
431 | 434 | ||
432 | cstate->recv_task = NULL; | 435 | cstate->recv_task = NULL; |
433 | cstate->in_destroy = GNUNET_SYSERR; | 436 | cstate->in_destroy = GNUNET_SYSERR; |
434 | ret = GNUNET_MST_read(cstate->mst, | 437 | ret = GNUNET_MST_read (cstate->mst, |
435 | cstate->sock, | 438 | cstate->sock, |
436 | GNUNET_NO, | 439 | GNUNET_NO, |
437 | GNUNET_NO); | 440 | GNUNET_NO); |
438 | if (GNUNET_SYSERR == ret) | 441 | if (GNUNET_SYSERR == ret) |
439 | { | 442 | { |
440 | if (NULL != cstate->mq) | 443 | if (NULL != cstate->mq) |
441 | GNUNET_MQ_inject_error(cstate->mq, | 444 | GNUNET_MQ_inject_error (cstate->mq, |
442 | GNUNET_MQ_ERROR_READ); | 445 | GNUNET_MQ_ERROR_READ); |
443 | if (GNUNET_YES == cstate->in_destroy) | 446 | if (GNUNET_YES == cstate->in_destroy) |
444 | connection_client_destroy_impl(cstate->mq, | 447 | connection_client_destroy_impl (cstate->mq, |
445 | cstate); | 448 | cstate); |
446 | return; | 449 | return; |
447 | } | 450 | } |
448 | if (GNUNET_YES == cstate->in_destroy) | 451 | if (GNUNET_YES == cstate->in_destroy) |
449 | { | 452 | { |
450 | connection_client_destroy_impl(cstate->mq, | 453 | connection_client_destroy_impl (cstate->mq, |
451 | cstate); | 454 | cstate); |
452 | return; | 455 | return; |
453 | } | 456 | } |
454 | cstate->in_destroy = GNUNET_NO; | 457 | cstate->in_destroy = GNUNET_NO; |
455 | cstate->recv_task | 458 | cstate->recv_task |
456 | = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 459 | = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
457 | cstate->sock, | 460 | cstate->sock, |
458 | &receive_ready, | 461 | &receive_ready, |
459 | cstate); | 462 | cstate); |
460 | } | 463 | } |
461 | 464 | ||
462 | 465 | ||
@@ -466,23 +469,23 @@ receive_ready(void *cls) | |||
466 | * @param cstate the connection we tried to establish | 469 | * @param cstate the connection we tried to establish |
467 | */ | 470 | */ |
468 | static void | 471 | static void |
469 | connect_success_continuation(struct ClientState *cstate) | 472 | connect_success_continuation (struct ClientState *cstate) |
470 | { | 473 | { |
471 | GNUNET_assert(NULL == cstate->recv_task); | 474 | GNUNET_assert (NULL == cstate->recv_task); |
472 | cstate->recv_task | 475 | cstate->recv_task |
473 | = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 476 | = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
474 | cstate->sock, | 477 | cstate->sock, |
475 | &receive_ready, | 478 | &receive_ready, |
476 | cstate); | 479 | cstate); |
477 | if (NULL != cstate->msg) | 480 | if (NULL != cstate->msg) |
478 | { | 481 | { |
479 | GNUNET_assert(NULL == cstate->send_task); | 482 | GNUNET_assert (NULL == cstate->send_task); |
480 | cstate->send_task | 483 | cstate->send_task |
481 | = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 484 | = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
482 | cstate->sock, | 485 | cstate->sock, |
483 | &transmit_ready, | 486 | &transmit_ready, |
484 | cstate); | 487 | cstate); |
485 | } | 488 | } |
486 | } | 489 | } |
487 | 490 | ||
488 | 491 | ||
@@ -494,8 +497,8 @@ connect_success_continuation(struct ClientState *cstate) | |||
494 | * @return NULL on error, socket connected to UNIX otherwise | 497 | * @return NULL on error, socket connected to UNIX otherwise |
495 | */ | 498 | */ |
496 | static struct GNUNET_NETWORK_Handle * | 499 | static struct GNUNET_NETWORK_Handle * |
497 | try_unixpath(const char *service_name, | 500 | try_unixpath (const char *service_name, |
498 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 501 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
499 | { | 502 | { |
500 | #if AF_UNIX | 503 | #if AF_UNIX |
501 | struct GNUNET_NETWORK_Handle *sock; | 504 | struct GNUNET_NETWORK_Handle *sock; |
@@ -504,67 +507,56 @@ try_unixpath(const char *service_name, | |||
504 | 507 | ||
505 | unixpath = NULL; | 508 | unixpath = NULL; |
506 | if ((GNUNET_OK == | 509 | if ((GNUNET_OK == |
507 | GNUNET_CONFIGURATION_get_value_filename(cfg, | 510 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
508 | service_name, | 511 | service_name, |
509 | "UNIXPATH", | 512 | "UNIXPATH", |
510 | &unixpath)) && | 513 | &unixpath)) && |
511 | (0 < strlen(unixpath))) | 514 | (0 < strlen (unixpath))) |
515 | { | ||
516 | /* We have a non-NULL unixpath, need to validate it */ | ||
517 | if (strlen (unixpath) >= sizeof(s_un.sun_path)) | ||
512 | { | 518 | { |
513 | /* We have a non-NULL unixpath, need to validate it */ | 519 | LOG (GNUNET_ERROR_TYPE_WARNING, |
514 | if (strlen(unixpath) >= sizeof(s_un.sun_path)) | 520 | _ ("UNIXPATH `%s' too long, maximum length is %llu\n"), |
515 | { | 521 | unixpath, |
516 | LOG(GNUNET_ERROR_TYPE_WARNING, | 522 | (unsigned long long) sizeof(s_un.sun_path)); |
517 | _("UNIXPATH `%s' too long, maximum length is %llu\n"), | 523 | unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); |
518 | unixpath, | 524 | LOG (GNUNET_ERROR_TYPE_INFO, |
519 | (unsigned long long)sizeof(s_un.sun_path)); | 525 | _ ("Using `%s' instead\n"), |
520 | unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath); | 526 | unixpath); |
521 | LOG(GNUNET_ERROR_TYPE_INFO, | 527 | if (NULL == unixpath) |
522 | _("Using `%s' instead\n"), | 528 | return NULL; |
523 | unixpath); | 529 | } |
524 | if (NULL == unixpath) | 530 | memset (&s_un, |
525 | return NULL; | 531 | 0, |
526 | } | 532 | sizeof(s_un)); |
527 | memset(&s_un, | 533 | s_un.sun_family = AF_UNIX; |
528 | 0, | 534 | GNUNET_strlcpy (s_un.sun_path, |
529 | sizeof(s_un)); | 535 | unixpath, |
530 | s_un.sun_family = AF_UNIX; | 536 | sizeof(s_un.sun_path)); |
531 | GNUNET_strlcpy(s_un.sun_path, | ||
532 | unixpath, | ||
533 | sizeof(s_un.sun_path)); | ||
534 | #ifdef LINUX | ||
535 | { | ||
536 | int abstract; | ||
537 | |||
538 | abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg, | ||
539 | "TESTING", | ||
540 | "USE_ABSTRACT_SOCKETS"); | ||
541 | if (GNUNET_YES == abstract) | ||
542 | s_un.sun_path[0] = '\0'; | ||
543 | } | ||
544 | #endif | ||
545 | #if HAVE_SOCKADDR_UN_SUN_LEN | 537 | #if HAVE_SOCKADDR_UN_SUN_LEN |
546 | s_un.sun_len = (u_char)sizeof(struct sockaddr_un); | 538 | s_un.sun_len = (u_char) sizeof(struct sockaddr_un); |
547 | #endif | 539 | #endif |
548 | sock = GNUNET_NETWORK_socket_create(AF_UNIX, | 540 | sock = GNUNET_NETWORK_socket_create (AF_UNIX, |
549 | SOCK_STREAM, | 541 | SOCK_STREAM, |
550 | 0); | 542 | 0); |
551 | if ((NULL != sock) && | 543 | if ((NULL != sock) && |
552 | ((GNUNET_OK == | 544 | ((GNUNET_OK == |
553 | GNUNET_NETWORK_socket_connect(sock, | 545 | GNUNET_NETWORK_socket_connect (sock, |
554 | (struct sockaddr *)&s_un, | 546 | (struct sockaddr *) &s_un, |
555 | sizeof(s_un))) || | 547 | sizeof(s_un))) || |
556 | (EINPROGRESS == errno))) | 548 | (EINPROGRESS == errno))) |
557 | { | 549 | { |
558 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 550 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
559 | "Successfully connected to unixpath `%s'!\n", | 551 | "Successfully connected to unixpath `%s'!\n", |
560 | unixpath); | 552 | unixpath); |
561 | GNUNET_free(unixpath); | 553 | GNUNET_free (unixpath); |
562 | return sock; | 554 | return sock; |
563 | } | ||
564 | if (NULL != sock) | ||
565 | GNUNET_NETWORK_socket_close(sock); | ||
566 | } | 555 | } |
567 | GNUNET_free_non_null(unixpath); | 556 | if (NULL != sock) |
557 | GNUNET_NETWORK_socket_close (sock); | ||
558 | } | ||
559 | GNUNET_free_non_null (unixpath); | ||
568 | #endif | 560 | #endif |
569 | return NULL; | 561 | return NULL; |
570 | } | 562 | } |
@@ -577,7 +569,7 @@ try_unixpath(const char *service_name, | |||
577 | * @param cls the `struct AddressProbe *` with the address that we are probing | 569 | * @param cls the `struct AddressProbe *` with the address that we are probing |
578 | */ | 570 | */ |
579 | static void | 571 | static void |
580 | connect_probe_continuation(void *cls) | 572 | connect_probe_continuation (void *cls) |
581 | { | 573 | { |
582 | struct AddressProbe *ap = cls; | 574 | struct AddressProbe *ap = cls; |
583 | struct ClientState *cstate = ap->cstate; | 575 | struct ClientState *cstate = ap->cstate; |
@@ -586,40 +578,40 @@ connect_probe_continuation(void *cls) | |||
586 | socklen_t len; | 578 | socklen_t len; |
587 | 579 | ||
588 | ap->task = NULL; | 580 | ap->task = NULL; |
589 | GNUNET_assert(NULL != ap->sock); | 581 | GNUNET_assert (NULL != ap->sock); |
590 | GNUNET_CONTAINER_DLL_remove(cstate->ap_head, | 582 | GNUNET_CONTAINER_DLL_remove (cstate->ap_head, |
591 | cstate->ap_tail, | 583 | cstate->ap_tail, |
592 | ap); | 584 | ap); |
593 | len = sizeof(error); | 585 | len = sizeof(error); |
594 | error = 0; | 586 | error = 0; |
595 | tc = GNUNET_SCHEDULER_get_task_context(); | 587 | tc = GNUNET_SCHEDULER_get_task_context (); |
596 | if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || | 588 | if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || |
597 | (GNUNET_OK != | 589 | (GNUNET_OK != |
598 | GNUNET_NETWORK_socket_getsockopt(ap->sock, | 590 | GNUNET_NETWORK_socket_getsockopt (ap->sock, |
599 | SOL_SOCKET, | 591 | SOL_SOCKET, |
600 | SO_ERROR, | 592 | SO_ERROR, |
601 | &error, | 593 | &error, |
602 | &len)) || | 594 | &len)) || |
603 | (0 != error)) | 595 | (0 != error)) |
604 | { | 596 | { |
605 | GNUNET_break(GNUNET_OK == | 597 | GNUNET_break (GNUNET_OK == |
606 | GNUNET_NETWORK_socket_close(ap->sock)); | 598 | GNUNET_NETWORK_socket_close (ap->sock)); |
607 | GNUNET_free(ap); | 599 | GNUNET_free (ap); |
608 | if ((NULL == cstate->ap_head) && | 600 | if ((NULL == cstate->ap_head) && |
609 | // (NULL == cstate->proxy_handshake) && | 601 | // (NULL == cstate->proxy_handshake) && |
610 | (NULL == cstate->dns_active)) | 602 | (NULL == cstate->dns_active)) |
611 | connect_fail_continuation(cstate); | 603 | connect_fail_continuation (cstate); |
612 | return; | 604 | return; |
613 | } | 605 | } |
614 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 606 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
615 | "Connection to `%s' succeeded!\n", | 607 | "Connection to `%s' succeeded!\n", |
616 | cstate->service_name); | 608 | cstate->service_name); |
617 | /* trigger jobs that waited for the connection */ | 609 | /* trigger jobs that waited for the connection */ |
618 | GNUNET_assert(NULL == cstate->sock); | 610 | GNUNET_assert (NULL == cstate->sock); |
619 | cstate->sock = ap->sock; | 611 | cstate->sock = ap->sock; |
620 | GNUNET_free(ap); | 612 | GNUNET_free (ap); |
621 | cancel_aps(cstate); | 613 | cancel_aps (cstate); |
622 | connect_success_continuation(cstate); | 614 | connect_success_continuation (cstate); |
623 | } | 615 | } |
624 | 616 | ||
625 | 617 | ||
@@ -632,82 +624,82 @@ connect_probe_continuation(void *cls) | |||
632 | * @param addrlen length of @a addr | 624 | * @param addrlen length of @a addr |
633 | */ | 625 | */ |
634 | static void | 626 | static void |
635 | try_connect_using_address(void *cls, | 627 | try_connect_using_address (void *cls, |
636 | const struct sockaddr *addr, | 628 | const struct sockaddr *addr, |
637 | socklen_t addrlen) | 629 | socklen_t addrlen) |
638 | { | 630 | { |
639 | struct ClientState *cstate = cls; | 631 | struct ClientState *cstate = cls; |
640 | struct AddressProbe *ap; | 632 | struct AddressProbe *ap; |
641 | 633 | ||
642 | if (NULL == addr) | 634 | if (NULL == addr) |
643 | { | 635 | { |
644 | cstate->dns_active = NULL; | 636 | cstate->dns_active = NULL; |
645 | if ((NULL == cstate->ap_head) && | 637 | if ((NULL == cstate->ap_head) && |
646 | // (NULL == cstate->proxy_handshake) && | 638 | // (NULL == cstate->proxy_handshake) && |
647 | (NULL == cstate->sock)) | 639 | (NULL == cstate->sock)) |
648 | connect_fail_continuation(cstate); | 640 | connect_fail_continuation (cstate); |
649 | return; | 641 | return; |
650 | } | 642 | } |
651 | if (NULL != cstate->sock) | 643 | if (NULL != cstate->sock) |
652 | return; /* already connected */ | 644 | return; /* already connected */ |
653 | /* try to connect */ | 645 | /* try to connect */ |
654 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 646 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
655 | "Trying to connect using address `%s:%u'\n", | 647 | "Trying to connect using address `%s:%u'\n", |
656 | GNUNET_a2s(addr, | 648 | GNUNET_a2s (addr, |
657 | addrlen), | 649 | addrlen), |
658 | cstate->port); | 650 | cstate->port); |
659 | ap = GNUNET_malloc(sizeof(struct AddressProbe) + addrlen); | 651 | ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen); |
660 | ap->addr = (const struct sockaddr *)&ap[1]; | 652 | ap->addr = (const struct sockaddr *) &ap[1]; |
661 | GNUNET_memcpy(&ap[1], | 653 | GNUNET_memcpy (&ap[1], |
662 | addr, | 654 | addr, |
663 | addrlen); | 655 | addrlen); |
664 | ap->addrlen = addrlen; | 656 | ap->addrlen = addrlen; |
665 | ap->cstate = cstate; | 657 | ap->cstate = cstate; |
666 | 658 | ||
667 | switch (ap->addr->sa_family) | 659 | switch (ap->addr->sa_family) |
668 | { | 660 | { |
669 | case AF_INET: | 661 | case AF_INET: |
670 | ((struct sockaddr_in *)ap->addr)->sin_port = htons(cstate->port); | 662 | ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port); |
671 | break; | 663 | break; |
672 | 664 | ||
673 | case AF_INET6: | 665 | case AF_INET6: |
674 | ((struct sockaddr_in6 *)ap->addr)->sin6_port = htons(cstate->port); | 666 | ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port); |
675 | break; | 667 | break; |
676 | 668 | ||
677 | default: | 669 | default: |
678 | GNUNET_break(0); | 670 | GNUNET_break (0); |
679 | GNUNET_free(ap); | 671 | GNUNET_free (ap); |
680 | return; /* not supported by us */ | 672 | return; /* not supported by us */ |
681 | } | 673 | } |
682 | ap->sock = GNUNET_NETWORK_socket_create(ap->addr->sa_family, | 674 | ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, |
683 | SOCK_STREAM, | 675 | SOCK_STREAM, |
684 | 0); | 676 | 0); |
685 | if (NULL == ap->sock) | 677 | if (NULL == ap->sock) |
686 | { | 678 | { |
687 | GNUNET_free(ap); | 679 | GNUNET_free (ap); |
688 | return; /* not supported by OS */ | 680 | return; /* not supported by OS */ |
689 | } | 681 | } |
690 | if ((GNUNET_OK != | 682 | if ((GNUNET_OK != |
691 | GNUNET_NETWORK_socket_connect(ap->sock, | 683 | GNUNET_NETWORK_socket_connect (ap->sock, |
692 | ap->addr, | 684 | ap->addr, |
693 | ap->addrlen)) && | 685 | ap->addrlen)) && |
694 | (EINPROGRESS != errno)) | 686 | (EINPROGRESS != errno)) |
695 | { | 687 | { |
696 | /* maybe refused / unsupported address, try next */ | 688 | /* maybe refused / unsupported address, try next */ |
697 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_INFO, | 689 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, |
698 | "connect"); | 690 | "connect"); |
699 | GNUNET_break(GNUNET_OK == | 691 | GNUNET_break (GNUNET_OK == |
700 | GNUNET_NETWORK_socket_close(ap->sock)); | 692 | GNUNET_NETWORK_socket_close (ap->sock)); |
701 | GNUNET_free(ap); | 693 | GNUNET_free (ap); |
702 | return; | 694 | return; |
703 | } | 695 | } |
704 | GNUNET_CONTAINER_DLL_insert(cstate->ap_head, | 696 | GNUNET_CONTAINER_DLL_insert (cstate->ap_head, |
705 | cstate->ap_tail, | 697 | cstate->ap_tail, |
706 | ap); | 698 | ap); |
707 | ap->task = GNUNET_SCHEDULER_add_write_net(CONNECT_RETRY_TIMEOUT, | 699 | ap->task = GNUNET_SCHEDULER_add_write_net (CONNECT_RETRY_TIMEOUT, |
708 | ap->sock, | 700 | ap->sock, |
709 | &connect_probe_continuation, | 701 | &connect_probe_continuation, |
710 | ap); | 702 | ap); |
711 | } | 703 | } |
712 | 704 | ||
713 | 705 | ||
@@ -720,8 +712,8 @@ try_connect_using_address(void *cls, | |||
720 | * @return #GNUNET_OK if the configuration is valid, #GNUNET_SYSERR if not | 712 | * @return #GNUNET_OK if the configuration is valid, #GNUNET_SYSERR if not |
721 | */ | 713 | */ |
722 | static int | 714 | static int |
723 | test_service_configuration(const char *service_name, | 715 | test_service_configuration (const char *service_name, |
724 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 716 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
725 | { | 717 | { |
726 | int ret = GNUNET_SYSERR; | 718 | int ret = GNUNET_SYSERR; |
727 | char *hostname = NULL; | 719 | char *hostname = NULL; |
@@ -731,45 +723,45 @@ test_service_configuration(const char *service_name, | |||
731 | char *unixpath = NULL; | 723 | char *unixpath = NULL; |
732 | 724 | ||
733 | if ((GNUNET_OK == | 725 | if ((GNUNET_OK == |
734 | GNUNET_CONFIGURATION_get_value_filename(cfg, | 726 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
735 | service_name, | 727 | service_name, |
736 | "UNIXPATH", | 728 | "UNIXPATH", |
737 | &unixpath)) && | 729 | &unixpath)) && |
738 | (0 < strlen(unixpath))) | 730 | (0 < strlen (unixpath))) |
739 | ret = GNUNET_OK; | 731 | ret = GNUNET_OK; |
740 | else if ((GNUNET_OK == | 732 | else if ((GNUNET_OK == |
741 | GNUNET_CONFIGURATION_have_value(cfg, | 733 | GNUNET_CONFIGURATION_have_value (cfg, |
742 | service_name, | 734 | service_name, |
743 | "UNIXPATH"))) | 735 | "UNIXPATH"))) |
744 | { | 736 | { |
745 | GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR, | 737 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, |
746 | service_name, | 738 | service_name, |
747 | "UNIXPATH", | 739 | "UNIXPATH", |
748 | _("not a valid filename")); | 740 | _ ("not a valid filename")); |
749 | return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */ | 741 | return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */ |
750 | } | 742 | } |
751 | GNUNET_free_non_null(unixpath); | 743 | GNUNET_free_non_null (unixpath); |
752 | #endif | 744 | #endif |
753 | 745 | ||
754 | if ((GNUNET_YES == | 746 | if ((GNUNET_YES == |
755 | GNUNET_CONFIGURATION_have_value(cfg, | 747 | GNUNET_CONFIGURATION_have_value (cfg, |
756 | service_name, | 748 | service_name, |
757 | "PORT")) && | 749 | "PORT")) && |
758 | (GNUNET_OK == | 750 | (GNUNET_OK == |
759 | GNUNET_CONFIGURATION_get_value_number(cfg, | 751 | GNUNET_CONFIGURATION_get_value_number (cfg, |
760 | service_name, | 752 | service_name, |
761 | "PORT", | 753 | "PORT", |
762 | &port)) && | 754 | &port)) && |
763 | (port <= 65535) && | 755 | (port <= 65535) && |
764 | (0 != port) && | 756 | (0 != port) && |
765 | (GNUNET_OK == | 757 | (GNUNET_OK == |
766 | GNUNET_CONFIGURATION_get_value_string(cfg, | 758 | GNUNET_CONFIGURATION_get_value_string (cfg, |
767 | service_name, | 759 | service_name, |
768 | "HOSTNAME", | 760 | "HOSTNAME", |
769 | &hostname)) && | 761 | &hostname)) && |
770 | (0 != strlen(hostname))) | 762 | (0 != strlen (hostname))) |
771 | ret = GNUNET_OK; | 763 | ret = GNUNET_OK; |
772 | GNUNET_free_non_null(hostname); | 764 | GNUNET_free_non_null (hostname); |
773 | return ret; | 765 | return ret; |
774 | } | 766 | } |
775 | 767 | ||
@@ -780,7 +772,7 @@ test_service_configuration(const char *service_name, | |||
780 | * @param cls the `struct ClientState` to try to connect to the service | 772 | * @param cls the `struct ClientState` to try to connect to the service |
781 | */ | 773 | */ |
782 | static void | 774 | static void |
783 | start_connect(void *cls) | 775 | start_connect (void *cls) |
784 | { | 776 | { |
785 | struct ClientState *cstate = cls; | 777 | struct ClientState *cstate = cls; |
786 | 778 | ||
@@ -788,41 +780,41 @@ start_connect(void *cls) | |||
788 | #if 0 | 780 | #if 0 |
789 | /* Never use a local source if a proxy is configured */ | 781 | /* Never use a local source if a proxy is configured */ |
790 | if (GNUNET_YES == | 782 | if (GNUNET_YES == |
791 | GNUNET_SOCKS_check_service(cstate->service_name, | 783 | GNUNET_SOCKS_check_service (cstate->service_name, |
792 | cstate->cfg)) | 784 | cstate->cfg)) |
793 | { | 785 | { |
794 | socks_connect(cstate); | 786 | socks_connect (cstate); |
795 | return; | 787 | return; |
796 | } | 788 | } |
797 | #endif | 789 | #endif |
798 | 790 | ||
799 | if ((0 == (cstate->attempts++ % 2)) || | 791 | if ((0 == (cstate->attempts++ % 2)) || |
800 | (0 == cstate->port) || | 792 | (0 == cstate->port) || |
801 | (NULL == cstate->hostname)) | 793 | (NULL == cstate->hostname)) |
794 | { | ||
795 | /* on even rounds, try UNIX first, or always | ||
796 | if we do not have a DNS name and TCP port. */ | ||
797 | cstate->sock = try_unixpath (cstate->service_name, | ||
798 | cstate->cfg); | ||
799 | if (NULL != cstate->sock) | ||
802 | { | 800 | { |
803 | /* on even rounds, try UNIX first, or always | 801 | connect_success_continuation (cstate); |
804 | if we do not have a DNS name and TCP port. */ | 802 | return; |
805 | cstate->sock = try_unixpath(cstate->service_name, | ||
806 | cstate->cfg); | ||
807 | if (NULL != cstate->sock) | ||
808 | { | ||
809 | connect_success_continuation(cstate); | ||
810 | return; | ||
811 | } | ||
812 | } | 803 | } |
804 | } | ||
813 | if ((NULL == cstate->hostname) || | 805 | if ((NULL == cstate->hostname) || |
814 | (0 == cstate->port)) | 806 | (0 == cstate->port)) |
815 | { | 807 | { |
816 | /* All options failed. Boo! */ | 808 | /* All options failed. Boo! */ |
817 | connect_fail_continuation(cstate); | 809 | connect_fail_continuation (cstate); |
818 | return; | 810 | return; |
819 | } | 811 | } |
820 | cstate->dns_active | 812 | cstate->dns_active |
821 | = GNUNET_RESOLVER_ip_get(cstate->hostname, | 813 | = GNUNET_RESOLVER_ip_get (cstate->hostname, |
822 | AF_UNSPEC, | 814 | AF_UNSPEC, |
823 | CONNECT_RETRY_TIMEOUT, | 815 | CONNECT_RETRY_TIMEOUT, |
824 | &try_connect_using_address, | 816 | &try_connect_using_address, |
825 | cstate); | 817 | cstate); |
826 | } | 818 | } |
827 | 819 | ||
828 | 820 | ||
@@ -834,30 +826,30 @@ start_connect(void *cls) | |||
834 | * @param impl_state our `struct ClientState` | 826 | * @param impl_state our `struct ClientState` |
835 | */ | 827 | */ |
836 | static void | 828 | static void |
837 | connection_client_send_impl(struct GNUNET_MQ_Handle *mq, | 829 | connection_client_send_impl (struct GNUNET_MQ_Handle *mq, |
838 | const struct GNUNET_MessageHeader *msg, | 830 | const struct GNUNET_MessageHeader *msg, |
839 | void *impl_state) | 831 | void *impl_state) |
840 | { | 832 | { |
841 | struct ClientState *cstate = impl_state; | 833 | struct ClientState *cstate = impl_state; |
842 | 834 | ||
843 | (void)mq; | 835 | (void) mq; |
844 | /* only one message at a time allowed */ | 836 | /* only one message at a time allowed */ |
845 | GNUNET_assert(NULL == cstate->msg); | 837 | GNUNET_assert (NULL == cstate->msg); |
846 | GNUNET_assert(NULL == cstate->send_task); | 838 | GNUNET_assert (NULL == cstate->send_task); |
847 | cstate->msg = msg; | 839 | cstate->msg = msg; |
848 | cstate->msg_off = 0; | 840 | cstate->msg_off = 0; |
849 | if (NULL == cstate->sock) | 841 | if (NULL == cstate->sock) |
850 | { | 842 | { |
851 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 843 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
852 | "message of type %u waiting for socket\n", | 844 | "message of type %u waiting for socket\n", |
853 | ntohs(msg->type)); | 845 | ntohs (msg->type)); |
854 | return; /* still waiting for connection */ | 846 | return; /* still waiting for connection */ |
855 | } | 847 | } |
856 | cstate->send_task | 848 | cstate->send_task |
857 | = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 849 | = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
858 | cstate->sock, | 850 | cstate->sock, |
859 | &transmit_ready, | 851 | &transmit_ready, |
860 | cstate); | 852 | cstate); |
861 | } | 853 | } |
862 | 854 | ||
863 | 855 | ||
@@ -868,20 +860,186 @@ connection_client_send_impl(struct GNUNET_MQ_Handle *mq, | |||
868 | * @param impl_state our `struct ClientState` | 860 | * @param impl_state our `struct ClientState` |
869 | */ | 861 | */ |
870 | static void | 862 | static void |
871 | connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, | 863 | connection_client_cancel_impl (struct GNUNET_MQ_Handle *mq, |
872 | void *impl_state) | 864 | void *impl_state) |
873 | { | 865 | { |
874 | struct ClientState *cstate = impl_state; | 866 | struct ClientState *cstate = impl_state; |
875 | 867 | ||
876 | (void)mq; | 868 | (void) mq; |
877 | GNUNET_assert(NULL != cstate->msg); | 869 | GNUNET_assert (NULL != cstate->msg); |
878 | GNUNET_assert(0 == cstate->msg_off); | 870 | GNUNET_assert (0 == cstate->msg_off); |
879 | cstate->msg = NULL; | 871 | cstate->msg = NULL; |
880 | if (NULL != cstate->send_task) | 872 | if (NULL != cstate->send_task) |
873 | { | ||
874 | GNUNET_SCHEDULER_cancel (cstate->send_task); | ||
875 | cstate->send_task = NULL; | ||
876 | } | ||
877 | } | ||
878 | |||
879 | |||
880 | /** | ||
881 | * Test if the port or UNIXPATH of the given @a service_name | ||
882 | * is in use and thus (most likely) the respective service is up. | ||
883 | * | ||
884 | * @param cfg our configuration | ||
885 | * @param service_name name of the service to connect to | ||
886 | * @return #GNUNET_YES if the service is (likely) up, | ||
887 | * #GNUNET_NO if the service is (definitively) down, | ||
888 | * #GNUNET_SYSERR if the configuration does not give us | ||
889 | * the necessary information about the service, or if | ||
890 | * we could not check (i.e. socket() failed) | ||
891 | */ | ||
892 | int | ||
893 | GNUNET_CLIENT_test (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
894 | const char *service_name) | ||
895 | { | ||
896 | char *hostname = NULL; | ||
897 | unsigned long long port; | ||
898 | int ret; | ||
899 | |||
900 | #if AF_UNIX | ||
901 | { | ||
902 | char *unixpath = NULL; | ||
903 | |||
904 | if (GNUNET_OK == | ||
905 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
906 | service_name, | ||
907 | "UNIXPATH", | ||
908 | &unixpath)) | ||
881 | { | 909 | { |
882 | GNUNET_SCHEDULER_cancel(cstate->send_task); | 910 | if (0 == strlen (unixpath)) |
883 | cstate->send_task = NULL; | 911 | { |
912 | GNUNET_free (unixpath); | ||
913 | return GNUNET_SYSERR; /* empty string not OK */ | ||
914 | } | ||
915 | if (0 == access (unixpath, | ||
916 | F_OK)) | ||
917 | { | ||
918 | GNUNET_free (unixpath); | ||
919 | return GNUNET_OK; /* file exists, we assume service is running */ | ||
920 | } | ||
921 | GNUNET_free (unixpath); | ||
922 | } | ||
923 | else if (GNUNET_OK == | ||
924 | GNUNET_CONFIGURATION_have_value (cfg, | ||
925 | service_name, | ||
926 | "UNIXPATH")) | ||
927 | { | ||
928 | /* UNIXPATH specified but not a valid path! */ | ||
929 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | ||
930 | service_name, | ||
931 | "UNIXPATH", | ||
932 | _ ("not a valid filename")); | ||
933 | return GNUNET_SYSERR; | ||
884 | } | 934 | } |
935 | } | ||
936 | #endif | ||
937 | |||
938 | if ( (GNUNET_OK != | ||
939 | GNUNET_CONFIGURATION_get_value_number (cfg, | ||
940 | service_name, | ||
941 | "PORT", | ||
942 | &port)) || | ||
943 | (port > 65535) || | ||
944 | (0 == port) ) | ||
945 | { | ||
946 | return GNUNET_SYSERR; | ||
947 | } | ||
948 | if (GNUNET_OK == | ||
949 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
950 | service_name, | ||
951 | "HOSTNAME", | ||
952 | &hostname)) | ||
953 | { | ||
954 | /* We always assume remotes are up */ | ||
955 | ret = GNUNET_YES; | ||
956 | } | ||
957 | else | ||
958 | { | ||
959 | /* We look for evidence the service is up */ | ||
960 | ret = GNUNET_NO; | ||
961 | } | ||
962 | if ( (NULL == hostname) || | ||
963 | (0 == strcasecmp (hostname, | ||
964 | "localhost")) || | ||
965 | (0 == strcasecmp (hostname, | ||
966 | "ip6-localnet")) ) | ||
967 | { | ||
968 | /* service runs on loopback */ | ||
969 | struct sockaddr_in v4; | ||
970 | struct sockaddr_in6 v6; | ||
971 | int sock; | ||
972 | |||
973 | memset (&v4, 0, sizeof (v4)); | ||
974 | memset (&v6, 0, sizeof (v6)); | ||
975 | v4.sin_family = AF_INET; | ||
976 | v4.sin_port = htons ((uint16_t) port); | ||
977 | #if HAVE_SOCKADDR_IN_SUN_LEN | ||
978 | v4.sin_len = (u_char) sizeof(struct sockaddr_in); | ||
979 | #endif | ||
980 | inet_pton (AF_INET, | ||
981 | "127.0.0.1", | ||
982 | &v4.sin_addr); | ||
983 | ret = GNUNET_NO; | ||
984 | sock = socket (AF_INET, | ||
985 | SOCK_STREAM, | ||
986 | 0); | ||
987 | if (-1 != sock) | ||
988 | { | ||
989 | if (0 != bind (sock, | ||
990 | (struct sockaddr *) &v4, | ||
991 | sizeof (v4))) | ||
992 | { | ||
993 | /* bind failed, so someone is listening! */ | ||
994 | ret = GNUNET_YES; | ||
995 | } | ||
996 | (void) close (sock); | ||
997 | } | ||
998 | else | ||
999 | { | ||
1000 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
1001 | "socket"); | ||
1002 | if (GNUNET_NO == ret) | ||
1003 | ret = GNUNET_SYSERR; | ||
1004 | } | ||
1005 | v6.sin6_family = AF_INET6; | ||
1006 | v6.sin6_port = htons ((uint16_t) port); | ||
1007 | #if HAVE_SOCKADDR_IN_SUN_LEN | ||
1008 | v6.sin6_len = (u_char) sizeof(struct sockaddr_in6); | ||
1009 | #endif | ||
1010 | inet_pton (AF_INET6, | ||
1011 | "::1", | ||
1012 | &v6.sin6_addr); | ||
1013 | sock = socket (AF_INET6, | ||
1014 | SOCK_STREAM, | ||
1015 | 0); | ||
1016 | if (-1 != sock) | ||
1017 | { | ||
1018 | if (0 != bind (sock, | ||
1019 | (struct sockaddr *) &v6, | ||
1020 | sizeof (v6))) | ||
1021 | { | ||
1022 | /* bind failed, so someone is listening! */ | ||
1023 | ret = GNUNET_YES; | ||
1024 | } | ||
1025 | (void) close (sock); | ||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | ||
1030 | "socket"); | ||
1031 | /* not changing 'ret' intentionally here, as | ||
1032 | v4 succeeding and v6 failing just means we | ||
1033 | should use v4 */ | ||
1034 | } | ||
1035 | } | ||
1036 | else | ||
1037 | { | ||
1038 | /* service running remotely */ | ||
1039 | ret = GNUNET_OK; | ||
1040 | } | ||
1041 | GNUNET_free_non_null (hostname); | ||
1042 | return ret; | ||
885 | } | 1043 | } |
886 | 1044 | ||
887 | 1045 | ||
@@ -897,57 +1055,57 @@ connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq, | |||
897 | * @return the message queue, NULL on error | 1055 | * @return the message queue, NULL on error |
898 | */ | 1056 | */ |
899 | struct GNUNET_MQ_Handle * | 1057 | struct GNUNET_MQ_Handle * |
900 | GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, | 1058 | GNUNET_CLIENT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, |
901 | const char *service_name, | 1059 | const char *service_name, |
902 | const struct GNUNET_MQ_MessageHandler *handlers, | 1060 | const struct GNUNET_MQ_MessageHandler *handlers, |
903 | GNUNET_MQ_ErrorHandler error_handler, | 1061 | GNUNET_MQ_ErrorHandler error_handler, |
904 | void *error_handler_cls) | 1062 | void *error_handler_cls) |
905 | { | 1063 | { |
906 | struct ClientState *cstate; | 1064 | struct ClientState *cstate; |
907 | 1065 | ||
908 | if (GNUNET_OK != | 1066 | if (GNUNET_OK != |
909 | test_service_configuration(service_name, | 1067 | test_service_configuration (service_name, |
910 | cfg)) | 1068 | cfg)) |
911 | return NULL; | 1069 | return NULL; |
912 | cstate = GNUNET_new(struct ClientState); | 1070 | cstate = GNUNET_new (struct ClientState); |
913 | cstate->service_name = GNUNET_strdup(service_name); | 1071 | cstate->service_name = GNUNET_strdup (service_name); |
914 | cstate->cfg = cfg; | 1072 | cstate->cfg = cfg; |
915 | cstate->retry_task = GNUNET_SCHEDULER_add_now(&start_connect, | 1073 | cstate->retry_task = GNUNET_SCHEDULER_add_now (&start_connect, |
916 | cstate); | 1074 | cstate); |
917 | cstate->mst = GNUNET_MST_create(&recv_message, | 1075 | cstate->mst = GNUNET_MST_create (&recv_message, |
918 | cstate); | 1076 | cstate); |
919 | if (GNUNET_YES == | 1077 | if (GNUNET_YES == |
920 | GNUNET_CONFIGURATION_have_value(cfg, | 1078 | GNUNET_CONFIGURATION_have_value (cfg, |
921 | service_name, | 1079 | service_name, |
922 | "PORT")) | 1080 | "PORT")) |
923 | { | 1081 | { |
924 | if (!((GNUNET_OK != | 1082 | if (! ((GNUNET_OK != |
925 | GNUNET_CONFIGURATION_get_value_number(cfg, | 1083 | GNUNET_CONFIGURATION_get_value_number (cfg, |
926 | service_name, | 1084 | service_name, |
927 | "PORT", | 1085 | "PORT", |
928 | &cstate->port)) || | 1086 | &cstate->port)) || |
929 | (cstate->port > 65535) || | 1087 | (cstate->port > 65535) || |
930 | (GNUNET_OK != | 1088 | (GNUNET_OK != |
931 | GNUNET_CONFIGURATION_get_value_string(cfg, | 1089 | GNUNET_CONFIGURATION_get_value_string (cfg, |
932 | service_name, | 1090 | service_name, |
933 | "HOSTNAME", | 1091 | "HOSTNAME", |
934 | &cstate->hostname))) && | 1092 | &cstate->hostname))) && |
935 | (0 == strlen(cstate->hostname))) | 1093 | (0 == strlen (cstate->hostname))) |
936 | { | 1094 | { |
937 | GNUNET_free(cstate->hostname); | 1095 | GNUNET_free (cstate->hostname); |
938 | cstate->hostname = NULL; | 1096 | cstate->hostname = NULL; |
939 | LOG(GNUNET_ERROR_TYPE_WARNING, | 1097 | LOG (GNUNET_ERROR_TYPE_WARNING, |
940 | _("Need a non-empty hostname for service `%s'.\n"), | 1098 | _ ("Need a non-empty hostname for service `%s'.\n"), |
941 | service_name); | 1099 | service_name); |
942 | } | ||
943 | } | 1100 | } |
944 | cstate->mq = GNUNET_MQ_queue_for_callbacks(&connection_client_send_impl, | 1101 | } |
945 | &connection_client_destroy_impl, | 1102 | cstate->mq = GNUNET_MQ_queue_for_callbacks (&connection_client_send_impl, |
946 | &connection_client_cancel_impl, | 1103 | &connection_client_destroy_impl, |
947 | cstate, | 1104 | &connection_client_cancel_impl, |
948 | handlers, | 1105 | cstate, |
949 | error_handler, | 1106 | handlers, |
950 | error_handler_cls); | 1107 | error_handler, |
1108 | error_handler_cls); | ||
951 | return cstate->mq; | 1109 | return cstate->mq; |
952 | } | 1110 | } |
953 | 1111 | ||
diff --git a/src/util/service.c b/src/util/service.c index b0f4ea289..21b99547c 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -37,19 +37,20 @@ | |||
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | 39 | ||
40 | #define LOG(kind, ...) GNUNET_log_from(kind, "util-service", __VA_ARGS__) | 40 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-service", __VA_ARGS__) |
41 | 41 | ||
42 | #define LOG_STRERROR(kind, syscall) \ | 42 | #define LOG_STRERROR(kind, syscall) \ |
43 | GNUNET_log_from_strerror(kind, "util-service", syscall) | 43 | GNUNET_log_from_strerror (kind, "util-service", syscall) |
44 | 44 | ||
45 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ | 45 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ |
46 | GNUNET_log_from_strerror_file(kind, "util-service", syscall, filename) | 46 | GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename) |
47 | 47 | ||
48 | 48 | ||
49 | /** | 49 | /** |
50 | * Information the service tracks per listen operation. | 50 | * Information the service tracks per listen operation. |
51 | */ | 51 | */ |
52 | struct ServiceListenContext { | 52 | struct ServiceListenContext |
53 | { | ||
53 | /** | 54 | /** |
54 | * Kept in a DLL. | 55 | * Kept in a DLL. |
55 | */ | 56 | */ |
@@ -80,7 +81,8 @@ struct ServiceListenContext { | |||
80 | /** | 81 | /** |
81 | * Reasons why we might be suspended. | 82 | * Reasons why we might be suspended. |
82 | */ | 83 | */ |
83 | enum SuspendReason { | 84 | enum SuspendReason |
85 | { | ||
84 | /** | 86 | /** |
85 | * We are running normally. | 87 | * We are running normally. |
86 | */ | 88 | */ |
@@ -111,7 +113,8 @@ enum SuspendReason { | |||
111 | /** | 113 | /** |
112 | * Handle to a service. | 114 | * Handle to a service. |
113 | */ | 115 | */ |
114 | struct GNUNET_SERVICE_Handle { | 116 | struct GNUNET_SERVICE_Handle |
117 | { | ||
115 | /** | 118 | /** |
116 | * Our configuration. | 119 | * Our configuration. |
117 | */ | 120 | */ |
@@ -172,6 +175,7 @@ struct GNUNET_SERVICE_Handle { | |||
172 | */ | 175 | */ |
173 | void *task_cls; | 176 | void *task_cls; |
174 | 177 | ||
178 | |||
175 | /** | 179 | /** |
176 | * IPv4 addresses that are not allowed to connect. | 180 | * IPv4 addresses that are not allowed to connect. |
177 | */ | 181 | */ |
@@ -243,7 +247,8 @@ struct GNUNET_SERVICE_Handle { | |||
243 | /** | 247 | /** |
244 | * Handle to a client that is connected to a service. | 248 | * Handle to a client that is connected to a service. |
245 | */ | 249 | */ |
246 | struct GNUNET_SERVICE_Client { | 250 | struct GNUNET_SERVICE_Client |
251 | { | ||
247 | /** | 252 | /** |
248 | * Kept in a DLL. | 253 | * Kept in a DLL. |
249 | */ | 254 | */ |
@@ -353,15 +358,15 @@ struct GNUNET_SERVICE_Client { | |||
353 | * @return #GNUNET_YES if we have non-monitoring clients left | 358 | * @return #GNUNET_YES if we have non-monitoring clients left |
354 | */ | 359 | */ |
355 | static int | 360 | static int |
356 | have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) | 361 | have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) |
357 | { | 362 | { |
358 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; | 363 | for (struct GNUNET_SERVICE_Client *client = sh->clients_head; NULL != client; |
359 | client = client->next) | 364 | client = client->next) |
360 | { | 365 | { |
361 | if (client->is_monitor) | 366 | if (client->is_monitor) |
362 | continue; | 367 | continue; |
363 | return GNUNET_YES; | 368 | return GNUNET_YES; |
364 | } | 369 | } |
365 | return GNUNET_NO; | 370 | return GNUNET_NO; |
366 | } | 371 | } |
367 | 372 | ||
@@ -374,20 +379,20 @@ have_non_monitor_clients(struct GNUNET_SERVICE_Handle *sh) | |||
374 | * @param sr reason for suspending accepting connections | 379 | * @param sr reason for suspending accepting connections |
375 | */ | 380 | */ |
376 | static void | 381 | static void |
377 | do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 382 | do_suspend (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) |
378 | { | 383 | { |
379 | struct ServiceListenContext *slc; | 384 | struct ServiceListenContext *slc; |
380 | 385 | ||
381 | GNUNET_assert(0 == (sh->suspend_state & sr)); | 386 | GNUNET_assert (0 == (sh->suspend_state & sr)); |
382 | sh->suspend_state |= sr; | 387 | sh->suspend_state |= sr; |
383 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 388 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) |
389 | { | ||
390 | if (NULL != slc->listen_task) | ||
384 | { | 391 | { |
385 | if (NULL != slc->listen_task) | 392 | GNUNET_SCHEDULER_cancel (slc->listen_task); |
386 | { | 393 | slc->listen_task = NULL; |
387 | GNUNET_SCHEDULER_cancel(slc->listen_task); | ||
388 | slc->listen_task = NULL; | ||
389 | } | ||
390 | } | 394 | } |
395 | } | ||
391 | } | 396 | } |
392 | 397 | ||
393 | 398 | ||
@@ -400,29 +405,27 @@ do_suspend(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | |||
400 | * @param cls our `struct GNUNET_SERVICE_Handle` | 405 | * @param cls our `struct GNUNET_SERVICE_Handle` |
401 | */ | 406 | */ |
402 | static void | 407 | static void |
403 | service_shutdown(void *cls) | 408 | service_shutdown (void *cls) |
404 | { | 409 | { |
405 | struct GNUNET_SERVICE_Handle *sh = cls; | 410 | struct GNUNET_SERVICE_Handle *sh = cls; |
406 | 411 | ||
407 | switch (sh->options) | 412 | switch (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK) |
408 | { | 413 | { |
409 | case GNUNET_SERVICE_OPTION_NONE: | 414 | case GNUNET_SERVICE_OPTION_NONE: |
410 | GNUNET_SERVICE_shutdown(sh); | 415 | GNUNET_SERVICE_shutdown (sh); |
411 | break; | 416 | break; |
412 | 417 | case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: | |
413 | case GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN: | 418 | /* This task should never be run if we are using |
414 | /* This task should never be run if we are using | 419 | the manual shutdown. */ |
415 | the manual shutdown. */ | 420 | GNUNET_assert (0); |
416 | GNUNET_assert(0); | 421 | break; |
417 | break; | 422 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: |
418 | 423 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | |
419 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: | 424 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); |
420 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 425 | if (GNUNET_NO == have_non_monitor_clients (sh)) |
421 | do_suspend(sh, SUSPEND_STATE_SHUTDOWN); | 426 | GNUNET_SERVICE_shutdown (sh); |
422 | if (GNUNET_NO == have_non_monitor_clients(sh)) | 427 | break; |
423 | GNUNET_SERVICE_shutdown(sh); | 428 | } |
424 | break; | ||
425 | } | ||
426 | } | 429 | } |
427 | 430 | ||
428 | 431 | ||
@@ -434,8 +437,8 @@ service_shutdown(void *cls) | |||
434 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is | 437 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is |
435 | */ | 438 | */ |
436 | static int | 439 | static int |
437 | check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | 440 | check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, |
438 | const struct in_addr *add) | 441 | const struct in_addr *add) |
439 | { | 442 | { |
440 | unsigned int i; | 443 | unsigned int i; |
441 | 444 | ||
@@ -443,12 +446,12 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | |||
443 | return GNUNET_NO; | 446 | return GNUNET_NO; |
444 | i = 0; | 447 | i = 0; |
445 | while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) | 448 | while ((0 != list[i].network.s_addr) || (0 != list[i].netmask.s_addr)) |
446 | { | 449 | { |
447 | if ((add->s_addr & list[i].netmask.s_addr) == | 450 | if ((add->s_addr & list[i].netmask.s_addr) == |
448 | (list[i].network.s_addr & list[i].netmask.s_addr)) | 451 | (list[i].network.s_addr & list[i].netmask.s_addr)) |
449 | return GNUNET_YES; | 452 | return GNUNET_YES; |
450 | i++; | 453 | i++; |
451 | } | 454 | } |
452 | return GNUNET_NO; | 455 | return GNUNET_NO; |
453 | } | 456 | } |
454 | 457 | ||
@@ -461,8 +464,8 @@ check_ipv4_listed(const struct GNUNET_STRINGS_IPv4NetworkPolicy *list, | |||
461 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is | 464 | * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is |
462 | */ | 465 | */ |
463 | static int | 466 | static int |
464 | check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, | 467 | check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, |
465 | const struct in6_addr *ip) | 468 | const struct in6_addr *ip) |
466 | { | 469 | { |
467 | unsigned int i; | 470 | unsigned int i; |
468 | unsigned int j; | 471 | unsigned int j; |
@@ -471,17 +474,17 @@ check_ipv6_listed(const struct GNUNET_STRINGS_IPv6NetworkPolicy *list, | |||
471 | return GNUNET_NO; | 474 | return GNUNET_NO; |
472 | i = 0; | 475 | i = 0; |
473 | NEXT: | 476 | NEXT: |
474 | while (0 != GNUNET_is_zero(&list[i].network)) | 477 | while (0 != GNUNET_is_zero (&list[i].network)) |
475 | { | 478 | { |
476 | for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) | 479 | for (j = 0; j < sizeof(struct in6_addr) / sizeof(int); j++) |
477 | if (((((int *)ip)[j] & ((int *)&list[i].netmask)[j])) != | 480 | if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) != |
478 | (((int *)&list[i].network)[j] & ((int *)&list[i].netmask)[j])) | 481 | (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j])) |
479 | { | 482 | { |
480 | i++; | 483 | i++; |
481 | goto NEXT; | 484 | goto NEXT; |
482 | } | 485 | } |
483 | return GNUNET_YES; | 486 | return GNUNET_YES; |
484 | } | 487 | } |
485 | return GNUNET_NO; | 488 | return GNUNET_NO; |
486 | } | 489 | } |
487 | 490 | ||
@@ -493,63 +496,63 @@ NEXT: | |||
493 | * @param cls the `struct GNUNET_SERVICE_Client *` to send to | 496 | * @param cls the `struct GNUNET_SERVICE_Client *` to send to |
494 | */ | 497 | */ |
495 | static void | 498 | static void |
496 | do_send(void *cls) | 499 | do_send (void *cls) |
497 | { | 500 | { |
498 | struct GNUNET_SERVICE_Client *client = cls; | 501 | struct GNUNET_SERVICE_Client *client = cls; |
499 | ssize_t ret; | 502 | ssize_t ret; |
500 | size_t left; | 503 | size_t left; |
501 | const char *buf; | 504 | const char *buf; |
502 | 505 | ||
503 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 506 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
504 | "service: sending message with type %u\n", | 507 | "service: sending message with type %u\n", |
505 | ntohs(client->msg->type)); | 508 | ntohs (client->msg->type)); |
506 | 509 | ||
507 | 510 | ||
508 | client->send_task = NULL; | 511 | client->send_task = NULL; |
509 | buf = (const char *)client->msg; | 512 | buf = (const char *) client->msg; |
510 | left = ntohs(client->msg->size) - client->msg_pos; | 513 | left = ntohs (client->msg->size) - client->msg_pos; |
511 | ret = GNUNET_NETWORK_socket_send(client->sock, &buf[client->msg_pos], left); | 514 | ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left); |
512 | GNUNET_assert(ret <= (ssize_t)left); | 515 | GNUNET_assert (ret <= (ssize_t) left); |
513 | if (0 == ret) | 516 | if (0 == ret) |
514 | { | 517 | { |
515 | LOG(GNUNET_ERROR_TYPE_DEBUG, "no data send"); | 518 | LOG (GNUNET_ERROR_TYPE_DEBUG, "no data send"); |
516 | GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE); | 519 | GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE); |
517 | return; | 520 | return; |
518 | } | 521 | } |
519 | if (-1 == ret) | 522 | if (-1 == ret) |
523 | { | ||
524 | if ((EAGAIN == errno) || (EINTR == errno)) | ||
520 | { | 525 | { |
521 | if ((EAGAIN == errno) || (EINTR == errno)) | 526 | /* ignore */ |
522 | { | 527 | ret = 0; |
523 | /* ignore */ | ||
524 | ret = 0; | ||
525 | } | ||
526 | else | ||
527 | { | ||
528 | if (EPIPE != errno) | ||
529 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "send"); | ||
530 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
531 | "socket send returned with error code %i", | ||
532 | errno); | ||
533 | GNUNET_MQ_inject_error(client->mq, GNUNET_MQ_ERROR_WRITE); | ||
534 | return; | ||
535 | } | ||
536 | } | ||
537 | if (0 == client->msg_pos) | ||
538 | { | ||
539 | GNUNET_MQ_impl_send_in_flight(client->mq); | ||
540 | } | 528 | } |
541 | client->msg_pos += ret; | 529 | else |
542 | if (left > (size_t)ret) | ||
543 | { | 530 | { |
544 | GNUNET_assert(NULL == client->drop_task); | 531 | if (EPIPE != errno) |
545 | client->send_task = | 532 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); |
546 | GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 533 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
547 | client->sock, | 534 | "socket send returned with error code %i", |
548 | &do_send, | 535 | errno); |
549 | client); | 536 | GNUNET_MQ_inject_error (client->mq, GNUNET_MQ_ERROR_WRITE); |
550 | return; | 537 | return; |
551 | } | 538 | } |
552 | GNUNET_MQ_impl_send_continue(client->mq); | 539 | } |
540 | if (0 == client->msg_pos) | ||
541 | { | ||
542 | GNUNET_MQ_impl_send_in_flight (client->mq); | ||
543 | } | ||
544 | client->msg_pos += ret; | ||
545 | if (left > (size_t) ret) | ||
546 | { | ||
547 | GNUNET_assert (NULL == client->drop_task); | ||
548 | client->send_task = | ||
549 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
550 | client->sock, | ||
551 | &do_send, | ||
552 | client); | ||
553 | return; | ||
554 | } | ||
555 | GNUNET_MQ_impl_send_continue (client->mq); | ||
553 | } | 556 | } |
554 | 557 | ||
555 | 558 | ||
@@ -562,27 +565,27 @@ do_send(void *cls) | |||
562 | * @param impl_state our `struct GNUNET_SERVICE_Client *` | 565 | * @param impl_state our `struct GNUNET_SERVICE_Client *` |
563 | */ | 566 | */ |
564 | static void | 567 | static void |
565 | service_mq_send(struct GNUNET_MQ_Handle *mq, | 568 | service_mq_send (struct GNUNET_MQ_Handle *mq, |
566 | const struct GNUNET_MessageHeader *msg, | 569 | const struct GNUNET_MessageHeader *msg, |
567 | void *impl_state) | 570 | void *impl_state) |
568 | { | 571 | { |
569 | struct GNUNET_SERVICE_Client *client = impl_state; | 572 | struct GNUNET_SERVICE_Client *client = impl_state; |
570 | 573 | ||
571 | (void)mq; | 574 | (void) mq; |
572 | if (NULL != client->drop_task) | 575 | if (NULL != client->drop_task) |
573 | return; /* we're going down right now, do not try to send */ | 576 | return; /* we're going down right now, do not try to send */ |
574 | GNUNET_assert(NULL == client->send_task); | 577 | GNUNET_assert (NULL == client->send_task); |
575 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 578 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
576 | "Sending message of type %u and size %u to client\n", | 579 | "Sending message of type %u and size %u to client\n", |
577 | ntohs(msg->type), | 580 | ntohs (msg->type), |
578 | ntohs(msg->size)); | 581 | ntohs (msg->size)); |
579 | client->msg = msg; | 582 | client->msg = msg; |
580 | client->msg_pos = 0; | 583 | client->msg_pos = 0; |
581 | client->send_task = | 584 | client->send_task = |
582 | GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL, | 585 | GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
583 | client->sock, | 586 | client->sock, |
584 | &do_send, | 587 | &do_send, |
585 | client); | 588 | client); |
586 | } | 589 | } |
587 | 590 | ||
588 | 591 | ||
@@ -593,14 +596,14 @@ service_mq_send(struct GNUNET_MQ_Handle *mq, | |||
593 | * @param impl_state state specific to the implementation | 596 | * @param impl_state state specific to the implementation |
594 | */ | 597 | */ |
595 | static void | 598 | static void |
596 | service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) | 599 | service_mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state) |
597 | { | 600 | { |
598 | struct GNUNET_SERVICE_Client *client = impl_state; | 601 | struct GNUNET_SERVICE_Client *client = impl_state; |
599 | 602 | ||
600 | (void)mq; | 603 | (void) mq; |
601 | GNUNET_assert(0 == client->msg_pos); | 604 | GNUNET_assert (0 == client->msg_pos); |
602 | client->msg = NULL; | 605 | client->msg = NULL; |
603 | GNUNET_SCHEDULER_cancel(client->send_task); | 606 | GNUNET_SCHEDULER_cancel (client->send_task); |
604 | client->send_task = NULL; | 607 | client->send_task = NULL; |
605 | } | 608 | } |
606 | 609 | ||
@@ -615,20 +618,20 @@ service_mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state) | |||
615 | * @param error error code | 618 | * @param error error code |
616 | */ | 619 | */ |
617 | static void | 620 | static void |
618 | service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) | 621 | service_mq_error_handler (void *cls, enum GNUNET_MQ_Error error) |
619 | { | 622 | { |
620 | struct GNUNET_SERVICE_Client *client = cls; | 623 | struct GNUNET_SERVICE_Client *client = cls; |
621 | struct GNUNET_SERVICE_Handle *sh = client->sh; | 624 | struct GNUNET_SERVICE_Handle *sh = client->sh; |
622 | 625 | ||
623 | if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) | 626 | if ((GNUNET_MQ_ERROR_NO_MATCH == error) && (GNUNET_NO == sh->require_found)) |
624 | { | 627 | { |
625 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
626 | "No handler for message of type %u found\n", | 629 | "No handler for message of type %u found\n", |
627 | (unsigned int)client->warn_type); | 630 | (unsigned int) client->warn_type); |
628 | GNUNET_SERVICE_client_continue(client); | 631 | GNUNET_SERVICE_client_continue (client); |
629 | return; /* ignore error */ | 632 | return; /* ignore error */ |
630 | } | 633 | } |
631 | GNUNET_SERVICE_client_drop(client); | 634 | GNUNET_SERVICE_client_drop (client); |
632 | } | 635 | } |
633 | 636 | ||
634 | 637 | ||
@@ -638,24 +641,24 @@ service_mq_error_handler(void *cls, enum GNUNET_MQ_Error error) | |||
638 | * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from | 641 | * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from |
639 | */ | 642 | */ |
640 | static void | 643 | static void |
641 | warn_no_client_continue(void *cls) | 644 | warn_no_client_continue (void *cls) |
642 | { | 645 | { |
643 | struct GNUNET_SERVICE_Client *client = cls; | 646 | struct GNUNET_SERVICE_Client *client = cls; |
644 | 647 | ||
645 | GNUNET_break( | 648 | GNUNET_break ( |
646 | 0 != | 649 | 0 != |
647 | client->warn_type); /* type should never be 0 here, as we don't use 0 */ | 650 | client->warn_type); /* type should never be 0 here, as we don't use 0 */ |
648 | client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, | 651 | client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
649 | &warn_no_client_continue, | 652 | &warn_no_client_continue, |
650 | client); | 653 | client); |
651 | LOG( | 654 | LOG ( |
652 | GNUNET_ERROR_TYPE_WARNING, | 655 | GNUNET_ERROR_TYPE_WARNING, |
653 | _( | 656 | _ ( |
654 | "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), | 657 | "Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"), |
655 | (unsigned int)client->warn_type, | 658 | (unsigned int) client->warn_type, |
656 | GNUNET_STRINGS_relative_time_to_string(GNUNET_TIME_absolute_get_duration( | 659 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration ( |
657 | client->warn_start), | 660 | client->warn_start), |
658 | GNUNET_YES)); | 661 | GNUNET_YES)); |
659 | } | 662 | } |
660 | 663 | ||
661 | 664 | ||
@@ -671,23 +674,23 @@ warn_no_client_continue(void *cls) | |||
671 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped | 674 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped |
672 | */ | 675 | */ |
673 | static int | 676 | static int |
674 | service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) | 677 | service_client_mst_cb (void *cls, const struct GNUNET_MessageHeader *message) |
675 | { | 678 | { |
676 | struct GNUNET_SERVICE_Client *client = cls; | 679 | struct GNUNET_SERVICE_Client *client = cls; |
677 | 680 | ||
678 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 681 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
679 | "Received message of type %u and size %u from client\n", | 682 | "Received message of type %u and size %u from client\n", |
680 | ntohs(message->type), | 683 | ntohs (message->type), |
681 | ntohs(message->size)); | 684 | ntohs (message->size)); |
682 | GNUNET_assert(GNUNET_NO == client->needs_continue); | 685 | GNUNET_assert (GNUNET_NO == client->needs_continue); |
683 | client->needs_continue = GNUNET_YES; | 686 | client->needs_continue = GNUNET_YES; |
684 | client->warn_type = ntohs(message->type); | 687 | client->warn_type = ntohs (message->type); |
685 | client->warn_start = GNUNET_TIME_absolute_get(); | 688 | client->warn_start = GNUNET_TIME_absolute_get (); |
686 | GNUNET_assert(NULL == client->warn_task); | 689 | GNUNET_assert (NULL == client->warn_task); |
687 | client->warn_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, | 690 | client->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
688 | &warn_no_client_continue, | 691 | &warn_no_client_continue, |
689 | client); | 692 | client); |
690 | GNUNET_MQ_inject_message(client->mq, message); | 693 | GNUNET_MQ_inject_message (client->mq, message); |
691 | if (NULL != client->drop_task) | 694 | if (NULL != client->drop_task) |
692 | return GNUNET_SYSERR; | 695 | return GNUNET_SYSERR; |
693 | return GNUNET_OK; | 696 | return GNUNET_OK; |
@@ -701,37 +704,37 @@ service_client_mst_cb(void *cls, const struct GNUNET_MessageHeader *message) | |||
701 | * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. | 704 | * @param cls the `struct GNUNET_SERVICE_Client` that sent us data. |
702 | */ | 705 | */ |
703 | static void | 706 | static void |
704 | service_client_recv(void *cls) | 707 | service_client_recv (void *cls) |
705 | { | 708 | { |
706 | struct GNUNET_SERVICE_Client *client = cls; | 709 | struct GNUNET_SERVICE_Client *client = cls; |
707 | int ret; | 710 | int ret; |
708 | 711 | ||
709 | client->recv_task = NULL; | 712 | client->recv_task = NULL; |
710 | ret = GNUNET_MST_read(client->mst, client->sock, GNUNET_NO, GNUNET_YES); | 713 | ret = GNUNET_MST_read (client->mst, client->sock, GNUNET_NO, GNUNET_YES); |
711 | if (GNUNET_SYSERR == ret) | 714 | if (GNUNET_SYSERR == ret) |
715 | { | ||
716 | /* client closed connection (or IO error) */ | ||
717 | if (NULL == client->drop_task) | ||
712 | { | 718 | { |
713 | /* client closed connection (or IO error) */ | 719 | GNUNET_assert (GNUNET_NO == client->needs_continue); |
714 | if (NULL == client->drop_task) | 720 | GNUNET_SERVICE_client_drop (client); |
715 | { | ||
716 | GNUNET_assert(GNUNET_NO == client->needs_continue); | ||
717 | GNUNET_SERVICE_client_drop(client); | ||
718 | } | ||
719 | return; | ||
720 | } | 721 | } |
722 | return; | ||
723 | } | ||
721 | if (GNUNET_NO == ret) | 724 | if (GNUNET_NO == ret) |
722 | return; /* more messages in buffer, wait for application | 725 | return; /* more messages in buffer, wait for application |
723 | to be done processing */ | 726 | to be done processing */ |
724 | GNUNET_assert(GNUNET_OK == ret); | 727 | GNUNET_assert (GNUNET_OK == ret); |
725 | if (GNUNET_YES == client->needs_continue) | 728 | if (GNUNET_YES == client->needs_continue) |
726 | return; | 729 | return; |
727 | if (NULL != client->recv_task) | 730 | if (NULL != client->recv_task) |
728 | return; | 731 | return; |
729 | /* MST needs more data, re-schedule read job */ | 732 | /* MST needs more data, re-schedule read job */ |
730 | client->recv_task = | 733 | client->recv_task = |
731 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 734 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
732 | client->sock, | 735 | client->sock, |
733 | &service_client_recv, | 736 | &service_client_recv, |
734 | client); | 737 | client); |
735 | } | 738 | } |
736 | 739 | ||
737 | 740 | ||
@@ -743,31 +746,31 @@ service_client_recv(void *cls) | |||
743 | * @param sock socket associated with the client | 746 | * @param sock socket associated with the client |
744 | */ | 747 | */ |
745 | static void | 748 | static void |
746 | start_client(struct GNUNET_SERVICE_Handle *sh, | 749 | start_client (struct GNUNET_SERVICE_Handle *sh, |
747 | struct GNUNET_NETWORK_Handle *csock) | 750 | struct GNUNET_NETWORK_Handle *csock) |
748 | { | 751 | { |
749 | struct GNUNET_SERVICE_Client *client; | 752 | struct GNUNET_SERVICE_Client *client; |
750 | 753 | ||
751 | client = GNUNET_new(struct GNUNET_SERVICE_Client); | 754 | client = GNUNET_new (struct GNUNET_SERVICE_Client); |
752 | GNUNET_CONTAINER_DLL_insert(sh->clients_head, sh->clients_tail, client); | 755 | GNUNET_CONTAINER_DLL_insert (sh->clients_head, sh->clients_tail, client); |
753 | client->sh = sh; | 756 | client->sh = sh; |
754 | client->sock = csock; | 757 | client->sock = csock; |
755 | client->mq = GNUNET_MQ_queue_for_callbacks(&service_mq_send, | 758 | client->mq = GNUNET_MQ_queue_for_callbacks (&service_mq_send, |
756 | NULL, | 759 | NULL, |
757 | &service_mq_cancel, | 760 | &service_mq_cancel, |
758 | client, | 761 | client, |
759 | sh->handlers, | 762 | sh->handlers, |
760 | &service_mq_error_handler, | 763 | &service_mq_error_handler, |
761 | client); | 764 | client); |
762 | client->mst = GNUNET_MST_create(&service_client_mst_cb, client); | 765 | client->mst = GNUNET_MST_create (&service_client_mst_cb, client); |
763 | if (NULL != sh->connect_cb) | 766 | if (NULL != sh->connect_cb) |
764 | client->user_context = sh->connect_cb(sh->cb_cls, client, client->mq); | 767 | client->user_context = sh->connect_cb (sh->cb_cls, client, client->mq); |
765 | GNUNET_MQ_set_handlers_closure(client->mq, client->user_context); | 768 | GNUNET_MQ_set_handlers_closure (client->mq, client->user_context); |
766 | client->recv_task = | 769 | client->recv_task = |
767 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 770 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
768 | client->sock, | 771 | client->sock, |
769 | &service_client_recv, | 772 | &service_client_recv, |
770 | client); | 773 | client); |
771 | } | 774 | } |
772 | 775 | ||
773 | 776 | ||
@@ -778,83 +781,83 @@ start_client(struct GNUNET_SERVICE_Handle *sh, | |||
778 | * @param cls the `struct ServiceListenContext` of the ready listen socket | 781 | * @param cls the `struct ServiceListenContext` of the ready listen socket |
779 | */ | 782 | */ |
780 | static void | 783 | static void |
781 | accept_client(void *cls) | 784 | accept_client (void *cls) |
782 | { | 785 | { |
783 | struct ServiceListenContext *slc = cls; | 786 | struct ServiceListenContext *slc = cls; |
784 | struct GNUNET_SERVICE_Handle *sh = slc->sh; | 787 | struct GNUNET_SERVICE_Handle *sh = slc->sh; |
785 | 788 | ||
786 | slc->listen_task = NULL; | 789 | slc->listen_task = NULL; |
787 | while (1) | 790 | while (1) |
791 | { | ||
792 | struct GNUNET_NETWORK_Handle *sock; | ||
793 | const struct sockaddr_in *v4; | ||
794 | const struct sockaddr_in6 *v6; | ||
795 | struct sockaddr_storage sa; | ||
796 | socklen_t addrlen; | ||
797 | int ok; | ||
798 | |||
799 | addrlen = sizeof(sa); | ||
800 | sock = GNUNET_NETWORK_socket_accept (slc->listen_socket, | ||
801 | (struct sockaddr *) &sa, | ||
802 | &addrlen); | ||
803 | if (NULL == sock) | ||
804 | { | ||
805 | if (EMFILE == errno) | ||
806 | do_suspend (sh, SUSPEND_STATE_EMFILE); | ||
807 | else if (EAGAIN != errno) | ||
808 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept"); | ||
809 | break; | ||
810 | } | ||
811 | switch (sa.ss_family) | ||
788 | { | 812 | { |
789 | struct GNUNET_NETWORK_Handle *sock; | 813 | case AF_INET: |
790 | const struct sockaddr_in *v4; | 814 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in)); |
791 | const struct sockaddr_in6 *v6; | 815 | v4 = (const struct sockaddr_in *) &sa; |
792 | struct sockaddr_storage sa; | 816 | ok = (((NULL == sh->v4_allowed) || |
793 | socklen_t addrlen; | 817 | (check_ipv4_listed (sh->v4_allowed, &v4->sin_addr))) && |
794 | int ok; | 818 | ((NULL == sh->v4_denied) || |
795 | 819 | (! check_ipv4_listed (sh->v4_denied, &v4->sin_addr)))); | |
796 | addrlen = sizeof(sa); | 820 | break; |
797 | sock = GNUNET_NETWORK_socket_accept(slc->listen_socket, | 821 | |
798 | (struct sockaddr *)&sa, | 822 | case AF_INET6: |
799 | &addrlen); | 823 | GNUNET_assert (addrlen == sizeof(struct sockaddr_in6)); |
800 | if (NULL == sock) | 824 | v6 = (const struct sockaddr_in6 *) &sa; |
801 | { | 825 | ok = (((NULL == sh->v6_allowed) || |
802 | if (EMFILE == errno) | 826 | (check_ipv6_listed (sh->v6_allowed, &v6->sin6_addr))) && |
803 | do_suspend(sh, SUSPEND_STATE_EMFILE); | 827 | ((NULL == sh->v6_denied) || |
804 | else if (EAGAIN != errno) | 828 | (! check_ipv6_listed (sh->v6_denied, &v6->sin6_addr)))); |
805 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "accept"); | 829 | break; |
806 | break; | 830 | |
807 | } | 831 | case AF_UNIX: |
808 | switch (sa.ss_family) | 832 | ok = GNUNET_OK; /* controlled using file-system ACL now */ |
809 | { | 833 | break; |
810 | case AF_INET: | 834 | |
811 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in)); | 835 | default: |
812 | v4 = (const struct sockaddr_in *)&sa; | 836 | LOG (GNUNET_ERROR_TYPE_WARNING, |
813 | ok = (((NULL == sh->v4_allowed) || | 837 | _ ("Unknown address family %d\n"), |
814 | (check_ipv4_listed(sh->v4_allowed, &v4->sin_addr))) && | 838 | sa.ss_family); |
815 | ((NULL == sh->v4_denied) || | 839 | return; |
816 | (!check_ipv4_listed(sh->v4_denied, &v4->sin_addr)))); | 840 | } |
817 | break; | 841 | if (! ok) |
818 | 842 | { | |
819 | case AF_INET6: | 843 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
820 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); | 844 | "Service rejected incoming connection from %s due to policy.\n", |
821 | v6 = (const struct sockaddr_in6 *)&sa; | 845 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); |
822 | ok = (((NULL == sh->v6_allowed) || | 846 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
823 | (check_ipv6_listed(sh->v6_allowed, &v6->sin6_addr))) && | 847 | continue; |
824 | ((NULL == sh->v6_denied) || | ||
825 | (!check_ipv6_listed(sh->v6_denied, &v6->sin6_addr)))); | ||
826 | break; | ||
827 | |||
828 | case AF_UNIX: | ||
829 | ok = GNUNET_OK; /* controlled using file-system ACL now */ | ||
830 | break; | ||
831 | |||
832 | default: | ||
833 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
834 | _("Unknown address family %d\n"), | ||
835 | sa.ss_family); | ||
836 | return; | ||
837 | } | ||
838 | if (!ok) | ||
839 | { | ||
840 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
841 | "Service rejected incoming connection from %s due to policy.\n", | ||
842 | GNUNET_a2s((const struct sockaddr *)&sa, addrlen)); | ||
843 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | ||
844 | continue; | ||
845 | } | ||
846 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
847 | "Service accepted incoming connection from %s.\n", | ||
848 | GNUNET_a2s((const struct sockaddr *)&sa, addrlen)); | ||
849 | start_client(slc->sh, sock); | ||
850 | } | 848 | } |
849 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
850 | "Service accepted incoming connection from %s.\n", | ||
851 | GNUNET_a2s ((const struct sockaddr *) &sa, addrlen)); | ||
852 | start_client (slc->sh, sock); | ||
853 | } | ||
851 | if (0 != sh->suspend_state) | 854 | if (0 != sh->suspend_state) |
852 | return; | 855 | return; |
853 | slc->listen_task = | 856 | slc->listen_task = |
854 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 857 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
855 | slc->listen_socket, | 858 | slc->listen_socket, |
856 | &accept_client, | 859 | &accept_client, |
857 | slc); | 860 | slc); |
858 | } | 861 | } |
859 | 862 | ||
860 | 863 | ||
@@ -866,23 +869,23 @@ accept_client(void *cls) | |||
866 | * or #SUSPEND_STATE_NONE on first startup | 869 | * or #SUSPEND_STATE_NONE on first startup |
867 | */ | 870 | */ |
868 | static void | 871 | static void |
869 | do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | 872 | do_resume (struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) |
870 | { | 873 | { |
871 | struct ServiceListenContext *slc; | 874 | struct ServiceListenContext *slc; |
872 | 875 | ||
873 | GNUNET_assert((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); | 876 | GNUNET_assert ((SUSPEND_STATE_NONE == sr) || (0 != (sh->suspend_state & sr))); |
874 | sh->suspend_state -= sr; | 877 | sh->suspend_state -= sr; |
875 | if (SUSPEND_STATE_NONE != sh->suspend_state) | 878 | if (SUSPEND_STATE_NONE != sh->suspend_state) |
876 | return; | 879 | return; |
877 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | 880 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) |
878 | { | 881 | { |
879 | GNUNET_assert(NULL == slc->listen_task); | 882 | GNUNET_assert (NULL == slc->listen_task); |
880 | slc->listen_task = | 883 | slc->listen_task = |
881 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 884 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
882 | slc->listen_socket, | 885 | slc->listen_socket, |
883 | &accept_client, | 886 | &accept_client, |
884 | slc); | 887 | slc); |
885 | } | 888 | } |
886 | } | 889 | } |
887 | 890 | ||
888 | 891 | ||
@@ -894,23 +897,24 @@ do_resume(struct GNUNET_SERVICE_Handle *sh, enum SuspendReason sr) | |||
894 | * @param cls our `struct GNUNET_SERVICE_Handle` | 897 | * @param cls our `struct GNUNET_SERVICE_Handle` |
895 | */ | 898 | */ |
896 | static void | 899 | static void |
897 | service_main(void *cls) | 900 | service_main (void *cls) |
898 | { | 901 | { |
899 | struct GNUNET_SERVICE_Handle *sh = cls; | 902 | struct GNUNET_SERVICE_Handle *sh = cls; |
900 | 903 | ||
901 | if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != sh->options) | 904 | if (GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN != |
902 | GNUNET_SCHEDULER_add_shutdown(&service_shutdown, sh); | 905 | (sh->options & GNUNET_SERVICE_OPTION_SHUTDOWN_BITMASK)) |
903 | do_resume(sh, SUSPEND_STATE_NONE); | 906 | GNUNET_SCHEDULER_add_shutdown (&service_shutdown, sh); |
907 | do_resume (sh, SUSPEND_STATE_NONE); | ||
904 | 908 | ||
905 | if (-1 != sh->ready_confirm_fd) | 909 | if (-1 != sh->ready_confirm_fd) |
906 | { | 910 | { |
907 | GNUNET_break(1 == write(sh->ready_confirm_fd, ".", 1)); | 911 | GNUNET_break (1 == write (sh->ready_confirm_fd, ".", 1)); |
908 | GNUNET_break(0 == close(sh->ready_confirm_fd)); | 912 | GNUNET_break (0 == close (sh->ready_confirm_fd)); |
909 | sh->ready_confirm_fd = -1; | 913 | sh->ready_confirm_fd = -1; |
910 | } | 914 | } |
911 | 915 | ||
912 | if (NULL != sh->service_init_cb) | 916 | if (NULL != sh->service_init_cb) |
913 | sh->service_init_cb(sh->cb_cls, sh->cfg, sh); | 917 | sh->service_init_cb (sh->cb_cls, sh->cfg, sh); |
914 | } | 918 | } |
915 | 919 | ||
916 | 920 | ||
@@ -924,33 +928,33 @@ service_main(void *cls) | |||
924 | * no ACL configured) | 928 | * no ACL configured) |
925 | */ | 929 | */ |
926 | static int | 930 | static int |
927 | process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, | 931 | process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, |
928 | struct GNUNET_SERVICE_Handle *sh, | 932 | struct GNUNET_SERVICE_Handle *sh, |
929 | const char *option) | 933 | const char *option) |
930 | { | 934 | { |
931 | char *opt; | 935 | char *opt; |
932 | 936 | ||
933 | if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) | 937 | if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option)) |
934 | { | 938 | { |
935 | *ret = NULL; | 939 | *ret = NULL; |
936 | return GNUNET_OK; | 940 | return GNUNET_OK; |
937 | } | 941 | } |
938 | GNUNET_break(GNUNET_OK == | 942 | GNUNET_break (GNUNET_OK == |
939 | GNUNET_CONFIGURATION_get_value_string(sh->cfg, | 943 | GNUNET_CONFIGURATION_get_value_string (sh->cfg, |
940 | sh->service_name, | 944 | sh->service_name, |
941 | option, | 945 | option, |
942 | &opt)); | 946 | &opt)); |
943 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy(opt))) | 947 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt))) |
944 | { | 948 | { |
945 | LOG(GNUNET_ERROR_TYPE_WARNING, | 949 | LOG (GNUNET_ERROR_TYPE_WARNING, |
946 | _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), | 950 | _ ("Could not parse IPv4 network specification `%s' for `%s:%s'\n"), |
947 | opt, | 951 | opt, |
948 | sh->service_name, | 952 | sh->service_name, |
949 | option); | 953 | option); |
950 | GNUNET_free(opt); | 954 | GNUNET_free (opt); |
951 | return GNUNET_SYSERR; | 955 | return GNUNET_SYSERR; |
952 | } | 956 | } |
953 | GNUNET_free(opt); | 957 | GNUNET_free (opt); |
954 | return GNUNET_OK; | 958 | return GNUNET_OK; |
955 | } | 959 | } |
956 | 960 | ||
@@ -965,33 +969,33 @@ process_acl4(struct GNUNET_STRINGS_IPv4NetworkPolicy **ret, | |||
965 | * no ACL configured) | 969 | * no ACL configured) |
966 | */ | 970 | */ |
967 | static int | 971 | static int |
968 | process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, | 972 | process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, |
969 | struct GNUNET_SERVICE_Handle *sh, | 973 | struct GNUNET_SERVICE_Handle *sh, |
970 | const char *option) | 974 | const char *option) |
971 | { | 975 | { |
972 | char *opt; | 976 | char *opt; |
973 | 977 | ||
974 | if (!GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, option)) | 978 | if (! GNUNET_CONFIGURATION_have_value (sh->cfg, sh->service_name, option)) |
975 | { | 979 | { |
976 | *ret = NULL; | 980 | *ret = NULL; |
977 | return GNUNET_OK; | 981 | return GNUNET_OK; |
978 | } | 982 | } |
979 | GNUNET_break(GNUNET_OK == | 983 | GNUNET_break (GNUNET_OK == |
980 | GNUNET_CONFIGURATION_get_value_string(sh->cfg, | 984 | GNUNET_CONFIGURATION_get_value_string (sh->cfg, |
981 | sh->service_name, | 985 | sh->service_name, |
982 | option, | 986 | option, |
983 | &opt)); | 987 | &opt)); |
984 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy(opt))) | 988 | if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt))) |
985 | { | 989 | { |
986 | LOG(GNUNET_ERROR_TYPE_WARNING, | 990 | LOG (GNUNET_ERROR_TYPE_WARNING, |
987 | _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), | 991 | _ ("Could not parse IPv6 network specification `%s' for `%s:%s'\n"), |
988 | opt, | 992 | opt, |
989 | sh->service_name, | 993 | sh->service_name, |
990 | option); | 994 | option); |
991 | GNUNET_free(opt); | 995 | GNUNET_free (opt); |
992 | return GNUNET_SYSERR; | 996 | return GNUNET_SYSERR; |
993 | } | 997 | } |
994 | GNUNET_free(opt); | 998 | GNUNET_free (opt); |
995 | return GNUNET_OK; | 999 | return GNUNET_OK; |
996 | } | 1000 | } |
997 | 1001 | ||
@@ -1003,34 +1007,27 @@ process_acl6(struct GNUNET_STRINGS_IPv6NetworkPolicy **ret, | |||
1003 | * @param saddrs array to update | 1007 | * @param saddrs array to update |
1004 | * @param saddrlens where to store the address length | 1008 | * @param saddrlens where to store the address length |
1005 | * @param unixpath path to add | 1009 | * @param unixpath path to add |
1006 | * @param abstract #GNUNET_YES to add an abstract UNIX domain socket. This | ||
1007 | * parameter is ignore on systems other than LINUX | ||
1008 | */ | 1010 | */ |
1009 | static void | 1011 | static void |
1010 | add_unixpath(struct sockaddr **saddrs, | 1012 | add_unixpath (struct sockaddr **saddrs, |
1011 | socklen_t *saddrlens, | 1013 | socklen_t *saddrlens, |
1012 | const char *unixpath, | 1014 | const char *unixpath) |
1013 | int abstract) | ||
1014 | { | 1015 | { |
1015 | #ifdef AF_UNIX | 1016 | #ifdef AF_UNIX |
1016 | struct sockaddr_un *un; | 1017 | struct sockaddr_un *un; |
1017 | 1018 | ||
1018 | un = GNUNET_new(struct sockaddr_un); | 1019 | un = GNUNET_new (struct sockaddr_un); |
1019 | un->sun_family = AF_UNIX; | 1020 | un->sun_family = AF_UNIX; |
1020 | GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path)); | 1021 | GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path)); |
1021 | #ifdef LINUX | ||
1022 | if (GNUNET_YES == abstract) | ||
1023 | un->sun_path[0] = '\0'; | ||
1024 | #endif | ||
1025 | #if HAVE_SOCKADDR_UN_SUN_LEN | 1022 | #if HAVE_SOCKADDR_UN_SUN_LEN |
1026 | un->sun_len = (u_char)sizeof(struct sockaddr_un); | 1023 | un->sun_len = (u_char) sizeof(struct sockaddr_un); |
1027 | #endif | 1024 | #endif |
1028 | *saddrs = (struct sockaddr *)un; | 1025 | *saddrs = (struct sockaddr *) un; |
1029 | *saddrlens = sizeof(struct sockaddr_un); | 1026 | *saddrlens = sizeof(struct sockaddr_un); |
1030 | #else | 1027 | #else |
1031 | /* this function should never be called | 1028 | /* this function should never be called |
1032 | * unless AF_UNIX is defined! */ | 1029 | * unless AF_UNIX is defined! */ |
1033 | GNUNET_assert(0); | 1030 | GNUNET_assert (0); |
1034 | #endif | 1031 | #endif |
1035 | } | 1032 | } |
1036 | 1033 | ||
@@ -1056,10 +1053,10 @@ add_unixpath(struct sockaddr **saddrs, | |||
1056 | * set to NULL). | 1053 | * set to NULL). |
1057 | */ | 1054 | */ |
1058 | static int | 1055 | static int |
1059 | get_server_addresses(const char *service_name, | 1056 | get_server_addresses (const char *service_name, |
1060 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 1057 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
1061 | struct sockaddr ***addrs, | 1058 | struct sockaddr ***addrs, |
1062 | socklen_t **addr_lens) | 1059 | socklen_t **addr_lens) |
1063 | { | 1060 | { |
1064 | int disablev6; | 1061 | int disablev6; |
1065 | struct GNUNET_NETWORK_Handle *desc; | 1062 | struct GNUNET_NETWORK_Handle *desc; |
@@ -1072,7 +1069,6 @@ get_server_addresses(const char *service_name, | |||
1072 | unsigned int i; | 1069 | unsigned int i; |
1073 | int resi; | 1070 | int resi; |
1074 | int ret; | 1071 | int ret; |
1075 | int abstract; | ||
1076 | struct sockaddr **saddrs; | 1072 | struct sockaddr **saddrs; |
1077 | socklen_t *saddrlens; | 1073 | socklen_t *saddrlens; |
1078 | char *hostname; | 1074 | char *hostname; |
@@ -1081,273 +1077,264 @@ get_server_addresses(const char *service_name, | |||
1081 | *addr_lens = NULL; | 1077 | *addr_lens = NULL; |
1082 | desc = NULL; | 1078 | desc = NULL; |
1083 | disablev6 = GNUNET_NO; | 1079 | disablev6 = GNUNET_NO; |
1084 | if ((GNUNET_NO == GNUNET_NETWORK_test_pf(PF_INET6)) || | 1080 | if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) || |
1085 | (GNUNET_YES == | 1081 | (GNUNET_YES == |
1086 | GNUNET_CONFIGURATION_get_value_yesno(cfg, service_name, "DISABLEV6"))) | 1082 | GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6"))) |
1087 | disablev6 = GNUNET_YES; | 1083 | disablev6 = GNUNET_YES; |
1088 | 1084 | ||
1089 | port = 0; | 1085 | port = 0; |
1090 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT")) | 1086 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) |
1087 | { | ||
1088 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, | ||
1089 | service_name, | ||
1090 | "PORT", | ||
1091 | &port)) | ||
1091 | { | 1092 | { |
1092 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, | 1093 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1093 | service_name, | 1094 | _ ("Require valid port number for service `%s' in configuration!\n"), |
1094 | "PORT", | 1095 | service_name); |
1095 | &port)) | ||
1096 | { | ||
1097 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1098 | _("Require valid port number for service `%s' in configuration!\n"), | ||
1099 | service_name); | ||
1100 | } | ||
1101 | if (port > 65535) | ||
1102 | { | ||
1103 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1104 | _("Require valid port number for service `%s' in configuration!\n"), | ||
1105 | service_name); | ||
1106 | return GNUNET_SYSERR; | ||
1107 | } | ||
1108 | } | 1096 | } |
1109 | 1097 | if (port > 65535) | |
1110 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO")) | ||
1111 | { | 1098 | { |
1112 | GNUNET_break(GNUNET_OK == | 1099 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1113 | GNUNET_CONFIGURATION_get_value_string(cfg, | 1100 | _ ("Require valid port number for service `%s' in configuration!\n"), |
1101 | service_name); | ||
1102 | return GNUNET_SYSERR; | ||
1103 | } | ||
1104 | } | ||
1105 | |||
1106 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) | ||
1107 | { | ||
1108 | GNUNET_break (GNUNET_OK == | ||
1109 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
1114 | service_name, | 1110 | service_name, |
1115 | "BINDTO", | 1111 | "BINDTO", |
1116 | &hostname)); | 1112 | &hostname)); |
1117 | } | 1113 | } |
1118 | else | 1114 | else |
1119 | hostname = NULL; | 1115 | hostname = NULL; |
1120 | 1116 | ||
1121 | unixpath = NULL; | 1117 | unixpath = NULL; |
1122 | abstract = GNUNET_NO; | ||
1123 | #ifdef AF_UNIX | 1118 | #ifdef AF_UNIX |
1124 | if ((GNUNET_YES == | 1119 | if ((GNUNET_YES == |
1125 | GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) && | 1120 | GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && |
1126 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg, | 1121 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, |
1127 | service_name, | 1122 | service_name, |
1128 | "UNIXPATH", | 1123 | "UNIXPATH", |
1129 | &unixpath)) && | 1124 | &unixpath)) && |
1130 | (0 < strlen(unixpath))) | 1125 | (0 < strlen (unixpath))) |
1126 | { | ||
1127 | /* probe UNIX support */ | ||
1128 | struct sockaddr_un s_un; | ||
1129 | |||
1130 | if (strlen (unixpath) >= sizeof(s_un.sun_path)) | ||
1131 | { | 1131 | { |
1132 | /* probe UNIX support */ | 1132 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1133 | struct sockaddr_un s_un; | 1133 | _ ("UNIXPATH `%s' too long, maximum length is %llu\n"), |
1134 | 1134 | unixpath, | |
1135 | if (strlen(unixpath) >= sizeof(s_un.sun_path)) | 1135 | (unsigned long long) sizeof(s_un.sun_path)); |
1136 | { | 1136 | unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); |
1137 | LOG(GNUNET_ERROR_TYPE_WARNING, | 1137 | LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath); |
1138 | _("UNIXPATH `%s' too long, maximum length is %llu\n"), | ||
1139 | unixpath, | ||
1140 | (unsigned long long)sizeof(s_un.sun_path)); | ||
1141 | unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath); | ||
1142 | LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); | ||
1143 | } | ||
1144 | #ifdef LINUX | ||
1145 | abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg, | ||
1146 | "TESTING", | ||
1147 | "USE_ABSTRACT_SOCKETS"); | ||
1148 | if (GNUNET_SYSERR == abstract) | ||
1149 | abstract = GNUNET_NO; | ||
1150 | #endif | ||
1151 | if ((GNUNET_YES != abstract) && | ||
1152 | (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath))) | ||
1153 | GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); | ||
1154 | } | 1138 | } |
1139 | if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath)) | ||
1140 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); | ||
1141 | } | ||
1155 | if (NULL != unixpath) | 1142 | if (NULL != unixpath) |
1143 | { | ||
1144 | desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); | ||
1145 | if (NULL == desc) | ||
1156 | { | 1146 | { |
1157 | desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0); | 1147 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || |
1158 | if (NULL == desc) | 1148 | (EACCES == errno)) |
1159 | { | 1149 | { |
1160 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || | 1150 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
1161 | (EACCES == errno)) | 1151 | GNUNET_free_non_null (hostname); |
1162 | { | 1152 | GNUNET_free (unixpath); |
1163 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 1153 | return GNUNET_SYSERR; |
1164 | GNUNET_free_non_null(hostname); | 1154 | } |
1165 | GNUNET_free(unixpath); | 1155 | LOG (GNUNET_ERROR_TYPE_INFO, |
1166 | return GNUNET_SYSERR; | 1156 | _ ( |
1167 | } | 1157 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), |
1168 | LOG(GNUNET_ERROR_TYPE_INFO, | 1158 | service_name, |
1169 | _( | 1159 | strerror (errno)); |
1170 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), | 1160 | GNUNET_free (unixpath); |
1171 | service_name, | 1161 | unixpath = NULL; |
1172 | strerror(errno)); | ||
1173 | GNUNET_free(unixpath); | ||
1174 | unixpath = NULL; | ||
1175 | } | ||
1176 | else | ||
1177 | { | ||
1178 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc)); | ||
1179 | desc = NULL; | ||
1180 | } | ||
1181 | } | 1162 | } |
1163 | else | ||
1164 | { | ||
1165 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); | ||
1166 | desc = NULL; | ||
1167 | } | ||
1168 | } | ||
1182 | #endif | 1169 | #endif |
1183 | 1170 | ||
1184 | if ((0 == port) && (NULL == unixpath)) | 1171 | if ((0 == port) && (NULL == unixpath)) |
1172 | { | ||
1173 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1174 | _ ( | ||
1175 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | ||
1176 | service_name); | ||
1177 | GNUNET_free_non_null (hostname); | ||
1178 | return GNUNET_SYSERR; | ||
1179 | } | ||
1180 | if (0 == port) | ||
1181 | { | ||
1182 | saddrs = GNUNET_new_array (2, struct sockaddr *); | ||
1183 | saddrlens = GNUNET_new_array (2, socklen_t); | ||
1184 | add_unixpath (saddrs, saddrlens, unixpath); | ||
1185 | GNUNET_free_non_null (unixpath); | ||
1186 | GNUNET_free_non_null (hostname); | ||
1187 | *addrs = saddrs; | ||
1188 | *addr_lens = saddrlens; | ||
1189 | return 1; | ||
1190 | } | ||
1191 | |||
1192 | if (NULL != hostname) | ||
1193 | { | ||
1194 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1195 | "Resolving `%s' since that is where `%s' will bind to.\n", | ||
1196 | hostname, | ||
1197 | service_name); | ||
1198 | memset (&hints, 0, sizeof(struct addrinfo)); | ||
1199 | if (disablev6) | ||
1200 | hints.ai_family = AF_INET; | ||
1201 | hints.ai_protocol = IPPROTO_TCP; | ||
1202 | if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || | ||
1203 | (NULL == res)) | ||
1185 | { | 1204 | { |
1186 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1205 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1187 | _( | 1206 | _ ("Failed to resolve `%s': %s\n"), |
1188 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | 1207 | hostname, |
1189 | service_name); | 1208 | gai_strerror (ret)); |
1190 | GNUNET_free_non_null(hostname); | 1209 | GNUNET_free (hostname); |
1210 | GNUNET_free_non_null (unixpath); | ||
1191 | return GNUNET_SYSERR; | 1211 | return GNUNET_SYSERR; |
1192 | } | 1212 | } |
1193 | if (0 == port) | 1213 | next = res; |
1214 | i = 0; | ||
1215 | while (NULL != (pos = next)) | ||
1194 | { | 1216 | { |
1195 | saddrs = GNUNET_new_array(2, struct sockaddr *); | 1217 | next = pos->ai_next; |
1196 | saddrlens = GNUNET_new_array(2, socklen_t); | 1218 | if ((disablev6) && (pos->ai_family == AF_INET6)) |
1197 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 1219 | continue; |
1198 | GNUNET_free_non_null(unixpath); | 1220 | i++; |
1199 | GNUNET_free_non_null(hostname); | ||
1200 | *addrs = saddrs; | ||
1201 | *addr_lens = saddrlens; | ||
1202 | return 1; | ||
1203 | } | 1221 | } |
1204 | 1222 | if (0 == i) | |
1205 | if (NULL != hostname) | ||
1206 | { | 1223 | { |
1207 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 1224 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1208 | "Resolving `%s' since that is where `%s' will bind to.\n", | 1225 | _ ("Failed to find %saddress for `%s'.\n"), |
1209 | hostname, | 1226 | disablev6 ? "IPv4 " : "", |
1210 | service_name); | 1227 | hostname); |
1211 | memset(&hints, 0, sizeof(struct addrinfo)); | 1228 | freeaddrinfo (res); |
1212 | if (disablev6) | 1229 | GNUNET_free (hostname); |
1213 | hints.ai_family = AF_INET; | 1230 | GNUNET_free_non_null (unixpath); |
1214 | hints.ai_protocol = IPPROTO_TCP; | 1231 | return GNUNET_SYSERR; |
1215 | if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) || | 1232 | } |
1216 | (NULL == res)) | 1233 | resi = i; |
1217 | { | 1234 | if (NULL != unixpath) |
1218 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1235 | resi++; |
1219 | _("Failed to resolve `%s': %s\n"), | 1236 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
1220 | hostname, | 1237 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
1221 | gai_strerror(ret)); | 1238 | i = 0; |
1222 | GNUNET_free(hostname); | 1239 | if (NULL != unixpath) |
1223 | GNUNET_free_non_null(unixpath); | 1240 | { |
1224 | return GNUNET_SYSERR; | 1241 | add_unixpath (saddrs, saddrlens, unixpath); |
1225 | } | 1242 | i++; |
1226 | next = res; | 1243 | } |
1227 | i = 0; | 1244 | next = res; |
1228 | while (NULL != (pos = next)) | 1245 | while (NULL != (pos = next)) |
1229 | { | 1246 | { |
1230 | next = pos->ai_next; | 1247 | next = pos->ai_next; |
1231 | if ((disablev6) && (pos->ai_family == AF_INET6)) | 1248 | if ((disablev6) && (AF_INET6 == pos->ai_family)) |
1232 | continue; | 1249 | continue; |
1233 | i++; | 1250 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) |
1234 | } | 1251 | continue; /* not TCP */ |
1235 | if (0 == i) | 1252 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) |
1236 | { | 1253 | continue; /* huh? */ |
1237 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1254 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1238 | _("Failed to find %saddress for `%s'.\n"), | 1255 | "Service `%s' will bind to `%s'\n", |
1239 | disablev6 ? "IPv4 " : "", | 1256 | service_name, |
1240 | hostname); | 1257 | GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); |
1241 | freeaddrinfo(res); | 1258 | if (AF_INET == pos->ai_family) |
1242 | GNUNET_free(hostname); | 1259 | { |
1243 | GNUNET_free_non_null(unixpath); | 1260 | GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen); |
1244 | return GNUNET_SYSERR; | 1261 | saddrlens[i] = pos->ai_addrlen; |
1245 | } | 1262 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1246 | resi = i; | 1263 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); |
1264 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); | ||
1265 | } | ||
1266 | else | ||
1267 | { | ||
1268 | GNUNET_assert (AF_INET6 == pos->ai_family); | ||
1269 | GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
1270 | saddrlens[i] = pos->ai_addrlen; | ||
1271 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
1272 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); | ||
1273 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); | ||
1274 | } | ||
1275 | i++; | ||
1276 | } | ||
1277 | GNUNET_free (hostname); | ||
1278 | freeaddrinfo (res); | ||
1279 | resi = i; | ||
1280 | } | ||
1281 | else | ||
1282 | { | ||
1283 | /* will bind against everything, just set port */ | ||
1284 | if (disablev6) | ||
1285 | { | ||
1286 | /* V4-only */ | ||
1287 | resi = 1; | ||
1247 | if (NULL != unixpath) | 1288 | if (NULL != unixpath) |
1248 | resi++; | 1289 | resi++; |
1249 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
1250 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
1251 | i = 0; | 1290 | i = 0; |
1291 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); | ||
1292 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); | ||
1252 | if (NULL != unixpath) | 1293 | if (NULL != unixpath) |
1253 | { | 1294 | { |
1254 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 1295 | add_unixpath (saddrs, saddrlens, unixpath); |
1255 | i++; | 1296 | i++; |
1256 | } | 1297 | } |
1257 | next = res; | 1298 | saddrlens[i] = sizeof(struct sockaddr_in); |
1258 | while (NULL != (pos = next)) | 1299 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1259 | { | ||
1260 | next = pos->ai_next; | ||
1261 | if ((disablev6) && (AF_INET6 == pos->ai_family)) | ||
1262 | continue; | ||
1263 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) | ||
1264 | continue; /* not TCP */ | ||
1265 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) | ||
1266 | continue; /* huh? */ | ||
1267 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
1268 | "Service `%s' will bind to `%s'\n", | ||
1269 | service_name, | ||
1270 | GNUNET_a2s(pos->ai_addr, pos->ai_addrlen)); | ||
1271 | if (AF_INET == pos->ai_family) | ||
1272 | { | ||
1273 | GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen); | ||
1274 | saddrlens[i] = pos->ai_addrlen; | ||
1275 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
1276 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
1277 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | ||
1278 | } | ||
1279 | else | ||
1280 | { | ||
1281 | GNUNET_assert(AF_INET6 == pos->ai_family); | ||
1282 | GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
1283 | saddrlens[i] = pos->ai_addrlen; | ||
1284 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
1285 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
1286 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | ||
1287 | } | ||
1288 | i++; | ||
1289 | } | ||
1290 | GNUNET_free(hostname); | ||
1291 | freeaddrinfo(res); | ||
1292 | resi = i; | ||
1293 | } | ||
1294 | else | ||
1295 | { | ||
1296 | /* will bind against everything, just set port */ | ||
1297 | if (disablev6) | ||
1298 | { | ||
1299 | /* V4-only */ | ||
1300 | resi = 1; | ||
1301 | if (NULL != unixpath) | ||
1302 | resi++; | ||
1303 | i = 0; | ||
1304 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
1305 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
1306 | if (NULL != unixpath) | ||
1307 | { | ||
1308 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | ||
1309 | i++; | ||
1310 | } | ||
1311 | saddrlens[i] = sizeof(struct sockaddr_in); | ||
1312 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
1313 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1300 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1314 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i]; | 1301 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; |
1315 | #endif | 1302 | #endif |
1316 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 1303 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
1317 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 1304 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
1318 | } | 1305 | } |
1319 | else | 1306 | else |
1320 | { | 1307 | { |
1321 | /* dual stack */ | 1308 | /* dual stack */ |
1322 | resi = 2; | 1309 | resi = 2; |
1323 | if (NULL != unixpath) | 1310 | if (NULL != unixpath) |
1324 | resi++; | 1311 | resi++; |
1325 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | 1312 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
1326 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | 1313 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
1327 | i = 0; | 1314 | i = 0; |
1328 | if (NULL != unixpath) | 1315 | if (NULL != unixpath) |
1329 | { | 1316 | { |
1330 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 1317 | add_unixpath (saddrs, saddrlens, unixpath); |
1331 | i++; | 1318 | i++; |
1332 | } | 1319 | } |
1333 | saddrlens[i] = sizeof(struct sockaddr_in6); | 1320 | saddrlens[i] = sizeof(struct sockaddr_in6); |
1334 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 1321 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1335 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1322 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1336 | ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0]; | 1323 | ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; |
1337 | #endif | 1324 | #endif |
1338 | ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6; | 1325 | ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; |
1339 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | 1326 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); |
1340 | i++; | 1327 | i++; |
1341 | saddrlens[i] = sizeof(struct sockaddr_in); | 1328 | saddrlens[i] = sizeof(struct sockaddr_in); |
1342 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 1329 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
1343 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1330 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1344 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1]; | 1331 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; |
1345 | #endif | 1332 | #endif |
1346 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 1333 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
1347 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 1334 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
1348 | } | ||
1349 | } | 1335 | } |
1350 | GNUNET_free_non_null(unixpath); | 1336 | } |
1337 | GNUNET_free_non_null (unixpath); | ||
1351 | *addrs = saddrs; | 1338 | *addrs = saddrs; |
1352 | *addr_lens = saddrlens; | 1339 | *addr_lens = saddrlens; |
1353 | return resi; | 1340 | return resi; |
@@ -1362,89 +1349,93 @@ get_server_addresses(const char *service_name, | |||
1362 | * @return NULL on error, otherwise the listen socket | 1349 | * @return NULL on error, otherwise the listen socket |
1363 | */ | 1350 | */ |
1364 | static struct GNUNET_NETWORK_Handle * | 1351 | static struct GNUNET_NETWORK_Handle * |
1365 | open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen) | 1352 | open_listen_socket (const struct sockaddr *server_addr, |
1353 | socklen_t socklen) | ||
1366 | { | 1354 | { |
1367 | struct GNUNET_NETWORK_Handle *sock; | 1355 | struct GNUNET_NETWORK_Handle *sock; |
1368 | uint16_t port; | 1356 | uint16_t port; |
1369 | int eno; | 1357 | int eno; |
1370 | 1358 | ||
1371 | switch (server_addr->sa_family) | 1359 | switch (server_addr->sa_family) |
1372 | { | 1360 | { |
1373 | case AF_INET: | 1361 | case AF_INET: |
1374 | port = ntohs(((const struct sockaddr_in *)server_addr)->sin_port); | 1362 | port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port); |
1375 | break; | 1363 | break; |
1376 | 1364 | case AF_INET6: | |
1377 | case AF_INET6: | 1365 | port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port); |
1378 | port = ntohs(((const struct sockaddr_in6 *)server_addr)->sin6_port); | 1366 | break; |
1379 | break; | 1367 | case AF_UNIX: |
1380 | 1368 | port = 0; | |
1381 | case AF_UNIX: | 1369 | break; |
1382 | port = 0; | 1370 | default: |
1383 | break; | 1371 | GNUNET_break (0); |
1384 | 1372 | port = 0; | |
1385 | default: | 1373 | break; |
1386 | GNUNET_break(0); | 1374 | } |
1387 | port = 0; | 1375 | sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, |
1388 | break; | 1376 | SOCK_STREAM, |
1389 | } | 1377 | 0); |
1390 | sock = GNUNET_NETWORK_socket_create(server_addr->sa_family, SOCK_STREAM, 0); | ||
1391 | if (NULL == sock) | 1378 | if (NULL == sock) |
1392 | { | 1379 | { |
1393 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 1380 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, |
1394 | errno = 0; | 1381 | "socket"); |
1395 | return NULL; | 1382 | errno = 0; |
1396 | } | 1383 | return NULL; |
1384 | } | ||
1397 | /* bind the socket */ | 1385 | /* bind the socket */ |
1398 | if (GNUNET_OK != GNUNET_NETWORK_socket_bind(sock, server_addr, socklen)) | 1386 | if (GNUNET_OK != |
1387 | GNUNET_NETWORK_socket_bind (sock, | ||
1388 | server_addr, | ||
1389 | socklen)) | ||
1390 | { | ||
1391 | eno = errno; | ||
1392 | if (EADDRINUSE != errno) | ||
1399 | { | 1393 | { |
1400 | eno = errno; | 1394 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may |
1401 | if (EADDRINUSE != errno) | 1395 | * fail if we already took the port on IPv6; if both IPv4 and |
1402 | { | 1396 | * IPv6 binds fail, then our caller will log using the |
1403 | /* we don't log 'EADDRINUSE' here since an IPv4 bind may | 1397 | * errno preserved in 'eno' */ |
1404 | * fail if we already took the port on IPv6; if both IPv4 and | 1398 | if (0 != port) |
1405 | * IPv6 binds fail, then our caller will log using the | 1399 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1406 | * errno preserved in 'eno' */ | 1400 | _ ("`%s' failed for port %d (%s).\n"), |
1407 | if (0 != port) | 1401 | "bind", |
1408 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1402 | port, |
1409 | _("`%s' failed for port %d (%s).\n"), | 1403 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); |
1410 | "bind", | ||
1411 | port, | ||
1412 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); | ||
1413 | else | ||
1414 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
1415 | eno = 0; | ||
1416 | } | ||
1417 | else | 1404 | else |
1418 | { | 1405 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind"); |
1419 | if (0 != port) | 1406 | eno = 0; |
1420 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
1421 | _("`%s' failed for port %d (%s): address already in use\n"), | ||
1422 | "bind", | ||
1423 | port, | ||
1424 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); | ||
1425 | else if (AF_UNIX == server_addr->sa_family) | ||
1426 | { | ||
1427 | LOG(GNUNET_ERROR_TYPE_WARNING, | ||
1428 | _("`%s' failed for `%s': address already in use\n"), | ||
1429 | "bind", | ||
1430 | GNUNET_a2s(server_addr, socklen)); | ||
1431 | } | ||
1432 | } | ||
1433 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | ||
1434 | errno = eno; | ||
1435 | return NULL; | ||
1436 | } | 1407 | } |
1437 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) | 1408 | else |
1438 | { | 1409 | { |
1439 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "listen"); | 1410 | if (0 != port) |
1440 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | 1411 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1441 | errno = 0; | 1412 | _ ("`%s' failed for port %d (%s): address already in use\n"), |
1442 | return NULL; | 1413 | "bind", |
1414 | port, | ||
1415 | (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6"); | ||
1416 | else if (AF_UNIX == server_addr->sa_family) | ||
1417 | { | ||
1418 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
1419 | _ ("`%s' failed for `%s': address already in use\n"), | ||
1420 | "bind", | ||
1421 | GNUNET_a2s (server_addr, socklen)); | ||
1422 | } | ||
1443 | } | 1423 | } |
1424 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
1425 | errno = eno; | ||
1426 | return NULL; | ||
1427 | } | ||
1428 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) | ||
1429 | { | ||
1430 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "listen"); | ||
1431 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); | ||
1432 | errno = 0; | ||
1433 | return NULL; | ||
1434 | } | ||
1444 | if (0 != port) | 1435 | if (0 != port) |
1445 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 1436 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1446 | "Server starts to listen on port %u.\n", | 1437 | "Server starts to listen on port %u.\n", |
1447 | port); | 1438 | port); |
1448 | return sock; | 1439 | return sock; |
1449 | } | 1440 | } |
1450 | 1441 | ||
@@ -1466,128 +1457,141 @@ open_listen_socket(const struct sockaddr *server_addr, socklen_t socklen) | |||
1466 | * @return #GNUNET_OK if configuration succeeded | 1457 | * @return #GNUNET_OK if configuration succeeded |
1467 | */ | 1458 | */ |
1468 | static int | 1459 | static int |
1469 | setup_service(struct GNUNET_SERVICE_Handle *sh) | 1460 | setup_service (struct GNUNET_SERVICE_Handle *sh) |
1470 | { | 1461 | { |
1471 | int tolerant; | 1462 | int tolerant; |
1463 | struct GNUNET_NETWORK_Handle **csocks = NULL; | ||
1472 | struct GNUNET_NETWORK_Handle **lsocks; | 1464 | struct GNUNET_NETWORK_Handle **lsocks; |
1473 | const char *nfds; | 1465 | const char *nfds; |
1474 | unsigned int cnt; | 1466 | unsigned int cnt; |
1475 | int flags; | 1467 | int flags; |
1476 | char dummy[2]; | 1468 | char dummy[2]; |
1477 | 1469 | ||
1478 | if (GNUNET_CONFIGURATION_have_value(sh->cfg, sh->service_name, "TOLERANT")) | 1470 | if (GNUNET_CONFIGURATION_have_value (sh->cfg, |
1471 | sh->service_name, | ||
1472 | "TOLERANT")) | ||
1473 | { | ||
1474 | if (GNUNET_SYSERR == | ||
1475 | (tolerant = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, | ||
1476 | sh->service_name, | ||
1477 | "TOLERANT"))) | ||
1479 | { | 1478 | { |
1480 | if (GNUNET_SYSERR == | 1479 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1481 | (tolerant = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1480 | _ ("Specified value for `%s' of service `%s' is invalid\n"), |
1482 | sh->service_name, | 1481 | "TOLERANT", |
1483 | "TOLERANT"))) | 1482 | sh->service_name); |
1484 | { | 1483 | return GNUNET_SYSERR; |
1485 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
1486 | _("Specified value for `%s' of service `%s' is invalid\n"), | ||
1487 | "TOLERANT", | ||
1488 | sh->service_name); | ||
1489 | return GNUNET_SYSERR; | ||
1490 | } | ||
1491 | } | 1484 | } |
1485 | } | ||
1492 | else | 1486 | else |
1493 | tolerant = GNUNET_NO; | 1487 | tolerant = GNUNET_NO; |
1494 | 1488 | ||
1495 | lsocks = NULL; | 1489 | lsocks = NULL; |
1496 | |||
1497 | errno = 0; | 1490 | errno = 0; |
1498 | if ((NULL != (nfds = getenv("LISTEN_FDS"))) && | 1491 | if ((NULL != (nfds = getenv ("LISTEN_FDS"))) && |
1499 | (1 == sscanf(nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && | 1492 | (1 == sscanf (nfds, "%u%1s", &cnt, dummy)) && (cnt > 0) && |
1500 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) | 1493 | (cnt < FD_SETSIZE) && (cnt + 4 < FD_SETSIZE)) |
1494 | { | ||
1495 | lsocks = GNUNET_new_array (cnt + 1, struct GNUNET_NETWORK_Handle *); | ||
1496 | while (0 < cnt--) | ||
1501 | { | 1497 | { |
1502 | lsocks = GNUNET_new_array(cnt + 1, struct GNUNET_NETWORK_Handle *); | 1498 | flags = fcntl (3 + cnt, F_GETFD); |
1503 | while (0 < cnt--) | 1499 | if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || |
1504 | { | 1500 | (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt)))) |
1505 | flags = fcntl(3 + cnt, F_GETFD); | 1501 | { |
1506 | if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) || | 1502 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1507 | (NULL == (lsocks[cnt] = GNUNET_NETWORK_socket_box_native(3 + cnt)))) | 1503 | _ ( |
1508 | { | 1504 | "Could not access pre-bound socket %u, will try to bind myself\n"), |
1509 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1505 | (unsigned int) 3 + cnt); |
1510 | _( | 1506 | cnt++; |
1511 | "Could not access pre-bound socket %u, will try to bind myself\n"), | 1507 | while (NULL != lsocks[cnt]) |
1512 | (unsigned int)3 + cnt); | 1508 | GNUNET_break (GNUNET_OK == |
1513 | cnt++; | 1509 | GNUNET_NETWORK_socket_close (lsocks[cnt++])); |
1514 | while (NULL != lsocks[cnt]) | 1510 | GNUNET_free (lsocks); |
1515 | GNUNET_break(GNUNET_OK == | 1511 | lsocks = NULL; |
1516 | GNUNET_NETWORK_socket_close(lsocks[cnt++])); | 1512 | break; |
1517 | GNUNET_free(lsocks); | 1513 | } |
1518 | lsocks = NULL; | ||
1519 | break; | ||
1520 | } | ||
1521 | } | ||
1522 | unsetenv("LISTEN_FDS"); | ||
1523 | } | 1514 | } |
1515 | unsetenv ("LISTEN_FDS"); | ||
1516 | } | ||
1517 | if ( (0 != (GNUNET_SERVICE_OPTION_CLOSE_LSOCKS & sh->options)) && | ||
1518 | (NULL != lsocks) ) | ||
1519 | { | ||
1520 | csocks = lsocks; | ||
1521 | lsocks = NULL; | ||
1522 | } | ||
1524 | 1523 | ||
1525 | if (NULL != lsocks) | 1524 | if (NULL != lsocks) |
1525 | { | ||
1526 | /* listen only on inherited sockets if we have any */ | ||
1527 | for (struct GNUNET_NETWORK_Handle **ls = lsocks; NULL != *ls; ls++) | ||
1526 | { | 1528 | { |
1527 | /* listen only on inherited sockets if we have any */ | 1529 | struct ServiceListenContext *slc; |
1528 | struct GNUNET_NETWORK_Handle **ls; | 1530 | |
1529 | 1531 | slc = GNUNET_new (struct ServiceListenContext); | |
1530 | for (ls = lsocks; NULL != *ls; ls++) | 1532 | slc->sh = sh; |
1531 | { | 1533 | slc->listen_socket = *ls; |
1532 | struct ServiceListenContext *slc; | 1534 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); |
1533 | |||
1534 | slc = GNUNET_new(struct ServiceListenContext); | ||
1535 | slc->sh = sh; | ||
1536 | slc->listen_socket = *ls; | ||
1537 | GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc); | ||
1538 | } | ||
1539 | GNUNET_free(lsocks); | ||
1540 | } | 1535 | } |
1536 | GNUNET_free (lsocks); | ||
1537 | } | ||
1541 | else | 1538 | else |
1542 | { | 1539 | { |
1543 | struct sockaddr **addrs; | 1540 | struct sockaddr **addrs; |
1544 | socklen_t *addrlens; | 1541 | socklen_t *addrlens; |
1545 | int num; | 1542 | int num; |
1546 | 1543 | ||
1547 | num = get_server_addresses(sh->service_name, sh->cfg, &addrs, &addrlens); | 1544 | num = get_server_addresses (sh->service_name, sh->cfg, &addrs, &addrlens); |
1548 | if (GNUNET_SYSERR == num) | 1545 | if (GNUNET_SYSERR == num) |
1549 | return GNUNET_SYSERR; | 1546 | return GNUNET_SYSERR; |
1550 | 1547 | ||
1551 | for (int i = 0; i < num; i++) | 1548 | for (int i = 0; i < num; i++) |
1552 | { | 1549 | { |
1553 | struct ServiceListenContext *slc; | 1550 | struct ServiceListenContext *slc; |
1554 | |||
1555 | slc = GNUNET_new(struct ServiceListenContext); | ||
1556 | slc->sh = sh; | ||
1557 | slc->listen_socket = open_listen_socket(addrs[i], addrlens[i]); | ||
1558 | GNUNET_free(addrs[i]); | ||
1559 | if (NULL == slc->listen_socket) | ||
1560 | { | ||
1561 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
1562 | GNUNET_free(slc); | ||
1563 | continue; | ||
1564 | } | ||
1565 | GNUNET_CONTAINER_DLL_insert(sh->slc_head, sh->slc_tail, slc); | ||
1566 | } | ||
1567 | GNUNET_free_non_null(addrlens); | ||
1568 | GNUNET_free_non_null(addrs); | ||
1569 | if ((0 != num) && (NULL == sh->slc_head)) | ||
1570 | { | ||
1571 | /* All attempts to bind failed, hard failure */ | ||
1572 | GNUNET_log( | ||
1573 | GNUNET_ERROR_TYPE_ERROR, | ||
1574 | _( | ||
1575 | "Could not bind to any of the ports I was supposed to, refusing to run!\n")); | ||
1576 | return GNUNET_SYSERR; | ||
1577 | } | ||
1578 | } | ||
1579 | 1551 | ||
1552 | slc = GNUNET_new (struct ServiceListenContext); | ||
1553 | slc->sh = sh; | ||
1554 | slc->listen_socket = open_listen_socket (addrs[i], addrlens[i]); | ||
1555 | GNUNET_free (addrs[i]); | ||
1556 | if (NULL == slc->listen_socket) | ||
1557 | { | ||
1558 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); | ||
1559 | GNUNET_free (slc); | ||
1560 | continue; | ||
1561 | } | ||
1562 | GNUNET_CONTAINER_DLL_insert (sh->slc_head, sh->slc_tail, slc); | ||
1563 | } | ||
1564 | GNUNET_free_non_null (addrlens); | ||
1565 | GNUNET_free_non_null (addrs); | ||
1566 | if ((0 != num) && (NULL == sh->slc_head)) | ||
1567 | { | ||
1568 | /* All attempts to bind failed, hard failure */ | ||
1569 | GNUNET_log ( | ||
1570 | GNUNET_ERROR_TYPE_ERROR, | ||
1571 | _ ( | ||
1572 | "Could not bind to any of the ports I was supposed to, refusing to run!\n")); | ||
1573 | GNUNET_free_non_null (csocks); | ||
1574 | return GNUNET_SYSERR; | ||
1575 | } | ||
1576 | } | ||
1577 | if (NULL != csocks) | ||
1578 | { | ||
1579 | /* close inherited sockets to signal parent that we are ready */ | ||
1580 | for (struct GNUNET_NETWORK_Handle **ls = csocks; NULL != *ls; ls++) | ||
1581 | GNUNET_NETWORK_socket_close (*ls); | ||
1582 | GNUNET_free (csocks); | ||
1583 | } | ||
1580 | sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; | 1584 | sh->require_found = tolerant ? GNUNET_NO : GNUNET_YES; |
1581 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1585 | sh->match_uid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, |
1582 | sh->service_name, | 1586 | sh->service_name, |
1583 | "UNIX_MATCH_UID"); | 1587 | "UNIX_MATCH_UID"); |
1584 | sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno(sh->cfg, | 1588 | sh->match_gid = GNUNET_CONFIGURATION_get_value_yesno (sh->cfg, |
1585 | sh->service_name, | 1589 | sh->service_name, |
1586 | "UNIX_MATCH_GID"); | 1590 | "UNIX_MATCH_GID"); |
1587 | process_acl4(&sh->v4_denied, sh, "REJECT_FROM"); | 1591 | process_acl4 (&sh->v4_denied, sh, "REJECT_FROM"); |
1588 | process_acl4(&sh->v4_allowed, sh, "ACCEPT_FROM"); | 1592 | process_acl4 (&sh->v4_allowed, sh, "ACCEPT_FROM"); |
1589 | process_acl6(&sh->v6_denied, sh, "REJECT_FROM6"); | 1593 | process_acl6 (&sh->v6_denied, sh, "REJECT_FROM6"); |
1590 | process_acl6(&sh->v6_allowed, sh, "ACCEPT_FROM6"); | 1594 | process_acl6 (&sh->v6_allowed, sh, "ACCEPT_FROM6"); |
1591 | return GNUNET_OK; | 1595 | return GNUNET_OK; |
1592 | } | 1596 | } |
1593 | 1597 | ||
@@ -1600,14 +1604,14 @@ setup_service(struct GNUNET_SERVICE_Handle *sh) | |||
1600 | * @return value of the 'USERNAME' option | 1604 | * @return value of the 'USERNAME' option |
1601 | */ | 1605 | */ |
1602 | static char * | 1606 | static char * |
1603 | get_user_name(struct GNUNET_SERVICE_Handle *sh) | 1607 | get_user_name (struct GNUNET_SERVICE_Handle *sh) |
1604 | { | 1608 | { |
1605 | char *un; | 1609 | char *un; |
1606 | 1610 | ||
1607 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, | 1611 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1608 | sh->service_name, | 1612 | sh->service_name, |
1609 | "USERNAME", | 1613 | "USERNAME", |
1610 | &un)) | 1614 | &un)) |
1611 | return NULL; | 1615 | return NULL; |
1612 | return un; | 1616 | return un; |
1613 | } | 1617 | } |
@@ -1620,45 +1624,45 @@ get_user_name(struct GNUNET_SERVICE_Handle *sh) | |||
1620 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1624 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1621 | */ | 1625 | */ |
1622 | static int | 1626 | static int |
1623 | set_user_id(struct GNUNET_SERVICE_Handle *sh) | 1627 | set_user_id (struct GNUNET_SERVICE_Handle *sh) |
1624 | { | 1628 | { |
1625 | char *user; | 1629 | char *user; |
1626 | 1630 | ||
1627 | if (NULL == (user = get_user_name(sh))) | 1631 | if (NULL == (user = get_user_name (sh))) |
1628 | return GNUNET_OK; /* keep */ | 1632 | return GNUNET_OK; /* keep */ |
1629 | 1633 | ||
1630 | struct passwd *pws; | 1634 | struct passwd *pws; |
1631 | 1635 | ||
1632 | errno = 0; | 1636 | errno = 0; |
1633 | pws = getpwnam(user); | 1637 | pws = getpwnam (user); |
1634 | if (NULL == pws) | 1638 | if (NULL == pws) |
1635 | { | 1639 | { |
1636 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1640 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1637 | _("Cannot obtain information about user `%s': %s\n"), | 1641 | _ ("Cannot obtain information about user `%s': %s\n"), |
1638 | user, | 1642 | user, |
1639 | errno == 0 ? _("No such user") : strerror(errno)); | 1643 | errno == 0 ? _ ("No such user") : strerror (errno)); |
1640 | GNUNET_free(user); | 1644 | GNUNET_free (user); |
1641 | return GNUNET_SYSERR; | 1645 | return GNUNET_SYSERR; |
1642 | } | 1646 | } |
1643 | if ((0 != setgid(pws->pw_gid)) || (0 != setegid(pws->pw_gid)) || | 1647 | if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) || |
1644 | #if HAVE_INITGROUPS | 1648 | #if HAVE_INITGROUPS |
1645 | (0 != initgroups(user, pws->pw_gid)) || | 1649 | (0 != initgroups (user, pws->pw_gid)) || |
1646 | #endif | 1650 | #endif |
1647 | (0 != setuid(pws->pw_uid)) || (0 != seteuid(pws->pw_uid))) | 1651 | (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid))) |
1652 | { | ||
1653 | if ((0 != setregid (pws->pw_gid, pws->pw_gid)) || | ||
1654 | (0 != setreuid (pws->pw_uid, pws->pw_uid))) | ||
1648 | { | 1655 | { |
1649 | if ((0 != setregid(pws->pw_gid, pws->pw_gid)) || | 1656 | LOG (GNUNET_ERROR_TYPE_ERROR, |
1650 | (0 != setreuid(pws->pw_uid, pws->pw_uid))) | 1657 | _ ("Cannot change user/group to `%s': %s\n"), |
1651 | { | 1658 | user, |
1652 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1659 | strerror (errno)); |
1653 | _("Cannot change user/group to `%s': %s\n"), | 1660 | GNUNET_free (user); |
1654 | user, | 1661 | return GNUNET_SYSERR; |
1655 | strerror(errno)); | ||
1656 | GNUNET_free(user); | ||
1657 | return GNUNET_SYSERR; | ||
1658 | } | ||
1659 | } | 1662 | } |
1663 | } | ||
1660 | 1664 | ||
1661 | GNUNET_free(user); | 1665 | GNUNET_free (user); |
1662 | return GNUNET_OK; | 1666 | return GNUNET_OK; |
1663 | } | 1667 | } |
1664 | 1668 | ||
@@ -1671,14 +1675,14 @@ set_user_id(struct GNUNET_SERVICE_Handle *sh) | |||
1671 | * @return name of the file for the process ID | 1675 | * @return name of the file for the process ID |
1672 | */ | 1676 | */ |
1673 | static char * | 1677 | static char * |
1674 | get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) | 1678 | get_pid_file_name (struct GNUNET_SERVICE_Handle *sh) |
1675 | { | 1679 | { |
1676 | char *pif; | 1680 | char *pif; |
1677 | 1681 | ||
1678 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(sh->cfg, | 1682 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (sh->cfg, |
1679 | sh->service_name, | 1683 | sh->service_name, |
1680 | "PIDFILE", | 1684 | "PIDFILE", |
1681 | &pif)) | 1685 | &pif)) |
1682 | return NULL; | 1686 | return NULL; |
1683 | return pif; | 1687 | return pif; |
1684 | } | 1688 | } |
@@ -1690,15 +1694,15 @@ get_pid_file_name(struct GNUNET_SERVICE_Handle *sh) | |||
1690 | * @param sh service context | 1694 | * @param sh service context |
1691 | */ | 1695 | */ |
1692 | static void | 1696 | static void |
1693 | pid_file_delete(struct GNUNET_SERVICE_Handle *sh) | 1697 | pid_file_delete (struct GNUNET_SERVICE_Handle *sh) |
1694 | { | 1698 | { |
1695 | char *pif = get_pid_file_name(sh); | 1699 | char *pif = get_pid_file_name (sh); |
1696 | 1700 | ||
1697 | if (NULL == pif) | 1701 | if (NULL == pif) |
1698 | return; /* no PID file */ | 1702 | return; /* no PID file */ |
1699 | if (0 != unlink(pif)) | 1703 | if (0 != unlink (pif)) |
1700 | LOG_STRERROR_FILE(GNUNET_ERROR_TYPE_WARNING, "unlink", pif); | 1704 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif); |
1701 | GNUNET_free(pif); | 1705 | GNUNET_free (pif); |
1702 | } | 1706 | } |
1703 | 1707 | ||
1704 | 1708 | ||
@@ -1709,73 +1713,73 @@ pid_file_delete(struct GNUNET_SERVICE_Handle *sh) | |||
1709 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | 1713 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error |
1710 | */ | 1714 | */ |
1711 | static int | 1715 | static int |
1712 | detach_terminal(struct GNUNET_SERVICE_Handle *sh) | 1716 | detach_terminal (struct GNUNET_SERVICE_Handle *sh) |
1713 | { | 1717 | { |
1714 | pid_t pid; | 1718 | pid_t pid; |
1715 | int nullfd; | 1719 | int nullfd; |
1716 | int filedes[2]; | 1720 | int filedes[2]; |
1717 | 1721 | ||
1718 | if (0 != pipe(filedes)) | 1722 | if (0 != pipe (filedes)) |
1719 | { | 1723 | { |
1720 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "pipe"); | 1724 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe"); |
1721 | return GNUNET_SYSERR; | 1725 | return GNUNET_SYSERR; |
1722 | } | 1726 | } |
1723 | pid = fork(); | 1727 | pid = fork (); |
1724 | if (pid < 0) | 1728 | if (pid < 0) |
1725 | { | 1729 | { |
1726 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "fork"); | 1730 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork"); |
1727 | return GNUNET_SYSERR; | 1731 | return GNUNET_SYSERR; |
1728 | } | 1732 | } |
1729 | if (0 != pid) | 1733 | if (0 != pid) |
1734 | { | ||
1735 | /* Parent */ | ||
1736 | char c; | ||
1737 | |||
1738 | GNUNET_break (0 == close (filedes[1])); | ||
1739 | c = 'X'; | ||
1740 | if (1 != read (filedes[0], &c, sizeof(char))) | ||
1741 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read"); | ||
1742 | fflush (stdout); | ||
1743 | switch (c) | ||
1730 | { | 1744 | { |
1731 | /* Parent */ | 1745 | case '.': |
1732 | char c; | 1746 | exit (0); |
1733 | 1747 | ||
1734 | GNUNET_break(0 == close(filedes[1])); | 1748 | case 'I': |
1735 | c = 'X'; | 1749 | LOG (GNUNET_ERROR_TYPE_INFO, |
1736 | if (1 != read(filedes[0], &c, sizeof(char))) | 1750 | _ ("Service process failed to initialize\n")); |
1737 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "read"); | 1751 | break; |
1738 | fflush(stdout); | 1752 | |
1739 | switch (c) | 1753 | case 'S': |
1740 | { | 1754 | LOG (GNUNET_ERROR_TYPE_INFO, |
1741 | case '.': | 1755 | _ ("Service process could not initialize server function\n")); |
1742 | exit(0); | 1756 | break; |
1743 | 1757 | ||
1744 | case 'I': | 1758 | case 'X': |
1745 | LOG(GNUNET_ERROR_TYPE_INFO, | 1759 | LOG (GNUNET_ERROR_TYPE_INFO, |
1746 | _("Service process failed to initialize\n")); | 1760 | _ ("Service process failed to report status\n")); |
1747 | break; | 1761 | break; |
1748 | |||
1749 | case 'S': | ||
1750 | LOG(GNUNET_ERROR_TYPE_INFO, | ||
1751 | _("Service process could not initialize server function\n")); | ||
1752 | break; | ||
1753 | |||
1754 | case 'X': | ||
1755 | LOG(GNUNET_ERROR_TYPE_INFO, | ||
1756 | _("Service process failed to report status\n")); | ||
1757 | break; | ||
1758 | } | ||
1759 | exit(1); /* child reported error */ | ||
1760 | } | 1762 | } |
1761 | GNUNET_break(0 == close(0)); | 1763 | exit (1); /* child reported error */ |
1762 | GNUNET_break(0 == close(1)); | 1764 | } |
1763 | GNUNET_break(0 == close(filedes[0])); | 1765 | GNUNET_break (0 == close (0)); |
1764 | nullfd = open("/dev/null", O_RDWR | O_APPEND); | 1766 | GNUNET_break (0 == close (1)); |
1767 | GNUNET_break (0 == close (filedes[0])); | ||
1768 | nullfd = open ("/dev/null", O_RDWR | O_APPEND); | ||
1765 | if (nullfd < 0) | 1769 | if (nullfd < 0) |
1766 | return GNUNET_SYSERR; | 1770 | return GNUNET_SYSERR; |
1767 | /* set stdin/stdout to /dev/null */ | 1771 | /* set stdin/stdout to /dev/null */ |
1768 | if ((dup2(nullfd, 0) < 0) || (dup2(nullfd, 1) < 0)) | 1772 | if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0)) |
1769 | { | 1773 | { |
1770 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "dup2"); | 1774 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); |
1771 | (void)close(nullfd); | 1775 | (void) close (nullfd); |
1772 | return GNUNET_SYSERR; | 1776 | return GNUNET_SYSERR; |
1773 | } | 1777 | } |
1774 | (void)close(nullfd); | 1778 | (void) close (nullfd); |
1775 | /* Detach from controlling terminal */ | 1779 | /* Detach from controlling terminal */ |
1776 | pid = setsid(); | 1780 | pid = setsid (); |
1777 | if (-1 == pid) | 1781 | if (-1 == pid) |
1778 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "setsid"); | 1782 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid"); |
1779 | sh->ready_confirm_fd = filedes[1]; | 1783 | sh->ready_confirm_fd = filedes[1]; |
1780 | 1784 | ||
1781 | return GNUNET_OK; | 1785 | return GNUNET_OK; |
@@ -1789,23 +1793,23 @@ detach_terminal(struct GNUNET_SERVICE_Handle *sh) | |||
1789 | * @param sh handle to the service to tear down. | 1793 | * @param sh handle to the service to tear down. |
1790 | */ | 1794 | */ |
1791 | static void | 1795 | static void |
1792 | teardown_service(struct GNUNET_SERVICE_Handle *sh) | 1796 | teardown_service (struct GNUNET_SERVICE_Handle *sh) |
1793 | { | 1797 | { |
1794 | struct ServiceListenContext *slc; | 1798 | struct ServiceListenContext *slc; |
1795 | 1799 | ||
1796 | GNUNET_free_non_null(sh->v4_denied); | 1800 | GNUNET_free_non_null (sh->v4_denied); |
1797 | GNUNET_free_non_null(sh->v6_denied); | 1801 | GNUNET_free_non_null (sh->v6_denied); |
1798 | GNUNET_free_non_null(sh->v4_allowed); | 1802 | GNUNET_free_non_null (sh->v4_allowed); |
1799 | GNUNET_free_non_null(sh->v6_allowed); | 1803 | GNUNET_free_non_null (sh->v6_allowed); |
1800 | while (NULL != (slc = sh->slc_head)) | 1804 | while (NULL != (slc = sh->slc_head)) |
1801 | { | 1805 | { |
1802 | GNUNET_CONTAINER_DLL_remove(sh->slc_head, sh->slc_tail, slc); | 1806 | GNUNET_CONTAINER_DLL_remove (sh->slc_head, sh->slc_tail, slc); |
1803 | if (NULL != slc->listen_task) | 1807 | if (NULL != slc->listen_task) |
1804 | GNUNET_SCHEDULER_cancel(slc->listen_task); | 1808 | GNUNET_SCHEDULER_cancel (slc->listen_task); |
1805 | GNUNET_break(GNUNET_OK == | 1809 | GNUNET_break (GNUNET_OK == |
1806 | GNUNET_NETWORK_socket_close(slc->listen_socket)); | 1810 | GNUNET_NETWORK_socket_close (slc->listen_socket)); |
1807 | GNUNET_free(slc); | 1811 | GNUNET_free (slc); |
1808 | } | 1812 | } |
1809 | } | 1813 | } |
1810 | 1814 | ||
1811 | 1815 | ||
@@ -1816,7 +1820,7 @@ teardown_service(struct GNUNET_SERVICE_Handle *sh) | |||
1816 | * @param msg AGPL request | 1820 | * @param msg AGPL request |
1817 | */ | 1821 | */ |
1818 | static void | 1822 | static void |
1819 | return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | 1823 | return_agpl (void *cls, const struct GNUNET_MessageHeader *msg) |
1820 | { | 1824 | { |
1821 | struct GNUNET_SERVICE_Client *client = cls; | 1825 | struct GNUNET_SERVICE_Client *client = cls; |
1822 | struct GNUNET_MQ_Handle *mq; | 1826 | struct GNUNET_MQ_Handle *mq; |
@@ -1824,13 +1828,13 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | |||
1824 | struct GNUNET_MessageHeader *res; | 1828 | struct GNUNET_MessageHeader *res; |
1825 | size_t slen; | 1829 | size_t slen; |
1826 | 1830 | ||
1827 | (void)msg; | 1831 | (void) msg; |
1828 | slen = strlen(GNUNET_AGPL_URL) + 1; | 1832 | slen = strlen (GNUNET_AGPL_URL) + 1; |
1829 | env = GNUNET_MQ_msg_extra(res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); | 1833 | env = GNUNET_MQ_msg_extra (res, GNUNET_MESSAGE_TYPE_RESPONSE_AGPL, slen); |
1830 | memcpy(&res[1], GNUNET_AGPL_URL, slen); | 1834 | memcpy (&res[1], GNUNET_AGPL_URL, slen); |
1831 | mq = GNUNET_SERVICE_client_get_mq(client); | 1835 | mq = GNUNET_SERVICE_client_get_mq (client); |
1832 | GNUNET_MQ_send(mq, env); | 1836 | GNUNET_MQ_send (mq, env); |
1833 | GNUNET_SERVICE_client_continue(client); | 1837 | GNUNET_SERVICE_client_continue (client); |
1834 | } | 1838 | } |
1835 | 1839 | ||
1836 | 1840 | ||
@@ -1871,29 +1875,29 @@ return_agpl(void *cls, const struct GNUNET_MessageHeader *msg) | |||
1871 | * @return NULL on error | 1875 | * @return NULL on error |
1872 | */ | 1876 | */ |
1873 | struct GNUNET_SERVICE_Handle * | 1877 | struct GNUNET_SERVICE_Handle * |
1874 | GNUNET_SERVICE_start(const char *service_name, | 1878 | GNUNET_SERVICE_start (const char *service_name, |
1875 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 1879 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
1876 | GNUNET_SERVICE_ConnectHandler connect_cb, | 1880 | GNUNET_SERVICE_ConnectHandler connect_cb, |
1877 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, | 1881 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, |
1878 | void *cls, | 1882 | void *cls, |
1879 | const struct GNUNET_MQ_MessageHandler *handlers) | 1883 | const struct GNUNET_MQ_MessageHandler *handlers) |
1880 | { | 1884 | { |
1881 | struct GNUNET_SERVICE_Handle *sh; | 1885 | struct GNUNET_SERVICE_Handle *sh; |
1882 | 1886 | ||
1883 | sh = GNUNET_new(struct GNUNET_SERVICE_Handle); | 1887 | sh = GNUNET_new (struct GNUNET_SERVICE_Handle); |
1884 | sh->service_name = service_name; | 1888 | sh->service_name = service_name; |
1885 | sh->cfg = cfg; | 1889 | sh->cfg = cfg; |
1886 | sh->connect_cb = connect_cb; | 1890 | sh->connect_cb = connect_cb; |
1887 | sh->disconnect_cb = disconnect_cb; | 1891 | sh->disconnect_cb = disconnect_cb; |
1888 | sh->cb_cls = cls; | 1892 | sh->cb_cls = cls; |
1889 | sh->handlers = GNUNET_MQ_copy_handlers2(handlers, &return_agpl, NULL); | 1893 | sh->handlers = GNUNET_MQ_copy_handlers2 (handlers, &return_agpl, NULL); |
1890 | if (GNUNET_OK != setup_service(sh)) | 1894 | if (GNUNET_OK != setup_service (sh)) |
1891 | { | 1895 | { |
1892 | GNUNET_free_non_null(sh->handlers); | 1896 | GNUNET_free_non_null (sh->handlers); |
1893 | GNUNET_free(sh); | 1897 | GNUNET_free (sh); |
1894 | return NULL; | 1898 | return NULL; |
1895 | } | 1899 | } |
1896 | do_resume(sh, SUSPEND_STATE_NONE); | 1900 | do_resume (sh, SUSPEND_STATE_NONE); |
1897 | return sh; | 1901 | return sh; |
1898 | } | 1902 | } |
1899 | 1903 | ||
@@ -1904,16 +1908,16 @@ GNUNET_SERVICE_start(const char *service_name, | |||
1904 | * @param srv service to stop | 1908 | * @param srv service to stop |
1905 | */ | 1909 | */ |
1906 | void | 1910 | void |
1907 | GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) | 1911 | GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Handle *srv) |
1908 | { | 1912 | { |
1909 | struct GNUNET_SERVICE_Client *client; | 1913 | struct GNUNET_SERVICE_Client *client; |
1910 | 1914 | ||
1911 | GNUNET_SERVICE_suspend(srv); | 1915 | GNUNET_SERVICE_suspend (srv); |
1912 | while (NULL != (client = srv->clients_head)) | 1916 | while (NULL != (client = srv->clients_head)) |
1913 | GNUNET_SERVICE_client_drop(client); | 1917 | GNUNET_SERVICE_client_drop (client); |
1914 | teardown_service(srv); | 1918 | teardown_service (srv); |
1915 | GNUNET_free_non_null(srv->handlers); | 1919 | GNUNET_free_non_null (srv->handlers); |
1916 | GNUNET_free(srv); | 1920 | GNUNET_free (srv); |
1917 | } | 1921 | } |
1918 | 1922 | ||
1919 | 1923 | ||
@@ -1959,15 +1963,15 @@ GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv) | |||
1959 | * @return 0 on success, non-zero on error | 1963 | * @return 0 on success, non-zero on error |
1960 | */ | 1964 | */ |
1961 | int | 1965 | int |
1962 | GNUNET_SERVICE_run_(int argc, | 1966 | GNUNET_SERVICE_run_ (int argc, |
1963 | char *const *argv, | 1967 | char *const *argv, |
1964 | const char *service_name, | 1968 | const char *service_name, |
1965 | enum GNUNET_SERVICE_Options options, | 1969 | enum GNUNET_SERVICE_Options options, |
1966 | GNUNET_SERVICE_InitCallback service_init_cb, | 1970 | GNUNET_SERVICE_InitCallback service_init_cb, |
1967 | GNUNET_SERVICE_ConnectHandler connect_cb, | 1971 | GNUNET_SERVICE_ConnectHandler connect_cb, |
1968 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, | 1972 | GNUNET_SERVICE_DisconnectHandler disconnect_cb, |
1969 | void *cls, | 1973 | void *cls, |
1970 | const struct GNUNET_MQ_MessageHandler *handlers) | 1974 | const struct GNUNET_MQ_MessageHandler *handlers) |
1971 | { | 1975 | { |
1972 | struct GNUNET_SERVICE_Handle sh; | 1976 | struct GNUNET_SERVICE_Handle sh; |
1973 | 1977 | ||
@@ -1986,40 +1990,40 @@ GNUNET_SERVICE_run_(int argc, | |||
1986 | struct GNUNET_CONFIGURATION_Handle *cfg; | 1990 | struct GNUNET_CONFIGURATION_Handle *cfg; |
1987 | int ret; | 1991 | int ret; |
1988 | int err; | 1992 | int err; |
1989 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get(); | 1993 | const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get (); |
1990 | 1994 | struct GNUNET_GETOPT_CommandLineOption service_options[] = { | |
1991 | struct GNUNET_GETOPT_CommandLineOption service_options[] = | 1995 | GNUNET_GETOPT_option_cfgfile (&opt_cfg_filename), |
1992 | { GNUNET_GETOPT_option_cfgfile(&opt_cfg_filename), | 1996 | GNUNET_GETOPT_option_flag ('d', |
1993 | GNUNET_GETOPT_option_flag('d', | 1997 | "daemonize", |
1994 | "daemonize", | 1998 | gettext_noop ( |
1995 | gettext_noop( | 1999 | "do daemonize (detach from terminal)"), |
1996 | "do daemonize (detach from terminal)"), | 2000 | &do_daemonize), |
1997 | &do_daemonize), | 2001 | GNUNET_GETOPT_option_help (NULL), |
1998 | GNUNET_GETOPT_option_help(NULL), | 2002 | GNUNET_GETOPT_option_loglevel (&loglev), |
1999 | GNUNET_GETOPT_option_loglevel(&loglev), | 2003 | GNUNET_GETOPT_option_logfile (&logfile), |
2000 | GNUNET_GETOPT_option_logfile(&logfile), | 2004 | GNUNET_GETOPT_option_version (pd->version), |
2001 | GNUNET_GETOPT_option_version(pd->version), | 2005 | GNUNET_GETOPT_OPTION_END |
2002 | GNUNET_GETOPT_OPTION_END }; | 2006 | }; |
2003 | 2007 | ||
2004 | err = 1; | 2008 | err = 1; |
2005 | memset(&sh, 0, sizeof(sh)); | 2009 | memset (&sh, 0, sizeof(sh)); |
2006 | xdg = getenv("XDG_CONFIG_HOME"); | 2010 | xdg = getenv ("XDG_CONFIG_HOME"); |
2007 | if (NULL != xdg) | 2011 | if (NULL != xdg) |
2008 | GNUNET_asprintf(&cfg_filename, | 2012 | GNUNET_asprintf (&cfg_filename, |
2009 | "%s%s%s", | 2013 | "%s%s%s", |
2010 | xdg, | 2014 | xdg, |
2011 | DIR_SEPARATOR_STR, | 2015 | DIR_SEPARATOR_STR, |
2012 | pd->config_file); | 2016 | pd->config_file); |
2013 | else | 2017 | else |
2014 | cfg_filename = GNUNET_strdup(pd->user_config_file); | 2018 | cfg_filename = GNUNET_strdup (pd->user_config_file); |
2015 | sh.ready_confirm_fd = -1; | 2019 | sh.ready_confirm_fd = -1; |
2016 | sh.options = options; | 2020 | sh.options = options; |
2017 | sh.cfg = cfg = GNUNET_CONFIGURATION_create(); | 2021 | sh.cfg = cfg = GNUNET_CONFIGURATION_create (); |
2018 | sh.service_init_cb = service_init_cb; | 2022 | sh.service_init_cb = service_init_cb; |
2019 | sh.connect_cb = connect_cb; | 2023 | sh.connect_cb = connect_cb; |
2020 | sh.disconnect_cb = disconnect_cb; | 2024 | sh.disconnect_cb = disconnect_cb; |
2021 | sh.cb_cls = cls; | 2025 | sh.cb_cls = cls; |
2022 | sh.handlers = GNUNET_MQ_copy_handlers(handlers); | 2026 | sh.handlers = GNUNET_MQ_copy_handlers (handlers); |
2023 | sh.service_name = service_name; | 2027 | sh.service_name = service_name; |
2024 | sh.ret = 0; | 2028 | sh.ret = 0; |
2025 | /* setup subsystems */ | 2029 | /* setup subsystems */ |
@@ -2029,135 +2033,140 @@ GNUNET_SERVICE_run_(int argc, | |||
2029 | do_daemonize = 0; | 2033 | do_daemonize = 0; |
2030 | #if ENABLE_NLS | 2034 | #if ENABLE_NLS |
2031 | if (NULL != pd->gettext_domain) | 2035 | if (NULL != pd->gettext_domain) |
2036 | { | ||
2037 | setlocale (LC_ALL, ""); | ||
2038 | path = (NULL == pd->gettext_path) ? | ||
2039 | GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR) : | ||
2040 | GNUNET_strdup (pd->gettext_path); | ||
2041 | if (NULL != path) | ||
2032 | { | 2042 | { |
2033 | setlocale(LC_ALL, ""); | 2043 | bindtextdomain (pd->gettext_domain, path); |
2034 | path = (NULL == pd->gettext_path) ? | 2044 | GNUNET_free (path); |
2035 | GNUNET_OS_installation_get_path(GNUNET_OS_IPK_LOCALEDIR) : | ||
2036 | GNUNET_strdup(pd->gettext_path); | ||
2037 | if (NULL != path) | ||
2038 | { | ||
2039 | bindtextdomain(pd->gettext_domain, path); | ||
2040 | GNUNET_free(path); | ||
2041 | } | ||
2042 | textdomain(pd->gettext_domain); | ||
2043 | } | 2045 | } |
2046 | textdomain (pd->gettext_domain); | ||
2047 | } | ||
2044 | #endif | 2048 | #endif |
2045 | ret = GNUNET_GETOPT_run(service_name, service_options, argc, argv); | 2049 | ret = GNUNET_GETOPT_run (service_name, |
2050 | service_options, | ||
2051 | argc, | ||
2052 | argv); | ||
2046 | if (GNUNET_SYSERR == ret) | 2053 | if (GNUNET_SYSERR == ret) |
2047 | goto shutdown; | 2054 | goto shutdown; |
2048 | if (GNUNET_NO == ret) | 2055 | if (GNUNET_NO == ret) |
2049 | { | 2056 | { |
2050 | err = 0; | 2057 | err = 0; |
2051 | goto shutdown; | 2058 | goto shutdown; |
2052 | } | 2059 | } |
2053 | if (GNUNET_OK != GNUNET_log_setup(service_name, loglev, logfile)) | 2060 | if (GNUNET_OK != GNUNET_log_setup (service_name, |
2054 | { | 2061 | loglev, |
2055 | GNUNET_break(0); | 2062 | logfile)) |
2056 | goto shutdown; | 2063 | { |
2057 | } | 2064 | GNUNET_break (0); |
2065 | goto shutdown; | ||
2066 | } | ||
2058 | if (NULL != opt_cfg_filename) | 2067 | if (NULL != opt_cfg_filename) |
2068 | { | ||
2069 | if ((GNUNET_YES != GNUNET_DISK_file_test (opt_cfg_filename)) || | ||
2070 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_filename))) | ||
2059 | { | 2071 | { |
2060 | if ((GNUNET_YES != GNUNET_DISK_file_test(opt_cfg_filename)) || | 2072 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2061 | (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, opt_cfg_filename))) | 2073 | _ ("Malformed configuration file `%s', exit ...\n"), |
2062 | { | 2074 | opt_cfg_filename); |
2063 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 2075 | goto shutdown; |
2064 | _("Malformed configuration file `%s', exit ...\n"), | ||
2065 | opt_cfg_filename); | ||
2066 | goto shutdown; | ||
2067 | } | ||
2068 | } | 2076 | } |
2077 | } | ||
2069 | else | 2078 | else |
2079 | { | ||
2080 | if (GNUNET_YES == GNUNET_DISK_file_test (cfg_filename)) | ||
2070 | { | 2081 | { |
2071 | if (GNUNET_YES == GNUNET_DISK_file_test(cfg_filename)) | 2082 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cfg_filename)) |
2072 | { | 2083 | { |
2073 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, cfg_filename)) | 2084 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2074 | { | 2085 | _ ("Malformed configuration file `%s', exit ...\n"), |
2075 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 2086 | cfg_filename); |
2076 | _("Malformed configuration file `%s', exit ...\n"), | 2087 | goto shutdown; |
2077 | cfg_filename); | 2088 | } |
2078 | goto shutdown; | ||
2079 | } | ||
2080 | } | ||
2081 | else | ||
2082 | { | ||
2083 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, NULL)) | ||
2084 | { | ||
2085 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
2086 | _("Malformed configuration, exit ...\n")); | ||
2087 | goto shutdown; | ||
2088 | } | ||
2089 | } | ||
2090 | } | 2089 | } |
2091 | if (GNUNET_OK != setup_service(&sh)) | 2090 | else |
2092 | goto shutdown; | ||
2093 | if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal(&sh))) | ||
2094 | { | 2091 | { |
2095 | GNUNET_break(0); | 2092 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) |
2096 | goto shutdown; | 2093 | { |
2094 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2095 | _ ("Malformed configuration, exit ...\n")); | ||
2096 | goto shutdown; | ||
2097 | } | ||
2097 | } | 2098 | } |
2098 | if (GNUNET_OK != set_user_id(&sh)) | 2099 | } |
2100 | if (GNUNET_OK != setup_service (&sh)) | ||
2099 | goto shutdown; | 2101 | goto shutdown; |
2100 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 2102 | if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sh))) |
2101 | "Service `%s' runs with configuration from `%s'\n", | 2103 | { |
2102 | service_name, | 2104 | GNUNET_break (0); |
2103 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); | 2105 | goto shutdown; |
2104 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, | 2106 | } |
2105 | "TESTING", | 2107 | if (GNUNET_OK != set_user_id (&sh)) |
2106 | "SKEW_OFFSET", | 2108 | goto shutdown; |
2107 | &skew_offset)) && | 2109 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2108 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(sh.cfg, | 2110 | "Service `%s' runs with configuration from `%s'\n", |
2109 | "TESTING", | 2111 | service_name, |
2110 | "SKEW_VARIANCE", | 2112 | (NULL != opt_cfg_filename) ? opt_cfg_filename : cfg_filename); |
2111 | &skew_variance))) | 2113 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2112 | { | 2114 | "TESTING", |
2113 | clock_offset = skew_offset - skew_variance; | 2115 | "SKEW_OFFSET", |
2114 | GNUNET_TIME_set_offset(clock_offset); | 2116 | &skew_offset)) && |
2115 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); | 2117 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (sh.cfg, |
2116 | } | 2118 | "TESTING", |
2117 | GNUNET_RESOLVER_connect(sh.cfg); | 2119 | "SKEW_VARIANCE", |
2120 | &skew_variance))) | ||
2121 | { | ||
2122 | clock_offset = skew_offset - skew_variance; | ||
2123 | GNUNET_TIME_set_offset (clock_offset); | ||
2124 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset); | ||
2125 | } | ||
2126 | GNUNET_RESOLVER_connect (sh.cfg); | ||
2118 | 2127 | ||
2119 | /* actually run service */ | 2128 | /* actually run service */ |
2120 | err = 0; | 2129 | err = 0; |
2121 | GNUNET_SCHEDULER_run(&service_main, &sh); | 2130 | GNUNET_SCHEDULER_run (&service_main, &sh); |
2122 | /* shutdown */ | 2131 | /* shutdown */ |
2123 | if (1 == do_daemonize) | 2132 | if (1 == do_daemonize) |
2124 | pid_file_delete(&sh); | 2133 | pid_file_delete (&sh); |
2125 | 2134 | ||
2126 | shutdown: | 2135 | shutdown: |
2127 | if (-1 != sh.ready_confirm_fd) | 2136 | if (-1 != sh.ready_confirm_fd) |
2128 | { | 2137 | { |
2129 | if (1 != write(sh.ready_confirm_fd, err ? "I" : "S", 1)) | 2138 | if (1 != write (sh.ready_confirm_fd, err ? "I" : "S", 1)) |
2130 | LOG_STRERROR(GNUNET_ERROR_TYPE_WARNING, "write"); | 2139 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write"); |
2131 | GNUNET_break(0 == close(sh.ready_confirm_fd)); | 2140 | GNUNET_break (0 == close (sh.ready_confirm_fd)); |
2132 | } | 2141 | } |
2133 | #if HAVE_MALLINFO | 2142 | #if HAVE_MALLINFO |
2134 | { | 2143 | { |
2135 | char *counter; | 2144 | char *counter; |
2136 | 2145 | ||
2137 | if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value(sh.cfg, | 2146 | if ((GNUNET_YES == GNUNET_CONFIGURATION_have_value (sh.cfg, |
2138 | service_name, | 2147 | service_name, |
2139 | "GAUGER_HEAP")) && | 2148 | "GAUGER_HEAP")) && |
2140 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(sh.cfg, | 2149 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (sh.cfg, |
2141 | service_name, | 2150 | service_name, |
2142 | "GAUGER_HEAP", | 2151 | "GAUGER_HEAP", |
2143 | &counter))) | 2152 | &counter))) |
2144 | { | 2153 | { |
2145 | struct mallinfo mi; | 2154 | struct mallinfo mi; |
2146 | 2155 | ||
2147 | mi = mallinfo(); | 2156 | mi = mallinfo (); |
2148 | GAUGER(service_name, counter, mi.usmblks, "blocks"); | 2157 | GAUGER (service_name, counter, mi.usmblks, "blocks"); |
2149 | GNUNET_free(counter); | 2158 | GNUNET_free (counter); |
2150 | } | 2159 | } |
2151 | } | 2160 | } |
2152 | #endif | 2161 | #endif |
2153 | teardown_service(&sh); | 2162 | teardown_service (&sh); |
2154 | GNUNET_free_non_null(sh.handlers); | 2163 | GNUNET_free_non_null (sh.handlers); |
2155 | GNUNET_SPEEDUP_stop_(); | 2164 | GNUNET_SPEEDUP_stop_ (); |
2156 | GNUNET_CONFIGURATION_destroy(cfg); | 2165 | GNUNET_CONFIGURATION_destroy (cfg); |
2157 | GNUNET_free_non_null(logfile); | 2166 | GNUNET_free_non_null (logfile); |
2158 | GNUNET_free_non_null(loglev); | 2167 | GNUNET_free_non_null (loglev); |
2159 | GNUNET_free(cfg_filename); | 2168 | GNUNET_free (cfg_filename); |
2160 | GNUNET_free_non_null(opt_cfg_filename); | 2169 | GNUNET_free_non_null (opt_cfg_filename); |
2161 | 2170 | ||
2162 | return err ? GNUNET_SYSERR : sh.ret; | 2171 | return err ? GNUNET_SYSERR : sh.ret; |
2163 | } | 2172 | } |
@@ -2170,9 +2179,9 @@ shutdown: | |||
2170 | * @param sh service to stop accepting connections. | 2179 | * @param sh service to stop accepting connections. |
2171 | */ | 2180 | */ |
2172 | void | 2181 | void |
2173 | GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) | 2182 | GNUNET_SERVICE_suspend (struct GNUNET_SERVICE_Handle *sh) |
2174 | { | 2183 | { |
2175 | do_suspend(sh, SUSPEND_STATE_APP); | 2184 | do_suspend (sh, SUSPEND_STATE_APP); |
2176 | } | 2185 | } |
2177 | 2186 | ||
2178 | 2187 | ||
@@ -2182,9 +2191,9 @@ GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh) | |||
2182 | * @param sh service to resume accepting connections. | 2191 | * @param sh service to resume accepting connections. |
2183 | */ | 2192 | */ |
2184 | void | 2193 | void |
2185 | GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) | 2194 | GNUNET_SERVICE_resume (struct GNUNET_SERVICE_Handle *sh) |
2186 | { | 2195 | { |
2187 | do_resume(sh, SUSPEND_STATE_APP); | 2196 | do_resume (sh, SUSPEND_STATE_APP); |
2188 | } | 2197 | } |
2189 | 2198 | ||
2190 | 2199 | ||
@@ -2195,32 +2204,32 @@ GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh) | |||
2195 | * @param cls our `struct GNUNET_SERVICE_Client` | 2204 | * @param cls our `struct GNUNET_SERVICE_Client` |
2196 | */ | 2205 | */ |
2197 | static void | 2206 | static void |
2198 | resume_client_receive(void *cls) | 2207 | resume_client_receive (void *cls) |
2199 | { | 2208 | { |
2200 | struct GNUNET_SERVICE_Client *c = cls; | 2209 | struct GNUNET_SERVICE_Client *c = cls; |
2201 | int ret; | 2210 | int ret; |
2202 | 2211 | ||
2203 | c->recv_task = NULL; | 2212 | c->recv_task = NULL; |
2204 | /* first, check if there is still something in the buffer */ | 2213 | /* first, check if there is still something in the buffer */ |
2205 | ret = GNUNET_MST_next(c->mst, GNUNET_YES); | 2214 | ret = GNUNET_MST_next (c->mst, GNUNET_YES); |
2206 | if (GNUNET_SYSERR == ret) | 2215 | if (GNUNET_SYSERR == ret) |
2207 | { | 2216 | { |
2208 | if (NULL == c->drop_task) | 2217 | if (NULL == c->drop_task) |
2209 | GNUNET_SERVICE_client_drop(c); | 2218 | GNUNET_SERVICE_client_drop (c); |
2210 | return; | 2219 | return; |
2211 | } | 2220 | } |
2212 | if (GNUNET_NO == ret) | 2221 | if (GNUNET_NO == ret) |
2213 | return; /* done processing, wait for more later */ | 2222 | return; /* done processing, wait for more later */ |
2214 | GNUNET_assert(GNUNET_OK == ret); | 2223 | GNUNET_assert (GNUNET_OK == ret); |
2215 | if (GNUNET_YES == c->needs_continue) | 2224 | if (GNUNET_YES == c->needs_continue) |
2216 | return; /* #GNUNET_MST_next() did give a message to the client */ | 2225 | return; /* #GNUNET_MST_next() did give a message to the client */ |
2217 | /* need to receive more data from the network first */ | 2226 | /* need to receive more data from the network first */ |
2218 | if (NULL != c->recv_task) | 2227 | if (NULL != c->recv_task) |
2219 | return; | 2228 | return; |
2220 | c->recv_task = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 2229 | c->recv_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
2221 | c->sock, | 2230 | c->sock, |
2222 | &service_client_recv, | 2231 | &service_client_recv, |
2223 | c); | 2232 | c); |
2224 | } | 2233 | } |
2225 | 2234 | ||
2226 | 2235 | ||
@@ -2231,18 +2240,18 @@ resume_client_receive(void *cls) | |||
2231 | * @param c the client to continue receiving from | 2240 | * @param c the client to continue receiving from |
2232 | */ | 2241 | */ |
2233 | void | 2242 | void |
2234 | GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) | 2243 | GNUNET_SERVICE_client_continue (struct GNUNET_SERVICE_Client *c) |
2235 | { | 2244 | { |
2236 | GNUNET_assert(NULL == c->drop_task); | 2245 | GNUNET_assert (NULL == c->drop_task); |
2237 | GNUNET_assert(GNUNET_YES == c->needs_continue); | 2246 | GNUNET_assert (GNUNET_YES == c->needs_continue); |
2238 | GNUNET_assert(NULL == c->recv_task); | 2247 | GNUNET_assert (NULL == c->recv_task); |
2239 | c->needs_continue = GNUNET_NO; | 2248 | c->needs_continue = GNUNET_NO; |
2240 | if (NULL != c->warn_task) | 2249 | if (NULL != c->warn_task) |
2241 | { | 2250 | { |
2242 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2251 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2243 | c->warn_task = NULL; | 2252 | c->warn_task = NULL; |
2244 | } | 2253 | } |
2245 | c->recv_task = GNUNET_SCHEDULER_add_now(&resume_client_receive, c); | 2254 | c->recv_task = GNUNET_SCHEDULER_add_now (&resume_client_receive, c); |
2246 | } | 2255 | } |
2247 | 2256 | ||
2248 | 2257 | ||
@@ -2255,14 +2264,14 @@ GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c) | |||
2255 | * @param c client for which to disable the warning | 2264 | * @param c client for which to disable the warning |
2256 | */ | 2265 | */ |
2257 | void | 2266 | void |
2258 | GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) | 2267 | GNUNET_SERVICE_client_disable_continue_warning (struct GNUNET_SERVICE_Client *c) |
2259 | { | 2268 | { |
2260 | GNUNET_break(NULL != c->warn_task); | 2269 | GNUNET_break (NULL != c->warn_task); |
2261 | if (NULL != c->warn_task) | 2270 | if (NULL != c->warn_task) |
2262 | { | 2271 | { |
2263 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2272 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2264 | c->warn_task = NULL; | 2273 | c->warn_task = NULL; |
2265 | } | 2274 | } |
2266 | } | 2275 | } |
2267 | 2276 | ||
2268 | 2277 | ||
@@ -2272,32 +2281,32 @@ GNUNET_SERVICE_client_disable_continue_warning(struct GNUNET_SERVICE_Client *c) | |||
2272 | * @param cls the `struct GNUNET_SERVICE_Client`. | 2281 | * @param cls the `struct GNUNET_SERVICE_Client`. |
2273 | */ | 2282 | */ |
2274 | static void | 2283 | static void |
2275 | finish_client_drop(void *cls) | 2284 | finish_client_drop (void *cls) |
2276 | { | 2285 | { |
2277 | struct GNUNET_SERVICE_Client *c = cls; | 2286 | struct GNUNET_SERVICE_Client *c = cls; |
2278 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2287 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2279 | 2288 | ||
2280 | c->drop_task = NULL; | 2289 | c->drop_task = NULL; |
2281 | GNUNET_assert(NULL == c->send_task); | 2290 | GNUNET_assert (NULL == c->send_task); |
2282 | GNUNET_assert(NULL == c->recv_task); | 2291 | GNUNET_assert (NULL == c->recv_task); |
2283 | GNUNET_assert(NULL == c->warn_task); | 2292 | GNUNET_assert (NULL == c->warn_task); |
2284 | GNUNET_MST_destroy(c->mst); | 2293 | GNUNET_MST_destroy (c->mst); |
2285 | GNUNET_MQ_destroy(c->mq); | 2294 | GNUNET_MQ_destroy (c->mq); |
2286 | if (GNUNET_NO == c->persist) | 2295 | if (GNUNET_NO == c->persist) |
2287 | { | 2296 | { |
2288 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(c->sock)); | 2297 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (c->sock)); |
2289 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && | 2298 | if ((0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && |
2290 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) | 2299 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state))) |
2291 | do_resume(sh, SUSPEND_STATE_EMFILE); | 2300 | do_resume (sh, SUSPEND_STATE_EMFILE); |
2292 | } | 2301 | } |
2293 | else | 2302 | else |
2294 | { | 2303 | { |
2295 | GNUNET_NETWORK_socket_free_memory_only_(c->sock); | 2304 | GNUNET_NETWORK_socket_free_memory_only_ (c->sock); |
2296 | } | 2305 | } |
2297 | GNUNET_free(c); | 2306 | GNUNET_free (c); |
2298 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && | 2307 | if ((0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && |
2299 | (GNUNET_NO == have_non_monitor_clients(sh))) | 2308 | (GNUNET_NO == have_non_monitor_clients (sh))) |
2300 | GNUNET_SERVICE_shutdown(sh); | 2309 | GNUNET_SERVICE_shutdown (sh); |
2301 | } | 2310 | } |
2302 | 2311 | ||
2303 | 2312 | ||
@@ -2312,52 +2321,56 @@ finish_client_drop(void *cls) | |||
2312 | * @param c client to disconnect now | 2321 | * @param c client to disconnect now |
2313 | */ | 2322 | */ |
2314 | void | 2323 | void |
2315 | GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) | 2324 | GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) |
2316 | { | 2325 | { |
2317 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2326 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2318 | 2327 | ||
2319 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 2328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2320 | "Client dropped: %p (MQ: %p)\n", | 2329 | "Client dropped: %p (MQ: %p)\n", |
2321 | c, | 2330 | c, |
2322 | c->mq); | 2331 | c->mq); |
2323 | #if EXECINFO | 2332 | #if EXECINFO |
2324 | { | 2333 | { |
2325 | void *backtrace_array[MAX_TRACE_DEPTH]; | 2334 | void *backtrace_array[MAX_TRACE_DEPTH]; |
2326 | int num_backtrace_strings = backtrace(backtrace_array, MAX_TRACE_DEPTH); | 2335 | int num_backtrace_strings = backtrace (backtrace_array, MAX_TRACE_DEPTH); |
2327 | char **backtrace_strings = | 2336 | char **backtrace_strings = |
2328 | backtrace_symbols(backtrace_array, t->num_backtrace_strings); | 2337 | backtrace_symbols (backtrace_array, t->num_backtrace_strings); |
2329 | for (unsigned int i = 0; i < num_backtrace_strings; i++) | 2338 | for (unsigned int i = 0; i < num_backtrace_strings; i++) |
2330 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 2339 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2331 | "client drop trace %u: %s\n", | 2340 | "client drop trace %u: %s\n", |
2332 | i, | 2341 | i, |
2333 | backtrace_strings[i]); | 2342 | backtrace_strings[i]); |
2334 | } | 2343 | } |
2335 | #endif | 2344 | #endif |
2336 | if (NULL != c->drop_task) | 2345 | if (NULL != c->drop_task) |
2337 | { | 2346 | { |
2338 | /* asked to drop twice! */ | 2347 | /* asked to drop twice! */ |
2339 | GNUNET_assert(0); | 2348 | GNUNET_assert (0); |
2340 | return; | 2349 | return; |
2341 | } | 2350 | } |
2342 | GNUNET_CONTAINER_DLL_remove(sh->clients_head, sh->clients_tail, c); | 2351 | GNUNET_CONTAINER_DLL_remove (sh->clients_head, |
2352 | sh->clients_tail, | ||
2353 | c); | ||
2343 | if (NULL != sh->disconnect_cb) | 2354 | if (NULL != sh->disconnect_cb) |
2344 | sh->disconnect_cb(sh->cb_cls, c, c->user_context); | 2355 | sh->disconnect_cb (sh->cb_cls, |
2356 | c, | ||
2357 | c->user_context); | ||
2345 | if (NULL != c->warn_task) | 2358 | if (NULL != c->warn_task) |
2346 | { | 2359 | { |
2347 | GNUNET_SCHEDULER_cancel(c->warn_task); | 2360 | GNUNET_SCHEDULER_cancel (c->warn_task); |
2348 | c->warn_task = NULL; | 2361 | c->warn_task = NULL; |
2349 | } | 2362 | } |
2350 | if (NULL != c->recv_task) | 2363 | if (NULL != c->recv_task) |
2351 | { | 2364 | { |
2352 | GNUNET_SCHEDULER_cancel(c->recv_task); | 2365 | GNUNET_SCHEDULER_cancel (c->recv_task); |
2353 | c->recv_task = NULL; | 2366 | c->recv_task = NULL; |
2354 | } | 2367 | } |
2355 | if (NULL != c->send_task) | 2368 | if (NULL != c->send_task) |
2356 | { | 2369 | { |
2357 | GNUNET_SCHEDULER_cancel(c->send_task); | 2370 | GNUNET_SCHEDULER_cancel (c->send_task); |
2358 | c->send_task = NULL; | 2371 | c->send_task = NULL; |
2359 | } | 2372 | } |
2360 | c->drop_task = GNUNET_SCHEDULER_add_now(&finish_client_drop, c); | 2373 | c->drop_task = GNUNET_SCHEDULER_add_now (&finish_client_drop, c); |
2361 | } | 2374 | } |
2362 | 2375 | ||
2363 | 2376 | ||
@@ -2367,14 +2380,14 @@ GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c) | |||
2367 | * @param sh server to shutdown | 2380 | * @param sh server to shutdown |
2368 | */ | 2381 | */ |
2369 | void | 2382 | void |
2370 | GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) | 2383 | GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh) |
2371 | { | 2384 | { |
2372 | struct GNUNET_SERVICE_Client *client; | 2385 | struct GNUNET_SERVICE_Client *client; |
2373 | 2386 | ||
2374 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) | 2387 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
2375 | do_suspend(sh, SUSPEND_STATE_SHUTDOWN); | 2388 | do_suspend (sh, SUSPEND_STATE_SHUTDOWN); |
2376 | while (NULL != (client = sh->clients_head)) | 2389 | while (NULL != (client = sh->clients_head)) |
2377 | GNUNET_SERVICE_client_drop(client); | 2390 | GNUNET_SERVICE_client_drop (client); |
2378 | } | 2391 | } |
2379 | 2392 | ||
2380 | 2393 | ||
@@ -2391,12 +2404,12 @@ GNUNET_SERVICE_shutdown(struct GNUNET_SERVICE_Handle *sh) | |||
2391 | * @param c client to mark as a monitor | 2404 | * @param c client to mark as a monitor |
2392 | */ | 2405 | */ |
2393 | void | 2406 | void |
2394 | GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) | 2407 | GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) |
2395 | { | 2408 | { |
2396 | c->is_monitor = GNUNET_YES; | 2409 | c->is_monitor = GNUNET_YES; |
2397 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && | 2410 | if (((0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state)) && |
2398 | (GNUNET_NO == have_non_monitor_clients(c->sh)))) | 2411 | (GNUNET_NO == have_non_monitor_clients (c->sh)))) |
2399 | GNUNET_SERVICE_shutdown(c->sh); | 2412 | GNUNET_SERVICE_shutdown (c->sh); |
2400 | } | 2413 | } |
2401 | 2414 | ||
2402 | 2415 | ||
@@ -2408,7 +2421,7 @@ GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c) | |||
2408 | * @param c client to persist the socket (never to be closed) | 2421 | * @param c client to persist the socket (never to be closed) |
2409 | */ | 2422 | */ |
2410 | void | 2423 | void |
2411 | GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) | 2424 | GNUNET_SERVICE_client_persist (struct GNUNET_SERVICE_Client *c) |
2412 | { | 2425 | { |
2413 | c->persist = GNUNET_YES; | 2426 | c->persist = GNUNET_YES; |
2414 | } | 2427 | } |
@@ -2421,10 +2434,10 @@ GNUNET_SERVICE_client_persist(struct GNUNET_SERVICE_Client *c) | |||
2421 | * @return the message queue of @a c | 2434 | * @return the message queue of @a c |
2422 | */ | 2435 | */ |
2423 | struct GNUNET_MQ_Handle * | 2436 | struct GNUNET_MQ_Handle * |
2424 | GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c) | 2437 | GNUNET_SERVICE_client_get_mq (struct GNUNET_SERVICE_Client *c) |
2425 | { | 2438 | { |
2426 | return c->mq; | 2439 | return c->mq; |
2427 | } | 2440 | } |
2428 | 2441 | ||
2429 | 2442 | ||
2430 | /* end of service_new.c */ | 2443 | /* end of service.c */ |