aboutsummaryrefslogtreecommitdiff
path: root/src/util/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/client.c')
-rw-r--r--src/util/client.c891
1 files changed, 445 insertions, 446 deletions
diff --git a/src/util/client.c b/src/util/client.c
index 313cc23af..e3585af2e 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file util/client.c 22 * @file util/client.c
@@ -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,7 @@
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(GNUNET_TIME_UNIT_SECONDS, 5)
45 45
46 46
47 47
@@ -55,9 +55,7 @@ struct ClientState;
55 * During connect, we try multiple possible IP addresses 55 * During connect, we try multiple possible IP addresses
56 * to find out which one might work. 56 * to find out which one might work.
57 */ 57 */
58struct AddressProbe 58struct AddressProbe {
59{
60
61 /** 59 /**
62 * This is a linked list. 60 * This is a linked list.
63 */ 61 */
@@ -98,9 +96,7 @@ struct AddressProbe
98/** 96/**
99 * Internal state for a client connected to a GNUnet service. 97 * Internal state for a client connected to a GNUnet service.
100 */ 98 */
101struct ClientState 99struct ClientState {
102{
103
104 /** 100 /**
105 * The connection handle, NULL if not live 101 * The connection handle, NULL if not live
106 */ 102 */
@@ -200,7 +196,6 @@ struct ClientState
200 * deferred. 196 * deferred.
201 */ 197 */
202 int in_destroy; 198 int in_destroy;
203
204}; 199};
205 200
206 201
@@ -210,7 +205,7 @@ struct ClientState
210 * @param cls the `struct ClientState` to try to connect to the service 205 * @param cls the `struct ClientState` to try to connect to the service
211 */ 206 */
212static void 207static void
213start_connect (void *cls); 208start_connect(void *cls);
214 209
215 210
216/** 211/**
@@ -220,26 +215,26 @@ start_connect (void *cls);
220 * @param cstate the connection we tried to establish 215 * @param cstate the connection we tried to establish
221 */ 216 */
222static void 217static void
223connect_fail_continuation (struct ClientState *cstate) 218connect_fail_continuation(struct ClientState *cstate)
224{ 219{
225 GNUNET_break (NULL == cstate->ap_head); 220 GNUNET_break(NULL == cstate->ap_head);
226 GNUNET_break (NULL == cstate->ap_tail); 221 GNUNET_break(NULL == cstate->ap_tail);
227 GNUNET_break (NULL == cstate->dns_active); 222 GNUNET_break(NULL == cstate->dns_active);
228 GNUNET_break (NULL == cstate->sock); 223 GNUNET_break(NULL == cstate->sock);
229 GNUNET_assert (NULL == cstate->send_task); 224 GNUNET_assert(NULL == cstate->send_task);
230 GNUNET_assert (NULL == cstate->recv_task); 225 GNUNET_assert(NULL == cstate->recv_task);
231 // GNUNET_assert (NULL == cstate->proxy_handshake); 226 // GNUNET_assert (NULL == cstate->proxy_handshake);
232 227
233 cstate->back_off = GNUNET_TIME_STD_BACKOFF (cstate->back_off); 228 cstate->back_off = GNUNET_TIME_STD_BACKOFF(cstate->back_off);
234 LOG (GNUNET_ERROR_TYPE_DEBUG, 229 LOG(GNUNET_ERROR_TYPE_DEBUG,
235 "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n", 230 "Failed to establish connection to `%s', no further addresses to try, will try again in %s.\n",
236 cstate->service_name, 231 cstate->service_name,
237 GNUNET_STRINGS_relative_time_to_string (cstate->back_off, 232 GNUNET_STRINGS_relative_time_to_string(cstate->back_off,
238 GNUNET_YES)); 233 GNUNET_YES));
239 cstate->retry_task 234 cstate->retry_task
240 = GNUNET_SCHEDULER_add_delayed (cstate->back_off, 235 = GNUNET_SCHEDULER_add_delayed(cstate->back_off,
241 &start_connect, 236 &start_connect,
242 cstate); 237 cstate);
243} 238}
244 239
245 240
@@ -249,7 +244,7 @@ connect_fail_continuation (struct ClientState *cstate)
249 * @param cls the `struct ClientState` with the `msg` to transmit 244 * @param cls the `struct ClientState` with the `msg` to transmit
250 */ 245 */
251static void 246static void
252transmit_ready (void *cls) 247transmit_ready(void *cls)
253{ 248{
254 struct ClientState *cstate = cls; 249 struct ClientState *cstate = cls;
255 ssize_t ret; 250 ssize_t ret;
@@ -260,55 +255,56 @@ transmit_ready (void *cls)
260 cstate->send_task = NULL; 255 cstate->send_task = NULL;
261 if (GNUNET_YES == cstate->in_destroy) 256 if (GNUNET_YES == cstate->in_destroy)
262 return; 257 return;
263 pos = (const char *) cstate->msg; 258 pos = (const char *)cstate->msg;
264 len = ntohs (cstate->msg->size); 259 len = ntohs(cstate->msg->size);
265 GNUNET_assert (cstate->msg_off < len); 260 GNUNET_assert(cstate->msg_off < len);
266 LOG (GNUNET_ERROR_TYPE_DEBUG, 261 LOG(GNUNET_ERROR_TYPE_DEBUG,
267 "message of type %u trying to send with socket %p (MQ: %p\n", 262 "message of type %u trying to send with socket %p (MQ: %p\n",
268 ntohs(cstate->msg->type), 263 ntohs(cstate->msg->type),
269 cstate->sock, 264 cstate->sock,
270 cstate->mq); 265 cstate->mq);
271 266
272 RETRY: 267RETRY:
273 ret = GNUNET_NETWORK_socket_send (cstate->sock, 268 ret = GNUNET_NETWORK_socket_send(cstate->sock,
274 &pos[cstate->msg_off], 269 &pos[cstate->msg_off],
275 len - cstate->msg_off); 270 len - cstate->msg_off);
276 if (-1 == ret) 271 if (-1 == ret)
277 { 272 {
278 LOG (GNUNET_ERROR_TYPE_WARNING, 273 LOG(GNUNET_ERROR_TYPE_WARNING,
279 "Error during sending message of type %u\n", 274 "Error during sending message of type %u\n",
280 ntohs(cstate->msg->type)); 275 ntohs(cstate->msg->type));
281 if (EINTR == errno){ 276 if (EINTR == errno)
282 LOG (GNUNET_ERROR_TYPE_DEBUG, 277 {
283 "Retrying message of type %u\n", 278 LOG(GNUNET_ERROR_TYPE_DEBUG,
284 ntohs(cstate->msg->type)); 279 "Retrying message of type %u\n",
285 goto RETRY; 280 ntohs(cstate->msg->type));
281 goto RETRY;
282 }
283 GNUNET_MQ_inject_error(cstate->mq,
284 GNUNET_MQ_ERROR_WRITE);
285 return;
286 } 286 }
287 GNUNET_MQ_inject_error (cstate->mq,
288 GNUNET_MQ_ERROR_WRITE);
289 return;
290 }
291 notify_in_flight = (0 == cstate->msg_off); 287 notify_in_flight = (0 == cstate->msg_off);
292 cstate->msg_off += ret; 288 cstate->msg_off += ret;
293 if (cstate->msg_off < len) 289 if (cstate->msg_off < len)
294 { 290 {
295 LOG (GNUNET_ERROR_TYPE_DEBUG, 291 LOG(GNUNET_ERROR_TYPE_DEBUG,
296 "rescheduling message of type %u\n", 292 "rescheduling message of type %u\n",
297 ntohs(cstate->msg->type)); 293 ntohs(cstate->msg->type));
298 cstate->send_task 294 cstate->send_task
299 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 295 = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL,
300 cstate->sock, 296 cstate->sock,
301 &transmit_ready, 297 &transmit_ready,
302 cstate); 298 cstate);
303 if (notify_in_flight) 299 if (notify_in_flight)
304 GNUNET_MQ_impl_send_in_flight (cstate->mq); 300 GNUNET_MQ_impl_send_in_flight(cstate->mq);
305 return; 301 return;
306 } 302 }
307 LOG (GNUNET_ERROR_TYPE_DEBUG, 303 LOG(GNUNET_ERROR_TYPE_DEBUG,
308 "sending message of type %u successful\n", 304 "sending message of type %u successful\n",
309 ntohs(cstate->msg->type)); 305 ntohs(cstate->msg->type));
310 cstate->msg = NULL; 306 cstate->msg = NULL;
311 GNUNET_MQ_impl_send_continue (cstate->mq); 307 GNUNET_MQ_impl_send_continue(cstate->mq);
312} 308}
313 309
314 310
@@ -323,20 +319,20 @@ transmit_ready (void *cls)
323 * #GNUNET_SYSERR to stop further processing due to error 319 * #GNUNET_SYSERR to stop further processing due to error
324 */ 320 */
325static int 321static int
326recv_message (void *cls, 322recv_message(void *cls,
327 const struct GNUNET_MessageHeader *msg) 323 const struct GNUNET_MessageHeader *msg)
328{ 324{
329 struct ClientState *cstate = cls; 325 struct ClientState *cstate = cls;
330 326
331 if (GNUNET_YES == cstate->in_destroy) 327 if (GNUNET_YES == cstate->in_destroy)
332 return GNUNET_NO; 328 return GNUNET_NO;
333 LOG (GNUNET_ERROR_TYPE_DEBUG, 329 LOG(GNUNET_ERROR_TYPE_DEBUG,
334 "Received message of type %u and size %u from %s\n", 330 "Received message of type %u and size %u from %s\n",
335 ntohs (msg->type), 331 ntohs(msg->type),
336 ntohs (msg->size), 332 ntohs(msg->size),
337 cstate->service_name); 333 cstate->service_name);
338 GNUNET_MQ_inject_message (cstate->mq, 334 GNUNET_MQ_inject_message(cstate->mq,
339 msg); 335 msg);
340 if (GNUNET_YES == cstate->in_destroy) 336 if (GNUNET_YES == cstate->in_destroy)
341 return GNUNET_NO; 337 return GNUNET_NO;
342 return GNUNET_OK; 338 return GNUNET_OK;
@@ -349,20 +345,20 @@ recv_message (void *cls,
349 * @param cstate handle of the client state to process 345 * @param cstate handle of the client state to process
350 */ 346 */
351static void 347static void
352cancel_aps (struct ClientState *cstate) 348cancel_aps(struct ClientState *cstate)
353{ 349{
354 struct AddressProbe *pos; 350 struct AddressProbe *pos;
355 351
356 while (NULL != (pos = cstate->ap_head)) 352 while (NULL != (pos = cstate->ap_head))
357 { 353 {
358 GNUNET_break (GNUNET_OK == 354 GNUNET_break(GNUNET_OK ==
359 GNUNET_NETWORK_socket_close (pos->sock)); 355 GNUNET_NETWORK_socket_close(pos->sock));
360 GNUNET_SCHEDULER_cancel (pos->task); 356 GNUNET_SCHEDULER_cancel(pos->task);
361 GNUNET_CONTAINER_DLL_remove (cstate->ap_head, 357 GNUNET_CONTAINER_DLL_remove(cstate->ap_head,
362 cstate->ap_tail, 358 cstate->ap_tail,
363 pos); 359 pos);
364 GNUNET_free (pos); 360 GNUNET_free(pos);
365 } 361 }
366} 362}
367 363
368 364
@@ -374,51 +370,51 @@ cancel_aps (struct ClientState *cstate)
374 * @param impl_state our `struct ClientState` 370 * @param impl_state our `struct ClientState`
375 */ 371 */
376static void 372static void
377connection_client_destroy_impl (struct GNUNET_MQ_Handle *mq, 373connection_client_destroy_impl(struct GNUNET_MQ_Handle *mq,
378 void *impl_state) 374 void *impl_state)
379{ 375{
380 struct ClientState *cstate = impl_state; 376 struct ClientState *cstate = impl_state;
381 377
382 (void) mq; 378 (void)mq;
383 if (NULL != cstate->dns_active) 379 if (NULL != cstate->dns_active)
384 { 380 {
385 GNUNET_RESOLVER_request_cancel (cstate->dns_active); 381 GNUNET_RESOLVER_request_cancel(cstate->dns_active);
386 cstate->dns_active = NULL; 382 cstate->dns_active = NULL;
387 } 383 }
388 if (NULL != cstate->send_task) 384 if (NULL != cstate->send_task)
389 { 385 {
390 GNUNET_SCHEDULER_cancel (cstate->send_task); 386 GNUNET_SCHEDULER_cancel(cstate->send_task);
391 cstate->send_task = NULL; 387 cstate->send_task = NULL;
392 } 388 }
393 if (NULL != cstate->retry_task) 389 if (NULL != cstate->retry_task)
394 { 390 {
395 GNUNET_SCHEDULER_cancel (cstate->retry_task); 391 GNUNET_SCHEDULER_cancel(cstate->retry_task);
396 cstate->retry_task = NULL; 392 cstate->retry_task = NULL;
397 } 393 }
398 if (GNUNET_SYSERR == cstate->in_destroy) 394 if (GNUNET_SYSERR == cstate->in_destroy)
399 { 395 {
400 /* defer destruction */ 396 /* defer destruction */
401 cstate->in_destroy = GNUNET_YES; 397 cstate->in_destroy = GNUNET_YES;
402 cstate->mq = NULL; 398 cstate->mq = NULL;
403 return; 399 return;
404 } 400 }
405 if (NULL != cstate->recv_task) 401 if (NULL != cstate->recv_task)
406 { 402 {
407 GNUNET_SCHEDULER_cancel (cstate->recv_task); 403 GNUNET_SCHEDULER_cancel(cstate->recv_task);
408 cstate->recv_task = NULL; 404 cstate->recv_task = NULL;
409 } 405 }
410 if (NULL != cstate->sock) 406 if (NULL != cstate->sock)
411 { 407 {
412 LOG (GNUNET_ERROR_TYPE_DEBUG, 408 LOG(GNUNET_ERROR_TYPE_DEBUG,
413 "destroying socket: %p\n", 409 "destroying socket: %p\n",
414 cstate->sock); 410 cstate->sock);
415 GNUNET_NETWORK_socket_close (cstate->sock); 411 GNUNET_NETWORK_socket_close(cstate->sock);
416 } 412 }
417 cancel_aps (cstate); 413 cancel_aps(cstate);
418 GNUNET_free (cstate->service_name); 414 GNUNET_free(cstate->service_name);
419 GNUNET_free_non_null (cstate->hostname); 415 GNUNET_free_non_null(cstate->hostname);
420 GNUNET_MST_destroy (cstate->mst); 416 GNUNET_MST_destroy(cstate->mst);
421 GNUNET_free (cstate); 417 GNUNET_free(cstate);
422} 418}
423 419
424 420
@@ -428,39 +424,39 @@ connection_client_destroy_impl (struct GNUNET_MQ_Handle *mq,
428 * @param cls `struct ClientState` with connection to read from 424 * @param cls `struct ClientState` with connection to read from
429 */ 425 */
430static void 426static void
431receive_ready (void *cls) 427receive_ready(void *cls)
432{ 428{
433 struct ClientState *cstate = cls; 429 struct ClientState *cstate = cls;
434 int ret; 430 int ret;
435 431
436 cstate->recv_task = NULL; 432 cstate->recv_task = NULL;
437 cstate->in_destroy = GNUNET_SYSERR; 433 cstate->in_destroy = GNUNET_SYSERR;
438 ret = GNUNET_MST_read (cstate->mst, 434 ret = GNUNET_MST_read(cstate->mst,
439 cstate->sock, 435 cstate->sock,
440 GNUNET_NO, 436 GNUNET_NO,
441 GNUNET_NO); 437 GNUNET_NO);
442 if (GNUNET_SYSERR == ret) 438 if (GNUNET_SYSERR == ret)
443 { 439 {
444 if (NULL != cstate->mq) 440 if (NULL != cstate->mq)
445 GNUNET_MQ_inject_error (cstate->mq, 441 GNUNET_MQ_inject_error(cstate->mq,
446 GNUNET_MQ_ERROR_READ); 442 GNUNET_MQ_ERROR_READ);
447 if (GNUNET_YES == cstate->in_destroy) 443 if (GNUNET_YES == cstate->in_destroy)
448 connection_client_destroy_impl (cstate->mq, 444 connection_client_destroy_impl(cstate->mq,
449 cstate); 445 cstate);
450 return; 446 return;
451 } 447 }
452 if (GNUNET_YES == cstate->in_destroy) 448 if (GNUNET_YES == cstate->in_destroy)
453 { 449 {
454 connection_client_destroy_impl (cstate->mq, 450 connection_client_destroy_impl(cstate->mq,
455 cstate); 451 cstate);
456 return; 452 return;
457 } 453 }
458 cstate->in_destroy = GNUNET_NO; 454 cstate->in_destroy = GNUNET_NO;
459 cstate->recv_task 455 cstate->recv_task
460 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 456 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
461 cstate->sock, 457 cstate->sock,
462 &receive_ready, 458 &receive_ready,
463 cstate); 459 cstate);
464} 460}
465 461
466 462
@@ -470,23 +466,23 @@ receive_ready (void *cls)
470 * @param cstate the connection we tried to establish 466 * @param cstate the connection we tried to establish
471 */ 467 */
472static void 468static void
473connect_success_continuation (struct ClientState *cstate) 469connect_success_continuation(struct ClientState *cstate)
474{ 470{
475 GNUNET_assert (NULL == cstate->recv_task); 471 GNUNET_assert(NULL == cstate->recv_task);
476 cstate->recv_task 472 cstate->recv_task
477 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 473 = GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
478 cstate->sock, 474 cstate->sock,
479 &receive_ready, 475 &receive_ready,
480 cstate); 476 cstate);
481 if (NULL != cstate->msg) 477 if (NULL != cstate->msg)
482 { 478 {
483 GNUNET_assert (NULL == cstate->send_task); 479 GNUNET_assert(NULL == cstate->send_task);
484 cstate->send_task 480 cstate->send_task
485 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 481 = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL,
486 cstate->sock, 482 cstate->sock,
487 &transmit_ready, 483 &transmit_ready,
488 cstate); 484 cstate);
489 } 485 }
490} 486}
491 487
492 488
@@ -498,8 +494,8 @@ connect_success_continuation (struct ClientState *cstate)
498 * @return NULL on error, socket connected to UNIX otherwise 494 * @return NULL on error, socket connected to UNIX otherwise
499 */ 495 */
500static struct GNUNET_NETWORK_Handle * 496static struct GNUNET_NETWORK_Handle *
501try_unixpath (const char *service_name, 497try_unixpath(const char *service_name,
502 const struct GNUNET_CONFIGURATION_Handle *cfg) 498 const struct GNUNET_CONFIGURATION_Handle *cfg)
503{ 499{
504#if AF_UNIX 500#if AF_UNIX
505 struct GNUNET_NETWORK_Handle *sock; 501 struct GNUNET_NETWORK_Handle *sock;
@@ -508,67 +504,67 @@ try_unixpath (const char *service_name,
508 504
509 unixpath = NULL; 505 unixpath = NULL;
510 if ((GNUNET_OK == 506 if ((GNUNET_OK ==
511 GNUNET_CONFIGURATION_get_value_filename (cfg, 507 GNUNET_CONFIGURATION_get_value_filename(cfg,
512 service_name, 508 service_name,
513 "UNIXPATH", 509 "UNIXPATH",
514 &unixpath)) && 510 &unixpath)) &&
515 (0 < strlen (unixpath))) 511 (0 < strlen(unixpath)))
516 {
517 /* We have a non-NULL unixpath, need to validate it */
518 if (strlen (unixpath) >= sizeof (s_un.sun_path))
519 { 512 {
520 LOG (GNUNET_ERROR_TYPE_WARNING, 513 /* We have a non-NULL unixpath, need to validate it */
521 _("UNIXPATH `%s' too long, maximum length is %llu\n"), 514 if (strlen(unixpath) >= sizeof(s_un.sun_path))
522 unixpath, 515 {
523 (unsigned long long) sizeof (s_un.sun_path)); 516 LOG(GNUNET_ERROR_TYPE_WARNING,
524 unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); 517 _("UNIXPATH `%s' too long, maximum length is %llu\n"),
525 LOG (GNUNET_ERROR_TYPE_INFO, 518 unixpath,
526 _("Using `%s' instead\n"), 519 (unsigned long long)sizeof(s_un.sun_path));
527 unixpath); 520 unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath);
528 if (NULL == unixpath) 521 LOG(GNUNET_ERROR_TYPE_INFO,
529 return NULL; 522 _("Using `%s' instead\n"),
530 } 523 unixpath);
531 memset (&s_un, 524 if (NULL == unixpath)
532 0, 525 return NULL;
533 sizeof (s_un)); 526 }
534 s_un.sun_family = AF_UNIX; 527 memset(&s_un,
535 GNUNET_strlcpy (s_un.sun_path, 528 0,
536 unixpath, 529 sizeof(s_un));
537 sizeof (s_un.sun_path)); 530 s_un.sun_family = AF_UNIX;
531 GNUNET_strlcpy(s_un.sun_path,
532 unixpath,
533 sizeof(s_un.sun_path));
538#ifdef LINUX 534#ifdef LINUX
539 { 535 {
540 int abstract; 536 int abstract;
541 537
542 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, 538 abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg,
543 "TESTING", 539 "TESTING",
544 "USE_ABSTRACT_SOCKETS"); 540 "USE_ABSTRACT_SOCKETS");
545 if (GNUNET_YES == abstract) 541 if (GNUNET_YES == abstract)
546 s_un.sun_path[0] = '\0'; 542 s_un.sun_path[0] = '\0';
547 } 543 }
548#endif 544#endif
549#if HAVE_SOCKADDR_UN_SUN_LEN 545#if HAVE_SOCKADDR_UN_SUN_LEN
550 s_un.sun_len = (u_char) sizeof (struct sockaddr_un); 546 s_un.sun_len = (u_char)sizeof(struct sockaddr_un);
551#endif 547#endif
552 sock = GNUNET_NETWORK_socket_create (AF_UNIX, 548 sock = GNUNET_NETWORK_socket_create(AF_UNIX,
553 SOCK_STREAM, 549 SOCK_STREAM,
554 0); 550 0);
555 if ( (NULL != sock) && 551 if ((NULL != sock) &&
556 ( (GNUNET_OK == 552 ((GNUNET_OK ==
557 GNUNET_NETWORK_socket_connect (sock, 553 GNUNET_NETWORK_socket_connect(sock,
558 (struct sockaddr *) &s_un, 554 (struct sockaddr *)&s_un,
559 sizeof (s_un))) || 555 sizeof(s_un))) ||
560 (EINPROGRESS == errno) ) ) 556 (EINPROGRESS == errno)))
561 { 557 {
562 LOG (GNUNET_ERROR_TYPE_DEBUG, 558 LOG(GNUNET_ERROR_TYPE_DEBUG,
563 "Successfully connected to unixpath `%s'!\n", 559 "Successfully connected to unixpath `%s'!\n",
564 unixpath); 560 unixpath);
565 GNUNET_free (unixpath); 561 GNUNET_free(unixpath);
566 return sock; 562 return sock;
563 }
564 if (NULL != sock)
565 GNUNET_NETWORK_socket_close(sock);
567 } 566 }
568 if (NULL != sock) 567 GNUNET_free_non_null(unixpath);
569 GNUNET_NETWORK_socket_close (sock);
570 }
571 GNUNET_free_non_null (unixpath);
572#endif 568#endif
573 return NULL; 569 return NULL;
574} 570}
@@ -581,7 +577,7 @@ try_unixpath (const char *service_name,
581 * @param cls the `struct AddressProbe *` with the address that we are probing 577 * @param cls the `struct AddressProbe *` with the address that we are probing
582 */ 578 */
583static void 579static void
584connect_probe_continuation (void *cls) 580connect_probe_continuation(void *cls)
585{ 581{
586 struct AddressProbe *ap = cls; 582 struct AddressProbe *ap = cls;
587 struct ClientState *cstate = ap->cstate; 583 struct ClientState *cstate = ap->cstate;
@@ -590,40 +586,40 @@ connect_probe_continuation (void *cls)
590 socklen_t len; 586 socklen_t len;
591 587
592 ap->task = NULL; 588 ap->task = NULL;
593 GNUNET_assert (NULL != ap->sock); 589 GNUNET_assert(NULL != ap->sock);
594 GNUNET_CONTAINER_DLL_remove (cstate->ap_head, 590 GNUNET_CONTAINER_DLL_remove(cstate->ap_head,
595 cstate->ap_tail, 591 cstate->ap_tail,
596 ap); 592 ap);
597 len = sizeof (error); 593 len = sizeof(error);
598 error = 0; 594 error = 0;
599 tc = GNUNET_SCHEDULER_get_task_context (); 595 tc = GNUNET_SCHEDULER_get_task_context();
600 if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || 596 if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
601 (GNUNET_OK != 597 (GNUNET_OK !=
602 GNUNET_NETWORK_socket_getsockopt (ap->sock, 598 GNUNET_NETWORK_socket_getsockopt(ap->sock,
603 SOL_SOCKET, 599 SOL_SOCKET,
604 SO_ERROR, 600 SO_ERROR,
605 &error, 601 &error,
606 &len)) || 602 &len)) ||
607 (0 != error) ) 603 (0 != error))
608 { 604 {
609 GNUNET_break (GNUNET_OK == 605 GNUNET_break(GNUNET_OK ==
610 GNUNET_NETWORK_socket_close (ap->sock)); 606 GNUNET_NETWORK_socket_close(ap->sock));
611 GNUNET_free (ap); 607 GNUNET_free(ap);
612 if ( (NULL == cstate->ap_head) && 608 if ((NULL == cstate->ap_head) &&
613 // (NULL == cstate->proxy_handshake) && 609 // (NULL == cstate->proxy_handshake) &&
614 (NULL == cstate->dns_active) ) 610 (NULL == cstate->dns_active))
615 connect_fail_continuation (cstate); 611 connect_fail_continuation(cstate);
616 return; 612 return;
617 } 613 }
618 LOG (GNUNET_ERROR_TYPE_DEBUG, 614 LOG(GNUNET_ERROR_TYPE_DEBUG,
619 "Connection to `%s' succeeded!\n", 615 "Connection to `%s' succeeded!\n",
620 cstate->service_name); 616 cstate->service_name);
621 /* trigger jobs that waited for the connection */ 617 /* trigger jobs that waited for the connection */
622 GNUNET_assert (NULL == cstate->sock); 618 GNUNET_assert(NULL == cstate->sock);
623 cstate->sock = ap->sock; 619 cstate->sock = ap->sock;
624 GNUNET_free (ap); 620 GNUNET_free(ap);
625 cancel_aps (cstate); 621 cancel_aps(cstate);
626 connect_success_continuation (cstate); 622 connect_success_continuation(cstate);
627} 623}
628 624
629 625
@@ -636,80 +632,82 @@ connect_probe_continuation (void *cls)
636 * @param addrlen length of @a addr 632 * @param addrlen length of @a addr
637 */ 633 */
638static void 634static void
639try_connect_using_address (void *cls, 635try_connect_using_address(void *cls,
640 const struct sockaddr *addr, 636 const struct sockaddr *addr,
641 socklen_t addrlen) 637 socklen_t addrlen)
642{ 638{
643 struct ClientState *cstate = cls; 639 struct ClientState *cstate = cls;
644 struct AddressProbe *ap; 640 struct AddressProbe *ap;
645 641
646 if (NULL == addr) 642 if (NULL == addr)
647 { 643 {
648 cstate->dns_active = NULL; 644 cstate->dns_active = NULL;
649 if ( (NULL == cstate->ap_head) && 645 if ((NULL == cstate->ap_head) &&
650 // (NULL == cstate->proxy_handshake) && 646 // (NULL == cstate->proxy_handshake) &&
651 (NULL == cstate->sock) ) 647 (NULL == cstate->sock))
652 connect_fail_continuation (cstate); 648 connect_fail_continuation(cstate);
653 return; 649 return;
654 } 650 }
655 if (NULL != cstate->sock) 651 if (NULL != cstate->sock)
656 return; /* already connected */ 652 return; /* already connected */
657 /* try to connect */ 653 /* try to connect */
658 LOG (GNUNET_ERROR_TYPE_DEBUG, 654 LOG(GNUNET_ERROR_TYPE_DEBUG,
659 "Trying to connect using address `%s:%u'\n", 655 "Trying to connect using address `%s:%u'\n",
660 GNUNET_a2s (addr, 656 GNUNET_a2s(addr,
661 addrlen), 657 addrlen),
662 cstate->port); 658 cstate->port);
663 ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen); 659 ap = GNUNET_malloc(sizeof(struct AddressProbe) + addrlen);
664 ap->addr = (const struct sockaddr *) &ap[1]; 660 ap->addr = (const struct sockaddr *)&ap[1];
665 GNUNET_memcpy (&ap[1], 661 GNUNET_memcpy(&ap[1],
666 addr, 662 addr,
667 addrlen); 663 addrlen);
668 ap->addrlen = addrlen; 664 ap->addrlen = addrlen;
669 ap->cstate = cstate; 665 ap->cstate = cstate;
670 666
671 switch (ap->addr->sa_family) 667 switch (ap->addr->sa_family)
672 { 668 {
673 case AF_INET: 669 case AF_INET:
674 ((struct sockaddr_in *) ap->addr)->sin_port = htons (cstate->port); 670 ((struct sockaddr_in *)ap->addr)->sin_port = htons(cstate->port);
675 break; 671 break;
676 case AF_INET6: 672
677 ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (cstate->port); 673 case AF_INET6:
678 break; 674 ((struct sockaddr_in6 *)ap->addr)->sin6_port = htons(cstate->port);
679 default: 675 break;
680 GNUNET_break (0); 676
681 GNUNET_free (ap); 677 default:
682 return; /* not supported by us */ 678 GNUNET_break(0);
683 } 679 GNUNET_free(ap);
684 ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, 680 return; /* not supported by us */
685 SOCK_STREAM, 681 }
686 0); 682 ap->sock = GNUNET_NETWORK_socket_create(ap->addr->sa_family,
683 SOCK_STREAM,
684 0);
687 if (NULL == ap->sock) 685 if (NULL == ap->sock)
688 { 686 {
689 GNUNET_free (ap); 687 GNUNET_free(ap);
690 return; /* not supported by OS */ 688 return; /* not supported by OS */
691 } 689 }
692 if ( (GNUNET_OK != 690 if ((GNUNET_OK !=
693 GNUNET_NETWORK_socket_connect (ap->sock, 691 GNUNET_NETWORK_socket_connect(ap->sock,
694 ap->addr, 692 ap->addr,
695 ap->addrlen)) && 693 ap->addrlen)) &&
696 (EINPROGRESS != errno) ) 694 (EINPROGRESS != errno))
697 { 695 {
698 /* maybe refused / unsupported address, try next */ 696 /* maybe refused / unsupported address, try next */
699 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, 697 GNUNET_log_strerror(GNUNET_ERROR_TYPE_INFO,
700 "connect"); 698 "connect");
701 GNUNET_break (GNUNET_OK == 699 GNUNET_break(GNUNET_OK ==
702 GNUNET_NETWORK_socket_close (ap->sock)); 700 GNUNET_NETWORK_socket_close(ap->sock));
703 GNUNET_free (ap); 701 GNUNET_free(ap);
704 return; 702 return;
705 } 703 }
706 GNUNET_CONTAINER_DLL_insert (cstate->ap_head, 704 GNUNET_CONTAINER_DLL_insert(cstate->ap_head,
707 cstate->ap_tail, 705 cstate->ap_tail,
708 ap); 706 ap);
709 ap->task = GNUNET_SCHEDULER_add_write_net (CONNECT_RETRY_TIMEOUT, 707 ap->task = GNUNET_SCHEDULER_add_write_net(CONNECT_RETRY_TIMEOUT,
710 ap->sock, 708 ap->sock,
711 &connect_probe_continuation, 709 &connect_probe_continuation,
712 ap); 710 ap);
713} 711}
714 712
715 713
@@ -722,55 +720,56 @@ try_connect_using_address (void *cls,
722 * @return #GNUNET_OK if the configuration is valid, #GNUNET_SYSERR if not 720 * @return #GNUNET_OK if the configuration is valid, #GNUNET_SYSERR if not
723 */ 721 */
724static int 722static int
725test_service_configuration (const char *service_name, 723test_service_configuration(const char *service_name,
726 const struct GNUNET_CONFIGURATION_Handle *cfg) 724 const struct GNUNET_CONFIGURATION_Handle *cfg)
727{ 725{
728 int ret = GNUNET_SYSERR; 726 int ret = GNUNET_SYSERR;
729 char *hostname = NULL; 727 char *hostname = NULL;
730 unsigned long long port; 728 unsigned long long port;
729
731#if AF_UNIX 730#if AF_UNIX
732 char *unixpath = NULL; 731 char *unixpath = NULL;
733 732
734 if ((GNUNET_OK == 733 if ((GNUNET_OK ==
735 GNUNET_CONFIGURATION_get_value_filename (cfg, 734 GNUNET_CONFIGURATION_get_value_filename(cfg,
736 service_name, 735 service_name,
737 "UNIXPATH", 736 "UNIXPATH",
738 &unixpath)) && 737 &unixpath)) &&
739 (0 < strlen (unixpath))) 738 (0 < strlen(unixpath)))
740 ret = GNUNET_OK; 739 ret = GNUNET_OK;
741 else if ((GNUNET_OK == 740 else if ((GNUNET_OK ==
742 GNUNET_CONFIGURATION_have_value (cfg, 741 GNUNET_CONFIGURATION_have_value(cfg,
743 service_name, 742 service_name,
744 "UNIXPATH"))) 743 "UNIXPATH")))
745 { 744 {
746 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 745 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
747 service_name, 746 service_name,
748 "UNIXPATH", 747 "UNIXPATH",
749 _("not a valid filename")); 748 _("not a valid filename"));
750 return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */ 749 return GNUNET_SYSERR; /* UNIXPATH specified but invalid! */
751 } 750 }
752 GNUNET_free_non_null (unixpath); 751 GNUNET_free_non_null(unixpath);
753#endif 752#endif
754 753
755 if ( (GNUNET_YES == 754 if ((GNUNET_YES ==
756 GNUNET_CONFIGURATION_have_value (cfg, 755 GNUNET_CONFIGURATION_have_value(cfg,
757 service_name, 756 service_name,
758 "PORT")) && 757 "PORT")) &&
759 (GNUNET_OK == 758 (GNUNET_OK ==
760 GNUNET_CONFIGURATION_get_value_number (cfg, 759 GNUNET_CONFIGURATION_get_value_number(cfg,
761 service_name, 760 service_name,
762 "PORT", 761 "PORT",
763 &port)) && 762 &port)) &&
764 (port <= 65535) && 763 (port <= 65535) &&
765 (0 != port) && 764 (0 != port) &&
766 (GNUNET_OK == 765 (GNUNET_OK ==
767 GNUNET_CONFIGURATION_get_value_string (cfg, 766 GNUNET_CONFIGURATION_get_value_string(cfg,
768 service_name, 767 service_name,
769 "HOSTNAME", 768 "HOSTNAME",
770 &hostname)) && 769 &hostname)) &&
771 (0 != strlen (hostname)) ) 770 (0 != strlen(hostname)))
772 ret = GNUNET_OK; 771 ret = GNUNET_OK;
773 GNUNET_free_non_null (hostname); 772 GNUNET_free_non_null(hostname);
774 return ret; 773 return ret;
775} 774}
776 775
@@ -781,7 +780,7 @@ test_service_configuration (const char *service_name,
781 * @param cls the `struct ClientState` to try to connect to the service 780 * @param cls the `struct ClientState` to try to connect to the service
782 */ 781 */
783static void 782static void
784start_connect (void *cls) 783start_connect(void *cls)
785{ 784{
786 struct ClientState *cstate = cls; 785 struct ClientState *cstate = cls;
787 786
@@ -789,41 +788,41 @@ start_connect (void *cls)
789#if 0 788#if 0
790 /* Never use a local source if a proxy is configured */ 789 /* Never use a local source if a proxy is configured */
791 if (GNUNET_YES == 790 if (GNUNET_YES ==
792 GNUNET_SOCKS_check_service (cstate->service_name, 791 GNUNET_SOCKS_check_service(cstate->service_name,
793 cstate->cfg)) 792 cstate->cfg))
794 { 793 {
795 socks_connect (cstate); 794 socks_connect(cstate);
796 return; 795 return;
797 } 796 }
798#endif 797#endif
799 798
800 if ( (0 == (cstate->attempts++ % 2)) || 799 if ((0 == (cstate->attempts++ % 2)) ||
801 (0 == cstate->port) || 800 (0 == cstate->port) ||
802 (NULL == cstate->hostname) ) 801 (NULL == cstate->hostname))
803 {
804 /* on even rounds, try UNIX first, or always
805 if we do not have a DNS name and TCP port. */
806 cstate->sock = try_unixpath (cstate->service_name,
807 cstate->cfg);
808 if (NULL != cstate->sock)
809 { 802 {
810 connect_success_continuation (cstate); 803 /* on even rounds, try UNIX first, or always
804 if we do not have a DNS name and TCP port. */
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 }
813 if ((NULL == cstate->hostname) ||
814 (0 == cstate->port))
815 {
816 /* All options failed. Boo! */
817 connect_fail_continuation(cstate);
811 return; 818 return;
812 } 819 }
813 }
814 if ( (NULL == cstate->hostname) ||
815 (0 == cstate->port) )
816 {
817 /* All options failed. Boo! */
818 connect_fail_continuation (cstate);
819 return;
820 }
821 cstate->dns_active 820 cstate->dns_active
822 = GNUNET_RESOLVER_ip_get (cstate->hostname, 821 = GNUNET_RESOLVER_ip_get(cstate->hostname,
823 AF_UNSPEC, 822 AF_UNSPEC,
824 CONNECT_RETRY_TIMEOUT, 823 CONNECT_RETRY_TIMEOUT,
825 &try_connect_using_address, 824 &try_connect_using_address,
826 cstate); 825 cstate);
827} 826}
828 827
829 828
@@ -835,30 +834,30 @@ start_connect (void *cls)
835 * @param impl_state our `struct ClientState` 834 * @param impl_state our `struct ClientState`
836 */ 835 */
837static void 836static void
838connection_client_send_impl (struct GNUNET_MQ_Handle *mq, 837connection_client_send_impl(struct GNUNET_MQ_Handle *mq,
839 const struct GNUNET_MessageHeader *msg, 838 const struct GNUNET_MessageHeader *msg,
840 void *impl_state) 839 void *impl_state)
841{ 840{
842 struct ClientState *cstate = impl_state; 841 struct ClientState *cstate = impl_state;
843 842
844 (void) mq; 843 (void)mq;
845 /* only one message at a time allowed */ 844 /* only one message at a time allowed */
846 GNUNET_assert (NULL == cstate->msg); 845 GNUNET_assert(NULL == cstate->msg);
847 GNUNET_assert (NULL == cstate->send_task); 846 GNUNET_assert(NULL == cstate->send_task);
848 cstate->msg = msg; 847 cstate->msg = msg;
849 cstate->msg_off = 0; 848 cstate->msg_off = 0;
850 if (NULL == cstate->sock) 849 if (NULL == cstate->sock)
851 { 850 {
852 LOG (GNUNET_ERROR_TYPE_DEBUG, 851 LOG(GNUNET_ERROR_TYPE_DEBUG,
853 "message of type %u waiting for socket\n", 852 "message of type %u waiting for socket\n",
854 ntohs(msg->type)); 853 ntohs(msg->type));
855 return; /* still waiting for connection */ 854 return; /* still waiting for connection */
856 } 855 }
857 cstate->send_task 856 cstate->send_task
858 = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 857 = GNUNET_SCHEDULER_add_write_net(GNUNET_TIME_UNIT_FOREVER_REL,
859 cstate->sock, 858 cstate->sock,
860 &transmit_ready, 859 &transmit_ready,
861 cstate); 860 cstate);
862} 861}
863 862
864 863
@@ -869,20 +868,20 @@ connection_client_send_impl (struct GNUNET_MQ_Handle *mq,
869 * @param impl_state our `struct ClientState` 868 * @param impl_state our `struct ClientState`
870 */ 869 */
871static void 870static void
872connection_client_cancel_impl (struct GNUNET_MQ_Handle *mq, 871connection_client_cancel_impl(struct GNUNET_MQ_Handle *mq,
873 void *impl_state) 872 void *impl_state)
874{ 873{
875 struct ClientState *cstate = impl_state; 874 struct ClientState *cstate = impl_state;
876 875
877 (void) mq; 876 (void)mq;
878 GNUNET_assert (NULL != cstate->msg); 877 GNUNET_assert(NULL != cstate->msg);
879 GNUNET_assert (0 == cstate->msg_off); 878 GNUNET_assert(0 == cstate->msg_off);
880 cstate->msg = NULL; 879 cstate->msg = NULL;
881 if (NULL != cstate->send_task) 880 if (NULL != cstate->send_task)
882 { 881 {
883 GNUNET_SCHEDULER_cancel (cstate->send_task); 882 GNUNET_SCHEDULER_cancel(cstate->send_task);
884 cstate->send_task = NULL; 883 cstate->send_task = NULL;
885 } 884 }
886} 885}
887 886
888 887
@@ -898,57 +897,57 @@ connection_client_cancel_impl (struct GNUNET_MQ_Handle *mq,
898 * @return the message queue, NULL on error 897 * @return the message queue, NULL on error
899 */ 898 */
900struct GNUNET_MQ_Handle * 899struct GNUNET_MQ_Handle *
901GNUNET_CLIENT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 900GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg,
902 const char *service_name, 901 const char *service_name,
903 const struct GNUNET_MQ_MessageHandler *handlers, 902 const struct GNUNET_MQ_MessageHandler *handlers,
904 GNUNET_MQ_ErrorHandler error_handler, 903 GNUNET_MQ_ErrorHandler error_handler,
905 void *error_handler_cls) 904 void *error_handler_cls)
906{ 905{
907 struct ClientState *cstate; 906 struct ClientState *cstate;
908 907
909 if (GNUNET_OK != 908 if (GNUNET_OK !=
910 test_service_configuration (service_name, 909 test_service_configuration(service_name,
911 cfg)) 910 cfg))
912 return NULL; 911 return NULL;
913 cstate = GNUNET_new (struct ClientState); 912 cstate = GNUNET_new(struct ClientState);
914 cstate->service_name = GNUNET_strdup (service_name); 913 cstate->service_name = GNUNET_strdup(service_name);
915 cstate->cfg = cfg; 914 cstate->cfg = cfg;
916 cstate->retry_task = GNUNET_SCHEDULER_add_now (&start_connect, 915 cstate->retry_task = GNUNET_SCHEDULER_add_now(&start_connect,
917 cstate); 916 cstate);
918 cstate->mst = GNUNET_MST_create (&recv_message, 917 cstate->mst = GNUNET_MST_create(&recv_message,
919 cstate); 918 cstate);
920 if (GNUNET_YES == 919 if (GNUNET_YES ==
921 GNUNET_CONFIGURATION_have_value (cfg, 920 GNUNET_CONFIGURATION_have_value(cfg,
922 service_name, 921 service_name,
923 "PORT")) 922 "PORT"))
924 {
925 if (! ( (GNUNET_OK !=
926 GNUNET_CONFIGURATION_get_value_number (cfg,
927 service_name,
928 "PORT",
929 &cstate->port)) ||
930 (cstate->port > 65535) ||
931 (GNUNET_OK !=
932 GNUNET_CONFIGURATION_get_value_string (cfg,
933 service_name,
934 "HOSTNAME",
935 &cstate->hostname)) ) &&
936 (0 == strlen (cstate->hostname)) )
937 { 923 {
938 GNUNET_free (cstate->hostname); 924 if (!((GNUNET_OK !=
939 cstate->hostname = NULL; 925 GNUNET_CONFIGURATION_get_value_number(cfg,
940 LOG (GNUNET_ERROR_TYPE_WARNING, 926 service_name,
941 _("Need a non-empty hostname for service `%s'.\n"), 927 "PORT",
942 service_name); 928 &cstate->port)) ||
929 (cstate->port > 65535) ||
930 (GNUNET_OK !=
931 GNUNET_CONFIGURATION_get_value_string(cfg,
932 service_name,
933 "HOSTNAME",
934 &cstate->hostname))) &&
935 (0 == strlen(cstate->hostname)))
936 {
937 GNUNET_free(cstate->hostname);
938 cstate->hostname = NULL;
939 LOG(GNUNET_ERROR_TYPE_WARNING,
940 _("Need a non-empty hostname for service `%s'.\n"),
941 service_name);
942 }
943 } 943 }
944 } 944 cstate->mq = GNUNET_MQ_queue_for_callbacks(&connection_client_send_impl,
945 cstate->mq = GNUNET_MQ_queue_for_callbacks (&connection_client_send_impl, 945 &connection_client_destroy_impl,
946 &connection_client_destroy_impl, 946 &connection_client_cancel_impl,
947 &connection_client_cancel_impl, 947 cstate,
948 cstate, 948 handlers,
949 handlers, 949 error_handler,
950 error_handler, 950 error_handler_cls);
951 error_handler_cls);
952 return cstate->mq; 951 return cstate->mq;
953} 952}
954 953