aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2016-09-20 01:21:59 +0000
committerBart Polot <bart@net.in.tum.de>2016-09-20 01:21:59 +0000
commitb4d5f474eef10017a470dccb01dae86c32bd5ddb (patch)
tree4b97bb46f4ab15c732e284ef0b275cc0dbc3173a /src
parent506899aa2be2b4d5dc09c1740969c28ddf43c82d (diff)
downloadgnunet-b4d5f474eef10017a470dccb01dae86c32bd5ddb.tar.gz
gnunet-b4d5f474eef10017a470dccb01dae86c32bd5ddb.zip
Port CADET to CORE MQ API
Diffstat (limited to 'src')
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c1163
-rw-r--r--src/cadet/gnunet-service-cadet_connection.h146
-rw-r--r--src/cadet/gnunet-service-cadet_local.c2
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c1404
-rw-r--r--src/cadet/gnunet-service-cadet_peer.h108
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.c33
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.h12
7 files changed, 1015 insertions, 1853 deletions
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index 0c11c24df..29695243f 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -268,7 +268,7 @@ struct CadetConnectionQueue
268 /** 268 /**
269 * Peer queue handle, to cancel if necessary. 269 * Peer queue handle, to cancel if necessary.
270 */ 270 */
271 struct CadetPeerQueue *q; 271 struct CadetPeerQueue *peer_q;
272 272
273 /** 273 /**
274 * Continuation to call once sent. 274 * Continuation to call once sent.
@@ -312,7 +312,8 @@ static struct GNUNET_CONTAINER_MultiHashMap *connections;
312 312
313/** 313/**
314 * How many connections are we willing to maintain. 314 * How many connections are we willing to maintain.
315 * Local connections are always allowed, even if there are more connections than max. 315 * Local connections are always allowed,
316 * even if there are more connections than max.
316 */ 317 */
317static unsigned long long max_connections; 318static unsigned long long max_connections;
318 319
@@ -621,40 +622,94 @@ send_ack (struct CadetConnection *c, unsigned int buffer, int fwd, int force)
621 622
622 623
623/** 624/**
625 * Update performance information if we are a connection's endpoint.
626 *
627 * @param c Connection to update.
628 * @param wait How much time did we wait to send the last message.
629 * @param size Size of the last message.
630 */
631static void
632update_perf (struct CadetConnection *c,
633 struct GNUNET_TIME_Relative wait,
634 uint16_t size)
635{
636 struct CadetConnectionPerformance *p;
637 double usecsperbyte;
638
639 if (NULL == c->perf)
640 return; /* Only endpoints are interested in timing. */
641
642 p = c->perf;
643 usecsperbyte = ((double) wait.rel_value_us) / size;
644 if (p->size == AVG_MSGS)
645 {
646 /* Array is full. Substract oldest value, add new one and store. */
647 p->avg -= (p->usecsperbyte[p->idx] / AVG_MSGS);
648 p->usecsperbyte[p->idx] = usecsperbyte;
649 p->avg += (p->usecsperbyte[p->idx] / AVG_MSGS);
650 }
651 else
652 {
653 /* Array not yet full. Add current value to avg and store. */
654 p->usecsperbyte[p->idx] = usecsperbyte;
655 p->avg *= p->size;
656 p->avg += p->usecsperbyte[p->idx];
657 p->size++;
658 p->avg /= p->size;
659 }
660 p->idx = (p->idx + 1) % AVG_MSGS;
661}
662
663
664/**
624 * Callback called when a connection queued message is sent. 665 * Callback called when a connection queued message is sent.
625 * 666 *
626 * Calculates the average time and connection packet tracking. 667 * Calculates the average time and connection packet tracking.
627 * 668 *
628 * @param cls Closure (ConnectionQueue Handle). 669 * @param cls Closure (ConnectionQueue Handle), can be NULL.
629 * @param c Connection this message was on. 670 * @param c Connection this message was on.
671 * @param fwd Was this a FWD going message?
630 * @param sent Was it really sent? (Could have been canceled) 672 * @param sent Was it really sent? (Could have been canceled)
631 * @param type Type of message sent. 673 * @param type Type of message sent.
632 * @param pid Packet ID, or 0 if not applicable (create, destroy, etc). 674 * @param payload_type Type of payload, if applicable.
633 * @param fwd Was this a FWD going message? 675 * @param pid Message ID, or 0 if not applicable (create, destroy, etc).
634 * @param size Size of the message. 676 * @param size Size of the message.
635 * @param wait Time spent waiting for core (only the time for THIS message) 677 * @param wait Time spent waiting for core (only the time for THIS message)
636 * @return #GNUNET_YES if connection was destroyed, #GNUNET_NO otherwise.
637 */ 678 */
638static int 679static void
639conn_message_sent (void *cls, 680conn_message_sent (void *cls,
640 struct CadetConnection *c, int sent, 681 struct CadetConnection *c, int fwd, int sent,
641 uint16_t type, uint32_t pid, int fwd, size_t size, 682 uint16_t type, uint16_t payload_type, uint32_t pid,
683 size_t size,
642 struct GNUNET_TIME_Relative wait) 684 struct GNUNET_TIME_Relative wait)
643{ 685{
644 struct CadetConnectionPerformance *p;
645 struct CadetFlowControl *fc;
646 struct CadetConnectionQueue *q = cls; 686 struct CadetConnectionQueue *q = cls;
647 double usecsperbyte; 687 struct CadetFlowControl *fc;
648 int forced; 688 int forced;
649 689
650 GCC_check_connections (); 690 GCC_check_connections ();
651 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection message_sent\n");
652 691
692 /* If c is NULL, nothing to update. */
693 if (NULL == c)
694 {
695 if (type != GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
696 && type != GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY)
697 {
698 LOG (GNUNET_ERROR_TYPE_ERROR, "Message %s sent on NULL connection!\n",
699 GC_m2s (type));
700 }
701 GCC_check_connections ();
702 return;
703 }
704
705 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection message_sent\n");
653 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG); 706 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG);
654 707
708 /* Update flow control info. */
655 fc = fwd ? &c->fwd_fc : &c->bck_fc; 709 fc = fwd ? &c->fwd_fc : &c->bck_fc;
656 LOG (GNUNET_ERROR_TYPE_DEBUG, " %ssent %s %s pid %u\n", 710 LOG (GNUNET_ERROR_TYPE_DEBUG, " %ssent %s %s pid %u\n",
657 sent ? "" : "not ", GC_f2s (fwd), GC_m2s (type), pid); 711 sent ? "" : "not ", GC_f2s (fwd),
712 GC_m2s (type), GC_m2s (payload_type), pid);
658 if (NULL != q) 713 if (NULL != q)
659 { 714 {
660 forced = q->forced; 715 forced = q->forced;
@@ -674,17 +729,7 @@ conn_message_sent (void *cls,
674 { 729 {
675 forced = GNUNET_NO; 730 forced = GNUNET_NO;
676 } 731 }
677 if (NULL == c) 732
678 {
679 if (type != GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
680 && type != GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY)
681 {
682 LOG (GNUNET_ERROR_TYPE_ERROR, "Message %s sent on NULL connection!\n",
683 GC_m2s (type));
684 }
685 GCC_check_connections ();
686 return GNUNET_NO;
687 }
688 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P- %p %u\n", c, c->pending_messages); 733 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P- %p %u\n", c, c->pending_messages);
689 c->pending_messages--; 734 c->pending_messages--;
690 if ( (GNUNET_YES == c->destroy) && 735 if ( (GNUNET_YES == c->destroy) &&
@@ -694,8 +739,9 @@ conn_message_sent (void *cls,
694 "! destroying connection!\n"); 739 "! destroying connection!\n");
695 GCC_destroy (c); 740 GCC_destroy (c);
696 GCC_check_connections (); 741 GCC_check_connections ();
697 return GNUNET_YES; 742 return;
698 } 743 }
744
699 /* Send ACK if needed, after accounting for sent ID in fc->queue_n */ 745 /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
700 switch (type) 746 switch (type)
701 { 747 {
@@ -758,30 +804,8 @@ conn_message_sent (void *cls,
758 } 804 }
759 LOG (GNUNET_ERROR_TYPE_DEBUG, "! message sent!\n"); 805 LOG (GNUNET_ERROR_TYPE_DEBUG, "! message sent!\n");
760 806
761 if (NULL == c->perf) 807 update_perf (c, wait, size);
762 return GNUNET_NO; /* Only endpoints are interested in timing. */
763
764 p = c->perf;
765 usecsperbyte = ((double) wait.rel_value_us) / size;
766 if (p->size == AVG_MSGS)
767 {
768 /* Array is full. Substract oldest value, add new one and store. */
769 p->avg -= (p->usecsperbyte[p->idx] / AVG_MSGS);
770 p->usecsperbyte[p->idx] = usecsperbyte;
771 p->avg += (p->usecsperbyte[p->idx] / AVG_MSGS);
772 }
773 else
774 {
775 /* Array not yet full. Add current value to avg and store. */
776 p->usecsperbyte[p->idx] = usecsperbyte;
777 p->avg *= p->size;
778 p->avg += p->usecsperbyte[p->idx];
779 p->size++;
780 p->avg /= p->size;
781 }
782 p->idx = (p->idx + 1) % AVG_MSGS;
783 GCC_check_connections (); 808 GCC_check_connections ();
784 return GNUNET_NO;
785} 809}
786 810
787 811
@@ -950,27 +974,26 @@ is_ooo_ok (uint32_t last_pid_recv, uint32_t ooo_pid, uint32_t ooo_bitmap)
950 * Is traffic coming from this sender 'FWD' traffic? 974 * Is traffic coming from this sender 'FWD' traffic?
951 * 975 *
952 * @param c Connection to check. 976 * @param c Connection to check.
953 * @param sender Peer identity of neighbor. 977 * @param sender Short peer identity of neighbor.
954 * 978 *
955 * @return #GNUNET_YES in case the sender is the 'prev' hop and therefore 979 * @return #GNUNET_YES in case the sender is the 'prev' hop and therefore
956 * the traffic is 'FWD'. 980 * the traffic is 'FWD'.
957 * #GNUNET_NO for BCK. 981 * #GNUNET_NO for BCK.
958 * #GNUNET_SYSERR for errors. 982 * #GNUNET_SYSERR for errors (sender isn't a hop in the connection).
959 */ 983 */
960static int 984static int
961is_fwd (const struct CadetConnection *c, 985is_fwd (const struct CadetConnection *c,
962 const struct GNUNET_PeerIdentity *sender) 986 const struct CadetPeer *sender)
963{ 987{
964 GNUNET_PEER_Id id; 988 GNUNET_PEER_Id id;
965 989
966 id = GNUNET_PEER_search (sender); 990 id = GCP_get_short_id (sender);
967 if (GCP_get_short_id (get_prev_hop (c)) == id) 991 if (GCP_get_short_id (get_prev_hop (c)) == id)
968 return GNUNET_YES; 992 return GNUNET_YES;
969 993
970 if (GCP_get_short_id (get_next_hop (c)) == id) 994 if (GCP_get_short_id (get_next_hop (c)) == id)
971 return GNUNET_NO; 995 return GNUNET_NO;
972 996
973 GNUNET_break (0);
974 return GNUNET_SYSERR; 997 return GNUNET_SYSERR;
975} 998}
976 999
@@ -979,29 +1002,40 @@ is_fwd (const struct CadetConnection *c,
979 * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE 1002 * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
980 * or a first CONNECTION_ACK directed to us. 1003 * or a first CONNECTION_ACK directed to us.
981 * 1004 *
982 * @param connection Connection to confirm. 1005 * @param c Connection to confirm.
983 * @param fwd Should we send it FWD? (root->dest) 1006 * @param fwd Should we send it FWD? (root->dest)
984 * (First (~SYNACK) goes BCK, second (~ACK) goes FWD) 1007 * (First (~SYNACK) goes BCK, second (~ACK) goes FWD)
985 */ 1008 */
986static void 1009static void
987send_connection_ack (struct CadetConnection *connection, int fwd) 1010send_connection_ack (struct CadetConnection *c, int fwd)
988{ 1011{
1012 struct GNUNET_CADET_ConnectionACK msg;
989 struct CadetTunnel *t; 1013 struct CadetTunnel *t;
990 size_t size = sizeof (struct GNUNET_CADET_ConnectionACK); 1014 size_t size = sizeof (struct GNUNET_CADET_ConnectionACK);
991 1015
992 GCC_check_connections (); 1016 GCC_check_connections ();
993 t = connection->t; 1017 t = c->t;
994 LOG (GNUNET_ERROR_TYPE_INFO, 1018 LOG (GNUNET_ERROR_TYPE_INFO,
995 "==> { C %s ACK} %19s on conn %s (%p) %s [%5u]\n", 1019 "==> { C %s ACK} %19s on conn %s (%p) %s [%5u]\n",
996 GC_f2s (!fwd), "", GCC_2s (connection), connection, GC_f2s (fwd), size); 1020 GC_f2s (!fwd), "", GCC_2s (c), c, GC_f2s (fwd), size);
997 GCP_queue_add (get_hop (connection, fwd), NULL, 1021
998 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK, UINT16_MAX, 0, 1022 msg.header.size = htons (sizeof (struct GNUNET_CADET_ConnectionACK));
999 size, connection, fwd, &conn_message_sent, NULL); 1023 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK);
1000 connection->pending_messages++; 1024 msg.cid = c->id;
1025
1026 GNUNET_assert (NULL == c->maintenance_q);
1027 c->maintenance_q = GCP_send (get_hop (c, fwd), &msg.header,
1028 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK, 0,
1029 c, fwd,
1030 &conn_message_sent, NULL);
1031 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %p %u (conn`ACK)\n",
1032 c, c->pending_messages);
1033 c->pending_messages++;
1034
1001 if (CADET_TUNNEL_NEW == GCT_get_cstate (t)) 1035 if (CADET_TUNNEL_NEW == GCT_get_cstate (t))
1002 GCT_change_cstate (t, CADET_TUNNEL_WAITING); 1036 GCT_change_cstate (t, CADET_TUNNEL_WAITING);
1003 if (CADET_CONNECTION_READY != connection->state) 1037 if (CADET_CONNECTION_READY != c->state)
1004 connection_change_state (connection, CADET_CONNECTION_SENT); 1038 connection_change_state (c, CADET_CONNECTION_SENT);
1005 GCC_check_connections (); 1039 GCC_check_connections ();
1006} 1040}
1007 1041
@@ -1042,17 +1076,15 @@ send_broken (struct CadetConnection *c,
1042 * @param connection_id Connection ID. 1076 * @param connection_id Connection ID.
1043 * @param id1 Peer that has disconnected, probably local peer. 1077 * @param id1 Peer that has disconnected, probably local peer.
1044 * @param id2 Peer that has disconnected can be NULL if unknown. 1078 * @param id2 Peer that has disconnected can be NULL if unknown.
1045 * @param peer Peer to notify (neighbor who sent the connection). 1079 * @param neighbor Peer to notify (neighbor who sent the connection).
1046 */ 1080 */
1047static void 1081static void
1048send_broken_unknown (const struct GNUNET_CADET_Hash *connection_id, 1082send_broken_unknown (const struct GNUNET_CADET_Hash *connection_id,
1049 const struct GNUNET_PeerIdentity *id1, 1083 const struct GNUNET_PeerIdentity *id1,
1050 const struct GNUNET_PeerIdentity *id2, 1084 const struct GNUNET_PeerIdentity *id2,
1051 const struct GNUNET_PeerIdentity *peer_id) 1085 struct CadetPeer *neighbor)
1052{ 1086{
1053 struct GNUNET_CADET_ConnectionBroken *msg; 1087 struct GNUNET_CADET_ConnectionBroken *msg;
1054 struct CadetPeerQueue *q;
1055 struct CadetPeer *neighbor;
1056 1088
1057 GCC_check_connections (); 1089 GCC_check_connections ();
1058 LOG (GNUNET_ERROR_TYPE_INFO, "--> BROKEN on unknown connection %s\n", 1090 LOG (GNUNET_ERROR_TYPE_INFO, "--> BROKEN on unknown connection %s\n",
@@ -1067,14 +1099,10 @@ send_broken_unknown (const struct GNUNET_CADET_Hash *connection_id,
1067 msg->peer2 = *id2; 1099 msg->peer2 = *id2;
1068 else 1100 else
1069 memset (&msg->peer2, 0, sizeof (msg->peer2)); 1101 memset (&msg->peer2, 0, sizeof (msg->peer2));
1070 neighbor = GCP_get (peer_id, GNUNET_NO); /* We MUST know neighbor. */ 1102 GNUNET_assert (NULL != GCP_send (neighbor, &msg->header,
1071 GNUNET_assert (NULL != neighbor); 1103 UINT16_MAX, 2,
1072 q = GCP_queue_add (neighbor, msg, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, 1104 NULL, GNUNET_SYSERR, /* connection, fwd */
1073 UINT16_MAX, 2, 1105 NULL, NULL)); /* continuation */
1074 sizeof (struct GNUNET_CADET_ConnectionBroken),
1075 NULL, GNUNET_SYSERR, /* connection, fwd */
1076 NULL, NULL); /* continuation */
1077 GNUNET_assert (NULL != q);
1078 GCC_check_connections (); 1106 GCC_check_connections ();
1079} 1107}
1080 1108
@@ -1311,38 +1339,6 @@ schedule_next_keepalive (struct CadetConnection *c, int fwd)
1311 1339
1312 1340
1313/** 1341/**
1314 * @brief Re-initiate traffic on this connection if necessary.
1315 *
1316 * Check if there is traffic queued towards this peer
1317 * and the core transmit handle is NULL (traffic was stalled).
1318 * If so, call core tmt rdy.
1319 *
1320 * @param c Connection on which initiate traffic.
1321 * @param fwd Is this about fwd traffic?
1322 */
1323static void
1324connection_unlock_queue (struct CadetConnection *c, int fwd)
1325{
1326 struct CadetPeer *peer;
1327
1328 GCC_check_connections ();
1329 LOG (GNUNET_ERROR_TYPE_DEBUG,
1330 "connection_unlock_queue %s on %s\n",
1331 GC_f2s (fwd), GCC_2s (c));
1332
1333 if (GCC_is_terminal (c, fwd))
1334 {
1335 LOG (GNUNET_ERROR_TYPE_DEBUG, " is terminal, can unlock!\n");
1336 return;
1337 }
1338
1339 peer = get_hop (c, fwd);
1340 GCP_queue_unlock (peer, c);
1341 GCC_check_connections ();
1342}
1343
1344
1345/**
1346 * Cancel all transmissions that belong to a certain connection. 1342 * Cancel all transmissions that belong to a certain connection.
1347 * 1343 *
1348 * If the connection is scheduled for destruction and no more messages are left, 1344 * If the connection is scheduled for destruction and no more messages are left,
@@ -1356,7 +1352,6 @@ connection_cancel_queues (struct CadetConnection *c,
1356 int fwd) 1352 int fwd)
1357{ 1353{
1358 struct CadetFlowControl *fc; 1354 struct CadetFlowControl *fc;
1359 struct CadetPeer *peer;
1360 1355
1361 GCC_check_connections (); 1356 GCC_check_connections ();
1362 LOG (GNUNET_ERROR_TYPE_DEBUG, 1357 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1380,8 +1375,6 @@ connection_cancel_queues (struct CadetConnection *c,
1380 GCC_cancel (fc->poll_msg); 1375 GCC_cancel (fc->poll_msg);
1381 LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL msg for fc %p\n", fc); 1376 LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL msg for fc %p\n", fc);
1382 } 1377 }
1383 peer = get_hop (c, fwd);
1384 GCP_queue_cancel (peer, c);
1385 GCC_check_connections (); 1378 GCC_check_connections ();
1386} 1379}
1387 1380
@@ -1471,53 +1464,6 @@ connection_poll (void *cls)
1471 1464
1472 1465
1473/** 1466/**
1474 * Resend all queued messages for a connection on other connections of the
1475 * same tunnel, if possible. The connection WILL BE DESTROYED by this function.
1476 *
1477 * @param c Connection whose messages to resend.
1478 * @param fwd Resend fwd messages?
1479 */
1480static void
1481resend_messages_and_destroy (struct CadetConnection *c, int fwd)
1482{
1483 struct GNUNET_MessageHeader *out_msg;
1484 struct CadetTunnel *t = c->t;
1485 struct CadetPeer *neighbor;
1486 unsigned int pending;
1487 int destroyed;
1488
1489 GCC_check_connections ();
1490 mark_destroyed (c);
1491
1492 destroyed = GNUNET_NO;
1493 neighbor = get_hop (c, fwd);
1494 pending = c->pending_messages;
1495
1496 while (NULL != (out_msg = GCP_connection_pop (neighbor, c, &destroyed)))
1497 {
1498 if (NULL != t)
1499 GCT_resend_message (out_msg, t);
1500 GNUNET_free (out_msg);
1501 }
1502
1503 /* All pending messages should have been popped,
1504 * and the connection destroyed by the continuation.
1505 */
1506 if (GNUNET_YES != destroyed)
1507 {
1508 if (0 != pending)
1509 {
1510 GNUNET_break (0);
1511 GCC_debug (c, GNUNET_ERROR_TYPE_ERROR);
1512 if (NULL != t) GCT_debug (t, GNUNET_ERROR_TYPE_ERROR);
1513 }
1514 GCC_destroy (c);
1515 }
1516 GCC_check_connections ();
1517}
1518
1519
1520/**
1521 * Generic connection timeout implementation. 1467 * Generic connection timeout implementation.
1522 * 1468 *
1523 * Timeout function due to lack of keepalive/traffic from an endpoint. 1469 * Timeout function due to lack of keepalive/traffic from an endpoint.
@@ -1529,10 +1475,7 @@ resend_messages_and_destroy (struct CadetConnection *c, int fwd)
1529static void 1475static void
1530connection_timeout (struct CadetConnection *c, int fwd) 1476connection_timeout (struct CadetConnection *c, int fwd)
1531{ 1477{
1532 struct CadetFlowControl *reverse_fc;
1533
1534 GCC_check_connections (); 1478 GCC_check_connections ();
1535 reverse_fc = fwd ? &c->bck_fc : &c->fwd_fc;
1536 1479
1537 LOG (GNUNET_ERROR_TYPE_INFO, 1480 LOG (GNUNET_ERROR_TYPE_INFO,
1538 "Connection %s %s timed out. Destroying.\n", 1481 "Connection %s %s timed out. Destroying.\n",
@@ -1546,17 +1489,13 @@ connection_timeout (struct CadetConnection *c, int fwd)
1546 return; 1489 return;
1547 } 1490 }
1548 1491
1549 /* If dest, salvage queued traffic. */ 1492 /* If dest, send "broken" notification. */
1550 if (GCC_is_terminal (c, fwd)) 1493 if (GCC_is_terminal (c, fwd))
1551 { 1494 {
1552 const struct GNUNET_PeerIdentity *next_hop; 1495 struct CadetPeer *next_hop;
1553 1496
1554 next_hop = GCP_get_id (fwd ? get_prev_hop (c) : get_next_hop (c)); 1497 next_hop = fwd ? get_prev_hop (c) : get_next_hop (c);
1555 send_broken_unknown (&c->id, &my_full_id, NULL, next_hop); 1498 send_broken_unknown (&c->id, &my_full_id, NULL, next_hop);
1556 if (0 < reverse_fc->queue_n)
1557 resend_messages_and_destroy (c, !fwd);
1558 GCC_check_connections ();
1559 return;
1560 } 1499 }
1561 1500
1562 GCC_destroy (c); 1501 GCC_destroy (c);
@@ -1907,13 +1846,13 @@ add_to_peer (struct CadetConnection *c,
1907 * Log receipt of message on stderr (INFO level). 1846 * Log receipt of message on stderr (INFO level).
1908 * 1847 *
1909 * @param message Message received. 1848 * @param message Message received.
1910 * @param peer Peer who sent the message. 1849 * @param peer Peer who sent the message.
1911 * @param hash Connection ID. 1850 * @param conn_id Connection ID of the message.
1912 */ 1851 */
1913static void 1852static void
1914log_message (const struct GNUNET_MessageHeader *message, 1853log_message (const struct GNUNET_MessageHeader *message,
1915 const struct GNUNET_PeerIdentity *peer, 1854 const struct CadetPeer *peer,
1916 const struct GNUNET_CADET_Hash *hash) 1855 const struct GNUNET_CADET_Hash *conn_id)
1917{ 1856{
1918 uint16_t size; 1857 uint16_t size;
1919 uint16_t type; 1858 uint16_t type;
@@ -1933,8 +1872,8 @@ log_message (const struct GNUNET_MessageHeader *message,
1933 arrow = "--"; 1872 arrow = "--";
1934 } 1873 }
1935 LOG (GNUNET_ERROR_TYPE_INFO, "<%s %s on conn %s from %s, %6u bytes\n", 1874 LOG (GNUNET_ERROR_TYPE_INFO, "<%s %s on conn %s from %s, %6u bytes\n",
1936 arrow, GC_m2s (type), GNUNET_h2s (GC_h2hc (hash)), 1875 arrow, GC_m2s (type), GNUNET_h2s (GC_h2hc (conn_id)),
1937 GNUNET_i2s (peer), (unsigned int) size); 1876 GCP_2s(peer), (unsigned int) size);
1938} 1877}
1939 1878
1940/******************************************************************************/ 1879/******************************************************************************/
@@ -1942,22 +1881,17 @@ log_message (const struct GNUNET_MessageHeader *message,
1942/******************************************************************************/ 1881/******************************************************************************/
1943 1882
1944/** 1883/**
1945 * Core handler for connection creation. 1884 * Handler for connection creation.
1946 * 1885 *
1947 * @param cls Closure (unused). 1886 * @param peer Message sender (neighbor).
1948 * @param peer Sender (neighbor). 1887 * @param msg Message itself.
1949 * @param message Message.
1950 * @return #GNUNET_OK to keep the connection open,
1951 * #GNUNET_SYSERR to close it (signal serious error)
1952 */ 1888 */
1953int 1889void
1954GCC_handle_create (void *cls, 1890GCC_handle_create (struct CadetPeer *peer,
1955 const struct GNUNET_PeerIdentity *peer, 1891 const struct GNUNET_CADET_ConnectionCreate *msg)
1956 const struct GNUNET_MessageHeader *message)
1957{ 1892{
1958 struct GNUNET_CADET_ConnectionCreate *msg; 1893 const struct GNUNET_CADET_Hash *cid;
1959 struct GNUNET_PeerIdentity *id; 1894 struct GNUNET_PeerIdentity *id;
1960 struct GNUNET_CADET_Hash *cid;
1961 struct CadetPeerPath *path; 1895 struct CadetPeerPath *path;
1962 struct CadetPeer *dest_peer; 1896 struct CadetPeer *dest_peer;
1963 struct CadetPeer *orig_peer; 1897 struct CadetPeer *orig_peer;
@@ -1966,38 +1900,26 @@ GCC_handle_create (void *cls,
1966 uint16_t size; 1900 uint16_t size;
1967 1901
1968 GCC_check_connections (); 1902 GCC_check_connections ();
1969 /* Check size */ 1903 size = ntohs (msg->header.size);
1970 size = ntohs (message->size);
1971 if (size < sizeof (struct GNUNET_CADET_ConnectionCreate))
1972 {
1973 GNUNET_break_op (0);
1974 return GNUNET_OK;
1975 }
1976 1904
1977 /* Calculate hops */ 1905 /* Calculate hops */
1978 size -= sizeof (struct GNUNET_CADET_ConnectionCreate); 1906 size -= sizeof (struct GNUNET_CADET_ConnectionCreate);
1979 if (size % sizeof (struct GNUNET_PeerIdentity))
1980 {
1981 GNUNET_break_op (0);
1982 return GNUNET_OK;
1983 }
1984 if (0 != size % sizeof (struct GNUNET_PeerIdentity)) 1907 if (0 != size % sizeof (struct GNUNET_PeerIdentity))
1985 { 1908 {
1986 GNUNET_break_op (0); 1909 GNUNET_break_op (0);
1987 return GNUNET_OK; 1910 return;
1988 } 1911 }
1989 size /= sizeof (struct GNUNET_PeerIdentity); 1912 size /= sizeof (struct GNUNET_PeerIdentity);
1990 if (1 > size) 1913 if (1 > size)
1991 { 1914 {
1992 GNUNET_break_op (0); 1915 GNUNET_break_op (0);
1993 return GNUNET_OK; 1916 return;
1994 } 1917 }
1995 LOG (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size); 1918 LOG (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size);
1996 1919
1997 /* Get parameters */ 1920 /* Get parameters */
1998 msg = (struct GNUNET_CADET_ConnectionCreate *) message;
1999 cid = &msg->cid; 1921 cid = &msg->cid;
2000 log_message (message, peer, cid); 1922 log_message (&msg->header, peer, cid);
2001 id = (struct GNUNET_PeerIdentity *) &msg[1]; 1923 id = (struct GNUNET_PeerIdentity *) &msg[1];
2002 LOG (GNUNET_ERROR_TYPE_DEBUG, " origin: %s\n", GNUNET_i2s (id)); 1924 LOG (GNUNET_ERROR_TYPE_DEBUG, " origin: %s\n", GNUNET_i2s (id));
2003 1925
@@ -2012,16 +1934,15 @@ GCC_handle_create (void *cls,
2012 /* Path was malformed, probably our own ID was not in it. */ 1934 /* Path was malformed, probably our own ID was not in it. */
2013 GNUNET_STATISTICS_update (stats, "# malformed paths", 1, GNUNET_NO); 1935 GNUNET_STATISTICS_update (stats, "# malformed paths", 1, GNUNET_NO);
2014 GNUNET_break_op (0); 1936 GNUNET_break_op (0);
2015 return GNUNET_OK; 1937 return;
2016 } 1938 }
2017
2018 if (0 == own_pos) 1939 if (0 == own_pos)
2019 { 1940 {
2020 /* We received this request from a neighbor, we cannot be origin */ 1941 /* We received this request from a neighbor, we cannot be origin */
2021 GNUNET_STATISTICS_update (stats, "# fake paths", 1, GNUNET_NO); 1942 GNUNET_STATISTICS_update (stats, "# fake paths", 1, GNUNET_NO);
2022 GNUNET_break_op (0); 1943 GNUNET_break_op (0);
2023 path_destroy (path); 1944 path_destroy (path);
2024 return GNUNET_OK; 1945 return;
2025 } 1946 }
2026 1947
2027 LOG (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos); 1948 LOG (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
@@ -2035,14 +1956,14 @@ GCC_handle_create (void *cls,
2035 GNUNET_break (0); 1956 GNUNET_break (0);
2036 path_destroy (path); 1957 path_destroy (path);
2037 GCC_check_connections (); 1958 GCC_check_connections ();
2038 return GNUNET_OK; 1959 return;
2039 } 1960 }
2040 send_broken_unknown (cid, &my_full_id, 1961 send_broken_unknown (cid, &my_full_id,
2041 GNUNET_PEER_resolve2 (path->peers[own_pos + 1]), 1962 GNUNET_PEER_resolve2 (path->peers[own_pos + 1]),
2042 peer); 1963 peer);
2043 path_destroy (path); 1964 path_destroy (path);
2044 GCC_check_connections (); 1965 GCC_check_connections ();
2045 return GNUNET_OK; 1966 return;
2046 } 1967 }
2047 GCP_add_path_to_all (path, GNUNET_NO); 1968 GCP_add_path_to_all (path, GNUNET_NO);
2048 connection_reset_timeout (c, GNUNET_YES); 1969 connection_reset_timeout (c, GNUNET_YES);
@@ -2092,40 +2013,32 @@ GCC_handle_create (void *cls,
2092 LOG (GNUNET_ERROR_TYPE_DEBUG, " Retransmitting.\n"); 2013 LOG (GNUNET_ERROR_TYPE_DEBUG, " Retransmitting.\n");
2093 GCP_add_path (dest_peer, path_duplicate (path), GNUNET_NO); 2014 GCP_add_path (dest_peer, path_duplicate (path), GNUNET_NO);
2094 GCP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_NO); 2015 GCP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_NO);
2095 GNUNET_assert (NULL == GCC_send_prebuilt_message (message, 0, 0, c, 2016 GNUNET_assert (NULL ==
2096 GNUNET_YES, GNUNET_YES, 2017 GCC_send_prebuilt_message (&msg->header, 0, 0, c,
2097 NULL, NULL)); 2018 GNUNET_YES, GNUNET_YES,
2019 NULL, NULL));
2098 } 2020 }
2099 path_destroy (path); 2021 path_destroy (path);
2100 GCC_check_connections (); 2022 GCC_check_connections ();
2101 return GNUNET_OK;
2102} 2023}
2103 2024
2104 2025
2105/** 2026/**
2106 * Core handler for path confirmations. 2027 * Handler for connection confirmations.
2107 * 2028 *
2108 * @param cls closure 2029 * @param peer Message sender (neighbor).
2109 * @param message message 2030 * @param msg Message itself.
2110 * @param peer peer identity this notification is about
2111 * @return #GNUNET_OK to keep the connection open,
2112 * #GNUNET_SYSERR to close it (signal serious error)
2113 */ 2031 */
2114int 2032void
2115GCC_handle_confirm (void *cls, 2033GCC_handle_confirm (struct CadetPeer *peer,
2116 const struct GNUNET_PeerIdentity *peer, 2034 const struct GNUNET_CADET_ConnectionACK *msg)
2117 const struct GNUNET_MessageHeader *message)
2118{ 2035{
2119 struct GNUNET_CADET_ConnectionACK *msg;
2120 struct CadetConnection *c; 2036 struct CadetConnection *c;
2121 struct CadetPeerPath *p;
2122 struct CadetPeer *pi;
2123 enum CadetConnectionState oldstate; 2037 enum CadetConnectionState oldstate;
2124 int fwd; 2038 int fwd;
2125 2039
2126 GCC_check_connections (); 2040 GCC_check_connections ();
2127 msg = (struct GNUNET_CADET_ConnectionACK *) message; 2041 log_message (&msg->header, peer, &msg->cid);
2128 log_message (message, peer, &msg->cid);
2129 c = connection_get (&msg->cid); 2042 c = connection_get (&msg->cid);
2130 if (NULL == c) 2043 if (NULL == c)
2131 { 2044 {
@@ -2135,30 +2048,30 @@ GCC_handle_confirm (void *cls,
2135 " don't know the connection!\n"); 2048 " don't know the connection!\n");
2136 send_broken_unknown (&msg->cid, &my_full_id, NULL, peer); 2049 send_broken_unknown (&msg->cid, &my_full_id, NULL, peer);
2137 GCC_check_connections (); 2050 GCC_check_connections ();
2138 return GNUNET_OK; 2051 return;
2139 } 2052 }
2140
2141 if (GNUNET_NO != c->destroy) 2053 if (GNUNET_NO != c->destroy)
2142 { 2054 {
2143 GNUNET_assert (CADET_CONNECTION_DESTROYED == c->state); 2055 GNUNET_assert (CADET_CONNECTION_DESTROYED == c->state);
2056 GNUNET_STATISTICS_update (stats, "# control on dying connection",
2057 1, GNUNET_NO);
2144 LOG (GNUNET_ERROR_TYPE_DEBUG, 2058 LOG (GNUNET_ERROR_TYPE_DEBUG,
2145 "connection %s being destroyed, ignoring confirm\n", 2059 "connection %s being destroyed, ignoring confirm\n",
2146 GCC_2s (c)); 2060 GCC_2s (c));
2147 GCC_check_connections (); 2061 GCC_check_connections ();
2148 return GNUNET_OK; 2062 return;
2149 } 2063 }
2150 2064
2151 oldstate = c->state; 2065 oldstate = c->state;
2152 LOG (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", GNUNET_i2s (peer)); 2066 LOG (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", GCP_2s (peer));
2153 pi = GCP_get (peer, GNUNET_YES); 2067 if (get_next_hop (c) == peer)
2154 if (get_next_hop (c) == pi)
2155 { 2068 {
2156 LOG (GNUNET_ERROR_TYPE_DEBUG, " SYNACK\n"); 2069 LOG (GNUNET_ERROR_TYPE_DEBUG, " SYNACK\n");
2157 fwd = GNUNET_NO; 2070 fwd = GNUNET_NO;
2158 if (CADET_CONNECTION_SENT == oldstate) 2071 if (CADET_CONNECTION_SENT == oldstate)
2159 connection_change_state (c, CADET_CONNECTION_ACK); 2072 connection_change_state (c, CADET_CONNECTION_ACK);
2160 } 2073 }
2161 else if (get_prev_hop (c) == pi) 2074 else if (get_prev_hop (c) == peer)
2162 { 2075 {
2163 LOG (GNUNET_ERROR_TYPE_DEBUG, " FINAL ACK\n"); 2076 LOG (GNUNET_ERROR_TYPE_DEBUG, " FINAL ACK\n");
2164 fwd = GNUNET_YES; 2077 fwd = GNUNET_YES;
@@ -2166,17 +2079,18 @@ GCC_handle_confirm (void *cls,
2166 } 2079 }
2167 else 2080 else
2168 { 2081 {
2082 GNUNET_STATISTICS_update (stats, "# control on connection from wrong peer",
2083 1, GNUNET_NO);
2169 GNUNET_break_op (0); 2084 GNUNET_break_op (0);
2170 return GNUNET_OK; 2085 return;
2171 } 2086 }
2172 2087
2173 connection_reset_timeout (c, fwd); 2088 connection_reset_timeout (c, fwd);
2174 2089
2175 /* Add path to peers? */ 2090 /* Add path to peers? */
2176 p = c->path; 2091 if (NULL != c->path)
2177 if (NULL != p)
2178 { 2092 {
2179 GCP_add_path_to_all (p, GNUNET_YES); 2093 GCP_add_path_to_all (c->path, GNUNET_YES);
2180 } 2094 }
2181 else 2095 else
2182 { 2096 {
@@ -2184,12 +2098,12 @@ GCC_handle_confirm (void *cls,
2184 } 2098 }
2185 2099
2186 /* Message for us as creator? */ 2100 /* Message for us as creator? */
2187 if (GCC_is_origin (c, GNUNET_YES)) 2101 if (GNUNET_YES == GCC_is_origin (c, GNUNET_YES))
2188 { 2102 {
2189 if (GNUNET_NO != fwd) 2103 if (GNUNET_NO != fwd)
2190 { 2104 {
2191 GNUNET_break_op (0); 2105 GNUNET_break (0);
2192 return GNUNET_OK; 2106 return;
2193 } 2107 }
2194 LOG (GNUNET_ERROR_TYPE_DEBUG, " Connection (SYN)ACK for us!\n"); 2108 LOG (GNUNET_ERROR_TYPE_DEBUG, " Connection (SYN)ACK for us!\n");
2195 2109
@@ -2197,7 +2111,7 @@ GCC_handle_confirm (void *cls,
2197 if (CADET_CONNECTION_SENT == oldstate) 2111 if (CADET_CONNECTION_SENT == oldstate)
2198 connection_reset_timeout (c, GNUNET_YES); 2112 connection_reset_timeout (c, GNUNET_YES);
2199 2113
2200 /* Change connection state */ 2114 /* Change connection state, send ACK */
2201 connection_change_state (c, CADET_CONNECTION_READY); 2115 connection_change_state (c, CADET_CONNECTION_READY);
2202 send_connection_ack (c, GNUNET_YES); 2116 send_connection_ack (c, GNUNET_YES);
2203 2117
@@ -2205,7 +2119,7 @@ GCC_handle_confirm (void *cls,
2205 if (CADET_TUNNEL_WAITING == GCT_get_cstate (c->t)) 2119 if (CADET_TUNNEL_WAITING == GCT_get_cstate (c->t))
2206 GCT_change_cstate (c->t, CADET_TUNNEL_READY); 2120 GCT_change_cstate (c->t, CADET_TUNNEL_READY);
2207 GCC_check_connections (); 2121 GCC_check_connections ();
2208 return GNUNET_OK; 2122 return;
2209 } 2123 }
2210 2124
2211 /* Message for us as destination? */ 2125 /* Message for us as destination? */
@@ -2213,8 +2127,8 @@ GCC_handle_confirm (void *cls,
2213 { 2127 {
2214 if (GNUNET_YES != fwd) 2128 if (GNUNET_YES != fwd)
2215 { 2129 {
2216 GNUNET_break_op (0); 2130 GNUNET_break (0);
2217 return GNUNET_OK; 2131 return;
2218 } 2132 }
2219 LOG (GNUNET_ERROR_TYPE_DEBUG, " Connection ACK for us!\n"); 2133 LOG (GNUNET_ERROR_TYPE_DEBUG, " Connection ACK for us!\n");
2220 2134
@@ -2226,41 +2140,34 @@ GCC_handle_confirm (void *cls,
2226 if (CADET_TUNNEL_WAITING == GCT_get_cstate (c->t)) 2140 if (CADET_TUNNEL_WAITING == GCT_get_cstate (c->t))
2227 GCT_change_cstate (c->t, CADET_TUNNEL_READY); 2141 GCT_change_cstate (c->t, CADET_TUNNEL_READY);
2228 GCC_check_connections (); 2142 GCC_check_connections ();
2229 return GNUNET_OK; 2143 return;
2230 } 2144 }
2231 2145
2232 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n"); 2146 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n");
2233 GNUNET_assert (NULL == 2147 GNUNET_assert (NULL ==
2234 GCC_send_prebuilt_message (message, 0, 0, c, fwd, 2148 GCC_send_prebuilt_message (&msg->header, 0, 0, c, fwd,
2235 GNUNET_YES, NULL, NULL)); 2149 GNUNET_YES, NULL, NULL));
2236 GCC_check_connections (); 2150 GCC_check_connections ();
2237 return GNUNET_OK; 2151 return;
2238} 2152}
2239 2153
2240 2154
2241/** 2155/**
2242 * Core handler for notifications of broken connections. 2156 * Handler for notifications of broken connections.
2243 * 2157 *
2244 * @param cls Closure (unused). 2158 * @param peer Message sender (neighbor).
2245 * @param id Peer identity of sending neighbor. 2159 * @param msg Message itself.
2246 * @param message Message.
2247 * @return #GNUNET_OK to keep the connection open,
2248 * #GNUNET_SYSERR to close it (signal serious error)
2249 */ 2160 */
2250int 2161void
2251GCC_handle_broken (void* cls, 2162GCC_handle_broken (struct CadetPeer *peer,
2252 const struct GNUNET_PeerIdentity* id, 2163 const struct GNUNET_CADET_ConnectionBroken *msg)
2253 const struct GNUNET_MessageHeader* message)
2254{ 2164{
2255 struct GNUNET_CADET_ConnectionBroken *msg;
2256 struct CadetConnection *c; 2165 struct CadetConnection *c;
2257 struct CadetTunnel *t; 2166 struct CadetTunnel *t;
2258 int pending;
2259 int fwd; 2167 int fwd;
2260 2168
2261 GCC_check_connections (); 2169 GCC_check_connections ();
2262 msg = (struct GNUNET_CADET_ConnectionBroken *) message; 2170 log_message (&msg->header, peer, &msg->cid);
2263 log_message (message, id, &msg->cid);
2264 LOG (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n", 2171 LOG (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n",
2265 GNUNET_i2s (&msg->peer1)); 2172 GNUNET_i2s (&msg->peer1));
2266 LOG (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n", 2173 LOG (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n",
@@ -2269,13 +2176,21 @@ GCC_handle_broken (void* cls,
2269 if (NULL == c) 2176 if (NULL == c)
2270 { 2177 {
2271 LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate CONNECTION_BROKEN\n"); 2178 LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate CONNECTION_BROKEN\n");
2179 GNUNET_STATISTICS_update (stats, "# duplicate CONNECTION_BROKEN",
2180 1, GNUNET_NO);
2272 GCC_check_connections (); 2181 GCC_check_connections ();
2273 return GNUNET_OK; 2182 return;
2274 } 2183 }
2275 2184
2276 t = c->t; 2185 t = c->t;
2277 2186
2278 fwd = is_fwd (c, id); 2187 fwd = is_fwd (c, peer);
2188 if (GNUNET_SYSERR == fwd)
2189 {
2190 GNUNET_break_op (0);
2191 GCC_check_connections ();
2192 return;
2193 }
2279 mark_destroyed (c); 2194 mark_destroyed (c);
2280 if (GCC_is_terminal (c, fwd)) 2195 if (GCC_is_terminal (c, fwd))
2281 { 2196 {
@@ -2286,7 +2201,7 @@ GCC_handle_broken (void* cls,
2286 /* A terminal connection should not have 't' set to NULL. */ 2201 /* A terminal connection should not have 't' set to NULL. */
2287 GNUNET_break (0); 2202 GNUNET_break (0);
2288 GCC_debug (c, GNUNET_ERROR_TYPE_ERROR); 2203 GCC_debug (c, GNUNET_ERROR_TYPE_ERROR);
2289 return GNUNET_OK; 2204 return;
2290 } 2205 }
2291 endpoint = GCP_get_short (c->path->peers[c->path->length - 1], GNUNET_YES); 2206 endpoint = GCP_get_short (c->path->peers[c->path->length - 1], GNUNET_YES);
2292 if (2 < c->path->length) 2207 if (2 < c->path->length)
@@ -2297,44 +2212,35 @@ GCC_handle_broken (void* cls,
2297 GCT_remove_connection (t, c); 2212 GCT_remove_connection (t, c);
2298 c->t = NULL; 2213 c->t = NULL;
2299 2214
2300 pending = c->pending_messages; 2215 GCC_destroy (c);
2301 if (0 < pending)
2302 resend_messages_and_destroy (c, !fwd);
2303 else
2304 GCC_destroy (c);
2305 } 2216 }
2306 else 2217 else
2307 { 2218 {
2308 GNUNET_assert (NULL == GCC_send_prebuilt_message (message, 0, 0, c, fwd, 2219 GNUNET_assert (NULL ==
2309 GNUNET_YES, NULL, NULL)); 2220 GCC_send_prebuilt_message (&msg->header, 0, 0, c, fwd,
2221 GNUNET_YES, NULL, NULL));
2310 connection_cancel_queues (c, !fwd); 2222 connection_cancel_queues (c, !fwd);
2311 } 2223 }
2312 GCC_check_connections (); 2224 GCC_check_connections ();
2313 return GNUNET_OK; 2225 return;
2314} 2226}
2315 2227
2316 2228
2317/** 2229/**
2318 * Core handler for tunnel destruction 2230 * Handler for notifications of destroyed connections.
2319 * 2231 *
2320 * @param cls Closure (unused). 2232 * @param peer Message sender (neighbor).
2321 * @param peer Peer identity of sending neighbor. 2233 * @param msg Message itself.
2322 * @param message Message.
2323 * @return #GNUNET_OK to keep the connection open,
2324 * #GNUNET_SYSERR to close it (signal serious error)
2325 */ 2234 */
2326int 2235void
2327GCC_handle_destroy (void *cls, 2236GCC_handle_destroy (struct CadetPeer *peer,
2328 const struct GNUNET_PeerIdentity *peer, 2237 const struct GNUNET_CADET_ConnectionDestroy *msg)
2329 const struct GNUNET_MessageHeader *message)
2330{ 2238{
2331 const struct GNUNET_CADET_ConnectionDestroy *msg;
2332 struct CadetConnection *c; 2239 struct CadetConnection *c;
2333 int fwd; 2240 int fwd;
2334 2241
2335 GCC_check_connections (); 2242 GCC_check_connections ();
2336 msg = (const struct GNUNET_CADET_ConnectionDestroy *) message; 2243 log_message (&msg->header, peer, &msg->cid);
2337 log_message (message, peer, &msg->cid);
2338 c = connection_get (&msg->cid); 2244 c = connection_get (&msg->cid);
2339 if (NULL == c) 2245 if (NULL == c)
2340 { 2246 {
@@ -2346,20 +2252,23 @@ GCC_handle_destroy (void *cls,
2346 "# control on unknown connection", 2252 "# control on unknown connection",
2347 1, GNUNET_NO); 2253 1, GNUNET_NO);
2348 LOG (GNUNET_ERROR_TYPE_DEBUG, 2254 LOG (GNUNET_ERROR_TYPE_DEBUG,
2349 " connection unknown: already destroyed?\n"); 2255 " connection unknown destroyed: previously destroyed?\n");
2350 GCC_check_connections (); 2256 GCC_check_connections ();
2351 return GNUNET_OK; 2257 return;
2352 } 2258 }
2259
2353 fwd = is_fwd (c, peer); 2260 fwd = is_fwd (c, peer);
2354 if (GNUNET_SYSERR == fwd) 2261 if (GNUNET_SYSERR == fwd)
2355 { 2262 {
2356 GNUNET_break_op (0); /* FIXME */ 2263 GNUNET_break_op (0);
2357 return GNUNET_OK; 2264 GCC_check_connections ();
2265 return;
2358 } 2266 }
2267
2359 if (GNUNET_NO == GCC_is_terminal (c, fwd)) 2268 if (GNUNET_NO == GCC_is_terminal (c, fwd))
2360 { 2269 {
2361 GNUNET_assert (NULL == 2270 GNUNET_assert (NULL ==
2362 GCC_send_prebuilt_message (message, 0, 0, c, fwd, 2271 GCC_send_prebuilt_message (&msg->header, 0, 0, c, fwd,
2363 GNUNET_YES, NULL, NULL)); 2272 GNUNET_YES, NULL, NULL));
2364 } 2273 }
2365 else if (0 == c->pending_messages) 2274 else if (0 == c->pending_messages)
@@ -2367,7 +2276,7 @@ GCC_handle_destroy (void *cls,
2367 LOG (GNUNET_ERROR_TYPE_DEBUG, " directly destroying connection!\n"); 2276 LOG (GNUNET_ERROR_TYPE_DEBUG, " directly destroying connection!\n");
2368 GCC_destroy (c); 2277 GCC_destroy (c);
2369 GCC_check_connections (); 2278 GCC_check_connections ();
2370 return GNUNET_OK; 2279 return;
2371 } 2280 }
2372 mark_destroyed (c); 2281 mark_destroyed (c);
2373 if (NULL != c->t) 2282 if (NULL != c->t)
@@ -2376,7 +2285,139 @@ GCC_handle_destroy (void *cls,
2376 c->t = NULL; 2285 c->t = NULL;
2377 } 2286 }
2378 GCC_check_connections (); 2287 GCC_check_connections ();
2379 return GNUNET_OK; 2288 return;
2289}
2290
2291
2292/**
2293 * Handler for cadet network traffic hop-by-hop acks.
2294 *
2295 * @param peer Message sender (neighbor).
2296 * @param msg Message itself.
2297 */
2298void
2299GCC_handle_ack (struct CadetPeer *peer,
2300 const struct GNUNET_CADET_ACK *msg)
2301{
2302 struct CadetConnection *c;
2303 struct CadetFlowControl *fc;
2304 uint32_t ack;
2305 int fwd;
2306
2307 GCC_check_connections ();
2308 log_message (&msg->header, peer, &msg->cid);
2309 c = connection_get (&msg->cid);
2310 if (NULL == c)
2311 {
2312 GNUNET_STATISTICS_update (stats,
2313 "# ack on unknown connection",
2314 1,
2315 GNUNET_NO);
2316 send_broken_unknown (&msg->cid,
2317 &my_full_id,
2318 NULL,
2319 peer);
2320 GCC_check_connections ();
2321 return;
2322 }
2323
2324 /* Is this a forward or backward ACK? */
2325 if (get_next_hop (c) == peer)
2326 {
2327 fc = &c->fwd_fc;
2328 fwd = GNUNET_YES;
2329 }
2330 else if (get_prev_hop (c) == peer)
2331 {
2332 fc = &c->bck_fc;
2333 fwd = GNUNET_NO;
2334 }
2335 else
2336 {
2337 GNUNET_break_op (0);
2338 return;
2339 }
2340
2341 ack = ntohl (msg->ack);
2342 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s ACK %u (was %u)\n",
2343 GC_f2s (fwd), ack, fc->last_ack_recv);
2344 if (GC_is_pid_bigger (ack, fc->last_ack_recv))
2345 fc->last_ack_recv = ack;
2346
2347 /* Cancel polling if the ACK is big enough. */
2348 if (NULL != fc->poll_task &&
2349 GC_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
2350 {
2351 LOG (GNUNET_ERROR_TYPE_DEBUG, " Cancel poll\n");
2352 GNUNET_SCHEDULER_cancel (fc->poll_task);
2353 fc->poll_task = NULL;
2354 fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
2355 }
2356
2357 GCC_check_connections ();
2358}
2359
2360
2361/**
2362 * Handler for cadet network traffic hop-by-hop data counter polls.
2363 *
2364 * @param peer Message sender (neighbor).
2365 * @param msg Message itself.
2366 */
2367void
2368GCC_handle_poll (struct CadetPeer *peer,
2369 const struct GNUNET_CADET_Poll *msg)
2370{
2371 struct CadetConnection *c;
2372 struct CadetFlowControl *fc;
2373 uint32_t pid;
2374 int fwd;
2375
2376 GCC_check_connections ();
2377 log_message (&msg->header, peer, &msg->cid);
2378 c = connection_get (&msg->cid);
2379 if (NULL == c)
2380 {
2381 GNUNET_STATISTICS_update (stats, "# poll on unknown connection", 1,
2382 GNUNET_NO);
2383 LOG (GNUNET_ERROR_TYPE_DEBUG,
2384 "POLL message on unknown connection %s!\n",
2385 GNUNET_h2s (GC_h2hc (&msg->cid)));
2386 send_broken_unknown (&msg->cid,
2387 &my_full_id,
2388 NULL,
2389 peer);
2390 GCC_check_connections ();
2391 return;
2392 }
2393
2394 /* Is this a forward or backward ACK?
2395 * Note: a poll should never be needed in a loopback case,
2396 * since there is no possiblility of packet loss there, so
2397 * this way of discerining FWD/BCK should not be a problem.
2398 */
2399 if (get_next_hop (c) == peer)
2400 {
2401 LOG (GNUNET_ERROR_TYPE_DEBUG, " FWD FC\n");
2402 fc = &c->fwd_fc;
2403 }
2404 else if (get_prev_hop (c) == peer)
2405 {
2406 LOG (GNUNET_ERROR_TYPE_DEBUG, " BCK FC\n");
2407 fc = &c->bck_fc;
2408 }
2409 else
2410 {
2411 GNUNET_break_op (0);
2412 return;
2413 }
2414
2415 pid = ntohl (msg->pid);
2416 LOG (GNUNET_ERROR_TYPE_DEBUG, " PID %u, OLD %u\n", pid, fc->last_pid_recv);
2417 fc->last_pid_recv = pid;
2418 fwd = fc == &c->bck_fc;
2419 GCC_send_ack (c, fwd, GNUNET_YES);
2420 GCC_check_connections ();
2380} 2421}
2381 2422
2382 2423
@@ -2386,34 +2427,26 @@ GCC_handle_destroy (void *cls,
2386 * Updates the PID, state and timeout values for the connection. 2427 * Updates the PID, state and timeout values for the connection.
2387 * 2428 *
2388 * @param message Message to check. It must belong to an existing connection. 2429 * @param message Message to check. It must belong to an existing connection.
2389 * @param minimum_size The message cannot be smaller than this value.
2390 * @param cid Connection ID (even if @a c is NULL, the ID is still needed). 2430 * @param cid Connection ID (even if @a c is NULL, the ID is still needed).
2391 * @param c Connection this message should belong. If NULL, check fails. 2431 * @param c Connection this message should belong. If NULL, check fails.
2392 * @param neighbor Neighbor that sent the message. 2432 * @param sender Neighbor that sent the message.
2433 *
2434 * @return #GNUNET_YES if the message goes FWD.
2435 * #GNUNET_NO if it goes BCK.
2436 * #GNUNET_SYSERR if there is an error (unauthorized sender, ...).
2393 */ 2437 */
2394static int 2438static int
2395check_message (const struct GNUNET_MessageHeader *message, 2439check_message (const struct GNUNET_MessageHeader *message,
2396 size_t minimum_size,
2397 const struct GNUNET_CADET_Hash* cid, 2440 const struct GNUNET_CADET_Hash* cid,
2398 struct CadetConnection *c, 2441 struct CadetConnection *c,
2399 const struct GNUNET_PeerIdentity *neighbor, 2442 struct CadetPeer *sender,
2400 uint32_t pid) 2443 uint32_t pid)
2401{ 2444{
2402 GNUNET_PEER_Id neighbor_id;
2403 struct CadetFlowControl *fc; 2445 struct CadetFlowControl *fc;
2404 struct CadetPeer *hop; 2446 struct CadetPeer *hop;
2405 int fwd; 2447 int fwd;
2406 uint16_t type; 2448 uint16_t type;
2407 2449
2408 /* Check size */
2409 if (ntohs (message->size) < minimum_size)
2410 {
2411 GNUNET_break_op (0);
2412 LOG (GNUNET_ERROR_TYPE_WARNING, "Size %u < %u\n",
2413 ntohs (message->size), minimum_size);
2414 return GNUNET_SYSERR;
2415 }
2416
2417 /* Check connection */ 2450 /* Check connection */
2418 if (NULL == c) 2451 if (NULL == c)
2419 { 2452 {
@@ -2427,14 +2460,13 @@ check_message (const struct GNUNET_MessageHeader *message,
2427 send_broken_unknown (cid, 2460 send_broken_unknown (cid,
2428 &my_full_id, 2461 &my_full_id,
2429 NULL, 2462 NULL,
2430 neighbor); 2463 sender);
2431 return GNUNET_SYSERR; 2464 return GNUNET_SYSERR;
2432 } 2465 }
2433 2466
2434 /* Check if origin is as expected */ 2467 /* Check if origin is as expected */
2435 neighbor_id = GNUNET_PEER_search (neighbor);
2436 hop = get_prev_hop (c); 2468 hop = get_prev_hop (c);
2437 if (neighbor_id == GCP_get_short_id (hop)) 2469 if (sender == hop)
2438 { 2470 {
2439 fwd = GNUNET_YES; 2471 fwd = GNUNET_YES;
2440 } 2472 }
@@ -2442,7 +2474,7 @@ check_message (const struct GNUNET_MessageHeader *message,
2442 { 2474 {
2443 hop = get_next_hop (c); 2475 hop = get_next_hop (c);
2444 GNUNET_break (hop == c->next_peer); 2476 GNUNET_break (hop == c->next_peer);
2445 if (neighbor_id == GCP_get_short_id (hop)) 2477 if (sender == hop)
2446 { 2478 {
2447 fwd = GNUNET_NO; 2479 fwd = GNUNET_NO;
2448 } 2480 }
@@ -2508,123 +2540,111 @@ check_message (const struct GNUNET_MessageHeader *message,
2508 2540
2509 2541
2510/** 2542/**
2511 * Generic handler for cadet network encrypted traffic. 2543 * Handler for key exchange traffic (Axolotl KX).
2512 * 2544 *
2513 * @param peer Peer identity this notification is about. 2545 * @param peer Message sender (neighbor).
2514 * @param msg Encrypted message. 2546 * @param msg Message itself.
2515 * @return #GNUNET_OK to keep the connection open,
2516 * #GNUNET_SYSERR to close it (signal serious error)
2517 */ 2547 */
2518static int 2548void
2519handle_cadet_encrypted (const struct GNUNET_PeerIdentity *peer, 2549GCC_handle_kx (struct CadetPeer *peer,
2520 const struct GNUNET_MessageHeader *message) 2550 const struct GNUNET_CADET_KX *msg)
2521{ 2551{
2522 const struct GNUNET_CADET_AX *ax_msg;
2523 const struct GNUNET_CADET_Hash* cid; 2552 const struct GNUNET_CADET_Hash* cid;
2524 struct CadetConnection *c; 2553 struct CadetConnection *c;
2525 size_t minimum_size;
2526 size_t overhead;
2527 uint32_t pid;
2528 int fwd; 2554 int fwd;
2529 2555
2530 GCC_check_connections (); 2556 GCC_check_connections ();
2531 GNUNET_assert (GNUNET_MESSAGE_TYPE_CADET_AX == ntohs (message->type)); 2557 cid = &msg->cid;
2532 overhead = sizeof (struct GNUNET_CADET_AX); 2558 log_message (&msg->header, peer, cid);
2533 ax_msg = (const struct GNUNET_CADET_AX *) message; 2559
2534 cid = &ax_msg->cid;
2535 pid = ntohl (ax_msg->pid);
2536 log_message (message, peer, cid);
2537
2538 minimum_size = sizeof (struct GNUNET_MessageHeader) + overhead;
2539 c = connection_get (cid); 2560 c = connection_get (cid);
2540 fwd = check_message (message, 2561 fwd = check_message (&msg->header,
2541 minimum_size,
2542 cid, 2562 cid,
2543 c, 2563 c,
2544 peer, 2564 peer,
2545 pid); 2565 0);
2546 2566
2547 /* If something went wrong, discard message. */ 2567 /* If something went wrong, discard message. */
2548 if (GNUNET_SYSERR == fwd) 2568 if (GNUNET_SYSERR == fwd)
2549 { 2569 {
2570 GNUNET_break_op (0);
2550 GCC_check_connections (); 2571 GCC_check_connections ();
2551 return GNUNET_OK; 2572 return;
2552 } 2573 }
2553 2574
2554 /* Is this message for us? */ 2575 /* Is this message for us? */
2555 if (GCC_is_terminal (c, fwd)) 2576 if (GCC_is_terminal (c, fwd))
2556 { 2577 {
2557 GNUNET_STATISTICS_update (stats, "# received encrypted", 1, GNUNET_NO); 2578 LOG (GNUNET_ERROR_TYPE_DEBUG, " message for us!\n");
2558 2579 GNUNET_STATISTICS_update (stats, "# received KX", 1, GNUNET_NO);
2559 if (NULL == c->t) 2580 if (NULL == c->t)
2560 { 2581 {
2561 GNUNET_break (GNUNET_NO != c->destroy); 2582 GNUNET_break (0);
2562 return GNUNET_OK; 2583 return;
2563 } 2584 }
2564 GCT_handle_encrypted (c->t, message); 2585 GCT_handle_kx (c->t, &msg[1].header);
2565 GCC_send_ack (c, fwd, GNUNET_NO);
2566 GCC_check_connections (); 2586 GCC_check_connections ();
2567 return GNUNET_OK; 2587 return;
2568 } 2588 }
2569 2589
2570 /* Message not for us: forward to next hop */ 2590 /* Message not for us: forward to next hop */
2571 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n"); 2591 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n");
2572 GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO); 2592 GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
2573 GNUNET_assert (NULL == GCC_send_prebuilt_message (message, 0, 0, c, fwd, 2593 GNUNET_assert (NULL == GCC_send_prebuilt_message (&msg->header, 0, 0, c, fwd,
2574 GNUNET_NO, NULL, NULL)); 2594 GNUNET_NO, NULL, NULL));
2575 GCC_check_connections (); 2595 GCC_check_connections ();
2576 return GNUNET_OK;
2577} 2596}
2578 2597
2579 2598
2580/** 2599/**
2581 * Generic handler for cadet network encrypted traffic. 2600 * Handler for encrypted cadet network traffic (channel mgmt, data).
2582 * 2601 *
2583 * @param peer Peer identity this notification is about. 2602 * @param peer Message sender (neighbor).
2584 * @param msg Encrypted message. 2603 * @param msg Message itself.
2585 * @return #GNUNET_OK to keep the connection open,
2586 * #GNUNET_SYSERR to close it (signal serious error)
2587 */ 2604 */
2588static int 2605void
2589handle_cadet_kx (const struct GNUNET_PeerIdentity *peer, 2606GCC_handle_encrypted (struct CadetPeer *peer,
2590 const struct GNUNET_CADET_KX *msg) 2607 const struct GNUNET_CADET_AX *msg)
2591{ 2608{
2592 const struct GNUNET_CADET_Hash* cid; 2609 const struct GNUNET_CADET_Hash* cid;
2593 struct CadetConnection *c; 2610 struct CadetConnection *c;
2594 size_t expected_size; 2611 uint32_t pid;
2595 int fwd; 2612 int fwd;
2596 2613
2597 GCC_check_connections (); 2614 GCC_check_connections ();
2598 cid = &msg->cid; 2615 cid = &msg->cid;
2616 pid = ntohl (msg->pid);
2599 log_message (&msg->header, peer, cid); 2617 log_message (&msg->header, peer, cid);
2600 2618
2601 expected_size = sizeof (struct GNUNET_CADET_KX)
2602 + sizeof (struct GNUNET_MessageHeader);
2603 c = connection_get (cid); 2619 c = connection_get (cid);
2604 fwd = check_message (&msg->header, 2620 fwd = check_message (&msg->header,
2605 expected_size,
2606 cid, 2621 cid,
2607 c, 2622 c,
2608 peer, 2623 peer,
2609 0); 2624 pid);
2610 2625
2611 /* If something went wrong, discard message. */ 2626 /* If something went wrong, discard message. */
2612 if (GNUNET_SYSERR == fwd) 2627 if (GNUNET_SYSERR == fwd)
2613 return GNUNET_OK; 2628 {
2629 GNUNET_break_op (0);
2630 GCC_check_connections ();
2631 return;
2632 }
2614 2633
2615 /* Is this message for us? */ 2634 /* Is this message for us? */
2616 if (GCC_is_terminal (c, fwd)) 2635 if (GCC_is_terminal (c, fwd))
2617 { 2636 {
2618 LOG (GNUNET_ERROR_TYPE_DEBUG, " message for us!\n"); 2637 GNUNET_STATISTICS_update (stats, "# received encrypted", 1, GNUNET_NO);
2619 GNUNET_STATISTICS_update (stats, "# received KX", 1, GNUNET_NO); 2638
2620 if (NULL == c->t) 2639 if (NULL == c->t)
2621 { 2640 {
2622 GNUNET_break (0); 2641 GNUNET_break (GNUNET_NO != c->destroy);
2623 return GNUNET_OK; 2642 return;
2624 } 2643 }
2625 GCT_handle_kx (c->t, &msg[1].header); 2644 GCT_handle_encrypted (c->t, &msg->header);
2645 GCC_send_ack (c, fwd, GNUNET_NO);
2626 GCC_check_connections (); 2646 GCC_check_connections ();
2627 return GNUNET_OK; 2647 return;
2628 } 2648 }
2629 2649
2630 /* Message not for us: forward to next hop */ 2650 /* Message not for us: forward to next hop */
@@ -2633,259 +2653,6 @@ handle_cadet_kx (const struct GNUNET_PeerIdentity *peer,
2633 GNUNET_assert (NULL == GCC_send_prebuilt_message (&msg->header, 0, 0, c, fwd, 2653 GNUNET_assert (NULL == GCC_send_prebuilt_message (&msg->header, 0, 0, c, fwd,
2634 GNUNET_NO, NULL, NULL)); 2654 GNUNET_NO, NULL, NULL));
2635 GCC_check_connections (); 2655 GCC_check_connections ();
2636 return GNUNET_OK;
2637}
2638
2639
2640/**
2641 * Core handler for key exchange traffic (ephemeral key, ping, pong).
2642 *
2643 * @param cls Closure (unused).
2644 * @param message Message received.
2645 * @param peer Peer who sent the message.
2646 * @return #GNUNET_OK to keep the connection open,
2647 * #GNUNET_SYSERR to close it (signal serious error)
2648 */
2649int
2650GCC_handle_kx (void *cls,
2651 const struct GNUNET_PeerIdentity *peer,
2652 const struct GNUNET_MessageHeader *message)
2653{
2654 GCC_check_connections ();
2655 return handle_cadet_kx (peer, (struct GNUNET_CADET_KX *) message);
2656}
2657
2658
2659/**
2660 * Core handler for encrypted cadet network traffic (channel mgmt, data).
2661 *
2662 * @param cls Closure (unused).
2663 * @param message Message received.
2664 * @param peer Peer who sent the message.
2665 * @return #GNUNET_OK to keep the connection open,
2666 * #GNUNET_SYSERR to close it (signal serious error)
2667 */
2668int
2669GCC_handle_encrypted (void *cls, const struct GNUNET_PeerIdentity *peer,
2670 const struct GNUNET_MessageHeader *message)
2671{
2672 GCC_check_connections ();
2673 return handle_cadet_encrypted (peer, message);
2674}
2675
2676
2677/**
2678 * Core handler for cadet network traffic point-to-point acks.
2679 *
2680 * @param cls closure
2681 * @param message message
2682 * @param peer peer identity this notification is about
2683 * @return #GNUNET_OK to keep the connection open,
2684 * #GNUNET_SYSERR to close it (signal serious error)
2685 */
2686int
2687GCC_handle_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
2688 const struct GNUNET_MessageHeader *message)
2689{
2690 struct GNUNET_CADET_ACK *msg;
2691 struct CadetConnection *c;
2692 struct CadetFlowControl *fc;
2693 GNUNET_PEER_Id id;
2694 uint32_t ack;
2695 int fwd;
2696
2697 GCC_check_connections ();
2698 msg = (struct GNUNET_CADET_ACK *) message;
2699 log_message (message, peer, &msg->cid);
2700 c = connection_get (&msg->cid);
2701 if (NULL == c)
2702 {
2703 GNUNET_STATISTICS_update (stats,
2704 "# ack on unknown connection",
2705 1,
2706 GNUNET_NO);
2707 send_broken_unknown (&msg->cid,
2708 &my_full_id,
2709 NULL,
2710 peer);
2711 GCC_check_connections ();
2712 return GNUNET_OK;
2713 }
2714
2715 /* Is this a forward or backward ACK? */
2716 id = GNUNET_PEER_search (peer);
2717 if (GCP_get_short_id (get_next_hop (c)) == id)
2718 {
2719 fc = &c->fwd_fc;
2720 fwd = GNUNET_YES;
2721 }
2722 else if (GCP_get_short_id (get_prev_hop (c)) == id)
2723 {
2724 fc = &c->bck_fc;
2725 fwd = GNUNET_NO;
2726 }
2727 else
2728 {
2729 GNUNET_break_op (0);
2730 return GNUNET_OK;
2731 }
2732
2733 ack = ntohl (msg->ack);
2734 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s ACK %u (was %u)\n",
2735 GC_f2s (fwd), ack, fc->last_ack_recv);
2736 if (GC_is_pid_bigger (ack, fc->last_ack_recv))
2737 fc->last_ack_recv = ack;
2738
2739 /* Cancel polling if the ACK is big enough. */
2740 if (NULL != fc->poll_task &&
2741 GC_is_pid_bigger (fc->last_ack_recv, fc->last_pid_sent))
2742 {
2743 LOG (GNUNET_ERROR_TYPE_DEBUG, " Cancel poll\n");
2744 GNUNET_SCHEDULER_cancel (fc->poll_task);
2745 fc->poll_task = NULL;
2746 fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
2747 }
2748
2749 connection_unlock_queue (c, fwd);
2750 GCC_check_connections ();
2751 return GNUNET_OK;
2752}
2753
2754
2755/**
2756 * Core handler for cadet network traffic point-to-point ack polls.
2757 *
2758 * @param cls closure
2759 * @param message message
2760 * @param peer peer identity this notification is about
2761 * @return #GNUNET_OK to keep the connection open,
2762 * #GNUNET_SYSERR to close it (signal serious error)
2763 */
2764int
2765GCC_handle_poll (void *cls,
2766 const struct GNUNET_PeerIdentity *peer,
2767 const struct GNUNET_MessageHeader *message)
2768{
2769 struct GNUNET_CADET_Poll *msg;
2770 struct CadetConnection *c;
2771 struct CadetFlowControl *fc;
2772 GNUNET_PEER_Id id;
2773 uint32_t pid;
2774 int fwd;
2775
2776 GCC_check_connections ();
2777 msg = (struct GNUNET_CADET_Poll *) message;
2778 log_message (message, peer, &msg->cid);
2779 c = connection_get (&msg->cid);
2780 if (NULL == c)
2781 {
2782 GNUNET_STATISTICS_update (stats, "# poll on unknown connection", 1,
2783 GNUNET_NO);
2784 LOG (GNUNET_ERROR_TYPE_DEBUG,
2785 "POLL message on unknown connection %s!\n",
2786 GNUNET_h2s (GC_h2hc (&msg->cid)));
2787 send_broken_unknown (&msg->cid,
2788 &my_full_id,
2789 NULL,
2790 peer);
2791 GCC_check_connections ();
2792 return GNUNET_OK;
2793 }
2794
2795 /* Is this a forward or backward ACK?
2796 * Note: a poll should never be needed in a loopback case,
2797 * since there is no possiblility of packet loss there, so
2798 * this way of discerining FWD/BCK should not be a problem.
2799 */
2800 id = GNUNET_PEER_search (peer);
2801 if (GCP_get_short_id (get_next_hop (c)) == id)
2802 {
2803 LOG (GNUNET_ERROR_TYPE_DEBUG, " FWD FC\n");
2804 fc = &c->fwd_fc;
2805 }
2806 else if (GCP_get_short_id (get_prev_hop (c)) == id)
2807 {
2808 LOG (GNUNET_ERROR_TYPE_DEBUG, " BCK FC\n");
2809 fc = &c->bck_fc;
2810 }
2811 else
2812 {
2813 GNUNET_break_op (0);
2814 return GNUNET_OK;
2815 }
2816
2817 pid = ntohl (msg->pid);
2818 LOG (GNUNET_ERROR_TYPE_DEBUG, " PID %u, OLD %u\n", pid, fc->last_pid_recv);
2819 fc->last_pid_recv = pid;
2820 fwd = fc == &c->bck_fc;
2821 GCC_send_ack (c, fwd, GNUNET_YES);
2822 GCC_check_connections ();
2823
2824 return GNUNET_OK;
2825}
2826
2827
2828/**
2829 * Send an ACK on the appropriate connection/channel, depending on
2830 * the direction and the position of the peer.
2831 *
2832 * @param c Which connection to send the hop-by-hop ACK.
2833 * @param fwd Is this a fwd ACK? (will go dest->root).
2834 * @param force Send the ACK even if suboptimal (e.g. requested by POLL).
2835 */
2836void
2837GCC_send_ack (struct CadetConnection *c, int fwd, int force)
2838{
2839 unsigned int buffer;
2840
2841 GCC_check_connections ();
2842 LOG (GNUNET_ERROR_TYPE_DEBUG, "GCC send %s ACK on %s\n",
2843 GC_f2s (fwd), GCC_2s (c));
2844
2845 if (NULL == c)
2846 {
2847 GNUNET_break (0);
2848 return;
2849 }
2850
2851 if (GNUNET_NO != c->destroy)
2852 {
2853 LOG (GNUNET_ERROR_TYPE_DEBUG, " being destroyed, why bother...\n");
2854 GCC_check_connections ();
2855 return;
2856 }
2857
2858 /* Get available buffer space */
2859 if (GCC_is_terminal (c, fwd))
2860 {
2861 LOG (GNUNET_ERROR_TYPE_DEBUG, " getting from all channels\n");
2862 buffer = GCT_get_channels_buffer (c->t);
2863 }
2864 else
2865 {
2866 LOG (GNUNET_ERROR_TYPE_DEBUG, " getting from one connection\n");
2867 buffer = GCC_get_buffer (c, fwd);
2868 }
2869 LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer available: %u\n", buffer);
2870 if (0 == buffer && GNUNET_NO == force)
2871 {
2872 GCC_check_connections ();
2873 return;
2874 }
2875
2876 /* Send available buffer space */
2877 if (GCC_is_origin (c, fwd))
2878 {
2879 GNUNET_assert (NULL != c->t);
2880 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channels...\n");
2881 GCT_unchoke_channels (c->t);
2882 }
2883 else
2884 {
2885 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on connection\n");
2886 send_ack (c, buffer, fwd, force);
2887 }
2888 GCC_check_connections ();
2889} 2656}
2890 2657
2891 2658
@@ -2974,12 +2741,13 @@ GCC_shutdown (void)
2974 * Create a connection. 2741 * Create a connection.
2975 * 2742 *
2976 * @param cid Connection ID (either created locally or imposed remotely). 2743 * @param cid Connection ID (either created locally or imposed remotely).
2977 * @param t Tunnel this connection belongs to (or NULL); 2744 * @param t Tunnel this connection belongs to (or NULL for transit connections);
2978 * @param path Path this connection has to use (copy is made). 2745 * @param path Path this connection has to use (copy is made).
2979 * @param own_pos Own position in the @c path path. 2746 * @param own_pos Own position in the @c path path.
2980 * 2747 *
2981 * @return Newly created connection, NULL in case of error (own id not in path). 2748 * @return Newly created connection.
2982 */ 2749 * NULL in case of error: own id not in path, wrong neighbors, ...
2750*/
2983struct CadetConnection * 2751struct CadetConnection *
2984GCC_new (const struct GNUNET_CADET_Hash *cid, 2752GCC_new (const struct GNUNET_CADET_Hash *cid,
2985 struct CadetTunnel *t, 2753 struct CadetTunnel *t,
@@ -3036,6 +2804,14 @@ GCC_new (const struct GNUNET_CADET_Hash *cid,
3036} 2804}
3037 2805
3038 2806
2807/**
2808 * Connection is no longer needed: destroy it.
2809 *
2810 * Cancels all pending traffic (including possible DESTROY messages), all
2811 * maintenance tasks and removes the connection from neighbor peers and tunnel.
2812 *
2813 * @param c Connection to destroy.
2814 */
3039void 2815void
3040GCC_destroy (struct CadetConnection *c) 2816GCC_destroy (struct CadetConnection *c)
3041{ 2817{
@@ -3428,6 +3204,7 @@ GCC_is_direct (struct CadetConnection *c)
3428 * @param message Message to send. Function makes a copy of it. 3204 * @param message Message to send. Function makes a copy of it.
3429 * If message is not hop-by-hop, decrements TTL of copy. 3205 * If message is not hop-by-hop, decrements TTL of copy.
3430 * @param payload_type Type of payload, in case the message is encrypted. 3206 * @param payload_type Type of payload, in case the message is encrypted.
3207 * @param payload_id ID of the payload (PID, ACK, ...).
3431 * @param c Connection on which this message is transmitted. 3208 * @param c Connection on which this message is transmitted.
3432 * @param fwd Is this a fwd message? 3209 * @param fwd Is this a fwd message?
3433 * @param force Force the connection to accept the message (buffer overfill). 3210 * @param force Force the connection to accept the message (buffer overfill).
@@ -3446,7 +3223,7 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3446{ 3223{
3447 struct CadetFlowControl *fc; 3224 struct CadetFlowControl *fc;
3448 struct CadetConnectionQueue *q; 3225 struct CadetConnectionQueue *q;
3449 void *data; 3226 struct GNUNET_MessageHeader *copy;
3450 size_t size; 3227 size_t size;
3451 uint16_t type; 3228 uint16_t type;
3452 int droppable; 3229 int droppable;
@@ -3460,8 +3237,8 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3460 } 3237 }
3461 3238
3462 size = ntohs (message->size); 3239 size = ntohs (message->size);
3463 data = GNUNET_malloc (size); 3240 copy = GNUNET_malloc (size);
3464 GNUNET_memcpy (data, message, size); 3241 GNUNET_memcpy (copy, message, size);
3465 type = ntohs (message->type); 3242 type = ntohs (message->type);
3466 LOG (GNUNET_ERROR_TYPE_INFO, 3243 LOG (GNUNET_ERROR_TYPE_INFO,
3467 "--> %s (%s %4u) on conn %s (%p) %s [%5u]\n", 3244 "--> %s (%s %4u) on conn %s (%p) %s [%5u]\n",
@@ -3478,7 +3255,7 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3478 struct GNUNET_CADET_ConnectionBroken *bmsg; 3255 struct GNUNET_CADET_ConnectionBroken *bmsg;
3479 3256
3480 case GNUNET_MESSAGE_TYPE_CADET_AX: 3257 case GNUNET_MESSAGE_TYPE_CADET_AX:
3481 axmsg = (struct GNUNET_CADET_AX *) data; 3258 axmsg = (struct GNUNET_CADET_AX *) copy;
3482 axmsg->cid = c->id; 3259 axmsg->cid = c->id;
3483 LOG (GNUNET_ERROR_TYPE_DEBUG, " Q_N+ %p %u\n", fc, fc->queue_n); 3260 LOG (GNUNET_ERROR_TYPE_DEBUG, " Q_N+ %p %u\n", fc, fc->queue_n);
3484 LOG (GNUNET_ERROR_TYPE_DEBUG, "last pid sent %u\n", fc->last_pid_sent); 3261 LOG (GNUNET_ERROR_TYPE_DEBUG, "last pid sent %u\n", fc->last_pid_sent);
@@ -3494,41 +3271,42 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3494 break; 3271 break;
3495 3272
3496 case GNUNET_MESSAGE_TYPE_CADET_KX: 3273 case GNUNET_MESSAGE_TYPE_CADET_KX:
3497 kmsg = (struct GNUNET_CADET_KX *) data; 3274 kmsg = (struct GNUNET_CADET_KX *) copy;
3498 kmsg->cid = c->id; 3275 kmsg->cid = c->id;
3499 break; 3276 break;
3500 3277
3501 case GNUNET_MESSAGE_TYPE_CADET_ACK: 3278 case GNUNET_MESSAGE_TYPE_CADET_ACK:
3502 amsg = (struct GNUNET_CADET_ACK *) data; 3279 amsg = (struct GNUNET_CADET_ACK *) copy;
3503 amsg->cid = c->id; 3280 amsg->cid = c->id;
3504 LOG (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ntohl (amsg->ack)); 3281 LOG (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ntohl (amsg->ack));
3505 droppable = GNUNET_NO; 3282 droppable = GNUNET_NO;
3506 break; 3283 break;
3507 3284
3508 case GNUNET_MESSAGE_TYPE_CADET_POLL: 3285 case GNUNET_MESSAGE_TYPE_CADET_POLL:
3509 pmsg = (struct GNUNET_CADET_Poll *) data; 3286 pmsg = (struct GNUNET_CADET_Poll *) copy;
3510 pmsg->cid = c->id; 3287 pmsg->cid = c->id;
3511 LOG (GNUNET_ERROR_TYPE_DEBUG, " POLL %u\n", ntohl (pmsg->pid)); 3288 LOG (GNUNET_ERROR_TYPE_DEBUG, " POLL %u\n", ntohl (pmsg->pid));
3512 droppable = GNUNET_NO; 3289 droppable = GNUNET_NO;
3513 break; 3290 break;
3514 3291
3515 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY: 3292 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
3516 dmsg = (struct GNUNET_CADET_ConnectionDestroy *) data; 3293 dmsg = (struct GNUNET_CADET_ConnectionDestroy *) copy;
3517 dmsg->cid = c->id; 3294 dmsg->cid = c->id;
3518 break; 3295 break;
3519 3296
3520 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN: 3297 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
3521 bmsg = (struct GNUNET_CADET_ConnectionBroken *) data; 3298 bmsg = (struct GNUNET_CADET_ConnectionBroken *) copy;
3522 bmsg->cid = c->id; 3299 bmsg->cid = c->id;
3523 break; 3300 break;
3524 3301
3525 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE: 3302 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
3526 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK: 3303 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK:
3304 GNUNET_break (0); /* Should've used specific functions. */
3527 break; 3305 break;
3528 3306
3529 default: 3307 default:
3530 GNUNET_break (0); 3308 GNUNET_break (0);
3531 GNUNET_free (data); 3309 GNUNET_free (copy);
3532 return NULL; 3310 return NULL;
3533 } 3311 }
3534 3312
@@ -3543,7 +3321,7 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3543 { 3321 {
3544 fc->queue_n--; 3322 fc->queue_n--;
3545 } 3323 }
3546 GNUNET_free (data); 3324 GNUNET_free (copy);
3547 return NULL; /* Drop this message */ 3325 return NULL; /* Drop this message */
3548 } 3326 }
3549 3327
@@ -3553,12 +3331,14 @@ GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3553 3331
3554 q = GNUNET_new (struct CadetConnectionQueue); 3332 q = GNUNET_new (struct CadetConnectionQueue);
3555 q->forced = !droppable; 3333 q->forced = !droppable;
3556 q->q = GCP_queue_add (get_hop (c, fwd), data, type, payload_type, payload_id, 3334 q->peer_q = GCP_send (get_hop (c, fwd), copy,
3557 size, c, fwd, &conn_message_sent, q); 3335 payload_type, payload_id,
3558 if (NULL == q->q) 3336 c, fwd,
3337 &conn_message_sent, q);
3338 if (NULL == q->peer_q)
3559 { 3339 {
3560 LOG (GNUNET_ERROR_TYPE_DEBUG, "dropping msg on %s, NULL q\n", GCC_2s (c)); 3340 LOG (GNUNET_ERROR_TYPE_DEBUG, "dropping msg on %s, NULL q\n", GCC_2s (c));
3561 GNUNET_free (data); 3341 GNUNET_free (copy);
3562 GNUNET_free (q); 3342 GNUNET_free (q);
3563 GCC_check_connections (); 3343 GCC_check_connections ();
3564 return NULL; 3344 return NULL;
@@ -3584,8 +3364,8 @@ GCC_cancel (struct CadetConnectionQueue *q)
3584{ 3364{
3585 LOG (GNUNET_ERROR_TYPE_DEBUG, "! GCC cancel message\n"); 3365 LOG (GNUNET_ERROR_TYPE_DEBUG, "! GCC cancel message\n");
3586 3366
3587 /* queue destroy calls message_sent, which calls q->cont and frees q */ 3367 /* send_cancel calls message_sent, which calls q->cont and frees q */
3588 GCP_queue_destroy (q->q, GNUNET_YES, GNUNET_NO, 0); 3368 GCP_send_cancel (q->peer_q);
3589 GCC_check_connections (); 3369 GCC_check_connections ();
3590} 3370}
3591 3371
@@ -3594,35 +3374,116 @@ GCC_cancel (struct CadetConnectionQueue *q)
3594 * Sends a CREATE CONNECTION message for a path to a peer. 3374 * Sends a CREATE CONNECTION message for a path to a peer.
3595 * Changes the connection and tunnel states if necessary. 3375 * Changes the connection and tunnel states if necessary.
3596 * 3376 *
3597 * @param connection Connection to create. 3377 * @param c Connection to create.
3598 */ 3378 */
3599void 3379void
3600GCC_send_create (struct CadetConnection *connection) 3380GCC_send_create (struct CadetConnection *c)
3601{ 3381{
3602 enum CadetTunnelCState state; 3382 enum CadetTunnelCState state;
3603 size_t size; 3383 size_t size;
3604 3384
3605 GCC_check_connections (); 3385 GCC_check_connections ();
3606 size = sizeof (struct GNUNET_CADET_ConnectionCreate); 3386 size = sizeof (struct GNUNET_CADET_ConnectionCreate);
3607 size += connection->path->length * sizeof (struct GNUNET_PeerIdentity); 3387 size += c->path->length * sizeof (struct GNUNET_PeerIdentity);
3388 {
3389 /* Allocate message on the stack */
3390 unsigned char cbuf[size];
3391 struct GNUNET_CADET_ConnectionCreate *msg;
3392 struct GNUNET_PeerIdentity *peers;
3393
3394 msg = (struct GNUNET_CADET_ConnectionCreate *) cbuf;
3395 msg->header.size = htons (size);
3396 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
3397 msg->cid = *GCC_get_id (c);
3398 peers = (struct GNUNET_PeerIdentity *) &msg[1];
3399 for (int i = 0; i < c->path->length; i++)
3400 {
3401 GNUNET_PEER_resolve (c->path->peers[i], peers++);
3402 }
3403 GNUNET_assert (NULL == c->maintenance_q);
3404 c->maintenance_q = GCP_send (get_next_hop (c),
3405 &msg->header,
3406 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, 0,
3407 c, GNUNET_YES,
3408 &conn_message_sent, NULL);
3409 }
3608 3410
3609 LOG (GNUNET_ERROR_TYPE_INFO, "==> %s %19s on conn %s (%p) FWD [%5u]\n", 3411 LOG (GNUNET_ERROR_TYPE_INFO, "==> %s %19s on conn %s (%p) FWD [%5u]\n",
3610 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE), "", 3412 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE), "",
3611 GCC_2s (connection), connection, size); 3413 GCC_2s (c), c, size);
3612 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %p %u (create)\n", 3414 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %p %u (create)\n",
3613 connection, connection->pending_messages); 3415 c, c->pending_messages);
3614 connection->pending_messages++; 3416 c->pending_messages++;
3615
3616 connection->maintenance_q =
3617 GCP_queue_add (get_next_hop (connection), NULL,
3618 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, UINT16_MAX, 0,
3619 size, connection, GNUNET_YES, &conn_message_sent, NULL);
3620 3417
3621 state = GCT_get_cstate (connection->t); 3418 state = GCT_get_cstate (c->t);
3622 if (CADET_TUNNEL_SEARCHING == state || CADET_TUNNEL_NEW == state) 3419 if (CADET_TUNNEL_SEARCHING == state || CADET_TUNNEL_NEW == state)
3623 GCT_change_cstate (connection->t, CADET_TUNNEL_WAITING); 3420 GCT_change_cstate (c->t, CADET_TUNNEL_WAITING);
3624 if (CADET_CONNECTION_NEW == connection->state) 3421 if (CADET_CONNECTION_NEW == c->state)
3625 connection_change_state (connection, CADET_CONNECTION_SENT); 3422 connection_change_state (c, CADET_CONNECTION_SENT);
3423 GCC_check_connections ();
3424}
3425
3426
3427/**
3428 * Send an ACK on the appropriate connection/channel, depending on
3429 * the direction and the position of the peer.
3430 *
3431 * @param c Which connection to send the hop-by-hop ACK.
3432 * @param fwd Is this a fwd ACK? (will go dest->root).
3433 * @param force Send the ACK even if suboptimal (e.g. requested by POLL).
3434 */
3435void
3436GCC_send_ack (struct CadetConnection *c, int fwd, int force)
3437{
3438 unsigned int buffer;
3439
3440 GCC_check_connections ();
3441 LOG (GNUNET_ERROR_TYPE_DEBUG, "GCC send %s ACK on %s\n",
3442 GC_f2s (fwd), GCC_2s (c));
3443
3444 if (NULL == c)
3445 {
3446 GNUNET_break (0);
3447 return;
3448 }
3449
3450 if (GNUNET_NO != c->destroy)
3451 {
3452 LOG (GNUNET_ERROR_TYPE_DEBUG, " being destroyed, why bother...\n");
3453 GCC_check_connections ();
3454 return;
3455 }
3456
3457 /* Get available buffer space */
3458 if (GCC_is_terminal (c, fwd))
3459 {
3460 LOG (GNUNET_ERROR_TYPE_DEBUG, " getting from all channels\n");
3461 buffer = GCT_get_channels_buffer (c->t);
3462 }
3463 else
3464 {
3465 LOG (GNUNET_ERROR_TYPE_DEBUG, " getting from one connection\n");
3466 buffer = GCC_get_buffer (c, fwd);
3467 }
3468 LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer available: %u\n", buffer);
3469 if (0 == buffer && GNUNET_NO == force)
3470 {
3471 GCC_check_connections ();
3472 return;
3473 }
3474
3475 /* Send available buffer space */
3476 if (GNUNET_YES == GCC_is_origin (c, fwd))
3477 {
3478 GNUNET_assert (NULL != c->t);
3479 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channels...\n");
3480 GCT_unchoke_channels (c->t);
3481 }
3482 else
3483 {
3484 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on connection\n");
3485 send_ack (c, buffer, fwd, force);
3486 }
3626 GCC_check_connections (); 3487 GCC_check_connections ();
3627} 3488}
3628 3489
diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h
index e96e2f24c..6302cd898 100644
--- a/src/cadet/gnunet-service-cadet_connection.h
+++ b/src/cadet/gnunet-service-cadet_connection.h
@@ -118,90 +118,86 @@ typedef void
118 118
119 119
120/** 120/**
121 * Core handler for connection creation. 121 * Handler for connection creation.
122 * 122 *
123 * @param cls Closure (unused). 123 * @param peer Message sender (neighbor).
124 * @param peer Sender (neighbor). 124 * @param msg Message itself.
125 * @param message Message.
126 * @return #GNUNET_OK to keep the connection open,
127 * #GNUNET_SYSERR to close it (signal serious error)
128 */ 125 */
129int 126void
130GCC_handle_create (void *cls, 127GCC_handle_create (struct CadetPeer *peer,
131 const struct GNUNET_PeerIdentity *peer, 128 const struct GNUNET_CADET_ConnectionCreate *msg);
132 const struct GNUNET_MessageHeader *message);
133 129
134 130
135/** 131/**
136 * Core handler for path confirmations. 132 * Handler for connection confirmations.
137 * 133 *
138 * @param cls closure 134 * @param peer Message sender (neighbor).
139 * @param message message 135 * @param msg Message itself.
140 * @param peer peer identity this notification is about
141 * @return #GNUNET_OK to keep the connection open,
142 * #GNUNET_SYSERR to close it (signal serious error)
143 */ 136 */
144int 137void
145GCC_handle_confirm (void *cls, 138GCC_handle_confirm (struct CadetPeer *peer,
146 const struct GNUNET_PeerIdentity *peer, 139 const struct GNUNET_CADET_ConnectionACK *msg);
147 const struct GNUNET_MessageHeader *message);
148 140
149 141
150/** 142/**
151 * Core handler for notifications of broken paths 143 * Handler for notifications of broken connections.
152 * 144 *
153 * @param cls Closure (unused). 145 * @param peer Message sender (neighbor).
154 * @param id Peer identity of sending neighbor. 146 * @param msg Message itself.
155 * @param message Message.
156 * @return #GNUNET_OK to keep the connection open,
157 * #GNUNET_SYSERR to close it (signal serious error)
158 */ 147 */
159int 148void
160GCC_handle_broken (void* cls, 149GCC_handle_broken (struct CadetPeer *peer,
161 const struct GNUNET_PeerIdentity* id, 150 const struct GNUNET_CADET_ConnectionBroken *msg);
162 const struct GNUNET_MessageHeader* message);
163 151
164/** 152/**
165 * Core handler for tunnel destruction 153 * Handler for notifications of destroyed connections.
166 * 154 *
167 * @param cls Closure (unused). 155 * @param peer Message sender (neighbor).
168 * @param peer Peer identity of sending neighbor. 156 * @param msg Message itself.
169 * @param message Message.
170 *
171 * @return GNUNET_OK to keep the connection open,
172 * GNUNET_SYSERR to close it (signal serious error)
173 */ 157 */
174int 158void
175GCC_handle_destroy (void *cls, const struct GNUNET_PeerIdentity *peer, 159GCC_handle_destroy (struct CadetPeer *peer,
176 const struct GNUNET_MessageHeader *message); 160 const struct GNUNET_CADET_ConnectionDestroy *msg);
177 161
178/** 162/**
179 * Core handler for key exchange traffic (ephemeral key, ping, pong). 163 * Handler for cadet network traffic hop-by-hop acks.
180 * 164 *
181 * @param cls Closure (unused). 165 * @param peer Message sender (neighbor).
182 * @param message Message received. 166 * @param msg Message itself.
183 * @param peer Peer who sent the message. 167 */
168void
169GCC_handle_ack (struct CadetPeer *peer,
170 const struct GNUNET_CADET_ACK *msg);
171
172/**
173 * Handler for cadet network traffic hop-by-hop data counter polls.
184 * 174 *
185 * @return GNUNET_OK to keep the connection open, 175 * @param peer Message sender (neighbor).
186 * GNUNET_SYSERR to close it (signal serious error) 176 * @param msg Message itself.
187 */ 177 */
188int 178void
189GCC_handle_kx (void *cls, const struct GNUNET_PeerIdentity *peer, 179GCC_handle_poll (struct CadetPeer *peer,
190 const struct GNUNET_MessageHeader *message); 180 const struct GNUNET_CADET_Poll *msg);
191 181
192/** 182/**
193 * Core handler for encrypted cadet network traffic (channel mgmt, data). 183 * Handler for key exchange traffic (Axolotl KX).
194 * 184 *
195 * @param cls Closure (unused). 185 * @param peer Message sender (neighbor).
196 * @param message Message received. 186 * @param msg Message itself.
197 * @param peer Peer who sent the message. 187 */
188void
189GCC_handle_kx (struct CadetPeer *peer,
190 const struct GNUNET_CADET_KX *msg);
191
192/**
193 * Handler for encrypted cadet network traffic (channel mgmt, data).
198 * 194 *
199 * @return GNUNET_OK to keep the connection open, 195 * @param peer Message sender (neighbor).
200 * GNUNET_SYSERR to close it (signal serious error) 196 * @param msg Message itself.
201 */ 197 */
202int 198void
203GCC_handle_encrypted (void *cls, const struct GNUNET_PeerIdentity *peer, 199GCC_handle_encrypted (struct CadetPeer *peer,
204 const struct GNUNET_MessageHeader *message); 200 const struct GNUNET_CADET_AX *msg);
205 201
206/** 202/**
207 * Core handler for axolotl key exchange traffic. 203 * Core handler for axolotl key exchange traffic.
@@ -230,34 +226,6 @@ GCC_handle_ax (void *cls, const struct GNUNET_PeerIdentity *peer,
230 struct GNUNET_MessageHeader *message); 226 struct GNUNET_MessageHeader *message);
231 227
232/** 228/**
233 * Core handler for cadet network traffic point-to-point acks.
234 *
235 * @param cls closure
236 * @param message message
237 * @param peer peer identity this notification is about
238 *
239 * @return GNUNET_OK to keep the connection open,
240 * GNUNET_SYSERR to close it (signal serious error)
241 */
242int
243GCC_handle_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
244 const struct GNUNET_MessageHeader *message);
245
246/**
247 * Core handler for cadet network traffic point-to-point ack polls.
248 *
249 * @param cls closure
250 * @param message message
251 * @param peer peer identity this notification is about
252 *
253 * @return GNUNET_OK to keep the connection open,
254 * GNUNET_SYSERR to close it (signal serious error)
255 */
256int
257GCC_handle_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
258 const struct GNUNET_MessageHeader *message);
259
260/**
261 * Core handler for cadet keepalives. 229 * Core handler for cadet keepalives.
262 * 230 *
263 * @param cls closure 231 * @param cls closure
@@ -301,11 +269,12 @@ GCC_shutdown (void);
301 * Create a connection. 269 * Create a connection.
302 * 270 *
303 * @param cid Connection ID (either created locally or imposed remotely). 271 * @param cid Connection ID (either created locally or imposed remotely).
304 * @param t Tunnel this connection belongs to (or NULL); 272 * @param t Tunnel this connection belongs to (or NULL for transit connections);
305 * @param path Path this connection has to use (copy is made). 273 * @param path Path this connection has to use (copy is made).
306 * @param own_pos Own position in the @c path path. 274 * @param own_pos Own position in the @c path path.
307 * 275 *
308 * @return Newly created connection, NULL in case of error (own id not in path). 276 * @return Newly created connection.
277 * NULL in case of error: own id not in path, wrong neighbors, ...
309 */ 278 */
310struct CadetConnection * 279struct CadetConnection *
311GCC_new (const struct GNUNET_CADET_Hash *cid, 280GCC_new (const struct GNUNET_CADET_Hash *cid,
@@ -525,6 +494,7 @@ GCC_cancel (struct CadetConnectionQueue *q);
525 * @param message Message to send. Function makes a copy of it. 494 * @param message Message to send. Function makes a copy of it.
526 * If message is not hop-by-hop, decrements TTL of copy. 495 * If message is not hop-by-hop, decrements TTL of copy.
527 * @param payload_type Type of payload, in case the message is encrypted. 496 * @param payload_type Type of payload, in case the message is encrypted.
497 * @param payload_id ID of the payload (PID, ACK, ...).
528 * @param c Connection on which this message is transmitted. 498 * @param c Connection on which this message is transmitted.
529 * @param fwd Is this a fwd message? 499 * @param fwd Is this a fwd message?
530 * @param force Force the connection to accept the message (buffer overfill). 500 * @param force Force the connection to accept the message (buffer overfill).
diff --git a/src/cadet/gnunet-service-cadet_local.c b/src/cadet/gnunet-service-cadet_local.c
index 303eaee86..9be1224c1 100644
--- a/src/cadet/gnunet-service-cadet_local.c
+++ b/src/cadet/gnunet-service-cadet_local.c
@@ -720,8 +720,6 @@ show_peer_iterator (void *cls,
720 struct CadetPeer *p = value; 720 struct CadetPeer *p = value;
721 struct CadetTunnel *t; 721 struct CadetTunnel *t;
722 722
723 GCP_debug (p, GNUNET_ERROR_TYPE_ERROR);
724
725 t = GCP_get_tunnel (p); 723 t = GCP_get_tunnel (p);
726 if (NULL != t) 724 if (NULL != t)
727 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR); 725 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR);
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index 64d9168fd..5ccd8f014 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -44,164 +44,145 @@
44/******************************** STRUCTS **********************************/ 44/******************************** STRUCTS **********************************/
45/******************************************************************************/ 45/******************************************************************************/
46 46
47
47/** 48/**
48 * Struct containing info about a queued transmission to this peer 49 * Struct containing all information regarding a given peer
49 */ 50 */
50struct CadetPeerQueue 51struct CadetPeer
51{ 52{
52 /** 53 /**
53 * DLL next 54 * ID of the peer
54 */ 55 */
55 struct CadetPeerQueue *next; 56 GNUNET_PEER_Id id;
56 57
57 /** 58 /**
58 * DLL previous 59 * Last time we heard from this peer
59 */ 60 */
60 struct CadetPeerQueue *prev; 61 struct GNUNET_TIME_Absolute last_contact;
61 62
62 /** 63 /**
63 * Peer this transmission is directed to. 64 * Paths to reach the peer, ordered by ascending hop count
64 */ 65 */
65 struct CadetPeer *peer; 66 struct CadetPeerPath *path_head;
66 67
67 /** 68 /**
68 * Connection this message belongs to. 69 * Paths to reach the peer, ordered by ascending hop count
69 */ 70 */
70 struct CadetConnection *c; 71 struct CadetPeerPath *path_tail;
71 72
72 /** 73 /**
73 * Is FWD in c? 74 * Handle to stop the DHT search for paths to this peer
74 */ 75 */
75 int fwd; 76 struct GCD_search_handle *search_h;
76 77
77 /** 78 /**
78 * Pointer to info stucture used as cls. 79 * Handle to stop the DHT search for paths to this peer
79 */ 80 */
80 void *cls; 81 struct GNUNET_SCHEDULER_Task *search_delayed;
81 82
82 /** 83 /**
83 * Type of message 84 * Tunnel to this peer, if any.
84 */ 85 */
85 uint16_t type; 86 struct CadetTunnel *tunnel;
86 87
87 /** 88 /**
88 * Type of message 89 * Connections that go through this peer; indexed by tid.
89 */ 90 */
90 uint16_t payload_type; 91 struct GNUNET_CONTAINER_MultiHashMap *connections;
91 92
92 /** 93 /**
93 * Type of message 94 * Handle for core transmissions.
94 */ 95 */
95 uint32_t payload_id; 96 struct GNUNET_MQ_Handle *core_mq;
96 97
97 /** 98 /**
98 * Size of the message 99 * How many messages are in the queue to this peer.
99 */ 100 */
100 size_t size; 101 unsigned int queue_n;
101 102
102 /** 103 /**
103 * Set when this message starts waiting for CORE. 104 * Hello message.
104 */ 105 */
105 struct GNUNET_TIME_Absolute start_waiting; 106 struct GNUNET_HELLO_Message* hello;
106 107
107 /** 108 /**
108 * Function to call on sending. 109 * Handle to us offering the HELLO to the transport.
109 */ 110 */
110 GCP_sent cont; 111 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
111 112
112 /** 113 /**
113 * Closure for callback. 114 * Handle to our ATS request asking ATS to suggest an address
115 * to TRANSPORT for this peer (to establish a direct link).
114 */ 116 */
115 void *cont_cls; 117 struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion;
118
116}; 119};
117 120
118 121
119/** 122/**
120 * Struct containing all information regarding a given peer 123 * Information about a queued message on the peer level.
121 */ 124 */
122struct CadetPeer 125struct CadetPeerQueue {
123{
124 /**
125 * ID of the peer
126 */
127 GNUNET_PEER_Id id;
128 126
129 /** 127 /**
130 * Last time we heard from this peer 128 * Envelope to cancel message before MQ sends it.
131 */
132 struct GNUNET_TIME_Absolute last_contact;
133
134 /**
135 * Paths to reach the peer, ordered by ascending hop count
136 */ 129 */
137 struct CadetPeerPath *path_head; 130 struct GNUNET_MQ_Envelope *env;
138 131
139 /** 132 /**
140 * Paths to reach the peer, ordered by ascending hop count 133 * Peer (neighbor) this message is being sent to.
141 */ 134 */
142 struct CadetPeerPath *path_tail; 135 struct CadetPeer *peer;
143
144 /**
145 * Handle to stop the DHT search for paths to this peer
146 */
147 struct GCD_search_handle *search_h;
148
149 /**
150 * Handle to stop the DHT search for paths to this peer
151 */
152 struct GNUNET_SCHEDULER_Task *search_delayed;
153 136
154 /** 137 /**
155 * Tunnel to this peer, if any. 138 * Continuation to call to notify higher layers about message sent.
156 */ 139 */
157 struct CadetTunnel *tunnel; 140 GCP_sent cont;
158 141
159 /** 142 /**
160 * Connections that go through this peer; indexed by tid. 143 * Closure for @a cont.
161 */ 144 */
162 struct GNUNET_CONTAINER_MultiHashMap *connections; 145 void *cont_cls;
163 146
164 /** 147 /**
165 * Handle for queued transmissions 148 * Time when message was queued for sending.
166 */ 149 */
167 struct GNUNET_CORE_TransmitHandle *core_transmit; 150 struct GNUNET_TIME_Absolute queue_timestamp;
168 151
169 /** 152 /**
170 * Timestamp 153 * #GNUNET_YES if message was management traffic (POLL, ACK, ...).
171 */ 154 */
172 struct GNUNET_TIME_Absolute tmt_time; 155 int management_traffic;
173 156
174 /** 157 /**
175 * Transmission queue to core DLL head 158 * Message type.
176 */ 159 */
177 struct CadetPeerQueue *queue_head; 160 uint16_t type;
178 161
179 /** 162 /**
180 * Transmission queue to core DLL tail 163 * Message size.
181 */ 164 */
182 struct CadetPeerQueue *queue_tail; 165 uint16_t size;
183 166
184 /** 167 /**
185 * How many messages are in the queue to this peer. 168 * Type of the message's payload, if it was encrypted data.
186 */ 169 */
187 unsigned int queue_n; 170 uint16_t payload_type;
188 171
189 /** 172 /**
190 * Hello message. 173 *ID of the payload (PID, ACK #, ...).
191 */ 174 */
192 struct GNUNET_HELLO_Message* hello; 175 uint16_t payload_id;
193 176
194 /** 177 /**
195 * Handle to us offering the HELLO to the transport. 178 * Connection this message was sent on.
196 */ 179 */
197 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer; 180 struct CadetConnection *c;
198 181
199 /** 182 /**
200 * Handle to our ATS request asking ATS to suggest an address 183 * Direction in @a c this message was send on (#GNUNET_YES = FWD).
201 * to TRANSPORT for this peer (to establish a direct link).
202 */ 184 */
203 struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion; 185 int c_fwd;
204
205}; 186};
206 187
207 188
@@ -261,98 +242,6 @@ static int in_shutdown;
261 242
262 243
263/******************************************************************************/ 244/******************************************************************************/
264/***************************** DEBUG *********************************/
265/******************************************************************************/
266
267/**
268 * Log all kinds of info about the queueing status of a peer.
269 *
270 * @param p Peer whose queue to show.
271 * @param level Error level to use for logging.
272 */
273static void
274queue_debug (const struct CadetPeer *p, enum GNUNET_ErrorType level)
275{
276 struct GNUNET_TIME_Relative core_wait_time;
277 struct CadetPeerQueue *q;
278 int do_log;
279
280 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
281 "cadet-p2p",
282 __FILE__, __FUNCTION__, __LINE__);
283 if (0 == do_log)
284 return;
285
286 LOG2 (level, "QQQ Message queue towards %s\n", GCP_2s (p));
287 LOG2 (level, "QQQ queue length: %u\n", p->queue_n);
288 LOG2 (level, "QQQ core tmt rdy: %p\n", p->core_transmit);
289 if (NULL != p->core_transmit)
290 {
291 core_wait_time = GNUNET_TIME_absolute_get_duration (p->tmt_time);
292 LOG2 (level, "QQQ core called %s ago\n",
293 GNUNET_STRINGS_relative_time_to_string (core_wait_time, GNUNET_NO));
294 }
295 for (q = p->queue_head; NULL != q; q = q->next)
296 {
297 LOG2 (level, "QQQ - %s %s on %s\n",
298 GC_m2s (q->type), GC_f2s (q->fwd), GCC_2s (q->c));
299 LOG2 (level, "QQQ payload %s, %u\n",
300 GC_m2s (q->payload_type), q->payload_id);
301 LOG2 (level, "QQQ size: %u bytes\n", q->size);
302 }
303
304 LOG2 (level, "QQQ End queue towards %s\n", GCP_2s (p));
305}
306
307
308/**
309 * Log all kinds of info about a peer.
310 *
311 * @param peer Peer.
312 */
313void
314GCP_debug (const struct CadetPeer *p, enum GNUNET_ErrorType level)
315{
316 struct CadetPeerPath *path;
317 unsigned int conns;
318 int do_log;
319
320 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
321 "cadet-p2p",
322 __FILE__, __FUNCTION__, __LINE__);
323 if (0 == do_log)
324 return;
325
326 if (NULL == p)
327 {
328 LOG2 (level, "PPP DEBUG PEER NULL\n");
329 return;
330 }
331
332 LOG2 (level, "PPP DEBUG PEER %s\n", GCP_2s (p));
333 LOG2 (level, "PPP last contact %s\n",
334 GNUNET_STRINGS_absolute_time_to_string (p->last_contact));
335 for (path = p->path_head; NULL != path; path = path->next)
336 {
337 char *s;
338
339 s = path_2s (path);
340 LOG2 (level, "PPP path: %s\n", s);
341 GNUNET_free (s);
342 }
343
344 LOG2 (level, "PPP core transmit handle %p\n", p->core_transmit);
345 LOG2 (level, "PPP DHT GET handle %p\n", p->search_h);
346 conns = 0;
347 if (NULL != p->connections)
348 conns += GNUNET_CONTAINER_multihashmap_size (p->connections);
349 LOG2 (level, "PPP # connections over link to peer: %u\n", conns);
350 queue_debug (p, level);
351 LOG2 (level, "PPP DEBUG END\n");
352}
353
354
355/******************************************************************************/
356/***************************** CORE HELPERS *********************************/ 245/***************************** CORE HELPERS *********************************/
357/******************************************************************************/ 246/******************************************************************************/
358 247
@@ -415,12 +304,16 @@ pop_direct_path (struct CadetPeer *peer)
415/** 304/**
416 * Method called whenever a given peer connects. 305 * Method called whenever a given peer connects.
417 * 306 *
418 * @param cls closure 307 * @param cls Core closure (unused).
419 * @param peer peer identity this notification is about 308 * @param peer Peer identity this notification is about
309 * @param mq Message Queue to this peer.
310 *
311 * @return Internal closure for handlers (CadetPeer struct).
420 */ 312 */
421static void 313static void *
422core_connect (void *cls, 314core_connect_handler (void *cls,
423 const struct GNUNET_PeerIdentity *peer) 315 const struct GNUNET_PeerIdentity *peer,
316 struct GNUNET_MQ_Handle *mq)
424{ 317{
425 struct CadetPeer *neighbor; 318 struct CadetPeer *neighbor;
426 struct CadetPeerPath *path; 319 struct CadetPeerPath *path;
@@ -431,6 +324,8 @@ core_connect (void *cls,
431 sizeof (own_id), 324 sizeof (own_id),
432 "%s", 325 "%s",
433 GNUNET_i2s (&my_full_id)); 326 GNUNET_i2s (&my_full_id));
327
328 /* Save a path to the neighbor */
434 neighbor = GCP_get (peer, GNUNET_YES); 329 neighbor = GCP_get (peer, GNUNET_YES);
435 if (myid == neighbor->id) 330 if (myid == neighbor->id)
436 { 331 {
@@ -448,11 +343,14 @@ core_connect (void *cls,
448 path = path_new (2); 343 path = path_new (2);
449 path->peers[1] = neighbor->id; 344 path->peers[1] = neighbor->id;
450 GNUNET_PEER_change_rc (neighbor->id, 1); 345 GNUNET_PEER_change_rc (neighbor->id, 1);
346 GNUNET_assert (NULL == neighbor->core_mq);
347 neighbor->core_mq = mq;
451 } 348 }
452 path->peers[0] = myid; 349 path->peers[0] = myid;
453 GNUNET_PEER_change_rc (myid, 1); 350 GNUNET_PEER_change_rc (myid, 1);
454 GCP_add_path (neighbor, path, GNUNET_YES); 351 GCP_add_path (neighbor, path, GNUNET_YES);
455 352
353 /* Create the connections hashmap */
456 GNUNET_assert (NULL == neighbor->connections); 354 GNUNET_assert (NULL == neighbor->connections);
457 neighbor->connections = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO); 355 neighbor->connections = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
458 GNUNET_STATISTICS_update (stats, 356 GNUNET_STATISTICS_update (stats,
@@ -462,42 +360,47 @@ core_connect (void *cls,
462 360
463 if ( (NULL != GCP_get_tunnel (neighbor)) && 361 if ( (NULL != GCP_get_tunnel (neighbor)) &&
464 (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, peer)) ) 362 (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, peer)) )
363 {
465 GCP_connect (neighbor); 364 GCP_connect (neighbor);
365 }
466 GCC_check_connections (); 366 GCC_check_connections ();
367
368 return neighbor;
467} 369}
468 370
469 371
470/** 372/**
471 * Method called whenever a peer disconnects. 373 * Method called whenever a peer disconnects.
472 * 374 *
473 * @param cls closure 375 * @param cls Core closure (unused).
474 * @param peer peer identity this notification is about 376 * @param peer Peer identity this notification is about.
377 * @param internal_cls Internal closure (CadetPeer struct).
475 */ 378 */
476static void 379static void
477core_disconnect (void *cls, 380core_disconnect_handler (void *cls,
478 const struct GNUNET_PeerIdentity *peer) 381 const struct GNUNET_PeerIdentity *peer,
382 void *internal_cls)
479{ 383{
480 struct CadetPeer *p; 384 struct CadetPeer *p = internal_cls;
481 struct CadetPeerPath *direct_path; 385 struct CadetPeerPath *direct_path;
482 char own_id[16]; 386 char own_id[16];
483 387
484 GCC_check_connections (); 388 GCC_check_connections ();
485 strncpy (own_id, GNUNET_i2s (&my_full_id), 16); 389 strncpy (own_id, GNUNET_i2s (&my_full_id), 16);
486 own_id[15] = '\0'; 390 own_id[15] = '\0';
487 p = GNUNET_CONTAINER_multipeermap_get (peers, peer);
488 if (NULL == p)
489 {
490 GNUNET_break (GNUNET_YES == in_shutdown);
491 return;
492 }
493 if (myid == p->id) 391 if (myid == p->id)
392 {
494 LOG (GNUNET_ERROR_TYPE_INFO, 393 LOG (GNUNET_ERROR_TYPE_INFO,
495 "DISCONNECTED %s (self)\n", 394 "DISCONNECTED %s (self)\n",
496 own_id); 395 own_id);
396 }
497 else 397 else
398 {
498 LOG (GNUNET_ERROR_TYPE_INFO, 399 LOG (GNUNET_ERROR_TYPE_INFO,
499 "DISCONNECTED %s <= %s\n", 400 "DISCONNECTED %s <= %s\n",
500 own_id, GNUNET_i2s (peer)); 401 own_id, GNUNET_i2s (peer));
402 p->core_mq = NULL;
403 }
501 direct_path = pop_direct_path (p); 404 direct_path = pop_direct_path (p);
502 if (NULL != p->connections) 405 if (NULL != p->connections)
503 { 406 {
@@ -507,12 +410,6 @@ core_disconnect (void *cls,
507 GNUNET_CONTAINER_multihashmap_destroy (p->connections); 410 GNUNET_CONTAINER_multihashmap_destroy (p->connections);
508 p->connections = NULL; 411 p->connections = NULL;
509 } 412 }
510 if (NULL != p->core_transmit)
511 {
512 GNUNET_CORE_notify_transmit_ready_cancel (p->core_transmit);
513 p->core_transmit = NULL;
514 p->tmt_time.abs_value_us = 0;
515 }
516 GNUNET_STATISTICS_update (stats, 413 GNUNET_STATISTICS_update (stats,
517 "# peers", 414 "# peers",
518 -1, 415 -1,
@@ -522,167 +419,283 @@ core_disconnect (void *cls,
522} 419}
523 420
524 421
422/******************************************************************************/
423/******************************************************************************/
424/******************************************************************************/
425/******************************************************************************/
426/******************************************************************************/
427
525/** 428/**
526 * Functions to handle messages from core 429 * Check if the create_connection message has the appropriate size.
527 */ 430 *
528static struct GNUNET_CORE_MessageHandler core_handlers[] = { 431 * @param cls Closure (unused).
529 {&GCC_handle_create, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, 0}, 432 * @param msg Message to check.
530 {&GCC_handle_confirm, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK, 433 *
531 sizeof (struct GNUNET_CADET_ConnectionACK)}, 434 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
532 {&GCC_handle_broken, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN, 435 */
533 sizeof (struct GNUNET_CADET_ConnectionBroken)}, 436static int
534 {&GCC_handle_destroy, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY, 437check_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg)
535 sizeof (struct GNUNET_CADET_ConnectionDestroy)}, 438{
536 {&GCC_handle_ack, GNUNET_MESSAGE_TYPE_CADET_ACK, 439 uint16_t size;
537 sizeof (struct GNUNET_CADET_ACK)},
538 {&GCC_handle_poll, GNUNET_MESSAGE_TYPE_CADET_POLL,
539 sizeof (struct GNUNET_CADET_Poll)},
540 {&GCC_handle_kx, GNUNET_MESSAGE_TYPE_CADET_KX, 0},
541 {&GCC_handle_encrypted, GNUNET_MESSAGE_TYPE_CADET_AX, 0},
542 {NULL, 0, 0}
543};
544 440
441 size = ntohs (msg->header.size);
442 if (size < sizeof (*msg))
443 {
444 GNUNET_break_op (0);
445 return GNUNET_NO;
446 }
447 return GNUNET_YES;
448}
545 449
546/** 450/**
547 * To be called on core init/fail. 451 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
548 * 452 *
549 * @param cls Closure (config) 453 * @param cls Closure (CadetPeer for neighbor that sent the message).
550 * @param identity the public identity of this peer 454 * @param msg Message itself.
551 */ 455 */
552static void 456static void
553core_init (void *cls, 457handle_create (void *cls, const struct GNUNET_CADET_ConnectionCreate *msg)
554 const struct GNUNET_PeerIdentity *identity)
555{ 458{
556 const struct GNUNET_CONFIGURATION_Handle *c = cls; 459 struct CadetPeer *peer = cls;
557 static int i = 0; 460 GCC_handle_create (peer, msg);
461}
558 462
559 LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n"); 463
560 if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id))) 464/**
561 { 465 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK
562 LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n")); 466 *
563 LOG (GNUNET_ERROR_TYPE_ERROR, " core id %s\n", GNUNET_i2s (identity)); 467 * @param cls Closure (CadetPeer for neighbor that sent the message).
564 LOG (GNUNET_ERROR_TYPE_ERROR, " my id %s\n", GNUNET_i2s (&my_full_id)); 468 * @param msg Message itself.
565 GNUNET_CORE_disconnect (core_handle); 469 */
566 core_handle = GNUNET_CORE_connect (c, /* Main configuration */ 470static void
567 NULL, /* Closure passed to CADET functions */ 471handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionACK *msg)
568 &core_init, /* Call core_init once connected */ 472{
569 &core_connect, /* Handle connects */ 473 struct CadetPeer *peer = cls;
570 &core_disconnect, /* remove peers on disconnects */ 474 GCC_handle_confirm (peer, msg);
571 NULL, /* Don't notify about all incoming messages */
572 GNUNET_NO, /* For header only in notification */
573 NULL, /* Don't notify about all outbound messages */
574 GNUNET_NO, /* For header-only out notification */
575 core_handlers); /* Register these handlers */
576 if (10 < i++)
577 GNUNET_assert (0);
578 }
579 GML_start ();
580} 475}
581 476
582 477
583/** 478/**
584 * Core callback to write a pre-constructed data packet to core buffer 479 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
585 * 480 *
586 * @param cls Closure (CadetTransmissionDescriptor with data in "data" member). 481 * @param cls Closure (CadetPeer for neighbor that sent the message).
587 * @param size Number of bytes available in buf. 482 * @param msg Message itself.
588 * @param buf Where the to write the message. 483 */
589 * 484static void
590 * @return number of bytes written to buf 485handle_broken (void *cls, const struct GNUNET_CADET_ConnectionBroken *msg)
591 */
592static size_t
593send_core_data_raw (void *cls, size_t size, void *buf)
594{ 486{
595 struct GNUNET_MessageHeader *msg = cls; 487 struct CadetPeer *peer = cls;
596 size_t total_size; 488 GCC_handle_broken (peer, msg);
489}
597 490
598 GNUNET_assert (NULL != msg);
599 total_size = ntohs (msg->size);
600 491
601 if (total_size > size) 492/**
602 { 493 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
603 GNUNET_break (0); 494 *
604 return 0; 495 * @param cls Closure (CadetPeer for neighbor that sent the message).
605 } 496 * @param msg Message itself.
606 GNUNET_memcpy (buf, msg, total_size); 497 */
607 GNUNET_free (cls); 498static void
608 return total_size; 499handle_destroy (void *cls, const struct GNUNET_CADET_ConnectionDestroy *msg)
500{
501 struct CadetPeer *peer = cls;
502 GCC_handle_destroy (peer, msg);
609} 503}
610 504
611 505
612/** 506/**
613 * Function to send a create connection message to a peer. 507 * Handle for #GNUNET_MESSAGE_TYPE_CADET_ACK
614 * 508 *
615 * @param c Connection to create. 509 * @param cls Closure (CadetPeer for neighbor that sent the message).
616 * @param size number of bytes available in buf 510 * @param msg Message itself.
617 * @param buf where the callee should write the message
618 * @return number of bytes written to buf
619 */ 511 */
620static size_t 512static void
621send_core_connection_create (struct CadetConnection *c, size_t size, void *buf) 513handle_ack (void *cls, const struct GNUNET_CADET_ACK *msg)
622{ 514{
623 struct GNUNET_CADET_ConnectionCreate *msg; 515 struct CadetPeer *peer = cls;
624 struct GNUNET_PeerIdentity *peer_ptr; 516 GCC_handle_ack (peer, msg);
625 const struct CadetPeerPath *p = GCC_get_path (c); 517}
626 size_t size_needed;
627 int i;
628 518
629 if (NULL == p)
630 return 0;
631 519
632 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION CREATE...\n"); 520/**
633 size_needed = 521 * Handle for #GNUNET_MESSAGE_TYPE_CADET_POLL
634 sizeof (struct GNUNET_CADET_ConnectionCreate) + 522 *
635 p->length * sizeof (struct GNUNET_PeerIdentity); 523 * @param cls Closure (CadetPeer for neighbor that sent the message).
524 * @param msg Message itself.
525 */
526static void
527handle_poll (void *cls, const struct GNUNET_CADET_Poll *msg)
528{
529 struct CadetPeer *peer = cls;
530 GCC_handle_poll (peer, msg);
531}
636 532
637 if (size < size_needed || NULL == buf) 533
534/**
535 * Check if the Key eXchange message has the appropriate size.
536 *
537 * @param cls Closure (unused).
538 * @param msg Message to check.
539 *
540 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
541 */
542static int
543check_kx (void *cls, const struct GNUNET_CADET_KX *msg)
544{
545 uint16_t size;
546 uint16_t expected_size;
547
548 size = ntohs (msg->header.size);
549 expected_size = sizeof (struct GNUNET_CADET_KX)
550 + sizeof (struct GNUNET_MessageHeader);
551
552 if (size < expected_size)
638 { 553 {
639 GNUNET_break (0); 554 GNUNET_break_op (0);
640 return 0; 555 return GNUNET_NO;
641 } 556 }
642 msg = (struct GNUNET_CADET_ConnectionCreate *) buf; 557 return GNUNET_YES;
643 msg->header.size = htons (size_needed); 558}
644 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
645 msg->cid = *GCC_get_id (c);
646 559
647 peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1]; 560/**
648 for (i = 0; i < p->length; i++) 561 * Handle for #GNUNET_MESSAGE_TYPE_CADET_KX
562 *
563 * @param cls Closure (CadetPeer for neighbor that sent the message).
564 * @param msg Message itself.
565 */
566static void
567handle_kx (void *cls, const struct GNUNET_CADET_KX *msg)
568{
569 struct CadetPeer *peer = cls;
570 GCC_handle_kx (peer, msg);
571}
572
573
574/**
575 * Check if the encrypted message has the appropriate size.
576 *
577 * @param cls Closure (unused).
578 * @param msg Message to check.
579 *
580 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
581 */
582static int
583check_encrypted (void *cls, const struct GNUNET_CADET_AX *msg)
584{
585 uint16_t size;
586 uint16_t minimum_size;
587
588 size = ntohs (msg->header.size);
589 minimum_size = sizeof (struct GNUNET_CADET_AX)
590 + sizeof (struct GNUNET_MessageHeader);
591
592 if (size < minimum_size)
649 { 593 {
650 GNUNET_PEER_resolve (p->peers[i], peer_ptr++); 594 GNUNET_break_op (0);
595 return GNUNET_NO;
651 } 596 }
597 return GNUNET_YES;
598}
652 599
653 LOG (GNUNET_ERROR_TYPE_DEBUG, 600/**
654 "CONNECTION CREATE (%u bytes long) sent!\n", 601 * Handle for #GNUNET_MESSAGE_TYPE_CADET_AX (AXolotl encrypted traffic).
655 size_needed); 602 *
656 return size_needed; 603 * @param cls Closure (CadetPeer for neighbor that sent the message).
604 * @param msg Message itself.
605 */
606static void
607handle_encrypted (void *cls, const struct GNUNET_CADET_AX *msg)
608{
609 struct CadetPeer *peer = cls;
610 GCC_handle_encrypted (peer, msg);
657} 611}
658 612
659 613
660/** 614/**
661 * Creates a path ack message in buf and frees all unused resources. 615 * To be called on core init/fail.
662 * 616 *
663 * @param c Connection to send an ACK on. 617 * @param cls Closure (config)
664 * @param size number of bytes available in buf 618 * @param identity The public identity of this peer.
665 * @param buf where the callee should write the message 619 */
620static void
621core_init_notify (void *cls,
622 const struct GNUNET_PeerIdentity *identity);
623
624
625static void
626connect_to_core (const struct GNUNET_CONFIGURATION_Handle *c)
627{
628 struct GNUNET_MQ_MessageHandler core_handlers[] = {
629 GNUNET_MQ_hd_var_size (create,
630 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
631 struct GNUNET_CADET_ConnectionCreate,
632 NULL),
633 GNUNET_MQ_hd_fixed_size (confirm,
634 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK,
635 struct GNUNET_CADET_ConnectionACK,
636 NULL),
637 GNUNET_MQ_hd_fixed_size (broken,
638 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
639 struct GNUNET_CADET_ConnectionBroken,
640 NULL),
641 GNUNET_MQ_hd_fixed_size (destroy,
642 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
643 struct GNUNET_CADET_ConnectionDestroy,
644 NULL),
645 GNUNET_MQ_hd_fixed_size (ack,
646 GNUNET_MESSAGE_TYPE_CADET_ACK,
647 struct GNUNET_CADET_ACK,
648 NULL),
649 GNUNET_MQ_hd_fixed_size (poll,
650 GNUNET_MESSAGE_TYPE_CADET_POLL,
651 struct GNUNET_CADET_Poll,
652 NULL),
653 GNUNET_MQ_hd_var_size (kx,
654 GNUNET_MESSAGE_TYPE_CADET_KX,
655 struct GNUNET_CADET_KX,
656 NULL),
657 GNUNET_MQ_hd_var_size (encrypted,
658 GNUNET_MESSAGE_TYPE_CADET_AX,
659 struct GNUNET_CADET_AX,
660 NULL),
661 GNUNET_MQ_handler_end ()
662 };
663 core_handle = GNUNET_CORE_connecT (c, NULL,
664 &core_init_notify,
665 &core_connect_handler,
666 &core_disconnect_handler,
667 core_handlers);
668}
669
670/******************************************************************************/
671/******************************************************************************/
672/******************************************************************************/
673/******************************************************************************/
674/******************************************************************************/
675
676/**
677 * To be called on core init/fail.
666 * 678 *
667 * @return number of bytes written to buf 679 * @param cls Closure (config)
680 * @param identity The public identity of this peer.
668 */ 681 */
669static size_t 682static void
670send_core_connection_ack (struct CadetConnection *c, size_t size, void *buf) 683core_init_notify (void *cls,
684 const struct GNUNET_PeerIdentity *core_identity)
671{ 685{
672 struct GNUNET_CADET_ConnectionACK *msg = buf; 686 const struct GNUNET_CONFIGURATION_Handle *c = cls;
673 687
674 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending CONNECTION ACK...\n"); 688 LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
675 if (sizeof (struct GNUNET_CADET_ConnectionACK) > size) 689 if (0 != memcmp (core_identity, &my_full_id, sizeof (my_full_id)))
676 { 690 {
677 GNUNET_break (0); 691 LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
678 return 0; 692 LOG (GNUNET_ERROR_TYPE_ERROR, " core id %s\n", GNUNET_i2s (core_identity));
693 LOG (GNUNET_ERROR_TYPE_ERROR, " my id %s\n", GNUNET_i2s (&my_full_id));
694 GNUNET_CORE_disconnecT (core_handle);
695 connect_to_core (c);
696 return;
679 } 697 }
680 msg->header.size = htons (sizeof (struct GNUNET_CADET_ConnectionACK)); 698 GML_start ();
681 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK);
682 msg->cid = *GCC_get_id (c);
683
684 LOG (GNUNET_ERROR_TYPE_DEBUG, "CONNECTION ACK sent!\n");
685 return sizeof (struct GNUNET_CADET_ConnectionACK);
686} 699}
687 700
688 701
@@ -697,8 +710,11 @@ send_core_connection_ack (struct CadetConnection *c, size_t size, void *buf)
697 * @param q Queued message 710 * @param q Queued message
698 * 711 *
699 * @return CORE priority to use. 712 * @return CORE priority to use.
713 *
714 * FIXME make static
715 * FIXME use when sending
700 */ 716 */
701static enum GNUNET_CORE_Priority 717enum GNUNET_CORE_Priority
702get_priority (struct CadetPeerQueue *q) 718get_priority (struct CadetPeerQueue *q)
703{ 719{
704 enum GNUNET_CORE_Priority low; 720 enum GNUNET_CORE_Priority low;
@@ -711,7 +727,7 @@ get_priority (struct CadetPeerQueue *q)
711 } 727 }
712 728
713 /* Relayed traffic has lower priority, our own traffic has higher */ 729 /* Relayed traffic has lower priority, our own traffic has higher */
714 if (NULL == q->c || GNUNET_NO == GCC_is_origin (q->c, q->fwd)) 730 if (NULL == q->c || GNUNET_NO == GCC_is_origin (q->c, q->c_fwd))
715 { 731 {
716 low = GNUNET_CORE_PRIO_BEST_EFFORT; 732 low = GNUNET_CORE_PRIO_BEST_EFFORT;
717 high = GNUNET_CORE_PRIO_URGENT; 733 high = GNUNET_CORE_PRIO_URGENT;
@@ -784,20 +800,6 @@ peer_destroy (struct CadetPeer *peer)
784 GNUNET_ATS_connectivity_suggest_cancel (peer->connectivity_suggestion); 800 GNUNET_ATS_connectivity_suggest_cancel (peer->connectivity_suggestion);
785 peer->connectivity_suggestion = NULL; 801 peer->connectivity_suggestion = NULL;
786 } 802 }
787 while (NULL != peer->queue_head)
788 {
789 /* This function destroys the current peer->queue_head but
790 * replaces it with the next in the queue, so it is correct
791 * to while() here.
792 */
793 GCP_queue_destroy (peer->queue_head, GNUNET_YES, GNUNET_NO, 0);
794 }
795 if (NULL != peer->core_transmit)
796 {
797 GNUNET_break (0); /* GCP_queue_destroy should've cancelled it! */
798 GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit);
799 peer->core_transmit = NULL;
800 }
801 803
802 GNUNET_free_non_null (peer->hello); 804 GNUNET_free_non_null (peer->hello);
803 GNUNET_free (peer); 805 GNUNET_free (peer);
@@ -831,7 +833,6 @@ shutdown_peer (void *cls,
831} 833}
832 834
833 835
834
835/** 836/**
836 * Check if peer is searching for a path (either active or delayed search). 837 * Check if peer is searching for a path (either active or delayed search).
837 * 838 *
@@ -996,64 +997,6 @@ peer_get_best_path (const struct CadetPeer *peer)
996 997
997 998
998/** 999/**
999 * Is this queue element sendable?
1000 *
1001 * - All management traffic is always sendable.
1002 * - For payload traffic, check the connection flow control.
1003 *
1004 * @param q Queue element to inspect.
1005 * @return #GNUNET_YES if it is sendable, #GNUNET_NO otherwise.
1006 */
1007static int
1008queue_is_sendable (struct CadetPeerQueue *q)
1009{
1010 /* Is PID-independent? */
1011 switch (q->type)
1012 {
1013 case GNUNET_MESSAGE_TYPE_CADET_ACK:
1014 case GNUNET_MESSAGE_TYPE_CADET_POLL:
1015 case GNUNET_MESSAGE_TYPE_CADET_KX:
1016 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
1017 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK:
1018 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
1019 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
1020 return GNUNET_YES;
1021
1022 case GNUNET_MESSAGE_TYPE_CADET_AX:
1023 break;
1024
1025 default:
1026 GNUNET_break (0);
1027 }
1028
1029 return GCC_is_sendable (q->c, q->fwd);
1030}
1031
1032
1033/**
1034 * Get first sendable message.
1035 *
1036 * @param peer The destination peer.
1037 *
1038 * @return First transmittable message, if any. Otherwise, NULL.
1039 */
1040static struct CadetPeerQueue *
1041peer_get_first_message (const struct CadetPeer *peer)
1042{
1043 struct CadetPeerQueue *q;
1044
1045 for (q = peer->queue_head; NULL != q; q = q->next)
1046 {
1047 LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking q:%p on c:%s\n", q, GCC_2s (q->c));
1048 if (queue_is_sendable (q))
1049 return q;
1050 }
1051
1052 return NULL;
1053}
1054
1055
1056/**
1057 * Function to process paths received for a new peer addition. The recorded 1000 * Function to process paths received for a new peer addition. The recorded
1058 * paths form the initial tunnel, which can be optimized later. 1001 * paths form the initial tunnel, which can be optimized later.
1059 * Called on each result obtained for the DHT search. 1002 * Called on each result obtained for the DHT search.
@@ -1090,19 +1033,6 @@ search_handler (void *cls, const struct CadetPeerPath *path)
1090 1033
1091 1034
1092/** 1035/**
1093 * Adjust core requested size to accomodate an ACK.
1094 *
1095 * @param message_size Requested size.
1096 *
1097 * @return Size enough to fit @c message_size and an ACK.
1098 */
1099static size_t
1100get_core_size (size_t message_size)
1101{
1102 return message_size + sizeof (struct GNUNET_CADET_ACK);
1103}
1104
1105/**
1106 * Test if a message type is connection management traffic 1036 * Test if a message type is connection management traffic
1107 * or regular payload traffic. 1037 * or regular payload traffic.
1108 * 1038 *
@@ -1119,85 +1049,13 @@ is_connection_management (uint16_t type)
1119 1049
1120 1050
1121/** 1051/**
1122 * Fill a core buffer with the appropriate data for the queued message.
1123 *
1124 * @param queue Queue element for the message.
1125 * @param buf Core buffer to fill.
1126 * @param size Size remaining in @c buf.
1127 * @param[out] pid In case its an encrypted payload, set payload.
1128 *
1129 * @return Bytes written to @c buf.
1130 */
1131static size_t
1132fill_buf (struct CadetPeerQueue *queue, void *buf, size_t size, uint32_t *pid)
1133{
1134 struct CadetConnection *c = queue->c;
1135 size_t msg_size;
1136
1137 switch (queue->type)
1138 {
1139 case GNUNET_MESSAGE_TYPE_CADET_AX:
1140 *pid = GCC_get_pid (queue->c, queue->fwd);
1141 LOG (GNUNET_ERROR_TYPE_DEBUG, " ax payload ID %u\n", *pid);
1142 msg_size = send_core_data_raw (queue->cls, size, buf);
1143 ((struct GNUNET_CADET_AX *) buf)->pid = htonl (*pid);
1144 break;
1145 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
1146 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
1147 case GNUNET_MESSAGE_TYPE_CADET_KX:
1148 case GNUNET_MESSAGE_TYPE_CADET_ACK:
1149 case GNUNET_MESSAGE_TYPE_CADET_POLL:
1150 LOG (GNUNET_ERROR_TYPE_DEBUG, " raw %s\n", GC_m2s (queue->type));
1151 msg_size = send_core_data_raw (queue->cls, size, buf);
1152 break;
1153 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
1154 LOG (GNUNET_ERROR_TYPE_DEBUG, " path create\n");
1155 if (GCC_is_origin (c, GNUNET_YES))
1156 msg_size = send_core_connection_create (c, size, buf);
1157 else
1158 msg_size = send_core_data_raw (queue->cls, size, buf);
1159 break;
1160 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK:
1161 LOG (GNUNET_ERROR_TYPE_DEBUG, " path ack\n");
1162 if (GCC_is_origin (c, GNUNET_NO) ||
1163 GCC_is_origin (c, GNUNET_YES))
1164 {
1165 msg_size = send_core_connection_ack (c, size, buf);
1166 }
1167 else
1168 {
1169 msg_size = send_core_data_raw (queue->cls, size, buf);
1170 }
1171 break;
1172 case GNUNET_MESSAGE_TYPE_CADET_DATA:
1173 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE:
1174 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1175 /* This should be encapsulted */
1176 msg_size = 0;
1177 GNUNET_assert (0);
1178 break;
1179 default:
1180 GNUNET_break (0);
1181 LOG (GNUNET_ERROR_TYPE_WARNING, " type unknown: %u\n", queue->type);
1182 msg_size = 0;
1183 }
1184
1185 GNUNET_assert (size >= msg_size);
1186
1187 return msg_size;
1188}
1189
1190
1191/**
1192 * Debug function should NEVER return true in production code, useful to 1052 * Debug function should NEVER return true in production code, useful to
1193 * simulate losses for testcases. 1053 * simulate losses for testcases.
1194 * 1054 *
1195 * @param q Queue handle with info about the message.
1196 *
1197 * @return #GNUNET_YES or #GNUNET_NO with the decision to drop. 1055 * @return #GNUNET_YES or #GNUNET_NO with the decision to drop.
1198 */ 1056 */
1199static int 1057static int
1200should_I_drop (struct CadetPeerQueue *q) 1058should_I_drop (void)
1201{ 1059{
1202 if (0 == drop_percent) 1060 if (0 == drop_percent)
1203 return GNUNET_NO; 1061 return GNUNET_NO;
@@ -1209,297 +1067,87 @@ should_I_drop (struct CadetPeerQueue *q)
1209} 1067}
1210 1068
1211 1069
1212/**
1213 * Core callback to write a queued packet to core buffer
1214 *
1215 * @param cls Closure (peer info).
1216 * @param size Number of bytes available in buf.
1217 * @param buf Where the to write the message.
1218 *
1219 * @return number of bytes written to buf
1220 */
1221static size_t
1222queue_send (void *cls, size_t size, void *buf)
1223{
1224 struct CadetPeer *peer = cls;
1225 struct CadetConnection *c;
1226 struct CadetPeerQueue *queue;
1227 struct GNUNET_TIME_Relative core_wait_time;
1228 const char *wait_s;
1229 const struct GNUNET_PeerIdentity *dst_id;
1230 size_t msg_size;
1231 size_t total_size;
1232 size_t rest;
1233 char *dst;
1234 uint32_t pid;
1235
1236 GCC_check_connections ();
1237 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
1238 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
1239 LOG (GNUNET_ERROR_TYPE_DEBUG, "Queue send towards %s (max %u)\n",
1240 GCP_2s (peer), size);
1241
1242 /* Sanity checking */
1243 if (NULL == buf || 0 == size)
1244 {
1245 LOG (GNUNET_ERROR_TYPE_DEBUG, " not allowed/\n");
1246 if (GNUNET_NO == in_shutdown)
1247 {
1248 queue = peer_get_first_message (peer);
1249 if (NULL == queue)
1250 {
1251 peer->core_transmit = NULL;
1252 peer->tmt_time.abs_value_us = 0;
1253 GCC_check_connections ();
1254 return 0;
1255 }
1256 dst_id = GNUNET_PEER_resolve2 (peer->id);
1257 peer->core_transmit =
1258 GNUNET_CORE_notify_transmit_ready (core_handle,
1259 GNUNET_NO, get_priority (queue),
1260 GNUNET_TIME_UNIT_FOREVER_REL,
1261 dst_id,
1262 get_core_size (queue->size),
1263 &queue_send,
1264 peer);
1265 peer->tmt_time = GNUNET_TIME_absolute_get ();
1266 }
1267 else
1268 {
1269 peer->core_transmit = NULL;
1270 peer->tmt_time.abs_value_us = 0;
1271 }
1272 GCC_check_connections ();
1273 return 0;
1274 }
1275
1276 /* Init */
1277 rest = size;
1278 total_size = 0;
1279 dst = (char *) buf;
1280 pid = 0;
1281 peer->core_transmit = NULL;
1282 queue = peer_get_first_message (peer);
1283 if (NULL == queue)
1284 {
1285 GNUNET_break (0); /* Core tmt_rdy should've been canceled */
1286 peer->tmt_time.abs_value_us = 0;
1287 return 0;
1288 }
1289 core_wait_time = GNUNET_TIME_absolute_get_duration (peer->tmt_time);
1290 wait_s = GNUNET_STRINGS_relative_time_to_string (core_wait_time, GNUNET_YES);
1291 if (core_wait_time.rel_value_us >= 1000000)
1292 {
1293 LOG (GNUNET_ERROR_TYPE_WARNING,
1294 " %s: core wait time %s (> 1 second) for %u bytes\n",
1295 GCP_2s (peer), wait_s, queue->size);
1296 }
1297 peer->tmt_time.abs_value_us = 0;
1298
1299 /* Copy all possible messages to the core buffer */
1300 while (NULL != queue && rest >= queue->size)
1301 {
1302 c = queue->c;
1303
1304 LOG (GNUNET_ERROR_TYPE_DEBUG, " on conn %s %s\n",
1305 GCC_2s (c), GC_f2s(queue->fwd));
1306 LOG (GNUNET_ERROR_TYPE_DEBUG, " size %u ok (%u/%u)\n",
1307 queue->size, total_size, size);
1308
1309 msg_size = fill_buf (queue, (void *) dst, size, &pid);
1310
1311 if (should_I_drop (queue))
1312 {
1313 LOG (GNUNET_ERROR_TYPE_WARNING, "DD %s (%s %u) on conn %s %s\n",
1314 GC_m2s (queue->type), GC_m2s (queue->payload_type),
1315 queue->payload_id, GCC_2s (c), GC_f2s (queue->fwd));
1316 msg_size = 0;
1317 }
1318 else
1319 {
1320 LOG (GNUNET_ERROR_TYPE_INFO,
1321 ">>> %s (%s %4u) on conn %s (%p) %s [%5u], after %s\n",
1322 GC_m2s (queue->type), GC_m2s (queue->payload_type),
1323 queue->payload_id, GCC_2s (c), c,
1324 GC_f2s (queue->fwd), msg_size, wait_s);
1325 }
1326 total_size += msg_size;
1327 rest -= msg_size;
1328 dst = &dst[msg_size];
1329 msg_size = 0;
1330
1331 /* Free queue, but cls was freed by send_core_* in fill_buf. */
1332 (void) GCP_queue_destroy (queue, GNUNET_NO, GNUNET_YES, pid);
1333
1334 /* Next! */
1335 queue = peer_get_first_message (peer);
1336 }
1337
1338 /* If more data in queue, send next */
1339 if (NULL != queue)
1340 {
1341 LOG (GNUNET_ERROR_TYPE_DEBUG, " more data! (%u)\n", queue->size);
1342 if (NULL == peer->core_transmit)
1343 {
1344 dst_id = GNUNET_PEER_resolve2 (peer->id);
1345 peer->core_transmit =
1346 GNUNET_CORE_notify_transmit_ready (core_handle,
1347 GNUNET_NO, get_priority (queue),
1348 GNUNET_TIME_UNIT_FOREVER_REL,
1349 dst_id,
1350 get_core_size (queue->size),
1351 &queue_send,
1352 peer);
1353 peer->tmt_time = GNUNET_TIME_absolute_get ();
1354 queue->start_waiting = GNUNET_TIME_absolute_get ();
1355 }
1356 else
1357 {
1358 LOG (GNUNET_ERROR_TYPE_DEBUG, "* tmt rdy called somewhere else\n");
1359 }
1360// GCC_start_poll (); FIXME needed?
1361 }
1362 else
1363 {
1364// GCC_stop_poll(); FIXME needed?
1365 }
1366
1367 LOG (GNUNET_ERROR_TYPE_DEBUG, " return %d\n", total_size);
1368 queue_debug (peer, GNUNET_ERROR_TYPE_DEBUG);
1369 GCC_check_connections ();
1370 return total_size;
1371}
1372
1373
1374/******************************************************************************/ 1070/******************************************************************************/
1375/******************************** API ***********************************/ 1071/******************************** API ***********************************/
1376/******************************************************************************/ 1072/******************************************************************************/
1377 1073
1378
1379/** 1074/**
1380 * Free a transmission that was already queued with all resources 1075 * Call the continuation after a message has been sent or dropped.
1381 * associated to the request.
1382 *
1383 * If connection was marked to be destroyed, and this was the last queued
1384 * message on it, the connection will be free'd as a result.
1385 * 1076 *
1386 * @param queue Queue handler to cancel. 1077 * @param q Queue handle.
1387 * @param clear_cls Is it necessary to free associated cls? 1078 * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped.
1388 * @param sent Was it really sent? (Could have been canceled)
1389 * @param pid PID, if relevant (was sent and was a payload message).
1390 *
1391 * @return #GNUNET_YES if connection was destroyed as a result,
1392 * #GNUNET_NO otherwise.
1393 */ 1079 */
1394int 1080static void
1395GCP_queue_destroy (struct CadetPeerQueue *queue, 1081call_peer_cont (const struct CadetPeerQueue *q, int sent)
1396 int clear_cls,
1397 int sent,
1398 uint32_t pid)
1399{ 1082{
1400 struct CadetPeer *peer; 1083 LOG (GNUNET_ERROR_TYPE_DEBUG, " core mq just sent %s\n", GC_m2s (q->type));
1401 int connection_destroyed; 1084 if (NULL != q->cont)
1402
1403 GCC_check_connections ();
1404 peer = queue->peer;
1405 LOG (GNUNET_ERROR_TYPE_DEBUG, "queue destroy %s\n", GC_m2s (queue->type));
1406 if (GNUNET_YES == clear_cls)
1407 {
1408 LOG (GNUNET_ERROR_TYPE_DEBUG, " free cls\n");
1409 switch (queue->type)
1410 {
1411 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
1412 LOG (GNUNET_ERROR_TYPE_INFO, "destroying a DESTROY message\n");
1413 /* fall through */
1414 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK:
1415 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
1416 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
1417 case GNUNET_MESSAGE_TYPE_CADET_KX:
1418 case GNUNET_MESSAGE_TYPE_CADET_AX:
1419 case GNUNET_MESSAGE_TYPE_CADET_ACK:
1420 case GNUNET_MESSAGE_TYPE_CADET_POLL:
1421 GNUNET_free_non_null (queue->cls);
1422 break;
1423
1424 default:
1425 GNUNET_break (0);
1426 LOG (GNUNET_ERROR_TYPE_ERROR, " type %s unknown!\n",
1427 GC_m2s (queue->type));
1428 }
1429 }
1430 GNUNET_CONTAINER_DLL_remove (peer->queue_head, peer->queue_tail, queue);
1431
1432 if (!is_connection_management (queue->type))
1433 {
1434 peer->queue_n--;
1435 }
1436
1437 if (NULL != queue->cont)
1438 { 1085 {
1439 struct GNUNET_TIME_Relative wait_time; 1086 struct GNUNET_TIME_Relative wait_time;
1440 1087
1441 wait_time = GNUNET_TIME_absolute_get_duration (queue->start_waiting); 1088 wait_time = GNUNET_TIME_absolute_get_duration (q->queue_timestamp);
1442 LOG (GNUNET_ERROR_TYPE_DEBUG, " calling callback, time elapsed %s\n", 1089 LOG (GNUNET_ERROR_TYPE_DEBUG, " calling callback, time elapsed %s\n",
1443 GNUNET_STRINGS_relative_time_to_string (wait_time, GNUNET_NO)); 1090 GNUNET_STRINGS_relative_time_to_string (wait_time, GNUNET_NO));
1444 connection_destroyed = queue->cont (queue->cont_cls, 1091 q->cont (q->cont_cls,
1445 queue->c, sent, queue->type, pid, 1092 q->c, q->c_fwd, sent,
1446 queue->fwd, queue->size, wait_time); 1093 q->type, q->payload_type, q->payload_id,
1447 } 1094 q->size, wait_time);
1448 else
1449 {
1450 connection_destroyed = GNUNET_NO;
1451 } 1095 }
1096}
1452 1097
1453 if (NULL == peer_get_first_message (peer) && NULL != peer->core_transmit) 1098
1099/**
1100 * Function called by MQ when a message is sent to CORE.
1101 *
1102 * @param cls Closure (queue handle).
1103 */
1104static void
1105mq_sent (void *cls)
1106{
1107 struct CadetPeerQueue *q = cls;
1108
1109 if (GNUNET_NO == q->management_traffic)
1454 { 1110 {
1455 GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit); 1111 q->peer->queue_n--;
1456 peer->core_transmit = NULL;
1457 peer->tmt_time.abs_value_us = 0;
1458 } 1112 }
1459 1113 call_peer_cont (q, GNUNET_YES);
1460 GNUNET_free (queue); 1114 GNUNET_free (q);
1461 GCC_check_connections ();
1462 return connection_destroyed;
1463} 1115}
1464 1116
1465 1117
1466/** 1118/**
1467 * @brief Queue and pass message to core when possible. 1119 * @brief Send a message to another peer (using CORE).
1468 * 1120 *
1469 * @param peer Peer towards which to queue the message. 1121 * @param peer Peer towards which to queue the message.
1470 * @param cls Closure (@c type dependant). It will be used by queue_send to 1122 * @param message Message to send.
1471 * build the message to be sent if not already prebuilt. 1123 * @param payload_type Type of the message's payload, for debug messages.
1472 * @param type Type of the message.
1473 * @param payload_type Type of the message's payload
1474 * 0 if the message is a retransmission (unknown payload). 1124 * 0 if the message is a retransmission (unknown payload).
1475 * UINT16_MAX if the message does not have payload. 1125 * UINT16_MAX if the message does not have payload.
1476 * @param payload_id ID of the payload (MID, ACK #, etc) 1126 * @param payload_id ID of the payload (MID, ACK #, etc)
1477 * @param size Size of the message.
1478 * @param c Connection this message belongs to (can be NULL). 1127 * @param c Connection this message belongs to (can be NULL).
1479 * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!) 1128 * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!)
1480 * @param cont Continuation to be called once CORE has taken the message. 1129 * @param cont Continuation to be called once CORE has sent the message.
1481 * @param cont_cls Closure for @c cont. 1130 * @param cont_cls Closure for @c cont.
1482 * 1131 *
1483 * @return Handle to cancel the message before it is sent. Once cont is called 1132 * @return A handle to the message in the queue or NULL (if dropped).
1484 * message has been sent and therefore the handle is no longer valid.
1485 */ 1133 */
1486struct CadetPeerQueue * 1134struct CadetPeerQueue *
1487GCP_queue_add (struct CadetPeer *peer, 1135GCP_send (struct CadetPeer *peer,
1488 void *cls, 1136 const struct GNUNET_MessageHeader *message,
1489 uint16_t type, 1137 uint16_t payload_type,
1490 uint16_t payload_type, 1138 uint32_t payload_id,
1491 uint32_t payload_id, 1139 struct CadetConnection *c,
1492 size_t size, 1140 int fwd,
1493 struct CadetConnection *c, 1141 GCP_sent cont,
1494 int fwd, 1142 void *cont_cls)
1495 GCP_sent cont,
1496 void *cont_cls)
1497{ 1143{
1498 struct CadetPeerQueue *q; 1144 struct CadetPeerQueue *q;
1499 int priority; 1145 uint16_t type;
1500 int call_core; 1146 uint16_t size;
1501 1147
1502 GCC_check_connections (); 1148 GCC_check_connections ();
1149 type = ntohs (message->type);
1150 size = ntohs (message->size);
1503 LOG (GNUNET_ERROR_TYPE_DEBUG, 1151 LOG (GNUNET_ERROR_TYPE_DEBUG,
1504 "que %s (%s %4u) on conn %s (%p) %s towards %s (size %u)\n", 1152 "que %s (%s %4u) on conn %s (%p) %s towards %s (size %u)\n",
1505 GC_m2s (type), GC_m2s (payload_type), payload_id, 1153 GC_m2s (type), GC_m2s (payload_type), payload_id,
@@ -1508,282 +1156,68 @@ GCP_queue_add (struct CadetPeer *peer,
1508 if (NULL == peer->connections) 1156 if (NULL == peer->connections)
1509 { 1157 {
1510 /* We are not connected to this peer, ignore request. */ 1158 /* We are not connected to this peer, ignore request. */
1159 GNUNET_break (0);
1511 LOG (GNUNET_ERROR_TYPE_INFO, "%s not a neighbor\n", GCP_2s (peer)); 1160 LOG (GNUNET_ERROR_TYPE_INFO, "%s not a neighbor\n", GCP_2s (peer));
1512 GNUNET_STATISTICS_update (stats, "# messages dropped due to wrong hop", 1, 1161 GNUNET_STATISTICS_update (stats, "# messages dropped due to wrong hop", 1,
1513 GNUNET_NO); 1162 GNUNET_NO);
1514 return NULL; 1163 return NULL;
1515 } 1164 }
1516 1165
1517 priority = 0;
1518 if (is_connection_management (type))
1519 {
1520 priority = 100;
1521 }
1522 LOG (GNUNET_ERROR_TYPE_DEBUG, "priority %d\n", priority);
1523
1524 call_core = (NULL == c || GNUNET_MESSAGE_TYPE_CADET_KX == type) ?
1525 GNUNET_YES : GCC_is_sendable (c, fwd);
1526 q = GNUNET_new (struct CadetPeerQueue); 1166 q = GNUNET_new (struct CadetPeerQueue);
1527 q->cls = cls; 1167 q->env = GNUNET_MQ_msg_copy (message);
1168 q->peer = peer;
1169 q->cont = cont;
1170 q->cont_cls = cont_cls;
1171 q->queue_timestamp = GNUNET_TIME_absolute_get ();
1172 q->management_traffic = is_connection_management (type);
1528 q->type = type; 1173 q->type = type;
1174 q->size = size;
1529 q->payload_type = payload_type; 1175 q->payload_type = payload_type;
1530 q->payload_id = payload_id; 1176 q->payload_id = payload_id;
1531 q->size = size;
1532 q->peer = peer;
1533 q->c = c; 1177 q->c = c;
1534 q->fwd = fwd; 1178 q->c_fwd = fwd;
1535 q->cont = cont; 1179 GNUNET_MQ_notify_sent (q->env, mq_sent, q);
1536 q->cont_cls = cont_cls;
1537 if (100 > priority)
1538 {
1539 GNUNET_CONTAINER_DLL_insert_tail (peer->queue_head, peer->queue_tail, q);
1540 peer->queue_n++;
1541 }
1542 else
1543 {
1544 GNUNET_CONTAINER_DLL_insert (peer->queue_head, peer->queue_tail, q);
1545 call_core = GNUNET_YES;
1546 }
1547 1180
1548 q->start_waiting = GNUNET_TIME_absolute_get (); 1181 if (GNUNET_YES == q->management_traffic)
1549 if (NULL == peer->core_transmit && GNUNET_YES == call_core)
1550 { 1182 {
1551 LOG (GNUNET_ERROR_TYPE_DEBUG, 1183 GNUNET_MQ_send (peer->core_mq, q->env); // FIXME implement "_urgent", use
1552 "calling core tmt rdy towards %s for %u bytes\n",
1553 GCP_2s (peer), size);
1554 peer->core_transmit =
1555 GNUNET_CORE_notify_transmit_ready (core_handle,
1556 GNUNET_NO, get_priority (q),
1557 GNUNET_TIME_UNIT_FOREVER_REL,
1558 GNUNET_PEER_resolve2 (peer->id),
1559 get_core_size (size),
1560 &queue_send, peer);
1561 peer->tmt_time = GNUNET_TIME_absolute_get ();
1562 }
1563 else if (GNUNET_NO == call_core)
1564 {
1565 LOG (GNUNET_ERROR_TYPE_DEBUG, "core tmt rdy towards %s not needed\n",
1566 GCP_2s (peer));
1567
1568 } 1184 }
1569 else 1185 else
1570 { 1186 {
1571 struct GNUNET_TIME_Relative elapsed; 1187 if (GNUNET_YES == should_I_drop())
1572 elapsed = GNUNET_TIME_absolute_get_duration (peer->tmt_time);
1573 LOG (GNUNET_ERROR_TYPE_DEBUG, "core tmt rdy towards %s already called %s\n",
1574 GCP_2s (peer),
1575 GNUNET_STRINGS_relative_time_to_string (elapsed, GNUNET_NO));
1576
1577 }
1578 queue_debug (peer, GNUNET_ERROR_TYPE_DEBUG);
1579 GCC_check_connections ();
1580 return q;
1581}
1582
1583
1584/**
1585 * Cancel all queued messages to a peer that belong to a certain connection.
1586 *
1587 * @param peer Peer towards whom to cancel.
1588 * @param c Connection whose queued messages to cancel. Might be destroyed by
1589 * the sent continuation call.
1590 */
1591void
1592GCP_queue_cancel (struct CadetPeer *peer,
1593 struct CadetConnection *c)
1594{
1595 struct CadetPeerQueue *q;
1596 struct CadetPeerQueue *next;
1597 struct CadetPeerQueue *prev;
1598 int connection_destroyed;
1599
1600 GCC_check_connections ();
1601 connection_destroyed = GNUNET_NO;
1602 for (q = peer->queue_head; NULL != q; q = next)
1603 {
1604 prev = q->prev;
1605 if (q->c == c)
1606 {
1607 LOG (GNUNET_ERROR_TYPE_DEBUG,
1608 "GMP queue cancel %s\n",
1609 GC_m2s (q->type));
1610 GNUNET_assert (GNUNET_NO == connection_destroyed);
1611 if (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY == q->type)
1612 {
1613 q->c = NULL;
1614 }
1615 else
1616 {
1617 connection_destroyed = GCP_queue_destroy (q, GNUNET_YES, GNUNET_NO, 0);
1618 }
1619
1620 /* Get next from prev, q->next might be already freed:
1621 * queue destroy -> callback -> GCC_destroy -> cancel_queues -> here
1622 */
1623 if (NULL == prev)
1624 next = peer->queue_head;
1625 else
1626 next = prev->next;
1627 }
1628 else
1629 {
1630 next = q->next;
1631 }
1632 }
1633
1634 if ( (NULL == peer->queue_head) &&
1635 (NULL != peer->core_transmit) )
1636 {
1637 GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit);
1638 peer->core_transmit = NULL;
1639 peer->tmt_time.abs_value_us = 0;
1640 }
1641 GCC_check_connections ();
1642}
1643
1644
1645/**
1646 * Get the first transmittable message for a connection.
1647 *
1648 * @param peer Neighboring peer.
1649 * @param c Connection.
1650 *
1651 * @return First transmittable message.
1652 */
1653static struct CadetPeerQueue *
1654connection_get_first_message (struct CadetPeer *peer, struct CadetConnection *c)
1655{
1656 struct CadetPeerQueue *q;
1657
1658 for (q = peer->queue_head; NULL != q; q = q->next)
1659 {
1660 if (q->c != c)
1661 continue;
1662 if (queue_is_sendable (q))
1663 { 1188 {
1664 LOG (GNUNET_ERROR_TYPE_DEBUG, " sendable!!\n"); 1189 LOG (GNUNET_ERROR_TYPE_WARNING, "DD %s (%s %u) on conn %s %s\n",
1665 return q; 1190 GC_m2s (q->type), GC_m2s (q->payload_type),
1191 q->payload_id, GCC_2s (c), GC_f2s (q->c_fwd));
1192 GNUNET_MQ_discard (q->env);
1193 call_peer_cont (q, GNUNET_NO);
1194 GNUNET_free (q);
1195 return NULL;
1666 } 1196 }
1667 LOG (GNUNET_ERROR_TYPE_DEBUG, " not sendable\n"); 1197 GNUNET_MQ_send (peer->core_mq, q->env);
1198 peer->queue_n++;
1668 } 1199 }
1669 1200
1670 return NULL;
1671}
1672
1673
1674/**
1675 * Get the first message for a connection and unqueue it.
1676 *
1677 * Only tunnel (or higher) level messages are unqueued. Connection specific
1678 * messages are silently destroyed upon encounter.
1679 *
1680 * @param peer Neighboring peer.
1681 * @param c Connection.
1682 * @param destroyed[in/out] Was the connection destroyed (prev/as a result)?.
1683 * Can NOT be NULL.
1684 *
1685 * @return First message for this connection.
1686 */
1687struct GNUNET_MessageHeader *
1688GCP_connection_pop (struct CadetPeer *peer,
1689 struct CadetConnection *c,
1690 int *destroyed)
1691{
1692 struct CadetPeerQueue *q;
1693 struct CadetPeerQueue *next;
1694 struct GNUNET_MessageHeader *msg;
1695 int dest;
1696
1697 GCC_check_connections ();
1698 GNUNET_assert (NULL != destroyed);
1699 LOG (GNUNET_ERROR_TYPE_DEBUG, "connection_pop on conn %p\n", c);
1700 for (q = peer->queue_head; NULL != q; q = next)
1701 {
1702 next = q->next;
1703 if (q->c != c)
1704 continue;
1705 LOG (GNUNET_ERROR_TYPE_DEBUG, " - queued: %s (%s %u), cont: %p\n",
1706 GC_m2s (q->type), GC_m2s (q->payload_type), q->payload_id,
1707 q->cont);
1708 switch (q->type)
1709 {
1710 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
1711 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK:
1712 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
1713 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
1714 case GNUNET_MESSAGE_TYPE_CADET_ACK:
1715 case GNUNET_MESSAGE_TYPE_CADET_POLL:
1716 dest = GCP_queue_destroy (q, GNUNET_YES, GNUNET_NO, 0);
1717 if (GNUNET_YES == dest)
1718 {
1719 GNUNET_break (GNUNET_NO == *destroyed);
1720 *destroyed = GNUNET_YES;
1721 }
1722 continue;
1723
1724 case GNUNET_MESSAGE_TYPE_CADET_KX:
1725 case GNUNET_MESSAGE_TYPE_CADET_AX:
1726 case GNUNET_MESSAGE_TYPE_CADET_AX_KX:
1727 msg = (struct GNUNET_MessageHeader *) q->cls;
1728 dest = GCP_queue_destroy (q, GNUNET_NO, GNUNET_NO, 0);
1729 if (GNUNET_YES == dest)
1730 {
1731 GNUNET_break (GNUNET_NO == *destroyed);
1732 *destroyed = GNUNET_YES;
1733 }
1734 return msg;
1735
1736 default:
1737 GNUNET_break (0);
1738 LOG (GNUNET_ERROR_TYPE_DEBUG, "Unknown message %s\n", GC_m2s (q->type));
1739 }
1740 }
1741 GCC_check_connections (); 1201 GCC_check_connections ();
1742 return NULL; 1202 return q;
1743} 1203}
1744 1204
1745 1205
1746/** 1206/**
1747 * Unlock a possibly locked queue for a connection. 1207 * Cancel sending a message. Message must have been sent with
1208 * #GCP_send before. May not be called after the notify sent
1209 * callback has been called.
1748 * 1210 *
1749 * If there is a message that can be sent on this connection, call core for it. 1211 * It DOES call the continuation given to #GCP_send.
1750 * Otherwise (if core transmit is already called or there is no sendable
1751 * message) do nothing.
1752 * 1212 *
1753 * @param peer Peer who keeps the queue. 1213 * @param q Queue handle to cancel
1754 * @param c Connection whose messages to unlock.
1755 */ 1214 */
1756void 1215void
1757GCP_queue_unlock (struct CadetPeer *peer, struct CadetConnection *c) 1216GCP_send_cancel (struct CadetPeerQueue *q)
1758{ 1217{
1759 struct CadetPeerQueue *q; 1218 call_peer_cont (q, GNUNET_NO);
1760 size_t size; 1219 GNUNET_MQ_send_cancel (q->env);
1761 1220 GNUNET_free (q);
1762 GCC_check_connections ();
1763 if (NULL != peer->core_transmit)
1764 {
1765 LOG (GNUNET_ERROR_TYPE_DEBUG, " already unlocked!\n");
1766 return; /* Already unlocked */
1767 }
1768
1769 q = connection_get_first_message (peer, c);
1770 if (NULL == q)
1771 {
1772 LOG (GNUNET_ERROR_TYPE_DEBUG, " queue empty!\n");
1773 return; /* Nothing to transmit */
1774 }
1775
1776 size = q->size;
1777 peer->core_transmit =
1778 GNUNET_CORE_notify_transmit_ready (core_handle,
1779 GNUNET_NO, get_priority (q),
1780 GNUNET_TIME_UNIT_FOREVER_REL,
1781 GNUNET_PEER_resolve2 (peer->id),
1782 get_core_size (size),
1783 &queue_send,
1784 peer);
1785 peer->tmt_time = GNUNET_TIME_absolute_get ();
1786 GCC_check_connections ();
1787} 1221}
1788 1222
1789 1223
@@ -1824,23 +1258,12 @@ GCP_init (const struct GNUNET_CONFIGURATION_Handle *c)
1824 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n"); 1258 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1825 } 1259 }
1826 ats_ch = GNUNET_ATS_connectivity_init (c); 1260 ats_ch = GNUNET_ATS_connectivity_init (c);
1827 core_handle = GNUNET_CORE_connect (c, /* Main configuration */ 1261 connect_to_core (c);
1828 NULL, /* Closure passed to CADET functions */
1829 &core_init, /* Call core_init once connected */
1830 &core_connect, /* Handle connects */
1831 &core_disconnect, /* remove peers on disconnects */
1832 NULL, /* Don't notify about all incoming messages */
1833 GNUNET_NO, /* For header only in notification */
1834 NULL, /* Don't notify about all outbound messages */
1835 GNUNET_NO, /* For header-only out notification */
1836 core_handlers); /* Register these handlers */
1837 if (NULL == core_handle) 1262 if (NULL == core_handle)
1838 { 1263 {
1839 GNUNET_break (0); 1264 GNUNET_break (0);
1840 GNUNET_SCHEDULER_shutdown (); 1265 GNUNET_SCHEDULER_shutdown ();
1841 return;
1842 } 1266 }
1843
1844} 1267}
1845 1268
1846 1269
@@ -1853,13 +1276,10 @@ GCP_shutdown (void)
1853 LOG (GNUNET_ERROR_TYPE_DEBUG, 1276 LOG (GNUNET_ERROR_TYPE_DEBUG,
1854 "Shutting down peer subsystem\n"); 1277 "Shutting down peer subsystem\n");
1855 in_shutdown = GNUNET_YES; 1278 in_shutdown = GNUNET_YES;
1856 GNUNET_CONTAINER_multipeermap_iterate (peers,
1857 &shutdown_peer,
1858 NULL);
1859 if (NULL != core_handle) 1279 if (NULL != core_handle)
1860 { 1280 {
1861 GNUNET_CORE_disconnect (core_handle); 1281 GNUNET_CORE_disconnecT (core_handle);
1862 core_handle = NULL; 1282 core_handle = NULL;
1863 } 1283 }
1864 if (NULL != ats_ch) 1284 if (NULL != ats_ch)
1865 { 1285 {
@@ -1867,6 +1287,12 @@ GCP_shutdown (void)
1867 ats_ch = NULL; 1287 ats_ch = NULL;
1868 } 1288 }
1869 GNUNET_PEER_change_rc (myid, -1); 1289 GNUNET_PEER_change_rc (myid, -1);
1290 /* With MQ API, CORE calls the disconnect handler for every peer
1291 * after calling GNUNET_CORE_disconnecT, shutdown must occur *after* that.
1292 */
1293 GNUNET_CONTAINER_multipeermap_iterate (peers,
1294 &shutdown_peer,
1295 NULL);
1870 GNUNET_CONTAINER_multipeermap_destroy (peers); 1296 GNUNET_CONTAINER_multipeermap_destroy (peers);
1871 peers = NULL; 1297 peers = NULL;
1872} 1298}
@@ -2054,7 +1480,6 @@ GCP_is_neighbor (const struct CadetPeer *peer)
2054 } 1480 }
2055 1481
2056 /* Is not a neighbor but connections is not NULL, probably disconnecting */ 1482 /* Is not a neighbor but connections is not NULL, probably disconnecting */
2057 GNUNET_break (0);
2058 return GNUNET_NO; 1483 return GNUNET_NO;
2059} 1484}
2060 1485
@@ -2254,7 +1679,8 @@ GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed)
2254{ 1679{
2255 unsigned int i; 1680 unsigned int i;
2256 1681
2257 /* TODO: invert and add */ 1682 /* TODO: invert and add to origin */
1683 /* TODO: replace all "GCP_add_path" with this, make the other one static */
2258 GCC_check_connections (); 1684 GCC_check_connections ();
2259 for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ; 1685 for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
2260 for (i++; i < p->length; i++) 1686 for (i++; i < p->length; i++)
diff --git a/src/cadet/gnunet-service-cadet_peer.h b/src/cadet/gnunet-service-cadet_peer.h
index 950c68fb6..093cfa21a 100644
--- a/src/cadet/gnunet-service-cadet_peer.h
+++ b/src/cadet/gnunet-service-cadet_peer.h
@@ -47,7 +47,7 @@ extern "C"
47struct CadetPeer; 47struct CadetPeer;
48 48
49/** 49/**
50 * Struct containing info about a queued transmission to this peer 50 * Handle to queued messages on a peer level.
51 */ 51 */
52struct CadetPeerQueue; 52struct CadetPeerQueue;
53 53
@@ -59,18 +59,19 @@ struct CadetPeerQueue;
59 * 59 *
60 * @param cls Closure. 60 * @param cls Closure.
61 * @param c Connection this message was on. 61 * @param c Connection this message was on.
62 * @param fwd Was this a FWD going message?
62 * @param sent Was it really sent? (Could have been canceled) 63 * @param sent Was it really sent? (Could have been canceled)
63 * @param type Type of message sent. 64 * @param type Type of message sent.
64 * @param pid Packet ID, or 0 if not applicable (create, destroy, etc). 65 * @param payload_type Type of payload, if applicable.
65 * @param fwd Was this a FWD going message? 66 * @param pid Message ID, or 0 if not applicable (create, destroy, etc).
66 * @param size Size of the message. 67 * @param size Size of the message.
67 * @param wait Time spent waiting for core (only the time for THIS message) 68 * @param wait Time spent waiting for core (only the time for THIS message)
68 * @return #GNUNET_YES if connection was destroyed, #GNUNET_NO otherwise.
69 */ 69 */
70typedef int 70typedef void
71(*GCP_sent) (void *cls, 71(*GCP_sent) (void *cls,
72 struct CadetConnection *c, int sent, 72 struct CadetConnection *c, int fwd, int sent,
73 uint16_t type, uint32_t pid, int fwd, size_t size, 73 uint16_t type, uint16_t payload_type, uint32_t pid,
74 size_t size,
74 struct GNUNET_TIME_Relative wait); 75 struct GNUNET_TIME_Relative wait);
75 76
76/** 77/**
@@ -146,97 +147,40 @@ void
146GCP_connect (struct CadetPeer *peer); 147GCP_connect (struct CadetPeer *peer);
147 148
148/** 149/**
149 * Free a transmission that was already queued with all resources 150 * @brief Send a message to another peer (using CORE).
150 * associated to the request.
151 *
152 * If connection was marked to be destroyed, and this was the last queued
153 * message on it, the connection will be free'd as a result.
154 *
155 * @param queue Queue handler to cancel.
156 * @param clear_cls Is it necessary to free associated cls?
157 * @param sent Was it really sent? (Could have been canceled)
158 * @param pid PID, if relevant (was sent and was a payload message).
159 *
160 * @return #GNUNET_YES if connection was destroyed as a result,
161 * #GNUNET_NO otherwise.
162 */
163int
164GCP_queue_destroy (struct CadetPeerQueue *queue, int clear_cls,
165 int sent, uint32_t pid);
166
167/**
168 * @brief Queue and pass message to core when possible.
169 * 151 *
170 * @param peer Peer towards which to queue the message. 152 * @param peer Peer towards which to queue the message.
171 * @param cls Closure (@c type dependant). It will be used by queue_send to 153 * @param message Message to send.
172 * build the message to be sent if not already prebuilt. 154 * @param payload_type Type of the message's payload, for debug messages.
173 * @param type Type of the message.
174 * @param payload_type Type of the message's payload
175 * 0 if the message is a retransmission (unknown payload). 155 * 0 if the message is a retransmission (unknown payload).
176 * UINT16_MAX if the message does not have payload. 156 * UINT16_MAX if the message does not have payload.
177 * @param payload_id ID of the payload (MID, ACK #, etc) 157 * @param payload_id ID of the payload (MID, ACK #, etc)
178 * @param size Size of the message.
179 * @param c Connection this message belongs to (can be NULL). 158 * @param c Connection this message belongs to (can be NULL).
180 * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!) 159 * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!)
181 * @param cont Continuation to be called once CORE has taken the message. 160 * @param cont Continuation to be called once CORE has sent the message.
182 * @param cont_cls Closure for @c cont. 161 * @param cont_cls Closure for @c cont.
183 *
184 * @return Handle to cancel the message before it is sent. Once cont is called
185 * message has been sent and therefore the handle is no longer valid.
186 */ 162 */
187struct CadetPeerQueue * 163struct CadetPeerQueue *
188GCP_queue_add (struct CadetPeer *peer, 164GCP_send (struct CadetPeer *peer,
189 void *cls, 165 const struct GNUNET_MessageHeader *message,
190 uint16_t type, 166 uint16_t payload_type,
191 uint16_t payload_type, 167 uint32_t payload_id,
192 uint32_t payload_id, 168 struct CadetConnection *c,
193 size_t size, 169 int fwd,
194 struct CadetConnection *c, 170 GCP_sent cont,
195 int fwd, 171 void *cont_cls);
196 GCP_sent cont,
197 void *cont_cls);
198
199/**
200 * Cancel all queued messages to a peer that belong to a certain connection.
201 *
202 * @param peer Peer towards whom to cancel.
203 * @param c Connection whose queued messages to cancel. Might be destroyed by
204 * the sent continuation call.
205 */
206void
207GCP_queue_cancel (struct CadetPeer *peer, struct CadetConnection *c);
208
209/**
210 * Get the first message for a connection and unqueue it.
211 *
212 * Only tunnel (or higher) level messages are unqueued. Connection specific
213 * messages are silently destroyed upon encounter.
214 *
215 * @param peer Neighboring peer.
216 * @param c Connection.
217 * @param destroyed[in/out] Was the connection destroyed as a result?.
218 * Can NOT be NULL.
219 *
220 *
221 * @return First message for this connection.
222 */
223struct GNUNET_MessageHeader *
224GCP_connection_pop (struct CadetPeer *peer,
225 struct CadetConnection *c,
226 int *destroyed);
227 172
228/** 173/**
229 * Unlock a possibly locked queue for a connection. 174 * Cancel sending a message. Message must have been sent with
175 * #GCP_send before. May not be called after the notify sent
176 * callback has been called.
230 * 177 *
231 * If there is a message that can be sent on this connection, call core for it. 178 * It does NOT call the continuation given to #GCP_send.
232 * Otherwise (if core transmit is already called or there is no sendable
233 * message) do nothing.
234 * 179 *
235 * @param peer Peer who keeps the queue. 180 * @param q Queue handle to cancel
236 * @param c Connection whose messages to unlock.
237 */ 181 */
238void 182void
239GCP_queue_unlock (struct CadetPeer *peer, struct CadetConnection *c); 183GCP_send_cancel (struct CadetPeerQueue *q);
240 184
241/** 185/**
242 * Set tunnel. 186 * Set tunnel.
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c
index 0ede4a886..e60c3c023 100644
--- a/src/cadet/gnunet-service-cadet_tunnel.c
+++ b/src/cadet/gnunet-service-cadet_tunnel.c
@@ -1600,7 +1600,6 @@ send_kx (struct CadetTunnel *t,
1600 { 1600 {
1601 GNUNET_break (0); 1601 GNUNET_break (0);
1602 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR); 1602 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR);
1603 GCP_debug (t->peer, GNUNET_ERROR_TYPE_ERROR);
1604 } 1603 }
1605 return NULL; 1604 return NULL;
1606 } 1605 }
@@ -2245,6 +2244,10 @@ GCT_handle_encrypted (struct CadetTunnel *t,
2245 * 2244 *
2246 * @param t Tunnel on which the message came. 2245 * @param t Tunnel on which the message came.
2247 * @param message Payload of KX message. 2246 * @param message Payload of KX message.
2247 *
2248 * FIXME: not needed anymore
2249 * - substitute with call to kx_ax
2250 * - eliminate encapsulation
2248 */ 2251 */
2249void 2252void
2250GCT_handle_kx (struct CadetTunnel *t, 2253GCT_handle_kx (struct CadetTunnel *t,
@@ -3367,34 +3370,6 @@ GCT_send_ax_kx (struct CadetTunnel *t, int force_reply)
3367 3370
3368 3371
3369/** 3372/**
3370 * Sends an already built and encrypted message on a tunnel, choosing the best
3371 * connection. Useful for re-queueing messages queued on a destroyed connection.
3372 *
3373 * @param message Message to send. Function modifies it.
3374 * @param t Tunnel on which this message is transmitted.
3375 */
3376void
3377GCT_resend_message (const struct GNUNET_MessageHeader *message,
3378 struct CadetTunnel *t)
3379{
3380 struct CadetConnection *c;
3381 int fwd;
3382
3383 c = tunnel_get_connection (t);
3384 if (NULL == c)
3385 {
3386 /* TODO queue in tunnel, marked as encrypted */
3387 LOG (GNUNET_ERROR_TYPE_DEBUG, "No connection available, dropping.\n");
3388 return;
3389 }
3390 fwd = GCC_is_origin (c, GNUNET_YES);
3391 GNUNET_break (NULL == GCC_send_prebuilt_message (message, UINT16_MAX, 0,
3392 c, fwd,
3393 GNUNET_YES, NULL, NULL));
3394}
3395
3396
3397/**
3398 * Is the tunnel directed towards the local peer? 3373 * Is the tunnel directed towards the local peer?
3399 * 3374 *
3400 * @param t Tunnel. 3375 * @param t Tunnel.
diff --git a/src/cadet/gnunet-service-cadet_tunnel.h b/src/cadet/gnunet-service-cadet_tunnel.h
index ca553a7d3..8d65cbebd 100644
--- a/src/cadet/gnunet-service-cadet_tunnel.h
+++ b/src/cadet/gnunet-service-cadet_tunnel.h
@@ -504,18 +504,6 @@ GCT_send_ax_kx (struct CadetTunnel *t, int force_reply);
504 504
505 505
506/** 506/**
507 * Sends an already built and encrypted message on a tunnel, choosing the best
508 * connection. Useful for re-queueing messages queued on a destroyed connection.
509 *
510 * @param message Message to send. Function modifies it.
511 * @param t Tunnel on which this message is transmitted.
512 */
513void
514GCT_resend_message (const struct GNUNET_MessageHeader *message,
515 struct CadetTunnel *t);
516
517
518/**
519 * Is the tunnel directed towards the local peer? 507 * Is the tunnel directed towards the local peer?
520 * 508 *
521 * @param t Tunnel. 509 * @param t Tunnel.