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 \
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 
61 
66 
71 
76 
81 
86  size_t notify_size;
87 };
88 
89 
94 struct AddressProbe {
98  struct AddressProbe *next;
99 
104 
108  const struct sockaddr *addr;
109 
114 
119 
123  socklen_t addrlen;
124 
129 };
130 
131 
140 
146 
152 
156  struct sockaddr *addr;
157 
162  char *hostname;
163 
168 
173 
178 
183 
188 
194 
200 
204  socklen_t addrlen;
205 
210 
215 
220 
225 
229  struct GNUNET_TIME_Absolute receive_timeout;
230 
234  size_t max;
235 
239  uint16_t port;
240 
247  int8_t persist;
248 
255 
260 };
261 
262 
270 void
272 {
273  connection->persist = GNUNET_YES;
274 }
275 
276 
288 int
290 {
291  return GNUNET_NETWORK_socket_disable_corking(connection->sock);
292 }
293 
294 
305 {
307 
308  connection = GNUNET_new(struct GNUNET_CONNECTION_Handle);
310  connection->write_buffer = GNUNET_malloc(connection->write_buffer_size);
311  connection->sock = osSocket;
312  return connection;
313 }
314 
315 
327  void *access_cb_cls,
328  struct GNUNET_NETWORK_Handle *lsock)
329 {
331  char addr[128];
332  socklen_t addrlen;
333  struct GNUNET_NETWORK_Handle *sock;
334  int aret;
335  struct sockaddr_in *v4;
336  struct sockaddr_in6 *v6;
337  struct sockaddr *sa;
338  void *uaddr;
339 
340 #ifdef SO_PEERCRED
341  struct ucred uc;
342  socklen_t olen;
343 #endif
344  struct GNUNET_CONNECTION_Credentials *gcp;
345 #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
347 
348  gc.uid = 0;
349  gc.gid = 0;
350 #endif
351 
352  addrlen = sizeof(addr);
353  sock =
354  GNUNET_NETWORK_socket_accept(lsock, (struct sockaddr *)&addr, &addrlen);
355  if (NULL == sock)
356  {
357  if (EAGAIN != errno)
359  return NULL;
360  }
361  if ((addrlen > sizeof(addr)) || (addrlen < sizeof(sa_family_t)))
362  {
363  GNUNET_break(0);
365  return NULL;
366  }
367 
368  sa = (struct sockaddr *)addr;
369  v6 = (struct sockaddr_in6 *)addr;
370  if ((AF_INET6 == sa->sa_family) && (IN6_IS_ADDR_V4MAPPED(&v6->sin6_addr)))
371  {
372  /* convert to V4 address */
373  v4 = GNUNET_new(struct sockaddr_in);
374  memset(v4, 0, sizeof(struct sockaddr_in));
375  v4->sin_family = AF_INET;
376 #if HAVE_SOCKADDR_IN_SIN_LEN
377  v4->sin_len = (u_char)sizeof(struct sockaddr_in);
378 #endif
379  GNUNET_memcpy(&v4->sin_addr,
380  &((char *)&v6->sin6_addr)[sizeof(struct in6_addr) -
381  sizeof(struct in_addr)],
382  sizeof(struct in_addr));
383  v4->sin_port = v6->sin6_port;
384  uaddr = v4;
385  addrlen = sizeof(struct sockaddr_in);
386  }
387  else
388  {
389  uaddr = GNUNET_malloc(addrlen);
390  GNUNET_memcpy(uaddr, addr, addrlen);
391  }
392  gcp = NULL;
393  if (AF_UNIX == sa->sa_family)
394  {
395 #if HAVE_GETPEEREID
396  /* most BSDs */
397  if (0 == getpeereid(GNUNET_NETWORK_get_fd(sock), &gc.uid, &gc.gid))
398  gcp = &gc;
399 #else
400 #ifdef SO_PEERCRED
401  /* largely traditional GNU/Linux */
402  olen = sizeof(uc);
403  if ((0 == getsockopt(GNUNET_NETWORK_get_fd(sock),
404  SOL_SOCKET,
405  SO_PEERCRED,
406  &uc,
407  &olen)) &&
408  (olen == sizeof(uc)))
409  {
410  gc.uid = uc.uid;
411  gc.gid = uc.gid;
412  gcp = &gc;
413  }
414 #else
415 #if HAVE_GETPEERUCRED
416  /* this is for Solaris 10 */
417  ucred_t *uc;
418 
419  uc = NULL;
420  if (0 == getpeerucred(GNUNET_NETWORK_get_fd(sock), &uc))
421  {
422  gc.uid = ucred_geteuid(uc);
423  gc.gid = ucred_getegid(uc);
424  gcp = &gc;
425  }
426  ucred_free(uc);
427 #endif
428 #endif
429 #endif
430  }
431 
432  if ((NULL != access_cb) &&
433  (GNUNET_YES != (aret = access_cb(access_cb_cls, gcp, uaddr, addrlen))))
434  {
435  if (GNUNET_NO == aret)
437  _("Access denied to `%s'\n"),
438  GNUNET_a2s(uaddr, addrlen));
440  GNUNET_NETWORK_socket_shutdown(sock, SHUT_RDWR));
442  GNUNET_free(uaddr);
443  return NULL;
444  }
445  connection = GNUNET_new(struct GNUNET_CONNECTION_Handle);
447  connection->write_buffer = GNUNET_malloc(connection->write_buffer_size);
448  connection->addr = uaddr;
449  connection->addrlen = addrlen;
450  connection->sock = sock;
452  _("Accepting connection from `%s': %p\n"),
453  GNUNET_a2s(uaddr, addrlen),
454  connection);
455  return connection;
456 }
457 
458 
467 int
469  void **addr,
470  size_t *addrlen)
471 {
472  if ((NULL == connection->addr) || (0 == connection->addrlen))
473  return GNUNET_NO;
474  *addr = GNUNET_malloc(connection->addrlen);
475  GNUNET_memcpy(*addr, connection->addr, connection->addrlen);
476  *addrlen = connection->addrlen;
477  return GNUNET_OK;
478 }
479 
480 
487 static void
489 {
491 
493  "Receive encounters error (%s), connection closed (%p)\n",
494  strerror(errcode),
495  connection);
496  GNUNET_assert(NULL != (receiver = connection->receiver));
497  connection->receiver = NULL;
498  receiver(connection->receiver_cls,
499  NULL,
500  0,
501  connection->addr,
502  connection->addrlen,
503  errcode);
504 }
505 
506 
512 static void
514 {
516 
518  "Connection signals timeout to receiver (%p)!\n",
519  connection);
520  GNUNET_assert(NULL != (receiver = connection->receiver));
521  connection->receiver = NULL;
522  receiver(connection->receiver_cls, NULL, 0, NULL, 0, 0);
523 }
524 
525 
532 static void
534 {
536 
538  "Transmission encounterd error (%s), connection closed (%p)\n",
539  strerror(ecode),
540  connection);
541  if (NULL != connection->sock)
542  {
543  (void)GNUNET_NETWORK_socket_shutdown(connection->sock, SHUT_RDWR);
545  connection->sock = NULL;
546  GNUNET_assert(NULL == connection->write_task);
547  }
548  if (NULL != connection->read_task)
549  {
550  /* send errors trigger read errors... */
551  GNUNET_SCHEDULER_cancel(connection->read_task);
552  connection->read_task = NULL;
553  signal_receive_timeout(connection);
554  return;
555  }
556  if (NULL == connection->nth.notify_ready)
557  return; /* nobody to tell about it */
558  notify = connection->nth.notify_ready;
559  connection->nth.notify_ready = NULL;
560  notify(connection->nth.notify_ready_cls, 0, NULL);
561 }
562 
563 
570 static void
572 {
574  "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
575  connection->hostname,
576  connection->port);
577  GNUNET_break(NULL == connection->ap_head);
578  GNUNET_break(NULL == connection->ap_tail);
579  GNUNET_break(GNUNET_NO == connection->dns_active);
580  GNUNET_break(NULL == connection->sock);
581  GNUNET_assert(NULL == connection->write_task);
582  GNUNET_assert(NULL == connection->proxy_handshake);
583 
584  /* signal errors for jobs that used to wait on the connection */
585  connection->destroy_later = 1;
586  if (NULL != connection->receiver)
587  signal_receive_error(connection, ECONNREFUSED);
588  if (NULL != connection->nth.notify_ready)
589  {
590  GNUNET_assert(NULL != connection->nth.timeout_task);
592  connection->nth.timeout_task = NULL;
593  signal_transmit_error(connection, ECONNREFUSED);
594  }
595  if (-1 == connection->destroy_later)
596  {
597  /* do it now */
598  connection->destroy_later = 0;
599  GNUNET_CONNECTION_destroy(connection);
600  return;
601  }
602  connection->destroy_later = 0;
603 }
604 
605 
611 static void
612 transmit_ready(void *cls);
613 
614 
621 static void
622 receive_ready(void *cls);
623 
624 
630 static void
632 {
634  "Connection to `%s' succeeded! (%p)\n",
635  GNUNET_a2s(connection->addr, connection->addrlen),
636  connection);
637  /* trigger jobs that waited for the connection */
638  if (NULL != connection->receiver)
639  {
641  "Connection succeeded, starting with receiving data (%p)\n",
642  connection);
643  GNUNET_assert(NULL == connection->read_task);
644  connection->read_task =
646  connection->receive_timeout),
647  connection->sock,
648  &receive_ready,
649  connection);
650  }
651  if (NULL != connection->nth.notify_ready)
652  {
654  "Connection succeeded, starting with sending data (%p)\n",
655  connection);
656  GNUNET_assert(connection->nth.timeout_task != NULL);
658  connection->nth.timeout_task = NULL;
659  GNUNET_assert(connection->write_task == NULL);
660  connection->write_task =
662  connection->nth.transmit_timeout),
663  connection->sock,
665  connection);
666  }
667 }
668 
669 
676 static void
678 {
679  struct AddressProbe *ap = cls;
681  const struct GNUNET_SCHEDULER_TaskContext *tc;
682  struct AddressProbe *pos;
683  int error;
684  socklen_t len;
685 
686  GNUNET_assert(NULL != ap->sock);
687  GNUNET_CONTAINER_DLL_remove(connection->ap_head, connection->ap_tail, ap);
688  len = sizeof(error);
689  errno = 0;
690  error = 0;
692  if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
694  SOL_SOCKET,
695  SO_ERROR,
696  &error,
697  &len)) ||
698  (0 != error))
699  {
701  GNUNET_free(ap);
702  if ((NULL == connection->ap_head) &&
703  (GNUNET_NO == connection->dns_active) &&
704  (NULL == connection->proxy_handshake))
705  connect_fail_continuation(connection);
706  return;
707  }
708  GNUNET_assert(NULL == connection->sock);
709  connection->sock = ap->sock;
710  GNUNET_assert(NULL == connection->addr);
711  connection->addr = GNUNET_malloc(ap->addrlen);
712  GNUNET_memcpy(connection->addr, ap->addr, ap->addrlen);
713  connection->addrlen = ap->addrlen;
714  GNUNET_free(ap);
715  /* cancel all other attempts */
716  while (NULL != (pos = connection->ap_head))
717  {
720  GNUNET_CONTAINER_DLL_remove(connection->ap_head, connection->ap_tail, pos);
721  GNUNET_free(pos);
722  }
723  connect_success_continuation(connection);
724 }
725 
726 
735 static void
737  const struct sockaddr *addr,
738  socklen_t addrlen)
739 {
740  struct GNUNET_CONNECTION_Handle *connection = cls;
741  struct AddressProbe *ap;
742  struct GNUNET_TIME_Relative delay;
743 
744  if (NULL == addr)
745  {
746  connection->dns_active = NULL;
747  if ((NULL == connection->ap_head) && (NULL == connection->sock) &&
748  (NULL == connection->proxy_handshake))
749  connect_fail_continuation(connection);
750  return;
751  }
752  if (NULL != connection->sock)
753  return; /* already connected */
754  GNUNET_assert(NULL == connection->addr);
755  /* try to connect */
757  "Trying to connect using address `%s:%u/%s:%u'\n",
758  connection->hostname,
759  connection->port,
760  GNUNET_a2s(addr, addrlen),
761  connection->port);
762  ap = GNUNET_malloc(sizeof(struct AddressProbe) + addrlen);
763  ap->addr = (const struct sockaddr *)&ap[1];
764  GNUNET_memcpy(&ap[1], addr, addrlen);
765  ap->addrlen = addrlen;
766  ap->connection = connection;
767 
768  switch (ap->addr->sa_family)
769  {
770  case AF_INET:
771  ((struct sockaddr_in *)ap->addr)->sin_port = htons(connection->port);
772  break;
773 
774  case AF_INET6:
775  ((struct sockaddr_in6 *)ap->addr)->sin6_port = htons(connection->port);
776  break;
777 
778  default:
779  GNUNET_break(0);
780  GNUNET_free(ap);
781  return; /* not supported by us */
782  }
783  ap->sock = GNUNET_NETWORK_socket_create(ap->addr->sa_family, SOCK_STREAM, 0);
784  if (NULL == ap->sock)
785  {
786  GNUNET_free(ap);
787  return; /* not supported by OS */
788  }
790  "Trying to connect to `%s' (%p)\n",
791  GNUNET_a2s(ap->addr, ap->addrlen),
792  connection);
793  if ((GNUNET_OK !=
795  (EINPROGRESS != errno))
796  {
797  /* maybe refused / unsupported address, try next */
800  GNUNET_free(ap);
801  return;
802  }
803  GNUNET_CONTAINER_DLL_insert(connection->ap_head, connection->ap_tail, ap);
804  delay = CONNECT_RETRY_TIMEOUT;
805  if (NULL != connection->nth.notify_ready)
806  delay = GNUNET_TIME_relative_min(delay,
808  connection->nth.transmit_timeout));
809  if (NULL != connection->receiver)
810  delay = GNUNET_TIME_relative_min(delay,
812  connection->receive_timeout));
814  ap->sock,
816  ap);
817 }
818 
819 
832  const struct GNUNET_CONFIGURATION_Handle *cfg,
833  const char *hostname,
834  uint16_t port)
835 {
837 
838  GNUNET_assert(0 < strlen(hostname)); /* sanity check */
839  connection = GNUNET_new(struct GNUNET_CONNECTION_Handle);
840  connection->cfg = cfg;
842  connection->write_buffer = GNUNET_malloc(connection->write_buffer_size);
843  connection->port = port;
844  connection->hostname = GNUNET_strdup(hostname);
845  connection->dns_active = GNUNET_RESOLVER_ip_get(connection->hostname,
846  AF_UNSPEC,
849  connection);
850  return connection;
851 }
852 
853 
865  const struct GNUNET_CONFIGURATION_Handle *cfg,
866  const char *unixpath)
867 {
868 #ifdef AF_UNIX
870  struct sockaddr_un *un;
871 
872  GNUNET_assert(0 < strlen(unixpath)); /* sanity check */
873  un = GNUNET_new(struct sockaddr_un);
874  un->sun_family = AF_UNIX;
875  GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path));
876 #ifdef LINUX
877  {
878  int abstract;
879 
881  "TESTING",
882  "USE_ABSTRACT_SOCKETS");
883  if (GNUNET_YES == abstract)
884  un->sun_path[0] = '\0';
885  }
886 #endif
887 #if HAVE_SOCKADDR_UN_SUN_LEN
888  un->sun_len = (u_char)sizeof(struct sockaddr_un);
889 #endif
890  connection = GNUNET_new(struct GNUNET_CONNECTION_Handle);
891  connection->cfg = cfg;
893  connection->write_buffer = GNUNET_malloc(connection->write_buffer_size);
894  connection->port = 0;
895  connection->hostname = NULL;
896  connection->addr = (struct sockaddr *)un;
897  connection->addrlen = sizeof(struct sockaddr_un);
898  connection->sock = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0);
899  if (NULL == connection->sock)
900  {
901  GNUNET_free(connection->addr);
902  GNUNET_free(connection->write_buffer);
903  GNUNET_free(connection);
904  return NULL;
905  }
906  if ((GNUNET_OK != GNUNET_NETWORK_socket_connect(connection->sock,
907  connection->addr,
908  connection->addrlen)) &&
909  (EINPROGRESS != errno))
910  {
911  /* Just return; we expect everything to work eventually so don't fail HARD */
913  connection->sock = NULL;
914  return connection;
915  }
916  connect_success_continuation(connection);
917  return connection;
918 #else
919  return NULL;
920 #endif
921 }
922 
923 
936  const struct sockaddr *serv_addr,
937  socklen_t addrlen)
938 {
940 
941  if ((GNUNET_OK != GNUNET_NETWORK_socket_connect(s, serv_addr, addrlen)) &&
942  (EINPROGRESS != errno))
943  {
944  /* maybe refused / unsupported address, try next */
947  "Attempt to connect to `%s' failed\n",
948  GNUNET_a2s(serv_addr, addrlen));
950  return NULL;
951  }
953  connection->addr = GNUNET_malloc(addrlen);
954  GNUNET_memcpy(connection->addr, serv_addr, addrlen);
955  connection->addrlen = addrlen;
957  "Trying to connect to `%s' (%p)\n",
958  GNUNET_a2s(serv_addr, addrlen),
959  connection);
960  return connection;
961 }
962 
963 
977  const struct sockaddr *serv_addr,
978  socklen_t addrlen)
979 {
980  struct GNUNET_NETWORK_Handle *s;
981 
982  s = GNUNET_NETWORK_socket_create(af_family, SOCK_STREAM, 0);
983  if (NULL == s)
984  {
986  return NULL;
987  }
988  return GNUNET_CONNECTION_connect_socket(s, serv_addr, addrlen);
989 }
990 
991 
1000 int
1002 {
1003  if ((NULL != connection->ap_head) || (NULL != connection->dns_active) ||
1004  (NULL != connection->proxy_handshake))
1005  return GNUNET_YES; /* still trying to connect */
1006  if ((0 != connection->destroy_later) || (NULL == connection->sock))
1007  return GNUNET_NO;
1008  return GNUNET_YES;
1009 }
1010 
1011 
1019 void
1021 {
1022  struct AddressProbe *pos;
1023 
1024  if (0 != connection->destroy_later)
1025  {
1026  connection->destroy_later = -1;
1027  return;
1028  }
1029  LOG(GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
1030  GNUNET_assert(NULL == connection->nth.notify_ready);
1031  GNUNET_assert(NULL == connection->receiver);
1032  if (NULL != connection->write_task)
1033  {
1034  GNUNET_SCHEDULER_cancel(connection->write_task);
1035  connection->write_task = NULL;
1036  connection->write_buffer_off = 0;
1037  }
1038  if (NULL != connection->read_task)
1039  {
1040  GNUNET_SCHEDULER_cancel(connection->read_task);
1041  connection->read_task = NULL;
1042  }
1043  if (NULL != connection->nth.timeout_task)
1044  {
1046  connection->nth.timeout_task = NULL;
1047  }
1048  connection->nth.notify_ready = NULL;
1049  if (NULL != connection->dns_active)
1050  {
1052  connection->dns_active = NULL;
1053  }
1054  if (NULL != connection->proxy_handshake)
1055  {
1056  /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
1057  connection->proxy_handshake->destroy_later = -1;
1058  connection->proxy_handshake = NULL; /* Not leaked ??? */
1059  }
1060  while (NULL != (pos = connection->ap_head))
1061  {
1064  GNUNET_CONTAINER_DLL_remove(connection->ap_head, connection->ap_tail, pos);
1065  GNUNET_free(pos);
1066  }
1067  if ((NULL != connection->sock) && (GNUNET_YES != connection->persist))
1068  {
1069  if ((GNUNET_OK !=
1070  GNUNET_NETWORK_socket_shutdown(connection->sock, SHUT_RDWR)) &&
1071  (ENOTCONN != errno) && (ECONNRESET != errno))
1073  }
1074  if (NULL != connection->sock)
1075  {
1076  if (GNUNET_YES != connection->persist)
1077  {
1079  GNUNET_NETWORK_socket_close(connection->sock));
1080  }
1081  else
1082  {
1084  connection->sock); /* at least no memory leak (we deliberately
1085  * leak the socket in this special case) ... */
1086  }
1087  }
1088  GNUNET_free_non_null(connection->addr);
1089  GNUNET_free_non_null(connection->hostname);
1090  GNUNET_free(connection->write_buffer);
1091  GNUNET_free(connection);
1092 }
1093 
1094 
1101 static void
1102 receive_ready(void *cls)
1103 {
1104  struct GNUNET_CONNECTION_Handle *connection = cls;
1105  const struct GNUNET_SCHEDULER_TaskContext *tc;
1106  char buffer[connection->max];
1107  ssize_t ret;
1108  GNUNET_CONNECTION_Receiver receiver;
1109 
1110  connection->read_task = NULL;
1112  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1113  {
1115  "Receive from `%s' encounters error: timeout (%s, %p)\n",
1116  GNUNET_a2s(connection->addr, connection->addrlen),
1118  connection->receive_timeout),
1119  GNUNET_YES),
1120  connection);
1121  signal_receive_timeout(connection);
1122  return;
1123  }
1124  if (NULL == connection->sock)
1125  {
1126  /* connect failed for good */
1127  signal_receive_error(connection, ECONNREFUSED);
1128  return;
1129  }
1131 RETRY:
1132  ret = GNUNET_NETWORK_socket_recv(connection->sock, buffer, connection->max);
1133  if (-1 == ret)
1134  {
1135  if (EINTR == errno)
1136  goto RETRY;
1137  signal_receive_error(connection, errno);
1138  return;
1139  }
1141  "receive_ready read %u/%u bytes from `%s' (%p)!\n",
1142  (unsigned int)ret,
1143  connection->max,
1144  GNUNET_a2s(connection->addr, connection->addrlen),
1145  connection);
1146  GNUNET_assert(NULL != (receiver = connection->receiver));
1147  connection->receiver = NULL;
1148  receiver(connection->receiver_cls,
1149  buffer,
1150  ret,
1151  connection->addr,
1152  connection->addrlen,
1153  0);
1154 }
1155 
1156 
1172 int
1174  size_t max,
1176  GNUNET_CONNECTION_Receiver receiver,
1177  void *receiver_cls)
1178 {
1179  GNUNET_assert((NULL == connection->read_task) &&
1180  (NULL == connection->receiver));
1181  GNUNET_assert(NULL != receiver);
1182  connection->receiver = receiver;
1183  connection->receiver_cls = receiver_cls;
1184  connection->receive_timeout = GNUNET_TIME_relative_to_absolute(timeout);
1185  connection->max = max;
1186  if (NULL != connection->sock)
1187  {
1188  connection->read_task =
1190  connection->receive_timeout),
1191  connection->sock,
1192  &receive_ready,
1193  connection);
1194  return GNUNET_OK;
1195  }
1196  if ((NULL == connection->dns_active) && (NULL == connection->ap_head) &&
1197  (NULL == connection->proxy_handshake))
1198  {
1199  connection->receiver = NULL;
1200  receiver(receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT);
1201  return GNUNET_SYSERR;
1202  }
1203  return GNUNET_OK;
1204 }
1205 
1206 
1215 void *
1217 {
1218  if (NULL != connection->read_task)
1219  {
1220  GNUNET_assert(connection ==
1221  GNUNET_SCHEDULER_cancel(connection->read_task));
1222  connection->read_task = NULL;
1223  }
1224  connection->receiver = NULL;
1225  return connection->receiver_cls;
1226 }
1227 
1228 
1236 static int
1238 {
1239  size_t used;
1240  size_t avail;
1241  size_t size;
1243 
1244  LOG(GNUNET_ERROR_TYPE_DEBUG, "process_notify is running\n");
1245  GNUNET_assert(NULL == connection->write_task);
1246  if (NULL == (notify = connection->nth.notify_ready))
1247  {
1248  LOG(GNUNET_ERROR_TYPE_DEBUG, "No one to notify\n");
1249  return GNUNET_NO;
1250  }
1251  used = connection->write_buffer_off - connection->write_buffer_pos;
1252  avail = connection->write_buffer_size - used;
1253  size = connection->nth.notify_size;
1254  if (size > avail)
1255  {
1256  LOG(GNUNET_ERROR_TYPE_DEBUG, "Not enough buffer\n");
1257  return GNUNET_NO;
1258  }
1259  connection->nth.notify_ready = NULL;
1260  if (connection->write_buffer_size - connection->write_buffer_off < size)
1261  {
1262  /* need to compact */
1263  memmove(connection->write_buffer,
1264  &connection->write_buffer[connection->write_buffer_pos],
1265  used);
1266  connection->write_buffer_off -= connection->write_buffer_pos;
1267  connection->write_buffer_pos = 0;
1268  }
1269  avail = connection->write_buffer_size - connection->write_buffer_off;
1270  GNUNET_assert(avail >= size);
1271  size = notify(connection->nth.notify_ready_cls,
1272  avail,
1273  &connection->write_buffer[connection->write_buffer_off]);
1274  GNUNET_assert(size <= avail);
1275  if (0 != size)
1276  connection->write_buffer_off += size;
1277  return GNUNET_YES;
1278 }
1279 
1280 
1291 static void
1293 {
1294  struct GNUNET_CONNECTION_Handle *connection = cls;
1296 
1297  connection->nth.timeout_task = NULL;
1299  "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
1300  connection->hostname,
1301  connection->port,
1302  GNUNET_a2s(connection->addr, connection->addrlen),
1303  connection);
1304  notify = connection->nth.notify_ready;
1305  GNUNET_assert(NULL != notify);
1306  connection->nth.notify_ready = NULL;
1307  notify(connection->nth.notify_ready_cls, 0, NULL);
1308 }
1309 
1310 
1319 static void
1320 connect_error(void *cls)
1321 {
1322  struct GNUNET_CONNECTION_Handle *connection = cls;
1324 
1326  "Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
1327  connection->nth.notify_size,
1328  connection->hostname,
1329  connection->port,
1330  connection);
1331  connection->write_task = NULL;
1332  notify = connection->nth.notify_ready;
1333  connection->nth.notify_ready = NULL;
1334  notify(connection->nth.notify_ready_cls, 0, NULL);
1335 }
1336 
1337 
1343 static void
1344 transmit_ready(void *cls)
1345 {
1346  struct GNUNET_CONNECTION_Handle *connection = cls;
1348  const struct GNUNET_SCHEDULER_TaskContext *tc;
1349  ssize_t ret;
1350  size_t have;
1351 
1352  LOG(GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", connection);
1353  GNUNET_assert(NULL != connection->write_task);
1354  connection->write_task = NULL;
1355  GNUNET_assert(NULL == connection->nth.timeout_task);
1357  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1358  {
1360  "Transmit to `%s' fails, time out reached (%p).\n",
1361  GNUNET_a2s(connection->addr, connection->addrlen),
1362  connection);
1363  notify = connection->nth.notify_ready;
1364  GNUNET_assert(NULL != notify);
1365  connection->nth.notify_ready = NULL;
1366  notify(connection->nth.notify_ready_cls, 0, NULL);
1367  return;
1368  }
1369  GNUNET_assert(NULL != connection->sock);
1370  if (NULL == tc->write_ready)
1371  {
1372  /* special circumstances (in particular, PREREQ_DONE after
1373  * connect): not yet ready to write, but no "fatal" error either.
1374  * Hence retry. */
1375  goto SCHEDULE_WRITE;
1376  }
1377  if (!GNUNET_NETWORK_fdset_isset(tc->write_ready, connection->sock))
1378  {
1379  GNUNET_assert(NULL == connection->write_task);
1380  /* special circumstances (in particular, shutdown): not yet ready
1381  * to write, but no "fatal" error either. Hence retry. */
1382  goto SCHEDULE_WRITE;
1383  }
1384  GNUNET_assert(connection->write_buffer_off >= connection->write_buffer_pos);
1385  if ((NULL != connection->nth.notify_ready) &&
1386  (connection->write_buffer_size < connection->nth.notify_size))
1387  {
1388  connection->write_buffer =
1389  GNUNET_realloc(connection->write_buffer, connection->nth.notify_size);
1390  connection->write_buffer_size = connection->nth.notify_size;
1391  }
1392  process_notify(connection);
1393  have = connection->write_buffer_off - connection->write_buffer_pos;
1394  if (0 == have)
1395  {
1396  /* no data ready for writing, terminate write loop */
1397  return;
1398  }
1399  GNUNET_assert(have <= connection->write_buffer_size);
1400  GNUNET_assert(have + connection->write_buffer_pos <=
1401  connection->write_buffer_size);
1402  GNUNET_assert(connection->write_buffer_pos <= connection->write_buffer_size);
1403 RETRY:
1404  ret =
1405  GNUNET_NETWORK_socket_send(connection->sock,
1406  &connection
1407  ->write_buffer[connection->write_buffer_pos],
1408  have);
1409  if (-1 == ret)
1410  {
1411  if (EINTR == errno)
1412  goto RETRY;
1413  if (NULL != connection->write_task)
1414  {
1415  GNUNET_SCHEDULER_cancel(connection->write_task);
1416  connection->write_task = NULL;
1417  }
1418  signal_transmit_error(connection, errno);
1419  return;
1420  }
1422  "Connection transmitted %u/%u bytes to `%s' (%p)\n",
1423  (unsigned int)ret,
1424  have,
1425  GNUNET_a2s(connection->addr, connection->addrlen),
1426  connection);
1427  connection->write_buffer_pos += ret;
1428  if (connection->write_buffer_pos == connection->write_buffer_off)
1429  {
1430  /* transmitted all pending data */
1431  connection->write_buffer_pos = 0;
1432  connection->write_buffer_off = 0;
1433  }
1434  if ((0 == connection->write_buffer_off) &&
1435  (NULL == connection->nth.notify_ready))
1436  return; /* all data sent! */
1437  /* not done writing, schedule more */
1438 SCHEDULE_WRITE:
1440  "Re-scheduling transmit_ready (more to do) (%p).\n",
1441  connection);
1442  have = connection->write_buffer_off - connection->write_buffer_pos;
1443  GNUNET_assert((NULL != connection->nth.notify_ready) || (have > 0));
1444  if (NULL == connection->write_task)
1445  connection->write_task =
1446  GNUNET_SCHEDULER_add_write_net((connection->nth.notify_ready == NULL)
1449  connection->nth.transmit_timeout),
1450  connection->sock,
1451  &transmit_ready,
1452  connection);
1453 }
1454 
1455 
1473  size_t size,
1476  void *notify_cls)
1477 {
1478  if (NULL != connection->nth.notify_ready)
1479  {
1480  GNUNET_assert(0);
1481  return NULL;
1482  }
1483  GNUNET_assert(NULL != notify);
1485  GNUNET_assert(connection->write_buffer_off <= connection->write_buffer_size);
1486  GNUNET_assert(connection->write_buffer_pos <= connection->write_buffer_size);
1487  GNUNET_assert(connection->write_buffer_pos <= connection->write_buffer_off);
1488  connection->nth.notify_ready = notify;
1489  connection->nth.notify_ready_cls = notify_cls;
1490  connection->nth.connection = connection;
1491  connection->nth.notify_size = size;
1492  connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute(timeout);
1493  GNUNET_assert(NULL == connection->nth.timeout_task);
1494  if ((NULL == connection->sock) && (NULL == connection->ap_head) &&
1495  (NULL == connection->dns_active) && (NULL == connection->proxy_handshake))
1496  {
1497  if (NULL != connection->write_task)
1498  GNUNET_SCHEDULER_cancel(connection->write_task);
1499  connection->write_task =
1501  return &connection->nth;
1502  }
1503  if (NULL != connection->write_task)
1504  return &connection->nth; /* previous transmission still in progress */
1505  if (NULL != connection->sock)
1506  {
1507  /* connected, try to transmit now */
1509  "Scheduling transmission (%p).\n",
1510  connection);
1511  connection->write_task =
1513  connection->nth.transmit_timeout),
1514  connection->sock,
1515  &transmit_ready,
1516  connection);
1517  return &connection->nth;
1518  }
1519  /* not yet connected, wait for connection */
1521  "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
1522  connection);
1523  connection->nth.timeout_task =
1524  GNUNET_SCHEDULER_add_delayed(timeout, &transmit_timeout, connection);
1525  return &connection->nth;
1526 }
1527 
1528 
1534 void
1537 {
1538  GNUNET_assert(NULL != th->notify_ready);
1539  th->notify_ready = NULL;
1540  if (NULL != th->timeout_task)
1541  {
1543  th->timeout_task = NULL;
1544  }
1545  if (NULL != th->connection->write_task)
1546  {
1548  th->connection->write_task = NULL;
1549  }
1550 }
1551 
1552 
1559 struct GNUNET_CONNECTION_Handle *
1561  struct GNUNET_CONNECTION_Handle *cph)
1562 {
1563  struct GNUNET_CONNECTION_Handle *proxied =
1565 
1566  proxied->proxy_handshake = cph;
1567  return proxied;
1568 }
1569 
1570 
1578 void
1580 {
1581  struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
1582 
1583  GNUNET_assert(NULL != cph);
1584  GNUNET_assert(NULL == proxied->sock);
1585  GNUNET_assert(NULL != cph->sock);
1586  proxied->sock = cph->sock;
1587  cph->sock = NULL;
1590 }
1591 
1592 
1593 /* 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:737
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1068
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:804
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:775
#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:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:410
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:671
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:949
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:1537
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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:78
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:933
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:928
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:181
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:610
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:420
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:1237
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:646
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
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:1264
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:686
#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:272
struct GNUNET_CONNECTION_Handle * connection
Our connection handle.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:81
configuration data
Definition: configuration.c:83
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:131
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:77
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:1467
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:1017
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.
Definition: strings.c:219
#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:548
#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:900
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:956