diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-02-06 09:35:56 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-02-06 09:35:56 +0000 |
commit | 7e599b44d257d9d9c6100e4050dc1eb09c9e13d2 (patch) | |
tree | 6f63e09cf3a296d4daf6135077b58a9006e564e9 /src/transport | |
parent | dc0da555fd351b2a96bca0a6494e83f0643fac31 (diff) | |
download | gnunet-7e599b44d257d9d9c6100e4050dc1eb09c9e13d2.tar.gz gnunet-7e599b44d257d9d9c6100e4050dc1eb09c9e13d2.zip |
-applying patch from vminko to fix #1972: adding support for continuous transport-level connection monitoring
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 23 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_clients.c | 253 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_clients.h | 13 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 32 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.h | 7 | ||||
-rw-r--r-- | src/transport/transport_api_address_lookup.c | 51 |
6 files changed, 309 insertions, 70 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index eec1684db..8b96babc3 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -494,6 +494,23 @@ neighbours_disconnect_notification (void *cls, | |||
494 | 494 | ||
495 | 495 | ||
496 | /** | 496 | /** |
497 | * Function called to notify transport users that a neighbour peer changed its | ||
498 | * active address. | ||
499 | * | ||
500 | * @param cls closure | ||
501 | * @param peer peer this update is about (never NULL) | ||
502 | * @param address address, NULL on disconnect | ||
503 | */ | ||
504 | static void | ||
505 | neighbours_address_notification (void *cls, | ||
506 | const struct GNUNET_PeerIdentity *peer, | ||
507 | const struct GNUNET_HELLO_Address *address) | ||
508 | { | ||
509 | GST_clients_broadcast_address_notification (peer, address); | ||
510 | } | ||
511 | |||
512 | |||
513 | /** | ||
497 | * Function called when the service shuts down. Unloads our plugins | 514 | * Function called when the service shuts down. Unloads our plugins |
498 | * and cancels pending validations. | 515 | * and cancels pending validations. |
499 | * | 516 | * |
@@ -589,8 +606,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
589 | &plugin_env_address_change_notification, | 606 | &plugin_env_address_change_notification, |
590 | &plugin_env_session_end, | 607 | &plugin_env_session_end, |
591 | &plugin_env_address_to_type); | 608 | &plugin_env_address_to_type); |
592 | GST_neighbours_start (NULL, &neighbours_connect_notification, | 609 | GST_neighbours_start (NULL, |
593 | &neighbours_disconnect_notification); | 610 | &neighbours_connect_notification, |
611 | &neighbours_disconnect_notification, | ||
612 | &neighbours_address_notification); | ||
594 | GST_clients_start (server); | 613 | GST_clients_start (server); |
595 | GST_validation_start (); | 614 | GST_validation_start (); |
596 | } | 615 | } |
diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index 7ce455f7d..3cc5aac34 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c | |||
@@ -117,6 +117,35 @@ struct TransportClient | |||
117 | 117 | ||
118 | 118 | ||
119 | /** | 119 | /** |
120 | * Client monitoring changes of active addresses of our neighbours. | ||
121 | */ | ||
122 | struct MonitoringClient | ||
123 | { | ||
124 | /** | ||
125 | * This is a doubly-linked list. | ||
126 | */ | ||
127 | struct MonitoringClient *next; | ||
128 | |||
129 | /** | ||
130 | * This is a doubly-linked list. | ||
131 | */ | ||
132 | struct MonitoringClient *prev; | ||
133 | |||
134 | /** | ||
135 | * Handle to the client. | ||
136 | */ | ||
137 | struct GNUNET_SERVER_Client *client; | ||
138 | |||
139 | /** | ||
140 | * Peer identity to monitor the addresses of. | ||
141 | * Zero to monitor all neighrours. | ||
142 | */ | ||
143 | struct GNUNET_PeerIdentity peer; | ||
144 | |||
145 | }; | ||
146 | |||
147 | |||
148 | /** | ||
120 | * Head of linked list of all clients to this service. | 149 | * Head of linked list of all clients to this service. |
121 | */ | 150 | */ |
122 | static struct TransportClient *clients_head; | 151 | static struct TransportClient *clients_head; |
@@ -127,6 +156,23 @@ static struct TransportClient *clients_head; | |||
127 | static struct TransportClient *clients_tail; | 156 | static struct TransportClient *clients_tail; |
128 | 157 | ||
129 | /** | 158 | /** |
159 | * Head of linked list of monitoring clients. | ||
160 | */ | ||
161 | static struct MonitoringClient *monitoring_clients_head; | ||
162 | |||
163 | /** | ||
164 | * Tail of linked list of monitoring clients. | ||
165 | */ | ||
166 | static struct MonitoringClient *monitoring_clients_tail; | ||
167 | |||
168 | /** | ||
169 | * Notification context, to send updates on changes to active addresses | ||
170 | * of our neighbours. | ||
171 | */ | ||
172 | struct GNUNET_SERVER_NotificationContext *nc = NULL; | ||
173 | |||
174 | |||
175 | /** | ||
130 | * Find the internal handle associated with the given client handle | 176 | * Find the internal handle associated with the given client handle |
131 | * | 177 | * |
132 | * @param client server's client handle to look up | 178 | * @param client server's client handle to look up |
@@ -171,6 +217,60 @@ setup_client (struct GNUNET_SERVER_Client *client) | |||
171 | 217 | ||
172 | 218 | ||
173 | /** | 219 | /** |
220 | * Find the handle to the monitoring client associated with the given | ||
221 | * client handle | ||
222 | * | ||
223 | * @param client server's client handle to look up | ||
224 | * @return handle to the monitoring client | ||
225 | */ | ||
226 | static struct MonitoringClient * | ||
227 | lookup_monitoring_client (struct GNUNET_SERVER_Client *client) | ||
228 | { | ||
229 | struct MonitoringClient *mc; | ||
230 | |||
231 | mc = monitoring_clients_head; | ||
232 | while (mc != NULL) | ||
233 | { | ||
234 | if (mc->client == client) | ||
235 | return mc; | ||
236 | mc = mc->next; | ||
237 | } | ||
238 | return NULL; | ||
239 | } | ||
240 | |||
241 | |||
242 | /** | ||
243 | * Setup a new monitoring client using the given server client handle and | ||
244 | * the peer identity. | ||
245 | * | ||
246 | * @param client server's client handle to create our internal handle for | ||
247 | * @param peer identity of the peer to monitor the addresses of, | ||
248 | * zero to monitor all neighrours. | ||
249 | * @return handle to the new monitoring client | ||
250 | */ | ||
251 | static struct MonitoringClient * | ||
252 | setup_monitoring_client (struct GNUNET_SERVER_Client *client, | ||
253 | struct GNUNET_PeerIdentity *peer) | ||
254 | { | ||
255 | struct MonitoringClient *mc; | ||
256 | |||
257 | GNUNET_assert (lookup_monitoring_client (client) == NULL); | ||
258 | mc = GNUNET_malloc (sizeof (struct MonitoringClient)); | ||
259 | mc->client = client; | ||
260 | mc->peer = *peer; | ||
261 | GNUNET_CONTAINER_DLL_insert (monitoring_clients_head, | ||
262 | monitoring_clients_tail, | ||
263 | mc); | ||
264 | GNUNET_SERVER_notification_context_add (nc, client); | ||
265 | |||
266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
267 | "Client %X started monitoring of the peer `%s'\n", | ||
268 | mc, GNUNET_i2s (peer)); | ||
269 | return mc; | ||
270 | } | ||
271 | |||
272 | |||
273 | /** | ||
174 | * Function called to notify a client about the socket being ready to | 274 | * Function called to notify a client about the socket being ready to |
175 | * queue more data. "buf" will be NULL and "size" zero if the socket | 275 | * queue more data. "buf" will be NULL and "size" zero if the socket |
176 | * was closed for writing in the meantime. | 276 | * was closed for writing in the meantime. |
@@ -287,10 +387,19 @@ static void | |||
287 | client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) | 387 | client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) |
288 | { | 388 | { |
289 | struct TransportClient *tc; | 389 | struct TransportClient *tc; |
390 | struct MonitoringClient *mc; | ||
290 | struct ClientMessageQueueEntry *mqe; | 391 | struct ClientMessageQueueEntry *mqe; |
291 | 392 | ||
292 | if (client == NULL) | 393 | if (client == NULL) |
293 | return; | 394 | return; |
395 | mc = lookup_monitoring_client (client); | ||
396 | if (mc != NULL) | ||
397 | { | ||
398 | GNUNET_CONTAINER_DLL_remove (monitoring_clients_head, | ||
399 | monitoring_clients_tail, | ||
400 | mc); | ||
401 | GNUNET_free (mc); | ||
402 | } | ||
294 | tc = lookup_client (client); | 403 | tc = lookup_client (client); |
295 | if (tc == NULL) | 404 | if (tc == NULL) |
296 | return; | 405 | return; |
@@ -690,6 +799,52 @@ clients_handle_address_to_string (void *cls, | |||
690 | 799 | ||
691 | 800 | ||
692 | /** | 801 | /** |
802 | * Compose AddressIterateResponseMessage using the given peer and address. | ||
803 | * | ||
804 | * @param peer identity of the peer | ||
805 | * @param address the address, NULL on disconnect | ||
806 | * @return composed message | ||
807 | */ | ||
808 | static struct AddressIterateResponseMessage * | ||
809 | compose_address_iterate_response_message (const struct GNUNET_PeerIdentity | ||
810 | *peer, | ||
811 | const struct GNUNET_HELLO_Address | ||
812 | *address) | ||
813 | { | ||
814 | struct AddressIterateResponseMessage *msg; | ||
815 | size_t size; | ||
816 | size_t tlen; | ||
817 | size_t alen; | ||
818 | char *addr; | ||
819 | |||
820 | GNUNET_assert (NULL != peer); | ||
821 | if (NULL != address) | ||
822 | { | ||
823 | tlen = strlen (address->transport_name) + 1; | ||
824 | alen = address->address_length; | ||
825 | } | ||
826 | else | ||
827 | tlen = alen = 0; | ||
828 | size = (sizeof (struct AddressIterateResponseMessage) + alen + tlen); | ||
829 | msg = GNUNET_malloc (size); | ||
830 | msg->header.size = htons (size); | ||
831 | msg->header.type = | ||
832 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE); | ||
833 | msg->reserved = htonl (0); | ||
834 | msg->peer = *peer; | ||
835 | msg->addrlen = htonl (alen); | ||
836 | msg->pluginlen = htonl (tlen); | ||
837 | if (NULL != address) | ||
838 | { | ||
839 | addr = (char *) &msg[1]; | ||
840 | memcpy (addr, address->address, alen); | ||
841 | memcpy (&addr[alen], address->transport_name, tlen); | ||
842 | } | ||
843 | return msg; | ||
844 | } | ||
845 | |||
846 | |||
847 | /** | ||
693 | * Output the active address of connected neighbours to the given client. | 848 | * Output the active address of connected neighbours to the given client. |
694 | * | 849 | * |
695 | * @param cls the 'struct GNUNET_SERVER_TransmitContext' for transmission to the client | 850 | * @param cls the 'struct GNUNET_SERVER_TransmitContext' for transmission to the client |
@@ -705,34 +860,10 @@ output_address (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
705 | { | 860 | { |
706 | struct GNUNET_SERVER_TransmitContext *tc = cls; | 861 | struct GNUNET_SERVER_TransmitContext *tc = cls; |
707 | struct AddressIterateResponseMessage *msg; | 862 | struct AddressIterateResponseMessage *msg; |
708 | size_t size; | ||
709 | size_t tlen; | ||
710 | size_t alen; | ||
711 | char *addr; | ||
712 | 863 | ||
713 | tlen = strlen (address->transport_name) + 1; | 864 | msg = compose_address_iterate_response_message (peer, address); |
714 | alen = address->address_length; | 865 | GNUNET_SERVER_transmit_context_append_message (tc, &msg->header); |
715 | size = (sizeof (struct AddressIterateResponseMessage) + alen + tlen); | 866 | GNUNET_free (msg); |
716 | { | ||
717 | char buf[size]; | ||
718 | |||
719 | msg = (struct AddressIterateResponseMessage *) buf; | ||
720 | msg->reserved = htonl (0); | ||
721 | msg->peer = *peer; | ||
722 | msg->addrlen = htonl (alen); | ||
723 | msg->pluginlen = htonl (tlen); | ||
724 | addr = (char *) &msg[1]; | ||
725 | memcpy (addr, address->address, alen); | ||
726 | memcpy (&addr[alen], address->transport_name, tlen); | ||
727 | GNUNET_SERVER_transmit_context_append_data (tc, | ||
728 | &buf[sizeof | ||
729 | (struct | ||
730 | GNUNET_MessageHeader)], | ||
731 | size - | ||
732 | sizeof (struct | ||
733 | GNUNET_MessageHeader), | ||
734 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE); | ||
735 | } | ||
736 | } | 867 | } |
737 | 868 | ||
738 | 869 | ||
@@ -753,6 +884,7 @@ clients_handle_address_iterate (void *cls, struct GNUNET_SERVER_Client *client, | |||
753 | struct GNUNET_SERVER_TransmitContext *tc; | 884 | struct GNUNET_SERVER_TransmitContext *tc; |
754 | struct AddressIterateMessage *msg; | 885 | struct AddressIterateMessage *msg; |
755 | struct GNUNET_HELLO_Address *address; | 886 | struct GNUNET_HELLO_Address *address; |
887 | struct MonitoringClient *mc; | ||
756 | 888 | ||
757 | if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE) | 889 | if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE) |
758 | { | 890 | { |
@@ -767,13 +899,6 @@ clients_handle_address_iterate (void *cls, struct GNUNET_SERVER_Client *client, | |||
767 | return; | 899 | return; |
768 | } | 900 | } |
769 | msg = (struct AddressIterateMessage *) message; | 901 | msg = (struct AddressIterateMessage *) message; |
770 | if (GNUNET_YES != ntohl (msg->one_shot)) | ||
771 | { | ||
772 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
773 | "Address monitoring not implemented\n"); | ||
774 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
775 | return; | ||
776 | } | ||
777 | GNUNET_SERVER_disable_receive_done_warning (client); | 902 | GNUNET_SERVER_disable_receive_done_warning (client); |
778 | tc = GNUNET_SERVER_transmit_context_create (client); | 903 | tc = GNUNET_SERVER_transmit_context_create (client); |
779 | if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity))) | 904 | if (0 == memcmp (&msg->peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity))) |
@@ -788,8 +913,24 @@ clients_handle_address_iterate (void *cls, struct GNUNET_SERVER_Client *client, | |||
788 | if (address != NULL) | 913 | if (address != NULL) |
789 | output_address (tc, &msg->peer, NULL, 0, address); | 914 | output_address (tc, &msg->peer, NULL, 0, address); |
790 | } | 915 | } |
916 | if (GNUNET_YES != ntohl (msg->one_shot)) | ||
917 | { | ||
918 | mc = lookup_monitoring_client (client); | ||
919 | if (mc != NULL) | ||
920 | { | ||
921 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | ||
922 | "ServerClient %X tried to start monitoring twice (MonitoringClient %X)\n", | ||
923 | client, mc); | ||
924 | GNUNET_break (0); | ||
925 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
926 | return; | ||
927 | } | ||
928 | setup_monitoring_client (client, &msg->peer); | ||
929 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
930 | return; | ||
931 | } | ||
791 | GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, | 932 | GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, |
792 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE); | 933 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE); |
793 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | 934 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); |
794 | } | 935 | } |
795 | 936 | ||
@@ -825,6 +966,7 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) | |||
825 | sizeof (struct BlacklistMessage)}, | 966 | sizeof (struct BlacklistMessage)}, |
826 | {NULL, NULL, 0, 0} | 967 | {NULL, NULL, 0, 0} |
827 | }; | 968 | }; |
969 | nc = GNUNET_SERVER_notification_context_create (server, 0); | ||
828 | GNUNET_SERVER_add_handlers (server, handlers); | 970 | GNUNET_SERVER_add_handlers (server, handlers); |
829 | GNUNET_SERVER_disconnect_notify (server, &client_disconnect_notification, | 971 | GNUNET_SERVER_disconnect_notify (server, &client_disconnect_notification, |
830 | NULL); | 972 | NULL); |
@@ -837,7 +979,11 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) | |||
837 | void | 979 | void |
838 | GST_clients_stop () | 980 | GST_clients_stop () |
839 | { | 981 | { |
840 | /* nothing to do */ | 982 | if (NULL != nc) |
983 | { | ||
984 | GNUNET_SERVER_notification_context_destroy (nc); | ||
985 | nc = NULL; | ||
986 | } | ||
841 | } | 987 | } |
842 | 988 | ||
843 | 989 | ||
@@ -881,4 +1027,39 @@ GST_clients_unicast (struct GNUNET_SERVER_Client *client, | |||
881 | } | 1027 | } |
882 | 1028 | ||
883 | 1029 | ||
1030 | /** | ||
1031 | * Broadcast the new active address to all clients monitoring the peer. | ||
1032 | * | ||
1033 | * @param peer peer this update is about (never NULL) | ||
1034 | * @param address address, NULL on disconnect | ||
1035 | */ | ||
1036 | void | ||
1037 | GST_clients_broadcast_address_notification (const struct GNUNET_PeerIdentity | ||
1038 | *peer, | ||
1039 | const struct GNUNET_HELLO_Address | ||
1040 | *address) | ||
1041 | { | ||
1042 | struct AddressIterateResponseMessage *msg; | ||
1043 | struct MonitoringClient *mc; | ||
1044 | static struct GNUNET_PeerIdentity all_zeros; | ||
1045 | |||
1046 | msg = compose_address_iterate_response_message (peer, address); | ||
1047 | mc = monitoring_clients_head; | ||
1048 | while (mc != NULL) | ||
1049 | { | ||
1050 | if ((0 == memcmp (&mc->peer, &all_zeros, | ||
1051 | sizeof (struct GNUNET_PeerIdentity))) || | ||
1052 | (0 == memcmp (&mc->peer, peer, | ||
1053 | sizeof (struct GNUNET_PeerIdentity)))) | ||
1054 | { | ||
1055 | GNUNET_SERVER_notification_context_unicast (nc, mc->client, | ||
1056 | &msg->header, GNUNET_NO); | ||
1057 | } | ||
1058 | |||
1059 | mc = mc->next; | ||
1060 | } | ||
1061 | GNUNET_free (msg); | ||
1062 | } | ||
1063 | |||
1064 | |||
884 | /* end of file gnunet-service-transport_clients.c */ | 1065 | /* end of file gnunet-service-transport_clients.c */ |
diff --git a/src/transport/gnunet-service-transport_clients.h b/src/transport/gnunet-service-transport_clients.h index d428fb257..9556620dd 100644 --- a/src/transport/gnunet-service-transport_clients.h +++ b/src/transport/gnunet-service-transport_clients.h | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "gnunet_statistics_service.h" | 29 | #include "gnunet_statistics_service.h" |
30 | #include "gnunet_util_lib.h" | 30 | #include "gnunet_util_lib.h" |
31 | #include "gnunet_hello_lib.h" | ||
31 | 32 | ||
32 | 33 | ||
33 | /** | 34 | /** |
@@ -68,6 +69,18 @@ GST_clients_unicast (struct GNUNET_SERVER_Client *client, | |||
68 | const struct GNUNET_MessageHeader *msg, int may_drop); | 69 | const struct GNUNET_MessageHeader *msg, int may_drop); |
69 | 70 | ||
70 | 71 | ||
72 | /** | ||
73 | * Broadcast the new active address to all clients monitoring the peer. | ||
74 | * | ||
75 | * @param peer peer this update is about (never NULL) | ||
76 | * @param address address, NULL on disconnect | ||
77 | */ | ||
78 | void | ||
79 | GST_clients_broadcast_address_notification (const struct GNUNET_PeerIdentity | ||
80 | *peer, | ||
81 | const struct GNUNET_HELLO_Address | ||
82 | *address); | ||
83 | |||
71 | 84 | ||
72 | #endif | 85 | #endif |
73 | /* end of file gnunet-service-transport_clients.h */ | 86 | /* end of file gnunet-service-transport_clients.h */ |
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 0f81ab7be..a6f42052c 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -357,7 +357,7 @@ struct NeighbourMapEntry | |||
357 | static struct GNUNET_CONTAINER_MultiHashMap *neighbours; | 357 | static struct GNUNET_CONTAINER_MultiHashMap *neighbours; |
358 | 358 | ||
359 | /** | 359 | /** |
360 | * Closure for connect_notify_cb and disconnect_notify_cb | 360 | * Closure for connect_notify_cb, disconnect_notify_cb and address_change_cb |
361 | */ | 361 | */ |
362 | static void *callback_cls; | 362 | static void *callback_cls; |
363 | 363 | ||
@@ -372,6 +372,11 @@ static GNUNET_TRANSPORT_NotifyConnect connect_notify_cb; | |||
372 | static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb; | 372 | static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb; |
373 | 373 | ||
374 | /** | 374 | /** |
375 | * Function to call when we changed an active address of a neighbour. | ||
376 | */ | ||
377 | static GNUNET_TRANSPORT_PeerIterateCallback address_change_cb; | ||
378 | |||
379 | /** | ||
375 | * counter for connected neighbours | 380 | * counter for connected neighbours |
376 | */ | 381 | */ |
377 | static int neighbours_connected; | 382 | static int neighbours_connected; |
@@ -492,9 +497,12 @@ reset_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
492 | static int | 497 | static int |
493 | change (struct NeighbourMapEntry *n, int state, int line) | 498 | change (struct NeighbourMapEntry *n, int state, int line) |
494 | { | 499 | { |
500 | int previous_state; | ||
495 | /* allowed transitions */ | 501 | /* allowed transitions */ |
496 | int allowed = GNUNET_NO; | 502 | int allowed = GNUNET_NO; |
497 | 503 | ||
504 | previous_state = n->state; | ||
505 | |||
498 | switch (n->state) | 506 | switch (n->state) |
499 | { | 507 | { |
500 | case S_NOT_CONNECTED: | 508 | case S_NOT_CONNECTED: |
@@ -584,7 +592,13 @@ change (struct NeighbourMapEntry *n, int state, int line) | |||
584 | GNUNET_assert (0); | 592 | GNUNET_assert (0); |
585 | } | 593 | } |
586 | 594 | ||
587 | 595 | if (NULL != address_change_cb) | |
596 | { | ||
597 | if (n->state == S_CONNECTED) | ||
598 | address_change_cb (callback_cls, &n->id, n->address); | ||
599 | else if (previous_state == S_CONNECTED) | ||
600 | address_change_cb (callback_cls, &n->id, NULL); | ||
601 | } | ||
588 | 602 | ||
589 | return GNUNET_OK; | 603 | return GNUNET_OK; |
590 | } | 604 | } |
@@ -839,14 +853,19 @@ transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
839 | * @param cls closure for callbacks | 853 | * @param cls closure for callbacks |
840 | * @param connect_cb function to call if we connect to a peer | 854 | * @param connect_cb function to call if we connect to a peer |
841 | * @param disconnect_cb function to call if we disconnect from a peer | 855 | * @param disconnect_cb function to call if we disconnect from a peer |
856 | * @param address_cb function to call if we change an active address | ||
857 | * of a neighbour | ||
842 | */ | 858 | */ |
843 | void | 859 | void |
844 | GST_neighbours_start (void *cls, GNUNET_TRANSPORT_NotifyConnect connect_cb, | 860 | GST_neighbours_start (void *cls, |
845 | GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb) | 861 | GNUNET_TRANSPORT_NotifyConnect connect_cb, |
862 | GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, | ||
863 | GNUNET_TRANSPORT_PeerIterateCallback address_cb) | ||
846 | { | 864 | { |
847 | callback_cls = cls; | 865 | callback_cls = cls; |
848 | connect_notify_cb = connect_cb; | 866 | connect_notify_cb = connect_cb; |
849 | disconnect_notify_cb = disconnect_cb; | 867 | disconnect_notify_cb = disconnect_cb; |
868 | address_change_cb = address_cb; | ||
850 | neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE); | 869 | neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE); |
851 | } | 870 | } |
852 | 871 | ||
@@ -1164,6 +1183,7 @@ GST_neighbours_stop () | |||
1164 | callback_cls = NULL; | 1183 | callback_cls = NULL; |
1165 | connect_notify_cb = NULL; | 1184 | connect_notify_cb = NULL; |
1166 | disconnect_notify_cb = NULL; | 1185 | disconnect_notify_cb = NULL; |
1186 | address_change_cb = NULL; | ||
1167 | } | 1187 | } |
1168 | 1188 | ||
1169 | struct ContinutionContext | 1189 | struct ContinutionContext |
@@ -1496,7 +1516,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, | |||
1496 | GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); | 1516 | GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); |
1497 | n->address_state = UNUSED; | 1517 | n->address_state = UNUSED; |
1498 | } | 1518 | } |
1499 | |||
1500 | } | 1519 | } |
1501 | 1520 | ||
1502 | /* set new address */ | 1521 | /* set new address */ |
@@ -1511,6 +1530,9 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, | |||
1511 | GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | 1530 | GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, |
1512 | &neighbour_timeout_task, n); | 1531 | &neighbour_timeout_task, n); |
1513 | 1532 | ||
1533 | if (NULL != address_change_cb && n->state == S_CONNECTED) | ||
1534 | address_change_cb (callback_cls, &n->id, n->address); | ||
1535 | |||
1514 | #if TEST_NEW_CODE | 1536 | #if TEST_NEW_CODE |
1515 | /* Obtain an session for this address from plugin */ | 1537 | /* Obtain an session for this address from plugin */ |
1516 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | 1538 | struct GNUNET_TRANSPORT_PluginFunctions *papi; |
diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h index 425274f79..f6e599db1 100644 --- a/src/transport/gnunet-service-transport_neighbours.h +++ b/src/transport/gnunet-service-transport_neighbours.h | |||
@@ -42,10 +42,13 @@ | |||
42 | * @param cls closure for callbacks | 42 | * @param cls closure for callbacks |
43 | * @param connect_cb function to call if we connect to a peer | 43 | * @param connect_cb function to call if we connect to a peer |
44 | * @param disconnect_cb function to call if we disconnect from a peer | 44 | * @param disconnect_cb function to call if we disconnect from a peer |
45 | * @param peer_address_cb function to call if a neighbour's active address changes | ||
45 | */ | 46 | */ |
46 | void | 47 | void |
47 | GST_neighbours_start (void *cls, GNUNET_TRANSPORT_NotifyConnect connect_cb, | 48 | GST_neighbours_start (void *cls, |
48 | GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb); | 49 | GNUNET_TRANSPORT_NotifyConnect connect_cb, |
50 | GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb, | ||
51 | GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb); | ||
49 | 52 | ||
50 | 53 | ||
51 | /** | 54 | /** |
diff --git a/src/transport/transport_api_address_lookup.c b/src/transport/transport_api_address_lookup.c index 9ae9b4031..a21daab5e 100644 --- a/src/transport/transport_api_address_lookup.c +++ b/src/transport/transport_api_address_lookup.c | |||
@@ -103,9 +103,7 @@ peer_address_response_processor (void *cls, | |||
103 | return; | 103 | return; |
104 | } | 104 | } |
105 | 105 | ||
106 | if ((size < | 106 | if ((size < sizeof (struct AddressIterateResponseMessage)) || |
107 | sizeof (struct GNUNET_MessageHeader) + | ||
108 | sizeof (struct AddressIterateResponseMessage)) || | ||
109 | (ntohs (msg->type) != | 107 | (ntohs (msg->type) != |
110 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE)) | 108 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE_RESPONSE)) |
111 | { | 109 | { |
@@ -127,28 +125,35 @@ peer_address_response_processor (void *cls, | |||
127 | return; | 125 | return; |
128 | } | 126 | } |
129 | 127 | ||
130 | addr = (const char *) &air_msg[1]; | 128 | if (alen == 0 && tlen == 0) |
131 | transport_name = &addr[alen]; | ||
132 | |||
133 | if (transport_name[tlen - 1] != '\0') | ||
134 | { | 129 | { |
135 | GNUNET_break_op (0); | 130 | pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, NULL); |
136 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL); | 131 | } |
137 | GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx); | 132 | else |
138 | return; | 133 | { |
134 | addr = (const char *) &air_msg[1]; | ||
135 | transport_name = &addr[alen]; | ||
136 | |||
137 | if (transport_name[tlen - 1] != '\0') | ||
138 | { | ||
139 | GNUNET_break_op (0); | ||
140 | pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL); | ||
141 | GNUNET_TRANSPORT_peer_get_active_addresses_cancel (pal_ctx); | ||
142 | return; | ||
143 | } | ||
144 | |||
145 | /* notify client */ | ||
146 | address = | ||
147 | GNUNET_HELLO_address_allocate (&air_msg->peer, transport_name, addr, | ||
148 | alen); | ||
149 | pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, address); | ||
150 | GNUNET_HELLO_address_free (address); | ||
139 | } | 151 | } |
140 | 152 | ||
141 | /* expect more replies */ | 153 | /* expect more replies */ |
142 | GNUNET_CLIENT_receive (pal_ctx->client, &peer_address_response_processor, | 154 | GNUNET_CLIENT_receive (pal_ctx->client, &peer_address_response_processor, |
143 | pal_ctx, | 155 | pal_ctx, |
144 | GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout)); | 156 | GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout)); |
145 | |||
146 | /* notify client */ | ||
147 | address = | ||
148 | GNUNET_HELLO_address_allocate (&air_msg->peer, transport_name, addr, | ||
149 | alen); | ||
150 | pal_ctx->cb (pal_ctx->cb_cls, &air_msg->peer, address); | ||
151 | GNUNET_HELLO_address_free (address); | ||
152 | } | 157 | } |
153 | 158 | ||
154 | 159 | ||
@@ -165,7 +170,7 @@ peer_address_response_processor (void *cls, | |||
165 | * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers | 170 | * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers |
166 | * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), | 171 | * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), |
167 | * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly cancelled) | 172 | * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly cancelled) |
168 | * @param timeout how long is the lookup allowed to take at most | 173 | * @param timeout how long is the lookup allowed to take at most (irrelevant if one_shot is set to GNUNET_NO) |
169 | * @param peer_address_callback function to call with the results | 174 | * @param peer_address_callback function to call with the results |
170 | * @param peer_address_callback_cls closure for peer_address_callback | 175 | * @param peer_address_callback_cls closure for peer_address_callback |
171 | */ | 176 | */ |
@@ -184,15 +189,11 @@ GNUNET_TRANSPORT_peer_get_active_addresses (const struct | |||
184 | struct GNUNET_CLIENT_Connection *client; | 189 | struct GNUNET_CLIENT_Connection *client; |
185 | struct GNUNET_TIME_Absolute abs_timeout; | 190 | struct GNUNET_TIME_Absolute abs_timeout; |
186 | 191 | ||
187 | if (GNUNET_YES != one_shot) | ||
188 | { | ||
189 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
190 | "Address monitoring not implemented\n"); | ||
191 | return NULL; | ||
192 | } | ||
193 | client = GNUNET_CLIENT_connect ("transport", cfg); | 192 | client = GNUNET_CLIENT_connect ("transport", cfg); |
194 | if (client == NULL) | 193 | if (client == NULL) |
195 | return NULL; | 194 | return NULL; |
195 | if (GNUNET_YES != one_shot) | ||
196 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
196 | abs_timeout = GNUNET_TIME_relative_to_absolute (timeout); | 197 | abs_timeout = GNUNET_TIME_relative_to_absolute (timeout); |
197 | msg.header.size = htons (sizeof (struct AddressIterateMessage)); | 198 | msg.header.size = htons (sizeof (struct AddressIterateMessage)); |
198 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE); | 199 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_ITERATE); |