aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/Makefile.am3
-rw-r--r--src/transport/gnunet-service-transport_clients.c27
-rw-r--r--src/transport/plugin_transport_http_client.c20
-rw-r--r--src/transport/plugin_transport_http_server.c19
-rw-r--r--src/transport/plugin_transport_tcp.c123
-rw-r--r--src/transport/plugin_transport_udp.c27
-rw-r--r--src/transport/plugin_transport_unix.c21
-rw-r--r--src/transport/plugin_transport_wlan.c10
-rw-r--r--src/transport/transport.h5
-rw-r--r--src/transport/transport_api_monitor_peers.c6
-rw-r--r--src/transport/transport_api_monitor_plugins.c434
11 files changed, 611 insertions, 84 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 83e820012..6866ea0ee 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -95,7 +95,7 @@ endif
95if LINUX 95if LINUX
96install-exec-hook: 96install-exec-hook:
97 $(top_srcdir)/src/transport/install-wlan-helper.sh $(libexecdir) $(SUDO_BINARY) || true 97 $(top_srcdir)/src/transport/install-wlan-helper.sh $(libexecdir) $(SUDO_BINARY) || true
98if HAVE_LIBBLUETOOTH 98if HAVE_LIBBLUETOOTH
99 $(top_srcdir)/src/transport/install-bluetooth-helper.sh $(libexecdir) $(SUDO_BINARY) || true 99 $(top_srcdir)/src/transport/install-bluetooth-helper.sh $(libexecdir) $(SUDO_BINARY) || true
100endif 100endif
101else 101else
@@ -164,6 +164,7 @@ libgnunettransport_la_SOURCES = \
164 transport_api_blacklist.c \ 164 transport_api_blacklist.c \
165 transport_api_address_to_string.c \ 165 transport_api_address_to_string.c \
166 transport_api_monitor_peers.c \ 166 transport_api_monitor_peers.c \
167 transport_api_monitor_plugins.c \
167 transport_api_monitor_validation.c 168 transport_api_monitor_validation.c
168libgnunettransport_la_LIBADD = \ 169libgnunettransport_la_LIBADD = \
169 $(top_builddir)/src/hello/libgnunethello.la \ 170 $(top_builddir)/src/hello/libgnunethello.la \
diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c
index b67d432c5..df73affc2 100644
--- a/src/transport/gnunet-service-transport_clients.c
+++ b/src/transport/gnunet-service-transport_clients.c
@@ -117,6 +117,7 @@ struct TransportClient
117 int send_payload; 117 int send_payload;
118}; 118};
119 119
120
120/** 121/**
121 * Context for address to string operations 122 * Context for address to string operations
122 */ 123 */
@@ -138,6 +139,7 @@ struct AddressToStringContext
138 struct GNUNET_SERVER_TransmitContext* tc; 139 struct GNUNET_SERVER_TransmitContext* tc;
139}; 140};
140 141
142
141/** 143/**
142 * Client monitoring changes of active addresses of our neighbours. 144 * Client monitoring changes of active addresses of our neighbours.
143 */ 145 */
@@ -225,6 +227,7 @@ static struct GNUNET_SERVER_NotificationContext *val_nc;
225 */ 227 */
226static struct GNUNET_SERVER_NotificationContext *plugin_nc; 228static struct GNUNET_SERVER_NotificationContext *plugin_nc;
227 229
230
228/** 231/**
229 * Find the internal handle associated with the given client handle 232 * Find the internal handle associated with the given client handle
230 * 233 *
@@ -306,6 +309,7 @@ setup_peer_monitoring_client (struct GNUNET_SERVER_Client *client,
306 mc->client = client; 309 mc->client = client;
307 mc->peer = *peer; 310 mc->peer = *peer;
308 GNUNET_CONTAINER_DLL_insert (peer_monitoring_clients_head, peer_monitoring_clients_tail, mc); 311 GNUNET_CONTAINER_DLL_insert (peer_monitoring_clients_head, peer_monitoring_clients_tail, mc);
312 GNUNET_SERVER_client_mark_monitor (client);
309 GNUNET_SERVER_notification_context_add (peer_nc, client); 313 GNUNET_SERVER_notification_context_add (peer_nc, client);
310 314
311 if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity))) 315 if (0 != memcmp (peer, &all_zeros, sizeof (struct GNUNET_PeerIdentity)))
@@ -635,7 +639,7 @@ clients_handle_hello (void *cls, struct GNUNET_SERVER_Client *client,
635 639
636 640
637/** 641/**
638 * Closure for 'handle_send_transmit_continuation' 642 * Closure for #handle_send_transmit_continuation()
639 */ 643 */
640struct SendTransmitContinuationContext 644struct SendTransmitContinuationContext
641{ 645{
@@ -1068,6 +1072,7 @@ compose_address_iterate_response_message (const struct GNUNET_PeerIdentity *peer
1068 return msg; 1072 return msg;
1069} 1073}
1070 1074
1075
1071/** 1076/**
1072 * Compose #PeerIterateResponseMessage using the given peer and address. 1077 * Compose #PeerIterateResponseMessage using the given peer and address.
1073 * 1078 *
@@ -1077,7 +1082,7 @@ compose_address_iterate_response_message (const struct GNUNET_PeerIdentity *peer
1077 */ 1082 */
1078static struct ValidationIterateResponseMessage * 1083static struct ValidationIterateResponseMessage *
1079compose_validation_iterate_response_message (const struct GNUNET_PeerIdentity *peer, 1084compose_validation_iterate_response_message (const struct GNUNET_PeerIdentity *peer,
1080 const struct GNUNET_HELLO_Address *address) 1085 const struct GNUNET_HELLO_Address *address)
1081{ 1086{
1082 struct ValidationIterateResponseMessage *msg; 1087 struct ValidationIterateResponseMessage *msg;
1083 size_t size; 1088 size_t size;
@@ -1113,12 +1118,26 @@ compose_validation_iterate_response_message (const struct GNUNET_PeerIdentity *p
1113 return msg; 1118 return msg;
1114} 1119}
1115 1120
1121
1122/**
1123 * Context for #send_validation_information() and
1124 * #send_peer_information().
1125 */
1116struct IterationContext 1126struct IterationContext
1117{ 1127{
1128 /**
1129 * Context to use for the transmission.
1130 */
1118 struct GNUNET_SERVER_TransmitContext *tc; 1131 struct GNUNET_SERVER_TransmitContext *tc;
1119 1132
1133 /**
1134 * Which peers do we care about?
1135 */
1120 struct GNUNET_PeerIdentity id; 1136 struct GNUNET_PeerIdentity id;
1121 1137
1138 /**
1139 * #GNUNET_YES if @e id should be ignored because we want all peers.
1140 */
1122 int all; 1141 int all;
1123}; 1142};
1124 1143
@@ -1245,6 +1264,7 @@ clients_handle_monitor_peers (void *cls, struct GNUNET_SERVER_Client *client,
1245 return; 1264 return;
1246 } 1265 }
1247 GNUNET_SERVER_disable_receive_done_warning (client); 1266 GNUNET_SERVER_disable_receive_done_warning (client);
1267 GNUNET_SERVER_client_mark_monitor (client);
1248 pc.tc = tc = GNUNET_SERVER_transmit_context_create (client); 1268 pc.tc = tc = GNUNET_SERVER_transmit_context_create (client);
1249 1269
1250 /* Send initial list */ 1270 /* Send initial list */
@@ -1318,6 +1338,7 @@ clients_handle_monitor_validation (void *cls,
1318 return; 1338 return;
1319 } 1339 }
1320 GNUNET_SERVER_disable_receive_done_warning (client); 1340 GNUNET_SERVER_disable_receive_done_warning (client);
1341 GNUNET_SERVER_client_mark_monitor (client);
1321 pc.tc = tc = GNUNET_SERVER_transmit_context_create (client); 1342 pc.tc = tc = GNUNET_SERVER_transmit_context_create (client);
1322 1343
1323 /* Send initial list */ 1344 /* Send initial list */
@@ -1396,6 +1417,7 @@ plugin_session_info_cb (void *cls,
1396 msg->timeout = GNUNET_TIME_absolute_hton (info->session_timeout); 1417 msg->timeout = GNUNET_TIME_absolute_hton (info->session_timeout);
1397 msg->delay = GNUNET_TIME_absolute_hton (info->receive_delay); 1418 msg->delay = GNUNET_TIME_absolute_hton (info->receive_delay);
1398 msg->peer = info->address->peer; 1419 msg->peer = info->address->peer;
1420 msg->session_id = (uint64_t) (intptr_t) session;
1399 msg->plugin_name_len = htons (slen); 1421 msg->plugin_name_len = htons (slen);
1400 msg->plugin_address_len = htons (alen); 1422 msg->plugin_address_len = htons (alen);
1401 name = (char *) &msg[1]; 1423 name = (char *) &msg[1];
@@ -1421,6 +1443,7 @@ clients_handle_monitor_plugins (void *cls,
1421 struct GNUNET_SERVER_Client *client, 1443 struct GNUNET_SERVER_Client *client,
1422 const struct GNUNET_MessageHeader *message) 1444 const struct GNUNET_MessageHeader *message)
1423{ 1445{
1446 GNUNET_SERVER_client_mark_monitor (client);
1424 GNUNET_SERVER_disable_receive_done_warning (client); 1447 GNUNET_SERVER_disable_receive_done_warning (client);
1425 if (0 == GNUNET_SERVER_notification_context_get_size (plugin_nc)) 1448 if (0 == GNUNET_SERVER_notification_context_get_size (plugin_nc))
1426 GST_plugins_monitor_subscribe (&plugin_session_info_cb, NULL); 1449 GST_plugins_monitor_subscribe (&plugin_session_info_cb, NULL);
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c
index 615639a6e..adb83c719 100644
--- a/src/transport/plugin_transport_http_client.c
+++ b/src/transport/plugin_transport_http_client.c
@@ -519,7 +519,7 @@ client_delete_session (struct Session *s)
519 GNUNET_assert (0 == s->bytes_in_queue); 519 GNUNET_assert (0 == s->bytes_in_queue);
520 notify_session_monitor (plugin, 520 notify_session_monitor (plugin,
521 s, 521 s,
522 GNUNET_TRANSPORT_SS_DOWN); 522 GNUNET_TRANSPORT_SS_DONE);
523 if (NULL != s->msg_tk) 523 if (NULL != s->msg_tk)
524 { 524 {
525 GNUNET_SERVER_mst_destroy (s->msg_tk); 525 GNUNET_SERVER_mst_destroy (s->msg_tk);
@@ -778,7 +778,7 @@ http_client_plugin_send (void *cls,
778 GNUNET_free (stat_txt); 778 GNUNET_free (stat_txt);
779 notify_session_monitor (plugin, 779 notify_session_monitor (plugin,
780 s, 780 s,
781 GNUNET_TRANSPORT_SS_UP); 781 GNUNET_TRANSPORT_SS_UPDATE);
782 if (H_TMP_DISCONNECTING == s->put.state) 782 if (H_TMP_DISCONNECTING == s->put.state)
783 { 783 {
784 /* PUT request is currently getting disconnected */ 784 /* PUT request is currently getting disconnected */
@@ -1078,7 +1078,7 @@ client_send_cb (void *stream,
1078 } 1078 }
1079 notify_session_monitor (plugin, 1079 notify_session_monitor (plugin,
1080 s, 1080 s,
1081 GNUNET_TRANSPORT_SS_UP); 1081 GNUNET_TRANSPORT_SS_UPDATE);
1082 GNUNET_asprintf (&stat_txt, 1082 GNUNET_asprintf (&stat_txt,
1083 "# bytes currently in %s_client buffers", 1083 "# bytes currently in %s_client buffers",
1084 plugin->protocol); 1084 plugin->protocol);
@@ -1741,7 +1741,7 @@ client_session_timeout (void *cls,
1741 the monitor, it may think we're about to die ... */ 1741 the monitor, it may think we're about to die ... */
1742 notify_session_monitor (s->plugin, 1742 notify_session_monitor (s->plugin,
1743 s, 1743 s,
1744 GNUNET_TRANSPORT_SS_UP); 1744 GNUNET_TRANSPORT_SS_UPDATE);
1745 s->timeout_task = GNUNET_SCHEDULER_add_delayed (left, 1745 s->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
1746 &client_session_timeout, 1746 &client_session_timeout,
1747 s); 1747 s);
@@ -1860,7 +1860,12 @@ http_client_plugin_get_session (void *cls,
1860 client_delete_session (s); 1860 client_delete_session (s);
1861 return NULL; 1861 return NULL;
1862 } 1862 }
1863 notify_session_monitor (plugin, s, GNUNET_TRANSPORT_SS_UP); /* or handshake? */ 1863 notify_session_monitor (plugin,
1864 s,
1865 GNUNET_TRANSPORT_SS_INIT);
1866 notify_session_monitor (plugin,
1867 s,
1868 GNUNET_TRANSPORT_SS_UP); /* or handshake? */
1864 return s; 1869 return s;
1865} 1870}
1866 1871
@@ -2162,7 +2167,10 @@ send_session_info_iter (void *cls,
2162 2167
2163 notify_session_monitor (plugin, 2168 notify_session_monitor (plugin,
2164 session, 2169 session,
2165 GNUNET_TRANSPORT_SS_UP); 2170 GNUNET_TRANSPORT_SS_INIT);
2171 notify_session_monitor (plugin,
2172 session,
2173 GNUNET_TRANSPORT_SS_UP); /* FIXME: or handshake? */
2166 return GNUNET_OK; 2174 return GNUNET_OK;
2167} 2175}
2168 2176
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index c7a1bfe7a..47b0bda7f 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -598,11 +598,13 @@ server_delete_session (struct Session *s)
598 } 598 }
599 notify_session_monitor (plugin, 599 notify_session_monitor (plugin,
600 s, 600 s,
601 GNUNET_TRANSPORT_SS_DOWN); 601 GNUNET_TRANSPORT_SS_DONE);
602 if (GNUNET_YES == s->known_to_service) 602 if (GNUNET_YES == s->known_to_service)
603 {
603 plugin->env->session_end (plugin->env->cls, 604 plugin->env->session_end (plugin->env->cls,
604 s->address, 605 s->address,
605 s); 606 s);
607 }
606 if (NULL != s->msg_tk) 608 if (NULL != s->msg_tk)
607 { 609 {
608 GNUNET_SERVER_mst_destroy (s->msg_tk); 610 GNUNET_SERVER_mst_destroy (s->msg_tk);
@@ -1461,6 +1463,9 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1461 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1463 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1462 notify_session_monitor (plugin, 1464 notify_session_monitor (plugin,
1463 s, 1465 s,
1466 GNUNET_TRANSPORT_SS_INIT);
1467 notify_session_monitor (plugin,
1468 s,
1464 GNUNET_TRANSPORT_SS_HANDSHAKE); 1469 GNUNET_TRANSPORT_SS_HANDSHAKE);
1465 LOG (GNUNET_ERROR_TYPE_DEBUG, 1470 LOG (GNUNET_ERROR_TYPE_DEBUG,
1466 "Creating new session %p for peer `%s' connecting from `%s'\n", 1471 "Creating new session %p for peer `%s' connecting from `%s'\n",
@@ -1512,7 +1517,13 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1512 (NULL != s->server_recv) ) 1517 (NULL != s->server_recv) )
1513 { 1518 {
1514 s->known_to_service = GNUNET_YES; 1519 s->known_to_service = GNUNET_YES;
1515 plugin->env->session_start (NULL, s->address ,s, NULL, 0); 1520 notify_session_monitor (plugin,
1521 s,
1522 GNUNET_TRANSPORT_SS_UP);
1523 plugin->env->session_start (NULL,
1524 s->address,
1525 s,
1526 NULL, 0);
1516 } 1527 }
1517 1528
1518 if ( (NULL == s->server_recv) || 1529 if ( (NULL == s->server_recv) ||
@@ -1592,7 +1603,7 @@ server_send_callback (void *cls,
1592 GNUNET_free (msg); 1603 GNUNET_free (msg);
1593 notify_session_monitor (s->plugin, 1604 notify_session_monitor (s->plugin,
1594 s, 1605 s,
1595 GNUNET_TRANSPORT_SS_UP); 1606 GNUNET_TRANSPORT_SS_UPDATE);
1596 } 1607 }
1597 } 1608 }
1598 if (0 < bytes_read) 1609 if (0 < bytes_read)
@@ -3298,7 +3309,7 @@ send_session_info_iter (void *cls,
3298 3309
3299 notify_session_monitor (plugin, 3310 notify_session_monitor (plugin,
3300 session, 3311 session,
3301 GNUNET_TRANSPORT_SS_UP); 3312 GNUNET_TRANSPORT_SS_INIT);
3302 return GNUNET_OK; 3313 return GNUNET_OK;
3303} 3314}
3304 3315
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index 310ac3483..4c2691e09 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -885,7 +885,7 @@ tcp_plugin_disconnect_session (void *cls,
885 GNUNET_assert (0 == session->bytes_in_queue); 885 GNUNET_assert (0 == session->bytes_in_queue);
886 notify_session_monitor (session->plugin, 886 notify_session_monitor (session->plugin,
887 session, 887 session,
888 GNUNET_TRANSPORT_SS_UP); 888 GNUNET_TRANSPORT_SS_DONE);
889 889
890 if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK) 890 if (session->receive_delay_task != GNUNET_SCHEDULER_NO_TASK)
891 { 891 {
@@ -942,7 +942,7 @@ session_timeout (void *cls,
942 the monitor, it may think we're about to die ... */ 942 the monitor, it may think we're about to die ... */
943 notify_session_monitor (s->plugin, 943 notify_session_monitor (s->plugin,
944 s, 944 s,
945 GNUNET_TRANSPORT_SS_UP); 945 GNUNET_TRANSPORT_SS_UPDATE);
946 s->timeout_task = GNUNET_SCHEDULER_add_delayed (left, 946 s->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
947 &session_timeout, 947 &session_timeout,
948 s); 948 s);
@@ -1030,6 +1030,9 @@ create_session (struct Plugin *plugin,
1030 session->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 1030 session->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1031 &session_timeout, 1031 &session_timeout,
1032 session); 1032 session);
1033 notify_session_monitor (session->plugin,
1034 session,
1035 GNUNET_TRANSPORT_SS_INIT);
1033 if (GNUNET_YES != is_nat) 1036 if (GNUNET_YES != is_nat)
1034 { 1037 {
1035 GNUNET_STATISTICS_update (plugin->env->stats, 1038 GNUNET_STATISTICS_update (plugin->env->stats,
@@ -1144,7 +1147,7 @@ do_transmit (void *cls, size_t size, void *buf)
1144 if (0 < ret) 1147 if (0 < ret)
1145 notify_session_monitor (session->plugin, 1148 notify_session_monitor (session->plugin,
1146 session, 1149 session,
1147 GNUNET_TRANSPORT_SS_UP); 1150 GNUNET_TRANSPORT_SS_UPDATE);
1148 return 0; 1151 return 0;
1149 } 1152 }
1150 /* copy all pending messages that would fit */ 1153 /* copy all pending messages that would fit */
@@ -1177,7 +1180,7 @@ do_transmit (void *cls, size_t size, void *buf)
1177 } 1180 }
1178 notify_session_monitor (session->plugin, 1181 notify_session_monitor (session->plugin,
1179 session, 1182 session,
1180 GNUNET_TRANSPORT_SS_UP); 1183 GNUNET_TRANSPORT_SS_UPDATE);
1181 /* schedule 'continuation' before callbacks so that callbacks that 1184 /* schedule 'continuation' before callbacks so that callbacks that
1182 * cancel everything don't cause us to use a session that no longer 1185 * cancel everything don't cause us to use a session that no longer
1183 * exists... */ 1186 * exists... */
@@ -1310,7 +1313,7 @@ tcp_plugin_send (void *cls,
1310 pm); 1313 pm);
1311 notify_session_monitor (session->plugin, 1314 notify_session_monitor (session->plugin,
1312 session, 1315 session,
1313 GNUNET_TRANSPORT_SS_UP); 1316 GNUNET_TRANSPORT_SS_UPDATE);
1314 session->msgs_in_queue++; 1317 session->msgs_in_queue++;
1315 session->bytes_in_queue += pm->message_size; 1318 session->bytes_in_queue += pm->message_size;
1316 process_pending_messages (session); 1319 process_pending_messages (session);
@@ -1410,12 +1413,12 @@ nat_connect_timeout (void *cls,
1410 struct Session *session = cls; 1413 struct Session *session = cls;
1411 1414
1412 session->nat_connection_timeout = GNUNET_SCHEDULER_NO_TASK; 1415 session->nat_connection_timeout = GNUNET_SCHEDULER_NO_TASK;
1413 LOG(GNUNET_ERROR_TYPE_DEBUG, 1416 LOG (GNUNET_ERROR_TYPE_DEBUG,
1414 "NAT WAIT connection to `%4s' at `%s' could not be established, removing session\n", 1417 "NAT WAIT connection to `%4s' at `%s' could not be established, removing session\n",
1415 GNUNET_i2s (&session->target), 1418 GNUNET_i2s (&session->target),
1416 tcp_plugin_address_to_string (NULL, 1419 tcp_plugin_address_to_string (NULL,
1417 session->address->address, 1420 session->address->address,
1418 session->address->address_length)); 1421 session->address->address_length));
1419 tcp_plugin_disconnect_session (session->plugin, 1422 tcp_plugin_disconnect_session (session->plugin,
1420 session); 1423 session);
1421} 1424}
@@ -1632,24 +1635,30 @@ tcp_plugin_get_session (void *cls,
1632 &address->peer))) 1635 &address->peer)))
1633 { 1636 {
1634 LOG (GNUNET_ERROR_TYPE_DEBUG, 1637 LOG (GNUNET_ERROR_TYPE_DEBUG,
1635 "Found valid IPv4 NAT address (creating session)!\n"); 1638 "Found valid IPv4 NAT address (creating session)!\n");
1636 session = create_session (plugin, address, NULL, GNUNET_YES); 1639 session = create_session (plugin,
1637 session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl ( 1640 address,
1638 ats.value); 1641 NULL,
1639 GNUNET_break( 1642 GNUNET_YES);
1640 session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); 1643 session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl (ats.value);
1644 GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED);
1641 session->nat_connection_timeout = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT, 1645 session->nat_connection_timeout = GNUNET_SCHEDULER_add_delayed (NAT_TIMEOUT,
1642 &nat_connect_timeout, session); 1646 &nat_connect_timeout,
1643 GNUNET_assert(session != NULL); 1647 session);
1644 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (plugin->nat_wait_conns, 1648 GNUNET_assert(GNUNET_OK ==
1645 &session->target, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1649 GNUNET_CONTAINER_multipeermap_put (plugin->nat_wait_conns,
1646 1650 &session->target,
1647 LOG(GNUNET_ERROR_TYPE_DEBUG, 1651 session,
1648 "Created NAT WAIT connection to `%4s' at `%s'\n", 1652 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1649 GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs));
1650 1653
1654 LOG (GNUNET_ERROR_TYPE_DEBUG,
1655 "Created NAT WAIT connection to `%4s' at `%s'\n",
1656 GNUNET_i2s (&session->target),
1657 GNUNET_a2s (sb, sbs));
1651 if (GNUNET_OK == GNUNET_NAT_run_client (plugin->nat, &a4)) 1658 if (GNUNET_OK == GNUNET_NAT_run_client (plugin->nat, &a4))
1659 {
1652 return session; 1660 return session;
1661 }
1653 else 1662 else
1654 { 1663 {
1655 LOG(GNUNET_ERROR_TYPE_DEBUG, 1664 LOG(GNUNET_ERROR_TYPE_DEBUG,
@@ -1714,24 +1723,28 @@ tcp_plugin_get_session (void *cls,
1714 if (plugin->cur_connections == plugin->max_connections) 1723 if (plugin->cur_connections == plugin->max_connections)
1715 GNUNET_SERVER_suspend (plugin->server); /* Maximum number of connections rechead */ 1724 GNUNET_SERVER_suspend (plugin->server); /* Maximum number of connections rechead */
1716 1725
1717 LOG(GNUNET_ERROR_TYPE_DEBUG, 1726 LOG (GNUNET_ERROR_TYPE_DEBUG,
1718 "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", 1727 "Asked to transmit to `%4s', creating fresh session using address `%s'.\n",
1719 GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); 1728 GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs));
1720 1729
1721 session = create_session (plugin, address, 1730 session = create_session (plugin,
1731 address,
1722 GNUNET_SERVER_connect_socket (plugin->server, sa), 1732 GNUNET_SERVER_connect_socket (plugin->server, sa),
1723 GNUNET_NO); 1733 GNUNET_NO);
1724 session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl ( 1734 session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl (ats.value);
1725 ats.value); 1735 GNUNET_break (session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED);
1726 GNUNET_break(session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED);
1727 GNUNET_SERVER_client_set_user_context(session->client, session); 1736 GNUNET_SERVER_client_set_user_context(session->client, session);
1728 GNUNET_CONTAINER_multipeermap_put (plugin->sessionmap, &session->target, 1737 GNUNET_CONTAINER_multipeermap_put (plugin->sessionmap,
1729 session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1738 &session->target,
1730 LOG(GNUNET_ERROR_TYPE_DEBUG, 1739 session,
1731 "Creating new session for `%s' address `%s' session %p\n", 1740 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1732 GNUNET_i2s (&address->peer), 1741 LOG (GNUNET_ERROR_TYPE_DEBUG,
1733 tcp_plugin_address_to_string(NULL, address->address, address->address_length), 1742 "Creating new session for `%s' address `%s' session %p\n",
1734 session); 1743 GNUNET_i2s (&address->peer),
1744 tcp_plugin_address_to_string (NULL,
1745 address->address,
1746 address->address_length),
1747 session);
1735 /* Send TCP Welcome */ 1748 /* Send TCP Welcome */
1736 process_pending_messages (session); 1749 process_pending_messages (session);
1737 1750
@@ -2259,8 +2272,9 @@ handle_tcp_welcome (void *cls,
2259 { 2272 {
2260 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) 2273 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
2261 { 2274 {
2262 LOG(GNUNET_ERROR_TYPE_DEBUG, "Found existing session %p for peer `%s'\n", 2275 LOG (GNUNET_ERROR_TYPE_DEBUG,
2263 session, GNUNET_a2s (vaddr, alen)); 2276 "Found existing session %p for peer `%s'\n",
2277 session, GNUNET_a2s (vaddr, alen));
2264 GNUNET_free(vaddr); 2278 GNUNET_free(vaddr);
2265 } 2279 }
2266 } 2280 }
@@ -2305,21 +2319,27 @@ handle_tcp_welcome (void *cls,
2305 session = create_session (plugin, address, client, GNUNET_NO); 2319 session = create_session (plugin, address, client, GNUNET_NO);
2306 GNUNET_HELLO_address_free (address); 2320 GNUNET_HELLO_address_free (address);
2307 ats = plugin->env->get_address_type (plugin->env->cls, vaddr, alen); 2321 ats = plugin->env->get_address_type (plugin->env->cls, vaddr, alen);
2308 session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl ( 2322 session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl (ats.value);
2309 ats.value); 2323 LOG(GNUNET_ERROR_TYPE_DEBUG,
2310 LOG(GNUNET_ERROR_TYPE_DEBUG, "Creating new%s session %p for peer `%s' client %p \n", 2324 "Creating new%s session %p for peer `%s' client %p \n",
2311 GNUNET_HELLO_address_check_option (session->address, 2325 GNUNET_HELLO_address_check_option (session->address,
2312 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? " inbound" : "", session, 2326 GNUNET_HELLO_ADDRESS_INFO_INBOUND)
2327 ? " inbound" : "",
2328 session,
2313 tcp_plugin_address_to_string(NULL, (void *) session->address->address, 2329 tcp_plugin_address_to_string(NULL, (void *) session->address->address,
2314 session->address->address_length), 2330 session->address->address_length),
2315 client); 2331 client);
2316 GNUNET_free(vaddr); 2332 GNUNET_free(vaddr);
2317 GNUNET_SERVER_client_set_user_context(session->client, session); 2333 GNUNET_SERVER_client_set_user_context(session->client, session);
2318 GNUNET_CONTAINER_multipeermap_put (plugin->sessionmap, &session->target, 2334 GNUNET_CONTAINER_multipeermap_put (plugin->sessionmap,
2319 session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 2335 &session->target,
2320 2336 session,
2337 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2321 /* Notify transport and ATS about new session */ 2338 /* Notify transport and ATS about new session */
2322 plugin->env->session_start (NULL, session->address, session, &ats, 1); 2339 plugin->env->session_start (NULL, session->address, session, &ats, 1);
2340 notify_session_monitor (plugin,
2341 session,
2342 GNUNET_TRANSPORT_SS_INIT);
2323 } 2343 }
2324 else 2344 else
2325 { 2345 {
@@ -2614,6 +2634,11 @@ send_session_info_iter (void *cls,
2614 2634
2615 notify_session_monitor (plugin, 2635 notify_session_monitor (plugin,
2616 session, 2636 session,
2637 GNUNET_TRANSPORT_SS_INIT);
2638 /* FIXME: cannot tell if this is up or not from current
2639 session state... */
2640 notify_session_monitor (plugin,
2641 session,
2617 GNUNET_TRANSPORT_SS_UP); 2642 GNUNET_TRANSPORT_SS_UP);
2618 return GNUNET_OK; 2643 return GNUNET_OK;
2619} 2644}
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index bb223263f..37de3c06e 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -1270,7 +1270,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc,
1270 } 1270 }
1271 notify_session_monitor (s->plugin, 1271 notify_session_monitor (s->plugin,
1272 s, 1272 s,
1273 GNUNET_TRANSPORT_SS_UP); 1273 GNUNET_TRANSPORT_SS_UPDATE);
1274 /* Destroy fragmentation context */ 1274 /* Destroy fragmentation context */
1275 GNUNET_FRAGMENT_context_destroy (fc->frag, 1275 GNUNET_FRAGMENT_context_destroy (fc->frag,
1276 &s->last_expected_msg_delay, 1276 &s->last_expected_msg_delay,
@@ -1385,7 +1385,7 @@ udp_disconnect_session (void *cls,
1385 } 1385 }
1386 notify_session_monitor (s->plugin, 1386 notify_session_monitor (s->plugin,
1387 s, 1387 s,
1388 GNUNET_TRANSPORT_SS_DOWN); 1388 GNUNET_TRANSPORT_SS_DONE);
1389 plugin->env->session_end (plugin->env->cls, 1389 plugin->env->session_end (plugin->env->cls,
1390 s->address, 1390 s->address,
1391 s); 1391 s);
@@ -1508,7 +1508,7 @@ session_timeout (void *cls,
1508 the monitor, it may think we're about to die ... */ 1508 the monitor, it may think we're about to die ... */
1509 notify_session_monitor (s->plugin, 1509 notify_session_monitor (s->plugin,
1510 s, 1510 s,
1511 GNUNET_TRANSPORT_SS_UP); 1511 GNUNET_TRANSPORT_SS_UPDATE);
1512 s->timeout_task = GNUNET_SCHEDULER_add_delayed (left, 1512 s->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
1513 &session_timeout, 1513 &session_timeout,
1514 s); 1514 s);
@@ -2154,7 +2154,7 @@ udp_plugin_send (void *cls,
2154 } 2154 }
2155 notify_session_monitor (s->plugin, 2155 notify_session_monitor (s->plugin,
2156 s, 2156 s,
2157 GNUNET_TRANSPORT_SS_UP); 2157 GNUNET_TRANSPORT_SS_UPDATE);
2158 schedule_select (plugin); 2158 schedule_select (plugin);
2159 return udpmlen; 2159 return udpmlen;
2160} 2160}
@@ -2335,8 +2335,14 @@ process_udp_message (struct Plugin *plugin,
2335 { 2335 {
2336 s = udp_plugin_create_session (plugin, address); 2336 s = udp_plugin_create_session (plugin, address);
2337 plugin->env->session_start (NULL, address, s, NULL, 0); 2337 plugin->env->session_start (NULL, address, s, NULL, 0);
2338 notify_session_monitor (s->plugin,
2339 s,
2340 GNUNET_TRANSPORT_SS_INIT);
2341 notify_session_monitor (s->plugin,
2342 s,
2343 GNUNET_TRANSPORT_SS_UP);
2338 } 2344 }
2339 GNUNET_free(address); 2345 GNUNET_free (address);
2340 2346
2341 /* iterate over all embedded messages */ 2347 /* iterate over all embedded messages */
2342 si.session = s; 2348 si.session = s;
@@ -2446,7 +2452,7 @@ ack_proc (void *cls,
2446 enqueue (rc->plugin, udpw); 2452 enqueue (rc->plugin, udpw);
2447 notify_session_monitor (s->plugin, 2453 notify_session_monitor (s->plugin,
2448 s, 2454 s,
2449 GNUNET_TRANSPORT_SS_UP); 2455 GNUNET_TRANSPORT_SS_UPDATE);
2450 schedule_select (rc->plugin); 2456 schedule_select (rc->plugin);
2451} 2457}
2452 2458
@@ -2845,7 +2851,7 @@ remove_timeout_messages_and_select (struct UDP_MessageWrapper *head,
2845 if (GNUNET_YES == removed) 2851 if (GNUNET_YES == removed)
2846 notify_session_monitor (session->plugin, 2852 notify_session_monitor (session->plugin,
2847 session, 2853 session,
2848 GNUNET_TRANSPORT_SS_UP); 2854 GNUNET_TRANSPORT_SS_UPDATE);
2849 return udpw; 2855 return udpw;
2850} 2856}
2851 2857
@@ -2955,7 +2961,7 @@ udp_select_send (struct Plugin *plugin,
2955 dequeue (plugin, udpw); 2961 dequeue (plugin, udpw);
2956 notify_session_monitor (plugin, 2962 notify_session_monitor (plugin,
2957 udpw->session, 2963 udpw->session,
2958 GNUNET_TRANSPORT_SS_UP); 2964 GNUNET_TRANSPORT_SS_UPDATE);
2959 GNUNET_free (udpw); 2965 GNUNET_free (udpw);
2960 return GNUNET_SYSERR; 2966 return GNUNET_SYSERR;
2961 } 2967 }
@@ -2994,7 +3000,7 @@ udp_select_send (struct Plugin *plugin,
2994 dequeue (plugin, udpw); 3000 dequeue (plugin, udpw);
2995 notify_session_monitor (plugin, 3001 notify_session_monitor (plugin,
2996 udpw->session, 3002 udpw->session,
2997 GNUNET_TRANSPORT_SS_UP); 3003 GNUNET_TRANSPORT_SS_UPDATE);
2998 GNUNET_free(udpw); 3004 GNUNET_free(udpw);
2999 return sent; 3005 return sent;
3000} 3006}
@@ -3311,6 +3317,9 @@ send_session_info_iter (void *cls,
3311 3317
3312 notify_session_monitor (plugin, 3318 notify_session_monitor (plugin,
3313 session, 3319 session,
3320 GNUNET_TRANSPORT_SS_INIT);
3321 notify_session_monitor (plugin,
3322 session,
3314 GNUNET_TRANSPORT_SS_UP); 3323 GNUNET_TRANSPORT_SS_UP);
3315 return GNUNET_OK; 3324 return GNUNET_OK;
3316} 3325}
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c
index 8a0aa72a0..a753db5ca 100644
--- a/src/transport/plugin_transport_unix.c
+++ b/src/transport/plugin_transport_unix.c
@@ -490,7 +490,7 @@ unix_plugin_session_disconnect (void *cls,
490 } 490 }
491 notify_session_monitor (plugin, 491 notify_session_monitor (plugin,
492 session, 492 session,
493 GNUNET_TRANSPORT_SS_DOWN); 493 GNUNET_TRANSPORT_SS_DONE);
494 GNUNET_HELLO_address_free (session->address); 494 GNUNET_HELLO_address_free (session->address);
495 GNUNET_break (0 == session->bytes_in_queue); 495 GNUNET_break (0 == session->bytes_in_queue);
496 GNUNET_break (0 == session->msgs_in_queue); 496 GNUNET_break (0 == session->msgs_in_queue);
@@ -520,7 +520,7 @@ session_timeout (void *cls,
520 the monitor, it may think we're about to die ... */ 520 the monitor, it may think we're about to die ... */
521 notify_session_monitor (session->plugin, 521 notify_session_monitor (session->plugin,
522 session, 522 session,
523 GNUNET_TRANSPORT_SS_UP); 523 GNUNET_TRANSPORT_SS_UPDATE);
524 session->timeout_task = GNUNET_SCHEDULER_add_delayed (left, 524 session->timeout_task = GNUNET_SCHEDULER_add_delayed (left,
525 &session_timeout, 525 &session_timeout,
526 session); 526 session);
@@ -898,6 +898,9 @@ unix_plugin_get_session (void *cls,
898 GNUNET_NO); 898 GNUNET_NO);
899 notify_session_monitor (plugin, 899 notify_session_monitor (plugin,
900 session, 900 session,
901 GNUNET_TRANSPORT_SS_INIT);
902 notify_session_monitor (plugin,
903 session,
901 GNUNET_TRANSPORT_SS_UP); 904 GNUNET_TRANSPORT_SS_UP);
902 return session; 905 return session;
903} 906}
@@ -973,9 +976,6 @@ unix_demultiplexer (struct Plugin *plugin,
973 session->address, 976 session->address,
974 session, 977 session,
975 &plugin->ats_network, 1); 978 &plugin->ats_network, 1);
976 notify_session_monitor (plugin,
977 session,
978 GNUNET_TRANSPORT_SS_UP);
979 } 979 }
980 else 980 else
981 { 981 {
@@ -1141,7 +1141,7 @@ unix_plugin_do_write (struct Plugin *plugin)
1141 if (GNUNET_YES == did_delete) 1141 if (GNUNET_YES == did_delete)
1142 notify_session_monitor (plugin, 1142 notify_session_monitor (plugin,
1143 session, 1143 session,
1144 GNUNET_TRANSPORT_SS_UP); 1144 GNUNET_TRANSPORT_SS_UPDATE);
1145 return; /* Nothing to send at the moment */ 1145 return; /* Nothing to send at the moment */
1146 } 1146 }
1147 1147
@@ -1163,7 +1163,7 @@ unix_plugin_do_write (struct Plugin *plugin)
1163 1, GNUNET_NO); 1163 1, GNUNET_NO);
1164 notify_session_monitor (plugin, 1164 notify_session_monitor (plugin,
1165 session, 1165 session,
1166 GNUNET_TRANSPORT_SS_UP); 1166 GNUNET_TRANSPORT_SS_UPDATE);
1167 return; 1167 return;
1168 } 1168 }
1169 GNUNET_CONTAINER_DLL_remove (plugin->msg_head, 1169 GNUNET_CONTAINER_DLL_remove (plugin->msg_head,
@@ -1180,7 +1180,7 @@ unix_plugin_do_write (struct Plugin *plugin)
1180 plugin->bytes_in_queue, GNUNET_NO); 1180 plugin->bytes_in_queue, GNUNET_NO);
1181 notify_session_monitor (plugin, 1181 notify_session_monitor (plugin,
1182 session, 1182 session,
1183 GNUNET_TRANSPORT_SS_UP); 1183 GNUNET_TRANSPORT_SS_UPDATE);
1184 if (GNUNET_SYSERR == sent) 1184 if (GNUNET_SYSERR == sent)
1185 { 1185 {
1186 /* failed and no retry */ 1186 /* failed and no retry */
@@ -1358,7 +1358,7 @@ unix_plugin_send (void *cls,
1358 GNUNET_NO); 1358 GNUNET_NO);
1359 notify_session_monitor (plugin, 1359 notify_session_monitor (plugin,
1360 session, 1360 session,
1361 GNUNET_TRANSPORT_SS_UP); 1361 GNUNET_TRANSPORT_SS_UPDATE);
1362 if (GNUNET_SCHEDULER_NO_TASK == plugin->write_task) 1362 if (GNUNET_SCHEDULER_NO_TASK == plugin->write_task)
1363 plugin->write_task = 1363 plugin->write_task =
1364 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 1364 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -1703,6 +1703,9 @@ send_session_info_iter (void *cls,
1703 1703
1704 notify_session_monitor (plugin, 1704 notify_session_monitor (plugin,
1705 session, 1705 session,
1706 GNUNET_TRANSPORT_SS_INIT);
1707 notify_session_monitor (plugin,
1708 session,
1706 GNUNET_TRANSPORT_SS_UP); 1709 GNUNET_TRANSPORT_SS_UP);
1707 return GNUNET_OK; 1710 return GNUNET_OK;
1708} 1711}
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index 912ff9a12..ab9fa4a74 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -773,7 +773,7 @@ wlan_plugin_disconnect_session (void *cls,
773 session); 773 session);
774 notify_session_monitor (plugin, 774 notify_session_monitor (plugin,
775 session, 775 session,
776 GNUNET_TRANSPORT_SS_DOWN); 776 GNUNET_TRANSPORT_SS_DONE);
777 GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, 777 GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head,
778 endpoint->sessions_tail, 778 endpoint->sessions_tail,
779 session); 779 session);
@@ -890,6 +890,9 @@ create_session (struct MacEndpoint *endpoint,
890 session); 890 session);
891 notify_session_monitor (endpoint->plugin, 891 notify_session_monitor (endpoint->plugin,
892 session, 892 session,
893 GNUNET_TRANSPORT_SS_INIT);
894 notify_session_monitor (endpoint->plugin,
895 session,
893 GNUNET_TRANSPORT_SS_UP); 896 GNUNET_TRANSPORT_SS_UP);
894 LOG (GNUNET_ERROR_TYPE_DEBUG, 897 LOG (GNUNET_ERROR_TYPE_DEBUG,
895 "Created new session %p for peer `%s' with endpoint %s\n", 898 "Created new session %p for peer `%s' with endpoint %s\n",
@@ -2046,9 +2049,14 @@ wlan_plugin_setup_monitor (void *cls,
2046 { 2049 {
2047 for (mac = plugin->mac_head; NULL != mac; mac = mac->next) 2050 for (mac = plugin->mac_head; NULL != mac; mac = mac->next)
2048 for (session = mac->sessions_head; NULL != session; session = session->next) 2051 for (session = mac->sessions_head; NULL != session; session = session->next)
2052 {
2053 notify_session_monitor (plugin,
2054 session,
2055 GNUNET_TRANSPORT_SS_INIT);
2049 notify_session_monitor (plugin, 2056 notify_session_monitor (plugin,
2050 session, 2057 session,
2051 GNUNET_TRANSPORT_SS_UP); 2058 GNUNET_TRANSPORT_SS_UP);
2059 }
2052 sic (sic_cls, NULL, NULL); 2060 sic (sic_cls, NULL, NULL);
2053 } 2061 }
2054} 2062}
diff --git a/src/transport/transport.h b/src/transport/transport.h
index 57e7d1b00..6fea9201c 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -644,6 +644,11 @@ struct TransportPluginMonitorMessage
644 struct GNUNET_PeerIdentity peer; 644 struct GNUNET_PeerIdentity peer;
645 645
646 /** 646 /**
647 * Unique identifier for the session.
648 */
649 uint64_t session_id;
650
651 /**
647 * Length of the plugin name in bytes, including 0-termination. 652 * Length of the plugin name in bytes, including 0-termination.
648 */ 653 */
649 uint16_t plugin_name_len GNUNET_PACKED; 654 uint16_t plugin_name_len GNUNET_PACKED;
diff --git a/src/transport/transport_api_monitor_peers.c b/src/transport/transport_api_monitor_peers.c
index f7b50d6d4..f1dab26e2 100644
--- a/src/transport/transport_api_monitor_peers.c
+++ b/src/transport/transport_api_monitor_peers.c
@@ -167,7 +167,7 @@ GNUNET_TRANSPORT_ps2s (enum GNUNET_TRANSPORT_PeerState state)
167/** 167/**
168 * Function called with responses from the service. 168 * Function called with responses from the service.
169 * 169 *
170 * @param cls our `struct GNUNET_TRANSPORT_PeerAddressLookupContext *` 170 * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *`
171 * @param msg NULL on timeout or error, otherwise presumably a 171 * @param msg NULL on timeout or error, otherwise presumably a
172 * message with the human-readable address 172 * message with the human-readable address
173 */ 173 */
@@ -203,7 +203,7 @@ send_peer_mon_request (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
203/** 203/**
204 * Task run to re-establish the connection. 204 * Task run to re-establish the connection.
205 * 205 *
206 * @param cls our `struct GNUNET_TRANSPORT_PeerAddressLookupContext *` 206 * @param cls our `struct GNUNET_TRANSPORT_PeerMonitoringContext *`
207 * @param tc scheduler context, unused 207 * @param tc scheduler context, unused
208 */ 208 */
209static void 209static void
@@ -423,7 +423,7 @@ GNUNET_TRANSPORT_monitor_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
423 struct GNUNET_CLIENT_Connection *client; 423 struct GNUNET_CLIENT_Connection *client;
424 424
425 client = GNUNET_CLIENT_connect ("transport", cfg); 425 client = GNUNET_CLIENT_connect ("transport", cfg);
426 if (client == NULL) 426 if (NULL == client)
427 return NULL; 427 return NULL;
428 if (GNUNET_YES != one_shot) 428 if (GNUNET_YES != one_shot)
429 timeout = GNUNET_TIME_UNIT_FOREVER_REL; 429 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
diff --git a/src/transport/transport_api_monitor_plugins.c b/src/transport/transport_api_monitor_plugins.c
new file mode 100644
index 000000000..290092c22
--- /dev/null
+++ b/src/transport/transport_api_monitor_plugins.c
@@ -0,0 +1,434 @@
1/*
2 This file is part of GNUnet.
3 (C) 2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file transport/transport_api_monitor_plugins.c
23 * @brief montoring api for transport plugin session status
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_arm_service.h"
28#include "gnunet_hello_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_transport_service.h"
31#include "transport.h"
32
33
34/**
35 * Handle for a plugin session state monitor.
36 */
37struct GNUNET_TRANSPORT_PluginMonitor
38{
39
40 /**
41 * Connection to the service.
42 */
43 struct GNUNET_CLIENT_Connection *client;
44
45 /**
46 * Our configuration.
47 */
48 const struct GNUNET_CONFIGURATION_Handle *cfg;
49
50 /**
51 * Callback to call.
52 */
53 GNUNET_TRANSPORT_SessionMonitorCallback cb;
54
55 /**
56 * Closure for @e cb
57 */
58 void *cb_cls;
59
60 /**
61 * Map of session_ids (reduced to 32-bits) to
62 * `struct GNUNET_TRANSPORT_PluginSession` objects.
63 */
64 struct GNUNET_CONTAINER_MultiHashMap32 *sessions;
65
66 /**
67 * Backoff for reconnect.
68 */
69 struct GNUNET_TIME_Relative backoff;
70
71 /**
72 * Task ID for reconnect.
73 */
74 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
75
76};
77
78
79/**
80 * Abstract representation of a plugin's session.
81 * Corresponds to the `struct Session` within the TRANSPORT service.
82 */
83struct GNUNET_TRANSPORT_PluginSession
84{
85 /**
86 * Unique session identifier.
87 */
88 uint64_t session_id;
89
90 /**
91 * Location for the client to store "data".
92 */
93 void *client_ctx;
94};
95
96
97/**
98 * Function called with responses from the service.
99 *
100 * @param cls our `struct GNUNET_TRANSPORT_PluginMonitor *`
101 * @param msg NULL on timeout or error, otherwise presumably a
102 * message with the human-readable address
103 */
104static void
105response_processor (void *cls,
106 const struct GNUNET_MessageHeader *msg);
107
108
109/**
110 * Send our subscription request to the service.
111 *
112 * @param pal_ctx our context
113 */
114static void
115send_plugin_mon_request (struct GNUNET_TRANSPORT_PluginMonitor *pm)
116{
117 struct GNUNET_MessageHeader msg;
118
119 msg.size = htons (sizeof (struct GNUNET_MessageHeader));
120 msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_START);
121 GNUNET_assert (GNUNET_OK ==
122 GNUNET_CLIENT_transmit_and_get_response (pm->client,
123 &msg,
124 GNUNET_TIME_UNIT_FOREVER_REL,
125 GNUNET_YES,
126 &response_processor,
127 pm));
128}
129
130
131/**
132 * Task run to re-establish the connection.
133 *
134 * @param cls our `struct GNUNET_TRANSPORT_PluginMonitor *`
135 * @param tc scheduler context, unused
136 */
137static void
138do_plugin_connect (void *cls,
139 const struct GNUNET_SCHEDULER_TaskContext *tc)
140{
141 struct GNUNET_TRANSPORT_PluginMonitor *pm = cls;
142
143 pm->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
144 pm->client = GNUNET_CLIENT_connect ("transport", pm->cfg);
145 GNUNET_assert (NULL != pm->client);
146 send_plugin_mon_request (pm);
147}
148
149
150/**
151 * Free the session entry and notify the callback about its demise.
152 *
153 * @param cls our `struct GNUNET_TRANSPORT_PluginMonitor`
154 * @param key key of the session in the map
155 * @param value the session to free
156 * @return #GNUNET_OK (continue to iterate)
157 */
158static int
159free_entry (void *cls,
160 uint32_t key,
161 void *value)
162{
163 struct GNUNET_TRANSPORT_PluginMonitor *pm = cls;
164 struct GNUNET_TRANSPORT_PluginSession *ps = value;
165
166 pm->cb (pm->cb_cls,
167 ps,
168 &ps->client_ctx,
169 NULL);
170 GNUNET_break (GNUNET_YES ==
171 GNUNET_CONTAINER_multihashmap32_remove (pm->sessions,
172 key,
173 ps));
174 GNUNET_break (NULL == ps->client_ctx);
175 GNUNET_free (ps);
176 return GNUNET_OK;
177}
178
179
180/**
181 * We got disconnected, remove all existing entries from
182 * the map and notify client.
183 *
184 * @param pm montitor that got disconnected
185 */
186static void
187clear_map (struct GNUNET_TRANSPORT_PluginMonitor *pm)
188{
189 GNUNET_CONTAINER_multihashmap32_iterate (pm->sessions,
190 &free_entry,
191 pm);
192}
193
194
195/**
196 * Cut the existing connection and reconnect.
197 *
198 * @param pm our context
199 */
200static void
201reconnect_plugin_ctx (struct GNUNET_TRANSPORT_PluginMonitor *pm)
202{
203 GNUNET_CLIENT_disconnect (pm->client);
204 pm->client = NULL;
205 clear_map (pm);
206 pm->backoff = GNUNET_TIME_STD_BACKOFF (pm->backoff);
207 pm->reconnect_task = GNUNET_SCHEDULER_add_delayed (pm->backoff,
208 &do_plugin_connect,
209 pm);
210}
211
212
213/**
214 * Convert 64-bit session ID to 32-bit index for hash map.
215 *
216 * @param id 64-bit session ID
217 * @return 32-bit hash map index
218 */
219static uint32_t
220wrap_id (uint64_t id)
221{
222 return ((uint32_t) id) ^ ((uint32_t) (id >> 32));
223}
224
225
226/**
227 * Context for #locate_by_id().
228 */
229struct SearchContext
230{
231
232 /**
233 * Result.
234 */
235 struct GNUNET_TRANSPORT_PluginSession *ps;
236
237 /**
238 * ID to locate.
239 */
240 uint64_t session_id;
241
242};
243
244
245/**
246 * Locate a session entry.
247 *
248 * @param cls our `struct SearchContext`
249 * @param key key of the session in the map
250 * @param value a session
251 * @return #GNUNET_OK (continue to iterate), or #GNUNET_SYSERR (match found)
252 */
253static int
254locate_by_id (void *cls,
255 uint32_t key,
256 void *value)
257{
258 struct SearchContext *sc = cls;
259 struct GNUNET_TRANSPORT_PluginSession *ps = value;
260
261 if (sc->session_id == ps->session_id)
262 {
263 sc->ps = ps;
264 return GNUNET_SYSERR;
265 }
266 return GNUNET_OK;
267}
268
269
270/**
271 * Function called with responses from the service.
272 *
273 * @param cls our `struct GNUNET_TRANSPORT_PluginMonitor *`
274 * @param msg NULL on timeout or error, otherwise presumably a
275 * message with the human-readable address
276 */
277static void
278response_processor (void *cls,
279 const struct GNUNET_MessageHeader *msg)
280{
281 struct GNUNET_TRANSPORT_PluginMonitor *pm = cls;
282 const struct TransportPluginMonitorMessage *tpmm;
283 struct GNUNET_TRANSPORT_PluginSession *ps;
284 const char *pname;
285 const void *paddr;
286 enum GNUNET_TRANSPORT_SessionState ss;
287 size_t pname_len;
288 size_t paddr_len;
289 struct GNUNET_TRANSPORT_SessionInfo info;
290 struct GNUNET_HELLO_Address addr;
291 struct SearchContext rv;
292
293 if (NULL == msg)
294 {
295 reconnect_plugin_ctx (pm);
296 return;
297 }
298 if ( (GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_EVENT != ntohs (msg->type)) ||
299 (sizeof (struct TransportPluginMonitorMessage) > ntohs (msg->size)) )
300 {
301 GNUNET_break (0);
302 reconnect_plugin_ctx (pm);
303 return;
304 }
305 tpmm = (const struct TransportPluginMonitorMessage *) msg;
306 pname = (const char *) &tpmm[1];
307 pname_len = ntohs (tpmm->plugin_name_len);
308 paddr_len = ntohs (tpmm->plugin_address_len);
309 if ( (pname_len +
310 paddr_len +
311 sizeof (struct TransportPluginMonitorMessage) != ntohs (msg->size)) ||
312 ( (0 != pname_len) &&
313 ('\0' != pname[pname_len - 1]) ) )
314 {
315 GNUNET_break (0);
316 reconnect_plugin_ctx (pm);
317 return;
318 }
319 paddr = &pname[pname_len];
320 ps = NULL;
321 ss = (enum GNUNET_TRANSPORT_SessionState) ntohs (tpmm->session_state);
322 if (GNUNET_TRANSPORT_SS_INIT == ss)
323 {
324 ps = GNUNET_new (struct GNUNET_TRANSPORT_PluginSession);
325 ps->session_id = tpmm->session_id;
326 (void) GNUNET_CONTAINER_multihashmap32_put (pm->sessions,
327 wrap_id (tpmm->session_id),
328 ps,
329 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
330
331 }
332 else
333 {
334 rv.session_id = tpmm->session_id;
335 rv.ps = NULL;
336 (void) GNUNET_CONTAINER_multihashmap32_get_multiple (pm->sessions,
337 wrap_id (tpmm->session_id),
338 &locate_by_id,
339 &rv);
340 ps = rv.ps;
341 if (NULL == ps)
342 {
343 GNUNET_break (0);
344 reconnect_plugin_ctx (pm);
345 return;
346 }
347 }
348 info.state = ss;
349 info.is_inbound = (int16_t) ntohs (tpmm->is_inbound);
350 info.num_msg_pending = ntohl (tpmm->msgs_pending);
351 info.num_bytes_pending = ntohl (tpmm->bytes_pending);
352 info.receive_delay = GNUNET_TIME_absolute_ntoh (tpmm->delay);
353 info.session_timeout = GNUNET_TIME_absolute_ntoh (tpmm->timeout);
354 info.address = &addr;
355 addr.peer = tpmm->peer;
356 addr.address = (0 == paddr_len) ? NULL : paddr;
357 addr.address_length = paddr_len;
358 addr.transport_name = (0 == pname_len) ? NULL : pname;
359 addr.local_info = GNUNET_HELLO_ADDRESS_INFO_NONE;
360 pm->cb (pm->cb_cls,
361 ps,
362 &ps->client_ctx,
363 &info);
364
365 if (GNUNET_TRANSPORT_SS_DONE == ss)
366 {
367 GNUNET_break (NULL == ps->client_ctx);
368 GNUNET_assert (GNUNET_YES ==
369 GNUNET_CONTAINER_multihashmap32_remove (pm->sessions,
370 wrap_id (tpmm->session_id),
371 ps));
372 GNUNET_free (ps);
373 }
374}
375
376
377/**
378 * Install a plugin session state monitor callback. The callback
379 * will be notified whenever the session changes.
380 *
381 * @param cfg configuration to use
382 * @param cb callback to invoke on events
383 * @param cb_cls closure for @a cb
384 * @return NULL on error, otherwise handle for cancellation
385 */
386struct GNUNET_TRANSPORT_PluginMonitor *
387GNUNET_TRANSPORT_monitor_plugins (const struct GNUNET_CONFIGURATION_Handle *cfg,
388 GNUNET_TRANSPORT_SessionMonitorCallback cb,
389 void *cb_cls)
390{
391 struct GNUNET_TRANSPORT_PluginMonitor *pm;
392 struct GNUNET_CLIENT_Connection *client;
393
394 client = GNUNET_CLIENT_connect ("transport", cfg);
395 if (NULL == client)
396 return NULL;
397 pm = GNUNET_new (struct GNUNET_TRANSPORT_PluginMonitor);
398 pm->cb = cb;
399 pm->cb_cls = cb_cls;
400 pm->cfg = cfg;
401 pm->client = client;
402 send_plugin_mon_request (pm);
403 return pm;
404}
405
406
407/**
408 * Cancel monitoring the plugin session state. The callback will
409 * be called once for each session that is up with the information
410 * #GNUNET_TRANSPORT_SS_FINI (even though the session may stay up;
411 * this is just to enable client-side cleanup).
412 *
413 * @param pm handle of the request that is to be cancelled
414 */
415void
416GNUNET_TRANSPORT_monitor_plugins_cancel (struct GNUNET_TRANSPORT_PluginMonitor *pm)
417{
418 if (NULL != pm->client)
419 {
420 GNUNET_CLIENT_disconnect (pm->client);
421 pm->client = NULL;
422 }
423 if (GNUNET_SCHEDULER_NO_TASK != pm->reconnect_task)
424 {
425 GNUNET_SCHEDULER_cancel (pm->reconnect_task);
426 pm->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
427 }
428 clear_map (pm);
429 GNUNET_CONTAINER_multihashmap32_destroy (pm->sessions);
430 GNUNET_free (pm);
431}
432
433
434/* end of transport_api_monitor_plugins.c */