GNUnet  0.11.x
gnunet-communicator-tcp.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2010-2014, 2018, 2019 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 
35 #include "platform.h"
36 #include "gnunet_util_lib.h"
37 #include "gnunet_protocols.h"
38 #include "gnunet_signatures.h"
39 #include "gnunet_constants.h"
40 #include "gnunet_nt_lib.h"
41 #include "gnunet_nat_service.h"
44 
49 #define ADDRESS_VALIDITY_PERIOD \
50  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
51 
60 #define DEFAULT_MAX_QUEUE_LENGTH 8
61 
66 #define BUF_SIZE (2 * 64 * 1024 + sizeof(struct TCPBox))
67 
71 #define REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
72 
76 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
77 
82 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
83 
88 #define INITIAL_KX_SIZE \
89  (sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) \
90  + sizeof(struct TCPConfirmation))
91 
92 
96 #define COMMUNICATOR_ADDRESS_PREFIX "tcp"
97 
101 #define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
102 
104 
105 
111 {
116 
121 
126 
131 
137 };
138 
139 
144 {
149 
153  struct GNUNET_CRYPTO_EddsaSignature sender_sig;
154 
159  struct GNUNET_TIME_AbsoluteNBO monotonic_time;
160 };
161 
162 
166 struct TCPBox
167 {
174  struct GNUNET_MessageHeader header;
175 
184  struct GNUNET_ShortHashCode hmac;
185 
186  /* followed by as may bytes of payload as indicated in @e header,
187  excluding the TCPBox itself! */
188 };
189 
190 
195 struct TCPRekey
196 {
200  struct GNUNET_MessageHeader header;
201 
210  struct GNUNET_ShortHashCode hmac;
211 
216 
220  struct GNUNET_CRYPTO_EddsaSignature sender_sig;
221 
226  struct GNUNET_TIME_AbsoluteNBO monotonic_time;
227 };
228 
229 
235 struct TCPFinish
236 {
240  struct GNUNET_MessageHeader header;
241 
250  struct GNUNET_ShortHashCode hmac;
251 };
252 
253 
255 
256 
260 struct Queue
261 {
265  struct GNUNET_PeerIdentity target;
266 
271 
275  gcry_cipher_hd_t in_cipher;
276 
280  gcry_cipher_hd_t out_cipher;
281 
285  struct GNUNET_HashCode in_hmac;
286 
291  struct GNUNET_HashCode out_hmac;
292 
298 
303 
308 
312  struct sockaddr *address;
313 
319 
324  struct GNUNET_TIME_Absolute rekey_time;
325 
329  socklen_t address_len;
330 
335 
340 
344  unsigned long long bytes_in_queue;
345 
349  char cread_buf[BUF_SIZE];
350 
354  char cwrite_buf[BUF_SIZE];
355 
359  char pread_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
360 
364  char pwrite_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
365 
370  size_t cread_off;
371 
376  size_t cwrite_off;
377 
382  size_t pread_off;
383 
388  size_t pwrite_off;
389 
394 
402  unsigned int backpressure;
403 
408 
413 
418 
426 
431  int rekeyed;
432 };
433 
434 
440 {
444  struct ProtoQueue *next;
445 
449  struct ProtoQueue *prev;
450 
455 
460 
464  struct sockaddr *address;
465 
469  socklen_t address_len;
470 
475 
480  char ibuf[INITIAL_KX_SIZE];
481 
485  size_t ibuf_off;
486 };
487 
488 
493 
497 static unsigned long long max_queue_length;
498 
503 
508 
513 
518 
523 
528 
532 static const struct GNUNET_CONFIGURATION_Handle *cfg;
533 
538 
542 static struct GNUNET_NAT_Handle *nat;
543 
547 static struct ProtoQueue *proto_head;
548 
552 static struct ProtoQueue *proto_tail;
553 
554 
562 static void
563 listen_cb (void *cls);
564 
565 
573 static void
575 {
576  struct GNUNET_MQ_Handle *mq;
577 
579  "Disconnecting queue for peer `%s'\n",
580  GNUNET_i2s (&queue->target));
581  if (NULL != (mq = queue->mq))
582  {
583  queue->mq = NULL;
584  GNUNET_MQ_destroy (mq);
585  }
586  if (NULL != queue->qh)
587  {
589  queue->qh = NULL;
590  }
591  GNUNET_assert (
592  GNUNET_YES ==
593  GNUNET_CONTAINER_multipeermap_remove (queue_map, &queue->target, queue));
594  GNUNET_STATISTICS_set (stats,
595  "# queues active",
597  GNUNET_NO);
598  if (NULL != queue->read_task)
599  {
601  queue->read_task = NULL;
602  }
603  if (NULL != queue->write_task)
604  {
606  queue->write_task = NULL;
607  }
609  gcry_cipher_close (queue->in_cipher);
610  gcry_cipher_close (queue->out_cipher);
611  GNUNET_free (queue->address);
612  if (0 != queue->backpressure)
613  queue->destroyed = GNUNET_YES;
614  else
615  GNUNET_free (queue);
616  if (NULL == listen_task)
618  listen_sock,
619  &listen_cb,
620  NULL);
621 }
622 
623 
632 static void
633 calculate_hmac (struct GNUNET_HashCode *hmac_secret,
634  const void *buf,
635  size_t buf_size,
636  struct GNUNET_ShortHashCode *smac)
637 {
638  struct GNUNET_HashCode mac;
639 
640  GNUNET_CRYPTO_hmac_raw (hmac_secret,
641  sizeof(struct GNUNET_HashCode),
642  buf,
643  buf_size,
644  &mac);
645  /* truncate to `struct GNUNET_ShortHashCode` */
646  memcpy (smac, &mac, sizeof(struct GNUNET_ShortHashCode));
647  /* ratchet hmac key */
648  GNUNET_CRYPTO_hash (hmac_secret,
649  sizeof(struct GNUNET_HashCode),
650  hmac_secret);
651 }
652 
653 
660 static void
662 {
663  struct TCPFinish fin;
664 
665  memset (&fin, 0, sizeof(fin));
666  fin.header.size = htons (sizeof(fin));
668  calculate_hmac (&queue->out_hmac, &fin, sizeof(fin), &fin.hmac);
669  /* if there is any message left in pwrite_buf, we
670  overwrite it (possibly dropping the last message
671  from CORE hard here) */
672  memcpy (queue->pwrite_buf, &fin, sizeof(fin));
673  queue->pwrite_off = sizeof(fin);
674  /* This flag will ensure that #queue_write() no longer
675  notifies CORE about the possibility of sending
676  more data, and that #queue_write() will call
677  #queue_destroy() once the @c fin was fully written. */
678  queue->finishing = GNUNET_YES;
679 }
680 
681 
689 static void
691 {
692  queue->timeout =
694 }
695 
696 
702 static void
703 queue_read (void *cls);
704 
705 
713 static void
714 core_read_finished_cb (void *cls, int success)
715 {
716  struct Queue *queue = cls;
717 
718  if (GNUNET_OK != success)
720  "# messages lost in communicator API towards CORE",
721  1,
722  GNUNET_NO);
723  queue->backpressure--;
724  /* handle deferred queue destruction */
725  if ((queue->destroyed) && (0 == queue->backpressure))
726  {
727  GNUNET_free (queue);
728  return;
729  }
730  reschedule_queue_timeout (queue);
731  /* possibly unchoke reading, now that CORE made progress */
732  if (NULL == queue->read_task)
733  queue->read_task =
735  queue->timeout),
736  queue->sock,
737  &queue_read,
738  queue);
739 }
740 
741 
751 static void
753  const void *plaintext,
754  size_t plaintext_len)
755 {
756  const struct GNUNET_MessageHeader *hdr = plaintext;
757  int ret;
758 
759  if (ntohs (hdr->size) != plaintext_len)
760  {
761  /* NOTE: If we ever allow multiple CORE messages in one
762  BOX, this will have to change! */
763  GNUNET_break (0);
764  return;
765  }
767  &queue->target,
768  hdr,
771  queue);
772  if (GNUNET_OK == ret)
773  queue->backpressure++;
774  GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
775  if (GNUNET_SYSERR == ret)
777  "# bytes lost due to CORE not running",
778  plaintext_len,
779  GNUNET_NO);
780 }
781 
782 
792 static void
793 setup_cipher (const struct GNUNET_HashCode *dh,
794  const struct GNUNET_PeerIdentity *pid,
795  gcry_cipher_hd_t *cipher,
796  struct GNUNET_HashCode *hmac_key)
797 {
798  char key[256 / 8];
799  char ctr[128 / 8];
800 
801  gcry_cipher_open (cipher,
802  GCRY_CIPHER_AES256 /* low level: go for speed */,
803  GCRY_CIPHER_MODE_CTR,
804  0 /* flags */);
806  sizeof(key),
807  "TCP-key",
808  strlen ("TCP-key"),
809  dh,
810  sizeof(*dh),
811  pid,
812  sizeof(*pid),
813  NULL,
814  0));
815  gcry_cipher_setkey (*cipher, key, sizeof(key));
817  sizeof(ctr),
818  "TCP-ctr",
819  strlen ("TCP-ctr"),
820  dh,
821  sizeof(*dh),
822  pid,
823  sizeof(*pid),
824  NULL,
825  0));
826  gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
828  GNUNET_CRYPTO_kdf (hmac_key,
829  sizeof(struct GNUNET_HashCode),
830  "TCP-hmac",
831  strlen ("TCP-hmac"),
832  dh,
833  sizeof(*dh),
834  pid,
835  sizeof(*pid),
836  NULL,
837  0));
838 }
839 
840 
847 static void
849  struct Queue *queue)
850 {
851  struct GNUNET_HashCode dh;
852 
853  GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &dh);
854  setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac);
855 }
856 
857 
866 static void
867 do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
868 {
869  struct TcpHandshakeSignature thp;
870 
872  thp.purpose.size = htonl (sizeof(thp));
873  thp.sender = queue->target;
874  thp.receiver = my_identity;
875  thp.ephemeral = rekey->ephemeral;
876  thp.monotonic_time = rekey->monotonic_time;
877  /* FIXME: check monotonic time is monotonic... */
878  if (GNUNET_OK !=
880  &thp.purpose,
881  &rekey->sender_sig,
882  &queue->target.public_key))
883  {
884  GNUNET_break (0);
885  queue_finish (queue);
886  return;
887  }
888  gcry_cipher_close (queue->in_cipher);
889  queue->rekeyed = GNUNET_YES;
890  setup_in_cipher (&rekey->ephemeral, queue);
891 }
892 
893 
901 static size_t
903 {
904  const struct GNUNET_MessageHeader *hdr =
905  (const struct GNUNET_MessageHeader *) queue->pread_buf;
906  const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf;
907  const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf;
908  const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf;
909  struct TCPRekey rekeyz;
910  struct TCPFinish finz;
911  struct GNUNET_ShortHashCode tmac;
912  uint16_t type;
913  size_t size = 0; /* make compiler happy */
914 
915  if (sizeof(*hdr) > queue->pread_off)
916  return 0; /* not even a header */
917  type = ntohs (hdr->type);
918  switch (type)
919  {
921  /* Special case: header size excludes box itself! */
922  if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
923  return 0;
924  calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
925  if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
926  {
927  GNUNET_break_op (0);
928  queue_finish (queue);
929  return 0;
930  }
931  pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
932  size = ntohs (hdr->size) + sizeof(*box);
933  break;
934 
936  if (sizeof(*rekey) > queue->pread_off)
937  return 0;
938  if (ntohs (hdr->size) != sizeof(*rekey))
939  {
940  GNUNET_break_op (0);
941  queue_finish (queue);
942  return 0;
943  }
944  rekeyz = *rekey;
945  memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
946  calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
947  if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
948  {
949  GNUNET_break_op (0);
950  queue_finish (queue);
951  return 0;
952  }
953  do_rekey (queue, rekey);
954  size = ntohs (hdr->size);
955  break;
956 
958  if (sizeof(*fin) > queue->pread_off)
959  return 0;
960  if (ntohs (hdr->size) != sizeof(*fin))
961  {
962  GNUNET_break_op (0);
963  queue_finish (queue);
964  return 0;
965  }
966  finz = *fin;
967  memset (&finz.hmac, 0, sizeof(finz.hmac));
968  calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
969  if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
970  {
971  GNUNET_break_op (0);
972  queue_finish (queue);
973  return 0;
974  }
975  /* handle FINISH by destroying queue */
976  queue_destroy (queue);
977  break;
978 
979  default:
980  GNUNET_break_op (0);
981  queue_finish (queue);
982  return 0;
983  }
984  GNUNET_assert (0 != size);
985  return size;
986 }
987 
988 
994 static void
995 queue_read (void *cls)
996 {
997  struct Queue *queue = cls;
998  struct GNUNET_TIME_Relative left;
999  ssize_t rcvd;
1000 
1001  queue->read_task = NULL;
1002  rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1003  &queue->cread_buf[queue->cread_off],
1004  BUF_SIZE - queue->cread_off);
1005  if (-1 == rcvd)
1006  {
1007  if ((EAGAIN != errno) && (EINTR != errno))
1008  {
1010  queue_finish (queue);
1011  return;
1012  }
1013  /* try again */
1014  queue->read_task =
1015  GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
1016  return;
1017  }
1018  if (0 != rcvd)
1019  reschedule_queue_timeout (queue);
1020  queue->cread_off += rcvd;
1021  while ((queue->pread_off < sizeof(queue->pread_buf)) &&
1022  (queue->cread_off > 0))
1023  {
1024  size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
1025  queue->cread_off);
1026  size_t done;
1027  size_t total;
1028 
1029  GNUNET_assert (0 ==
1030  gcry_cipher_decrypt (queue->in_cipher,
1031  &queue->pread_buf[queue->pread_off],
1032  max,
1033  queue->cread_buf,
1034  max));
1035  queue->pread_off += max;
1036  total = 0;
1037  while ((GNUNET_NO == queue->rekeyed) &&
1038  (0 != (done = try_handle_plaintext (queue))))
1039  {
1040  /* 'done' bytes of plaintext were used, shift buffer */
1041  GNUNET_assert (done <= queue->pread_off);
1042  /* NOTE: this memmove() could possibly sometimes be
1043  avoided if we pass 'total' into try_handle_plaintext()
1044  and use it at an offset into the buffer there! */
1045  memmove (queue->pread_buf,
1046  &queue->pread_buf[done],
1047  queue->pread_off - done);
1048  queue->pread_off -= done;
1049  total += done;
1050  }
1051  /* when we encounter a rekey message, the decryption above uses the
1052  wrong key for everything after the rekey; in that case, we have
1053  to re-do the decryption at 'total' instead of at 'max'. If there
1054  is no rekey and the last message is incomplete (max > total),
1055  it is safe to keep the decryption so we shift by 'max' */if (GNUNET_YES == queue->rekeyed)
1056  {
1057  max = total;
1058  queue->rekeyed = GNUNET_NO;
1059  }
1060  memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
1061  queue->cread_off -= max;
1062  }
1063 
1064  if (BUF_SIZE == queue->cread_off)
1065  return; /* buffer full, suspend reading */
1067  if (0 != left.rel_value_us)
1068  {
1069  if (max_queue_length < queue->backpressure)
1070  {
1071  /* continue reading */
1072  queue->read_task =
1073  GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read, queue);
1074  }
1075  return;
1076  }
1078  "Queue %p was idle for %s, disconnecting\n",
1079  queue,
1082  GNUNET_YES));
1083  queue_finish (queue);
1084 }
1085 
1086 
1094 static struct sockaddr *
1095 tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
1096 {
1097  struct sockaddr *in;
1098  unsigned int port;
1099  char dummy[2];
1100  char *colon;
1101  char *cp;
1102 
1103  if (1 == sscanf (bindto, "%u%1s", &port, dummy))
1104  {
1105  /* interpreting value as just a PORT number */
1106  if (port > UINT16_MAX)
1107  {
1109  "BINDTO specification `%s' invalid: value too large for port\n",
1110  bindto);
1111  return NULL;
1112  }
1113  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
1114  (GNUNET_YES ==
1117  "DISABLE_V6")))
1118  {
1119  struct sockaddr_in *i4;
1120 
1121  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
1122  i4->sin_family = AF_INET;
1123  i4->sin_port = htons ((uint16_t) port);
1124  *sock_len = sizeof(struct sockaddr_in);
1125  in = (struct sockaddr *) i4;
1126  }
1127  else
1128  {
1129  struct sockaddr_in6 *i6;
1130 
1131  i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
1132  i6->sin6_family = AF_INET6;
1133  i6->sin6_port = htons ((uint16_t) port);
1134  *sock_len = sizeof(struct sockaddr_in6);
1135  in = (struct sockaddr *) i6;
1136  }
1137  return in;
1138  }
1139  cp = GNUNET_strdup (bindto);
1140  colon = strrchr (cp, ':');
1141  if (NULL != colon)
1142  {
1143  /* interpet value after colon as port */
1144  *colon = '\0';
1145  colon++;
1146  if (1 == sscanf (colon, "%u%1s", &port, dummy))
1147  {
1148  /* interpreting value as just a PORT number */
1149  if (port > UINT16_MAX)
1150  {
1152  "BINDTO specification `%s' invalid: value too large for port\n",
1153  bindto);
1154  GNUNET_free (cp);
1155  return NULL;
1156  }
1157  }
1158  else
1159  {
1160  GNUNET_log (
1162  "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1163  bindto);
1164  GNUNET_free (cp);
1165  return NULL;
1166  }
1167  }
1168  else
1169  {
1170  /* interpret missing port as 0, aka pick any free one */
1171  port = 0;
1172  }
1173  {
1174  /* try IPv4 */
1175  struct sockaddr_in v4;
1176 
1177  if (1 == inet_pton (AF_INET, cp, &v4))
1178  {
1179  v4.sin_port = htons ((uint16_t) port);
1180  in = GNUNET_memdup (&v4, sizeof(v4));
1181  *sock_len = sizeof(v4);
1182  GNUNET_free (cp);
1183  return in;
1184  }
1185  }
1186  {
1187  /* try IPv6 */
1188  struct sockaddr_in6 v6;
1189  const char *start;
1190 
1191  start = cp;
1192  if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
1193  {
1194  start++; /* skip over '[' */
1195  cp[strlen (cp) - 1] = '\0'; /* eat ']' */
1196  }
1197  if (1 == inet_pton (AF_INET6, start, &v6))
1198  {
1199  v6.sin6_port = htons ((uint16_t) port);
1200  in = GNUNET_memdup (&v6, sizeof(v6));
1201  *sock_len = sizeof(v6);
1202  GNUNET_free (cp);
1203  return in;
1204  }
1205  }
1206  /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
1207  GNUNET_free (cp);
1208  return NULL;
1209 }
1210 
1211 
1218 static void
1220 {
1221  struct GNUNET_HashCode dh;
1222 
1223  GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral, &queue->target.public_key, &dh);
1224  /* we don't need the private key anymore, drop it! */
1225  memset (&queue->ephemeral, 0, sizeof(queue->ephemeral));
1226  setup_cipher (&dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1228  queue->rekey_left_bytes =
1230 }
1231 
1232 
1239 static void
1241 {
1242  struct TCPRekey rekey;
1243  struct TcpHandshakeSignature thp;
1244 
1245  GNUNET_assert (0 == queue->pwrite_off);
1246  memset (&rekey, 0, sizeof(rekey));
1250  rekey.header.size = ntohs (sizeof(rekey));
1252  rekey.monotonic_time =
1255  thp.purpose.size = htonl (sizeof(thp));
1256  thp.sender = my_identity;
1257  thp.receiver = queue->target;
1258  thp.ephemeral = rekey.ephemeral;
1259  thp.monotonic_time = rekey.monotonic_time;
1260  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_private_key,
1261  &thp.purpose,
1262  &rekey.sender_sig));
1263  calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1264  memcpy (queue->pwrite_buf, &rekey, sizeof(rekey));
1265  queue->pwrite_off = sizeof(rekey);
1266 }
1267 
1268 
1275 static void
1276 queue_write (void *cls)
1277 {
1278  struct Queue *queue = cls;
1279  ssize_t sent;
1280 
1281  queue->write_task = NULL;
1282  if (0 != queue->cwrite_off)
1283  {
1284  sent = GNUNET_NETWORK_socket_send (queue->sock,
1285  queue->cwrite_buf,
1286  queue->cwrite_off);
1287  if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1288  {
1290  queue_destroy (queue);
1291  return;
1292  }
1293  if (sent > 0)
1294  {
1295  size_t usent = (size_t) sent;
1296 
1297  memmove (queue->cwrite_buf,
1298  &queue->cwrite_buf[usent],
1299  queue->cwrite_off - usent);
1300  reschedule_queue_timeout (queue);
1301  }
1302  }
1303  /* can we encrypt more? (always encrypt full messages, needed
1304  such that #mq_cancel() can work!) */
1305  if ((0 < queue->rekey_left_bytes) &&
1306  (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1307  {
1308  GNUNET_assert (0 ==
1309  gcry_cipher_encrypt (queue->out_cipher,
1310  &queue->cwrite_buf[queue->cwrite_off],
1311  queue->pwrite_off,
1312  queue->pwrite_buf,
1313  queue->pwrite_off));
1314  if (queue->rekey_left_bytes > queue->pwrite_off)
1315  queue->rekey_left_bytes -= queue->pwrite_off;
1316  else
1317  queue->rekey_left_bytes = 0;
1318  queue->cwrite_off += queue->pwrite_off;
1319  queue->pwrite_off = 0;
1320  }
1321  if ((0 == queue->pwrite_off) &&
1322  ((0 == queue->rekey_left_bytes) ||
1323  (0 ==
1325  {
1326  gcry_cipher_close (queue->out_cipher);
1327  setup_out_cipher (queue);
1328  inject_rekey (queue);
1329  }
1330  if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1331  (queue->mq_awaits_continue))
1332  {
1333  queue->mq_awaits_continue = GNUNET_NO;
1335  }
1336  /* did we just finish writing 'finish'? */
1337  if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1338  {
1339  queue_destroy (queue);
1340  return;
1341  }
1342  /* do we care to write more? */
1343  if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1344  queue->write_task =
1346  queue->sock,
1347  &queue_write,
1348  queue);
1349 }
1350 
1351 
1360 static void
1362  const struct GNUNET_MessageHeader *msg,
1363  void *impl_state)
1364 {
1365  struct Queue *queue = impl_state;
1366  uint16_t msize = ntohs (msg->size);
1367  struct TCPBox box;
1368 
1369  GNUNET_assert (mq == queue->mq);
1370  if (GNUNET_YES == queue->finishing)
1371  return; /* this queue is dying, drop msg */
1372  GNUNET_assert (0 == queue->pread_off);
1374  box.header.size = htons (msize);
1375  calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
1376  memcpy (&queue->pread_buf[queue->pread_off], &box, sizeof(box));
1377  queue->pread_off += sizeof(box);
1378  memcpy (&queue->pread_buf[queue->pread_off], msg, msize);
1379  queue->pread_off += msize;
1380  GNUNET_assert (NULL != queue->sock);
1381  if (NULL == queue->write_task)
1382  queue->write_task =
1384  queue->sock,
1385  &queue_write,
1386  queue);
1387 }
1388 
1389 
1398 static void
1399 mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
1400 {
1401  struct Queue *queue = impl_state;
1402 
1403  if (mq == queue->mq)
1404  {
1405  queue->mq = NULL;
1406  queue_finish (queue);
1407  }
1408 }
1409 
1410 
1417 static void
1418 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
1419 {
1420  struct Queue *queue = impl_state;
1421 
1422  GNUNET_assert (0 != queue->pwrite_off);
1423  queue->pwrite_off = 0;
1424 }
1425 
1426 
1436 static void
1437 mq_error (void *cls, enum GNUNET_MQ_Error error)
1438 {
1439  struct Queue *queue = cls;
1440 
1442  "MQ error in queue to %s: %d\n",
1443  GNUNET_i2s (&queue->target),
1444  (int) error);
1445  queue_finish (queue);
1446 }
1447 
1448 
1456 static void
1458 {
1459  queue->nt =
1460  GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
1462  queue_map,
1463  &queue->target,
1464  queue,
1466  GNUNET_STATISTICS_set (stats,
1467  "# queues active",
1469  GNUNET_NO);
1470  queue->timeout =
1473  &mq_destroy,
1474  &mq_cancel,
1475  queue,
1476  NULL,
1477  &mq_error,
1478  queue);
1479  {
1480  char *foreign_addr;
1481 
1482  switch (queue->address->sa_family)
1483  {
1484  case AF_INET:
1485  GNUNET_asprintf (&foreign_addr,
1486  "%s-%s",
1488  GNUNET_a2s (queue->address, queue->address_len));
1489  break;
1490 
1491  case AF_INET6:
1492  GNUNET_asprintf (&foreign_addr,
1493  "%s-%s",
1495  GNUNET_a2s (queue->address, queue->address_len));
1496  break;
1497 
1498  default:
1499  GNUNET_assert (0);
1500  }
1502  &queue->target,
1503  foreign_addr,
1504  0 /* no MTU */,
1505  queue->nt,
1506  cs,
1507  queue->mq);
1508  GNUNET_free (foreign_addr);
1509  }
1510 }
1511 
1512 
1523 static void
1525  const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1526 {
1527  struct TcpHandshakeSignature ths;
1528  struct TCPConfirmation tc;
1529 
1530  memcpy (queue->cwrite_buf, epub, sizeof(*epub));
1531  queue->cwrite_off = sizeof(epub);
1532  /* compute 'tc' and append in encrypted format to cwrite_buf */
1533  tc.sender = my_identity;
1534  tc.monotonic_time =
1537  ths.purpose.size = htonl (sizeof(ths));
1538  ths.sender = my_identity;
1539  ths.receiver = queue->target;
1540  ths.ephemeral = *epub;
1541  ths.monotonic_time = tc.monotonic_time;
1542  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (my_private_key,
1543  &ths.purpose,
1544  &tc.sender_sig));
1545  GNUNET_assert (0 ==
1546  gcry_cipher_encrypt (queue->out_cipher,
1547  &queue->cwrite_buf[queue->cwrite_off],
1548  sizeof(tc),
1549  &tc,
1550  sizeof(tc)));
1551  queue->cwrite_off += sizeof(tc);
1552 }
1553 
1554 
1562 static void
1564 {
1565  struct GNUNET_CRYPTO_EcdhePublicKey epub;
1566 
1570  setup_out_cipher (queue);
1571  transmit_kx (queue, &epub);
1572 }
1573 
1574 
1586 static int
1588  struct TCPConfirmation *tc,
1589  char *ibuf)
1590 {
1591  struct TcpHandshakeSignature ths;
1592 
1593  GNUNET_assert (
1594  0 ==
1595  gcry_cipher_decrypt (queue->in_cipher,
1596  tc,
1597  sizeof(*tc),
1598  &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
1599  sizeof(tc)));
1601  ths.purpose.size = htonl (sizeof(ths));
1602  ths.sender = tc->sender;
1603  ths.receiver = my_identity;
1604  memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
1605  ths.monotonic_time = tc->monotonic_time;
1606  /* FIXME: check monotonic time against previous mono times
1607  from this sender! */
1610  &ths.purpose,
1611  &tc->sender_sig,
1612  &tc->sender.public_key);
1613 }
1614 
1615 
1621 static void
1623 {
1625  GNUNET_free (pq->address);
1626  GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
1627  GNUNET_free (pq);
1628 }
1629 
1630 
1637 static void
1638 proto_read_kx (void *cls)
1639 {
1640  struct ProtoQueue *pq = cls;
1641  ssize_t rcvd;
1642  struct GNUNET_TIME_Relative left;
1643  struct Queue *queue;
1644  struct TCPConfirmation tc;
1645 
1646  pq->read_task = NULL;
1648  if (0 == left.rel_value_us)
1649  {
1650  free_proto_queue (pq);
1651  return;
1652  }
1653  rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
1654  &pq->ibuf[pq->ibuf_off],
1655  sizeof(pq->ibuf) - pq->ibuf_off);
1656  if (-1 == rcvd)
1657  {
1658  if ((EAGAIN != errno) && (EINTR != errno))
1659  {
1661  free_proto_queue (pq);
1662  return;
1663  }
1664  /* try again */
1665  pq->read_task =
1667  return;
1668  }
1669  pq->ibuf_off += rcvd;
1670  if (pq->ibuf_off > sizeof(pq->ibuf))
1671  {
1672  /* read more */
1673  pq->read_task =
1675  return;
1676  }
1677  /* we got all the data, let's find out who we are talking to! */
1678  queue = GNUNET_new (struct Queue);
1679  setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
1680  queue);
1681  if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
1682  {
1684  "Invalid TCP KX received from %s\n",
1685  GNUNET_a2s (queue->address, queue->address_len));
1686  gcry_cipher_close (queue->in_cipher);
1687  GNUNET_free (queue);
1688  free_proto_queue (pq);
1689  return;
1690  }
1691  queue->address = pq->address; /* steals reference */
1692  queue->address_len = pq->address_len;
1693  queue->target = tc.sender;
1694  start_initial_kx_out (queue);
1696  queue->read_task =
1698  queue->sock,
1699  &queue_read,
1700  queue);
1701  queue->write_task =
1703  queue->sock,
1704  &queue_write,
1705  queue);
1706  GNUNET_CONTAINER_DLL_remove (proto_head, proto_tail, pq);
1707  GNUNET_free (pq);
1708 }
1709 
1710 
1718 static void
1719 listen_cb (void *cls)
1720 {
1721  struct sockaddr_storage in;
1722  socklen_t addrlen;
1723  struct GNUNET_NETWORK_Handle *sock;
1724  struct ProtoQueue *pq;
1725 
1726  listen_task = NULL;
1727  GNUNET_assert (NULL != listen_sock);
1728  addrlen = sizeof(in);
1729  memset (&in, 0, sizeof(in));
1730  sock = GNUNET_NETWORK_socket_accept (listen_sock,
1731  (struct sockaddr *) &in,
1732  &addrlen);
1733  if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
1734  return; /* system limit reached, wait until connection goes down */
1736  listen_sock,
1737  &listen_cb,
1738  NULL);
1739  if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
1740  return;
1741  if (NULL == sock)
1742  {
1744  return;
1745  }
1746  pq = GNUNET_new (struct ProtoQueue);
1747  pq->address_len = addrlen;
1748  pq->address = GNUNET_memdup (&in, addrlen);
1750  pq->sock = sock;
1752  pq->sock,
1753  &proto_read_kx,
1754  pq);
1755  GNUNET_CONTAINER_DLL_insert (proto_head, proto_tail, pq);
1756 }
1757 
1758 
1766 static void
1767 queue_read_kx (void *cls)
1768 {
1769  struct Queue *queue = cls;
1770  ssize_t rcvd;
1771  struct GNUNET_TIME_Relative left;
1772  struct TCPConfirmation tc;
1773 
1774  queue->read_task = NULL;
1776  if (0 == left.rel_value_us)
1777  {
1778  queue_destroy (queue);
1779  return;
1780  }
1781  rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1782  &queue->cread_buf[queue->cread_off],
1783  BUF_SIZE - queue->cread_off);
1784  if (-1 == rcvd)
1785  {
1786  if ((EAGAIN != errno) && (EINTR != errno))
1787  {
1789  queue_destroy (queue);
1790  return;
1791  }
1792  queue->read_task =
1793  GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
1794  return;
1795  }
1796  queue->cread_off += rcvd;
1797  if (queue->cread_off < INITIAL_KX_SIZE)
1798  {
1799  /* read more */
1800  queue->read_task =
1801  GNUNET_SCHEDULER_add_read_net (left, queue->sock, &queue_read_kx, queue);
1802  return;
1803  }
1804  /* we got all the data, let's find out who we are talking to! */
1806  queue->cread_buf,
1807  queue);
1808  if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
1809  {
1811  "Invalid TCP KX received from %s\n",
1812  GNUNET_a2s (queue->address, queue->address_len));
1813  queue_destroy (queue);
1814  return;
1815  }
1816  if (0 !=
1817  memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
1818  {
1820  "Invalid sender in TCP KX received from %s\n",
1821  GNUNET_a2s (queue->address, queue->address_len));
1822  queue_destroy (queue);
1823  return;
1824  }
1825 
1826  /* update queue timeout */
1827  reschedule_queue_timeout (queue);
1828  /* prepare to continue with regular read task immediately */
1829  memmove (queue->cread_buf,
1830  &queue->cread_buf[INITIAL_KX_SIZE],
1831  queue->cread_off - (INITIAL_KX_SIZE));
1832  queue->cread_off -= INITIAL_KX_SIZE;
1833  queue->read_task = GNUNET_SCHEDULER_add_now (&queue_read, queue);
1834 }
1835 
1836 
1855 static int
1856 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
1857 {
1858  struct Queue *queue;
1859  const char *path;
1860  struct sockaddr *in;
1861  socklen_t in_len;
1862  struct GNUNET_NETWORK_Handle *sock;
1863 
1864  if (0 != strncmp (address,
1866  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1867  {
1868  GNUNET_break_op (0);
1869  return GNUNET_SYSERR;
1870  }
1871  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1872  in = tcp_address_to_sockaddr (path, &in_len);
1873 
1874  sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP);
1875  if (NULL == sock)
1876  {
1878  "socket(%d) failed: %s",
1879  in->sa_family,
1880  strerror (errno));
1881  GNUNET_free (in);
1882  return GNUNET_SYSERR;
1883  }
1884  if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len))
1885  {
1887  "connect to `%s' failed: %s",
1888  address,
1889  strerror (errno));
1891  GNUNET_free (in);
1892  return GNUNET_SYSERR;
1893  }
1894 
1895  queue = GNUNET_new (struct Queue);
1896  queue->target = *peer;
1897  queue->address = in;
1898  queue->address_len = in_len;
1899  queue->sock = sock;
1901  queue->read_task =
1903  queue->sock,
1904  &queue_read_kx,
1905  queue);
1906  start_initial_kx_out (queue);
1907  queue->write_task =
1909  queue->sock,
1910  &queue_write,
1911  queue);
1912  return GNUNET_OK;
1913 }
1914 
1915 
1924 static int
1926  const struct GNUNET_PeerIdentity *target,
1927  void *value)
1928 {
1929  struct Queue *queue = value;
1930 
1931  (void) cls;
1932  (void) target;
1933  queue_destroy (queue);
1934  return GNUNET_OK;
1935 }
1936 
1937 
1943 static void
1944 do_shutdown (void *cls)
1945 {
1946  while (NULL != proto_head)
1947  free_proto_queue (proto_head);
1948  if (NULL != nat)
1949  {
1950  GNUNET_NAT_unregister (nat);
1951  nat = NULL;
1952  }
1953  if (NULL != listen_task)
1954  {
1955  GNUNET_SCHEDULER_cancel (listen_task);
1956  listen_task = NULL;
1957  }
1958  if (NULL != listen_sock)
1959  {
1961  listen_sock = NULL;
1962  }
1965  if (NULL != ch)
1966  {
1968  ch = NULL;
1969  }
1970  if (NULL != stats)
1971  {
1973  stats = NULL;
1974  }
1975  if (NULL != my_private_key)
1976  {
1977  GNUNET_free (my_private_key);
1978  my_private_key = NULL;
1979  }
1980  if (NULL != is)
1981  {
1983  is = NULL;
1984  }
1985 }
1986 
1987 
1999 static void
2000 enc_notify_cb (void *cls,
2001  const struct GNUNET_PeerIdentity *sender,
2002  const struct GNUNET_MessageHeader *msg)
2003 {
2004  (void) cls;
2005  (void) sender;
2006  (void) msg;
2007  GNUNET_break_op (0);
2008 }
2009 
2010 
2024 static void
2025 nat_address_cb (void *cls,
2026  void **app_ctx,
2027  int add_remove,
2029  const struct sockaddr *addr,
2030  socklen_t addrlen)
2031 {
2032  char *my_addr;
2034 
2035  if (GNUNET_YES == add_remove)
2036  {
2037  enum GNUNET_NetworkType nt;
2038 
2039  GNUNET_asprintf (&my_addr,
2040  "%s-%s",
2042  GNUNET_a2s (addr, addrlen));
2043  nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
2044  ai =
2046  my_addr,
2047  nt,
2049  GNUNET_free (my_addr);
2050  *app_ctx = ai;
2051  }
2052  else
2053  {
2054  ai = *app_ctx;
2056  *app_ctx = NULL;
2057  }
2058 }
2059 
2060 
2069 static void
2070 run (void *cls,
2071  char *const *args,
2072  const char *cfgfile,
2073  const struct GNUNET_CONFIGURATION_Handle *c)
2074 {
2075  char *bindto;
2076  struct sockaddr *in;
2077  socklen_t in_len;
2078  struct sockaddr_storage in_sto;
2079  socklen_t sto_len;
2080 
2081  (void) cls;
2082  cfg = c;
2083  if (GNUNET_OK !=
2086  "BINDTO",
2087  &bindto))
2088  {
2091  "BINDTO");
2092  return;
2093  }
2094  if (GNUNET_OK !=
2097  "MAX_QUEUE_LENGTH",
2098  &max_queue_length))
2100 
2101  in = tcp_address_to_sockaddr (bindto, &in_len);
2102  if (NULL == in)
2103  {
2105  "Failed to setup TCP socket address with path `%s'\n",
2106  bindto);
2107  GNUNET_free (bindto);
2108  return;
2109  }
2110  listen_sock =
2111  GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP);
2112  if (NULL == listen_sock)
2113  {
2115  GNUNET_free (in);
2116  GNUNET_free (bindto);
2117  return;
2118  }
2119  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, in, in_len))
2120  {
2122  GNUNET_NETWORK_socket_close (listen_sock);
2123  listen_sock = NULL;
2124  GNUNET_free (in);
2125  GNUNET_free (bindto);
2126  return;
2127  }
2128  /* We might have bound to port 0, allowing the OS to figure it out;
2129  thus, get the real IN-address from the socket */
2130  sto_len = sizeof(in_sto);
2131  if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
2132  (struct sockaddr *) &in_sto,
2133  &sto_len))
2134  {
2135  memcpy (&in_sto, in, in_len);
2136  sto_len = in_len;
2137  }
2138  GNUNET_free (in);
2139  GNUNET_free (bindto);
2140  in = (struct sockaddr *) &in_sto;
2141  in_len = sto_len;
2143  "Bound to `%s'\n",
2144  GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
2145  stats = GNUNET_STATISTICS_create ("C-TCP", cfg);
2147  is = GNUNET_NT_scanner_init ();
2149  if (NULL == my_private_key)
2150  {
2151  GNUNET_log (
2153  _ (
2154  "Transport service is lacking key configuration settings. Exiting.\n"));
2156  return;
2157  }
2159  /* start listening */
2161  listen_sock,
2162  &listen_cb,
2163  NULL);
2169  &mq_init,
2170  NULL,
2171  &enc_notify_cb,
2172  NULL);
2173  if (NULL == ch)
2174  {
2175  GNUNET_break (0);
2177  return;
2178  }
2179  nat = GNUNET_NAT_register (cfg,
2181  IPPROTO_TCP,
2182  1 /* one address */,
2183  (const struct sockaddr **) &in,
2184  &in_len,
2185  &nat_address_cb,
2186  NULL /* FIXME: support reversal: #5529 */,
2187  NULL /* closure */);
2188 }
2189 
2190 
2198 int
2199 main (int argc, char *const *argv)
2200 {
2201  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2203  };
2204  int ret;
2205 
2206  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
2207  return 2;
2208 
2209  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
2210  argv,
2211  "gnunet-communicator-tcp",
2212  _ ("GNUnet TCP communicator"),
2213  options,
2214  &run,
2215  NULL))
2216  ? 0
2217  : 1;
2218  GNUNET_free ((void *) argv);
2219  return ret;
2220 }
2221 
2222 
2223 /* end of gnunet-communicator-tcp.c */
#define GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE
Signature used by TCP communicator handshake,.
int GNUNET_CRYPTO_ecdhe_key_create2(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:630
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static void queue(const char *hostname)
Add hostname to the list of requests to be made.
Handle to the interface scanner.
Definition: nt.c:110
int rekeyed
GNUNET_YES if we just rekeyed and must thus possibly re-decrypt ciphertext.
char ibuf[(sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof(struct TCPConfirmation))]
Buffer for reading all the information we need to upgrade from protoqueue to queue.
static void listen_cb(void *cls)
We have been notified that our listen socket has something to read.
Transmission is reliabile (with ACKs), i.e.
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1080
static void setup_in_cipher(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct Queue *queue)
Setup cipher of queue for decryption.
static void queue_read_kx(void *cls)
Read from the socket of the queue until we have enough data to initialize the decryption logic and ca...
char cread_buf[(2 *64 *1024+sizeof(struct TCPBox))]
Buffer for reading ciphertext from network into.
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition: nt.c:314
static void done()
Handle for active NAT registrations.
Definition: nat_api.c:71
static void boot_queue(struct Queue *queue, enum GNUNET_TRANSPORT_ConnectionStatus cs)
Add the given queue to our internal data structure.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_PeerIdentity target
To whom are we talking to.
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
static void core_read_finished_cb(void *cls, int success)
Core tells us it is done processing a message that transport received on a queue with status success...
uint64_t rel_value_us
The actual value.
int main(int argc, char *const *argv)
The main function for the UNIX communicator.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
int finishing
Did we enqueue a finish message and are closing down the queue?
struct GNUNET_HashCode in_hmac
Shared secret for HMAC verification on incoming data.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
socklen_t address_len
Length of the address.
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:816
static struct GNUNET_PeerIdentity my_identity
Our public key.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
size_t cread_off
At which offset in the ciphertext read buffer should we append more ciphertext for transmission next...
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer...
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key used by the sender.
void GNUNET_CRYPTO_hmac_raw(const void *key, size_t key_len, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104) TODO: Shouldn&#39; this be the standard hmac function and the abov...
Definition: crypto_hash.c:403
struct GNUNET_PeerIdentity sender
Sender&#39;s identity.
GNUNET_MQ_Error
Error codes for the queue.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender&#39;s signature of type GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE.
unsigned int backpressure
How may messages did we pass from this queue to CORE for which we have yet to receive an acknoweldgem...
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:787
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
#define GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY
Signature used by TCP communicator rekey.
int destroyed
Did we technically destroy this queue, but kept the allocation around because of backpressure not bei...
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1438
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_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY
TCP communicator rekey message.
static struct GNUNET_SCHEDULER_Task * listen_task
ID of listen task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void proto_read_kx(void *cls)
Read from the socket of the proto queue until we have enough data to upgrade to full queue...
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:418
uint64_t rekey_left_bytes
How many more bytes may we sent with the current out_cipher before we should rekey?
#define BUF_SIZE
Size of our IO buffers for ciphertext data.
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:485
int GNUNET_CRYPTO_eddsa_sign(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:986
#define PROTO_QUEUE_TIMEOUT
How long do we wait until we must have received the initial KX?
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:1557
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static void pass_plaintext_to_core(struct Queue *queue, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext on queue.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_TIME_Absolute rekey_time
Until what time may we sent with the current out_cipher before we should rekey?
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
static void transmit_kx(struct Queue *queue, const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
Generate and transmit our ephemeral key and the signature for the initial KX with the other peer...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral
Our ephemeral key.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX
TCP communicator payload box.
static void calculate_hmac(struct GNUNET_HashCode *hmac_secret, const void *buf, size_t buf_size, struct GNUNET_ShortHashCode *smac)
Compute mac over buf, and ratched the hmac_secret.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
Handle for the service.
static void queue_read(void *cls)
Queue read task.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
struct GNUNET_MQ_Handle * mq
Message queue we are providing for the ch.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:35
Handle for an incoming connection where we do not yet have enough information to setup a full queue...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue&#39;s plaintext buffer.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
A 256-bit hashcode.
Opaque handle to the transport service for communicators.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
static int decrypt_and_check_tc(struct Queue *queue, struct TCPConfirmation *tc, char *ibuf)
We have received the first bytes from the other side on a queue.
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:430
Signature we use to verify that the ephemeral key was really chosen by the specified sender...
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
static unsigned long long max_queue_length
Maximum queue length before we stop reading towards the transport service.
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
#define INITIAL_KX_SIZE
Size of the initial key exchange message sent first in both directions.
struct GNUNET_HashCode out_hmac
Shared secret for HMAC generation on outgoing data, ratcheted after each operation.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received an acknowledgement for this communicator (!) ...
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:658
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
unsigned long long bytes_in_queue
Number of bytes we currently have in our write queue.
static struct GNUNET_CONTAINER_MultiPeerMap * queue_map
Queues (map from peer identity to struct Queue)
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:552
int GNUNET_CRYPTO_eddsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:1113
static void queue_destroy(struct Queue *queue)
Functions with this signature are called whenever we need to close a queue due to a disconnect or fai...
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
int GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition: crypto_ecc.c:1502
static char * value
Value of the record to add/remove.
Handle for a queue.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
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:1280
size_t cwrite_off
At which offset in the ciphertext write buffer should we append more ciphertext from reading next...
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
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:687
static char buf[2048]
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls)
Connect to the transport service.
static void setup_cipher(const struct GNUNET_HashCode *dh, const struct GNUNET_PeerIdentity *pid, gcry_cipher_hd_t *cipher, struct GNUNET_HashCode *hmac_key)
Setup cipher based on shared secret dh and decrypting peer pid.
this is an inbound connection (communicator initiated)
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void reschedule_queue_timeout(struct Queue *queue)
Increment queue timeout due to activity.
static void queue_finish(struct Queue *queue)
Append a &#39;finish&#39; message to the outgoing transmission.
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)...
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
struct GNUNET_NETWORK_Handle * sock
socket that we transmit all data with on this queue
struct GNUNET_TIME_Absolute timeout
Timeout for this protoqueue.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
Internal representation of the hash map.
struct GNUNET_SCHEDULER_Task * write_task
ID of write task for this connection.
struct sockaddr * address
Address of the other peer.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
A 512-bit hashcode.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender&#39;s signature of type GNUNET_SIGNATURE_COMMUNICATOR_TCP_REKEY.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH
TCP communicator end of stream.
int GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition: crypto_ecc.c:1612
char cwrite_buf[(2 *64 *1024+sizeof(struct TCPBox))]
buffer for writing ciphertext to network.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
static void do_rekey(struct Queue *queue, const struct TCPRekey *rekey)
Handle rekey message on queue.
char pwrite_buf[UINT16_MAX+1+sizeof(struct TCPBox)]
Plaintext buffer for messages to be encrypted.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:433
static struct sockaddr * tcp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert TCP bind specification to a struct sockaddr *
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Private ECC key encoded for transmission.
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition: nat_api.c:692
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
New ephemeral key.
size_t pread_off
At which offset in the plaintext input buffer should we append more plaintext from decryption next...
int mq_awaits_continue
Is MQ awaiting a GNUNET_MQ_impl_send_continue() call?
struct GNUNET_NETWORK_Handle * sock
socket that we transmit all data with on this queue
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer...
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:301
static int get_queue_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all message queues to clean up.
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition: nat_api.c:378
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static void mq_send(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue. ...
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:412
static struct ProtoQueue * proto_tail
Protoqueues DLL tail.
#define DEFAULT_MAX_QUEUE_LENGTH
How many messages do we keep at most in the queue to the transport service before we start to drop (d...
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition: time.c:807
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
TCP message box.
static void start_initial_kx_out(struct Queue *queue)
Initialize our key material for outgoing transmissions and inform the other peer about it...
an ECC signature using EdDSA.
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the TCP connection (TCP server)
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:270
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
#define REKEY_MAX_BYTES
How often do we rekey based on number of bytes transmitted? (additionally randomized).
Allow multiple values with the same key.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
Handle to a message queue.
Definition: mq.c:85
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
socklen_t address_len
Length of the address.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
Private ECC key encoded for transmission.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
The identity of the host (wraps the signing key of the peer).
static void free_proto_queue(struct ProtoQueue *pq)
Closes socket and frees memory associated with pq.
struct sockaddr * address
Address of the other peer.
size_t ibuf_off
Current offset for reading into ibuf.
static void setup_out_cipher(struct Queue *queue)
Setup cipher for outgoing data stream based on target and our ephemeral private key.
TCP rekey message box.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
configuration data
Definition: configuration.c:85
this is an outbound connection (transport initiated)
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
enum GNUNET_TRANSPORT_ConnectionStatus cs
Connection status for this queue.
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
Encrypted continuation of TCP initial handshake.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
size_t pwrite_off
At which offset in the plaintext output buffer should we append more plaintext for encryption next...
#define GNUNET_log(kind,...)
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
Entry in list of pending tasks.
Definition: scheduler.c:134
struct ProtoQueue * next
Kept in a DLL.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX.
handle to a socket
Definition: network.c:52
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:367
struct ProtoQueue * prev
Kept in a DLL.
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static size_t try_handle_plaintext(struct Queue *queue)
Test if we have received a full message in plaintext.
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer&#39;s key from the file specified in the configuration...
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
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
gcry_cipher_hd_t in_cipher
cipher for decryption of incoming data.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
#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:1486
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
GNUNET_TRANSPORT_ConnectionStatus
Possible states of a connection.
enum GNUNET_NetworkType nt
Which network type does this queue use?
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_COMMUNICATOR_TCP_HANDSHAKE.
struct GNUNET_TIME_Absolute timeout
Timeout for this queue.
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
static struct ProtoQueue * proto_head
Protoqueues DLL head.
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".
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct GNUNET_TRANSPORT_QueueHandle * qh
handle for this queue with the ch.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
static char * address
GNS address for this phone.
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:486
gcry_cipher_hd_t out_cipher
cipher for encryption of outgoing data.
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:89
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Handle returned to identify the internal data structure the transport API has created to manage a mes...
char pread_buf[UINT16_MAX+1+sizeof(struct TCPBox)]
Plaintext buffer for decrypted plaintext.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_malloc(size)
Wrapper around malloc.
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:85
Internal representation of an address a communicator is currently providing for the transport service...
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:912
static void queue_write(void *cls)
We have been notified that our socket is ready to write.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966