diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet_connection.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_connection.c | 1163 |
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 | */ |
317 | static unsigned long long max_connections; | 318 | static 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 | */ | ||
631 | static void | ||
632 | update_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 | */ |
638 | static int | 679 | static void |
639 | conn_message_sent (void *cls, | 680 | conn_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 | */ |
960 | static int | 984 | static int |
961 | is_fwd (const struct CadetConnection *c, | 985 | is_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 | */ |
986 | static void | 1009 | static void |
987 | send_connection_ack (struct CadetConnection *connection, int fwd) | 1010 | send_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 | */ |
1047 | static void | 1081 | static void |
1048 | send_broken_unknown (const struct GNUNET_CADET_Hash *connection_id, | 1082 | send_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 | */ | ||
1323 | static void | ||
1324 | connection_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 | */ | ||
1480 | static void | ||
1481 | resend_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) | |||
1529 | static void | 1475 | static void |
1530 | connection_timeout (struct CadetConnection *c, int fwd) | 1476 | connection_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 | */ |
1913 | static void | 1852 | static void |
1914 | log_message (const struct GNUNET_MessageHeader *message, | 1853 | log_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 | */ |
1953 | int | 1889 | void |
1954 | GCC_handle_create (void *cls, | 1890 | GCC_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 | */ |
2114 | int | 2032 | void |
2115 | GCC_handle_confirm (void *cls, | 2033 | GCC_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 | */ |
2250 | int | 2161 | void |
2251 | GCC_handle_broken (void* cls, | 2162 | GCC_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 | */ |
2326 | int | 2235 | void |
2327 | GCC_handle_destroy (void *cls, | 2236 | GCC_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 | */ | ||
2298 | void | ||
2299 | GCC_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 | */ | ||
2367 | void | ||
2368 | GCC_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 | */ |
2394 | static int | 2438 | static int |
2395 | check_message (const struct GNUNET_MessageHeader *message, | 2439 | check_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 | */ |
2518 | static int | 2548 | void |
2519 | handle_cadet_encrypted (const struct GNUNET_PeerIdentity *peer, | 2549 | GCC_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 | */ |
2588 | static int | 2605 | void |
2589 | handle_cadet_kx (const struct GNUNET_PeerIdentity *peer, | 2606 | GCC_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 | */ | ||
2649 | int | ||
2650 | GCC_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 | */ | ||
2668 | int | ||
2669 | GCC_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 | */ | ||
2686 | int | ||
2687 | GCC_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 | */ | ||
2764 | int | ||
2765 | GCC_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 | */ | ||
2836 | void | ||
2837 | GCC_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 | */ | ||
2983 | struct CadetConnection * | 2751 | struct CadetConnection * |
2984 | GCC_new (const struct GNUNET_CADET_Hash *cid, | 2752 | GCC_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 | */ | ||
3039 | void | 2815 | void |
3040 | GCC_destroy (struct CadetConnection *c) | 2816 | GCC_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 | */ |
3599 | void | 3379 | void |
3600 | GCC_send_create (struct CadetConnection *connection) | 3380 | GCC_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 | */ | ||
3435 | void | ||
3436 | GCC_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 | ||