GNUnet  0.19.4
tcp_connection_legacy.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2013 GNUnet e.V.
4 
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
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
33 #include "platform.h"
34 #include "gnunet_util_lib.h"
36 
37 
44 #define CONNECT_RETRY_TIMEOUT \
45  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
46 
47 
48 #define LOG_STRERROR(kind, syscall) \
49  GNUNET_log_from_strerror (kind, "util-connection", syscall)
50 
51 
56 {
62 
67 
72 
77 
82 
87  size_t notify_size;
88 };
89 
90 
96 {
101 
106 
110  const struct sockaddr *addr;
111 
116 
121 
125  socklen_t addrlen;
126 
131 };
132 
133 
138 {
143 
149 
155 
159  struct sockaddr *addr;
160 
165  char *hostname;
166 
171 
176 
181 
186 
191 
197 
203 
207  socklen_t addrlen;
208 
213 
218 
223 
228 
233 
237  size_t max;
238 
242  uint16_t port;
243 
250  int8_t persist;
251 
258 
263 };
264 
265 
273 void
275 {
276  connection->persist = GNUNET_YES;
277 }
278 
279 
291 int
293 {
294  return GNUNET_NETWORK_socket_disable_corking (connection->sock);
295 }
296 
297 
308 {
309  struct GNUNET_CONNECTION_Handle *connection;
310 
311  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
313  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
314  connection->sock = osSocket;
315  return connection;
316 }
317 
318 
330  void *access_cb_cls,
331  struct GNUNET_NETWORK_Handle *lsock)
332 {
333  struct GNUNET_CONNECTION_Handle *connection;
334  char addr[128];
335  socklen_t addrlen;
336  struct GNUNET_NETWORK_Handle *sock;
337  int aret;
338  struct sockaddr_in *v4;
339  struct sockaddr_in6 *v6;
340  struct sockaddr *sa;
341  void *uaddr;
342 
343 #ifdef SO_PEERCRED
344  struct ucred uc;
345  socklen_t olen;
346 #endif
347  struct GNUNET_CONNECTION_Credentials *gcp;
348 #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
350 
351  gc.uid = 0;
352  gc.gid = 0;
353 #endif
354 
355  addrlen = sizeof(addr);
356  sock =
357  GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen);
358  if (NULL == sock)
359  {
360  if (EAGAIN != errno)
362  return NULL;
363  }
364  if ((addrlen > sizeof(addr)) || (addrlen < sizeof(sa_family_t)))
365  {
366  GNUNET_break (0);
368  return NULL;
369  }
370 
371  sa = (struct sockaddr *) addr;
372  v6 = (struct sockaddr_in6 *) addr;
373  if ((AF_INET6 == sa->sa_family) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)))
374  {
375  /* convert to V4 address */
376  v4 = GNUNET_new (struct sockaddr_in);
377  memset (v4, 0, sizeof(struct sockaddr_in));
378  v4->sin_family = AF_INET;
379 #if HAVE_SOCKADDR_IN_SIN_LEN
380  v4->sin_len = (u_char) sizeof(struct sockaddr_in);
381 #endif
382  GNUNET_memcpy (&v4->sin_addr,
383  &((char *) &v6->sin6_addr)[sizeof(struct in6_addr)
384  - sizeof(struct in_addr)],
385  sizeof(struct in_addr));
386  v4->sin_port = v6->sin6_port;
387  uaddr = v4;
388  addrlen = sizeof(struct sockaddr_in);
389  }
390  else
391  {
392  uaddr = GNUNET_malloc (addrlen);
393  GNUNET_memcpy (uaddr, addr, addrlen);
394  }
395  gcp = NULL;
396  if (AF_UNIX == sa->sa_family)
397  {
398 #if HAVE_GETPEEREID
399  /* most BSDs */
400  if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), &gc.uid, &gc.gid))
401  gcp = &gc;
402 #else
403 #ifdef SO_PEERCRED
404  /* largely traditional GNU/Linux */
405  olen = sizeof(uc);
406  if ((0 == getsockopt (GNUNET_NETWORK_get_fd (sock),
407  SOL_SOCKET,
408  SO_PEERCRED,
409  &uc,
410  &olen)) &&
411  (olen == sizeof(uc)))
412  {
413  gc.uid = uc.uid;
414  gc.gid = uc.gid;
415  gcp = &gc;
416  }
417 #else
418 #if HAVE_GETPEERUCRED
419  /* this is for Solaris 10 */
420  ucred_t *uc;
421 
422  uc = NULL;
423  if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
424  {
425  gc.uid = ucred_geteuid (uc);
426  gc.gid = ucred_getegid (uc);
427  gcp = &gc;
428  }
429  ucred_free (uc);
430 #endif
431 #endif
432 #endif
433  }
434 
435  if ((NULL != access_cb) &&
436  (GNUNET_YES != (aret = access_cb (access_cb_cls, gcp, uaddr, addrlen))))
437  {
438  if (GNUNET_NO == aret)
440  _ ("Access denied to `%s'\n"),
441  GNUNET_a2s (uaddr, addrlen));
443  GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR));
445  GNUNET_free (uaddr);
446  return NULL;
447  }
448  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
450  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
451  connection->addr = uaddr;
452  connection->addrlen = addrlen;
453  connection->sock = sock;
455  _ ("Accepting connection from `%s': %p\n"),
456  GNUNET_a2s (uaddr, addrlen),
457  connection);
458  return connection;
459 }
460 
461 
470 int
472  void **addr,
473  size_t *addrlen)
474 {
475  if ((NULL == connection->addr) || (0 == connection->addrlen))
476  return GNUNET_NO;
477  *addr = GNUNET_malloc (connection->addrlen);
478  GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
479  *addrlen = connection->addrlen;
480  return GNUNET_OK;
481 }
482 
483 
490 static void
491 signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode)
492 {
494 
496  "Receive encounters error (%s), connection closed (%p)\n",
497  strerror (errcode),
498  connection);
499  GNUNET_assert (NULL != (receiver = connection->receiver));
500  connection->receiver = NULL;
501  receiver (connection->receiver_cls,
502  NULL,
503  0,
504  connection->addr,
505  connection->addrlen,
506  errcode);
507 }
508 
509 
515 static void
517 {
519 
521  "Connection signals timeout to receiver (%p)!\n",
522  connection);
523  GNUNET_assert (NULL != (receiver = connection->receiver));
524  connection->receiver = NULL;
525  receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
526 }
527 
528 
535 static void
536 signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection, int ecode)
537 {
539 
541  "Transmission encountered error (%s), connection closed (%p)\n",
542  strerror (ecode),
543  connection);
544  if (NULL != connection->sock)
545  {
546  (void) GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR);
548  connection->sock = NULL;
549  GNUNET_assert (NULL == connection->write_task);
550  }
551  if (NULL != connection->read_task)
552  {
553  /* send errors trigger read errors... */
554  GNUNET_SCHEDULER_cancel (connection->read_task);
555  connection->read_task = NULL;
556  signal_receive_timeout (connection);
557  return;
558  }
559  if (NULL == connection->nth.notify_ready)
560  return; /* nobody to tell about it */
561  notify = connection->nth.notify_ready;
562  connection->nth.notify_ready = NULL;
563  notify (connection->nth.notify_ready_cls, 0, NULL);
564 }
565 
566 
573 static void
575 {
577  "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
578  connection->hostname,
579  connection->port);
580  GNUNET_break (NULL == connection->ap_head);
581  GNUNET_break (NULL == connection->ap_tail);
582  GNUNET_break (GNUNET_NO == connection->dns_active);
583  GNUNET_break (NULL == connection->sock);
584  GNUNET_assert (NULL == connection->write_task);
585  GNUNET_assert (NULL == connection->proxy_handshake);
586 
587  /* signal errors for jobs that used to wait on the connection */
588  connection->destroy_later = 1;
589  if (NULL != connection->receiver)
590  signal_receive_error (connection, ECONNREFUSED);
591  if (NULL != connection->nth.notify_ready)
592  {
593  GNUNET_assert (NULL != connection->nth.timeout_task);
595  connection->nth.timeout_task = NULL;
596  signal_transmit_error (connection, ECONNREFUSED);
597  }
598  if (-1 == connection->destroy_later)
599  {
600  /* do it now */
601  connection->destroy_later = 0;
602  GNUNET_CONNECTION_destroy (connection);
603  return;
604  }
605  connection->destroy_later = 0;
606 }
607 
608 
614 static void
615 transmit_ready (void *cls);
616 
617 
624 static void
625 receive_ready (void *cls);
626 
627 
633 static void
635 {
637  "Connection to `%s' succeeded! (%p)\n",
638  GNUNET_a2s (connection->addr, connection->addrlen),
639  connection);
640  /* trigger jobs that waited for the connection */
641  if (NULL != connection->receiver)
642  {
644  "Connection succeeded, starting with receiving data (%p)\n",
645  connection);
646  GNUNET_assert (NULL == connection->read_task);
647  connection->read_task =
649  connection->receive_timeout),
650  connection->sock,
651  &receive_ready,
652  connection);
653  }
654  if (NULL != connection->nth.notify_ready)
655  {
657  "Connection succeeded, starting with sending data (%p)\n",
658  connection);
659  GNUNET_assert (connection->nth.timeout_task != NULL);
661  connection->nth.timeout_task = NULL;
662  GNUNET_assert (connection->write_task == NULL);
663  connection->write_task =
665  connection->nth.transmit_timeout),
666  connection->sock,
668  connection);
669  }
670 }
671 
672 
679 static void
681 {
682  struct AddressProbe *ap = cls;
683  struct GNUNET_CONNECTION_Handle *connection = ap->connection;
684  const struct GNUNET_SCHEDULER_TaskContext *tc;
685  struct AddressProbe *pos;
686  int error;
687  socklen_t len;
688 
689  GNUNET_assert (NULL != ap->sock);
691  len = sizeof(error);
692  errno = 0;
693  error = 0;
697  SOL_SOCKET,
698  SO_ERROR,
699  &error,
700  &len)) ||
701  (0 != error))
702  {
704  GNUNET_free (ap);
705  if ((NULL == connection->ap_head) &&
707  (NULL == connection->proxy_handshake))
709  return;
710  }
711  GNUNET_assert (NULL == connection->sock);
712  connection->sock = ap->sock;
713  GNUNET_assert (NULL == connection->addr);
716  connection->addrlen = ap->addrlen;
717  GNUNET_free (ap);
718  /* cancel all other attempts */
719  while (NULL != (pos = connection->ap_head))
720  {
724  GNUNET_free (pos);
725  }
727 }
728 
729 
738 static void
740  const struct sockaddr *addr,
741  socklen_t addrlen)
742 {
743  struct GNUNET_CONNECTION_Handle *connection = cls;
744  struct AddressProbe *ap;
746 
747  if (NULL == addr)
748  {
749  connection->dns_active = NULL;
750  if ((NULL == connection->ap_head) && (NULL == connection->sock) &&
751  (NULL == connection->proxy_handshake))
752  connect_fail_continuation (connection);
753  return;
754  }
755  if (NULL != connection->sock)
756  return; /* already connected */
757  GNUNET_assert (NULL == connection->addr);
758  /* try to connect */
760  "Trying to connect using address `%s:%u/%s:%u'\n",
761  connection->hostname,
762  connection->port,
763  GNUNET_a2s (addr, addrlen),
764  connection->port);
765  ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen);
766  ap->addr = (const struct sockaddr *) &ap[1];
767  GNUNET_memcpy (&ap[1], addr, addrlen);
768  ap->addrlen = addrlen;
769  ap->connection = connection;
770 
771  switch (ap->addr->sa_family)
772  {
773  case AF_INET:
774  ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
775  break;
776 
777  case AF_INET6:
778  ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
779  break;
780 
781  default:
782  GNUNET_break (0);
783  GNUNET_free (ap);
784  return; /* not supported by us */
785  }
786  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0);
787  if (NULL == ap->sock)
788  {
789  GNUNET_free (ap);
790  return; /* not supported by OS */
791  }
793  "Trying to connect to `%s' (%p)\n",
794  GNUNET_a2s (ap->addr, ap->addrlen),
795  connection);
796  if ((GNUNET_OK !=
797  GNUNET_NETWORK_socket_connect (ap->sock, ap->addr, ap->addrlen)) &&
798  (EINPROGRESS != errno))
799  {
800  /* maybe refused / unsupported address, try next */
803  GNUNET_free (ap);
804  return;
805  }
806  GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
808  if (NULL != connection->nth.notify_ready)
811  connection->nth.transmit_timeout));
812  if (NULL != connection->receiver)
815  connection->receive_timeout));
817  ap->sock,
819  ap);
820 }
821 
822 
835  const struct GNUNET_CONFIGURATION_Handle *cfg,
836  const char *hostname,
837  uint16_t port)
838 {
839  struct GNUNET_CONNECTION_Handle *connection;
840 
841  GNUNET_assert (0 < strlen (hostname)); /* sanity check */
842  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
843  connection->cfg = cfg;
845  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
846  connection->port = port;
847  connection->hostname = GNUNET_strdup (hostname);
848  connection->dns_active = GNUNET_RESOLVER_ip_get (connection->hostname,
849  AF_UNSPEC,
852  connection);
853  return connection;
854 }
855 
856 
868  const struct GNUNET_CONFIGURATION_Handle *cfg,
869  const char *unixpath)
870 {
871 #ifdef AF_UNIX
872  struct GNUNET_CONNECTION_Handle *connection;
873  struct sockaddr_un *un;
874 
875  GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
876  un = GNUNET_new (struct sockaddr_un);
877  un->sun_family = AF_UNIX;
878  GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
879 #ifdef __linux__
880  {
881  int abstract;
882 
884  "TESTING",
885  "USE_ABSTRACT_SOCKETS");
886  if (GNUNET_YES == abstract)
887  un->sun_path[0] = '\0';
888  }
889 #endif
890 #if HAVE_SOCKADDR_UN_SUN_LEN
891  un->sun_len = (u_char) sizeof(struct sockaddr_un);
892 #endif
893  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
894  connection->cfg = cfg;
896  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
897  connection->port = 0;
898  connection->hostname = NULL;
899  connection->addr = (struct sockaddr *) un;
900  connection->addrlen = sizeof(struct sockaddr_un);
901  connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
902  if (NULL == connection->sock)
903  {
904  GNUNET_free (connection->addr);
905  GNUNET_free (connection->write_buffer);
906  GNUNET_free (connection);
907  return NULL;
908  }
909  if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (connection->sock,
910  connection->addr,
911  connection->addrlen)) &&
912  (EINPROGRESS != errno))
913  {
914  /* Just return; we expect everything to work eventually so don't fail HARD */
916  connection->sock = NULL;
917  return connection;
918  }
919  connect_success_continuation (connection);
920  return connection;
921 #else
922  return NULL;
923 #endif
924 }
925 
926 
939  const struct sockaddr *serv_addr,
940  socklen_t addrlen)
941 {
942  struct GNUNET_CONNECTION_Handle *connection;
943 
944  if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
945  (EINPROGRESS != errno))
946  {
947  /* maybe refused / unsupported address, try next */
950  "Attempt to connect to `%s' failed\n",
951  GNUNET_a2s (serv_addr, addrlen));
953  return NULL;
954  }
956  connection->addr = GNUNET_malloc (addrlen);
957  GNUNET_memcpy (connection->addr, serv_addr, addrlen);
958  connection->addrlen = addrlen;
960  "Trying to connect to `%s' (%p)\n",
961  GNUNET_a2s (serv_addr, addrlen),
962  connection);
963  return connection;
964 }
965 
966 
980  const struct sockaddr *serv_addr,
981  socklen_t addrlen)
982 {
983  struct GNUNET_NETWORK_Handle *s;
984 
985  s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
986  if (NULL == s)
987  {
989  return NULL;
990  }
991  return GNUNET_CONNECTION_connect_socket (s, serv_addr, addrlen);
992 }
993 
994 
1003 int
1005 {
1006  if ((NULL != connection->ap_head) || (NULL != connection->dns_active) ||
1007  (NULL != connection->proxy_handshake))
1008  return GNUNET_YES; /* still trying to connect */
1009  if ((0 != connection->destroy_later) || (NULL == connection->sock))
1010  return GNUNET_NO;
1011  return GNUNET_YES;
1012 }
1013 
1014 
1022 void
1024 {
1025  struct AddressProbe *pos;
1026 
1027  if (0 != connection->destroy_later)
1028  {
1029  connection->destroy_later = -1;
1030  return;
1031  }
1032  LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
1034  GNUNET_assert (NULL == connection->receiver);
1035  if (NULL != connection->write_task)
1036  {
1038  connection->write_task = NULL;
1040  }
1041  if (NULL != connection->read_task)
1042  {
1044  connection->read_task = NULL;
1045  }
1046  if (NULL != connection->nth.timeout_task)
1047  {
1049  connection->nth.timeout_task = NULL;
1050  }
1051  connection->nth.notify_ready = NULL;
1052  if (NULL != connection->dns_active)
1053  {
1055  connection->dns_active = NULL;
1056  }
1057  if (NULL != connection->proxy_handshake)
1058  {
1059  /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
1061  connection->proxy_handshake = NULL; /* Not leaked ??? */
1062  }
1063  while (NULL != (pos = connection->ap_head))
1064  {
1068  GNUNET_free (pos);
1069  }
1070  if ((NULL != connection->sock) && (GNUNET_YES != connection->persist))
1071  {
1072  if ((GNUNET_OK !=
1074  (ENOTCONN != errno) && (ECONNRESET != errno))
1076  }
1077  if (NULL != connection->sock)
1078  {
1079  if (GNUNET_YES != connection->persist)
1080  {
1083  }
1084  else
1085  {
1087  connection->sock); /* at least no memory leak (we deliberately
1088  * leak the socket in this special case) ... */
1089  }
1090  }
1095 }
1096 
1097 
1104 static void
1105 receive_ready (void *cls)
1106 {
1107  struct GNUNET_CONNECTION_Handle *connection = cls;
1108  const struct GNUNET_SCHEDULER_TaskContext *tc;
1109  char buffer[connection->max];
1110  ssize_t ret;
1112 
1113  connection->read_task = NULL;
1116  {
1118  "Receive from `%s' encounters error: timeout (%s, %p)\n",
1119  GNUNET_a2s (connection->addr, connection->addrlen),
1122  connection->receive_timeout),
1123  GNUNET_YES),
1124  connection);
1125  signal_receive_timeout (connection);
1126  return;
1127  }
1128  if (NULL == connection->sock)
1129  {
1130  /* connect failed for good */
1131  signal_receive_error (connection, ECONNREFUSED);
1132  return;
1133  }
1135 RETRY:
1136  ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max);
1137  if (-1 == ret)
1138  {
1139  if (EINTR == errno)
1140  goto RETRY;
1141  signal_receive_error (connection, errno);
1142  return;
1143  }
1145  "receive_ready read %lu/%lu bytes from `%s' (%p)!\n",
1146  (unsigned long) ret,
1147  (unsigned long) connection->max,
1148  GNUNET_a2s (connection->addr, connection->addrlen),
1149  connection);
1150  GNUNET_assert (NULL != (receiver = connection->receiver));
1151  connection->receiver = NULL;
1152  receiver (connection->receiver_cls,
1153  buffer,
1154  ret,
1155  connection->addr,
1156  connection->addrlen,
1157  0);
1158 }
1159 
1160 
1176 int
1178  size_t max,
1181  void *receiver_cls)
1182 {
1183  GNUNET_assert ((NULL == connection->read_task) &&
1184  (NULL == connection->receiver));
1185  GNUNET_assert (NULL != receiver);
1186  connection->receiver = receiver;
1187  connection->receiver_cls = receiver_cls;
1189  connection->max = max;
1190  if (NULL != connection->sock)
1191  {
1192  connection->read_task =
1194  connection->receive_timeout),
1195  connection->sock,
1196  &receive_ready,
1197  connection);
1198  return GNUNET_OK;
1199  }
1200  if ((NULL == connection->dns_active) && (NULL == connection->ap_head) &&
1201  (NULL == connection->proxy_handshake))
1202  {
1203  connection->receiver = NULL;
1204  receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT);
1205  return GNUNET_SYSERR;
1206  }
1207  return GNUNET_OK;
1208 }
1209 
1210 
1219 void *
1221 {
1222  if (NULL != connection->read_task)
1223  {
1224  GNUNET_assert (connection ==
1225  GNUNET_SCHEDULER_cancel (connection->read_task));
1226  connection->read_task = NULL;
1227  }
1228  connection->receiver = NULL;
1229  return connection->receiver_cls;
1230 }
1231 
1232 
1240 static int
1242 {
1243  size_t used;
1244  size_t avail;
1245  size_t size;
1247 
1248  LOG (GNUNET_ERROR_TYPE_DEBUG, "process_notify is running\n");
1249  GNUNET_assert (NULL == connection->write_task);
1250  if (NULL == (notify = connection->nth.notify_ready))
1251  {
1252  LOG (GNUNET_ERROR_TYPE_DEBUG, "No one to notify\n");
1253  return GNUNET_NO;
1254  }
1255  used = connection->write_buffer_off - connection->write_buffer_pos;
1256  avail = connection->write_buffer_size - used;
1257  size = connection->nth.notify_size;
1258  if (size > avail)
1259  {
1260  LOG (GNUNET_ERROR_TYPE_DEBUG, "Not enough buffer\n");
1261  return GNUNET_NO;
1262  }
1263  connection->nth.notify_ready = NULL;
1264  if (connection->write_buffer_size - connection->write_buffer_off < size)
1265  {
1266  /* need to compact */
1267  memmove (connection->write_buffer,
1268  &connection->write_buffer[connection->write_buffer_pos],
1269  used);
1270  connection->write_buffer_off -= connection->write_buffer_pos;
1271  connection->write_buffer_pos = 0;
1272  }
1273  avail = connection->write_buffer_size - connection->write_buffer_off;
1274  GNUNET_assert (avail >= size);
1275  size = notify (connection->nth.notify_ready_cls,
1276  avail,
1277  &connection->write_buffer[connection->write_buffer_off]);
1278  GNUNET_assert (size <= avail);
1279  if (0 != size)
1280  connection->write_buffer_off += size;
1281  return GNUNET_YES;
1282 }
1283 
1284 
1295 static void
1296 transmit_timeout (void *cls)
1297 {
1298  struct GNUNET_CONNECTION_Handle *connection = cls;
1300 
1301  connection->nth.timeout_task = NULL;
1303  "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
1304  connection->hostname,
1305  connection->port,
1306  GNUNET_a2s (connection->addr, connection->addrlen),
1307  connection);
1308  notify = connection->nth.notify_ready;
1309  GNUNET_assert (NULL != notify);
1310  connection->nth.notify_ready = NULL;
1311  notify (connection->nth.notify_ready_cls, 0, NULL);
1312 }
1313 
1314 
1323 static void
1324 connect_error (void *cls)
1325 {
1326  struct GNUNET_CONNECTION_Handle *connection = cls;
1328 
1330  "Transmission request of size %lu fails (%s/%u), connection failed (%p).\n",
1331  (unsigned long) connection->nth.notify_size,
1332  connection->hostname,
1333  connection->port,
1334  connection);
1335  connection->write_task = NULL;
1336  notify = connection->nth.notify_ready;
1337  connection->nth.notify_ready = NULL;
1338  notify (connection->nth.notify_ready_cls, 0, NULL);
1339 }
1340 
1341 
1347 static void
1348 transmit_ready (void *cls)
1349 {
1350  struct GNUNET_CONNECTION_Handle *connection = cls;
1352  const struct GNUNET_SCHEDULER_TaskContext *tc;
1353  ssize_t ret;
1354  size_t have;
1355 
1356  LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", connection);
1357  GNUNET_assert (NULL != connection->write_task);
1358  connection->write_task = NULL;
1359  GNUNET_assert (NULL == connection->nth.timeout_task);
1362  {
1364  "Transmit to `%s' fails, time out reached (%p).\n",
1365  GNUNET_a2s (connection->addr, connection->addrlen),
1366  connection);
1367  notify = connection->nth.notify_ready;
1368  GNUNET_assert (NULL != notify);
1369  connection->nth.notify_ready = NULL;
1370  notify (connection->nth.notify_ready_cls, 0, NULL);
1371  return;
1372  }
1373  GNUNET_assert (NULL != connection->sock);
1374  if (NULL == tc->write_ready)
1375  {
1376  /* special circumstances (in particular, PREREQ_DONE after
1377  * connect): not yet ready to write, but no "fatal" error either.
1378  * Hence retry. */
1379  goto SCHEDULE_WRITE;
1380  }
1381  if (! GNUNET_NETWORK_fdset_isset (tc->write_ready, connection->sock))
1382  {
1383  GNUNET_assert (NULL == connection->write_task);
1384  /* special circumstances (in particular, shutdown): not yet ready
1385  * to write, but no "fatal" error either. Hence retry. */
1386  goto SCHEDULE_WRITE;
1387  }
1388  GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
1389  if ((NULL != connection->nth.notify_ready) &&
1390  (connection->write_buffer_size < connection->nth.notify_size))
1391  {
1392  connection->write_buffer =
1393  GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
1394  connection->write_buffer_size = connection->nth.notify_size;
1395  }
1396  process_notify (connection);
1397  have = connection->write_buffer_off - connection->write_buffer_pos;
1398  if (0 == have)
1399  {
1400  /* no data ready for writing, terminate write loop */
1401  return;
1402  }
1403  GNUNET_assert (have <= connection->write_buffer_size);
1404  GNUNET_assert (have + connection->write_buffer_pos <=
1405  connection->write_buffer_size);
1406  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1407 RETRY:
1408  ret =
1409  GNUNET_NETWORK_socket_send (connection->sock,
1410  &connection
1411  ->write_buffer[connection->write_buffer_pos],
1412  have);
1413  if (-1 == ret)
1414  {
1415  if (EINTR == errno)
1416  goto RETRY;
1417  if (NULL != connection->write_task)
1418  {
1419  GNUNET_SCHEDULER_cancel (connection->write_task);
1420  connection->write_task = NULL;
1421  }
1422  signal_transmit_error (connection, errno);
1423  return;
1424  }
1426  "Connection transmitted %lu/%lu bytes to `%s' (%p)\n",
1427  (unsigned long) ret,
1428  (unsigned long) have,
1429  GNUNET_a2s (connection->addr, connection->addrlen),
1430  connection);
1431  connection->write_buffer_pos += ret;
1432  if (connection->write_buffer_pos == connection->write_buffer_off)
1433  {
1434  /* transmitted all pending data */
1435  connection->write_buffer_pos = 0;
1436  connection->write_buffer_off = 0;
1437  }
1438  if ((0 == connection->write_buffer_off) &&
1439  (NULL == connection->nth.notify_ready))
1440  return; /* all data sent! */
1441  /* not done writing, schedule more */
1442 SCHEDULE_WRITE:
1444  "Re-scheduling transmit_ready (more to do) (%p).\n",
1445  connection);
1446  have = connection->write_buffer_off - connection->write_buffer_pos;
1447  GNUNET_assert ((NULL != connection->nth.notify_ready) || (have > 0));
1448  if (NULL == connection->write_task)
1449  connection->write_task =
1450  GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready == NULL)
1453  connection->nth.transmit_timeout),
1454  connection->sock,
1455  &transmit_ready,
1456  connection);
1457 }
1458 
1459 
1477  size_t size,
1480  void *notify_cls)
1481 {
1482  if (NULL != connection->nth.notify_ready)
1483  {
1484  GNUNET_assert (0);
1485  return NULL;
1486  }
1487  GNUNET_assert (NULL != notify);
1493  connection->nth.notify_ready_cls = notify_cls;
1498  if ((NULL == connection->sock) && (NULL == connection->ap_head) &&
1499  (NULL == connection->dns_active) && (NULL == connection->proxy_handshake))
1500  {
1501  if (NULL != connection->write_task)
1505  return &connection->nth;
1506  }
1507  if (NULL != connection->write_task)
1508  return &connection->nth; /* previous transmission still in progress */
1509  if (NULL != connection->sock)
1510  {
1511  /* connected, try to transmit now */
1513  "Scheduling transmission (%p).\n",
1514  connection);
1518  connection->sock,
1519  &transmit_ready,
1520  connection);
1521  return &connection->nth;
1522  }
1523  /* not yet connected, wait for connection */
1525  "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
1526  connection);
1529  return &connection->nth;
1530 }
1531 
1532 
1538 void
1541 {
1542  GNUNET_assert (NULL != th->notify_ready);
1543  th->notify_ready = NULL;
1544  if (NULL != th->timeout_task)
1545  {
1547  th->timeout_task = NULL;
1548  }
1549  if (NULL != th->connection->write_task)
1550  {
1552  th->connection->write_task = NULL;
1553  }
1554 }
1555 
1556 
1563 struct GNUNET_CONNECTION_Handle *
1565  struct GNUNET_CONNECTION_Handle *cph)
1566 {
1567  struct GNUNET_CONNECTION_Handle *proxied =
1569 
1570  proxied->proxy_handshake = cph;
1571  return proxied;
1572 }
1573 
1574 
1582 void
1584 {
1585  struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
1586 
1587  GNUNET_assert (NULL != cph);
1588  GNUNET_assert (NULL == proxied->sock);
1589  GNUNET_assert (NULL != cph->sock);
1590  proxied->sock = cph->sock;
1591  cph->sock = NULL;
1593  connect_success_continuation (proxied);
1594 }
1595 
1596 
1597 /* end of connection.c */
#define LOG(kind,...)
Definition: abd_api.c:38
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_PEERINFO_NotifyContext * notify
Handle to the peerinfo notify service (NULL until we've connected to it).
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static char * hostname
Our hostname; we give this to all the peers we start.
static struct GNUNET_FS_UnindexContext * uc
Functions related to doing DNS lookups.
#define GNUNET_MIN_MESSAGE_SIZE
Smallest supported message.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_getsockopt(const struct GNUNET_NETWORK_Handle *desc, int level, int optname, void *optval, socklen_t *optlen)
Get socket options.
Definition: network.c:626
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1000
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition: network.c:716
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition: network.c:601
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition: network.c:392
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
void GNUNET_NETWORK_socket_free_memory_only_(struct GNUNET_NETWORK_Handle *desc)
Only free memory of a socket, keep the file descriptor untouched.
Definition: network.c:565
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:737
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_shutdown(struct GNUNET_NETWORK_Handle *desc, int how)
Shut down socket operations.
Definition: network.c:860
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition: network.c:949
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_disable_corking(struct GNUNET_NETWORK_Handle *desc)
Disable the "CORK" feature for communication with the given socket, forcing the OS to immediately flu...
Definition: network.c:881
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
Definition: resolver_api.c:940
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1577
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1506
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:752
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
@ GNUNET_SCHEDULER_REASON_TIMEOUT
The specified timeout has expired.
@ GNUNET_SCHEDULER_REASON_WRITE_READY
The writing socket is ready.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Definition: strings.c:138
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:343
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:436
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:569
#define max(x, y)
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
size_t(* GNUNET_CONNECTION_TransmitReadyNotify)(void *cls, size_t size, void *buf)
Function called to notify a client about the connection begin ready to queue more data.
void(* GNUNET_CONNECTION_Receiver)(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback function for data received from the network.
int(* GNUNET_CONNECTION_AccessCheck)(void *cls, const struct GNUNET_CONNECTION_Credentials *ucred, const struct sockaddr *addr, socklen_t addrlen)
Function to call for access control checks.
#define RETRY
Return code we give on 'send' if we failed to send right now but it makes sense to retry later.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition: socks.c:330
During connect, we try multiple possible IP addresses to find out which one might work.
socklen_t addrlen
Length of addr.
struct AddressProbe * prev
This is a doubly-linked list.
struct GNUNET_CONNECTION_Handle * connection
Connection for which we are probing.
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
struct GNUNET_NETWORK_Handle * sock
Underlying OS's socket.
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).
struct AddressProbe * next
This is a linked list.
Credentials for UNIX domain sockets.
uid_t uid
UID of the other end of the connection.
gid_t gid
GID of the other end of the connection.
handle for a network connection
int8_t persist
When shutdown, do not ever actually close the socket, but free resources.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
size_t write_buffer_pos
Current read-offset in write_buffer (how many bytes have already been sent).
char * hostname
Pointer to the hostname if connection was created using DNS lookup, otherwise NULL.
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request.
size_t max
Maximum number of bytes to read (for receiving).
struct sockaddr * addr
Network address of the other end-point, may be NULL.
socklen_t addrlen
Length of addr.
GNUNET_CONNECTION_Receiver receiver
Function to call on data received, NULL if no receive is pending.
uint16_t port
Port to connect to.
size_t write_buffer_off
Current write-offset in write_buffer (where would we write next).
char * write_buffer
Pointer to our write buffer.
struct AddressProbe * ap_head
Linked list of sockets we are currently trying out (during connect).
struct GNUNET_CONNECTION_TransmitHandle nth
The handle we return for GNUNET_CONNECTION_notify_transmit_ready().
size_t write_buffer_size
Current size of our write_buffer.
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
struct GNUNET_SCHEDULER_Task * read_task
Read task that we may need to wait for.
struct GNUNET_NETWORK_Handle * sock
Underlying OS's socket, set to NULL after fatal errors.
void * receiver_cls
Closure for receiver.
struct GNUNET_CONNECTION_Handle * proxy_handshake
Handle to subsequent connection after proxy handshake completes,.
struct GNUNET_SCHEDULER_Task * write_task
Write task that we may need to wait for.
struct GNUNET_TIME_Absolute receive_timeout
Timeout for receiving (in absolute time).
struct GNUNET_CONNECTION_Handle * connection
Our connection handle.
struct GNUNET_SCHEDULER_Task * timeout_task
Task called on timeout.
size_t notify_size
At what number of bytes available in the write buffer should the notify method be called?
struct GNUNET_TIME_Absolute transmit_timeout
Timeout for receiving (in absolute time).
GNUNET_CONNECTION_TransmitReadyNotify notify_ready
Function to call if the send buffer has notify_size bytes available.
void * notify_ready_cls
Closure for notify_ready.
handle to a socket
Definition: network.c:53
socklen_t addrlen
Number of bytes in addr.
Definition: network.c:69
Handle to a request given to the resolver.
Definition: resolver_api.c:104
Context information passed to each scheduler task.
const struct GNUNET_NETWORK_FDSet * read_ready
Set of file descriptors ready for reading; note that additional bits may be set that were not in the ...
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
const struct GNUNET_NETWORK_FDSet * write_ready
Set of file descriptors ready for writing; note that additional bits may be set that were not in the ...
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
static void try_connect_using_address(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Try to establish a connection given the specified address.
static void signal_receive_timeout(struct GNUNET_CONNECTION_Handle *connection)
Tell the receiver callback that a timeout was reached.
void * GNUNET_CONNECTION_receive_cancel(struct GNUNET_CONNECTION_Handle *connection)
Cancel receive job on the given connection.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_connect_to_unixpath(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *unixpath)
Create a connection handle by connecting to a UNIX domain service.
static void transmit_timeout(void *cls)
Task invoked by the scheduler when a call to transmit is timing out (we never got enough buffer space...
struct GNUNET_CONNECTION_TransmitHandle * GNUNET_CONNECTION_notify_transmit_ready(struct GNUNET_CONNECTION_Handle *connection, size_t size, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls)
Ask the connection to call us once the specified number of bytes are free in the transmission buffer.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_connect_socket(struct GNUNET_NETWORK_Handle *s, const struct sockaddr *serv_addr, socklen_t addrlen)
Create a connection handle by (asynchronously) connecting to a host.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_proxied_from_handshake(struct GNUNET_CONNECTION_Handle *cph)
Create a connection to be proxied using a given connection.
int GNUNET_CONNECTION_disable_corking(struct GNUNET_CONNECTION_Handle *connection)
Disable the "CORK" feature for communication with the given connection, forcing the OS to immediately...
static void transmit_ready(void *cls)
We are ready to transmit (or got a timeout).
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_existing(struct GNUNET_NETWORK_Handle *osSocket)
Create a connection handle by boxing an existing OS socket.
static void connect_probe_continuation(void *cls)
Scheduler let us know that we're either ready to write on the socket OR connect timed out.
static void connect_success_continuation(struct GNUNET_CONNECTION_Handle *connection)
We've succeeded in establishing a connection.
static int process_notify(struct GNUNET_CONNECTION_Handle *connection)
Try to call the transmit notify method (check if we do have enough space available first)!
int GNUNET_CONNECTION_get_address(struct GNUNET_CONNECTION_Handle *connection, void **addr, size_t *addrlen)
Obtain the network address of the other party.
int GNUNET_CONNECTION_check(struct GNUNET_CONNECTION_Handle *connection)
Check if connection is valid (no fatal errors have happened so far).
int GNUNET_CONNECTION_receive(struct GNUNET_CONNECTION_Handle *connection, size_t max, struct GNUNET_TIME_Relative timeout, GNUNET_CONNECTION_Receiver receiver, void *receiver_cls)
Receive data from the given connection.
static void receive_ready(void *cls)
This function is called once we either timeout or have data ready to read.
void GNUNET_CONNECTION_destroy(struct GNUNET_CONNECTION_Handle *connection)
Close the connection and free associated resources.
void GNUNET_CONNECTION_acivate_proxied(struct GNUNET_CONNECTION_Handle *proxied)
Activate proxied connection and destroy initial proxy handshake connection.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_accept(GNUNET_CONNECTION_AccessCheck access_cb, void *access_cb_cls, struct GNUNET_NETWORK_Handle *lsock)
Create a connection handle by accepting on a listen socket.
static void connect_error(void *cls)
Task invoked by the scheduler when we failed to connect at the time of being asked to transmit.
void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *connection)
Set the persist option on this connection handle.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_sockaddr(int af_family, const struct sockaddr *serv_addr, socklen_t addrlen)
Create a connection handle by creating a socket and (asynchronously) connecting to a host.
#define LOG_STRERROR(kind, syscall)
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *hostname, uint16_t port)
Create a connection handle by (asynchronously) connecting to a host.
static void signal_receive_error(struct GNUNET_CONNECTION_Handle *connection, int errcode)
Tell the receiver callback that we had an IO error.
void GNUNET_CONNECTION_notify_transmit_ready_cancel(struct GNUNET_CONNECTION_TransmitHandle *th)
Cancel the specified transmission-ready notification.
#define CONNECT_RETRY_TIMEOUT
Timeout we use on TCP connect before trying another result from the DNS resolver.
static void connect_fail_continuation(struct GNUNET_CONNECTION_Handle *connection)
We've failed for good to establish a connection (timeout or no more addresses to try).
static void signal_transmit_error(struct GNUNET_CONNECTION_Handle *connection, int ecode)
We failed to transmit data to the service, signal the error.