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 
115 
120 
125 
130 
136 };
137 
138 
147 
151  struct GNUNET_CRYPTO_EddsaSignature sender_sig;
152 
157  struct GNUNET_TIME_AbsoluteNBO monotonic_time;
158 };
159 
160 
164 struct TCPBox {
171  struct GNUNET_MessageHeader header;
172 
181  struct GNUNET_ShortHashCode hmac;
182 
183  /* followed by as may bytes of payload as indicated in @e header,
184  excluding the TCPBox itself! */
185 };
186 
187 
192 struct TCPRekey {
196  struct GNUNET_MessageHeader header;
197 
206  struct GNUNET_ShortHashCode hmac;
207 
212 
216  struct GNUNET_CRYPTO_EddsaSignature sender_sig;
217 
222  struct GNUNET_TIME_AbsoluteNBO monotonic_time;
223 };
224 
225 
231 struct TCPFinish {
235  struct GNUNET_MessageHeader header;
236 
245  struct GNUNET_ShortHashCode hmac;
246 };
247 
248 
250 
251 
255 struct Queue {
259  struct GNUNET_PeerIdentity target;
260 
265 
269  gcry_cipher_hd_t in_cipher;
270 
274  gcry_cipher_hd_t out_cipher;
275 
279  struct GNUNET_HashCode in_hmac;
280 
285  struct GNUNET_HashCode out_hmac;
286 
292 
297 
302 
306  struct sockaddr *address;
307 
313 
318  struct GNUNET_TIME_Absolute rekey_time;
319 
323  socklen_t address_len;
324 
329 
334 
338  unsigned long long bytes_in_queue;
339 
343  char cread_buf[BUF_SIZE];
344 
348  char cwrite_buf[BUF_SIZE];
349 
353  char pread_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
354 
358  char pwrite_buf[UINT16_MAX + 1 + sizeof(struct TCPBox)];
359 
364  size_t cread_off;
365 
370  size_t cwrite_off;
371 
376  size_t pread_off;
377 
382  size_t pwrite_off;
383 
388 
396  unsigned int backpressure;
397 
402 
407 
412 
420 
425  int rekeyed;
426 };
427 
428 
433 struct ProtoQueue {
437  struct ProtoQueue *next;
438 
442  struct ProtoQueue *prev;
443 
448 
453 
457  struct sockaddr *address;
458 
462  socklen_t address_len;
463 
468 
473  char ibuf[INITIAL_KX_SIZE];
474 
478  size_t ibuf_off;
479 };
480 
481 
486 
490 static unsigned long long max_queue_length;
491 
496 
501 
506 
511 
516 
521 
525 static const struct GNUNET_CONFIGURATION_Handle *cfg;
526 
531 
535 static struct GNUNET_NAT_Handle *nat;
536 
540 static struct ProtoQueue *proto_head;
541 
545 static struct ProtoQueue *proto_tail;
546 
547 
555 static void
556 listen_cb(void *cls);
557 
558 
566 static void
568 {
569  struct GNUNET_MQ_Handle *mq;
570 
572  "Disconnecting queue for peer `%s'\n",
573  GNUNET_i2s(&queue->target));
574  if (NULL != (mq = queue->mq))
575  {
576  queue->mq = NULL;
577  GNUNET_MQ_destroy(mq);
578  }
579  if (NULL != queue->qh)
580  {
582  queue->qh = NULL;
583  }
585  GNUNET_YES ==
586  GNUNET_CONTAINER_multipeermap_remove(queue_map, &queue->target, queue));
587  GNUNET_STATISTICS_set(stats,
588  "# queues active",
590  GNUNET_NO);
591  if (NULL != queue->read_task)
592  {
594  queue->read_task = NULL;
595  }
596  if (NULL != queue->write_task)
597  {
599  queue->write_task = NULL;
600  }
602  gcry_cipher_close(queue->in_cipher);
603  gcry_cipher_close(queue->out_cipher);
604  GNUNET_free(queue->address);
605  if (0 != queue->backpressure)
606  queue->destroyed = GNUNET_YES;
607  else
608  GNUNET_free(queue);
609  if (NULL == listen_task)
611  listen_sock,
612  &listen_cb,
613  NULL);
614 }
615 
616 
625 static void
626 calculate_hmac(struct GNUNET_HashCode *hmac_secret,
627  const void *buf,
628  size_t buf_size,
629  struct GNUNET_ShortHashCode *smac)
630 {
631  struct GNUNET_HashCode mac;
632 
633  GNUNET_CRYPTO_hmac_raw(hmac_secret,
634  sizeof(struct GNUNET_HashCode),
635  buf,
636  buf_size,
637  &mac);
638  /* truncate to `struct GNUNET_ShortHashCode` */
639  memcpy(smac, &mac, sizeof(struct GNUNET_ShortHashCode));
640  /* ratchet hmac key */
641  GNUNET_CRYPTO_hash(hmac_secret,
642  sizeof(struct GNUNET_HashCode),
643  hmac_secret);
644 }
645 
646 
653 static void
655 {
656  struct TCPFinish fin;
657 
658  memset(&fin, 0, sizeof(fin));
659  fin.header.size = htons(sizeof(fin));
661  calculate_hmac(&queue->out_hmac, &fin, sizeof(fin), &fin.hmac);
662  /* if there is any message left in pwrite_buf, we
663  overwrite it (possibly dropping the last message
664  from CORE hard here) */
665  memcpy(queue->pwrite_buf, &fin, sizeof(fin));
666  queue->pwrite_off = sizeof(fin);
667  /* This flag will ensure that #queue_write() no longer
668  notifies CORE about the possibility of sending
669  more data, and that #queue_write() will call
670  #queue_destroy() once the @c fin was fully written. */
671  queue->finishing = GNUNET_YES;
672 }
673 
674 
682 static void
684 {
685  queue->timeout =
687 }
688 
689 
695 static void
696 queue_read(void *cls);
697 
698 
706 static void
707 core_read_finished_cb(void *cls, int success)
708 {
709  struct Queue *queue = cls;
710 
711  if (GNUNET_OK != success)
713  "# messages lost in communicator API towards CORE",
714  1,
715  GNUNET_NO);
716  queue->backpressure--;
717  /* handle deferred queue destruction */
718  if ((queue->destroyed) && (0 == queue->backpressure))
719  {
720  GNUNET_free(queue);
721  return;
722  }
724  /* possibly unchoke reading, now that CORE made progress */
725  if (NULL == queue->read_task)
726  queue->read_task =
728  queue->timeout),
729  queue->sock,
730  &queue_read,
731  queue);
732 }
733 
734 
744 static void
746  const void *plaintext,
747  size_t plaintext_len)
748 {
749  const struct GNUNET_MessageHeader *hdr = plaintext;
750  int ret;
751 
752  if (ntohs(hdr->size) != plaintext_len)
753  {
754  /* NOTE: If we ever allow multiple CORE messages in one
755  BOX, this will have to change! */
756  GNUNET_break(0);
757  return;
758  }
760  &queue->target,
761  hdr,
764  queue);
765  if (GNUNET_OK == ret)
766  queue->backpressure++;
767  GNUNET_break(GNUNET_NO != ret); /* backpressure not working!? */
768  if (GNUNET_SYSERR == ret)
770  "# bytes lost due to CORE not running",
771  plaintext_len,
772  GNUNET_NO);
773 }
774 
775 
785 static void
786 setup_cipher(const struct GNUNET_HashCode *dh,
787  const struct GNUNET_PeerIdentity *pid,
788  gcry_cipher_hd_t *cipher,
789  struct GNUNET_HashCode *hmac_key)
790 {
791  char key[256 / 8];
792  char ctr[128 / 8];
793 
794  gcry_cipher_open(cipher,
795  GCRY_CIPHER_AES256 /* low level: go for speed */,
796  GCRY_CIPHER_MODE_CTR,
797  0 /* flags */);
799  sizeof(key),
800  "TCP-key",
801  strlen("TCP-key"),
802  dh,
803  sizeof(*dh),
804  pid,
805  sizeof(*pid),
806  NULL,
807  0));
808  gcry_cipher_setkey(*cipher, key, sizeof(key));
810  sizeof(ctr),
811  "TCP-ctr",
812  strlen("TCP-ctr"),
813  dh,
814  sizeof(*dh),
815  pid,
816  sizeof(*pid),
817  NULL,
818  0));
819  gcry_cipher_setctr(*cipher, ctr, sizeof(ctr));
821  GNUNET_CRYPTO_kdf(hmac_key,
822  sizeof(struct GNUNET_HashCode),
823  "TCP-hmac",
824  strlen("TCP-hmac"),
825  dh,
826  sizeof(*dh),
827  pid,
828  sizeof(*pid),
829  NULL,
830  0));
831 }
832 
833 
840 static void
842  struct Queue *queue)
843 {
844  struct GNUNET_HashCode dh;
845 
846  GNUNET_CRYPTO_eddsa_ecdh(my_private_key, ephemeral, &dh);
847  setup_cipher(&dh, &my_identity, &queue->in_cipher, &queue->in_hmac);
848 }
849 
850 
859 static void
860 do_rekey(struct Queue *queue, const struct TCPRekey *rekey)
861 {
862  struct TcpHandshakeSignature thp;
863 
865  thp.purpose.size = htonl(sizeof(thp));
866  thp.sender = queue->target;
867  thp.receiver = my_identity;
868  thp.ephemeral = rekey->ephemeral;
869  thp.monotonic_time = rekey->monotonic_time;
870  /* FIXME: check monotonic time is monotonic... */
871  if (GNUNET_OK !=
873  &thp.purpose,
874  &rekey->sender_sig,
875  &queue->target.public_key))
876  {
877  GNUNET_break(0);
878  queue_finish(queue);
879  return;
880  }
881  gcry_cipher_close(queue->in_cipher);
882  queue->rekeyed = GNUNET_YES;
883  setup_in_cipher(&rekey->ephemeral, queue);
884 }
885 
886 
894 static size_t
896 {
897  const struct GNUNET_MessageHeader *hdr =
898  (const struct GNUNET_MessageHeader *)queue->pread_buf;
899  const struct TCPBox *box = (const struct TCPBox *)queue->pread_buf;
900  const struct TCPRekey *rekey = (const struct TCPRekey *)queue->pread_buf;
901  const struct TCPFinish *fin = (const struct TCPFinish *)queue->pread_buf;
902  struct TCPRekey rekeyz;
903  struct TCPFinish finz;
904  struct GNUNET_ShortHashCode tmac;
905  uint16_t type;
906  size_t size = 0; /* make compiler happy */
907 
908  if (sizeof(*hdr) > queue->pread_off)
909  return 0; /* not even a header */
910  type = ntohs(hdr->type);
911  switch (type)
912  {
914  /* Special case: header size excludes box itself! */
915  if (ntohs(hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
916  return 0;
917  calculate_hmac(&queue->in_hmac, &box[1], ntohs(hdr->size), &tmac);
918  if (0 != memcmp(&tmac, &box->hmac, sizeof(tmac)))
919  {
920  GNUNET_break_op(0);
921  queue_finish(queue);
922  return 0;
923  }
924  pass_plaintext_to_core(queue, (const void *)&box[1], ntohs(hdr->size));
925  size = ntohs(hdr->size) + sizeof(*box);
926  break;
927 
929  if (sizeof(*rekey) > queue->pread_off)
930  return 0;
931  if (ntohs(hdr->size) != sizeof(*rekey))
932  {
933  GNUNET_break_op(0);
934  queue_finish(queue);
935  return 0;
936  }
937  rekeyz = *rekey;
938  memset(&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
939  calculate_hmac(&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
940  if (0 != memcmp(&tmac, &box->hmac, sizeof(tmac)))
941  {
942  GNUNET_break_op(0);
943  queue_finish(queue);
944  return 0;
945  }
946  do_rekey(queue, rekey);
947  size = ntohs(hdr->size);
948  break;
949 
951  if (sizeof(*fin) > queue->pread_off)
952  return 0;
953  if (ntohs(hdr->size) != sizeof(*fin))
954  {
955  GNUNET_break_op(0);
956  queue_finish(queue);
957  return 0;
958  }
959  finz = *fin;
960  memset(&finz.hmac, 0, sizeof(finz.hmac));
961  calculate_hmac(&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
962  if (0 != memcmp(&tmac, &fin->hmac, sizeof(tmac)))
963  {
964  GNUNET_break_op(0);
965  queue_finish(queue);
966  return 0;
967  }
968  /* handle FINISH by destroying queue */
969  queue_destroy(queue);
970  break;
971 
972  default:
973  GNUNET_break_op(0);
974  queue_finish(queue);
975  return 0;
976  }
977  GNUNET_assert(0 != size);
978  return size;
979 }
980 
981 
987 static void
988 queue_read(void *cls)
989 {
990  struct Queue *queue = cls;
991  struct GNUNET_TIME_Relative left;
992  ssize_t rcvd;
993 
994  queue->read_task = NULL;
995  rcvd = GNUNET_NETWORK_socket_recv(queue->sock,
996  &queue->cread_buf[queue->cread_off],
997  BUF_SIZE - queue->cread_off);
998  if (-1 == rcvd)
999  {
1000  if ((EAGAIN != errno) && (EINTR != errno))
1001  {
1003  queue_finish(queue);
1004  return;
1005  }
1006  /* try again */
1007  queue->read_task =
1008  GNUNET_SCHEDULER_add_read_net(left, queue->sock, &queue_read, queue);
1009  return;
1010  }
1011  if (0 != rcvd)
1012  reschedule_queue_timeout(queue);
1013  queue->cread_off += rcvd;
1014  while ((queue->pread_off < sizeof(queue->pread_buf)) &&
1015  (queue->cread_off > 0))
1016  {
1017  size_t max = GNUNET_MIN(sizeof(queue->pread_buf) - queue->pread_off,
1018  queue->cread_off);
1019  size_t done;
1020  size_t total;
1021 
1022  GNUNET_assert(0 ==
1023  gcry_cipher_decrypt(queue->in_cipher,
1024  &queue->pread_buf[queue->pread_off],
1025  max,
1026  queue->cread_buf,
1027  max));
1028  queue->pread_off += max;
1029  total = 0;
1030  while ((GNUNET_NO == queue->rekeyed) &&
1031  (0 != (done = try_handle_plaintext(queue))))
1032  {
1033  /* 'done' bytes of plaintext were used, shift buffer */
1034  GNUNET_assert(done <= queue->pread_off);
1035  /* NOTE: this memmove() could possibly sometimes be
1036  avoided if we pass 'total' into try_handle_plaintext()
1037  and use it at an offset into the buffer there! */
1038  memmove(queue->pread_buf,
1039  &queue->pread_buf[done],
1040  queue->pread_off - done);
1041  queue->pread_off -= done;
1042  total += done;
1043  }
1044  /* when we encounter a rekey message, the decryption above uses the
1045  wrong key for everything after the rekey; in that case, we have
1046  to re-do the decryption at 'total' instead of at 'max'. If there
1047  is no rekey and the last message is incomplete (max > total),
1048  it is safe to keep the decryption so we shift by 'max' */
1049  if (GNUNET_YES == queue->rekeyed)
1050  {
1051  max = total;
1052  queue->rekeyed = GNUNET_NO;
1053  }
1054  memmove(queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
1055  queue->cread_off -= max;
1056  }
1057 
1058  if (BUF_SIZE == queue->cread_off)
1059  return; /* buffer full, suspend reading */
1061  if (0 != left.rel_value_us)
1062  {
1063  if (max_queue_length < queue->backpressure)
1064  {
1065  /* continue reading */
1066  queue->read_task =
1067  GNUNET_SCHEDULER_add_read_net(left, queue->sock, &queue_read, queue);
1068  }
1069  return;
1070  }
1072  "Queue %p was idle for %s, disconnecting\n",
1073  queue,
1076  GNUNET_YES));
1077  queue_finish(queue);
1078 }
1079 
1080 
1088 static struct sockaddr *
1089 tcp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
1090 {
1091  struct sockaddr *in;
1092  unsigned int port;
1093  char dummy[2];
1094  char *colon;
1095  char *cp;
1096 
1097  if (1 == sscanf(bindto, "%u%1s", &port, dummy))
1098  {
1099  /* interpreting value as just a PORT number */
1100  if (port > UINT16_MAX)
1101  {
1103  "BINDTO specification `%s' invalid: value too large for port\n",
1104  bindto);
1105  return NULL;
1106  }
1107  if ((GNUNET_NO == GNUNET_NETWORK_test_pf(PF_INET6)) ||
1108  (GNUNET_YES ==
1111  "DISABLE_V6")))
1112  {
1113  struct sockaddr_in *i4;
1114 
1115  i4 = GNUNET_malloc(sizeof(struct sockaddr_in));
1116  i4->sin_family = AF_INET;
1117  i4->sin_port = htons((uint16_t)port);
1118  *sock_len = sizeof(struct sockaddr_in);
1119  in = (struct sockaddr *)i4;
1120  }
1121  else
1122  {
1123  struct sockaddr_in6 *i6;
1124 
1125  i6 = GNUNET_malloc(sizeof(struct sockaddr_in6));
1126  i6->sin6_family = AF_INET6;
1127  i6->sin6_port = htons((uint16_t)port);
1128  *sock_len = sizeof(struct sockaddr_in6);
1129  in = (struct sockaddr *)i6;
1130  }
1131  return in;
1132  }
1133  cp = GNUNET_strdup(bindto);
1134  colon = strrchr(cp, ':');
1135  if (NULL != colon)
1136  {
1137  /* interpet value after colon as port */
1138  *colon = '\0';
1139  colon++;
1140  if (1 == sscanf(colon, "%u%1s", &port, dummy))
1141  {
1142  /* interpreting value as just a PORT number */
1143  if (port > UINT16_MAX)
1144  {
1146  "BINDTO specification `%s' invalid: value too large for port\n",
1147  bindto);
1148  GNUNET_free(cp);
1149  return NULL;
1150  }
1151  }
1152  else
1153  {
1154  GNUNET_log(
1156  "BINDTO specification `%s' invalid: last ':' not followed by number\n",
1157  bindto);
1158  GNUNET_free(cp);
1159  return NULL;
1160  }
1161  }
1162  else
1163  {
1164  /* interpret missing port as 0, aka pick any free one */
1165  port = 0;
1166  }
1167  {
1168  /* try IPv4 */
1169  struct sockaddr_in v4;
1170 
1171  if (1 == inet_pton(AF_INET, cp, &v4))
1172  {
1173  v4.sin_port = htons((uint16_t)port);
1174  in = GNUNET_memdup(&v4, sizeof(v4));
1175  *sock_len = sizeof(v4);
1176  GNUNET_free(cp);
1177  return in;
1178  }
1179  }
1180  {
1181  /* try IPv6 */
1182  struct sockaddr_in6 v6;
1183  const char *start;
1184 
1185  start = cp;
1186  if (('[' == *cp) && (']' == cp[strlen(cp) - 1]))
1187  {
1188  start++; /* skip over '[' */
1189  cp[strlen(cp) - 1] = '\0'; /* eat ']' */
1190  }
1191  if (1 == inet_pton(AF_INET6, start, &v6))
1192  {
1193  v6.sin6_port = htons((uint16_t)port);
1194  in = GNUNET_memdup(&v6, sizeof(v6));
1195  *sock_len = sizeof(v6);
1196  GNUNET_free(cp);
1197  return in;
1198  }
1199  }
1200  /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
1201  GNUNET_free(cp);
1202  return NULL;
1203 }
1204 
1205 
1212 static void
1214 {
1215  struct GNUNET_HashCode dh;
1216 
1217  GNUNET_CRYPTO_ecdh_eddsa(&queue->ephemeral, &queue->target.public_key, &dh);
1218  /* we don't need the private key anymore, drop it! */
1219  memset(&queue->ephemeral, 0, sizeof(queue->ephemeral));
1220  setup_cipher(&dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1222  queue->rekey_left_bytes =
1224 }
1225 
1226 
1233 static void
1235 {
1236  struct TCPRekey rekey;
1237  struct TcpHandshakeSignature thp;
1238 
1239  GNUNET_assert(0 == queue->pwrite_off);
1240  memset(&rekey, 0, sizeof(rekey));
1244  rekey.header.size = ntohs(sizeof(rekey));
1246  rekey.monotonic_time =
1249  thp.purpose.size = htonl(sizeof(thp));
1250  thp.sender = my_identity;
1251  thp.receiver = queue->target;
1252  thp.ephemeral = rekey.ephemeral;
1253  thp.monotonic_time = rekey.monotonic_time;
1255  &thp.purpose,
1256  &rekey.sender_sig));
1257  calculate_hmac(&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1258  memcpy(queue->pwrite_buf, &rekey, sizeof(rekey));
1259  queue->pwrite_off = sizeof(rekey);
1260 }
1261 
1262 
1269 static void
1270 queue_write(void *cls)
1271 {
1272  struct Queue *queue = cls;
1273  ssize_t sent;
1274 
1275  queue->write_task = NULL;
1276  if (0 != queue->cwrite_off)
1277  {
1278  sent = GNUNET_NETWORK_socket_send(queue->sock,
1279  queue->cwrite_buf,
1280  queue->cwrite_off);
1281  if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1282  {
1284  queue_destroy(queue);
1285  return;
1286  }
1287  if (sent > 0)
1288  {
1289  size_t usent = (size_t)sent;
1290 
1291  memmove(queue->cwrite_buf,
1292  &queue->cwrite_buf[usent],
1293  queue->cwrite_off - usent);
1294  reschedule_queue_timeout(queue);
1295  }
1296  }
1297  /* can we encrypt more? (always encrypt full messages, needed
1298  such that #mq_cancel() can work!) */
1299  if ((0 < queue->rekey_left_bytes) &&
1300  (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1301  {
1302  GNUNET_assert(0 ==
1303  gcry_cipher_encrypt(queue->out_cipher,
1304  &queue->cwrite_buf[queue->cwrite_off],
1305  queue->pwrite_off,
1306  queue->pwrite_buf,
1307  queue->pwrite_off));
1308  if (queue->rekey_left_bytes > queue->pwrite_off)
1309  queue->rekey_left_bytes -= queue->pwrite_off;
1310  else
1311  queue->rekey_left_bytes = 0;
1312  queue->cwrite_off += queue->pwrite_off;
1313  queue->pwrite_off = 0;
1314  }
1315  if ((0 == queue->pwrite_off) &&
1316  ((0 == queue->rekey_left_bytes) ||
1317  (0 ==
1319  {
1320  gcry_cipher_close(queue->out_cipher);
1321  setup_out_cipher(queue);
1322  inject_rekey(queue);
1323  }
1324  if ((0 == queue->pwrite_off) && (!queue->finishing) &&
1325  (queue->mq_awaits_continue))
1326  {
1327  queue->mq_awaits_continue = GNUNET_NO;
1329  }
1330  /* did we just finish writing 'finish'? */
1331  if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1332  {
1333  queue_destroy(queue);
1334  return;
1335  }
1336  /* do we care to write more? */
1337  if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1338  queue->write_task =
1340  queue->sock,
1341  &queue_write,
1342  queue);
1343 }
1344 
1345 
1354 static void
1356  const struct GNUNET_MessageHeader *msg,
1357  void *impl_state)
1358 {
1359  struct Queue *queue = impl_state;
1360  uint16_t msize = ntohs(msg->size);
1361  struct TCPBox box;
1362 
1363  GNUNET_assert(mq == queue->mq);
1364  if (GNUNET_YES == queue->finishing)
1365  return; /* this queue is dying, drop msg */
1366  GNUNET_assert(0 == queue->pread_off);
1368  box.header.size = htons(msize);
1369  calculate_hmac(&queue->out_hmac, msg, msize, &box.hmac);
1370  memcpy(&queue->pread_buf[queue->pread_off], &box, sizeof(box));
1371  queue->pread_off += sizeof(box);
1372  memcpy(&queue->pread_buf[queue->pread_off], msg, msize);
1373  queue->pread_off += msize;
1374  GNUNET_assert(NULL != queue->sock);
1375  if (NULL == queue->write_task)
1376  queue->write_task =
1378  queue->sock,
1379  &queue_write,
1380  queue);
1381 }
1382 
1383 
1392 static void
1393 mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
1394 {
1395  struct Queue *queue = impl_state;
1396 
1397  if (mq == queue->mq)
1398  {
1399  queue->mq = NULL;
1400  queue_finish(queue);
1401  }
1402 }
1403 
1404 
1411 static void
1412 mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
1413 {
1414  struct Queue *queue = impl_state;
1415 
1416  GNUNET_assert(0 != queue->pwrite_off);
1417  queue->pwrite_off = 0;
1418 }
1419 
1420 
1430 static void
1431 mq_error(void *cls, enum GNUNET_MQ_Error error)
1432 {
1433  struct Queue *queue = cls;
1434 
1436  "MQ error in queue to %s: %d\n",
1437  GNUNET_i2s(&queue->target),
1438  (int)error);
1439  queue_finish(queue);
1440 }
1441 
1442 
1450 static void
1452 {
1453  queue->nt =
1454  GNUNET_NT_scanner_get_type(is, queue->address, queue->address_len);
1456  queue_map,
1457  &queue->target,
1458  queue,
1460  GNUNET_STATISTICS_set(stats,
1461  "# queues active",
1463  GNUNET_NO);
1464  queue->timeout =
1467  &mq_destroy,
1468  &mq_cancel,
1469  queue,
1470  NULL,
1471  &mq_error,
1472  queue);
1473  {
1474  char *foreign_addr;
1475 
1476  switch (queue->address->sa_family)
1477  {
1478  case AF_INET:
1479  GNUNET_asprintf(&foreign_addr,
1480  "%s-%s",
1482  GNUNET_a2s(queue->address, queue->address_len));
1483  break;
1484 
1485  case AF_INET6:
1486  GNUNET_asprintf(&foreign_addr,
1487  "%s-%s",
1489  GNUNET_a2s(queue->address, queue->address_len));
1490  break;
1491 
1492  default:
1493  GNUNET_assert(0);
1494  }
1496  &queue->target,
1497  foreign_addr,
1498  0 /* no MTU */,
1499  queue->nt,
1500  cs,
1501  queue->mq);
1502  GNUNET_free(foreign_addr);
1503  }
1504 }
1505 
1506 
1517 static void
1519  const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
1520 {
1521  struct TcpHandshakeSignature ths;
1522  struct TCPConfirmation tc;
1523 
1524  memcpy(queue->cwrite_buf, epub, sizeof(*epub));
1525  queue->cwrite_off = sizeof(epub);
1526  /* compute 'tc' and append in encrypted format to cwrite_buf */
1527  tc.sender = my_identity;
1528  tc.monotonic_time =
1531  ths.purpose.size = htonl(sizeof(ths));
1532  ths.sender = my_identity;
1533  ths.receiver = queue->target;
1534  ths.ephemeral = *epub;
1535  ths.monotonic_time = tc.monotonic_time;
1537  &ths.purpose,
1538  &tc.sender_sig));
1539  GNUNET_assert(0 ==
1540  gcry_cipher_encrypt(queue->out_cipher,
1541  &queue->cwrite_buf[queue->cwrite_off],
1542  sizeof(tc),
1543  &tc,
1544  sizeof(tc)));
1545  queue->cwrite_off += sizeof(tc);
1546 }
1547 
1548 
1556 static void
1558 {
1559  struct GNUNET_CRYPTO_EcdhePublicKey epub;
1560 
1564  setup_out_cipher(queue);
1565  transmit_kx(queue, &epub);
1566 }
1567 
1568 
1580 static int
1582  struct TCPConfirmation *tc,
1583  char *ibuf)
1584 {
1585  struct TcpHandshakeSignature ths;
1586 
1587  GNUNET_assert(
1588  0 ==
1589  gcry_cipher_decrypt(queue->in_cipher,
1590  tc,
1591  sizeof(*tc),
1592  &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
1593  sizeof(tc)));
1595  ths.purpose.size = htonl(sizeof(ths));
1596  ths.sender = tc->sender;
1597  ths.receiver = my_identity;
1598  memcpy(&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
1599  ths.monotonic_time = tc->monotonic_time;
1600  /* FIXME: check monotonic time against previous mono times
1601  from this sender! */
1603  &ths.purpose,
1604  &tc->sender_sig,
1605  &tc->sender.public_key);
1606 }
1607 
1608 
1614 static void
1616 {
1618  GNUNET_free(pq->address);
1619  GNUNET_CONTAINER_DLL_remove(proto_head, proto_tail, pq);
1620  GNUNET_free(pq);
1621 }
1622 
1623 
1630 static void
1631 proto_read_kx(void *cls)
1632 {
1633  struct ProtoQueue *pq = cls;
1634  ssize_t rcvd;
1635  struct GNUNET_TIME_Relative left;
1636  struct Queue *queue;
1637  struct TCPConfirmation tc;
1638 
1639  pq->read_task = NULL;
1641  if (0 == left.rel_value_us)
1642  {
1643  free_proto_queue(pq);
1644  return;
1645  }
1646  rcvd = GNUNET_NETWORK_socket_recv(pq->sock,
1647  &pq->ibuf[pq->ibuf_off],
1648  sizeof(pq->ibuf) - pq->ibuf_off);
1649  if (-1 == rcvd)
1650  {
1651  if ((EAGAIN != errno) && (EINTR != errno))
1652  {
1654  free_proto_queue(pq);
1655  return;
1656  }
1657  /* try again */
1658  pq->read_task =
1660  return;
1661  }
1662  pq->ibuf_off += rcvd;
1663  if (pq->ibuf_off > sizeof(pq->ibuf))
1664  {
1665  /* read more */
1666  pq->read_task =
1668  return;
1669  }
1670  /* we got all the data, let's find out who we are talking to! */
1671  queue = GNUNET_new(struct Queue);
1673  queue);
1674  if (GNUNET_OK != decrypt_and_check_tc(queue, &tc, pq->ibuf))
1675  {
1677  "Invalid TCP KX received from %s\n",
1678  GNUNET_a2s(queue->address, queue->address_len));
1679  gcry_cipher_close(queue->in_cipher);
1680  GNUNET_free(queue);
1681  free_proto_queue(pq);
1682  return;
1683  }
1684  queue->address = pq->address; /* steals reference */
1685  queue->address_len = pq->address_len;
1686  queue->target = tc.sender;
1687  start_initial_kx_out(queue);
1689  queue->read_task =
1691  queue->sock,
1692  &queue_read,
1693  queue);
1694  queue->write_task =
1696  queue->sock,
1697  &queue_write,
1698  queue);
1699  GNUNET_CONTAINER_DLL_remove(proto_head, proto_tail, pq);
1700  GNUNET_free(pq);
1701 }
1702 
1703 
1711 static void
1712 listen_cb(void *cls)
1713 {
1714  struct sockaddr_storage in;
1715  socklen_t addrlen;
1716  struct GNUNET_NETWORK_Handle *sock;
1717  struct ProtoQueue *pq;
1718 
1719  listen_task = NULL;
1720  GNUNET_assert(NULL != listen_sock);
1721  addrlen = sizeof(in);
1722  memset(&in, 0, sizeof(in));
1723  sock = GNUNET_NETWORK_socket_accept(listen_sock,
1724  (struct sockaddr *)&in,
1725  &addrlen);
1726  if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
1727  return; /* system limit reached, wait until connection goes down */
1729  listen_sock,
1730  &listen_cb,
1731  NULL);
1732  if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
1733  return;
1734  if (NULL == sock)
1735  {
1737  return;
1738  }
1739  pq = GNUNET_new(struct ProtoQueue);
1740  pq->address_len = addrlen;
1741  pq->address = GNUNET_memdup(&in, addrlen);
1743  pq->sock = sock;
1745  pq->sock,
1746  &proto_read_kx,
1747  pq);
1748  GNUNET_CONTAINER_DLL_insert(proto_head, proto_tail, pq);
1749 }
1750 
1751 
1759 static void
1760 queue_read_kx(void *cls)
1761 {
1762  struct Queue *queue = cls;
1763  ssize_t rcvd;
1764  struct GNUNET_TIME_Relative left;
1765  struct TCPConfirmation tc;
1766 
1767  queue->read_task = NULL;
1769  if (0 == left.rel_value_us)
1770  {
1771  queue_destroy(queue);
1772  return;
1773  }
1774  rcvd = GNUNET_NETWORK_socket_recv(queue->sock,
1775  &queue->cread_buf[queue->cread_off],
1776  BUF_SIZE - queue->cread_off);
1777  if (-1 == rcvd)
1778  {
1779  if ((EAGAIN != errno) && (EINTR != errno))
1780  {
1782  queue_destroy(queue);
1783  return;
1784  }
1785  queue->read_task =
1786  GNUNET_SCHEDULER_add_read_net(left, queue->sock, &queue_read_kx, queue);
1787  return;
1788  }
1789  queue->cread_off += rcvd;
1790  if (queue->cread_off < INITIAL_KX_SIZE)
1791  {
1792  /* read more */
1793  queue->read_task =
1794  GNUNET_SCHEDULER_add_read_net(left, queue->sock, &queue_read_kx, queue);
1795  return;
1796  }
1797  /* we got all the data, let's find out who we are talking to! */
1799  queue->cread_buf,
1800  queue);
1801  if (GNUNET_OK != decrypt_and_check_tc(queue, &tc, queue->cread_buf))
1802  {
1804  "Invalid TCP KX received from %s\n",
1805  GNUNET_a2s(queue->address, queue->address_len));
1806  queue_destroy(queue);
1807  return;
1808  }
1809  if (0 !=
1810  memcmp(&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
1811  {
1813  "Invalid sender in TCP KX received from %s\n",
1814  GNUNET_a2s(queue->address, queue->address_len));
1815  queue_destroy(queue);
1816  return;
1817  }
1818 
1819  /* update queue timeout */
1820  reschedule_queue_timeout(queue);
1821  /* prepare to continue with regular read task immediately */
1822  memmove(queue->cread_buf,
1823  &queue->cread_buf[INITIAL_KX_SIZE],
1824  queue->cread_off - (INITIAL_KX_SIZE));
1825  queue->cread_off -= INITIAL_KX_SIZE;
1826  queue->read_task = GNUNET_SCHEDULER_add_now(&queue_read, queue);
1827 }
1828 
1829 
1848 static int
1849 mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
1850 {
1851  struct Queue *queue;
1852  const char *path;
1853  struct sockaddr *in;
1854  socklen_t in_len;
1855  struct GNUNET_NETWORK_Handle *sock;
1856 
1857  if (0 != strncmp(address,
1859  strlen(COMMUNICATOR_ADDRESS_PREFIX "-")))
1860  {
1861  GNUNET_break_op(0);
1862  return GNUNET_SYSERR;
1863  }
1864  path = &address[strlen(COMMUNICATOR_ADDRESS_PREFIX "-")];
1865  in = tcp_address_to_sockaddr(path, &in_len);
1866 
1867  sock = GNUNET_NETWORK_socket_create(in->sa_family, SOCK_STREAM, IPPROTO_TCP);
1868  if (NULL == sock)
1869  {
1871  "socket(%d) failed: %s",
1872  in->sa_family,
1873  strerror(errno));
1874  GNUNET_free(in);
1875  return GNUNET_SYSERR;
1876  }
1877  if (GNUNET_OK != GNUNET_NETWORK_socket_connect(sock, in, in_len))
1878  {
1880  "connect to `%s' failed: %s",
1881  address,
1882  strerror(errno));
1884  GNUNET_free(in);
1885  return GNUNET_SYSERR;
1886  }
1887 
1888  queue = GNUNET_new(struct Queue);
1889  queue->target = *peer;
1890  queue->address = in;
1891  queue->address_len = in_len;
1892  queue->sock = sock;
1894  queue->read_task =
1896  queue->sock,
1897  &queue_read_kx,
1898  queue);
1899  start_initial_kx_out(queue);
1900  queue->write_task =
1902  queue->sock,
1903  &queue_write,
1904  queue);
1905  return GNUNET_OK;
1906 }
1907 
1908 
1917 static int
1919  const struct GNUNET_PeerIdentity *target,
1920  void *value)
1921 {
1922  struct Queue *queue = value;
1923 
1924  (void)cls;
1925  (void)target;
1926  queue_destroy(queue);
1927  return GNUNET_OK;
1928 }
1929 
1930 
1936 static void
1937 do_shutdown(void *cls)
1938 {
1939  while (NULL != proto_head)
1940  free_proto_queue(proto_head);
1941  if (NULL != nat)
1942  {
1943  GNUNET_NAT_unregister(nat);
1944  nat = NULL;
1945  }
1946  if (NULL != listen_task)
1947  {
1948  GNUNET_SCHEDULER_cancel(listen_task);
1949  listen_task = NULL;
1950  }
1951  if (NULL != listen_sock)
1952  {
1954  listen_sock = NULL;
1955  }
1958  if (NULL != ch)
1959  {
1961  ch = NULL;
1962  }
1963  if (NULL != stats)
1964  {
1966  stats = NULL;
1967  }
1968  if (NULL != my_private_key)
1969  {
1970  GNUNET_free(my_private_key);
1971  my_private_key = NULL;
1972  }
1973  if (NULL != is)
1974  {
1976  is = NULL;
1977  }
1978 }
1979 
1980 
1992 static void
1993 enc_notify_cb(void *cls,
1994  const struct GNUNET_PeerIdentity *sender,
1995  const struct GNUNET_MessageHeader *msg)
1996 {
1997  (void)cls;
1998  (void)sender;
1999  (void)msg;
2000  GNUNET_break_op(0);
2001 }
2002 
2003 
2017 static void
2018 nat_address_cb(void *cls,
2019  void **app_ctx,
2020  int add_remove,
2022  const struct sockaddr *addr,
2023  socklen_t addrlen)
2024 {
2025  char *my_addr;
2027 
2028  if (GNUNET_YES == add_remove)
2029  {
2030  enum GNUNET_NetworkType nt;
2031 
2032  GNUNET_asprintf(&my_addr,
2033  "%s-%s",
2035  GNUNET_a2s(addr, addrlen));
2036  nt = GNUNET_NT_scanner_get_type(is, addr, addrlen);
2037  ai =
2039  my_addr,
2040  nt,
2042  GNUNET_free(my_addr);
2043  *app_ctx = ai;
2044  }
2045  else
2046  {
2047  ai = *app_ctx;
2049  *app_ctx = NULL;
2050  }
2051 }
2052 
2053 
2062 static void
2063 run(void *cls,
2064  char *const *args,
2065  const char *cfgfile,
2066  const struct GNUNET_CONFIGURATION_Handle *c)
2067 {
2068  char *bindto;
2069  struct sockaddr *in;
2070  socklen_t in_len;
2071  struct sockaddr_storage in_sto;
2072  socklen_t sto_len;
2073 
2074  (void)cls;
2075  cfg = c;
2076  if (GNUNET_OK !=
2079  "BINDTO",
2080  &bindto))
2081  {
2084  "BINDTO");
2085  return;
2086  }
2087  if (GNUNET_OK !=
2090  "MAX_QUEUE_LENGTH",
2091  &max_queue_length))
2093 
2094  in = tcp_address_to_sockaddr(bindto, &in_len);
2095  if (NULL == in)
2096  {
2098  "Failed to setup TCP socket address with path `%s'\n",
2099  bindto);
2100  GNUNET_free(bindto);
2101  return;
2102  }
2103  listen_sock =
2104  GNUNET_NETWORK_socket_create(in->sa_family, SOCK_STREAM, IPPROTO_TCP);
2105  if (NULL == listen_sock)
2106  {
2108  GNUNET_free(in);
2109  GNUNET_free(bindto);
2110  return;
2111  }
2112  if (GNUNET_OK != GNUNET_NETWORK_socket_bind(listen_sock, in, in_len))
2113  {
2115  GNUNET_NETWORK_socket_close(listen_sock);
2116  listen_sock = NULL;
2117  GNUNET_free(in);
2118  GNUNET_free(bindto);
2119  return;
2120  }
2121  /* We might have bound to port 0, allowing the OS to figure it out;
2122  thus, get the real IN-address from the socket */
2123  sto_len = sizeof(in_sto);
2124  if (0 != getsockname(GNUNET_NETWORK_get_fd(listen_sock),
2125  (struct sockaddr *)&in_sto,
2126  &sto_len))
2127  {
2128  memcpy(&in_sto, in, in_len);
2129  sto_len = in_len;
2130  }
2131  GNUNET_free(in);
2132  GNUNET_free(bindto);
2133  in = (struct sockaddr *)&in_sto;
2134  in_len = sto_len;
2136  "Bound to `%s'\n",
2137  GNUNET_a2s((const struct sockaddr *)&in_sto, sto_len));
2138  stats = GNUNET_STATISTICS_create("C-TCP", cfg);
2140  is = GNUNET_NT_scanner_init();
2142  if (NULL == my_private_key)
2143  {
2144  GNUNET_log(
2146  _(
2147  "Transport service is lacking key configuration settings. Exiting.\n"));
2149  return;
2150  }
2152  /* start listening */
2154  listen_sock,
2155  &listen_cb,
2156  NULL);
2162  &mq_init,
2163  NULL,
2164  &enc_notify_cb,
2165  NULL);
2166  if (NULL == ch)
2167  {
2168  GNUNET_break(0);
2170  return;
2171  }
2172  nat = GNUNET_NAT_register(cfg,
2174  IPPROTO_TCP,
2175  1 /* one address */,
2176  (const struct sockaddr **)&in,
2177  &in_len,
2178  &nat_address_cb,
2179  NULL /* FIXME: support reversal: #5529 */,
2180  NULL /* closure */);
2181 }
2182 
2183 
2191 int
2192 main(int argc, char *const *argv)
2193 {
2194  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
2196  };
2197  int ret;
2198 
2199  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
2200  return 2;
2201 
2202  ret = (GNUNET_OK == GNUNET_PROGRAM_run(argc,
2203  argv,
2204  "gnunet-communicator-tcp",
2205  _("GNUnet TCP communicator"),
2206  options,
2207  &run,
2208  NULL))
2209  ? 0
2210  : 1;
2211  GNUNET_free((void *)argv);
2212  return ret;
2213 }
2214 
2215 
2216 /* 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:108
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:1068
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:306
static void done()
Handle for active NAT registrations.
Definition: nat_api.c:70
static void boot_queue(struct Queue *queue, enum GNUNET_TRANSPORT_ConnectionStatus cs)
Add the given queue to our internal data structure.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_PeerIdentity target
To whom are we talking to.
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
static void core_read_finished_cb(void *cls, int success)
Core tells us it is done processing a message that transport received on a queue with status success...
uint64_t rel_value_us
The actual value.
int main(int argc, char *const *argv)
The main function for the UNIX communicator.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
int finishing
Did we enqueue a finish message and are closing down the queue?
struct GNUNET_HashCode in_hmac
Shared secret for HMAC verification on incoming data.
struct GNUNET_PeerIdentity sender
Identity of the inititor of the TCP connection (TCP client).
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
socklen_t address_len
Length of the address.
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:804
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:1284
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:775
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:1439
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY
TCP communicator rekey message.
static struct GNUNET_SCHEDULER_Task * listen_task
ID of listen task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void proto_read_kx(void *cls)
Read from the socket of the proto queue until we have enough data to upgrade to full queue...
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:410
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:474
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:1537
static void pass_plaintext_to_core(struct Queue *queue, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext on queue.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_TIME_Absolute rekey_time
Until what time may we sent with the current out_cipher before we should rekey?
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
static void transmit_kx(struct Queue *queue, const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
Generate and transmit our ephemeral key and the signature for the initial KX with the other peer...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral
Our ephemeral key.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX
TCP communicator payload box.
static void calculate_hmac(struct GNUNET_HashCode *hmac_secret, const void *buf, size_t buf_size, struct GNUNET_ShortHashCode *smac)
Compute mac over buf, and ratched the hmac_secret.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define REKEY_TIME_INTERVAL
How often do we rekey based on time (at least)
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
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:181
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
static int decrypt_and_check_tc(struct Queue *queue, struct TCPConfirmation *tc, char *ibuf)
We have received the first bytes from the other side on a queue.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition: network.c:420
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:646
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:550
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:1505
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:1264
size_t cwrite_off
At which offset in the ciphertext write buffer should we append more ciphertext from reading next...
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
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:1615
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:419
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:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:376
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:399
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:805
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 in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
#define REKEY_MAX_BYTES
How often do we rekey based on number of bytes transmitted? (additionally randomized).
Allow multiple values with the same key.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
Handle to a message queue.
Definition: mq.c:84
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
socklen_t address_len
Length of the address.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
Private ECC key encoded for transmission.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
The identity of the host (wraps the signing key of the peer).
static void free_proto_queue(struct ProtoQueue *pq)
Closes socket and frees memory associated with pq.
struct sockaddr * address
Address of the other peer.
size_t ibuf_off
Current offset for reading into ibuf.
static void setup_out_cipher(struct Queue *queue)
Setup cipher for outgoing data stream based on target and our ephemeral private key.
TCP rekey message box.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
configuration data
Definition: configuration.c:83
this is an outbound connection (transport initiated)
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
enum GNUNET_TRANSPORT_ConnectionStatus cs
Connection status for this queue.
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.
Encrypted continuation of TCP initial handshake.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
size_t pwrite_off
At which offset in the plaintext output buffer should we append more plaintext for encryption next...
#define GNUNET_log(kind,...)
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
Entry in list of pending tasks.
Definition: scheduler.c:131
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:367
struct ProtoQueue * prev
Kept in a DLL.
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static size_t try_handle_plaintext(struct Queue *queue)
Test if we have received a full message in plaintext.
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer&#39;s key from the file specified in the configuration...
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
gcry_cipher_hd_t in_cipher
cipher for decryption of incoming data.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1467
struct GNUNET_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:655
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:484
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:548
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:78
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:900
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:956