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