diff options
Diffstat (limited to 'src/transport/gnunet-service-transport_neighbours.c')
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 372 |
1 files changed, 184 insertions, 188 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 461d2669a..86212f9ab 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -862,87 +862,57 @@ set_alternative_address (struct NeighbourMapEntry *n, | |||
862 | 862 | ||
863 | 863 | ||
864 | /** | 864 | /** |
865 | * Initialize the primary address of a neighbour | 865 | * Transmit a message using the current session of the given |
866 | * neighbour. | ||
866 | * | 867 | * |
867 | * @param n the neighbour | 868 | * @param n entry for the recipient |
868 | * @param address address of the other peer, NULL if other peer | 869 | * @param msgbuf buffer to transmit |
869 | * connected to us | 870 | * @param msgbuf_size number of bytes in @a msgbuf buffer |
870 | * @param session session to use (or NULL, in which case an | 871 | * @param priority transmission priority |
871 | * address must be setup) | 872 | * @param timeout transmission timeout |
872 | * @param bandwidth_in inbound quota to be used when connection is up | 873 | * @param use_keepalive_timeout #GNUNET_YES to use plugin-specific keep-alive |
873 | * @param bandwidth_out outbound quota to be used when connection is up | 874 | * timeout (@a timeout is ignored in that case), #GNUNET_NO otherwise |
875 | * @param cont continuation to call when finished (can be NULL) | ||
876 | * @param cont_cls closure for @a cont | ||
877 | * @return timeout (copy of @a timeout or a calculated one if | ||
878 | * @a use_keepalive_timeout is #GNUNET_YES. | ||
874 | */ | 879 | */ |
875 | static void | 880 | static struct GNUNET_TIME_Relative |
876 | set_primary_address (struct NeighbourMapEntry *n, | 881 | send_with_session (struct NeighbourMapEntry *n, |
877 | const struct GNUNET_HELLO_Address *address, | 882 | const void *msgbuf, |
878 | struct Session *session, | 883 | size_t msgbuf_size, |
879 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, | 884 | uint32_t priority, |
880 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) | 885 | struct GNUNET_TIME_Relative timeout, |
886 | unsigned int use_keepalive_timeout, | ||
887 | GNUNET_TRANSPORT_TransmitContinuation cont, | ||
888 | void *cont_cls) | ||
881 | { | 889 | { |
882 | if (session == n->primary_address.session) | 890 | struct GNUNET_TRANSPORT_PluginFunctions *papi; |
883 | { | 891 | struct GNUNET_TIME_Relative result = GNUNET_TIME_UNIT_FOREVER_REL; |
884 | GST_validation_set_address_use (n->primary_address.address, | ||
885 | GNUNET_YES); | ||
886 | if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__) | ||
887 | { | ||
888 | n->primary_address.bandwidth_in = bandwidth_in; | ||
889 | GST_neighbours_set_incoming_quota (&address->peer, | ||
890 | bandwidth_in); | ||
891 | } | ||
892 | if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__) | ||
893 | { | ||
894 | n->primary_address.bandwidth_out = bandwidth_out; | ||
895 | send_outbound_quota_to_clients (&address->peer, | ||
896 | bandwidth_out); | ||
897 | } | ||
898 | return; | ||
899 | } | ||
900 | if ( (NULL != n->primary_address.address) && | ||
901 | (0 == GNUNET_HELLO_address_cmp (address, | ||
902 | n->primary_address.address)) ) | ||
903 | { | ||
904 | GNUNET_break (0); | ||
905 | return; | ||
906 | } | ||
907 | if (NULL == session) | ||
908 | { | ||
909 | GNUNET_break (0); | ||
910 | GST_ats_block_address (address, | ||
911 | session); | ||
912 | return; | ||
913 | } | ||
914 | if (NULL != n->primary_address.address) | ||
915 | { | ||
916 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
917 | "Replacing existing primary address with another one\n"); | ||
918 | free_address (&n->primary_address); | ||
919 | } | ||
920 | n->primary_address.address = GNUNET_HELLO_address_copy (address); | ||
921 | n->primary_address.bandwidth_in = bandwidth_in; | ||
922 | n->primary_address.bandwidth_out = bandwidth_out; | ||
923 | n->primary_address.session = session; | ||
924 | n->primary_address.keep_alive_nonce = 0; | ||
925 | GNUNET_assert (GNUNET_YES == | ||
926 | GST_ats_is_known (n->primary_address.address, | ||
927 | n->primary_address.session)); | ||
928 | /* subsystems about address use */ | ||
929 | GST_validation_set_address_use (n->primary_address.address, | ||
930 | GNUNET_YES); | ||
931 | GST_neighbours_set_incoming_quota (&address->peer, | ||
932 | bandwidth_in); | ||
933 | send_outbound_quota_to_clients (&address->peer, | ||
934 | bandwidth_out); | ||
935 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
936 | "Neighbour `%s' switched to address `%s'\n", | ||
937 | GNUNET_i2s (&n->id), | ||
938 | GST_plugins_a2s(address)); | ||
939 | 892 | ||
940 | neighbours_changed_notification (&n->id, | 893 | GNUNET_assert (NULL != n->primary_address.session); |
941 | n->primary_address.address, | 894 | if ( ((NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name)) || |
942 | n->state, | 895 | (-1 == papi->send (papi->cls, |
943 | n->timeout, | 896 | n->primary_address.session, |
944 | n->primary_address.bandwidth_in, | 897 | msgbuf, |
945 | n->primary_address.bandwidth_out); | 898 | msgbuf_size, |
899 | priority, | ||
900 | (result = (GNUNET_NO == use_keepalive_timeout) ? timeout : | ||
901 | GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
902 | papi->query_keepalive_factor (papi->cls))), | ||
903 | cont, | ||
904 | cont_cls)))) && | ||
905 | (NULL != cont)) | ||
906 | cont (cont_cls, | ||
907 | &n->id, | ||
908 | GNUNET_SYSERR, | ||
909 | msgbuf_size, | ||
910 | 0); | ||
911 | GST_neighbours_notify_data_sent (n->primary_address.address, | ||
912 | n->primary_address.session, | ||
913 | msgbuf_size); | ||
914 | GNUNET_break (NULL != papi); | ||
915 | return result; | ||
946 | } | 916 | } |
947 | 917 | ||
948 | 918 | ||
@@ -1041,61 +1011,6 @@ free_neighbour (struct NeighbourMapEntry *n) | |||
1041 | 1011 | ||
1042 | 1012 | ||
1043 | /** | 1013 | /** |
1044 | * Transmit a message using the current session of the given | ||
1045 | * neighbour. | ||
1046 | * | ||
1047 | * @param n entry for the recipient | ||
1048 | * @param msgbuf buffer to transmit | ||
1049 | * @param msgbuf_size number of bytes in @a msgbuf buffer | ||
1050 | * @param priority transmission priority | ||
1051 | * @param timeout transmission timeout | ||
1052 | * @param use_keepalive_timeout #GNUNET_YES to use plugin-specific keep-alive | ||
1053 | * timeout (@a timeout is ignored in that case), #GNUNET_NO otherwise | ||
1054 | * @param cont continuation to call when finished (can be NULL) | ||
1055 | * @param cont_cls closure for @a cont | ||
1056 | * @return timeout (copy of @a timeout or a calculated one if | ||
1057 | * @a use_keepalive_timeout is #GNUNET_YES. | ||
1058 | */ | ||
1059 | static struct GNUNET_TIME_Relative | ||
1060 | send_with_session (struct NeighbourMapEntry *n, | ||
1061 | const void *msgbuf, | ||
1062 | size_t msgbuf_size, | ||
1063 | uint32_t priority, | ||
1064 | struct GNUNET_TIME_Relative timeout, | ||
1065 | unsigned int use_keepalive_timeout, | ||
1066 | GNUNET_TRANSPORT_TransmitContinuation cont, | ||
1067 | void *cont_cls) | ||
1068 | { | ||
1069 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
1070 | struct GNUNET_TIME_Relative result = GNUNET_TIME_UNIT_FOREVER_REL; | ||
1071 | |||
1072 | GNUNET_assert (NULL != n->primary_address.session); | ||
1073 | if ( ((NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name)) || | ||
1074 | (-1 == papi->send (papi->cls, | ||
1075 | n->primary_address.session, | ||
1076 | msgbuf, | ||
1077 | msgbuf_size, | ||
1078 | priority, | ||
1079 | (result = (GNUNET_NO == use_keepalive_timeout) ? timeout : | ||
1080 | GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
1081 | papi->query_keepalive_factor (papi->cls))), | ||
1082 | cont, | ||
1083 | cont_cls)))) && | ||
1084 | (NULL != cont)) | ||
1085 | cont (cont_cls, | ||
1086 | &n->id, | ||
1087 | GNUNET_SYSERR, | ||
1088 | msgbuf_size, | ||
1089 | 0); | ||
1090 | GST_neighbours_notify_data_sent (n->primary_address.address, | ||
1091 | n->primary_address.session, | ||
1092 | msgbuf_size); | ||
1093 | GNUNET_break (NULL != papi); | ||
1094 | return result; | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | /** | ||
1099 | * Function called when the 'DISCONNECT' message has been sent by the | 1014 | * Function called when the 'DISCONNECT' message has been sent by the |
1100 | * plugin. Frees the neighbour --- if the entry still exists. | 1015 | * plugin. Frees the neighbour --- if the entry still exists. |
1101 | * | 1016 | * |
@@ -1248,6 +1163,140 @@ disconnect_neighbour (struct NeighbourMapEntry *n) | |||
1248 | 1163 | ||
1249 | 1164 | ||
1250 | /** | 1165 | /** |
1166 | * Change the incoming quota for the given peer. Updates | ||
1167 | * our own receive rate and informs the neighbour about | ||
1168 | * the new quota. | ||
1169 | * | ||
1170 | * @param n neighbour entry to change qutoa for | ||
1171 | * @param quota new quota | ||
1172 | */ | ||
1173 | static void | ||
1174 | set_incoming_quota (struct NeighbourMapEntry *n, | ||
1175 | struct GNUNET_BANDWIDTH_Value32NBO quota) | ||
1176 | { | ||
1177 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1178 | "Setting inbound quota of %u Bps for peer `%s' to all clients\n", | ||
1179 | ntohl (quota.value__), GNUNET_i2s (&n->id)); | ||
1180 | GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, quota); | ||
1181 | if (0 != ntohl (quota.value__)) | ||
1182 | { | ||
1183 | struct SessionQuotaMessage sqm; | ||
1184 | |||
1185 | sqm.header.size = htons (sizeof (struct SessionQuotaMessage)); | ||
1186 | sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA); | ||
1187 | sqm.quota = quota.value__; | ||
1188 | (void) send_with_session (n, | ||
1189 | &sqm, | ||
1190 | sizeof (sqm), | ||
1191 | UINT32_MAX - 1, | ||
1192 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
1193 | GNUNET_NO, | ||
1194 | NULL, NULL); | ||
1195 | return; | ||
1196 | } | ||
1197 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1198 | "Disconnecting peer `%4s' due to SET_QUOTA\n", | ||
1199 | GNUNET_i2s (&n->id)); | ||
1200 | if (GNUNET_YES == test_connected (n)) | ||
1201 | GNUNET_STATISTICS_update (GST_stats, | ||
1202 | gettext_noop ("# disconnects due to quota of 0"), | ||
1203 | 1, GNUNET_NO); | ||
1204 | disconnect_neighbour (n); | ||
1205 | } | ||
1206 | |||
1207 | |||
1208 | /** | ||
1209 | * Initialize the primary address of a neighbour | ||
1210 | * | ||
1211 | * @param n the neighbour | ||
1212 | * @param address address of the other peer, NULL if other peer | ||
1213 | * connected to us | ||
1214 | * @param session session to use (or NULL, in which case an | ||
1215 | * address must be setup) | ||
1216 | * @param bandwidth_in inbound quota to be used when connection is up | ||
1217 | * @param bandwidth_out outbound quota to be used when connection is up | ||
1218 | */ | ||
1219 | static void | ||
1220 | set_primary_address (struct NeighbourMapEntry *n, | ||
1221 | const struct GNUNET_HELLO_Address *address, | ||
1222 | struct Session *session, | ||
1223 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, | ||
1224 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) | ||
1225 | { | ||
1226 | if (session == n->primary_address.session) | ||
1227 | { | ||
1228 | GST_validation_set_address_use (n->primary_address.address, | ||
1229 | GNUNET_YES); | ||
1230 | if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__) | ||
1231 | { | ||
1232 | n->primary_address.bandwidth_in = bandwidth_in; | ||
1233 | set_incoming_quota (n, | ||
1234 | bandwidth_in); | ||
1235 | } | ||
1236 | if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__) | ||
1237 | { | ||
1238 | n->primary_address.bandwidth_out = bandwidth_out; | ||
1239 | // FIXME: this ignores n->neighbour_receive_quota! | ||
1240 | // -> might get 'unusually' high quota on initial | ||
1241 | // connect | ||
1242 | send_outbound_quota_to_clients (&address->peer, | ||
1243 | bandwidth_out); | ||
1244 | } | ||
1245 | return; | ||
1246 | } | ||
1247 | if ( (NULL != n->primary_address.address) && | ||
1248 | (0 == GNUNET_HELLO_address_cmp (address, | ||
1249 | n->primary_address.address)) ) | ||
1250 | { | ||
1251 | GNUNET_break (0); | ||
1252 | return; | ||
1253 | } | ||
1254 | if (NULL == session) | ||
1255 | { | ||
1256 | GNUNET_break (0); | ||
1257 | GST_ats_block_address (address, | ||
1258 | session); | ||
1259 | return; | ||
1260 | } | ||
1261 | if (NULL != n->primary_address.address) | ||
1262 | { | ||
1263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1264 | "Replacing existing primary address with another one\n"); | ||
1265 | free_address (&n->primary_address); | ||
1266 | } | ||
1267 | n->primary_address.address = GNUNET_HELLO_address_copy (address); | ||
1268 | n->primary_address.bandwidth_in = bandwidth_in; | ||
1269 | n->primary_address.bandwidth_out = bandwidth_out; | ||
1270 | n->primary_address.session = session; | ||
1271 | n->primary_address.keep_alive_nonce = 0; | ||
1272 | GNUNET_assert (GNUNET_YES == | ||
1273 | GST_ats_is_known (n->primary_address.address, | ||
1274 | n->primary_address.session)); | ||
1275 | /* subsystems about address use */ | ||
1276 | GST_validation_set_address_use (n->primary_address.address, | ||
1277 | GNUNET_YES); | ||
1278 | set_incoming_quota (n, | ||
1279 | bandwidth_in); | ||
1280 | // FIXME: this ignores n->neighbour_receive_quota! | ||
1281 | // -> might get 'unusually' high quota on initial | ||
1282 | // connect | ||
1283 | send_outbound_quota_to_clients (&address->peer, | ||
1284 | bandwidth_out); | ||
1285 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1286 | "Neighbour `%s' switched to address `%s'\n", | ||
1287 | GNUNET_i2s (&n->id), | ||
1288 | GST_plugins_a2s(address)); | ||
1289 | |||
1290 | neighbours_changed_notification (&n->id, | ||
1291 | n->primary_address.address, | ||
1292 | n->state, | ||
1293 | n->timeout, | ||
1294 | n->primary_address.bandwidth_in, | ||
1295 | n->primary_address.bandwidth_out); | ||
1296 | } | ||
1297 | |||
1298 | |||
1299 | /** | ||
1251 | * We're done with our transmission attempt, continue processing. | 1300 | * We're done with our transmission attempt, continue processing. |
1252 | * | 1301 | * |
1253 | * @param cls the `struct MessageQueue` of the message | 1302 | * @param cls the `struct MessageQueue` of the message |
@@ -2503,8 +2552,8 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address, | |||
2503 | if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__) | 2552 | if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__) |
2504 | { | 2553 | { |
2505 | n->primary_address.bandwidth_in = bandwidth_in; | 2554 | n->primary_address.bandwidth_in = bandwidth_in; |
2506 | GST_neighbours_set_incoming_quota (&address->peer, | 2555 | set_incoming_quota (n, |
2507 | bandwidth_in); | 2556 | bandwidth_in); |
2508 | } | 2557 | } |
2509 | if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__) | 2558 | if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__) |
2510 | { | 2559 | { |
@@ -3588,59 +3637,6 @@ GST_neighbours_test_connected (const struct GNUNET_PeerIdentity *target) | |||
3588 | 3637 | ||
3589 | 3638 | ||
3590 | /** | 3639 | /** |
3591 | * Change the incoming quota for the given peer. Updates | ||
3592 | * our own receive rate and informs the neighbour about | ||
3593 | * the new quota. | ||
3594 | * | ||
3595 | * @param neighbour identity of peer to change qutoa for | ||
3596 | * @param quota new quota | ||
3597 | */ | ||
3598 | void | ||
3599 | GST_neighbours_set_incoming_quota (const struct GNUNET_PeerIdentity *neighbour, | ||
3600 | struct GNUNET_BANDWIDTH_Value32NBO quota) | ||
3601 | { | ||
3602 | struct NeighbourMapEntry *n; | ||
3603 | |||
3604 | if (NULL == (n = lookup_neighbour (neighbour))) | ||
3605 | { | ||
3606 | GNUNET_STATISTICS_update (GST_stats, | ||
3607 | gettext_noop | ||
3608 | ("# SET QUOTA messages ignored (no such peer)"), | ||
3609 | 1, GNUNET_NO); | ||
3610 | return; | ||
3611 | } | ||
3612 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3613 | "Setting inbound quota of %u Bps for peer `%s' to all clients\n", | ||
3614 | ntohl (quota.value__), GNUNET_i2s (&n->id)); | ||
3615 | GNUNET_BANDWIDTH_tracker_update_quota (&n->in_tracker, quota); | ||
3616 | if (0 != ntohl (quota.value__)) | ||
3617 | { | ||
3618 | struct SessionQuotaMessage sqm; | ||
3619 | |||
3620 | sqm.header.size = htons (sizeof (struct SessionQuotaMessage)); | ||
3621 | sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA); | ||
3622 | sqm.quota = quota.value__; | ||
3623 | (void) send_with_session (n, | ||
3624 | &sqm, | ||
3625 | sizeof (sqm), | ||
3626 | UINT32_MAX - 1, | ||
3627 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
3628 | GNUNET_NO, | ||
3629 | NULL, NULL); | ||
3630 | return; | ||
3631 | } | ||
3632 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
3633 | "Disconnecting peer `%4s' due to SET_QUOTA\n", | ||
3634 | GNUNET_i2s (&n->id)); | ||
3635 | if (GNUNET_YES == test_connected (n)) | ||
3636 | GNUNET_STATISTICS_update (GST_stats, | ||
3637 | gettext_noop ("# disconnects due to quota of 0"), | ||
3638 | 1, GNUNET_NO); | ||
3639 | disconnect_neighbour (n); | ||
3640 | } | ||
3641 | |||
3642 | |||
3643 | /** | ||
3644 | * Task to asynchronously run #free_neighbour(). | 3640 | * Task to asynchronously run #free_neighbour(). |
3645 | * | 3641 | * |
3646 | * @param cls the `struct NeighbourMapEntry` to free | 3642 | * @param cls the `struct NeighbourMapEntry` to free |
@@ -3661,7 +3657,7 @@ delayed_disconnect (void *cls, | |||
3661 | 3657 | ||
3662 | 3658 | ||
3663 | /** | 3659 | /** |
3664 | * We received a quoat message from the given peer, | 3660 | * We received a quota message from the given peer, |
3665 | * validate and process. | 3661 | * validate and process. |
3666 | * | 3662 | * |
3667 | * @param peer sender of the message | 3663 | * @param peer sender of the message |