aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-02-06 09:35:56 +0000
committerChristian Grothoff <christian@grothoff.org>2012-02-06 09:35:56 +0000
commit7e599b44d257d9d9c6100e4050dc1eb09c9e13d2 (patch)
tree6f63e09cf3a296d4daf6135077b58a9006e564e9 /src/transport
parentdc0da555fd351b2a96bca0a6494e83f0643fac31 (diff)
downloadgnunet-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.c23
-rw-r--r--src/transport/gnunet-service-transport_clients.c253
-rw-r--r--src/transport/gnunet-service-transport_clients.h13
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c32
-rw-r--r--src/transport/gnunet-service-transport_neighbours.h7
-rw-r--r--src/transport/transport_api_address_lookup.c51
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 */
504static void
505neighbours_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 */
122struct 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 */
122static struct TransportClient *clients_head; 151static struct TransportClient *clients_head;
@@ -127,6 +156,23 @@ static struct TransportClient *clients_head;
127static struct TransportClient *clients_tail; 156static struct TransportClient *clients_tail;
128 157
129/** 158/**
159 * Head of linked list of monitoring clients.
160 */
161static struct MonitoringClient *monitoring_clients_head;
162
163/**
164 * Tail of linked list of monitoring clients.
165 */
166static struct MonitoringClient *monitoring_clients_tail;
167
168/**
169 * Notification context, to send updates on changes to active addresses
170 * of our neighbours.
171 */
172struct 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 */
226static struct MonitoringClient *
227lookup_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 */
251static struct MonitoringClient *
252setup_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
287client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) 387client_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 */
808static struct AddressIterateResponseMessage *
809compose_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)
837void 979void
838GST_clients_stop () 980GST_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 */
1036void
1037GST_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 */
78void
79GST_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
357static struct GNUNET_CONTAINER_MultiHashMap *neighbours; 357static 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 */
362static void *callback_cls; 362static void *callback_cls;
363 363
@@ -372,6 +372,11 @@ static GNUNET_TRANSPORT_NotifyConnect connect_notify_cb;
372static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb; 372static GNUNET_TRANSPORT_NotifyDisconnect disconnect_notify_cb;
373 373
374/** 374/**
375 * Function to call when we changed an active address of a neighbour.
376 */
377static GNUNET_TRANSPORT_PeerIterateCallback address_change_cb;
378
379/**
375 * counter for connected neighbours 380 * counter for connected neighbours
376 */ 381 */
377static int neighbours_connected; 382static int neighbours_connected;
@@ -492,9 +497,12 @@ reset_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
492static int 497static int
493change (struct NeighbourMapEntry *n, int state, int line) 498change (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 */
843void 859void
844GST_neighbours_start (void *cls, GNUNET_TRANSPORT_NotifyConnect connect_cb, 860GST_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
1169struct ContinutionContext 1189struct 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 */
46void 47void
47GST_neighbours_start (void *cls, GNUNET_TRANSPORT_NotifyConnect connect_cb, 48GST_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);