GNUnet  0.10.x
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 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
45 
46 
47 
48 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall)
49 
50 
55 {
56 
62 
67 
72 
77 
82 
87  size_t notify_size;
88 
89 };
90 
91 
97 {
98 
103 
108 
112  const struct sockaddr *addr;
113 
118 
123 
127  socklen_t addrlen;
128 
133 };
134 
135 
140 {
141 
146 
152 
158 
162  struct sockaddr *addr;
163 
168  char *hostname;
169 
174 
179 
184 
189 
194 
200 
206 
210  socklen_t addrlen;
211 
216 
221 
226 
231 
235  struct GNUNET_TIME_Absolute receive_timeout;
236 
240  size_t max;
241 
245  uint16_t port;
246 
253  int8_t persist;
254 
261 
266 
267 };
268 
269 
277 void
279 {
280  connection->persist = GNUNET_YES;
281 }
282 
283 
295 int
297 {
298  return GNUNET_NETWORK_socket_disable_corking (connection->sock);
299 }
300 
301 
312 {
314 
315  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
317  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
318  connection->sock = osSocket;
319  return connection;
320 }
321 
322 
334  void *access_cb_cls,
335  struct GNUNET_NETWORK_Handle *lsock)
336 {
338  char addr[128];
339  socklen_t addrlen;
340  struct GNUNET_NETWORK_Handle *sock;
341  int aret;
342  struct sockaddr_in *v4;
343  struct sockaddr_in6 *v6;
344  struct sockaddr *sa;
345  void *uaddr;
346 #ifdef SO_PEERCRED
347  struct ucred uc;
348  socklen_t olen;
349 #endif
350  struct GNUNET_CONNECTION_Credentials *gcp;
351 #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
353 
354  gc.uid = 0;
355  gc.gid = 0;
356 #endif
357 
358  addrlen = sizeof (addr);
359  sock =
361  (struct sockaddr *) &addr,
362  &addrlen);
363  if (NULL == sock)
364  {
365  if (EAGAIN != errno)
367  return NULL;
368  }
369  if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t)))
370  {
371  GNUNET_break (0);
373  return NULL;
374  }
375 
376  sa = (struct sockaddr *) addr;
377  v6 = (struct sockaddr_in6 *) addr;
378  if ( (AF_INET6 == sa->sa_family) &&
379  (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)) )
380  {
381  /* convert to V4 address */
382  v4 = GNUNET_new (struct sockaddr_in);
383  memset (v4, 0, sizeof (struct sockaddr_in));
384  v4->sin_family = AF_INET;
385 #if HAVE_SOCKADDR_IN_SIN_LEN
386  v4->sin_len = (u_char) sizeof (struct sockaddr_in);
387 #endif
388  GNUNET_memcpy (&v4->sin_addr,
389  &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
390  sizeof (struct in_addr)],
391  sizeof (struct in_addr));
392  v4->sin_port = v6->sin6_port;
393  uaddr = v4;
394  addrlen = sizeof (struct sockaddr_in);
395  }
396  else
397  {
398  uaddr = GNUNET_malloc (addrlen);
399  GNUNET_memcpy (uaddr, addr, addrlen);
400  }
401  gcp = NULL;
402  if (AF_UNIX == sa->sa_family)
403  {
404 #if HAVE_GETPEEREID
405  /* most BSDs */
406  if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock),
407  &gc.uid,
408  &gc.gid))
409  gcp = &gc;
410 #else
411 #ifdef SO_PEERCRED
412  /* largely traditional GNU/Linux */
413  olen = sizeof (uc);
414  if ( (0 ==
415  getsockopt (GNUNET_NETWORK_get_fd (sock),
416  SOL_SOCKET,
417  SO_PEERCRED,
418  &uc,
419  &olen)) &&
420  (olen == sizeof (uc)) )
421  {
422  gc.uid = uc.uid;
423  gc.gid = uc.gid;
424  gcp = &gc;
425  }
426 #else
427 #if HAVE_GETPEERUCRED
428  /* this is for Solaris 10 */
429  ucred_t *uc;
430 
431  uc = NULL;
432  if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
433  {
434  gc.uid = ucred_geteuid (uc);
435  gc.gid = ucred_getegid (uc);
436  gcp = &gc;
437  }
438  ucred_free (uc);
439 #endif
440 #endif
441 #endif
442  }
443 
444  if ( (NULL != access_cb) &&
445  (GNUNET_YES != (aret = access_cb (access_cb_cls,
446  gcp,
447  uaddr,
448  addrlen))) )
449  {
450  if (GNUNET_NO == aret)
452  _("Access denied to `%s'\n"),
453  GNUNET_a2s (uaddr,
454  addrlen));
457  SHUT_RDWR));
459  GNUNET_free (uaddr);
460  return NULL;
461  }
462  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
464  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
465  connection->addr = uaddr;
466  connection->addrlen = addrlen;
467  connection->sock = sock;
469  _("Accepting connection from `%s': %p\n"),
470  GNUNET_a2s (uaddr,
471  addrlen),
472  connection);
473  return connection;
474 }
475 
476 
485 int
487  void **addr,
488  size_t *addrlen)
489 {
490  if ((NULL == connection->addr) || (0 == connection->addrlen))
491  return GNUNET_NO;
492  *addr = GNUNET_malloc (connection->addrlen);
493  GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
494  *addrlen = connection->addrlen;
495  return GNUNET_OK;
496 }
497 
498 
505 static void
507  int errcode)
508 {
510 
512  "Receive encounters error (%s), connection closed (%p)\n",
513  STRERROR (errcode),
514  connection);
515  GNUNET_assert (NULL != (receiver = connection->receiver));
516  connection->receiver = NULL;
517  receiver (connection->receiver_cls,
518  NULL,
519  0,
520  connection->addr,
521  connection->addrlen,
522  errcode);
523 }
524 
525 
531 static void
533 {
535 
537  "Connection signals timeout to receiver (%p)!\n",
538  connection);
539  GNUNET_assert (NULL != (receiver = connection->receiver));
540  connection->receiver = NULL;
541  receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
542 }
543 
544 
551 static void
553  int ecode)
554 {
556 
558  "Transmission encounterd error (%s), connection closed (%p)\n",
559  STRERROR (ecode),
560  connection);
561  if (NULL != connection->sock)
562  {
563  (void) GNUNET_NETWORK_socket_shutdown (connection->sock,
564  SHUT_RDWR);
566  GNUNET_NETWORK_socket_close (connection->sock));
567  connection->sock = NULL;
568  GNUNET_assert (NULL == connection->write_task);
569  }
570  if (NULL != connection->read_task)
571  {
572  /* send errors trigger read errors... */
573  GNUNET_SCHEDULER_cancel (connection->read_task);
574  connection->read_task = NULL;
575  signal_receive_timeout (connection);
576  return;
577  }
578  if (NULL == connection->nth.notify_ready)
579  return; /* nobody to tell about it */
580  notify = connection->nth.notify_ready;
581  connection->nth.notify_ready = NULL;
582  notify (connection->nth.notify_ready_cls,
583  0,
584  NULL);
585 }
586 
587 
594 static void
596 {
598  "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
599  connection->hostname,
600  connection->port);
601  GNUNET_break (NULL == connection->ap_head);
602  GNUNET_break (NULL == connection->ap_tail);
603  GNUNET_break (GNUNET_NO == connection->dns_active);
604  GNUNET_break (NULL == connection->sock);
605  GNUNET_assert (NULL == connection->write_task);
606  GNUNET_assert (NULL == connection->proxy_handshake);
607 
608  /* signal errors for jobs that used to wait on the connection */
609  connection->destroy_later = 1;
610  if (NULL != connection->receiver)
611  signal_receive_error (connection,
612  ECONNREFUSED);
613  if (NULL != connection->nth.notify_ready)
614  {
615  GNUNET_assert (NULL != connection->nth.timeout_task);
617  connection->nth.timeout_task = NULL;
618  signal_transmit_error (connection,
619  ECONNREFUSED);
620  }
621  if (-1 == connection->destroy_later)
622  {
623  /* do it now */
624  connection->destroy_later = 0;
625  GNUNET_CONNECTION_destroy (connection);
626  return;
627  }
628  connection->destroy_later = 0;
629 }
630 
631 
637 static void
638 transmit_ready (void *cls);
639 
640 
647 static void
648 receive_ready (void *cls);
649 
650 
656 static void
658 {
660  "Connection to `%s' succeeded! (%p)\n",
661  GNUNET_a2s (connection->addr,
662  connection->addrlen),
663  connection);
664  /* trigger jobs that waited for the connection */
665  if (NULL != connection->receiver)
666  {
668  "Connection succeeded, starting with receiving data (%p)\n",
669  connection);
670  GNUNET_assert (NULL == connection->read_task);
671  connection->read_task =
673  (connection->receive_timeout),
674  connection->sock,
675  &receive_ready, connection);
676  }
677  if (NULL != connection->nth.notify_ready)
678  {
680  "Connection succeeded, starting with sending data (%p)\n",
681  connection);
682  GNUNET_assert (connection->nth.timeout_task != NULL);
684  connection->nth.timeout_task = NULL;
685  GNUNET_assert (connection->write_task == NULL);
686  connection->write_task =
688  (connection->nth.transmit_timeout), connection->sock,
689  &transmit_ready, connection);
690  }
691 }
692 
693 
700 static void
702 {
703  struct AddressProbe *ap = cls;
705  const struct GNUNET_SCHEDULER_TaskContext *tc;
706  struct AddressProbe *pos;
707  int error;
708  socklen_t len;
709 
710  GNUNET_assert (NULL != ap->sock);
712  connection->ap_tail,
713  ap);
714  len = sizeof (error);
715  errno = 0;
716  error = 0;
718  if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
719  (GNUNET_OK !=
721  SOL_SOCKET,
722  SO_ERROR,
723  &error,
724  &len)) ||
725  (0 != error) )
726  {
729  GNUNET_free (ap);
730  if ( (NULL == connection->ap_head) &&
731  (GNUNET_NO == connection->dns_active) &&
732  (NULL == connection->proxy_handshake) )
733  connect_fail_continuation (connection);
734  return;
735  }
736  GNUNET_assert (NULL == connection->sock);
737  connection->sock = ap->sock;
738  GNUNET_assert (NULL == connection->addr);
739  connection->addr = GNUNET_malloc (ap->addrlen);
740  GNUNET_memcpy (connection->addr, ap->addr, ap->addrlen);
741  connection->addrlen = ap->addrlen;
742  GNUNET_free (ap);
743  /* cancel all other attempts */
744  while (NULL != (pos = connection->ap_head))
745  {
749  connection->ap_tail,
750  pos);
751  GNUNET_free (pos);
752  }
753  connect_success_continuation (connection);
754 }
755 
756 
765 static void
767  const struct sockaddr *addr,
768  socklen_t addrlen)
769 {
770  struct GNUNET_CONNECTION_Handle *connection = cls;
771  struct AddressProbe *ap;
772  struct GNUNET_TIME_Relative delay;
773 
774  if (NULL == addr)
775  {
776  connection->dns_active = NULL;
777  if ((NULL == connection->ap_head) &&
778  (NULL == connection->sock) &&
779  (NULL == connection->proxy_handshake))
780  connect_fail_continuation (connection);
781  return;
782  }
783  if (NULL != connection->sock)
784  return; /* already connected */
785  GNUNET_assert (NULL == connection->addr);
786  /* try to connect */
788  "Trying to connect using address `%s:%u/%s:%u'\n",
789  connection->hostname,
790  connection->port,
791  GNUNET_a2s (addr, addrlen),
792  connection->port);
793  ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
794  ap->addr = (const struct sockaddr *) &ap[1];
795  GNUNET_memcpy (&ap[1], addr, addrlen);
796  ap->addrlen = addrlen;
797  ap->connection = connection;
798 
799  switch (ap->addr->sa_family)
800  {
801  case AF_INET:
802  ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
803  break;
804  case AF_INET6:
805  ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
806  break;
807  default:
808  GNUNET_break (0);
809  GNUNET_free (ap);
810  return; /* not supported by us */
811  }
812  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
813  SOCK_STREAM, 0);
814  if (NULL == ap->sock)
815  {
816  GNUNET_free (ap);
817  return; /* not supported by OS */
818  }
820  "Trying to connect to `%s' (%p)\n",
821  GNUNET_a2s (ap->addr, ap->addrlen),
822  connection);
823  if ((GNUNET_OK !=
825  ap->addr,
826  ap->addrlen)) &&
827  (EINPROGRESS != errno))
828  {
829  /* maybe refused / unsupported address, try next */
832  GNUNET_free (ap);
833  return;
834  }
835  GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
836  delay = CONNECT_RETRY_TIMEOUT;
837  if (NULL != connection->nth.notify_ready)
838  delay = GNUNET_TIME_relative_min (delay,
840  if (NULL != connection->receiver)
841  delay = GNUNET_TIME_relative_min (delay,
844  ap->sock,
846  ap);
847 }
848 
849 
862  const char *hostname,
863  uint16_t port)
864 {
866 
867  GNUNET_assert (0 < strlen (hostname)); /* sanity check */
868  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
869  connection->cfg = cfg;
871  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
872  connection->port = port;
873  connection->hostname = GNUNET_strdup (hostname);
874  connection->dns_active =
875  GNUNET_RESOLVER_ip_get (connection->hostname,
876  AF_UNSPEC,
879  connection);
880  return connection;
881 }
882 
883 
895  const char *unixpath)
896 {
897 #ifdef AF_UNIX
899  struct sockaddr_un *un;
900 
901  GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
902  un = GNUNET_new (struct sockaddr_un);
903  un->sun_family = AF_UNIX;
904  GNUNET_strlcpy (un->sun_path, unixpath, sizeof (un->sun_path));
905 #ifdef LINUX
906  {
907  int abstract;
908 
909  abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
910  "TESTING",
911  "USE_ABSTRACT_SOCKETS");
912  if (GNUNET_YES == abstract)
913  un->sun_path[0] = '\0';
914  }
915 #endif
916 #if HAVE_SOCKADDR_UN_SUN_LEN
917  un->sun_len = (u_char) sizeof (struct sockaddr_un);
918 #endif
919  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
920  connection->cfg = cfg;
922  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
923  connection->port = 0;
924  connection->hostname = NULL;
925  connection->addr = (struct sockaddr *) un;
926  connection->addrlen = sizeof (struct sockaddr_un);
927  connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX,
928  SOCK_STREAM,
929  0);
930  if (NULL == connection->sock)
931  {
932  GNUNET_free (connection->addr);
933  GNUNET_free (connection->write_buffer);
934  GNUNET_free (connection);
935  return NULL;
936  }
937  if ( (GNUNET_OK !=
938  GNUNET_NETWORK_socket_connect (connection->sock,
939  connection->addr,
940  connection->addrlen)) &&
941  (EINPROGRESS != errno) )
942  {
943  /* Just return; we expect everything to work eventually so don't fail HARD */
945  GNUNET_NETWORK_socket_close (connection->sock));
946  connection->sock = NULL;
947  return connection;
948  }
949  connect_success_continuation (connection);
950  return connection;
951 #else
952  return NULL;
953 #endif
954 }
955 
956 
969  const struct sockaddr *serv_addr,
970  socklen_t addrlen)
971 {
973 
974  if ( (GNUNET_OK !=
975  GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
976  (EINPROGRESS != errno) )
977  {
978  /* maybe refused / unsupported address, try next */
980  "connect");
982  "Attempt to connect to `%s' failed\n",
983  GNUNET_a2s (serv_addr,
984  addrlen));
986  return NULL;
987  }
989  connection->addr = GNUNET_malloc (addrlen);
990  GNUNET_memcpy (connection->addr, serv_addr, addrlen);
991  connection->addrlen = addrlen;
993  "Trying to connect to `%s' (%p)\n",
994  GNUNET_a2s (serv_addr, addrlen),
995  connection);
996  return connection;
997 }
998 
999 
1011 struct GNUNET_CONNECTION_Handle *
1013  const struct sockaddr *serv_addr,
1014  socklen_t addrlen)
1015 {
1016  struct GNUNET_NETWORK_Handle *s;
1017 
1018  s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
1019  if (NULL == s)
1020  {
1022  "socket");
1023  return NULL;
1024  }
1026  serv_addr,
1027  addrlen);
1028 }
1029 
1030 
1039 int
1041 {
1042  if ((NULL != connection->ap_head) ||
1043  (NULL != connection->dns_active) ||
1044  (NULL != connection->proxy_handshake))
1045  return GNUNET_YES; /* still trying to connect */
1046  if ( (0 != connection->destroy_later) ||
1047  (NULL == connection->sock) )
1048  return GNUNET_NO;
1049  return GNUNET_YES;
1050 }
1051 
1052 
1060 void
1062 {
1063  struct AddressProbe *pos;
1064 
1065  if (0 != connection->destroy_later)
1066  {
1067  connection->destroy_later = -1;
1068  return;
1069  }
1071  "Shutting down connection (%p)\n",
1072  connection);
1073  GNUNET_assert (NULL == connection->nth.notify_ready);
1074  GNUNET_assert (NULL == connection->receiver);
1075  if (NULL != connection->write_task)
1076  {
1077  GNUNET_SCHEDULER_cancel (connection->write_task);
1078  connection->write_task = NULL;
1079  connection->write_buffer_off = 0;
1080  }
1081  if (NULL != connection->read_task)
1082  {
1083  GNUNET_SCHEDULER_cancel (connection->read_task);
1084  connection->read_task = NULL;
1085  }
1086  if (NULL != connection->nth.timeout_task)
1087  {
1089  connection->nth.timeout_task = NULL;
1090  }
1091  connection->nth.notify_ready = NULL;
1092  if (NULL != connection->dns_active)
1093  {
1095  connection->dns_active = NULL;
1096  }
1097  if (NULL != connection->proxy_handshake)
1098  {
1099  /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
1100  connection->proxy_handshake->destroy_later = -1;
1101  connection->proxy_handshake = NULL; /* Not leaked ??? */
1102  }
1103  while (NULL != (pos = connection->ap_head))
1104  {
1107  GNUNET_CONTAINER_DLL_remove (connection->ap_head,
1108  connection->ap_tail,
1109  pos);
1110  GNUNET_free (pos);
1111  }
1112  if ( (NULL != connection->sock) &&
1113  (GNUNET_YES != connection->persist) )
1114  {
1115  if ((GNUNET_OK !=
1116  GNUNET_NETWORK_socket_shutdown (connection->sock,
1117  SHUT_RDWR)) &&
1118  (ENOTCONN != errno) &&
1119  (ECONNRESET != errno) )
1121  "shutdown");
1122  }
1123  if (NULL != connection->sock)
1124  {
1125  if (GNUNET_YES != connection->persist)
1126  {
1128  GNUNET_NETWORK_socket_close (connection->sock));
1129  }
1130  else
1131  {
1132  GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately
1133  * leak the socket in this special case) ... */
1134  }
1135  }
1136  GNUNET_free_non_null (connection->addr);
1137  GNUNET_free_non_null (connection->hostname);
1138  GNUNET_free (connection->write_buffer);
1139  GNUNET_free (connection);
1140 }
1141 
1142 
1149 static void
1150 receive_ready (void *cls)
1151 {
1152  struct GNUNET_CONNECTION_Handle *connection = cls;
1153  const struct GNUNET_SCHEDULER_TaskContext *tc;
1154  char buffer[connection->max];
1155  ssize_t ret;
1156  GNUNET_CONNECTION_Receiver receiver;
1157 
1158  connection->read_task = NULL;
1160  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1161  {
1163  "Receive from `%s' encounters error: timeout (%s, %p)\n",
1164  GNUNET_a2s (connection->addr,
1165  connection->addrlen),
1167  GNUNET_YES),
1168  connection);
1169  signal_receive_timeout (connection);
1170  return;
1171  }
1172  if (NULL == connection->sock)
1173  {
1174  /* connect failed for good */
1175  signal_receive_error (connection, ECONNREFUSED);
1176  return;
1177  }
1179  connection->sock));
1180 RETRY:
1181  ret = GNUNET_NETWORK_socket_recv (connection->sock,
1182  buffer,
1183  connection->max);
1184  if (-1 == ret)
1185  {
1186  if (EINTR == errno)
1187  goto RETRY;
1188  signal_receive_error (connection, errno);
1189  return;
1190  }
1192  "receive_ready read %u/%u bytes from `%s' (%p)!\n",
1193  (unsigned int) ret,
1194  connection->max,
1195  GNUNET_a2s (connection->addr,
1196  connection->addrlen),
1197  connection);
1198  GNUNET_assert (NULL != (receiver = connection->receiver));
1199  connection->receiver = NULL;
1200  receiver (connection->receiver_cls,
1201  buffer,
1202  ret,
1203  connection->addr,
1204  connection->addrlen,
1205  0);
1206 }
1207 
1208 
1224 int
1226  size_t max,
1228  GNUNET_CONNECTION_Receiver receiver,
1229  void *receiver_cls)
1230 {
1231  GNUNET_assert ((NULL == connection->read_task) &&
1232  (NULL == connection->receiver));
1233  GNUNET_assert (NULL != receiver);
1234  connection->receiver = receiver;
1235  connection->receiver_cls = receiver_cls;
1236  connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1237  connection->max = max;
1238  if (NULL != connection->sock)
1239  {
1240  connection->read_task =
1242  (connection->receive_timeout),
1243  connection->sock,
1244  &receive_ready,
1245  connection);
1246  return GNUNET_OK;
1247  }
1248  if ((NULL == connection->dns_active) &&
1249  (NULL == connection->ap_head) &&
1250  (NULL == connection->proxy_handshake))
1251  {
1252  connection->receiver = NULL;
1253  receiver (receiver_cls,
1254  NULL, 0,
1255  NULL, 0,
1256  ETIMEDOUT);
1257  return GNUNET_SYSERR;
1258  }
1259  return GNUNET_OK;
1260 }
1261 
1262 
1271 void *
1273 {
1274  if (NULL != connection->read_task)
1275  {
1276  GNUNET_assert (connection ==
1277  GNUNET_SCHEDULER_cancel (connection->read_task));
1278  connection->read_task = NULL;
1279  }
1280  connection->receiver = NULL;
1281  return connection->receiver_cls;
1282 }
1283 
1284 
1292 static int
1294 {
1295  size_t used;
1296  size_t avail;
1297  size_t size;
1299 
1301  "process_notify is running\n");
1302  GNUNET_assert (NULL == connection->write_task);
1303  if (NULL == (notify = connection->nth.notify_ready))
1304  {
1306  "No one to notify\n");
1307  return GNUNET_NO;
1308  }
1309  used = connection->write_buffer_off - connection->write_buffer_pos;
1310  avail = connection->write_buffer_size - used;
1311  size = connection->nth.notify_size;
1312  if (size > avail)
1313  {
1315  "Not enough buffer\n");
1316  return GNUNET_NO;
1317  }
1318  connection->nth.notify_ready = NULL;
1319  if (connection->write_buffer_size - connection->write_buffer_off < size)
1320  {
1321  /* need to compact */
1322  memmove (connection->write_buffer,
1323  &connection->write_buffer[connection->write_buffer_pos],
1324  used);
1325  connection->write_buffer_off -= connection->write_buffer_pos;
1326  connection->write_buffer_pos = 0;
1327  }
1328  avail = connection->write_buffer_size - connection->write_buffer_off;
1329  GNUNET_assert (avail >= size);
1330  size =
1331  notify (connection->nth.notify_ready_cls, avail,
1332  &connection->write_buffer[connection->write_buffer_off]);
1333  GNUNET_assert (size <= avail);
1334  if (0 != size)
1335  connection->write_buffer_off += size;
1336  return GNUNET_YES;
1337 }
1338 
1339 
1350 static void
1351 transmit_timeout (void *cls)
1352 {
1353  struct GNUNET_CONNECTION_Handle *connection = cls;
1355 
1356  connection->nth.timeout_task = NULL;
1358  "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
1359  connection->hostname,
1360  connection->port,
1361  GNUNET_a2s (connection->addr,
1362  connection->addrlen),
1363  connection);
1364  notify = connection->nth.notify_ready;
1365  GNUNET_assert (NULL != notify);
1366  connection->nth.notify_ready = NULL;
1367  notify (connection->nth.notify_ready_cls,
1368  0,
1369  NULL);
1370 }
1371 
1372 
1381 static void
1382 connect_error (void *cls)
1383 {
1384  struct GNUNET_CONNECTION_Handle *connection = cls;
1386 
1388  "Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
1389  connection->nth.notify_size,
1390  connection->hostname,
1391  connection->port,
1392  connection);
1393  connection->write_task = NULL;
1394  notify = connection->nth.notify_ready;
1395  connection->nth.notify_ready = NULL;
1396  notify (connection->nth.notify_ready_cls,
1397  0,
1398  NULL);
1399 }
1400 
1401 
1407 static void
1408 transmit_ready (void *cls)
1409 {
1410  struct GNUNET_CONNECTION_Handle *connection = cls;
1412  const struct GNUNET_SCHEDULER_TaskContext *tc;
1413  ssize_t ret;
1414  size_t have;
1415 
1417  "transmit_ready running (%p).\n",
1418  connection);
1419  GNUNET_assert (NULL != connection->write_task);
1420  connection->write_task = NULL;
1421  GNUNET_assert (NULL == connection->nth.timeout_task);
1423  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1424  {
1426  "Transmit to `%s' fails, time out reached (%p).\n",
1427  GNUNET_a2s (connection->addr,
1428  connection->addrlen),
1429  connection);
1430  notify = connection->nth.notify_ready;
1431  GNUNET_assert (NULL != notify);
1432  connection->nth.notify_ready = NULL;
1433  notify (connection->nth.notify_ready_cls, 0, NULL);
1434  return;
1435  }
1436  GNUNET_assert (NULL != connection->sock);
1437  if (NULL == tc->write_ready)
1438  {
1439  /* special circumstances (in particular, PREREQ_DONE after
1440  * connect): not yet ready to write, but no "fatal" error either.
1441  * Hence retry. */
1442  goto SCHEDULE_WRITE;
1443  }
1445  connection->sock))
1446  {
1447  GNUNET_assert (NULL == connection->write_task);
1448  /* special circumstances (in particular, shutdown): not yet ready
1449  * to write, but no "fatal" error either. Hence retry. */
1450  goto SCHEDULE_WRITE;
1451  }
1452  GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
1453  if ((NULL != connection->nth.notify_ready) &&
1454  (connection->write_buffer_size < connection->nth.notify_size))
1455  {
1456  connection->write_buffer =
1457  GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
1458  connection->write_buffer_size = connection->nth.notify_size;
1459  }
1460  process_notify (connection);
1461  have = connection->write_buffer_off - connection->write_buffer_pos;
1462  if (0 == have)
1463  {
1464  /* no data ready for writing, terminate write loop */
1465  return;
1466  }
1467  GNUNET_assert (have <= connection->write_buffer_size);
1468  GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size);
1469  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1470 RETRY:
1471  ret =
1472  GNUNET_NETWORK_socket_send (connection->sock,
1473  &connection->write_buffer[connection->write_buffer_pos],
1474  have);
1475  if (-1 == ret)
1476  {
1477  if (EINTR == errno)
1478  goto RETRY;
1479  if (NULL != connection->write_task)
1480  {
1481  GNUNET_SCHEDULER_cancel (connection->write_task);
1482  connection->write_task = NULL;
1483  }
1484  signal_transmit_error (connection, errno);
1485  return;
1486  }
1488  "Connection transmitted %u/%u bytes to `%s' (%p)\n",
1489  (unsigned int) ret,
1490  have,
1491  GNUNET_a2s (connection->addr,
1492  connection->addrlen),
1493  connection);
1494  connection->write_buffer_pos += ret;
1495  if (connection->write_buffer_pos == connection->write_buffer_off)
1496  {
1497  /* transmitted all pending data */
1498  connection->write_buffer_pos = 0;
1499  connection->write_buffer_off = 0;
1500  }
1501  if ( (0 == connection->write_buffer_off) &&
1502  (NULL == connection->nth.notify_ready) )
1503  return; /* all data sent! */
1504  /* not done writing, schedule more */
1505 SCHEDULE_WRITE:
1507  "Re-scheduling transmit_ready (more to do) (%p).\n",
1508  connection);
1509  have = connection->write_buffer_off - connection->write_buffer_pos;
1510  GNUNET_assert ( (NULL != connection->nth.notify_ready) ||
1511  (have > 0) );
1512  if (NULL == connection->write_task)
1513  connection->write_task =
1517  (connection->nth.transmit_timeout),
1518  connection->sock,
1519  &transmit_ready, connection);
1520 }
1521 
1522 
1539  size_t size,
1542  void *notify_cls)
1543 {
1544  if (NULL != connection->nth.notify_ready)
1545  {
1546  GNUNET_assert (0);
1547  return NULL;
1548  }
1549  GNUNET_assert (NULL != notify);
1551  GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
1552  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1553  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
1554  connection->nth.notify_ready = notify;
1555  connection->nth.notify_ready_cls = notify_cls;
1556  connection->nth.connection = connection;
1557  connection->nth.notify_size = size;
1558  connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1559  GNUNET_assert (NULL == connection->nth.timeout_task);
1560  if ((NULL == connection->sock) &&
1561  (NULL == connection->ap_head) &&
1562  (NULL == connection->dns_active) &&
1563  (NULL == connection->proxy_handshake))
1564  {
1565  if (NULL != connection->write_task)
1566  GNUNET_SCHEDULER_cancel (connection->write_task);
1568  connection);
1569  return &connection->nth;
1570  }
1571  if (NULL != connection->write_task)
1572  return &connection->nth; /* previous transmission still in progress */
1573  if (NULL != connection->sock)
1574  {
1575  /* connected, try to transmit now */
1577  "Scheduling transmission (%p).\n",
1578  connection);
1579  connection->write_task =
1581  (connection->nth.transmit_timeout),
1582  connection->sock,
1583  &transmit_ready, connection);
1584  return &connection->nth;
1585  }
1586  /* not yet connected, wait for connection */
1588  "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
1589  connection);
1590  connection->nth.timeout_task =
1593  connection);
1594  return &connection->nth;
1595 }
1596 
1597 
1603 void
1605 {
1606  GNUNET_assert (NULL != th->notify_ready);
1607  th->notify_ready = NULL;
1608  if (NULL != th->timeout_task)
1609  {
1611  th->timeout_task = NULL;
1612  }
1613  if (NULL != th->connection->write_task)
1614  {
1616  th->connection->write_task = NULL;
1617  }
1618 }
1619 
1620 
1627 struct GNUNET_CONNECTION_Handle *
1629 {
1631 
1632  proxied->proxy_handshake = cph;
1633  return proxied;
1634 }
1635 
1636 
1644 void
1646 {
1647  struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
1648 
1649  GNUNET_assert (NULL != cph);
1650  GNUNET_assert (NULL == proxied->sock);
1651  GNUNET_assert (NULL != cph->sock);
1652  proxied->sock = cph->sock;
1653  cph->sock = NULL;
1655  connect_success_continuation (proxied);
1656 }
1657 
1658 
1659 /* end of connection.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
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.
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition: scheduler.c:746
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1268
struct GNUNET_NETWORK_Handle * sock
Underlying OS&#39;s socket, set to NULL after fatal errors.
void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *connection)
Set the persist option on this connection handle.
const struct sockaddr * addr
The address; do not free (allocated at the end of this struct).
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
struct AddressProbe * prev
This is a doubly-linked list.
#define RETRY
Return code we give on &#39;send&#39; if we failed to send right now but it makes sense to retry later...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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:927
static void connect_probe_continuation(void *cls)
Scheduler let us know that we&#39;re either ready to write on the socket OR connect timed out...
struct AddressProbe * ap_head
Linked list of sockets we are currently trying out (during connect).
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.
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)! ...
struct GNUNET_CONNECTION_Handle * proxy_handshake
Handle to subsequent connection after proxy handshake completes,.
static void connect_error(void *cls)
Task invoked by the scheduler when we failed to connect at the time of being asked to transmit...
Context information passed to each scheduler task.
void GNUNET_CONNECTION_acivate_proxied(struct GNUNET_CONNECTION_Handle *proxied)
Activate proxied connection and destroy initial proxy handshake connection.
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:894
#define LOG(kind,...)
Definition: arm_api.c:33
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:245
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define STRERROR(i)
Definition: plibc.h:676
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:417
uid_t uid
UID of the other end of the connection.
int 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:763
int 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:1089
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 ...
static struct GNUNET_FS_UnindexContext * uc
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:1548
static void signal_receive_error(struct GNUNET_CONNECTION_Handle *connection, int errcode)
Tell the receiver callback that we had an IO error.
#define GNUNET_NO
Definition: gnunet_common.h:81
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:927
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
void * GNUNET_CONNECTION_receive_cancel(struct GNUNET_CONNECTION_Handle *connection)
Cancel receive job on the given connection.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
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 ...
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct AddressProbe * ap_tail
Linked list of sockets we are currently trying out (during connect).
void GNUNET_CONNECTION_notify_transmit_ready_cancel(struct GNUNET_CONNECTION_TransmitHandle *th)
Cancel the specified transmission-ready notification.
struct GNUNET_SCHEDULER_Task * task
Task waiting for the connection to finish connecting.
struct GNUNET_CONNECTION_Handle * GNUNET_CONNECTION_create_from_existing(struct GNUNET_NETWORK_Handle *osSocket)
Create a connection handle by boxing an existing OS socket.
int GNUNET_NETWORK_socket_shutdown(struct GNUNET_NETWORK_Handle *desc, int how)
Shut down socket operations.
Definition: network.c:1065
static int ret
Final status code.
Definition: gnunet-arm.c:89
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.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
uint16_t port
Port to connect to.
enum GNUNET_SCHEDULER_Reason reason
Reason why the task is run now.
size_t write_buffer_size
Current size of our write_buffer.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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...
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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.
void * notify_ready_cls
Closure for notify_ready.
gid_t gid
GID of the other end of the connection.
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:680
static void connect_fail_continuation(struct GNUNET_CONNECTION_Handle *connection)
We&#39;ve failed for good to establish a connection (timeout or no more addresses to try).
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:468
char * hostname
Pointer to the hostname if connection was created using DNS lookup, otherwise NULL.
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...
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:1246
int 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:731
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#define GNUNET_memcpy(dst, src, n)
struct GNUNET_SCHEDULER_Task * read_task
Read task that we may need to wait for.
struct sockaddr * addr
Network address of the other end-point, may be NULL.
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.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
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:1273
static struct GNUNET_PEERINFO_NotifyContext * notify
Handle to the peerinfo notify service (NULL until we&#39;ve connected to it).
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:727
#define GNUNET_MIN_MESSAGE_SIZE
Smallest supported message.
struct GNUNET_RESOLVER_RequestHandle * dns_active
Handle to a pending DNS lookup request.
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.
int GNUNET_CONNECTION_check(struct GNUNET_CONNECTION_Handle *connection)
Check if connection is valid (no fatal errors have happened so far).
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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...
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
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)...
socklen_t addrlen
Lenth of addr.
struct GNUNET_TIME_Absolute receive_timeout
Timeout for receiving (in absolute time).
size_t write_buffer_off
Current write-offset in write_buffer (where would we write next).
struct GNUNET_NETWORK_Handle * sock
Underlying OS&#39;s socket.
int8_t persist
When shutdown, do not ever actually close the socket, but free resources.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
static void transmit_ready(void *cls)
We are ready to transmit (or got a timeout).
size_t write_buffer_pos
Current read-offset in write_buffer (how many bytes have already been sent).
The writing socket is ready.
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:271
struct GNUNET_CONNECTION_Handle * connection
Our connection handle.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
Handle to a request given to the resolver.
Definition: resolver_api.c:100
The specified timeout has expired.
int GNUNET_CONNECTION_get_address(struct GNUNET_CONNECTION_Handle *connection, void **addr, size_t *addrlen)
Obtain the network address of the other party.
struct GNUNET_CONNECTION_TransmitHandle nth
The handle we return for GNUNET_CONNECTION_notify_transmit_ready().
void GNUNET_CONNECTION_destroy(struct GNUNET_CONNECTION_Handle *connection)
Close the connection and free associated resources.
GNUNET_CONNECTION_Receiver receiver
Function to call on data received, NULL if no receive is pending.
static void connect_success_continuation(struct GNUNET_CONNECTION_Handle *connection)
We&#39;ve succeeded in establishing a connection.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
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.
struct AddressProbe * next
This is a linked list.
static char * hostname
Our hostname; we give this to all the peers we start.
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 uint16_t port
Port number.
Definition: gnunet-bcd.c:79
configuration data
Definition: configuration.c:85
static void signal_receive_timeout(struct GNUNET_CONNECTION_Handle *connection)
Tell the receiver callback that a timeout was reached.
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_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:373
size_t max
Maximum number of bytes to read (for receiving).
size_t notify_size
At what number of bytes available in the write buffer should the notify method be called...
Entry in list of pending tasks.
Definition: scheduler.c:134
Credentials for UNIX domain sockets.
handle to a socket
Definition: network.c:46
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.
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:331
struct GNUNET_SCHEDULER_Task * write_task
Write task that we may need to wait for.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:1478
struct GNUNET_TIME_Absolute transmit_timeout
Timeout for receiving (in absolute time).
socklen_t addrlen
Length of addr.
char * write_buffer
Pointer to our write buffer.
GNUNET_CONNECTION_TransmitReadyNotify notify_ready
Function to call if the send buffer has notify_size bytes available.
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:1181
int 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".
handle for a network connection
void * receiver_cls
Closure for receiver.
#define LOG_STRERROR(kind, syscall)
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
#define CONNECT_RETRY_TIMEOUT
Timeout we use on TCP connect before trying another result from the DNS resolver. ...
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:604
#define GNUNET_malloc(size)
Wrapper around malloc.
During connect, we try multiple possible IP addresses to find out which one might work...
static void receive_ready(void *cls)
This function is called once we either timeout or have data ready to read.
static void signal_transmit_error(struct GNUNET_CONNECTION_Handle *connection, int ecode)
We failed to transmit data to the service, signal the error.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_CONNECTION_Handle * connection
Connection for which we are probing.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:1037
struct GNUNET_SCHEDULER_Task * timeout_task
Task called on timeout.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965