GNUnet  0.19.5
gnunet-communicator-udp.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 
40 #include "platform.h"
41 #include "gnunet_common.h"
42 #include "gnunet_util_lib.h"
43 #include "gnunet_protocols.h"
44 #include "gnunet_signatures.h"
45 #include "gnunet_constants.h"
46 #include "gnunet_nt_lib.h"
47 #include "gnunet_nat_service.h"
51 
55 #define DEFAULT_REKEY_TIME_INTERVAL GNUNET_TIME_UNIT_DAYS
56 
60 #define PROTO_QUEUE_TIMEOUT GNUNET_TIME_UNIT_MINUTES
61 
65 #define BROADCAST_FREQUENCY GNUNET_TIME_UNIT_MINUTES
66 
70 #define INTERFACE_SCAN_FREQUENCY \
71  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
72 
77 #define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
78 
79 #define WORKING_QUEUE_INTERVALL \
80  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
81 
85 #define AES_KEY_SIZE (256 / 8)
86 
90 #define AES_IV_SIZE (96 / 8)
91 
95 #define GCM_TAG_SIZE (128 / 8)
96 
97 #define GENERATE_AT_ONCE 16
98 
108 #define KCN_THRESHOLD 96
109 
116 #define KCN_TARGET 128
117 
127 #define MAX_SQN_DELTA 160
128 
138 #define MAX_SECRETS 256
139 
144 #define DEFAULT_REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU)
145 
150 #define COMMUNICATOR_ADDRESS_PREFIX "udp"
151 
155 #define COMMUNICATOR_CONFIG_SECTION "communicator-udp"
156 
158 
159 
166 {
171 
176 
181 
186 
192 };
193 
194 
199 struct InitialKX
200 {
205 
211 
212 };
213 
214 
220 {
225 
230 
236 
237  /* followed by messages */
238 
239  /* padding may follow actual messages */
240 };
241 
242 
247 struct UDPAck
248 {
253 
259 
263  struct GNUNET_HashCode cmac;
264 };
265 
266 
276 {
281 
286 
290  struct GNUNET_HashCode h_address;
291 };
292 
293 
301 {
306 
312 };
313 
314 
319 struct UDPBox
320 {
328  struct GNUNET_ShortHashCode kid;
329 
338 
339 };
340 
344 struct UDPRekey
345 {
350 
355 };
356 
358 
362 struct SharedSecret;
363 
364 
370 {
375 
380 
388  struct GNUNET_ShortHashCode kid;
389 
393  struct SharedSecret *ss;
394 
398  uint32_t sequence_number;
399 };
400 
401 
406 struct SenderAddress;
407 
412 struct ReceiverAddress;
413 
418 {
423 
428 
433 
438 
443 
448 
452  struct GNUNET_HashCode master;
453 
457  struct GNUNET_HashCode cmac;
458 
463  uint32_t sequence_used;
464 
471 
475  unsigned int active_kce_count;
476 
480  size_t bytes_sent;
481 
486 
491 };
492 
493 
499 {
504 
509 
514 
519 
523  struct sockaddr *address;
524 
528  socklen_t address_len;
529 
534 
538  unsigned int num_secrets;
539 
544  unsigned int acks_available;
545 
549  enum GNUNET_NetworkType nt;
550 
555 
560 
565 
570 };
571 
572 
578 {
583 
588 
593 
598 
604 
608  struct sockaddr *address;
609 
613  socklen_t address_len;
614 
619 
624 
629 
634 
639 
644 
648  size_t kx_mtu;
649 
653  size_t d_mtu;
654 
658  unsigned int num_secrets;
659 
664  unsigned int acks_available;
665 
669  enum GNUNET_NetworkType nt;
670 
675 };
676 
681 {
686 
691 
696 
700  struct sockaddr *sa;
701 
705  struct sockaddr *ba;
706 
710  struct UDPBroadcast bcm;
711 
716  struct ipv6_mreq mcreq;
717 
721  socklen_t salen;
722 
726  int found;
727 };
728 
733 
737 static unsigned long long rekey_max_bytes;
738 
743 
748 
753 
758 
763 
768 
773 
778 
783 
788 
793 
798 
803 
807 static int have_v6_socket;
808 
812 static struct GNUNET_PeerIdentity my_identity;
813 
818 
822 static const struct GNUNET_CONFIGURATION_Handle *cfg;
823 
828 
833 
837 static struct GNUNET_NAT_Handle *nat;
838 
842 static uint16_t my_port;
843 
844 
850 static void
852 {
853  if (AF_INET6 == bi->sa->sa_family)
854  {
855  /* Leave the multicast group */
857  IPPROTO_IPV6,
858  IPV6_LEAVE_GROUP,
859  &bi->mcreq,
860  sizeof(bi->mcreq)))
861  {
863  }
864  }
867  GNUNET_free (bi->sa);
868  GNUNET_free (bi->ba);
869  GNUNET_free (bi);
870 }
871 
872 
878 static void
880 {
881 
882  receiver->receiver_destroy_called = GNUNET_YES;
883 
885  "Disconnecting receiver for peer `%s'\n",
886  GNUNET_i2s (&receiver->target));
887  if (NULL != receiver->kx_qh)
888  {
890  receiver->kx_qh = NULL;
891  receiver->kx_mq = NULL;
892  }
893  if (NULL != receiver->d_qh)
894  {
896  receiver->d_qh = NULL;
897  }
900  &receiver->target,
901  receiver));
904  "# receivers active",
906  GNUNET_NO);
907  GNUNET_free (receiver->address);
908  GNUNET_free (receiver->foreign_addr);
910 }
911 
912 
918 static void
920 {
921  struct SharedSecret *ss = kce->ss;
922 
923  ss->active_kce_count--;
924  ss->sender->acks_available--;
927  &kce->kid,
928  kce));
929  GNUNET_free (kce);
930 }
931 
932 
940 static void
941 get_kid (const struct GNUNET_HashCode *msec,
942  uint32_t serial,
943  struct GNUNET_ShortHashCode *kid)
944 {
945  uint32_t sid = htonl (serial);
946 
947  GNUNET_CRYPTO_hkdf (kid,
948  sizeof(*kid),
949  GCRY_MD_SHA512,
950  GCRY_MD_SHA256,
951  &sid,
952  sizeof(sid),
953  msec,
954  sizeof(*msec),
955  "UDP-KID",
956  strlen ("UDP-KID"),
957  NULL,
958  0);
959 }
960 
961 
968 static void
969 kce_generate (struct SharedSecret *ss, uint32_t seq)
970 {
971  struct KeyCacheEntry *kce;
972 
973  GNUNET_assert (0 < seq);
974  kce = GNUNET_new (struct KeyCacheEntry);
975  kce->ss = ss;
976  kce->sequence_number = seq;
977  get_kid (&ss->master, seq, &kce->kid);
979  ss->active_kce_count++;
982  key_cache,
983  &kce->kid,
984  kce,
987  "# KIDs active",
989  GNUNET_NO);
990 }
991 
992 
999 static int
1001 {
1002  struct SenderAddress *sender;
1003  struct ReceiverAddress *receiver;
1004  struct KeyCacheEntry *kce;
1005 
1007  "secret %s destroy %u\n",
1008  GNUNET_h2s (&ss->master),
1009  ss->sequence_allowed);
1010  if (NULL != (sender = ss->sender))
1011  {
1012  GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1013  sender->num_secrets--;
1015  "%u sender->num_secrets\n",
1016  receiver->num_secrets);
1017  if (NULL != ss->sender->kce_task)
1018  {
1020  ss->sender->kce_task = NULL;
1021  }
1022  }
1023  if (NULL != (receiver = ss->receiver))
1024  {
1025  GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1026  receiver->num_secrets--;
1027  receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1029  "%u receiver->num_secrets\n",
1030  receiver->num_secrets);
1031  }
1032  while (NULL != (kce = ss->kce_head))
1033  kce_destroy (kce);
1034  GNUNET_STATISTICS_update (stats, "# Secrets active", -1, GNUNET_NO);
1036  "# KIDs active",
1038  GNUNET_NO);
1039  GNUNET_free (ss);
1040  return GNUNET_YES;
1041 }
1042 
1043 
1050 static void
1052 {
1054  GNUNET_assert (
1055  GNUNET_YES ==
1057  GNUNET_assert (sender == GNUNET_CONTAINER_heap_remove_node (sender->hn));
1059  "# senders active",
1061  GNUNET_NO);
1062  GNUNET_free (sender->address);
1063  GNUNET_free (sender);
1064 }
1065 
1066 
1075 static void
1076 get_iv_key (const struct GNUNET_HashCode *msec,
1077  uint32_t serial,
1078  char key[AES_KEY_SIZE],
1079  char iv[AES_IV_SIZE])
1080 {
1081  uint32_t sid = htonl (serial);
1082  char res[AES_KEY_SIZE + AES_IV_SIZE];
1083 
1085  sizeof(res),
1086  GCRY_MD_SHA512,
1087  GCRY_MD_SHA256,
1088  &sid,
1089  sizeof(sid),
1090  msec,
1091  sizeof(*msec),
1092  "UDP-IV-KEY",
1093  strlen ("UDP-IV-KEY"),
1094  NULL,
1095  0);
1096  memcpy (key, res, AES_KEY_SIZE);
1097  memcpy (iv, &res[AES_KEY_SIZE], AES_IV_SIZE);
1098 }
1099 
1100 
1106 static void
1108 {
1109  sender->timeout =
1112 }
1113 
1114 
1120 static void
1122 {
1123  receiver->timeout =
1126  receiver->timeout.abs_value_us);
1127 }
1128 
1129 
1135 static void
1136 check_timeouts (void *cls)
1137 {
1138  struct GNUNET_TIME_Relative st;
1139  struct GNUNET_TIME_Relative rt;
1140  struct GNUNET_TIME_Relative delay;
1141  struct ReceiverAddress *receiver;
1142  struct SenderAddress *sender;
1143 
1144  (void) cls;
1145  timeout_task = NULL;
1147  while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap)))
1148  {
1150  if (0 != rt.rel_value_us)
1151  break;
1153  "Receiver timed out\n");
1155  }
1157  while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1158  {
1159  if (GNUNET_YES != sender->sender_destroy_called)
1160  {
1162  if (0 != st.rel_value_us)
1163  break;
1164  sender_destroy (sender);
1165  }
1166  }
1168  if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1170 }
1171 
1172 
1178 static void
1180 {
1181  GNUNET_CRYPTO_hkdf (&ss->cmac,
1182  sizeof(ss->cmac),
1183  GCRY_MD_SHA512,
1184  GCRY_MD_SHA256,
1185  "CMAC",
1186  strlen ("CMAC"),
1187  &ss->master,
1188  sizeof(ss->master),
1189  "UDP-CMAC",
1190  strlen ("UDP-CMAC"),
1191  NULL,
1192  0);
1193 }
1194 
1195 
1204 static void
1206  const void *plaintext,
1207  size_t plaintext_len)
1208 {
1209  const struct GNUNET_MessageHeader *hdr = plaintext;
1210  const char *pos = plaintext;
1211 
1212  while (ntohs (hdr->size) <= plaintext_len)
1213  {
1215  "# bytes given to core",
1216  ntohs (hdr->size),
1217  GNUNET_NO);
1219  "Giving %u bytes to TNG\n", ntohs (hdr->size));
1222  &sender->target,
1223  hdr,
1225  NULL /* no flow control possible */
1226  ,
1227  NULL));
1228  /* move on to next message, if any */
1229  plaintext_len -= ntohs (hdr->size);
1230  if (plaintext_len < sizeof(*hdr))
1231  break;
1232  pos += ntohs (hdr->size);
1233  hdr = (const struct GNUNET_MessageHeader *) pos;
1234  // TODO for now..., we do not actually sen >1msg or have a way of telling
1235  // if we are done
1236  break;
1237  }
1239  "# bytes padding discarded",
1240  plaintext_len,
1241  GNUNET_NO);
1242 }
1243 
1244 
1253 static void
1254 setup_cipher (const struct GNUNET_HashCode *msec,
1255  uint32_t serial,
1256  gcry_cipher_hd_t *cipher)
1257 {
1258  char key[AES_KEY_SIZE];
1259  char iv[AES_IV_SIZE];
1260  int rc;
1261 
1262  GNUNET_assert (0 ==
1263  gcry_cipher_open (cipher,
1264  GCRY_CIPHER_AES256 /* low level: go for speed */,
1265  GCRY_CIPHER_MODE_GCM,
1266  0 /* flags */));
1267  get_iv_key (msec, serial, key, iv);
1268  rc = gcry_cipher_setkey (*cipher, key, sizeof(key));
1269  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1270  rc = gcry_cipher_setiv (*cipher, iv, sizeof(iv));
1271  GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
1272 }
1273 
1274 
1287 static int
1288 try_decrypt (const struct SharedSecret *ss,
1289  const uint8_t *tag,
1290  uint32_t serial,
1291  const char *in_buf,
1292  size_t in_buf_size,
1293  char *out_buf)
1294 {
1295  gcry_cipher_hd_t cipher;
1296 
1297  setup_cipher (&ss->master, serial, &cipher);
1298  GNUNET_assert (
1299  0 ==
1300  gcry_cipher_decrypt (cipher, out_buf, in_buf_size, in_buf, in_buf_size));
1301  if (0 != gcry_cipher_checktag (cipher, tag, GCM_TAG_SIZE))
1302  {
1303  gcry_cipher_close (cipher);
1305  "# AEAD authentication failures",
1306  1,
1307  GNUNET_NO);
1308  return GNUNET_SYSERR;
1309  }
1310  gcry_cipher_close (cipher);
1311  return GNUNET_OK;
1312 }
1313 
1314 
1321 static struct SharedSecret *
1323 {
1324  struct SharedSecret *ss;
1325 
1326  ss = GNUNET_new (struct SharedSecret);
1328  calculate_cmac (ss);
1329  return ss;
1330 }
1331 
1332 
1340 static struct SharedSecret *
1342  struct ReceiverAddress *receiver)
1343 {
1344  struct SharedSecret *ss;
1345  struct GNUNET_HashCode k;
1346 
1347  GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral, &k);
1348  ss = GNUNET_new (struct SharedSecret);
1349  memcpy (&ss->master, &k, sizeof (k));
1350  calculate_cmac (ss);
1351  ss->receiver = receiver;
1352  GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1353  receiver->num_secrets++;
1354  GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
1355  return ss;
1356 }
1357 
1358 
1366 static void
1368 
1369 
1377 static enum GNUNET_GenericReturnValue
1378 purge_secrets (struct SharedSecret *ss_list_tail)
1379 {
1380  struct SharedSecret *pos;
1381  struct SharedSecret *ss_to_purge;
1382  int deleted = 0;
1383 
1385  "Purging secrets.\n");
1386  pos = ss_list_tail;
1387  while (NULL != pos)
1388  {
1389  ss_to_purge = pos;
1390  pos = pos->prev;
1391 
1392  // FIXME we may also want to purge old unacked.
1393  if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1394  {
1395  secret_destroy (ss_to_purge);
1396  deleted++;
1397  }
1398  }
1400  "Finished purging all, deleted %u.\n", deleted);
1401 }
1402 
1403 
1404 static void
1405 add_acks (struct SharedSecret *ss, int acks_to_add)
1406 {
1407 
1408  struct ReceiverAddress *receiver = ss->receiver;
1409 
1410  GNUNET_assert (NULL != ss);
1411  GNUNET_assert (NULL != receiver);
1412 
1413  if (NULL == receiver->d_qh)
1414  {
1415  receiver->d_qh =
1417  &receiver->target,
1418  receiver->foreign_addr,
1419  receiver->d_mtu,
1420  acks_to_add,
1421  1, /* Priority */
1422  receiver->nt,
1424  receiver->d_mq);
1425  }
1426  else
1427  {
1429  receiver->d_qh,
1430  acks_to_add,
1431  1);
1432  }
1433 
1435  "Tell transport we have %u more acks!\n",
1436  acks_to_add);
1437 
1438  // Until here for alternativ 1
1439 
1440  /* move ss to head to avoid discarding it anytime soon! */
1441 
1442  GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1443  GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1444 }
1445 
1446 
1457 static int
1458 handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
1459 {
1460  const struct UDPAck *ack = cls;
1461  struct ReceiverAddress *receiver = value;
1462  uint32_t acks_to_add;
1463  uint32_t allowed;
1464 
1466  "in handle ack with cmac %s\n",
1467  GNUNET_h2s (&ack->cmac));
1468 
1469  (void) pid;
1470  for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1471  {
1472  if (0 == memcmp (&ack->cmac, &ss->cmac, sizeof(struct GNUNET_HashCode)))
1473  {
1474 
1476  "Found matching cmac\n");
1477 
1478  allowed = ntohl (ack->sequence_ack);
1479 
1480  if (allowed <= ss->sequence_allowed)
1481  {
1483  "Ignoring ack, not giving us increased window\n.");
1484  return GNUNET_NO;
1485  }
1486  acks_to_add = (allowed - ss->sequence_allowed);
1487  GNUNET_assert (0 != acks_to_add);
1488  receiver->acks_available += (allowed - ss->sequence_allowed);
1489  ss->sequence_allowed = allowed;
1490  add_acks (ss, acks_to_add);
1492  "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1493  allowed,
1494  acks_to_add,
1495  receiver->acks_available,
1496  GNUNET_h2s (&ss->master));
1497  return GNUNET_NO;
1498  }
1499  }
1501  "Matching cmac not found for ack!\n");
1502  return GNUNET_YES;
1503 }
1504 
1505 
1514 static void
1516 {
1517  struct UDPAck ack;
1518  GNUNET_assert (NULL != ss->sender);
1520  "Considering SS UDPAck %s\n",
1521  GNUNET_i2s_full (&ss->sender->target));
1522 
1524  "Sender has %u acks available.\n",
1525  ss->sender->acks_available);
1526  /* drop ancient KeyCacheEntries */
1527  while ((NULL != ss->kce_head) &&
1528  (MAX_SQN_DELTA <
1530  kce_destroy (ss->kce_tail);
1531 
1532 
1534  ack.header.size = htons (sizeof(ack));
1535  ack.sequence_ack = htonl (ss->sequence_allowed);
1536  ack.cmac = ss->cmac;
1538  "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1539  GNUNET_i2s_full (&ss->sender->target),
1540  ss->sequence_allowed,
1541  GNUNET_h2s (&(ss->master)));
1543  &ss->sender->target,
1545  &ack.header);
1546 }
1547 
1548 
1549 static void
1550 kce_generate_cb (void *cls)
1551 {
1552  struct SharedSecret *ss = cls;
1553  static uint64_t kce_last_available = 0;
1554  ss->sender->kce_task = NULL;
1555 
1557  "Precomputing %u keys for master %s\n",
1559  GNUNET_h2s (&(ss->master)));
1560  if ((ss->override_available_acks != GNUNET_YES) &&
1561  (KCN_TARGET < ss->sender->acks_available))
1562  return;
1563  for (int i = 0; i < GENERATE_AT_ONCE; i++)
1564  kce_generate (ss, ++ss->sequence_allowed);
1565 
1570  if (KCN_TARGET > ss->sender->acks_available)
1571  {
1575  ss);
1576  return;
1577  }
1579  "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1583  consider_ss_ack (ss);
1584 }
1585 
1586 
1595 static void
1597  const void *buf,
1598  size_t buf_size)
1599 {
1600  const struct GNUNET_MessageHeader *hdr;
1601  const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_pubkey;
1602  const struct UDPAck *ack;
1603  const struct UDPRekey *rekey;
1604  struct SharedSecret *ss_rekey;
1605  const char *buf_pos = buf;
1606  size_t bytes_remaining = buf_size;
1607  uint16_t type;
1608 
1609  hdr = (struct GNUNET_MessageHeader*) buf_pos;
1610  if (sizeof(*hdr) > bytes_remaining)
1611  {
1612  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1613  return; /* no data left */
1614  }
1616  "try_handle_plaintext of size %lu (%u %lu) and type %u\n",
1617  bytes_remaining,
1618  ntohs (hdr->size),
1619  sizeof(*hdr),
1620  ntohs (hdr->type));
1621  if (ntohs (hdr->size) > bytes_remaining)
1622  return; /* buffer too short for indicated message length */
1623  type = ntohs (hdr->type);
1624  switch (type)
1625  {
1627  rekey = (struct UDPRekey*) buf_pos;
1628  ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1629  ss_rekey->sender = sender;
1630  GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1631  sender->num_secrets++;
1633  "Received rekey secret with cmac %s\n",
1634  GNUNET_h2s (&(ss_rekey->cmac)));
1636  "Received secret with master %s.\n",
1637  GNUNET_h2s (&(ss_rekey->master)));
1639  "We have %u sequence_allowed.\n",
1640  ss_rekey->sequence_allowed);
1642  "We have a sender %p\n",
1643  ss_rekey->sender);
1645  "We have %u acks available.\n",
1646  ss_rekey->sender->acks_available);
1648  ss_rekey->override_available_acks = GNUNET_YES;
1649  // FIXME
1653  ss_rekey);
1654  // FIXME: Theoretically, this could be an Ack
1655  buf_pos += ntohs (hdr->size);
1656  bytes_remaining -= ntohs (hdr->size);
1657  pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1658  if (sender->num_secrets > MAX_SECRETS)
1659  {
1660  if (GNUNET_NO == purge_secrets (sender->ss_tail))
1661  {
1662  // No secret purged. Delete oldest.
1663  secret_destroy (sender->ss_tail);
1664  }
1665  }
1666  break;
1668  /* lookup master secret by 'cmac', then update sequence_max */
1669  ack = (struct UDPAck*) buf_pos;
1671  &sender->target,
1672  &handle_ack,
1673  (void *) ack);
1674  /* There could be more messages after the ACK, handle those as well */
1675  buf_pos += ntohs (hdr->size);
1676  bytes_remaining -= ntohs (hdr->size);
1677  pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1678  break;
1679 
1681  /* skip padding */
1682  break;
1683 
1684  default:
1685  pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1686  }
1687  return;
1688 }
1689 
1690 
1698 static void
1699 decrypt_box (const struct UDPBox *box,
1700  size_t box_len,
1701  struct KeyCacheEntry *kce)
1702 {
1703  struct SharedSecret *ss = kce->ss;
1704  char out_buf[box_len - sizeof(*box)];
1705  uint16_t rekeying;
1706 
1707  GNUNET_assert (NULL != ss->sender);
1708  if (GNUNET_OK != try_decrypt (ss,
1709  box->gcm_tag,
1710  kce->sequence_number,
1711  (const char *) &box[1],
1712  sizeof(out_buf),
1713  out_buf))
1714  {
1715  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1717  "# Decryption failures with valid KCE",
1718  1,
1719  GNUNET_NO);
1720  kce_destroy (kce);
1721  return;
1722  }
1723  kce_destroy (kce);
1724  kce = NULL;
1726  "# bytes decrypted with BOX",
1727  sizeof(out_buf),
1728  GNUNET_NO);
1730  "# messages decrypted with BOX",
1731  1,
1732  GNUNET_NO);
1734  "decrypted UDPBox with kid %s\n",
1735  GNUNET_sh2s (&box->kid));
1736  try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1737  if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1738  (NULL == ss->sender->kce_task) &&
1740  {
1742  "Sender has %u ack left which is under threshold.\n",
1743  ss->sender->acks_available);
1747  ss);
1748  }
1749 }
1750 
1751 
1755 struct SearchContext
1756 {
1760  const struct sockaddr *address;
1761 
1765  socklen_t address_len;
1766 
1771 };
1772 
1773 
1782 static int
1784  const struct GNUNET_PeerIdentity *key,
1785  void *value)
1786 {
1787  struct SearchContext *sc = cls;
1788  struct SenderAddress *sender = value;
1789 
1790  if ((sender->address_len == sc->address_len) &&
1791  (0 == memcmp (sender->address, sc->address, sender->address_len)))
1792  {
1793  sc->sender = sender;
1794  return GNUNET_NO; /* stop iterating! */
1795  }
1796  return GNUNET_YES;
1797 }
1798 
1799 
1811 static struct SenderAddress *
1813  const struct sockaddr *address,
1814  socklen_t address_len)
1815 {
1816  struct SenderAddress *sender;
1817  struct SearchContext sc = { .address = address,
1818  .address_len = address_len,
1819  .sender = NULL };
1820 
1822  target,
1824  &sc);
1825  if (NULL != sc.sender)
1826  {
1827  reschedule_sender_timeout (sc.sender);
1828  return sc.sender;
1829  }
1830  sender = GNUNET_new (struct SenderAddress);
1831  sender->target = *target;
1835  senders,
1836  &sender->target,
1837  sender,
1840  "# senders active",
1842  GNUNET_NO);
1843  sender->timeout =
1846  sender,
1849  if (NULL == timeout_task)
1851  return sender;
1852 }
1853 
1854 
1862 static int
1864  const struct UDPConfirmation *uc)
1865 {
1866  struct UdpHandshakeSignature uhs;
1867 
1868  uhs.purpose.purpose = htonl (
1870  uhs.purpose.size = htonl (sizeof(uhs));
1871  uhs.sender = uc->sender;
1872  uhs.receiver = my_identity;
1873  uhs.ephemeral = *ephemeral;
1874  uhs.monotonic_time = uc->monotonic_time;
1877  &uhs,
1878  &uc->sender_sig,
1879  &uc->sender.public_key);
1880 }
1881 
1882 
1891 static char *
1892 sockaddr_to_udpaddr_string (const struct sockaddr *address,
1893  socklen_t address_len)
1894 {
1895  char *ret;
1896 
1897  switch (address->sa_family)
1898  {
1899  case AF_INET:
1900  GNUNET_asprintf (&ret,
1901  "%s-%s",
1903  GNUNET_a2s (address, address_len));
1904  break;
1905 
1906  case AF_INET6:
1907  GNUNET_asprintf (&ret,
1908  "%s-%s",
1910  GNUNET_a2s (address, address_len));
1911  break;
1912 
1913  default:
1914  GNUNET_assert (0);
1915  }
1916  return ret;
1917 }
1918 
1919 
1925 static void
1926 sock_read (void *cls)
1927 {
1928  struct sockaddr_storage sa;
1929  struct sockaddr_in *addr_verify;
1930  socklen_t salen = sizeof(sa);
1931  char buf[UINT16_MAX];
1932  ssize_t rcvd;
1933 
1934  (void) cls;
1936  udp_sock,
1937  &sock_read,
1938  NULL);
1939  while (1)
1940  {
1942  buf,
1943  sizeof(buf),
1944  (struct sockaddr *) &sa,
1945  &salen);
1946  if (-1 == rcvd)
1947  {
1948  if (EAGAIN == errno)
1949  break; // We are done reading data
1951  return;
1952  }
1954  "Read %lu bytes\n", rcvd);
1955 
1956  /* first, see if it is a UDPBox */
1957  if (rcvd > sizeof(struct UDPBox))
1958  {
1959  const struct UDPBox *box;
1960  struct KeyCacheEntry *kce;
1961 
1962  box = (const struct UDPBox *) buf;
1964  if (NULL != kce)
1965  {
1967  "Found KCE with kid %s\n",
1968  GNUNET_sh2s (&box->kid));
1969  decrypt_box (box, (size_t) rcvd, kce);
1970  continue;
1971  }
1972  }
1973 
1974  /* next, check if it is a broadcast */
1975  if (sizeof(struct UDPBroadcast) == rcvd)
1976  {
1977  const struct UDPBroadcast *ub;
1978  struct UdpBroadcastSignature uhs;
1979  struct GNUNET_PeerIdentity sender;
1980 
1981  addr_verify = GNUNET_memdup (&sa, salen);
1982  addr_verify->sin_port = 0;
1984  "received UDPBroadcast from %s\n",
1985  GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
1986  ub = (const struct UDPBroadcast *) buf;
1987  uhs.purpose.purpose = htonl (
1989  uhs.purpose.size = htonl (sizeof(uhs));
1990  uhs.sender = ub->sender;
1991  sender = ub->sender;
1992  if (0 == memcmp (&sender, &my_identity, sizeof (struct
1994  {
1996  "Received our own broadcast\n");
1997  GNUNET_free (addr_verify);
1998  continue;
1999  }
2001  "checking UDPBroadcastSignature for %s\n",
2002  GNUNET_i2s (&sender));
2003  GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2004  &uhs.h_address);
2005  if (GNUNET_OK ==
2008  &uhs,
2009  &ub->sender_sig,
2010  &ub->sender.public_key))
2011  {
2012  char *addr_s;
2013  enum GNUNET_NetworkType nt;
2014 
2015  addr_s =
2016  sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2017  GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2018  /* use our own mechanism to determine network type */
2019  nt =
2020  GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2022  "validating address %s received from UDPBroadcast\n",
2023  GNUNET_i2s (&sender));
2025  GNUNET_free (addr_s);
2026  GNUNET_free (addr_verify);
2027  continue;
2028  }
2029  else
2030  {
2032  "VerifyingPeer %s is verifying UDPBroadcast\n",
2033  GNUNET_i2s (&my_identity));
2035  "Verifying UDPBroadcast from %s failed\n",
2036  GNUNET_i2s (&ub->sender));
2037  }
2038  GNUNET_free (addr_verify);
2039  /* continue with KX, mostly for statistics... */
2040  }
2041 
2042 
2043  /* finally, test if it is a KX */
2044  if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2045  {
2047  "# messages dropped (no kid, too small for KX)",
2048  1,
2049  GNUNET_NO);
2050  continue;
2051  }
2053  "Got KX\n");
2054  {
2055  const struct InitialKX *kx;
2056  struct SharedSecret *ss;
2057  char pbuf[rcvd - sizeof(struct InitialKX)];
2058  const struct UDPConfirmation *uc;
2059  struct SenderAddress *sender;
2060 
2061  kx = (const struct InitialKX *) buf;
2062  ss = setup_shared_secret_dec (&kx->ephemeral);
2064  "Before DEC\n");
2065 
2066  if (GNUNET_OK != try_decrypt (ss,
2067  kx->gcm_tag,
2068  0,
2069  &buf[sizeof(*kx)],
2070  sizeof(pbuf),
2071  pbuf))
2072  {
2074  "Unable to decrypt tag, dropping...\n");
2075  GNUNET_free (ss);
2077  stats,
2078  "# messages dropped (no kid, AEAD decryption failed)",
2079  1,
2080  GNUNET_NO);
2081  continue;
2082  }
2084  "Before VERIFY\n");
2085 
2086  uc = (const struct UDPConfirmation *) pbuf;
2087  if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc))
2088  {
2089  GNUNET_break_op (0);
2090  GNUNET_free (ss);
2092  "# messages dropped (sender signature invalid)",
2093  1,
2094  GNUNET_NO);
2095  continue;
2096  }
2098  "Before SETUP_SENDER\n");
2099 
2100  calculate_cmac (ss);
2101  sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2102  ss->sender = sender;
2103  GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2104  if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2105  (NULL == ss->sender->kce_task) &&
2107  {
2108  // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix.
2112  ss);
2113  }
2114  sender->num_secrets++;
2115  GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2117  "# messages decrypted without BOX",
2118  1,
2119  GNUNET_NO);
2120  try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2121  if (sender->num_secrets > MAX_SECRETS)
2122  {
2123  if (GNUNET_NO == purge_secrets (sender->ss_tail))
2124  {
2125  // No secret purged. Delete oldest.
2126  secret_destroy (sender->ss_tail);
2127  }
2128  }
2129  }
2130  }
2131 }
2132 
2133 
2141 static struct sockaddr *
2142 udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
2143 {
2144  struct sockaddr *in;
2145  unsigned int port;
2146  char dummy[2];
2147  char *colon;
2148  char *cp;
2149 
2150  if (1 == sscanf (bindto, "%u%1s", &port, dummy))
2151  {
2152  /* interpreting value as just a PORT number */
2153  if (port > UINT16_MAX)
2154  {
2156  "BINDTO specification `%s' invalid: value too large for port\n",
2157  bindto);
2158  return NULL;
2159  }
2160  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2161  (GNUNET_YES ==
2164  "DISABLE_V6")))
2165  {
2166  struct sockaddr_in *i4;
2167 
2168  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2169  i4->sin_family = AF_INET;
2170  i4->sin_port = htons ((uint16_t) port);
2171  *sock_len = sizeof(struct sockaddr_in);
2172  in = (struct sockaddr *) i4;
2173  }
2174  else
2175  {
2176  struct sockaddr_in6 *i6;
2177 
2178  i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2179  i6->sin6_family = AF_INET6;
2180  i6->sin6_port = htons ((uint16_t) port);
2181  *sock_len = sizeof(struct sockaddr_in6);
2182  in = (struct sockaddr *) i6;
2183  }
2184  return in;
2185  }
2186  cp = GNUNET_strdup (bindto);
2187  colon = strrchr (cp, ':');
2188  if (NULL != colon)
2189  {
2190  /* interpret value after colon as port */
2191  *colon = '\0';
2192  colon++;
2193  if (1 == sscanf (colon, "%u%1s", &port, dummy))
2194  {
2195  /* interpreting value as just a PORT number */
2196  if (port > UINT16_MAX)
2197  {
2199  "BINDTO specification `%s' invalid: value too large for port\n",
2200  bindto);
2201  GNUNET_free (cp);
2202  return NULL;
2203  }
2204  }
2205  else
2206  {
2207  GNUNET_log (
2209  "BINDTO specification `%s' invalid: last ':' not followed by number\n",
2210  bindto);
2211  GNUNET_free (cp);
2212  return NULL;
2213  }
2214  }
2215  else
2216  {
2217  /* interpret missing port as 0, aka pick any free one */
2218  port = 0;
2219  }
2220  {
2221  /* try IPv4 */
2222  struct sockaddr_in v4;
2223 
2224  memset (&v4, 0, sizeof(v4));
2225  if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
2226  {
2227  v4.sin_family = AF_INET;
2228  v4.sin_port = htons ((uint16_t) port);
2229 #if HAVE_SOCKADDR_IN_SIN_LEN
2230  v4.sin_len = sizeof(struct sockaddr_in);
2231 #endif
2232  in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
2233  *sock_len = sizeof(struct sockaddr_in);
2234  GNUNET_free (cp);
2235  return in;
2236  }
2237  }
2238  {
2239  /* try IPv6 */
2240  struct sockaddr_in6 v6;
2241  const char *start;
2242 
2243  memset (&v6, 0, sizeof(v6));
2244  start = cp;
2245  if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2246  {
2247  start++; /* skip over '[' */
2248  cp[strlen (cp) - 1] = '\0'; /* eat ']' */
2249  }
2250  if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2251  {
2252  v6.sin6_family = AF_INET6;
2253  v6.sin6_port = htons ((uint16_t) port);
2254 #if HAVE_SOCKADDR_IN_SIN_LEN
2255  v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2256 #endif
2257  in = GNUNET_memdup (&v6, sizeof(v6));
2258  *sock_len = sizeof(v6);
2259  GNUNET_free (cp);
2260  return in;
2261  }
2262  }
2263  /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
2264  GNUNET_free (cp);
2265  return NULL;
2266 }
2267 
2268 
2276 static void
2277 do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2278 {
2279  char pad[pad_size];
2280 
2282  if (sizeof(pad) > sizeof(struct GNUNET_MessageHeader))
2283  {
2284  struct GNUNET_MessageHeader hdr =
2285  { .size = htons (sizeof(pad)),
2286  .type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD) };
2287 
2288  memcpy (pad, &hdr, sizeof(hdr));
2289  }
2290  GNUNET_assert (
2291  0 ==
2292  gcry_cipher_encrypt (out_cipher, dgram, sizeof(pad), pad, sizeof(pad)));
2293 }
2294 
2295 
2296 static void
2299 {
2300  uint16_t msize = ntohs (msg->size);
2301  struct UdpHandshakeSignature uhs;
2302  struct UDPConfirmation uc;
2303  struct InitialKX kx;
2304  char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2305  size_t dpos;
2306  gcry_cipher_hd_t out_cipher;
2307  struct SharedSecret *ss;
2308 
2309  if (msize > receiver->kx_mtu)
2310  {
2311  GNUNET_break (0);
2312  if (GNUNET_YES != receiver->receiver_destroy_called)
2314  return;
2315  }
2317 
2318  /* setup key material */
2319 
2321 
2322  if (receiver->num_secrets > MAX_SECRETS)
2323  {
2324  if (GNUNET_NO == purge_secrets (receiver->ss_tail))
2325  {
2326  // No secret purged. Delete oldest.
2327  secret_destroy (receiver->ss_tail);
2328  }
2329  }
2330 
2331  setup_cipher (&ss->master, 0, &out_cipher);
2332  /* compute 'uc' */
2333  uc.sender = my_identity;
2334  uc.monotonic_time =
2336  uhs.purpose.purpose = htonl (
2338  uhs.purpose.size = htonl (sizeof(uhs));
2339  uhs.sender = my_identity;
2340  uhs.receiver = receiver->target;
2341  uhs.monotonic_time = uc.monotonic_time;
2343  &uhs,
2344  &uc.sender_sig);
2345  /* Leave space for kx */
2346  dpos = sizeof(kx);
2347  /* Append encrypted uc to dgram */
2348  GNUNET_assert (0 == gcry_cipher_encrypt (out_cipher,
2349  &dgram[dpos],
2350  sizeof(uc),
2351  &uc,
2352  sizeof(uc)));
2353  dpos += sizeof(uc);
2354  /* Append encrypted payload to dgram */
2355  GNUNET_assert (
2356  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2357  dpos += msize;
2358  do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2359  /* Datagram starts with kx */
2360  kx.ephemeral = uhs.ephemeral;
2361  GNUNET_assert (
2362  0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2363  gcry_cipher_close (out_cipher);
2364  memcpy (dgram, &kx, sizeof(kx));
2366  dgram,
2367  sizeof(dgram),
2368  receiver->address,
2369  receiver->address_len))
2372  "Sending KX with payload size %u to %s\n",
2373  msize,
2374  GNUNET_a2s (receiver->address,
2375  receiver->address_len));
2376 }
2377 
2378 
2387 static void
2389  const struct GNUNET_MessageHeader *msg,
2390  void *impl_state)
2391 {
2392  struct ReceiverAddress *receiver = impl_state;
2393 
2394  GNUNET_assert (mq == receiver->kx_mq);
2397 }
2398 
2399 
2400 static void
2402  UDPRekey *rekey)
2403 {
2404  uint8_t is_ss_rekey_sequence_allowed_zero = GNUNET_NO;
2405  uint8_t is_acks_available_below = GNUNET_NO;
2406  uint8_t send_rekey = GNUNET_NO;
2407  struct SharedSecret *ss_rekey;
2408 
2410  /* setup key material */
2411  ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2412  receiver);
2413  ss_rekey->sequence_allowed = 0;
2415  "Setup secret with k = %s\n",
2416  GNUNET_h2s (&(ss_rekey->master)));
2418  "Setup secret with H(k) = %s\n",
2419  GNUNET_h2s (&(ss_rekey->cmac)));
2420 
2421  /* Append encrypted payload to dgram */
2423  rekey->header.size = htons (sizeof (struct UDPRekey));
2424 }
2425 
2426 
2435 static void
2437  const struct GNUNET_MessageHeader *msg,
2438  void *impl_state)
2439 {
2440  struct ReceiverAddress *receiver = impl_state;
2441  struct UDPRekey rekey;
2442  struct SharedSecret *ss;
2443  int inject_rekey = GNUNET_NO;
2444  uint16_t msize = ntohs (msg->size);
2445 
2446  GNUNET_assert (mq == receiver->d_mq);
2447  if ((msize > receiver->d_mtu) ||
2448  (0 == receiver->acks_available))
2449  {
2451  "msize: %u, mtu: %lu, acks: %u\n",
2452  msize,
2453  receiver->d_mtu,
2454  receiver->acks_available);
2455 
2456  GNUNET_break (0);
2457  if (GNUNET_YES != receiver->receiver_destroy_called)
2459  return;
2460  }
2462 
2463  if (receiver->num_secrets > MAX_SECRETS)
2464  {
2465  if (GNUNET_NO == purge_secrets (receiver->ss_tail))
2466  {
2467  // No secret purged. Delete oldest.
2468  secret_destroy (receiver->ss_tail);
2469  }
2470  }
2471  /* begin "BOX" encryption method, scan for ACKs from tail! */
2472  for (ss = receiver->ss_tail; NULL != ss; ss = ss->prev)
2473  {
2474  size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2475  if (ss->sequence_used >= ss->sequence_allowed)
2476  {
2478  "Skipping ss because no acks to use.\n");
2479  continue;
2480  }
2481  if (ss->bytes_sent >= rekey_max_bytes)
2482  {
2484  "Skipping ss because rekey bytes reached.\n");
2485  // FIXME cleanup ss with too many bytes sent!
2486  continue;
2487  }
2488  if (ss->bytes_sent > rekey_max_bytes * 0.7)
2489  {
2490  if (ss->rekey_initiated == GNUNET_NO)
2491  {
2493  "Injecting rekey for ss with byte sent %u\n",
2494  ss->bytes_sent);
2495  create_rekey (receiver, ss, &rekey);
2497  payload_len += sizeof (rekey);
2499  }
2500  }
2501  if (0 < ss->sequence_used)
2503  "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2504  GNUNET_h2s (&ss->master),
2505  ss->sequence_used,
2506  ss->sequence_allowed);
2507 
2508  char dgram[payload_len];
2509  struct UDPBox *box;
2510  gcry_cipher_hd_t out_cipher;
2511  size_t dpos;
2512 
2513  box = (struct UDPBox *) dgram;
2514  ss->sequence_used++;
2515  get_kid (&ss->master, ss->sequence_used, &box->kid);
2516  setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2517  /* Append encrypted payload to dgram */
2518  dpos = sizeof(struct UDPBox);
2519  if (GNUNET_YES == inject_rekey)
2520  {
2521  GNUNET_assert (
2522  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2523  &rekey, sizeof (rekey)));
2524  dpos += sizeof (rekey);
2525  }
2526  GNUNET_assert (
2527  0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2528  dpos += msize;
2529  do_pad (out_cipher, &dgram[dpos], sizeof(dgram) - dpos);
2530  GNUNET_assert (0 == gcry_cipher_gettag (out_cipher,
2531  box->gcm_tag,
2532  sizeof(box->gcm_tag)));
2533  gcry_cipher_close (out_cipher);
2534 
2536  dgram,
2537  payload_len, // FIXME why always send sizeof dgram?
2538  receiver->address,
2539  receiver->address_len))
2542  "Sending UDPBox with payload size %u, %u acks left, %u bytes sent\n",
2543  msize,
2544  receiver->acks_available);
2545  ss->bytes_sent += sizeof (dgram);
2546  receiver->acks_available--;
2548  return;
2549  }
2551  "No suitable ss found, sending as KX...\n");
2554 }
2555 
2556 
2565 static void
2566 mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
2567 {
2568  struct ReceiverAddress *receiver = impl_state;
2570  "Default MQ destroyed\n");
2571  if (mq == receiver->d_mq)
2572  {
2573  receiver->d_mq = NULL;
2574  if (GNUNET_YES != receiver->receiver_destroy_called)
2576  }
2577 }
2578 
2579 
2588 static void
2589 mq_destroy_kx (struct GNUNET_MQ_Handle *mq, void *impl_state)
2590 {
2591  struct ReceiverAddress *receiver = impl_state;
2593  "KX MQ destroyed\n");
2594  if (mq == receiver->kx_mq)
2595  {
2596  receiver->kx_mq = NULL;
2597  if (GNUNET_YES != receiver->receiver_destroy_called)
2599  }
2600 }
2601 
2602 
2609 static void
2610 mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
2611 {
2612  /* Cancellation is impossible with UDP; bail */
2613  GNUNET_assert (0);
2614 }
2615 
2616 
2626 static void
2627 mq_error (void *cls, enum GNUNET_MQ_Error error)
2628 {
2629  struct ReceiverAddress *receiver = cls;
2630 
2632  "MQ error in queue to %s: %d\n",
2633  GNUNET_i2s (&receiver->target),
2634  (int) error);
2636 }
2637 
2638 
2646 static void
2648 {
2649  size_t base_mtu;
2650 
2651  switch (receiver->address->sa_family)
2652  {
2653  case AF_INET:
2654  base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
2655  - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
2656  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2657  break;
2658 
2659  case AF_INET6:
2660  base_mtu = 1280 /* Minimum MTU required by IPv6 */
2661  - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
2662  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
2663  break;
2664 
2665  default:
2666  GNUNET_assert (0);
2667  break;
2668  }
2669  /* MTU based on full KX messages */
2670  receiver->kx_mtu = base_mtu - sizeof(struct InitialKX) /* 48 */
2671  - sizeof(struct UDPConfirmation); /* 104 */
2672  /* MTU based on BOXed messages */
2673  receiver->d_mtu = base_mtu - sizeof(struct UDPBox);
2674 
2676  "Setting up MQs and QHs\n");
2677  /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
2678  1404 (IPv4 + Box) bytes, depending on circumstances... */
2679  if (NULL == receiver->kx_mq)
2681  &mq_destroy_kx,
2682  &mq_cancel,
2683  receiver,
2684  NULL,
2685  &mq_error,
2686  receiver);
2687  if (NULL == receiver->d_mq)
2689  &mq_destroy_d,
2690  &mq_cancel,
2691  receiver,
2692  NULL,
2693  &mq_error,
2694  receiver);
2695 
2696  receiver->kx_qh =
2698  &receiver->target,
2699  receiver->foreign_addr,
2700  receiver->kx_mtu,
2702  0, /* Priority */
2703  receiver->nt,
2705  receiver->kx_mq);
2706 }
2707 
2708 
2727 static int
2728 mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
2729 {
2730  struct ReceiverAddress *receiver;
2731  const char *path;
2732  struct sockaddr *in;
2733  socklen_t in_len;
2734 
2735  if (0 != strncmp (address,
2737  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2738  {
2739  GNUNET_break_op (0);
2740  return GNUNET_SYSERR;
2741  }
2742  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2743  in = udp_address_to_sockaddr (path, &in_len);
2744 
2745  receiver = GNUNET_new (struct ReceiverAddress);
2746  receiver->address = in;
2747  receiver->address_len = in_len;
2748  receiver->target = *peer;
2749  receiver->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
2751  receivers,
2752  &receiver->target,
2753  receiver,
2756  "Added %s to receivers\n",
2757  GNUNET_i2s_full (&receiver->target));
2758  receiver->timeout =
2761  receiver,
2762  receiver->timeout.abs_value_us);
2764  "# receivers active",
2766  GNUNET_NO);
2767  receiver->foreign_addr =
2768  sockaddr_to_udpaddr_string (receiver->address, receiver->address_len);
2770  if (NULL == timeout_task)
2772  return GNUNET_OK;
2773 }
2774 
2775 
2784 static int
2786  const struct GNUNET_PeerIdentity *target,
2787  void *value)
2788 {
2789  struct ReceiverAddress *receiver = value;
2790 
2791  (void) cls;
2792  (void) target;
2794  return GNUNET_OK;
2795 }
2796 
2797 
2806 static int
2808  const struct GNUNET_PeerIdentity *target,
2809  void *value)
2810 {
2811  struct SenderAddress *sender = value;
2812 
2813  (void) cls;
2814  (void) target;
2815 
2816 
2817  sender_destroy (sender);
2818  return GNUNET_OK;
2819 }
2820 
2821 
2827 static void
2828 do_shutdown (void *cls)
2829 {
2831  "do_shutdown\n");
2832  if (NULL != nat)
2833  {
2835  nat = NULL;
2836  }
2837  while (NULL != bi_head)
2838  bi_destroy (bi_head);
2839  if (NULL != broadcast_task)
2840  {
2842  broadcast_task = NULL;
2843  }
2844  if (NULL != timeout_task)
2845  {
2847  timeout_task = NULL;
2848  }
2849  if (NULL != read_task)
2850  {
2852  read_task = NULL;
2853  }
2854  if (NULL != udp_sock)
2855  {
2858  udp_sock = NULL;
2859  }
2862  NULL);
2866  NULL);
2871  if (NULL != timeout_task)
2872  {
2874  timeout_task = NULL;
2875  }
2876  if (NULL != ch)
2877  {
2879  ch = NULL;
2880  }
2881  if (NULL != ah)
2882  {
2884  ah = NULL;
2885  }
2886  if (NULL != stats)
2887  {
2889  stats = NULL;
2890  }
2891  if (NULL != my_private_key)
2892  {
2894  my_private_key = NULL;
2895  }
2896  if (NULL != is)
2897  {
2899  is = NULL;
2900  }
2902  "do_shutdown finished\n");
2903 }
2904 
2905 
2915 static void
2916 enc_notify_cb (void *cls,
2917  const struct GNUNET_PeerIdentity *sender,
2918  const struct GNUNET_MessageHeader *msg)
2919 {
2920  const struct UDPAck *ack;
2921 
2922  (void) cls;
2924  "Storing UDPAck received from backchannel from %s\n",
2925  GNUNET_i2s_full (sender));
2927  (ntohs (msg->size) != sizeof(struct UDPAck)))
2928  {
2929  GNUNET_break_op (0);
2930  return;
2931  }
2932  ack = (const struct UDPAck *) msg;
2934  sender,
2935  &handle_ack,
2936  (void *) ack);
2937 }
2938 
2939 
2953 static void
2954 nat_address_cb (void *cls,
2955  void **app_ctx,
2956  int add_remove,
2958  const struct sockaddr *addr,
2959  socklen_t addrlen)
2960 {
2961  char *my_addr;
2963 
2964  if (GNUNET_YES == add_remove)
2965  {
2966  enum GNUNET_NetworkType nt;
2967 
2968  GNUNET_asprintf (&my_addr,
2969  "%s-%s",
2971  GNUNET_a2s (addr, addrlen));
2972  nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
2973  ai =
2975  my_addr,
2976  nt,
2978  GNUNET_free (my_addr);
2979  *app_ctx = ai;
2980  }
2981  else
2982  {
2983  ai = *app_ctx;
2985  *app_ctx = NULL;
2986  }
2987 }
2988 
2989 
2995 static void
2996 ifc_broadcast (void *cls)
2997 {
2998  struct BroadcastInterface *bi = cls;
2999  struct GNUNET_TIME_Relative delay;
3000 
3004  bi->broadcast_task =
3006 
3007  switch (bi->sa->sa_family)
3008  {
3009  case AF_INET: {
3010  static int yes = 1;
3011  static int no = 0;
3012  ssize_t sent;
3013 
3014  if (GNUNET_OK !=
3016  SOL_SOCKET,
3017  SO_BROADCAST,
3018  &yes,
3019  sizeof(int)))
3021  "setsockopt");
3023  "creating UDPBroadcast from %s\n",
3024  GNUNET_i2s (&(bi->bcm.sender)));
3026  "sending UDPBroadcast to add %s\n",
3027  GNUNET_a2s (bi->ba, bi->salen));
3029  &bi->bcm,
3030  sizeof(bi->bcm),
3031  bi->ba,
3032  bi->salen);
3033  if (-1 == sent)
3035  "sendto");
3037  SOL_SOCKET,
3038  SO_BROADCAST,
3039  &no,
3040  sizeof(int)))
3042  "setsockopt");
3043  break;
3044  }
3045 
3046  case AF_INET6: {
3047  ssize_t sent;
3048  struct sockaddr_in6 dst;
3049 
3050  dst.sin6_family = AF_INET6;
3051  dst.sin6_port = htons (my_port);
3052  dst.sin6_addr = bi->mcreq.ipv6mr_multiaddr;
3053  dst.sin6_scope_id = ((struct sockaddr_in6 *) bi->ba)->sin6_scope_id;
3054 
3056  "sending UDPBroadcast\n");
3058  &bi->bcm,
3059  sizeof(bi->bcm),
3060  (const struct sockaddr *) &dst,
3061  sizeof(dst));
3062  if (-1 == sent)
3064  break;
3065  }
3066 
3067  default:
3068  GNUNET_break (0);
3069  break;
3070  }
3071 }
3072 
3073 
3088 static int
3089 iface_proc (void *cls,
3090  const char *name,
3091  int isDefault,
3092  const struct sockaddr *addr,
3093  const struct sockaddr *broadcast_addr,
3094  const struct sockaddr *netmask,
3095  socklen_t addrlen)
3096 {
3097  struct BroadcastInterface *bi;
3098  enum GNUNET_NetworkType network;
3099  struct UdpBroadcastSignature ubs;
3100 
3101  (void) cls;
3102  (void) netmask;
3103  if (NULL == addr)
3104  return GNUNET_YES; /* need to know our address! */
3105  network = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3106  if (GNUNET_NT_LOOPBACK == network)
3107  {
3108  /* Broadcasting on loopback does not make sense */
3109  return GNUNET_YES;
3110  }
3111  for (bi = bi_head; NULL != bi; bi = bi->next)
3112  {
3113  if ((bi->salen == addrlen) && (0 == memcmp (addr, bi->sa, addrlen)))
3114  {
3115  bi->found = GNUNET_YES;
3116  return GNUNET_OK;
3117  }
3118  }
3119 
3120  if ((AF_INET6 == addr->sa_family) && (NULL == broadcast_addr))
3121  return GNUNET_OK; /* broadcast_addr is required for IPv6! */
3122  if ((AF_INET6 == addr->sa_family) && (GNUNET_YES != have_v6_socket))
3123  return GNUNET_OK; /* not using IPv6 */
3124 
3125  bi = GNUNET_new (struct BroadcastInterface);
3126  bi->sa = GNUNET_memdup (addr,
3127  addrlen);
3128  if ( (NULL != broadcast_addr) &&
3129  (addrlen == sizeof (struct sockaddr_in)) )
3130  {
3131  struct sockaddr_in *ba;
3132 
3133  ba = GNUNET_memdup (broadcast_addr,
3134  addrlen);
3135  ba->sin_port = htons (2086); /* always GNUnet port, ignore configuration! */
3136  bi->ba = (struct sockaddr *) ba;
3137  }
3138  bi->salen = addrlen;
3139  bi->found = GNUNET_YES;
3140  bi->bcm.sender = my_identity;
3141  ubs.purpose.purpose = htonl (
3143  ubs.purpose.size = htonl (sizeof(ubs));
3144  ubs.sender = my_identity;
3146  "creating UDPBroadcastSignature for %s\n",
3147  GNUNET_a2s (addr, addrlen));
3148  GNUNET_CRYPTO_hash (addr, addrlen, &ubs.h_address);
3150  &ubs,
3151  &bi->bcm.sender_sig);
3152  if (NULL != bi->ba)
3153  {
3156  }
3157  if ((AF_INET6 == addr->sa_family) && (NULL != broadcast_addr))
3158  {
3159  /* Create IPv6 multicast request */
3160  const struct sockaddr_in6 *s6 =
3161  (const struct sockaddr_in6 *) broadcast_addr;
3162 
3163  GNUNET_assert (
3164  1 == inet_pton (AF_INET6, "FF05::13B", &bi->mcreq.ipv6mr_multiaddr));
3165 
3166  /* http://tools.ietf.org/html/rfc2553#section-5.2:
3167  *
3168  * IPV6_JOIN_GROUP
3169  *
3170  * Join a multicast group on a specified local interface. If the
3171  * interface index is specified as 0, the kernel chooses the local
3172  * interface. For example, some kernels look up the multicast
3173  * group in the normal IPv6 routing table and using the resulting
3174  * interface; we do this for each interface, so no need to use
3175  * zero (anymore...).
3176  */
3177  bi->mcreq.ipv6mr_interface = s6->sin6_scope_id;
3178 
3179  /* Join the multicast group */
3181  IPPROTO_IPV6,
3182  IPV6_JOIN_GROUP,
3183  &bi->mcreq,
3184  sizeof(bi->mcreq)))
3185  {
3187  }
3188  }
3189  return GNUNET_OK;
3190 }
3191 
3192 
3198 static void
3199 do_broadcast (void *cls)
3200 {
3201  struct BroadcastInterface *bin;
3202 
3203  (void) cls;
3204  for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bi->next)
3205  bi->found = GNUNET_NO;
3207  for (struct BroadcastInterface *bi = bi_head; NULL != bi; bi = bin)
3208  {
3209  bin = bi->next;
3210  if (GNUNET_NO == bi->found)
3211  bi_destroy (bi);
3212  }
3214  &do_broadcast,
3215  NULL);
3216 }
3217 
3218 
3219 static void
3221  const struct sockaddr *addr,
3222  socklen_t addrlen)
3223 {
3224  /* FIXME: support reversal: #5529 */
3226  "No connection reversal implemented!");
3227 }
3228 
3229 
3238 static void
3239 run (void *cls,
3240  char *const *args,
3241  const char *cfgfile,
3242  const struct GNUNET_CONFIGURATION_Handle *c)
3243 {
3244  char *bindto;
3245  struct sockaddr *in;
3246  socklen_t in_len;
3247  struct sockaddr_storage in_sto;
3248  socklen_t sto_len;
3249 
3250  (void) cls;
3251  cfg = c;
3252  if (GNUNET_OK !=
3255  "BINDTO",
3256  &bindto))
3257  {
3260  "BINDTO");
3261  return;
3262  }
3263 
3264  if (GNUNET_OK !=
3267  "REKEY_INTERVAL",
3268  &rekey_interval))
3270 
3271  if (GNUNET_OK !=
3274  "REKEY_MAX_BYTES",
3275  &rekey_max_bytes))
3277 
3278  in = udp_address_to_sockaddr (bindto, &in_len);
3279  if (NULL == in)
3280  {
3282  "Failed to setup UDP socket address with path `%s'\n",
3283  bindto);
3284  GNUNET_free (bindto);
3285  return;
3286  }
3287  udp_sock =
3288  GNUNET_NETWORK_socket_create (in->sa_family,
3289  SOCK_DGRAM,
3290  IPPROTO_UDP);
3291  if (NULL == udp_sock)
3292  {
3294  GNUNET_free (in);
3295  GNUNET_free (bindto);
3296  return;
3297  }
3298  if (AF_INET6 == in->sa_family)
3300  if (GNUNET_OK !=
3302  in,
3303  in_len))
3304  {
3306  "bind",
3307  bindto);
3309  udp_sock = NULL;
3310  GNUNET_free (in);
3311  GNUNET_free (bindto);
3312  return;
3313  }
3314 
3315  /* We might have bound to port 0, allowing the OS to figure it out;
3316  thus, get the real IN-address from the socket */
3317  sto_len = sizeof(in_sto);
3318  if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
3319  (struct sockaddr *) &in_sto,
3320  &sto_len))
3321  {
3322  memcpy (&in_sto, in, in_len);
3323  sto_len = in_len;
3324  }
3325  GNUNET_free (in);
3326  GNUNET_free (bindto);
3327  in = (struct sockaddr *) &in_sto;
3328  in_len = sto_len;
3330  "transport",
3331  "Bound to `%s'\n",
3332  GNUNET_a2s ((const struct sockaddr *) &in_sto,
3333  sto_len));
3334  switch (in->sa_family)
3335  {
3336  case AF_INET:
3337  my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
3338  break;
3339 
3340  case AF_INET6:
3341  my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
3342  break;
3343 
3344  default:
3345  GNUNET_break (0);
3346  my_port = 0;
3347  }
3348  stats = GNUNET_STATISTICS_create ("C-UDP", cfg);
3352  receivers_heap =
3358  if (NULL == my_private_key)
3359  {
3360  GNUNET_log (
3362  _ (
3363  "Transport service is lacking key configuration settings. Exiting.\n"));
3365  return;
3366  }
3368  /* start reading */
3370  udp_sock,
3371  &sock_read,
3372  NULL);
3377  &mq_init,
3378  NULL,
3379  &enc_notify_cb,
3380  NULL);
3381  if (NULL == ch)
3382  {
3383  GNUNET_break (0);
3385  return;
3386  }
3388  if (NULL == ah)
3389  {
3390  GNUNET_break (0);
3392  return;
3393  }
3394  /* start broadcasting */
3395  if (GNUNET_YES !=
3398  "DISABLE_BROADCAST"))
3399  {
3401  }
3404  IPPROTO_UDP,
3405  1 /* one address */,
3406  (const struct sockaddr **) &in,
3407  &in_len,
3408  &nat_address_cb,
3410  NULL /* closure */);
3411 }
3412 
3413 
3421 int
3422 main (int argc, char *const *argv)
3423 {
3424  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3426  };
3427  int ret;
3428 
3430  "transport",
3431  "Starting udp communicator\n");
3432  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3433  return 2;
3434 
3435  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
3436  argv,
3437  "gnunet-communicator-udp",
3438  _ ("GNUnet UDP communicator"),
3439  options,
3440  &run,
3441  NULL))
3442  ? 0
3443  : 1;
3444  GNUNET_free_nz ((void *) argv);
3445  return ret;
3446 }
3447 
3448 
3449 /* end of gnunet-communicator-udp.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
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST
Signature used by UDP broadcasts.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE
Signature used by UDP communicator handshake.
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 uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
#define AES_KEY_SIZE
AES key size.
static struct BroadcastInterface * bi_tail
Broadcast interface tasks.
#define DEFAULT_REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
static int try_decrypt(const struct SharedSecret *ss, const uint8_t *tag, uint32_t serial, const char *in_buf, size_t in_buf_size, char *out_buf)
Try to decrypt buf using shared secret ss and key/iv derived using serial.
#define WORKING_QUEUE_INTERVALL
static void kce_destroy(struct KeyCacheEntry *kce)
Free memory used by key cache entry.
static void create_rekey(struct ReceiverAddress *receiver, struct SharedSecret *ss, struct UDPRekey *rekey)
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void get_iv_key(const struct GNUNET_HashCode *msec, uint32_t serial, char key[(256/8)], char iv[(96/8)])
Compute key and iv.
static int secret_destroy(struct SharedSecret *ss)
Destroy ss and associated key cache entries.
static void setup_cipher(const struct GNUNET_HashCode *msec, uint32_t serial, gcry_cipher_hd_t *cipher)
Setup cipher based on shared secret msec and serial number serial.
#define GCM_TAG_SIZE
Size of the GCM tag.
static void send_msg_with_kx(const struct GNUNET_MessageHeader *msg, struct ReceiverAddress *receiver)
static struct GNUNET_PeerIdentity my_identity
Our public key.
static void mq_send_kx(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static void kce_generate(struct SharedSecret *ss, uint32_t seq)
Setup key cache entry for sequence number seq and shared secret ss.
static void add_acks(struct SharedSecret *ss, int acks_to_add)
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static void mq_destroy_kx(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static struct GNUNET_CONTAINER_MultiPeerMap * receivers
Receivers (map from peer identity to struct ReceiverAddress)
static int find_sender_by_address(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Find existing struct SenderAddress by matching addresses.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static struct GNUNET_SCHEDULER_Task * broadcast_task
ID of master broadcast task.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
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 a backchannel message for this communicator (...
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
static void reschedule_receiver_timeout(struct ReceiverAddress *receiver)
Increment receiver timeout due to activity.
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static void do_pad(gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
Pad dgram by pad_size using out_cipher.
static void mq_send_d(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 sock_read(void *cls)
Socket read task.
static void reschedule_sender_timeout(struct SenderAddress *sender)
Increment sender timeout due to activity.
static struct GNUNET_CONTAINER_Heap * senders_heap
Expiration heap for senders (contains struct SenderAddress)
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
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 struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
static void sender_destroy(struct SenderAddress *sender)
Functions with this signature are called whenever we need to close a sender's state due to timeout.
static void setup_receiver_mq(struct ReceiverAddress *receiver)
Setup the MQ for the receiver.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
#define DEFAULT_REKEY_MAX_BYTES
Default value for how often we do rekey based on number of bytes transmitted? (additionally randomize...
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static struct SenderAddress * setup_sender(const struct GNUNET_PeerIdentity *target, const struct sockaddr *address, socklen_t address_len)
Create sender address for target.
#define GENERATE_AT_ONCE
static void kce_generate_cb(void *cls)
static struct GNUNET_SCHEDULER_Task * read_task
ID of read task.
static void try_handle_plaintext(struct SenderAddress *sender, const void *buf, size_t buf_size)
Test if we have received a valid message in plaintext.
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
static void receiver_destroy(struct ReceiverAddress *receiver)
Destroys a receiving state due to timeout or shutdown.
static struct GNUNET_CONTAINER_MultiShortmap * key_cache
Cache of pre-generated key IDs.
static int handle_ack(void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
We received an ACK for pid.
#define KCN_TARGET
How many KCNs do we keep around after we hit the KCN_THRESHOLD? Should be larger than KCN_THRESHOLD s...
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
static struct GNUNET_TRANSPORT_ApplicationHandle * ah
Our handle to report addresses for validation to TRANSPORT.
static void bi_destroy(struct BroadcastInterface *bi)
An interface went away, stop broadcasting on it.
static int have_v6_socket
GNUNET_YES if udp_sock supports IPv6.
static void pass_plaintext_to_core(struct SenderAddress *sender, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext from a sender.
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 do_broadcast(void *cls)
Scan interfaces to broadcast our presence on the LAN.
#define INTERFACE_SCAN_FREQUENCY
How often do we scan for changes to our network interfaces?
static struct SharedSecret * setup_shared_secret_ephemeral(struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct ReceiverAddress *receiver)
Setup new shared secret for encryption using KEM.
static struct GNUNET_CONTAINER_Heap * receivers_heap
Expiration heap for receivers (contains struct ReceiverAddress)
static uint16_t my_port
Port number to which we are actually bound.
static void get_kid(const struct GNUNET_HashCode *msec, uint32_t serial, struct GNUNET_ShortHashCode *kid)
Compute kid.
static void check_timeouts(void *cls)
Task run to check #receiver_heap and #sender_heap for timeouts.
static int get_receiver_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all receivers to clean up.
static struct GNUNET_CONTAINER_MultiPeerMap * senders
Senders (map from peer identity to struct SenderAddress)
static void calculate_cmac(struct SharedSecret *ss)
Calculate cmac from master in ss.
static struct GNUNET_SCHEDULER_Task * timeout_task
ID of timeout task.
#define MAX_SQN_DELTA
What is the maximum delta between KCN sequence numbers that we allow.
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.
#define KCN_THRESHOLD
If we fall below this number of available KCNs, we generate additional ACKs until we reach KCN_TARGET...
#define MAX_SECRETS
How many shared master secrets do we keep around at most per sender? Should be large enough so that w...
static enum GNUNET_GenericReturnValue purge_secrets(struct SharedSecret *ss_list_tail)
Best effort try to purge some secrets.
static struct BroadcastInterface * bi_head
Broadcast interface tasks.
static int get_sender_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all senders to clean up.
static struct SharedSecret * setup_shared_secret_dec(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
Setup shared secret for decryption.
static char * sockaddr_to_udpaddr_string(const struct sockaddr *address, socklen_t address_len)
Converts address to the address string format used by this communicator in HELLOs.
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 int iface_proc(void *cls, const char *name, int isDefault, const struct sockaddr *addr, const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, socklen_t addrlen)
Callback function invoked for each interface found.
static void ifc_broadcast(void *cls)
Broadcast our presence on one of our interfaces.
static void decrypt_box(const struct UDPBox *box, size_t box_len, struct KeyCacheEntry *kce)
We received a box with matching kce.
static int verify_confirmation(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, const struct UDPConfirmation *uc)
Check signature from uc against ephemeral.
static void consider_ss_ack(struct SharedSecret *ss)
We established a shared secret with a sender.
static unsigned long long rekey_max_bytes
How often we do rekey based on number of bytes transmitted.
#define AES_IV_SIZE
AES (GCM) IV size.
#define BROADCAST_FREQUENCY
How often do we broadcast our presence on the LAN?
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
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.
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 struct GNUNET_FS_SearchContext * sc
Definition: gnunet-search.c:87
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static char buf[2048]
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_FS_UnindexContext * uc
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Constants for network protocols.
API to create, modify and access statistics.
Bandwidth allocation API for applications to interact with.
API of the transport service towards the communicator processes.
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.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
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_application_validate(struct GNUNET_TRANSPORT_ApplicationHandle *ch, const struct GNUNET_PeerIdentity *peer, enum GNUNET_NetworkType nt, const char *addr)
An application (or a communicator) has received a HELLO (or other address data of another peer) and w...
void GNUNET_TRANSPORT_communicator_mq_update(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_TRANSPORT_QueueHandle *u_qh, uint64_t q_len, uint32_t priority)
Notify transport service that an MQ was updated.
void GNUNET_TRANSPORT_communicator_notify(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *pid, const char *comm, const struct GNUNET_MessageHeader *header)
The communicator asks the transport service to route a message via a different path to another commun...
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
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_UNRELIABLE
Transmission is unreliable (e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_size(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *size)
Get a configuration value that should be a size in bytes.
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?
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Decapsulate a key for a private EdDSA key.
Definition: crypto_ecc.c:749
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:198
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps(const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material)
Encapsulate key material for a EdDSA public key.
Definition: crypto_ecc.c:794
#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.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#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_hkdf(void *result, size_t out_len, int xtr_algo, int prf_algo, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_hkdf.c:341
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.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multishortmap_put(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair 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).
struct GNUNET_CONTAINER_MultiShortmap * GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_CONTAINER_multishortmap_destroy(struct GNUNET_CONTAINER_MultiShortmap *map)
Destroy a hash map.
void * GNUNET_CONTAINER_multishortmap_get(const struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key)
Given a key find a value in the map matching the key.
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned int GNUNET_CONTAINER_multishortmap_size(const struct GNUNET_CONTAINER_MultiShortmap *map)
Get the number of key-value pairs in the map.
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.
int GNUNET_CONTAINER_multishortmap_remove(struct GNUNET_CONTAINER_MultiShortmap *map, const struct GNUNET_ShortHashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue 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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#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;.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_sh2s(const struct GNUNET_ShortHashCode *shc)
Convert a short hash value to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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).
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ 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:465
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:421
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:674
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:366
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:509
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1001
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:688
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:80
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:440
int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Handle *fd, int level, int option_name, const void *option_value, socklen_t option_len)
Set socket option.
Definition: network.c:806
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:772
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:39
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:427
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:406
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:308
@ GNUNET_NT_LOOPBACK
Loopback (same host).
Definition: gnunet_nt_lib.h:48
void GNUNET_OS_network_interfaces_list(GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
Enumerate all network interfaces.
Definition: os_network.c:397
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:400
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY
UDP Rekey.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD
UDP communicator padding.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK
UDP KX acknowledgement.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1506
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:1334
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
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:1222
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:343
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
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:860
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
const char * name
void receiver(void *cls, const void *buf, size_t available, const struct sockaddr *addr, socklen_t addrlen, int errCode)
Callback to read from the SOCKS5 proxy.
Definition: socks.c:330
Interface we broadcast our presence on.
socklen_t salen
Number of bytes in sa.
struct ipv6_mreq mcreq
If this is an IPv6 interface, this is the request we use to join/leave the group.
struct BroadcastInterface * next
Kept in a DLL.
int found
Was this interface found in the last iface_proc() scan?
struct UDPBroadcast bcm
Message we broadcast on this interface.
struct sockaddr * ba
Broadcast address to use on the interface.
struct GNUNET_SCHEDULER_Task * broadcast_task
Task for this broadcast interface.
struct BroadcastInterface * prev
Kept in a DLL.
struct sockaddr * sa
Sender's address of the interface.
Handle to a node in a heap.
Internal representation of the hash map.
Internal representation of the hash map.
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...
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:87
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:54
Handle to the interface scanner.
Definition: nt.c:105
The identity of the host (wraps the signing key of the peer).
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Entry in list of pending tasks.
Definition: scheduler.c:136
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...
Handle to the TRANSPORT subsystem for application management.
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...
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
"Plaintext" header at beginning of KX message.
uint8_t gcm_tag[(128/8)]
HMAC for the following encrypted message, using GCM.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key for KX.
Pre-generated "kid" code (key and IV identification code) to quickly derive master key for a struct U...
struct GNUNET_ShortHashCode kid
Key and IV identification code.
uint32_t sequence_number
Sequence number used to derive this entry from master key.
struct KeyCacheEntry * next
Kept in a DLL.
struct KeyCacheEntry * prev
Kept in a DLL.
struct SharedSecret * ss
Corresponding shared secret.
Information we track per receiving address we have recently been in contact with (encryption to recei...
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct GNUNET_TIME_Absolute rekey_timeout
Timeout for this receiver address.
struct SharedSecret * ss_tail
Shared secrets we received with target, last used is tail.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this receiver.
struct SharedSecret * ss_head
Shared secrets we received from target, first used is head.
struct GNUNET_TRANSPORT_QueueHandle * kx_qh
handle for KX queue with the ch.
unsigned int num_secrets
Length of the DLL at ss_head.
struct GNUNET_TIME_Absolute timeout
Timeout for this receiver address.
size_t kx_mtu
MTU we allowed transport for this receiver's KX queue.
struct sockaddr * address
Address of the other peer.
struct GNUNET_PeerIdentity target
To whom are we talking to.
socklen_t address_len
Length of the address.
struct GNUNET_MQ_Handle * kx_mq
KX message queue we are providing for the ch.
int receiver_destroy_called
receiver_destroy already called on receiver.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
enum GNUNET_NetworkType nt
Which network type does this queue use?
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
struct GNUNET_TRANSPORT_QueueHandle * d_qh
handle for default queue with the ch.
Context information to be used while searching for operation contexts.
Definition: testbed_api.c:226
const struct sockaddr * address
Address we are looking for.
struct SenderAddress * sender
Return value to set if we found a match.
socklen_t address_len
Number of bytes in address.
Information we track per sender address we have recently been in contact with (we decrypt messages fr...
struct GNUNET_PeerIdentity target
To whom are we talking to.
struct GNUNET_CONTAINER_HeapNode * hn
Entry in sender expiration heap.
struct sockaddr * address
Address of the other peer.
socklen_t address_len
Length of the address.
enum GNUNET_NetworkType nt
Which network type does this queue use?
unsigned int acks_available
Number of BOX keys from ACKs we have currently available for this sender.
unsigned int num_secrets
Length of the DLL at ss_head.
int kce_send_ack_on_finish
When KCE finishes, send ACK if GNUNET_YES.
struct GNUNET_TIME_Absolute timeout
Timeout for this sender.
int kce_task_finished
Is the kce_task finished?
struct GNUNET_SCHEDULER_Task * kce_task
ID of kce working queue task.
struct SharedSecret * ss_head
Shared secrets we used with target, first used is head.
int sender_destroy_called
sender_destroy already called on sender.
struct SharedSecret * ss_tail
Shared secrets we used with target, last used is tail.
Shared secret we generated for a particular sender or receiver.
struct KeyCacheEntry * kce_tail
Kept in a DLL, sorted by sequence number.
uint32_t sequence_allowed
Up to which sequence number did the other peer allow us to use this key, or up to which number did we...
struct SharedSecret * next
Kept in a DLL.
unsigned int active_kce_count
Number of active KCN entries.
uint32_t sequence_used
Up to which sequence number did we use this master already? (for encrypting only)
size_t bytes_sent
Bytes sent with this shared secret.
struct SharedSecret * prev
Kept in a DLL.
struct SenderAddress * sender
Sender we use this shared secret with, or NULL.
struct KeyCacheEntry * kce_head
Kept in a DLL, sorted by sequence number.
struct GNUNET_HashCode cmac
CMAC is used to identify master in ACKs.
struct ReceiverAddress * receiver
Receiver we use this shared secret with, or NULL.
struct GNUNET_HashCode master
Master shared secret.
int override_available_acks
Also precompute keys despite sufficient acks (for rekey)
int rekey_initiated
rekey initiated for this secret?
UDP key acknowledgement.
uint32_t sequence_ack
Sequence acknowledgement limit.
struct GNUNET_HashCode cmac
CMAC of the base key being acknowledged.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK.
UDP message box.
uint8_t gcm_tag[(128/8)]
128-bit authentication tag for the following encrypted message, from GCM.
struct GNUNET_ShortHashCode kid
Key and IV identification code.
Broadcast by peer in LAN announcing its presence.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_PeerIdentity sender
Sender's peer identity.
Encrypted continuation of UDP initial handshake, followed by message header with payload.
struct GNUNET_PeerIdentity sender
Sender's identity.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
Plaintext of a rekey payload in a UDPBox.
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
Ephemeral key to rekey with.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.
Signature we use to verify that the broadcast was really made by the peer that claims to have made it...
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST.
struct GNUNET_HashCode h_address
Hash of the sender's UDP address.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP broadcast.
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_PeerIdentity receiver
Presumed identity of the target of the UDP connection (UDP server)
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
Ephemeral key used by the sender.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_HANDSHAKE.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the UDP connection (UDP client).
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.