aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/gnunet-service-cadet_connection.c')
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c1163
1 files changed, 512 insertions, 651 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