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 
30 #include "platform.h"
31 #include "gnunet_util_lib.h"
32 #include "gnunet_core_service.h"
34 #include "gnunet_protocols.h"
35 #include "gnunet_signatures.h"
36 #include "gnunet_constants.h"
37 #include "gnunet_nt_lib.h"
38 #include "gnunet_nat_service.h"
42 
47 #define ADDRESS_VALIDITY_PERIOD \
48  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
49 
58 #define DEFAULT_MAX_QUEUE_LENGTH 8
59 
64 #define BUF_SIZE (2 * 64 * 1024 + sizeof(struct TCPBox))
65 
69 #define DEFAULT_REKEY_INTERVAL GNUNET_TIME_UNIT_DAYS
70 
74 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
75 
80 #define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
81 
86 #define INITIAL_KX_SIZE \
87  (sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) \
88  + sizeof(struct TCPConfirmation))
89 
93 #define INITIAL_CORE_KX_SIZE \
94  (sizeof(struct EphemeralKeyMessage) \
95  + sizeof(struct PingMessage) \
96  + sizeof(struct PongMessage))
97 
101 #define COMMUNICATOR_ADDRESS_PREFIX "tcp"
102 
106 #define COMMUNICATOR_CONFIG_SECTION "communicator-tcp"
107 
109 
110 
116 {
121 
126 
131 
136 
142 
147 };
148 
154 {
159 
164 
169 
175 
180 };
181 
186 {
191 
196 
202 
207 
208 };
209 
214 {
215 
216 
221 
226 
231 
237 
242 
243 };
244 
248 struct TCPBox
249 {
257 
266  struct GNUNET_ShortHashCode hmac;
267 
268  /* followed by as may bytes of payload as indicated in @e header,
269  excluding the TCPBox itself! */
270 };
271 
272 
277 struct TCPRekey
278 {
283 
292  struct GNUNET_ShortHashCode hmac;
293 
298 
303 
309 };
310 
316 {
321 
326 
331 
336 
342 };
343 
349 struct TCPFinish
350 {
355 
364  struct GNUNET_ShortHashCode hmac;
365 };
366 
367 
369 
374 {
379 
384 };
385 
389 struct Queue
390 {
395 
400 
405 
409  gcry_cipher_hd_t in_cipher;
410 
414  gcry_cipher_hd_t out_cipher;
415 
419  struct GNUNET_HashCode in_hmac;
420 
425  struct GNUNET_HashCode out_hmac;
426 
432 
437 
442 
446  struct sockaddr *address;
447 
453 
459 
463  socklen_t address_len;
464 
469 
474 
478  unsigned long long bytes_in_queue;
479 
484 
489 
493  char pread_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
494 
498  char pwrite_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
499 
504  size_t cread_off;
505 
510  size_t cwrite_off;
511 
516  size_t pread_off;
517 
522  size_t pwrite_off;
523 
528 
536  unsigned int backpressure;
537 
541  enum GNUNET_NetworkType nt;
542 
547 
552 
557 
565 
570  int rekeyed;
571 
576 
581 
586 
591 
596 
601 
606 
611 
616 
621 
626 };
627 
628 
634 {
638  struct ProtoQueue *next;
639 
643  struct ProtoQueue *prev;
644 
649 
654 
659 
663  struct sockaddr *address;
664 
668  socklen_t address_len;
669 
674 
680 
684  size_t ibuf_off;
685 };
686 
691 {
695  struct sockaddr *addr_ipv4;
696 
700  socklen_t addr_len_ipv4;
701 
705  struct sockaddr *addr_ipv6;
706 
710  socklen_t addr_len_ipv6;
711 
712 };
713 
717 struct Addresses
718 {
722  struct Addresses *next;
723 
727  struct Addresses *prev;
728 
732  struct sockaddr *addr;
733 
737  socklen_t addr_len;
738 
739 };
740 
741 
745 static unsigned long long max_queue_length;
746 
751 
756 
761 
766 
770 static struct GNUNET_PeerIdentity my_identity;
771 
776 
781 
785 static const struct GNUNET_CONFIGURATION_Handle *cfg;
786 
791 
795 static struct GNUNET_NAT_Handle *nat;
796 
800 static struct ProtoQueue *proto_head;
801 
805 static struct ProtoQueue *proto_tail;
806 
811 
816 
821 
826 
831 
836 
840 // TODO remove?
842 
847 
852 
856 unsigned int bind_port;
857 
865 static void
866 listen_cb (void *cls);
867 
875 static void
877 {
878  struct ListenTask *lt = NULL;
879  struct GNUNET_HashCode h_sock;
880  int sockfd;
881 
882  if (NULL != queue->listen_sock)
883  {
884  sockfd = GNUNET_NETWORK_get_fd (queue->listen_sock);
885  GNUNET_CRYPTO_hash (&sockfd,
886  sizeof(int),
887  &h_sock);
888 
890  }
891 
893  "Disconnecting queue for peer `%s'\n",
894  GNUNET_i2s (&queue->target));
895  if (NULL != queue->rekey_monotime_sc)
896  {
897  GNUNET_PEERSTORE_store_cancel (queue->rekey_monotime_sc);
898  queue->rekey_monotime_sc = NULL;
899  }
900  if (NULL != queue->handshake_monotime_sc)
901  {
902  GNUNET_PEERSTORE_store_cancel (queue->handshake_monotime_sc);
903  queue->handshake_monotime_sc = NULL;
904  }
905  if (NULL != queue->handshake_ack_monotime_sc)
906  {
907  GNUNET_PEERSTORE_store_cancel (queue->handshake_ack_monotime_sc);
908  queue->handshake_ack_monotime_sc = NULL;
909  }
910  if (NULL != queue->rekey_monotime_get)
911  {
912  GNUNET_PEERSTORE_iterate_cancel (queue->rekey_monotime_get);
913  queue->rekey_monotime_get = NULL;
914  }
915  if (NULL != queue->handshake_monotime_get)
916  {
917  GNUNET_PEERSTORE_iterate_cancel (queue->handshake_monotime_get);
918  queue->handshake_monotime_get = NULL;
919  }
920  if (NULL != queue->handshake_ack_monotime_get)
921  {
922  GNUNET_PEERSTORE_iterate_cancel (queue->handshake_ack_monotime_get);
923  queue->handshake_ack_monotime_get = NULL;
924  }
925  if (NULL != queue->qh)
926  {
928  queue->qh = NULL;
929  }
930  GNUNET_assert (
931  GNUNET_YES ==
934  "# queues active",
936  GNUNET_NO);
937  if (NULL != queue->read_task)
938  {
939  GNUNET_SCHEDULER_cancel (queue->read_task);
940  queue->read_task = NULL;
941  }
942  if (NULL != queue->write_task)
943  {
944  GNUNET_SCHEDULER_cancel (queue->write_task);
945  queue->write_task = NULL;
946  }
948  {
950  "closing socket failed\n");
951  }
952  gcry_cipher_close (queue->in_cipher);
953  gcry_cipher_close (queue->out_cipher);
954  GNUNET_free (queue->address);
955  if (0 != queue->backpressure)
956  queue->destroyed = GNUNET_YES;
957  else
958  GNUNET_free (queue);
959 
960  if (NULL == lt)
961  return;
962 
963  if ((! shutdown_running) && (NULL == lt->listen_task))
964  {
966  "add read net listen\n");
969  lt->listen_sock,
970  &listen_cb,
971  lt);
972  }
973  else
974  GNUNET_free (lt);
975 }
976 
977 
986 static void
987 calculate_hmac (struct GNUNET_HashCode *hmac_secret,
988  const void *buf,
989  size_t buf_size,
990  struct GNUNET_ShortHashCode *smac)
991 {
992  struct GNUNET_HashCode mac;
993 
994  GNUNET_CRYPTO_hmac_raw (hmac_secret,
995  sizeof(struct GNUNET_HashCode),
996  buf,
997  buf_size,
998  &mac);
999  /* truncate to `struct GNUNET_ShortHashCode` */
1000  memcpy (smac, &mac, sizeof(struct GNUNET_ShortHashCode));
1001  /* ratchet hmac key */
1002  GNUNET_CRYPTO_hash (hmac_secret,
1003  sizeof(struct GNUNET_HashCode),
1004  hmac_secret);
1005 }
1006 
1007 
1014 static void
1016 {
1017  struct TCPFinish fin;
1018 
1019  memset (&fin, 0, sizeof(fin));
1020  fin.header.size = htons (sizeof(fin));
1022  calculate_hmac (&queue->out_hmac, &fin, sizeof(fin), &fin.hmac);
1023  /* if there is any message left in pwrite_buf, we
1024  overwrite it (possibly dropping the last message
1025  from CORE hard here) */
1026  memcpy (queue->pwrite_buf, &fin, sizeof(fin));
1027  queue->pwrite_off = sizeof(fin);
1028  /* This flag will ensure that #queue_write() no longer
1029  notifies CORE about the possibility of sending
1030  more data, and that #queue_write() will call
1031  #queue_destroy() once the @c fin was fully written. */
1032  queue->finishing = GNUNET_YES;
1033 }
1034 
1035 
1043 static void
1045 {
1046  queue->timeout =
1048 }
1049 
1050 
1056 static void
1057 queue_read (void *cls);
1058 
1059 
1067 static void
1068 core_read_finished_cb (void *cls, int success)
1069 {
1070  struct Queue *queue = cls;
1071  if (GNUNET_OK != success)
1073  "# messages lost in communicator API towards CORE",
1074  1,
1075  GNUNET_NO);
1076  if (NULL == queue)
1077  return;
1078 
1080  "backpressure %u\n",
1081  queue->backpressure);
1082 
1083  queue->backpressure--;
1084  /* handle deferred queue destruction */
1085  if ((queue->destroyed) && (0 == queue->backpressure))
1086  {
1087  GNUNET_free (queue);
1088  return;
1089  }
1090  else if (GNUNET_YES != queue->destroyed)
1091  {
1093  /* possibly unchoke reading, now that CORE made progress */
1094  if (NULL == queue->read_task)
1095  queue->read_task =
1097  queue->timeout),
1098  queue->sock,
1099  &queue_read,
1100  queue);
1101  }
1102 }
1103 
1104 
1114 static void
1116  const void *plaintext,
1117  size_t plaintext_len)
1118 {
1119  const struct GNUNET_MessageHeader *hdr = plaintext;
1120  int ret;
1121 
1123  "pass message from %s to core\n",
1124  GNUNET_i2s (&queue->target));
1125 
1126  if (ntohs (hdr->size) != plaintext_len)
1127  {
1128  /* NOTE: If we ever allow multiple CORE messages in one
1129  BOX, this will have to change! */
1130  GNUNET_break (0);
1131  return;
1132  }
1134  &queue->target,
1135  hdr,
1138  queue);
1140  "passed to core\n");
1141  if (GNUNET_OK == ret)
1142  queue->backpressure++;
1143  GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
1144  if (GNUNET_SYSERR == ret)
1146  "# bytes lost due to CORE not running",
1147  plaintext_len,
1148  GNUNET_NO);
1149 }
1150 
1151 
1161 static void
1162 setup_cipher (const struct GNUNET_HashCode *dh,
1163  const struct GNUNET_PeerIdentity *pid,
1164  gcry_cipher_hd_t *cipher,
1165  struct GNUNET_HashCode *hmac_key)
1166 {
1167  char key[256 / 8];
1168  char ctr[128 / 8];
1169 
1170  GNUNET_assert (0 == gcry_cipher_open (cipher,
1171  GCRY_CIPHER_AES256 /* low level: go for speed */,
1172  GCRY_CIPHER_MODE_CTR,
1173  0 /* flags */));
1175  sizeof(key),
1176  "TCP-key",
1177  strlen ("TCP-key"),
1178  dh,
1179  sizeof(*dh),
1180  pid,
1181  sizeof(*pid),
1182  NULL,
1183  0));
1184  GNUNET_assert (0 == gcry_cipher_setkey (*cipher, key, sizeof(key)));
1186  sizeof(ctr),
1187  "TCP-ctr",
1188  strlen ("TCP-ctr"),
1189  dh,
1190  sizeof(*dh),
1191  pid,
1192  sizeof(*pid),
1193  NULL,
1194  0));
1195  gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
1197  GNUNET_CRYPTO_kdf (hmac_key,
1198  sizeof(struct GNUNET_HashCode),
1199  "TCP-hmac",
1200  strlen ("TCP-hmac"),
1201  dh,
1202  sizeof(*dh),
1203  pid,
1204  sizeof(*pid),
1205  NULL,
1206  0));
1207 }
1208 
1209 
1215 static void
1216 rekey_monotime_store_cb (void *cls, int success)
1217 {
1218  struct Queue *queue = cls;
1219  if (GNUNET_OK != success)
1220  {
1222  "Failed to store rekey monotonic time in PEERSTORE!\n");
1223  }
1224  queue->rekey_monotime_sc = NULL;
1225 }
1226 
1227 
1235 static void
1237  const struct GNUNET_PEERSTORE_Record *record,
1238  const char *emsg)
1239 {
1240  struct Queue *queue = cls;
1241  struct GNUNET_TIME_AbsoluteNBO *mtbe;
1242  struct GNUNET_TIME_Absolute mt;
1243  const struct GNUNET_PeerIdentity *pid;
1244  struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
1245 
1246  (void) emsg;
1247 
1248  rekey_monotonic_time = &queue->rekey_monotonic_time;
1249  pid = &queue->target;
1250  if (NULL == record)
1251  {
1252  queue->rekey_monotime_get = NULL;
1253  return;
1254  }
1255  if (sizeof(*mtbe) != record->value_size)
1256  {
1257  GNUNET_break (0);
1258  return;
1259  }
1260  mtbe = record->value;
1261  mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1263  queue->rekey_monotonic_time).abs_value_us)
1264  {
1266  "Queue from %s dropped, rekey monotime in the past\n",
1267  GNUNET_i2s (&queue->target));
1268  GNUNET_break (0);
1269  queue_finish (queue);
1270  return;
1271  }
1272  queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
1273  "transport_tcp_communicator",
1274  pid,
1276  rekey_monotonic_time,
1277  sizeof(*
1278  rekey_monotonic_time),
1282  queue);
1283 }
1284 
1285 
1292 static void
1294  struct Queue *queue)
1295 {
1296  struct GNUNET_HashCode dh;
1297 
1298  GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &dh);
1299  setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac);
1300 }
1301 
1302 
1311 static void
1312 do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
1313 {
1314  struct TcpRekeySignature thp;
1315 
1317  thp.purpose.size = htonl (sizeof(thp));
1319  "do_rekey size %u\n",
1320  thp.purpose.size);
1321  thp.sender = queue->target;
1323  "sender %s\n",
1324  GNUNET_p2s (&thp.sender.public_key));
1326  "sender %s\n",
1327  GNUNET_p2s (&queue->target.public_key));
1328  thp.receiver = my_identity;
1330  "receiver %s\n",
1331  GNUNET_p2s (&thp.receiver.public_key));
1332  thp.ephemeral = rekey->ephemeral;
1334  "ephemeral %s\n",
1335  GNUNET_e2s (&thp.ephemeral));
1336  thp.monotonic_time = rekey->monotonic_time;
1338  "time %s\n",
1341  GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp)));
1342  if (GNUNET_OK !=
1344  &thp,
1345  &rekey->sender_sig,
1346  &queue->target.public_key))
1347  {
1348  GNUNET_break (0);
1349  queue_finish (queue);
1350  return;
1351  }
1352  queue->rekey_monotonic_time = rekey->monotonic_time;
1353  queue->rekey_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1354  "transport_tcp_communicator",
1355  &queue->target,
1358  queue);
1359  gcry_cipher_close (queue->in_cipher);
1360  queue->rekeyed = GNUNET_YES;
1361  setup_in_cipher (&rekey->ephemeral, queue);
1362 }
1363 
1364 
1370 static void
1371 handshake_ack_monotime_store_cb (void *cls, int success)
1372 {
1373  struct Queue *queue = cls;
1374 
1375  if (GNUNET_OK != success)
1376  {
1378  "Failed to store handshake ack monotonic time in PEERSTORE!\n");
1379  }
1380  queue->handshake_ack_monotime_sc = NULL;
1381 }
1382 
1383 
1391 static void
1393  const struct GNUNET_PEERSTORE_Record *record,
1394  const char *emsg)
1395 {
1396  struct Queue *queue = cls;
1397  struct GNUNET_TIME_AbsoluteNBO *mtbe;
1398  struct GNUNET_TIME_Absolute mt;
1399  const struct GNUNET_PeerIdentity *pid;
1400  struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
1401 
1402  (void) emsg;
1403 
1404  handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
1405  pid = &queue->target;
1406  if (NULL == record)
1407  {
1408  queue->handshake_ack_monotime_get = NULL;
1409  return;
1410  }
1411  if (sizeof(*mtbe) != record->value_size)
1412  {
1413  GNUNET_break (0);
1414  return;
1415  }
1416  mtbe = record->value;
1417  mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1419  queue->handshake_ack_monotonic_time).abs_value_us)
1420  {
1422  "Queue from %s dropped, handshake ack monotime in the past\n",
1423  GNUNET_i2s (&queue->target));
1424  GNUNET_break (0);
1425  queue_finish (queue);
1426  return;
1427  }
1428  queue->handshake_ack_monotime_sc =
1430  "transport_tcp_communicator",
1431  pid,
1433  handshake_ack_monotonic_time,
1434  sizeof(*handshake_ack_monotonic_time),
1437  &
1439  queue);
1440 }
1441 
1442 
1449 static void
1451 {
1452  struct TCPConfirmationAck tca;
1453  struct TcpHandshakeAckSignature thas;
1454 
1456  "transport",
1457  "sending challenge\n");
1458 
1459  tca.header.type = ntohs (
1461  tca.header.size = ntohs (sizeof(tca));
1462  tca.challenge = challenge;
1463  tca.sender = my_identity;
1464  tca.monotonic_time =
1466  thas.purpose.purpose = htonl (
1468  thas.purpose.size = htonl (sizeof(thas));
1469  thas.sender = my_identity;
1470  thas.receiver = queue->target;
1471  thas.monotonic_time = tca.monotonic_time;
1472  thas.challenge = tca.challenge;
1474  &thas,
1475  &tca.sender_sig);
1476  GNUNET_assert (0 ==
1477  gcry_cipher_encrypt (queue->out_cipher,
1478  &queue->cwrite_buf[queue->cwrite_off],
1479  sizeof(tca),
1480  &tca,
1481  sizeof(tca)));
1482  queue->cwrite_off += sizeof(tca);
1484  "transport",
1485  "sending challenge done\n");
1486 }
1487 
1488 
1495 static void
1497 {
1498  struct GNUNET_HashCode dh;
1499 
1500  GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral, &queue->target.public_key, &dh);
1501  /* we don't need the private key anymore, drop it! */
1502  memset (&queue->ephemeral, 0, sizeof(queue->ephemeral));
1503  setup_cipher (&dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1505  queue->rekey_left_bytes =
1507 }
1508 
1509 
1516 static void
1518 {
1519  struct TCPRekey rekey;
1520  struct TcpRekeySignature thp;
1521 
1522  GNUNET_assert (0 == queue->pwrite_off);
1523  memset (&rekey, 0, sizeof(rekey));
1524  GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
1526  rekey.header.size = ntohs (sizeof(rekey));
1527  GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral);
1528  rekey.monotonic_time =
1531  thp.purpose.size = htonl (sizeof(thp));
1533  "inject_rekey size %u\n",
1534  thp.purpose.size);
1535  thp.sender = my_identity;
1537  "sender %s\n",
1538  GNUNET_p2s (&thp.sender.public_key));
1539  thp.receiver = queue->target;
1541  "receiver %s\n",
1542  GNUNET_p2s (&thp.receiver.public_key));
1543  thp.ephemeral = rekey.ephemeral;
1545  "ephemeral %s\n",
1546  GNUNET_e2s (&thp.ephemeral));
1547  thp.monotonic_time = rekey.monotonic_time;
1549  "time %s\n",
1553  &thp,
1554  &rekey.sender_sig);
1555  calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1556  /* Encrypt rekey message with 'old' cipher */
1557  GNUNET_assert (0 ==
1558  gcry_cipher_encrypt (queue->out_cipher,
1559  &queue->cwrite_buf[queue->cwrite_off],
1560  sizeof(rekey),
1561  &rekey,
1562  sizeof(rekey)));
1563  queue->cwrite_off += sizeof(rekey);
1564  /* Setup new cipher for successive messages */
1565  gcry_cipher_close (queue->out_cipher);
1567 }
1568 
1569 
1576 static void
1577 queue_write (void *cls)
1578 {
1579  struct Queue *queue = cls;
1580  ssize_t sent;
1581  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1582  queue->write_task = NULL;
1583  if (0 != queue->cwrite_off)
1584  {
1585  sent = GNUNET_NETWORK_socket_send (queue->sock,
1586  queue->cwrite_buf,
1587  queue->cwrite_off);
1589  "Sent %lu bytes to TCP queue\n", sent);
1590  if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1591  {
1593  queue_destroy (queue);
1594  return;
1595  }
1596  if (sent > 0)
1597  {
1598  size_t usent = (size_t) sent;
1599  queue->cwrite_off -= usent;
1600  memmove (queue->cwrite_buf,
1601  &queue->cwrite_buf[usent],
1602  queue->cwrite_off);
1604  }
1605  }
1606  /* can we encrypt more? (always encrypt full messages, needed
1607  such that #mq_cancel() can work!) */
1608  if ((0 < queue->rekey_left_bytes) &&
1609  (queue->pwrite_off > 0) &&
1610  (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1611  {
1613  "Encrypting %lu bytes\n", queue->pwrite_off);
1614  GNUNET_assert (0 ==
1615  gcry_cipher_encrypt (queue->out_cipher,
1616  &queue->cwrite_buf[queue->cwrite_off],
1617  queue->pwrite_off,
1618  queue->pwrite_buf,
1619  queue->pwrite_off));
1620  if (queue->rekey_left_bytes > queue->pwrite_off)
1621  queue->rekey_left_bytes -= queue->pwrite_off;
1622  else
1623  queue->rekey_left_bytes = 0;
1624  queue->cwrite_off += queue->pwrite_off;
1625  queue->pwrite_off = 0;
1626  }
1627  // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1628  if (((0 == queue->pwrite_off) &&
1629  ((0 == queue->rekey_left_bytes) ||
1630  (0 ==
1632  queue->rekey_time).rel_value_us))))
1633  {
1634  inject_rekey (queue);
1635  }
1636  if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1637  (GNUNET_YES == queue->mq_awaits_continue))
1638  {
1639  queue->mq_awaits_continue = GNUNET_NO;
1641  }
1642  /* did we just finish writing 'finish'? */
1643  if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1644  {
1646  "Finishing queue\n");
1647  queue_destroy (queue);
1648  return;
1649  }
1650  /* do we care to write more? */
1651  if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1652  queue->write_task =
1654  queue->sock,
1655  &queue_write,
1656  queue);
1657 }
1658 
1659 
1667 static size_t
1669 {
1670  const struct GNUNET_MessageHeader *hdr =
1671  (const struct GNUNET_MessageHeader *) queue->pread_buf;
1672  const struct TCPConfirmationAck *tca = (const struct
1673  TCPConfirmationAck *) queue->pread_buf;
1674  const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf;
1675  const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf;
1676  const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf;
1677  struct TCPRekey rekeyz;
1678  struct TCPFinish finz;
1679  struct GNUNET_ShortHashCode tmac;
1680  uint16_t type;
1681  size_t size = 0; /* make compiler happy */
1682  struct TcpHandshakeAckSignature thas;
1683  const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1684 
1686  "try handle plaintext!\n");
1687 
1688  if ((sizeof(*hdr) > queue->pread_off))
1689  {
1691  "Handling plaintext, not even a header!\n");
1692  return 0; /* not even a header */
1693  }
1694 
1696  {
1698  "Already received data of size %lu bigger than KX size %lu!\n",
1701  GNUNET_break_op (0);
1702  queue_finish (queue);
1703  return 0;
1704  }
1705 
1706  type = ntohs (hdr->type);
1707  switch (type)
1708  {
1711  "start processing ack\n");
1712  if (sizeof(*tca) > queue->pread_off)
1713  {
1715  "Handling plaintext size of tca greater than pread offset.\n");
1716  return 0;
1717  }
1718  if (ntohs (hdr->size) != sizeof(*tca))
1719  {
1721  "Handling plaintext size does not match message type.\n");
1722  GNUNET_break_op (0);
1723  queue_finish (queue);
1724  return 0;
1725  }
1726 
1727  thas.purpose.purpose = htonl (
1729  thas.purpose.size = htonl (sizeof(thas));
1730  thas.sender = tca->sender;
1731  thas.receiver = my_identity;
1732  thas.monotonic_time = tca->monotonic_time;
1733  thas.challenge = tca->challenge;
1734 
1737  &thas,
1738  &tca->sender_sig,
1739  &tca->sender.public_key))
1740  {
1742  "Verification of signature failed!\n");
1743  GNUNET_break (0);
1744  queue_finish (queue);
1745  return 0;
1746  }
1747  if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
1748  {
1750  "Challenge in TCPConfirmationAck not correct!\n");
1751  GNUNET_break (0);
1752  queue_finish (queue);
1753  return 0;
1754  }
1755 
1756  queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1757  "transport_tcp_communicator",
1758  &queue->target,
1760  &
1762  queue);
1763 
1765  "Handling plaintext, ack processed!\n");
1766 
1768  {
1769  send_challenge (queue->challenge_received, queue);
1770  queue->write_task =
1772  queue->sock,
1773  &queue_write,
1774  queue);
1775  }
1776 
1777  unverified_size = -1;
1778 
1779  char *foreign_addr;
1780 
1781  switch (queue->address->sa_family)
1782  {
1783  case AF_INET:
1784  GNUNET_asprintf (&foreign_addr,
1785  "%s-%s",
1787  GNUNET_a2s (queue->address, queue->address_len));
1788  break;
1789 
1790  case AF_INET6:
1791  GNUNET_asprintf (&foreign_addr,
1792  "%s-%s",
1794  GNUNET_a2s (queue->address, queue->address_len));
1795  break;
1796 
1797  default:
1798  GNUNET_assert (0);
1799  }
1800 
1802  &queue->target,
1803  foreign_addr,
1804  UINT16_MAX, /* no MTU */
1806  0, /* Priority */
1807  queue->nt,
1808  queue->cs,
1809  queue->mq);
1810 
1811  GNUNET_free (foreign_addr);
1812 
1813  size = ntohs (hdr->size);
1814  break;
1816  /* Special case: header size excludes box itself! */
1817  if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
1818  return 0;
1819  calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
1820  if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
1821  {
1822  GNUNET_break_op (0);
1823  queue_finish (queue);
1824  return 0;
1825  }
1826  pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
1827  size = ntohs (hdr->size) + sizeof(*box);
1829  "Handling plaintext, box processed!\n");
1830  break;
1831 
1833  if (sizeof(*rekey) > queue->pread_off)
1834  return 0;
1835  if (ntohs (hdr->size) != sizeof(*rekey))
1836  {
1837  GNUNET_break_op (0);
1838  queue_finish (queue);
1839  return 0;
1840  }
1841  rekeyz = *rekey;
1842  memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
1843  calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
1844  if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
1845  {
1846  GNUNET_break_op (0);
1847  queue_finish (queue);
1848  return 0;
1849  }
1850  do_rekey (queue, rekey);
1851  size = ntohs (hdr->size);
1853  "Handling plaintext, rekey processed!\n");
1854  break;
1855 
1857  if (sizeof(*fin) > queue->pread_off)
1858  return 0;
1859  if (ntohs (hdr->size) != sizeof(*fin))
1860  {
1861  GNUNET_break_op (0);
1862  queue_finish (queue);
1863  return 0;
1864  }
1865  finz = *fin;
1866  memset (&finz.hmac, 0, sizeof(finz.hmac));
1867  calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
1868  if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
1869  {
1870  GNUNET_break_op (0);
1871  queue_finish (queue);
1872  return 0;
1873  }
1874  /* handle FINISH by destroying queue */
1875  queue_destroy (queue);
1877  "Handling plaintext, finish processed!\n");
1878  break;
1879 
1880  default:
1882  "Handling plaintext, nothing processed!\n");
1883  GNUNET_break_op (0);
1884  queue_finish (queue);
1885  return 0;
1886  }
1887  GNUNET_assert (0 != size);
1888  if (-1 != unverified_size)
1889  unverified_size += size;
1890  return size;
1891 }
1892 
1893 
1899 static void
1900 queue_read (void *cls)
1901 {
1902  struct Queue *queue = cls;
1903  struct GNUNET_TIME_Relative left;
1904  ssize_t rcvd;
1905 
1906  queue->read_task = NULL;
1907  rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1908  &queue->cread_buf[queue->cread_off],
1909  BUF_SIZE - queue->cread_off);
1911  "Received %lu bytes from TCP queue\n", rcvd);
1913  "transport",
1914  "Received %lu bytes from TCP queue\n", rcvd);
1915  if (-1 == rcvd)
1916  {
1917  if ((EAGAIN != errno) && (EINTR != errno))
1918  {
1920  queue_finish (queue);
1921  return;
1922  }
1923  /* try again */
1924  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1925  queue->read_task =
1927  return;
1928  }
1929  if (0 != rcvd)
1931  queue->cread_off += rcvd;
1932  while ((queue->pread_off < sizeof(queue->pread_buf)) &&
1933  (queue->cread_off > 0))
1934  {
1935  size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
1936  queue->cread_off);
1937  size_t done;
1938  size_t total;
1939  size_t old_pread_off = queue->pread_off;
1940 
1941  GNUNET_assert (0 ==
1942  gcry_cipher_decrypt (queue->in_cipher,
1943  &queue->pread_buf[queue->pread_off],
1944  max,
1945  queue->cread_buf,
1946  max));
1947  queue->pread_off += max;
1948  total = 0;
1949  while (0 != (done = try_handle_plaintext (queue)))
1950  {
1951  /* 'done' bytes of plaintext were used, shift buffer */
1952  GNUNET_assert (done <= queue->pread_off);
1953  /* NOTE: this memmove() could possibly sometimes be
1954  avoided if we pass 'total' into try_handle_plaintext()
1955  and use it at an offset into the buffer there! */
1956  memmove (queue->pread_buf,
1957  &queue->pread_buf[done],
1958  queue->pread_off - done);
1959  queue->pread_off -= done;
1960  total += done;
1961  /* The last plaintext was a rekey, abort for now */
1962  if (GNUNET_YES == queue->rekeyed)
1963  break;
1964  }
1965  /* when we encounter a rekey message, the decryption above uses the
1966  wrong key for everything after the rekey; in that case, we have
1967  to re-do the decryption at 'total' instead of at 'max'.
1968  However, we have to take into account that the plaintext buffer may have
1969  already contained data and not jumped too far ahead in the ciphertext.
1970  If there is no rekey and the last message is incomplete (max > total),
1971  it is safe to keep the decryption so we shift by 'max' */
1972  if (GNUNET_YES == queue->rekeyed)
1973  {
1974  max = total - old_pread_off;
1975  queue->rekeyed = GNUNET_NO;
1976  queue->pread_off = 0;
1977  }
1978  memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
1979  queue->cread_off -= max;
1980  }
1981  if (BUF_SIZE == queue->cread_off)
1982  return; /* buffer full, suspend reading */
1983  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1984  if (0 != left.rel_value_us)
1985  {
1986  if (max_queue_length > queue->backpressure)
1987  {
1988  /* continue reading */
1989  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1990  queue->read_task =
1992  }
1993  return;
1994  }
1996  "Queue %p was idle for %s, disconnecting\n",
1997  queue,
2000  GNUNET_YES));
2001  queue_finish (queue);
2002 }
2003 
2004 
2012 static struct sockaddr *
2014  struct sockaddr_in6 v6,
2015  unsigned int port)
2016 {
2017  struct sockaddr *in;
2018 
2019  v6.sin6_family = AF_INET6;
2020  v6.sin6_port = htons ((uint16_t) port);
2021 #if HAVE_SOCKADDR_IN_SIN_LEN
2022  v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2023 #endif
2024  v6.sin6_flowinfo = 0;
2025  v6.sin6_scope_id = 0;
2026  in = GNUNET_memdup (&v6, sizeof(v6));
2027  *sock_len = sizeof(struct sockaddr_in6);
2028 
2029  return in;
2030 }
2031 
2032 
2040 static struct sockaddr *
2042  struct sockaddr_in v4,
2043  unsigned int port)
2044 {
2045  struct sockaddr *in;
2046 
2047  v4.sin_family = AF_INET;
2048  v4.sin_port = htons ((uint16_t) port);
2049 #if HAVE_SOCKADDR_IN_SIN_LEN
2050  v4.sin_len = sizeof(struct sockaddr_in);
2051 #endif
2052  in = GNUNET_memdup (&v4, sizeof(v4));
2053  *sock_len = sizeof(struct sockaddr_in);
2054  return in;
2055 }
2056 
2057 
2064 static struct PortOnlyIpv4Ipv6 *
2065 tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
2066 {
2067  struct PortOnlyIpv4Ipv6 *po;
2068  struct sockaddr_in *i4;
2069  struct sockaddr_in6 *i6;
2070  socklen_t sock_len_ipv4;
2071  socklen_t sock_len_ipv6;
2072 
2073  /* interpreting value as just a PORT number */
2074  if (*port > UINT16_MAX)
2075  {
2077  "BINDTO specification `%s' invalid: value too large for port\n",
2078  bindto);
2079  return NULL;
2080  }
2081 
2082  po = GNUNET_new (struct PortOnlyIpv4Ipv6);
2083 
2084  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2085  (GNUNET_YES ==
2088  "DISABLE_V6")))
2089  {
2090  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2091  po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2092  *port);
2093  po->addr_len_ipv4 = sock_len_ipv4;
2094  }
2095  else
2096  {
2097 
2098  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2099  po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2100  *port);
2101  po->addr_len_ipv4 = sock_len_ipv4;
2102 
2103  i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2104  po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
2105  *port);
2106 
2107  po->addr_len_ipv6 = sock_len_ipv6;
2108 
2109  GNUNET_free (i6);
2110  }
2111 
2112  GNUNET_free (i4);
2113 
2114  return po;
2115 }
2116 
2117 
2124 static char *
2125 extract_address (const char *bindto)
2126 {
2127  char *addr;
2128  char *start;
2129  char *token;
2130  char *cp;
2131  char *rest = NULL;
2132  char *res;
2133 
2135  "extract address with bindto %s\n",
2136  bindto);
2137 
2138  if (NULL == bindto)
2140  "bindto is NULL\n");
2141 
2142  cp = GNUNET_strdup (bindto);
2143 
2145  "extract address 2\n");
2146 
2147  start = cp;
2148  if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2149  {
2150  start++; /* skip over '['*/
2151  cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
2152  addr = GNUNET_strdup (start);
2153  }
2154  else
2155  {
2156  token = strtok_r (cp, "]", &rest);
2157  if (strlen (bindto) == strlen (token))
2158  {
2159  token = strtok_r (cp, ":", &rest);
2160  addr = GNUNET_strdup (token);
2161  }
2162  else
2163  {
2164  token++;
2165  res = GNUNET_strdup (token);
2166  addr = GNUNET_strdup (res);
2167  }
2168  }
2169 
2171  "tcp address: %s\n",
2172  addr);
2173  GNUNET_free (cp);
2174  return addr;
2175 }
2176 
2177 
2184 static unsigned int
2185 extract_port (const char *addr_and_port)
2186 {
2187  unsigned int port;
2188  char dummy[2];
2189  char *token;
2190  char *addr;
2191  char *colon;
2192  char *cp;
2193  char *rest = NULL;
2194 
2195  if (NULL != addr_and_port)
2196  {
2197  cp = GNUNET_strdup (addr_and_port);
2198  token = strtok_r (cp, "]", &rest);
2199  if (strlen (addr_and_port) == strlen (token))
2200  {
2201  colon = strrchr (cp, ':');
2202  if (NULL == colon)
2203  {
2204  GNUNET_free (cp);
2205  return 0;
2206  }
2207  addr = colon;
2208  addr++;
2209  }
2210  else
2211  {
2212  token = strtok_r (NULL, "]", &rest);
2213  if (NULL == token)
2214  {
2215  GNUNET_free (cp);
2216  return 0;
2217  }
2218  else
2219  {
2220  addr = token;
2221  addr++;
2222  }
2223  }
2224 
2225 
2226  if (1 == sscanf (addr, "%u%1s", &port, dummy))
2227  {
2228  /* interpreting value as just a PORT number */
2229  if (port > UINT16_MAX)
2230  {
2232  "Port `%u' invalid: value too large for port\n",
2233  port);
2234  GNUNET_free (cp);
2235  return 0;
2236  }
2237  }
2238  else
2239  {
2241  "BINDTO specification invalid: last ':' not followed by number\n");
2242  GNUNET_free (cp);
2243  return 0;
2244  }
2245  GNUNET_free (cp);
2246  }
2247  else
2248  {
2250  "return 0\n");
2251  /* interpret missing port as 0, aka pick any free one */
2252  port = 0;
2253  }
2254 
2255  return port;
2256 }
2257 
2258 
2266 static struct sockaddr *
2267 tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2268 {
2269  struct sockaddr *in;
2270  unsigned int port;
2271  struct sockaddr_in v4;
2272  struct sockaddr_in6 v6;
2273  char *start;
2274 
2275  start = extract_address (bindto);
2276  // FIXME: check NULL == start
2278  "start %s\n",
2279  start);
2280 
2282  "!bindto %s\n",
2283  bindto);
2284 
2285 
2286  if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2287  {
2288  // colon = strrchr (cp, ':');
2289  port = extract_port (bindto);
2290 
2292  "port %u\n",
2293  port);
2294 
2295  in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
2296  }
2297  else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2298  {
2299  // colon = strrchr (cp, ':');
2300  port = extract_port (bindto);
2301  in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
2302  }
2303  else
2304  {
2305  GNUNET_assert (0);
2306  }
2307 
2308  GNUNET_free (start);
2309  return in;
2310 }
2311 
2312 
2321 static void
2323  const struct GNUNET_MessageHeader *msg,
2324  void *impl_state)
2325 {
2326  struct Queue *queue = impl_state;
2327  uint16_t msize = ntohs (msg->size);
2328  struct TCPBox box;
2330  "In MQ send. Queue finishing: %s; write task running: %s\n",
2331  (GNUNET_YES == queue->finishing) ? "yes" : "no",
2332  (NULL == queue->write_task) ? "yes" : "no");
2333  GNUNET_assert (mq == queue->mq);
2334  queue->mq_awaits_continue = GNUNET_YES;
2335  if (GNUNET_YES == queue->finishing)
2336  return; /* this queue is dying, drop msg */
2337  GNUNET_assert (0 == queue->pwrite_off);
2339  box.header.size = htons (msize);
2340  calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
2341  memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
2342  queue->pwrite_off += sizeof(box);
2343  memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
2344  queue->pwrite_off += msize;
2346  "%lu bytes of plaintext to send\n", queue->pwrite_off);
2347  GNUNET_assert (NULL != queue->sock);
2348  if (NULL == queue->write_task)
2349  queue->write_task =
2351  queue->sock,
2352  &queue_write,
2353  queue);
2354 }
2355 
2356 
2365 static void
2366 mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
2367 {
2368  struct Queue *queue = impl_state;
2369 
2370  if (mq == queue->mq)
2371  {
2372  queue->mq = NULL;
2373  queue_finish (queue);
2374  }
2375 }
2376 
2377 
2384 static void
2385 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2386 {
2387  struct Queue *queue = impl_state;
2388 
2389  GNUNET_assert (0 != queue->pwrite_off);
2390  queue->pwrite_off = 0;
2391 }
2392 
2393 
2403 static void
2404 mq_error (void *cls, enum GNUNET_MQ_Error error)
2405 {
2406  struct Queue *queue = cls;
2407 
2409  "MQ error in queue to %s: %d\n",
2410  GNUNET_i2s (&queue->target),
2411  (int) error);
2412  queue_finish (queue);
2413 }
2414 
2415 
2423 static void
2425 {
2426  queue->nt =
2427  GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
2429  queue_map,
2430  &queue->target,
2431  queue,
2434  "# queues active",
2436  GNUNET_NO);
2437  queue->timeout =
2440  &mq_destroy,
2441  &mq_cancel,
2442  queue,
2443  NULL,
2444  &mq_error,
2445  queue);
2446 }
2447 
2448 
2459 static void
2461  const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
2462 {
2463  struct TcpHandshakeSignature ths;
2464  struct TCPConfirmation tc;
2465 
2466  memcpy (queue->cwrite_buf, epub, sizeof(*epub));
2467  queue->cwrite_off = sizeof(*epub);
2468  /* compute 'tc' and append in encrypted format to cwrite_buf */
2469  tc.sender = my_identity;
2470  tc.monotonic_time =
2473  &tc.challenge,
2474  sizeof(tc.challenge));
2476  ths.purpose.size = htonl (sizeof(ths));
2477  ths.sender = my_identity;
2478  ths.receiver = queue->target;
2479  ths.ephemeral = *epub;
2480  ths.monotonic_time = tc.monotonic_time;
2481  ths.challenge = tc.challenge;
2483  &ths,
2484  &tc.sender_sig);
2485  GNUNET_assert (0 ==
2486  gcry_cipher_encrypt (queue->out_cipher,
2487  &queue->cwrite_buf[queue->cwrite_off],
2488  sizeof(tc),
2489  &tc,
2490  sizeof(tc)));
2491  queue->challenge = tc.challenge;
2492  queue->cwrite_off += sizeof(tc);
2493 
2495  "transport",
2496  "handshake written\n");
2497 }
2498 
2499 
2507 static void
2509 {
2510  struct GNUNET_CRYPTO_EcdhePublicKey epub;
2511 
2512  GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
2513  GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &epub);
2515  transmit_kx (queue, &epub);
2516 }
2517 
2518 
2524 static void
2525 handshake_monotime_store_cb (void *cls, int success)
2526 {
2527  struct Queue *queue = cls;
2528  if (GNUNET_OK != success)
2529  {
2531  "Failed to store handshake monotonic time in PEERSTORE!\n");
2532  }
2533  queue->handshake_monotime_sc = NULL;
2534 }
2535 
2536 
2544 static void
2546  const struct GNUNET_PEERSTORE_Record *record,
2547  const char *emsg)
2548 {
2549  struct Queue *queue = cls;
2550  struct GNUNET_TIME_AbsoluteNBO *mtbe;
2551  struct GNUNET_TIME_Absolute mt;
2552  const struct GNUNET_PeerIdentity *pid;
2553  struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2554 
2555  (void) emsg;
2556 
2557  handshake_monotonic_time = &queue->handshake_monotonic_time;
2558  pid = &queue->target;
2560  "tcp handshake with us %s\n",
2561  GNUNET_i2s (&my_identity));
2562  if (NULL == record)
2563  {
2564  queue->handshake_monotime_get = NULL;
2565  return;
2566  }
2568  "tcp handshake from peer %s\n",
2569  GNUNET_i2s (pid));
2570  if (sizeof(*mtbe) != record->value_size)
2571  {
2572  GNUNET_break (0);
2573  return;
2574  }
2575  mtbe = record->value;
2576  mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2578  queue->handshake_monotonic_time).abs_value_us)
2579  {
2581  "Queue from %s dropped, handshake monotime in the past\n",
2582  GNUNET_i2s (&queue->target));
2583  GNUNET_break (0);
2584  queue_finish (queue);
2585  return;
2586  }
2587  queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2588  "transport_tcp_communicator",
2589  pid,
2591  handshake_monotonic_time,
2592  sizeof(*
2593  handshake_monotonic_time),
2596  &
2598  queue);
2599 }
2600 
2601 
2613 static int
2615  struct TCPConfirmation *tc,
2616  char *ibuf)
2617 {
2618  struct TcpHandshakeSignature ths;
2620 
2621  GNUNET_assert (
2622  0 ==
2623  gcry_cipher_decrypt (queue->in_cipher,
2624  tc,
2625  sizeof(*tc),
2626  &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2627  sizeof(*tc)));
2629  ths.purpose.size = htonl (sizeof(ths));
2630  ths.sender = tc->sender;
2631  ths.receiver = my_identity;
2632  memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2633  ths.monotonic_time = tc->monotonic_time;
2634  ths.challenge = tc->challenge;
2637  &ths,
2638  &tc->sender_sig,
2639  &tc->sender.public_key);
2640  if (GNUNET_YES == ret)
2641  queue->handshake_monotime_get =
2643  "transport_tcp_communicator",
2644  &queue->target,
2647  queue);
2648  return ret;
2649 }
2650 
2651 
2657 static void
2659 {
2660  if (NULL != pq->listen_sock)
2661  {
2663  pq->listen_sock = NULL;
2664  }
2666  GNUNET_free (pq->address);
2668  GNUNET_free (pq);
2669 }
2670 
2671 
2678 static void
2679 proto_read_kx (void *cls)
2680 {
2681  struct ProtoQueue *pq = cls;
2682  ssize_t rcvd;
2683  struct GNUNET_TIME_Relative left;
2684  struct Queue *queue;
2685  struct TCPConfirmation tc;
2686 
2687  pq->read_task = NULL;
2689  if (0 == left.rel_value_us)
2690  {
2691  free_proto_queue (pq);
2692  return;
2693  }
2694  rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
2695  &pq->ibuf[pq->ibuf_off],
2696  sizeof(pq->ibuf) - pq->ibuf_off);
2698  "Received %lu bytes for KX\n", rcvd);
2700  "transport",
2701  "Received %lu bytes for KX\n", rcvd);
2702  if (-1 == rcvd)
2703  {
2704  if ((EAGAIN != errno) && (EINTR != errno))
2705  {
2707  free_proto_queue (pq);
2708  return;
2709  }
2710  /* try again */
2711  pq->read_task =
2713  return;
2714  }
2715  pq->ibuf_off += rcvd;
2716  if (pq->ibuf_off > sizeof(pq->ibuf))
2717  {
2718  /* read more */
2719  pq->read_task =
2721  return;
2722  }
2723  /* we got all the data, let's find out who we are talking to! */
2724  queue = GNUNET_new (struct Queue);
2725  setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
2726  queue);
2727  if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
2728  {
2730  "Invalid TCP KX received from %s\n",
2731  GNUNET_a2s (pq->address, pq->address_len));
2732  gcry_cipher_close (queue->in_cipher);
2733  GNUNET_free (queue);
2734  free_proto_queue (pq);
2735  return;
2736  }
2737  queue->address = pq->address; /* steals reference */
2738  queue->address_len = pq->address_len;
2739  queue->target = tc.sender;
2740  queue->listen_sock = pq->listen_sock;
2741  queue->sock = pq->sock;
2742 
2744  "created queue with target %s\n",
2745  GNUNET_i2s (&queue->target));
2746 
2748  "start kx proto\n");
2749 
2752  boot_queue (queue);
2753  queue->read_task =
2755  queue->sock,
2756  &queue_read,
2757  queue);
2758  queue->write_task =
2760  queue->sock,
2761  &queue_write,
2762  queue);
2763  // TODO To early! Move it somewhere else.
2764  // send_challenge (tc.challenge, queue);
2765  queue->challenge_received = tc.challenge;
2766 
2768  GNUNET_free (pq);
2769 }
2770 
2771 
2779 static void
2780 listen_cb (void *cls)
2781 {
2782  struct sockaddr_storage in;
2783  socklen_t addrlen;
2784  struct GNUNET_NETWORK_Handle *sock;
2785  struct ProtoQueue *pq;
2786  struct ListenTask *lt;
2787 
2789  "listen_cb\n");
2790 
2791  lt = cls;
2792 
2793  lt->listen_task = NULL;
2794  GNUNET_assert (NULL != lt->listen_sock);
2795  addrlen = sizeof(in);
2796  memset (&in, 0, sizeof(in));
2798  (struct sockaddr*) &in,
2799  &addrlen);
2800  if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
2801  return; /* system limit reached, wait until connection goes down */
2803  lt->listen_sock,
2804  &listen_cb,
2805  lt);
2806  if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
2807  return;
2808  if (NULL == sock)
2809  {
2811  return;
2812  }
2813  pq = GNUNET_new (struct ProtoQueue);
2814  pq->address_len = addrlen;
2815  pq->address = GNUNET_memdup (&in, addrlen);
2817  pq->sock = sock;
2819  pq->sock,
2820  &proto_read_kx,
2821  pq);
2823 }
2824 
2825 
2833 static void
2834 queue_read_kx (void *cls)
2835 {
2836  struct Queue *queue = cls;
2837  ssize_t rcvd;
2838  struct GNUNET_TIME_Relative left;
2839  struct TCPConfirmation tc;
2840 
2841  queue->read_task = NULL;
2842  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2843  if (0 == left.rel_value_us)
2844  {
2845  queue_destroy (queue);
2846  return;
2847  }
2848  rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2849  &queue->cread_buf[queue->cread_off],
2850  BUF_SIZE - queue->cread_off);
2852  "Received %lu bytes for KX\n",
2853  rcvd);
2855  "transport",
2856  "Received %lu bytes for KX\n",
2857  rcvd);
2858  if (-1 == rcvd)
2859  {
2860  if ((EAGAIN != errno) && (EINTR != errno))
2861  {
2863  queue_destroy (queue);
2864  return;
2865  }
2866  queue->read_task =
2868  return;
2869  }
2870  queue->cread_off += rcvd;
2871  if (queue->cread_off < INITIAL_KX_SIZE)
2872  {
2873  /* read more */
2874  queue->read_task =
2876  return;
2877  }
2878  /* we got all the data, let's find out who we are talking to! */
2880  queue->cread_buf,
2881  queue);
2882  if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
2883  {
2885  "Invalid TCP KX received from %s\n",
2886  GNUNET_a2s (queue->address, queue->address_len));
2887  queue_destroy (queue);
2888  return;
2889  }
2890  if (0 !=
2891  memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
2892  {
2894  "Invalid sender in TCP KX received from %s\n",
2895  GNUNET_a2s (queue->address, queue->address_len));
2896  queue_destroy (queue);
2897  return;
2898  }
2899  send_challenge (tc.challenge, queue);
2900  queue->write_task =
2902  queue->sock,
2903  &queue_write,
2904  queue);
2905 
2906  /* update queue timeout */
2908  /* prepare to continue with regular read task immediately */
2909  memmove (queue->cread_buf,
2910  &queue->cread_buf[INITIAL_KX_SIZE],
2911  queue->cread_off - (INITIAL_KX_SIZE));
2913  "cread_off is %lu bytes before adjusting\n",
2914  queue->cread_off);
2915  queue->cread_off -= INITIAL_KX_SIZE;
2917  "cread_off set to %lu bytes\n",
2918  queue->cread_off);
2920 }
2921 
2922 
2941 static int
2942 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2943 {
2944  struct Queue *queue;
2945  const char *path;
2946  struct sockaddr *in;
2947  socklen_t in_len = 0;
2948  struct GNUNET_NETWORK_Handle *sock;
2949 
2951  "Connecting to %s\n", address);
2953  "transport",
2954  "Connecting to %s\n", address);
2955  if (0 != strncmp (address,
2957  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2958  {
2959  GNUNET_break_op (0);
2960  return GNUNET_SYSERR;
2961  }
2962  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2963  in = tcp_address_to_sockaddr (path, &in_len);
2964 
2965  if (NULL == in)
2966  {
2968  "Failed to setup TCP socket address\n");
2969  return GNUNET_SYSERR;
2970  }
2971 
2973  "in %s\n",
2974  GNUNET_a2s (in, in_len));
2975 
2976  sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP);
2977  if (NULL == sock)
2978  {
2980  "socket(%d) failed: %s",
2981  in->sa_family,
2982  strerror (errno));
2983  GNUNET_free (in);
2984  return GNUNET_SYSERR;
2985  }
2986  if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
2987  (errno != EINPROGRESS))
2988  {
2990  "connect to `%s' failed: %s",
2991  address,
2992  strerror (errno));
2994  GNUNET_free (in);
2995  return GNUNET_SYSERR;
2996  }
2997 
2998  queue = GNUNET_new (struct Queue);
2999  queue->target = *peer;
3000  queue->address = in;
3001  queue->address_len = in_len;
3002  queue->sock = sock;
3004  boot_queue (queue);
3006  "booted queue with target %s\n",
3007  GNUNET_i2s (&queue->target));
3008  // queue->mq_awaits_continue = GNUNET_YES;
3009  queue->read_task =
3011  queue->sock,
3012  &queue_read_kx,
3013  queue);
3014 
3015 
3017  "start kx mq_init\n");
3018 
3020  queue->write_task =
3022  queue->sock,
3023  &queue_write,
3024  queue);
3025  return GNUNET_OK;
3026 }
3027 
3028 
3037 static int
3038 get_lt_delete_it (void *cls,
3039  const struct GNUNET_HashCode *key,
3040  void *value)
3041 {
3042  struct ListenTask *lt = value;
3043 
3044  (void) cls;
3045  (void) key;
3046  if (NULL != lt->listen_task)
3047  {
3049  lt->listen_task = NULL;
3050  }
3051  if (NULL != lt->listen_sock)
3052  {
3054  lt->listen_sock = NULL;
3055  }
3056  return GNUNET_OK;
3057 }
3058 
3059 
3068 static int
3070  const struct GNUNET_PeerIdentity *target,
3071  void *value)
3072 {
3073  struct Queue *queue = value;
3074 
3075  (void) cls;
3076  (void) target;
3077  queue_destroy (queue);
3078  return GNUNET_OK;
3079 }
3080 
3081 
3087 static void
3088 do_shutdown (void *cls)
3089 {
3091  "Shutdown %s!\n",
3092  shutdown_running ? "running" : "not running");
3093 
3095  return;
3096  else
3098 
3099  while (NULL != proto_head)
3101  if (NULL != nat)
3102  {
3104  nat = NULL;
3105  }
3109  if (NULL != ch)
3110  {
3113  ch = NULL;
3114  }
3115  if (NULL != stats)
3116  {
3118  stats = NULL;
3119  }
3120  if (NULL != my_private_key)
3121  {
3123  my_private_key = NULL;
3124  }
3125  if (NULL != is)
3126  {
3128  is = NULL;
3129  }
3130  if (NULL != peerstore)
3131  {
3133  peerstore = NULL;
3134  }
3135  if (NULL != resolve_request_handle)
3136  {
3138  resolve_request_handle = NULL;
3139  }
3141  "Shutdown done!\n");
3142 }
3143 
3144 
3156 static void
3157 enc_notify_cb (void *cls,
3158  const struct GNUNET_PeerIdentity *sender,
3159  const struct GNUNET_MessageHeader *msg)
3160 {
3161  (void) cls;
3162  (void) sender;
3163  (void) msg;
3164  GNUNET_break_op (0);
3165 }
3166 
3167 
3181 static void
3182 nat_address_cb (void *cls,
3183  void **app_ctx,
3184  int add_remove,
3186  const struct sockaddr *addr,
3187  socklen_t addrlen)
3188 {
3189  char *my_addr;
3191 
3193  "nat address cb %s %s\n",
3194  add_remove ? "add" : "remove",
3195  GNUNET_a2s (addr, addrlen));
3196 
3197  if (GNUNET_YES == add_remove)
3198  {
3199  enum GNUNET_NetworkType nt;
3200 
3201  GNUNET_asprintf (&my_addr,
3202  "%s-%s",
3204  GNUNET_a2s (addr, addrlen));
3205  nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3206  ai =
3208  my_addr,
3209  nt,
3211  GNUNET_free (my_addr);
3212  *app_ctx = ai;
3213  }
3214  else
3215  {
3216  ai = *app_ctx;
3218  *app_ctx = NULL;
3219  }
3220 }
3221 
3222 
3226 static void
3227 add_addr (struct sockaddr *in, socklen_t in_len)
3228 {
3229 
3230  struct Addresses *saddrs;
3231 
3233  "add address %s\n",
3234  GNUNET_a2s (in, in_len));
3235 
3236  saddrs = GNUNET_new (struct Addresses);
3237  saddrs->addr = in;
3238  saddrs->addr_len = in_len;
3240 
3242  "after add address %s\n",
3243  GNUNET_a2s (in, in_len));
3244 
3246  "add address %s\n",
3247  GNUNET_a2s (saddrs->addr, saddrs->addr_len));
3248 
3249  addrs_lens++;
3250 }
3251 
3252 
3260 static int
3261 init_socket (struct sockaddr *addr,
3262  socklen_t in_len)
3263 {
3264  struct sockaddr_storage in_sto;
3265  socklen_t sto_len;
3266  struct GNUNET_NETWORK_Handle *listen_sock;
3267  struct ListenTask *lt;
3268  int sockfd;
3269  struct GNUNET_HashCode h_sock;
3270 
3271  if (NULL == addr)
3272  {
3274  "Address is NULL.\n");
3275  return GNUNET_SYSERR;
3276  }
3277 
3279  "address %s\n",
3280  GNUNET_a2s (addr, in_len));
3281 
3282  listen_sock =
3283  GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3284  if (NULL == listen_sock)
3285  {
3287  return GNUNET_SYSERR;
3288  }
3289 
3290  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3291  {
3293  GNUNET_NETWORK_socket_close (listen_sock);
3294  listen_sock = NULL;
3295  return GNUNET_SYSERR;
3296  }
3297 
3298  if (GNUNET_OK !=
3299  GNUNET_NETWORK_socket_listen (listen_sock,
3300  5))
3301  {
3303  "listen");
3304  GNUNET_NETWORK_socket_close (listen_sock);
3305  listen_sock = NULL;
3306  return GNUNET_SYSERR;
3307  }
3308 
3309  /* We might have bound to port 0, allowing the OS to figure it out;
3310  thus, get the real IN-address from the socket */
3311  sto_len = sizeof(in_sto);
3312 
3313  if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3314  (struct sockaddr *) &in_sto,
3315  &sto_len))
3316  {
3317  memcpy (&in_sto, addr, in_len);
3318  sto_len = in_len;
3319  }
3320 
3321  // addr = (struct sockaddr *) &in_sto;
3322  in_len = sto_len;
3324  "Bound to `%s'\n",
3325  GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3326  stats = GNUNET_STATISTICS_create ("C-TCP", cfg);
3327 
3328  if (NULL == is)
3330 
3331  if (NULL == my_private_key)
3333  if (NULL == my_private_key)
3334  {
3335  GNUNET_log (
3337  _ (
3338  "Transport service is lacking key configuration settings. Exiting.\n"));
3339  if (NULL != resolve_request_handle)
3342  return GNUNET_SYSERR;
3343  }
3345  /* start listening */
3346 
3347  lt = GNUNET_new (struct ListenTask);
3348  lt->listen_sock = listen_sock;
3349 
3351  listen_sock,
3352  &listen_cb,
3353  lt);
3354 
3356  "creating hash\n");
3357  sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3358  GNUNET_CRYPTO_hash (&sockfd,
3359  sizeof(int),
3360  &h_sock);
3361 
3363  "creating map\n");
3364  if (NULL == lt_map)
3366 
3368  "creating map entry\n");
3371  &h_sock,
3372  lt,
3374 
3376  "map entry created\n");
3377 
3378  if (NULL == queue_map)
3380 
3381  if (NULL == ch)
3386  &mq_init,
3387  NULL,
3388  &enc_notify_cb,
3389  NULL);
3390 
3391  if (NULL == ch)
3392  {
3393  GNUNET_break (0);
3394  if (NULL != resolve_request_handle)
3397  return GNUNET_SYSERR;
3398  }
3399 
3400  add_addr (addr, in_len);
3401  return GNUNET_OK;
3402 
3403 }
3404 
3405 
3409 static void
3411 {
3412  struct sockaddr **saddrs;
3413  socklen_t *saddr_lens;
3414  int i;
3415  size_t len;
3416 
3418  "starting nat register!\n");
3419  len = 0;
3420  i = 0;
3421  saddrs = GNUNET_malloc ((addrs_lens) * sizeof(struct sockaddr *));
3422  saddr_lens = GNUNET_malloc ((addrs_lens) * sizeof(socklen_t));
3423  for (struct Addresses *pos = addrs_head; NULL != pos; pos = pos->next)
3424  {
3426  "registering address %s\n",
3428 
3429  saddr_lens[i] = addrs_head->addr_len;
3430  len += saddr_lens[i];
3431  saddrs[i] = GNUNET_memdup (addrs_head->addr, saddr_lens[i]);
3432  i++;
3433  }
3434 
3436  "registering addresses %lu %lu %lu %lu\n",
3437  (addrs_lens) * sizeof(struct sockaddr *),
3438  (addrs_lens) * sizeof(socklen_t),
3439  len,
3440  sizeof(COMMUNICATOR_CONFIG_SECTION));
3443  IPPROTO_TCP,
3444  addrs_lens,
3445  (const struct sockaddr **) saddrs,
3446  saddr_lens,
3447  &nat_address_cb,
3448  NULL /* FIXME: support reversal: #5529 */,
3449  NULL /* closure */);
3450  for (i = addrs_lens - 1; i >= 0; i--)
3451  GNUNET_free (saddrs[i]);
3452  GNUNET_free (saddrs);
3453  GNUNET_free (saddr_lens);
3454 
3455  if (NULL == nat)
3456  {
3457  GNUNET_break (0);
3458  if (NULL != resolve_request_handle)
3461  }
3462 }
3463 
3464 
3472 static void
3474  const struct sockaddr *addr,
3475  socklen_t in_len)
3476 {
3477  struct sockaddr_in *v4;
3478  struct sockaddr_in6 *v6;
3479  struct sockaddr *in;
3480 
3481  (void) cls;
3482  if (NULL != addr)
3483  {
3484  if (AF_INET == addr->sa_family)
3485  {
3486  v4 = (struct sockaddr_in *) addr;
3487  in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, bind_port);// _global);
3488  }
3489  else if (AF_INET6 == addr->sa_family)
3490  {
3491  v6 = (struct sockaddr_in6 *) addr;
3492  in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, bind_port);// _global);
3493  }
3494  else
3495  {
3497  "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
3498  addr->sa_family,
3499  AF_INET,
3500  AF_INET6);
3501  return;
3502  }
3503  init_socket (in, in_len);
3504  }
3505  else
3506  {
3508  "Address is NULL. This might be an error or the resolver finished resolving.\n");
3509  if (NULL == addrs_head)
3510  {
3512  "Resolver finished resolving, but we do not listen to an address!.\n");
3513  return;
3514  }
3515  nat_register ();
3516  }
3517 }
3518 
3519 
3528 static void
3529 run (void *cls,
3530  char *const *args,
3531  const char *cfgfile,
3532  const struct GNUNET_CONFIGURATION_Handle *c)
3533 {
3534  char *bindto;
3535  struct sockaddr *in;
3536  socklen_t in_len;
3537  struct sockaddr_in v4;
3538  struct sockaddr_in6 v6;
3539  char *start;
3540  unsigned int port;
3541  char dummy[2];
3542  char *rest = NULL;
3543  struct PortOnlyIpv4Ipv6 *po;
3544  socklen_t addr_len_ipv4;
3545  socklen_t addr_len_ipv6;
3546 
3547  (void) cls;
3548  cfg = c;
3549  if (GNUNET_OK !=
3552  "BINDTO",
3553  &bindto))
3554  {
3557  "BINDTO");
3558  return;
3559  }
3560  if (GNUNET_OK !=
3563  "MAX_QUEUE_LENGTH",
3564  &max_queue_length))
3566  if (GNUNET_OK !=
3569  "REKEY_INTERVAL",
3570  &rekey_interval))
3572 
3574  if (NULL == peerstore)
3575  {
3576  GNUNET_free (bindto);
3577  GNUNET_break (0);
3579  return;
3580  }
3581 
3583 
3584  if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
3585  {
3589  "address po %s\n",
3591  if (NULL != po->addr_ipv4)
3592  {
3594  }
3595  if (NULL != po->addr_ipv6)
3596  {
3599  }
3600  GNUNET_free (po);
3601  nat_register ();
3602  GNUNET_free (bindto);
3603  return;
3604  }
3605 
3606  start = extract_address (bindto);
3607  // FIXME: check for NULL == start...
3608  if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
3609  {
3610  bind_port = extract_port (bindto);
3611 
3612  in = tcp_address_to_sockaddr_numeric_v4 (&in_len, v4, bind_port);
3613  init_socket (in, in_len);
3614  nat_register ();
3615  GNUNET_free (start);
3616  GNUNET_free (bindto);
3617  return;
3618  }
3619 
3620  if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
3621  {
3622  bind_port = extract_port (bindto);
3623  in = tcp_address_to_sockaddr_numeric_v6 (&in_len, v6, bind_port);
3624  init_socket (in, in_len);
3625  nat_register ();
3626  GNUNET_free (start);
3627  GNUNET_free (bindto);
3628  return;
3629  }
3630 
3631  bind_port = extract_port (bindto);
3632  resolve_request_handle = GNUNET_RESOLVER_ip_get (strtok_r (bindto,
3633  ":",
3634  &rest),
3635  AF_UNSPEC,
3638  &port);
3639  GNUNET_free (bindto);
3640  GNUNET_free (start);
3641 }
3642 
3643 
3651 int
3652 main (int argc, char *const *argv)
3653 {
3654  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3656  };
3657  int ret;
3658 
3660  "transport",
3661  "Starting tcp communicator\n");
3662  if (GNUNET_OK !=
3663  GNUNET_STRINGS_get_utf8_args (argc, argv,
3664  &argc, &argv))
3665  return 2;
3666 
3667  ret = (GNUNET_OK ==
3668  GNUNET_PROGRAM_run (argc,
3669  argv,
3670  "gnunet-communicator-tcp",
3671  _ ("GNUnet TCP communicator"),
3672  options,
3673  &run,
3674  NULL))
3675  ? 0
3676  : 1;
3677  GNUNET_free_nz ((void *) argv);
3678  return ret;
3679 }
3680 
3681 
3682 /* end of gnunet-communicator-tcp.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int res
static void done()
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
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.
static void queue_finish(struct Queue *queue)
Append a 'finish' message to the outgoing transmission.
static struct GNUNET_CONTAINER_MultiPeerMap * queue_map
Queues (map from peer identity to struct Queue)
static void boot_queue(struct Queue *queue)
Add the given queue to our internal data structure.
unsigned int bind_port
The port the communicator should be assigned to.
struct ListenTask * lts_tail
Head of DLL with ListenTask.
static size_t try_handle_plaintext(struct Queue *queue)
Test if we have received a full message in plaintext.
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.
size_t unverified_size
Size of data received without KX challenge played back.
static struct GNUNET_PeerIdentity my_identity
Our public key.
static int get_queue_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all message queues to clean up.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static void mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
#define INITIAL_CORE_KX_SIZE
Size of the initial core key exchange messages.
static void do_rekey(struct Queue *queue, const struct TCPRekey *rekey)
Handle rekey message on queue.
static int init_socket(struct sockaddr *addr, socklen_t in_len)
This method launch network interactions for each address we like to bind to.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static void listen_cb(void *cls)
We have been notified that our listen socket has something to read.
static void rekey_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY where...
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
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...
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
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 (!...
static void handshake_ack_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for handshake ack monotime value is finished.
static struct GNUNET_PEERSTORE_Handle * peerstore
Database for peer's HELLOs.
static struct ProtoQueue * proto_tail
Protoqueues DLL tail.
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...
static int get_lt_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all ListenTasks to clean up.
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static struct PortOnlyIpv4Ipv6 * tcp_address_to_sockaddr_port_only(const char *bindto, unsigned int *port)
Convert TCP bind specification to a struct PortOnlyIpv4Ipv6 *
#define BUF_SIZE
Size of our IO buffers for ciphertext data.
static void reschedule_queue_timeout(struct Queue *queue)
Increment queue timeout due to activity.
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
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 char * extract_address(const char *bindto)
This Method extracts the address part of the BINDTO string.
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 ...
static void init_socket_resolv(void *cls, const struct sockaddr *addr, socklen_t in_len)
This method is the callback called by the resolver API, and wraps method init_socket.
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
static unsigned long long max_queue_length
Maximum queue length before we stop reading towards the transport service.
struct GNUNET_RESOLVER_RequestHandle * resolve_request_handle
Handle for DNS lookup of bindto address.
static void nat_register()
This method reads from the DLL addrs_head to register them at the NAT service.
int addrs_lens
Number of addresses in the DLL for register at NAT service.
static struct sockaddr * tcp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert TCP bind specification to a struct sockaddr *
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
struct ListenTask * lts_head
Head of DLL with ListenTasks.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
#define PROTO_QUEUE_TIMEOUT
How long do we wait until we must have received the initial KX?
static void queue_read(void *cls)
Queue read task.
#define REKEY_MAX_BYTES
How often do we rekey based on number of bytes transmitted? (additionally randomized).
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
#define INITIAL_KX_SIZE
Size of the initial key exchange message sent first in both directions.
static void handshake_ack_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_A...
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...
static void setup_out_cipher(struct Queue *queue)
Setup cipher for outgoing data stream based on target and our ephemeral private key.
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.
static struct sockaddr * tcp_address_to_sockaddr_numeric_v4(socklen_t *sock_len, struct sockaddr_in v4, unsigned int port)
Convert a struct sockaddr_in4 to astruct sockaddr *`.
static void handshake_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for handshake monotime is finished.
static void send_challenge(struct GNUNET_CRYPTO_ChallengeNonceP challenge, struct Queue *queue)
Sending challenge with TcpConfirmationAck back to sender of ephemeral key.
static void rekey_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for rekey monotime value is finished.
static struct ProtoQueue * proto_head
Protoqueues DLL head.
static void setup_in_cipher(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct Queue *queue)
Setup cipher of queue for decryption.
int shutdown_running
A flag indicating we are already doing a shutdown.
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.
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.
#define DEFAULT_REKEY_INTERVAL
How often do we rekey based on time (at least)
int main(int argc, char *const *argv)
The main function for the UNIX communicator.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
static void queue_write(void *cls)
We have been notified that our socket is ready to write.
static void add_addr(struct sockaddr *in, socklen_t in_len)
This method adds addresses to the DLL, that are later register at the NAT service.
static void handshake_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE w...
struct Addresses * addrs_head
Head of DLL with addresses we like to register at NAT servcie.
struct Addresses * addrs_tail
Head of DLL with addresses we like to register at NAT servcie.
#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...
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 unsigned int extract_port(const char *addr_and_port)
This Method extracts the port part of the BINDTO string.
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.
static void start_initial_kx_out(struct Queue *queue)
Initialize our key material for outgoing transmissions and inform the other peer about it.
static void free_proto_queue(struct ProtoQueue *pq)
Closes socket and frees memory associated with pq.
static struct GNUNET_CONTAINER_MultiHashMap * lt_map
ListenTasks (map from socket to struct ListenTask)
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.
static struct sockaddr * tcp_address_to_sockaddr_numeric_v6(socklen_t *sock_len, struct sockaddr_in6 v6, unsigned int port)
Convert a struct sockaddr_in6 to astruct sockaddr *`.
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static char * value
Value of the record to add/remove.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static struct GNUNET_MQ_Envelope * ac
Handle to current GNUNET_PEERINFO_add_peer() operation.
static char buf[2048]
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static void queue(const char *hostname)
Add hostname to the list of requests to be made.
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_log(kind,...)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_MIN(a, b)
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't this be the standard hmac function and the abo...
Definition: crypto_hash.c:299
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK
Signature by a peer sending back the nonce received at initial handshake.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY
Signature used by TCP communicator rekey.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE
Signature used by TCP communicator handshake.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:435
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
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's key from the file specified in the configuration.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
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:197
enum GNUNET_GenericReturnValue 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:718
enum GNUNET_GenericReturnValue 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:758
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
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:213
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue 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:69
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
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).
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.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.
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).
const char * GNUNET_p2s(const struct GNUNET_CRYPTO_EddsaPublicKey *p)
Convert a public key value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
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:467
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:423
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:701
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
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:386
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1023
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:731
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition: network.c:606
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition: network.c:392
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:855
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:760
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
enum GNUNET_GenericReturnValue 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:439
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:656
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:36
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:433
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:412
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
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
struct GNUNET_PEERSTORE_StoreContext * GNUNET_PEERSTORE_store(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Store a new entry in the PEERSTORE.
void GNUNET_PEERSTORE_store_cancel(struct GNUNET_PEERSTORE_StoreContext *sc)
Cancel a store request.
void GNUNET_PEERSTORE_iterate_cancel(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iterate request Please do not call after the iterate request is done.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE
Key used to store sender's monotonic time from handshake message.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h, int sync_first)
Disconnect from the PEERSTORE service.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK
Key used to store sender's monotonic time from handshake ack message.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY
Key used to store sender's monotonic time from rekey message.
struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iterate(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Iterate over records matching supplied key information.
@ GNUNET_PEERSTORE_STOREOPTION_REPLACE
Delete any previous values for the given key before storing the given value.
enum GNUNET_GenericReturnValue 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,...
Definition: program.c:399
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK
TCP communicator confirmation ack.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH
TCP communicator end of stream.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX
TCP communicator payload box.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY
TCP communicator rekey message.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
Definition: resolver_api.c:939
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:533
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:1281
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:1573
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:1502
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,...
Definition: scheduler.c:1316
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1223
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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:404
#define GNUNET_TIME_UNIT_MINUTES
One minute.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
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:315
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:859
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:570
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
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.
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.
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 GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
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, uint64_t q_len, uint32_t priority, 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...
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.
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
GNUNET_TRANSPORT_ConnectionStatus
Possible states of a connection.
void GNUNET_TRANSPORT_communicator_address_remove_all(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Notify transport service that this communicator no longer provides all its addresses for this peer.
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.
@ GNUNET_TRANSPORT_CC_RELIABLE
Transmission is reliabile (with ACKs), e.g.
@ GNUNET_TRANSPORT_CS_INBOUND
this is an inbound connection (communicator initiated)
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
#define max(x, y)
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:423
DLL to store the addresses we like to register at NAT service.
struct Addresses * next
Kept in a DLL.
struct Addresses * prev
Kept in a DLL.
struct sockaddr * addr
Address we like to register at NAT service.
socklen_t addr_len
Length of address we like to register at NAT service.
Internal representation of the hash map.
Internal representation of the hash map.
Type of a nonce used for challenges.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Private ECC key encoded for transmission.
an ECC signature using EdDSA.
Definition of a command line option.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle for active NAT registrations.
Definition: nat_api.c:72
handle to a socket
Definition: network.c:53
Handle to the interface scanner.
Definition: nt.c:111
Handle to the PEERSTORE service.
Definition: peerstore_api.c:41
Context for a iterate request.
Single PEERSTORE record.
Context for a store request.
Definition: peerstore_api.c:97
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Handle to a request given to the resolver.
Definition: resolver_api.c:103
Entry in list of pending tasks.
Definition: scheduler.c:135
Handle for the service.
A 256-bit hashcode.
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Internal representation of an address a communicator is currently providing for the transport service...
Opaque handle to the transport service for communicators.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Struct to use as closure.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
struct GNUNET_SCHEDULER_Task * listen_task
ID of listen task.
In case of port only configuration we like to bind to ipv4 and ipv6 addresses.
struct sockaddr * addr_ipv4
Ipv4 address we like to bind to.
struct sockaddr * addr_ipv6
Ipv6 address we like to bind to.
socklen_t addr_len_ipv6
Length of ipv6 address.
socklen_t addr_len_ipv4
Length of ipv4 address.
Handle for an incoming connection where we do not yet have enough information to setup a full queue.
socklen_t address_len
Length of the address.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
size_t ibuf_off
Current offset for reading into ibuf.
struct GNUNET_TIME_Absolute timeout
Timeout for this protoqueue.
struct GNUNET_NETWORK_Handle * sock
socket that we transmit all data with on this queue
struct sockaddr * address
Address of the other peer.
struct ProtoQueue * prev
Kept in a DLL.
char ibuf[(sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof(struct TCPConfirmation))]
Buffer for reading all the information we need to upgrade from protoqueue to queue.
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
struct ProtoQueue * next
Kept in a DLL.
Handle for a queue.
unsigned int backpressure
How may messages did we pass from this queue to CORE for which we have yet to receive an acknoweldgem...
struct GNUNET_NETWORK_Handle * sock
socket that we transmit all data with on this queue
struct GNUNET_PEERSTORE_IterateContext * handshake_ack_monotime_get
Iteration Context for retrieving the monotonic time send with the handshake ack.
int rekeyed
GNUNET_YES if we just rekeyed and must thus possibly re-decrypt ciphertext.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_TRANSPORT_QueueHandle * qh
handle for this queue with the ch.
struct GNUNET_HashCode out_hmac
Shared secret for HMAC generation on outgoing data, ratcheted after each operation.
int finishing
Did we enqueue a finish message and are closing down the queue?
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * mq
Message queue we are providing for the ch.
unsigned long long bytes_in_queue
Number of bytes we currently have in our write queue.
char pread_buf[UINT16_MAX+1+sizeof(struct TCPBox)]
Plaintext buffer for decrypted plaintext.
int destroyed
Did we technically destroy this queue, but kept the allocation around because of backpressure not bei...
struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral
Our ephemeral key.
struct GNUNET_PEERSTORE_StoreContext * rekey_monotime_sc
Store Context for retrieving the monotonic time send with key for rekeying.
size_t cwrite_off
At which offset in the ciphertext write buffer should we append more ciphertext from reading next?
struct GNUNET_PEERSTORE_IterateContext * rekey_monotime_get
Iteration Context for retrieving the monotonic time send with key for rekeying.
char cread_buf[(2 *64 *1024+sizeof(struct TCPBox))]
Buffer for reading ciphertext from network into.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_CRYPTO_ChallengeNonceP challenge_received
Challenge value received.
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
uint64_t rekey_left_bytes
How many more bytes may we sent with the current out_cipher before we should rekey?
int mq_awaits_continue
Is MQ awaiting a GNUNET_MQ_impl_send_continue() call?
gcry_cipher_hd_t in_cipher
cipher for decryption of incoming data.
struct GNUNET_PEERSTORE_StoreContext * handshake_ack_monotime_sc
Store Context for retrieving the monotonic time send with the handshake ack.
size_t pwrite_off
At which offset in the plaintext output buffer should we append more plaintext for encryption next?
struct GNUNET_TIME_Absolute timeout
Timeout for this queue.
struct sockaddr * address
Address of the other peer.
size_t cread_off
At which offset in the ciphertext read buffer should we append more ciphertext for transmission next?
struct GNUNET_TIME_Absolute rekey_time
Until what time may we sent with the current out_cipher before we should rekey?
struct GNUNET_PeerIdentity target
To whom are we talking to.
char cwrite_buf[(2 *64 *1024+sizeof(struct TCPBox))]
buffer for writing ciphertext to network.
struct GNUNET_PEERSTORE_StoreContext * handshake_monotime_sc
Store Context for retrieving the monotonic time send with the handshake.
size_t pread_off
At which offset in the plaintext input buffer should we append more plaintext from decryption next?
enum GNUNET_TRANSPORT_ConnectionStatus cs
The connection status of this queue.
gcry_cipher_hd_t out_cipher
cipher for encryption of outgoing data.
char pwrite_buf[UINT16_MAX+1+sizeof(struct TCPBox)]
Plaintext buffer for messages to be encrypted.
struct GNUNET_HashCode in_hmac
Shared secret for HMAC verification on incoming data.
struct GNUNET_PEERSTORE_IterateContext * handshake_monotime_get
Iteration Context for retrieving the monotonic time send with the handshake.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
struct GNUNET_SCHEDULER_Task * write_task
ID of write task for this connection.
struct GNUNET_TIME_AbsoluteNBO handshake_ack_monotonic_time
Monotonic time value for handshake ack message.
struct GNUNET_TIME_AbsoluteNBO rekey_monotonic_time
Monotonic time value for rekey message.
struct GNUNET_TIME_AbsoluteNBO handshake_monotonic_time
Monotonic time value for handshake message.
TCP message box.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
Ack for the encrypted continuation of TCP initial handshake.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK.
struct GNUNET_PeerIdentity sender
Sender's identity.
Encrypted continuation of TCP initial handshake.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
TCP rekey message box.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
New ephemeral key.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY.
Signature we use to verify that the ack from the receiver of the ephemeral key was really send by the...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the TCP connection (TCP server)
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key used by the sender.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the TCP connection (TCP server)
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key used by the sender.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the TCP connection (TCP server)
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.