aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-19 01:08:03 +0000
committerChristian Grothoff <christian@grothoff.org>2015-01-19 01:08:03 +0000
commitf735158d94616b75ade351a3cce226483b8af55e (patch)
tree1cd9732b99cc6437fec7751b8f3c9ef28f0371c9 /src/transport/gnunet-service-transport.c
parentd769049a7db56037ea4aff3d9d8a8d42a373ec9c (diff)
downloadgnunet-f735158d94616b75ade351a3cce226483b8af55e.tar.gz
gnunet-f735158d94616b75ade351a3cce226483b8af55e.zip
-towards improved ATS API, adding return value with address record when adding address, adding new subsystem with peer-to-address map to transport; causes various new assertions to fail, but no major regression -- not finished
Diffstat (limited to 'src/transport/gnunet-service-transport.c')
-rw-r--r--src/transport/gnunet-service-transport.c468
1 files changed, 175 insertions, 293 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 01ca2fc67..5126dad96 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file transport/gnunet-service-transport.c 22 * @file transport/gnunet-service-transport.c
23 * @brief 23 * @brief main for gnunet-service-transport
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
@@ -31,6 +31,7 @@
31#include "gnunet_peerinfo_service.h" 31#include "gnunet_peerinfo_service.h"
32#include "gnunet_ats_service.h" 32#include "gnunet_ats_service.h"
33#include "gnunet-service-transport.h" 33#include "gnunet-service-transport.h"
34#include "gnunet-service-transport_ats.h"
34#include "gnunet-service-transport_blacklist.h" 35#include "gnunet-service-transport_blacklist.h"
35#include "gnunet-service-transport_clients.h" 36#include "gnunet-service-transport_clients.h"
36#include "gnunet-service-transport_hello.h" 37#include "gnunet-service-transport_hello.h"
@@ -71,19 +72,21 @@ struct SessionKiller
71 struct GNUNET_SCHEDULER_Task * task; 72 struct GNUNET_SCHEDULER_Task * task;
72}; 73};
73 74
75
74struct BlacklistCheckContext 76struct BlacklistCheckContext
75{ 77{
76 struct BlacklistCheckContext *prev; 78 struct BlacklistCheckContext *prev;
77 struct BlacklistCheckContext *next;
78 79
80 struct BlacklistCheckContext *next;
79 81
80 struct GST_BlacklistCheck *blc; 82 struct GST_BlacklistCheck *blc;
81 83
82 struct GNUNET_HELLO_Address *address; 84 struct GNUNET_HELLO_Address *address;
85
83 struct Session *session; 86 struct Session *session;
87
84 struct GNUNET_MessageHeader *msg; 88 struct GNUNET_MessageHeader *msg;
85 struct GNUNET_ATS_Information *ats; 89
86 uint32_t ats_count;
87}; 90};
88 91
89/* globals */ 92/* globals */
@@ -143,7 +146,14 @@ static struct SessionKiller *sk_head;
143 */ 146 */
144static struct SessionKiller *sk_tail; 147static struct SessionKiller *sk_tail;
145 148
149/**
150 * FIXME
151 */
146struct BlacklistCheckContext *bc_head; 152struct BlacklistCheckContext *bc_head;
153
154/**
155 * FIXME
156 */
147struct BlacklistCheckContext *bc_tail; 157struct BlacklistCheckContext *bc_tail;
148 158
149 159
@@ -172,7 +182,7 @@ transmit_our_hello (void *cls, const struct GNUNET_PeerIdentity *target,
172 return; 182 return;
173 183
174 GST_neighbours_send (target, hello, ntohs (hello->size), hello_expiration, 184 GST_neighbours_send (target, hello, ntohs (hello->size), hello_expiration,
175 NULL, NULL ); 185 NULL, NULL);
176} 186}
177 187
178/** 188/**
@@ -193,15 +203,18 @@ process_hello_update (void *cls, const struct GNUNET_MessageHeader *hello)
193 * We received some payload. Prepare to pass it on to our clients. 203 * We received some payload. Prepare to pass it on to our clients.
194 * 204 *
195 * @param peer (claimed) identity of the other peer 205 * @param peer (claimed) identity of the other peer
196 * @param address the address 206 * @param address address and (claimed) identity of the other peer
197 * @param session session used 207 * @param session identifier used for this session (NULL for plugins
208 * that do not offer bi-directional communication to the sender
209 * using the same "connection")
198 * @param message the message to process 210 * @param message the message to process
199 * @return how long the plugin should wait until receiving more data 211 * @return how long the plugin should wait until receiving more data
200 */ 212 */
201static struct GNUNET_TIME_Relative 213static struct GNUNET_TIME_Relative
202process_payload (const struct GNUNET_PeerIdentity *peer, 214process_payload (const struct GNUNET_PeerIdentity *peer,
203 const struct GNUNET_HELLO_Address *address, struct Session *session, 215 const struct GNUNET_HELLO_Address *address,
204 const struct GNUNET_MessageHeader *message) 216 struct Session *session,
217 const struct GNUNET_MessageHeader *message)
205{ 218{
206 struct GNUNET_TIME_Relative ret; 219 struct GNUNET_TIME_Relative ret;
207 int do_forward; 220 int do_forward;
@@ -214,18 +227,18 @@ process_payload (const struct GNUNET_PeerIdentity *peer,
214 ret = GST_neighbours_calculate_receive_delay (peer, msg_size, &do_forward); 227 ret = GST_neighbours_calculate_receive_delay (peer, msg_size, &do_forward);
215 if (! GST_neighbours_test_connected (peer)) 228 if (! GST_neighbours_test_connected (peer))
216 { 229 {
217 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 230 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
218 "Discarded %u bytes type %u payload from peer `%s'\n", msg_size, 231 "Discarded %u bytes type %u payload from peer `%s'\n",
219 ntohs (message->type), GNUNET_i2s (peer)); 232 msg_size,
233 ntohs (message->type),
234 GNUNET_i2s (peer));
220 GNUNET_STATISTICS_update (GST_stats, gettext_noop 235 GNUNET_STATISTICS_update (GST_stats, gettext_noop
221 ("# bytes payload discarded due to not connected peer"), msg_size, 236 ("# bytes payload discarded due to not connected peer"),
222 GNUNET_NO); 237 msg_size,
238 GNUNET_NO);
223 return ret; 239 return ret;
224 } 240 }
225 241
226 // FIXME: why is this call here?
227 GST_ats_add_address (address, session, NULL, 0);
228
229 if (GNUNET_YES != do_forward) 242 if (GNUNET_YES != do_forward)
230 return ret; 243 return ret;
231 im = (struct InboundMessage *) buf; 244 im = (struct InboundMessage *) buf;
@@ -237,6 +250,7 @@ process_payload (const struct GNUNET_PeerIdentity *peer,
237 return ret; 250 return ret;
238} 251}
239 252
253
240/** 254/**
241 * Task to asynchronously terminate a session. 255 * Task to asynchronously terminate a session.
242 * 256 *
@@ -254,16 +268,25 @@ kill_session_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
254 GNUNET_free(sk); 268 GNUNET_free(sk);
255} 269}
256 270
271
272/**
273 * FIXME. Also, consider moving the "bc_*" logic into
274 * blacklist.h?
275 */
257static void 276static void
258cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, struct Session *session) 277cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address,
278 struct Session *session)
259{ 279{
260 struct BlacklistCheckContext *blctx; 280 struct BlacklistCheckContext *blctx;
261 struct BlacklistCheckContext *next; 281 struct BlacklistCheckContext *next;
282
262 next = bc_head; 283 next = bc_head;
263 for (blctx = next; NULL != blctx; blctx = next) 284 for (blctx = next; NULL != blctx; blctx = next)
264 { 285 {
265 next = blctx->next; 286 next = blctx->next;
266 if ((NULL != blctx->address) && (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) && (blctx->session == session)) 287 if ( (NULL != blctx->address) &&
288 (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) &&
289 (blctx->session == session))
267 { 290 {
268 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx); 291 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
269 if (NULL != blctx->blc) 292 if (NULL != blctx->blc)
@@ -273,12 +296,12 @@ cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, str
273 } 296 }
274 GNUNET_HELLO_address_free (blctx->address); 297 GNUNET_HELLO_address_free (blctx->address);
275 GNUNET_free_non_null (blctx->msg); 298 GNUNET_free_non_null (blctx->msg);
276 GNUNET_free_non_null (blctx->ats);
277 GNUNET_free (blctx); 299 GNUNET_free (blctx);
278 } 300 }
279 } 301 }
280} 302}
281 303
304
282/** 305/**
283 * Force plugin to terminate session due to communication 306 * Force plugin to terminate session due to communication
284 * issue. 307 * issue.
@@ -287,7 +310,8 @@ cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address, str
287 * @param session session to termiante 310 * @param session session to termiante
288 */ 311 */
289static void 312static void
290kill_session (const char *plugin_name, struct Session *session) 313kill_session (const char *plugin_name,
314 struct Session *session)
291{ 315{
292 struct GNUNET_TRANSPORT_PluginFunctions *plugin; 316 struct GNUNET_TRANSPORT_PluginFunctions *plugin;
293 struct SessionKiller *sk; 317 struct SessionKiller *sk;
@@ -306,14 +330,15 @@ kill_session (const char *plugin_name, struct Session *session)
306 sk->session = session; 330 sk->session = session;
307 sk->plugin = plugin; 331 sk->plugin = plugin;
308 sk->task = GNUNET_SCHEDULER_add_now (&kill_session_task, sk); 332 sk->task = GNUNET_SCHEDULER_add_now (&kill_session_task, sk);
309 GNUNET_CONTAINER_DLL_insert(sk_head, sk_tail, sk); 333 GNUNET_CONTAINER_DLL_insert (sk_head,
334 sk_tail,
335 sk);
310} 336}
311 337
312 338
313
314/** 339/**
315 * Black list check result for try_connect call 340 * Black list check result for try_connect call
316 * If connection to the peer is allowed request adddress and 341 * If connection to the peer is allowed request adddress and ???
317 * 342 *
318 * @param cls blc_ctx bl context 343 * @param cls blc_ctx bl context
319 * @param peer the peer 344 * @param peer the peer
@@ -321,7 +346,8 @@ kill_session (const char *plugin_name, struct Session *session)
321 */ 346 */
322static void 347static void
323connect_bl_check_cont (void *cls, 348connect_bl_check_cont (void *cls,
324 const struct GNUNET_PeerIdentity *peer, int result) 349 const struct GNUNET_PeerIdentity *peer,
350 int result)
325{ 351{
326 struct BlacklistCheckContext *blctx = cls; 352 struct BlacklistCheckContext *blctx = cls;
327 353
@@ -335,8 +361,9 @@ connect_bl_check_cont (void *cls,
335 "Received SYN message from peer `%s' with `%s' %p\n", 361 "Received SYN message from peer `%s' with `%s' %p\n",
336 GNUNET_i2s (peer), GST_plugins_a2s (blctx->address), blctx->session); 362 GNUNET_i2s (peer), GST_plugins_a2s (blctx->address), blctx->session);
337 363
338 if (GNUNET_OK != GST_neighbours_handle_session_syn (blctx->msg, 364 if (GNUNET_OK !=
339 &blctx->address->peer)) 365 GST_neighbours_handle_session_syn (blctx->msg,
366 &blctx->address->peer))
340 { 367 {
341 cancel_pending_blacklist_checks (blctx->address, blctx->session); 368 cancel_pending_blacklist_checks (blctx->address, blctx->session);
342 kill_session (blctx->address->transport_name, blctx->session); 369 kill_session (blctx->address->transport_name, blctx->session);
@@ -361,38 +388,6 @@ connect_bl_check_cont (void *cls,
361 388
362 389
363/** 390/**
364 * Black list check result for try_connect call
365 * If connection to the peer is allowed request adddress and
366 *
367 * @param cls blc_ctx bl context
368 * @param peer the peer
369 * @param result the result
370 */
371static void
372connect_transport_bl_check_cont (void *cls,
373 const struct GNUNET_PeerIdentity *peer, int result)
374{
375 struct BlacklistCheckContext *blctx = cls;
376
377 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
378 blctx->blc = NULL;
379
380 if (GNUNET_OK == result)
381 {
382 /* Blacklist allows to speak to this transport */
383 GST_ats_add_address (blctx->address,
384 blctx->session,
385 blctx->ats, blctx->ats_count);
386 }
387
388 if (NULL != blctx->address)
389 GNUNET_HELLO_address_free (blctx->address);
390 GNUNET_free (blctx->msg);
391 GNUNET_free (blctx);
392}
393
394
395/**
396 * Function called by the transport for each received message. 391 * Function called by the transport for each received message.
397 * 392 *
398 * @param cls closure, const char* with the name of the plugin we received the message from 393 * @param cls closure, const char* with the name of the plugin we received the message from
@@ -426,7 +421,9 @@ GST_receive_callback (void *cls,
426 GNUNET_i2s (&address->peer)); 421 GNUNET_i2s (&address->peer));
427 422
428 GNUNET_STATISTICS_update (GST_stats, gettext_noop 423 GNUNET_STATISTICS_update (GST_stats, gettext_noop
429 ("# bytes total received"), ntohs (message->size), GNUNET_NO); 424 ("# bytes total received"),
425 ntohs (message->size),
426 GNUNET_NO);
430 GST_neighbours_notify_data_recv (&address->peer, address, session, message); 427 GST_neighbours_notify_data_recv (&address->peer, address, session, message);
431 428
432 switch (type) 429 switch (type)
@@ -442,19 +439,23 @@ GST_receive_callback (void *cls,
442 } 439 }
443 return ret; 440 return ret;
444 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: 441 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
445 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
446 "Processing `%s' from `%s'\n", "PING", GST_plugins_a2s (address)); 443 "Processing `%s' from `%s'\n", "PING",
447 if (GNUNET_OK 444 GST_plugins_a2s (address));
448 != GST_validation_handle_ping (&address->peer, message, address, session)) 445 if (GNUNET_OK !=
446 GST_validation_handle_ping (&address->peer,
447 message,
448 address,
449 session))
449 { 450 {
450 cancel_pending_blacklist_checks (address, session); 451 cancel_pending_blacklist_checks (address, session);
451 kill_session (plugin_name, session); 452 kill_session (plugin_name, session);
452 } 453 }
453 break; 454 break;
454 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG: 455 case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
455 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 456 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
456 "Processing `%s' from `%s'\n", "PONG", 457 "Processing `%s' from `%s'\n", "PONG",
457 GST_plugins_a2s (address)); 458 GST_plugins_a2s (address));
458 if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message)) 459 if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message))
459 { 460 {
460 GNUNET_break_op(0); 461 GNUNET_break_op(0);
@@ -475,18 +476,6 @@ GST_receive_callback (void *cls,
475 { 476 {
476 blctx->blc = blc; 477 blctx->blc = blc;
477 } 478 }
478
479 blctx = GNUNET_new (struct BlacklistCheckContext);
480 blctx->address = GNUNET_HELLO_address_copy (address);
481 blctx->session = session;
482 blctx->msg = GNUNET_malloc (ntohs(message->size));
483 memcpy (blctx->msg, message, ntohs(message->size));
484 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx);
485 if (NULL != (blc = GST_blacklist_test_allowed (&address->peer,
486 address->transport_name, &connect_transport_bl_check_cont, blctx)))
487 {
488 blctx->blc = blc;
489 }
490 break; 479 break;
491 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK: 480 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK:
492 if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message, 481 if (GNUNET_OK != GST_neighbours_handle_session_syn_ack (message,
@@ -529,6 +518,7 @@ GST_receive_callback (void *cls,
529 return ret; 518 return ret;
530} 519}
531 520
521
532/** 522/**
533 * Function that will be called for each address the transport 523 * Function that will be called for each address the transport
534 * is aware that it might be reachable under. Update our HELLO. 524 * is aware that it might be reachable under. Update our HELLO.
@@ -539,8 +529,9 @@ GST_receive_callback (void *cls,
539 * @param address the address to add or remove 529 * @param address the address to add or remove
540 */ 530 */
541static void 531static void
542plugin_env_address_change_notification (void *cls, int add_remove, 532plugin_env_address_change_notification (void *cls,
543 const struct GNUNET_HELLO_Address *address) 533 int add_remove,
534 const struct GNUNET_HELLO_Address *address)
544{ 535{
545 static int addresses = 0; 536 static int addresses = 0;
546 struct GNUNET_STATISTICS_Handle *cfg = GST_stats; 537 struct GNUNET_STATISTICS_Handle *cfg = GST_stats;
@@ -562,11 +553,12 @@ plugin_env_address_change_notification (void *cls, int add_remove,
562 } 553 }
563 554
564 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 555 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
565 "Transport now has %u addresses to communicate\n", addresses); 556 "Transport now has %u addresses to communicate\n",
566 557 addresses);
567 GST_hello_modify_addresses (add_remove, address); 558 GST_hello_modify_addresses (add_remove, address);
568} 559}
569 560
561
570/** 562/**
571 * Function that will be called whenever the plugin internally 563 * Function that will be called whenever the plugin internally
572 * cleans up a session pointer and hence the service needs to 564 * cleans up a session pointer and hence the service needs to
@@ -581,8 +573,9 @@ plugin_env_address_change_notification (void *cls, int add_remove,
581 * @param session which session is being destoyed 573 * @param session which session is being destoyed
582 */ 574 */
583static void 575static void
584plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address, 576plugin_env_session_end (void *cls,
585 struct Session *session) 577 const struct GNUNET_HELLO_Address *address,
578 struct Session *session)
586{ 579{
587 struct SessionKiller *sk; 580 struct SessionKiller *sk;
588 581
@@ -591,40 +584,30 @@ plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address,
591 GNUNET_break (0); 584 GNUNET_break (0);
592 return; 585 return;
593 } 586 }
594
595 if (NULL == session) 587 if (NULL == session)
596 { 588 {
597 GNUNET_break (0); 589 GNUNET_break (0);
598 return; 590 return;
599 } 591 }
592 GNUNET_assert (strlen (address->transport_name) > 0);
600 593
601 GNUNET_assert(strlen (address->transport_name) > 0); 594 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
602 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Session %p to peer `%s' ended \n", 595 "Notification from plugin `%s' about terminated %s session %p from peer `%s' address `%s'\n",
603 session, GNUNET_i2s (&address->peer)); 596 address->transport_name,
604 597 GNUNET_HELLO_address_check_option (address,
605 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 598 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session,
606 "Notification from plugin `%s' about terminated %s session %p from peer `%s' address `%s'\n", 599 GNUNET_i2s (&address->peer),
607 address->transport_name, 600 GST_plugins_a2s (address));
608 GNUNET_HELLO_address_check_option (address,
609 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", session,
610 GNUNET_i2s (&address->peer), GST_plugins_a2s (address));
611 601
612 GST_neighbours_session_terminated (&address->peer, session); 602 GST_neighbours_session_terminated (&address->peer, session);
613 603 GST_ats_del_session (address, session);
614 GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
615 "transport-ats", "Telling ATS to destroy session %p from peer %s\n",
616 session, GNUNET_i2s (&address->peer));
617
618 /* Tell ATS that session has ended */
619 GNUNET_ATS_address_destroyed (GST_ats, address, session);
620
621 cancel_pending_blacklist_checks (address, session); 604 cancel_pending_blacklist_checks (address, session);
622 605
623 for (sk = sk_head; NULL != sk; sk = sk->next) 606 for (sk = sk_head; NULL != sk; sk = sk->next)
624 { 607 {
625 if (sk->session == session) 608 if (sk->session == session)
626 { 609 {
627 GNUNET_CONTAINER_DLL_remove(sk_head, sk_tail, sk); 610 GNUNET_CONTAINER_DLL_remove (sk_head, sk_tail, sk);
628 GNUNET_SCHEDULER_cancel (sk->task); 611 GNUNET_SCHEDULER_cancel (sk->task);
629 GNUNET_free(sk); 612 GNUNET_free(sk);
630 break; 613 break;
@@ -632,6 +615,7 @@ plugin_env_session_end (void *cls, const struct GNUNET_HELLO_Address *address,
632 } 615 }
633} 616}
634 617
618
635/** 619/**
636 * Function that will be called to figure if an address is an loopback, 620 * Function that will be called to figure if an address is an loopback,
637 * LAN, WAN etc. address 621 * LAN, WAN etc. address
@@ -651,14 +635,6 @@ plugin_env_address_to_type (void *cls,
651 GNUNET_break(0); 635 GNUNET_break(0);
652 return GNUNET_ATS_NET_UNSPECIFIED; 636 return GNUNET_ATS_NET_UNSPECIFIED;
653 } 637 }
654 if (((addr->sa_family != AF_INET) && (addrlen != sizeof(struct sockaddr_in)))
655 && ((addr->sa_family != AF_INET6)
656 && (addrlen != sizeof(struct sockaddr_in6)))
657 && (addr->sa_family != AF_UNIX))
658 {
659 GNUNET_break(0);
660 return GNUNET_ATS_NET_UNSPECIFIED;
661 }
662 return GNUNET_ATS_address_get_type (GST_ats, 638 return GNUNET_ATS_address_get_type (GST_ats,
663 addr, 639 addr,
664 addrlen); 640 addrlen);
@@ -666,110 +642,6 @@ plugin_env_address_to_type (void *cls,
666 642
667 643
668/** 644/**
669 * Notify ATS about the new address including the network this address is
670 * located in.
671 *
672 * @param address the address
673 * @param session the session
674 * @param ats ats information
675 * @param ats_count number of @a ats information
676 */
677void
678GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
679 struct Session *session,
680 const struct GNUNET_ATS_Information *ats,
681 uint32_t ats_count)
682{
683 struct GNUNET_TRANSPORT_PluginFunctions *papi;
684 struct GNUNET_ATS_Information ats2[ats_count + 1];
685 uint32_t net;
686
687 /* valid new address, let ATS know! */
688 if (NULL == address->transport_name)
689 {
690 GNUNET_break(0);
691 return;
692 }
693 if (NULL == (papi = GST_plugins_find (address->transport_name)))
694 {
695 /* we don't have the plugin for this address */
696 GNUNET_break(0);
697 return;
698 }
699
700 if (GNUNET_YES == GNUNET_ATS_session_known (GST_ats, address, session))
701 {
702 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
703 "ATS already knows the address, not passing it on again\n");
704 return;
705 }
706
707 net = papi->get_network (papi->cls, session);
708 if (GNUNET_ATS_NET_UNSPECIFIED == net)
709 {
710 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
711 _("Could not obtain a valid network for `%s' %s (%s)\n"),
712 GNUNET_i2s (&address->peer), GST_plugins_a2s (address),
713 address->transport_name);
714 return;
715 }
716 ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
717 ats2[0].value = htonl (net);
718 memcpy (&ats2[1], ats, sizeof(struct GNUNET_ATS_Information) * ats_count);
719 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
720 "Notifying ATS about peer `%s''s new address `%s' session %p in network %s\n",
721 GNUNET_i2s (&address->peer),
722 (0 == address->address_length)
723 ? "<inbound>"
724 : GST_plugins_a2s (address),
725 session,
726 GNUNET_ATS_print_network_type (net));
727 GNUNET_ATS_address_add (GST_ats, address, session,
728 ats2, ats_count + 1);
729}
730
731
732/**
733 * Notify ATS about property changes to an address
734 *
735 * @param peer the peer
736 * @param address the address
737 * @param session the session
738 * @param ats performance information
739 * @param ats_count number of elements in @a ats
740 */
741void
742GST_ats_update_metrics (const struct GNUNET_PeerIdentity *peer,
743 const struct GNUNET_HELLO_Address *address,
744 struct Session *session,
745 const struct GNUNET_ATS_Information *ats,
746 uint32_t ats_count)
747{
748 struct GNUNET_ATS_Information *ats_new;
749
750 if (GNUNET_NO == GNUNET_ATS_session_known (GST_ats, address, session))
751 return;
752
753 /* Call to manipulation to manipulate ATS information */
754 ats_new = GST_manipulation_manipulate_metrics (peer, address, session, ats,
755 ats_count);
756 if (NULL == ats_new)
757 {
758 GNUNET_break(0);
759 return;
760 }
761 if (GNUNET_NO == GNUNET_ATS_address_update (GST_ats, address, session,
762 ats_new, ats_count))
763 {
764 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
765 _("Address or session unknown: failed to update properties for peer `%s' plugin `%s' address `%s' session %p\n"),
766 GNUNET_i2s (peer), address->transport_name, GST_plugins_a2s (address),
767 session);
768 }
769 GNUNET_free(ats_new);
770}
771
772/**
773 * Function that will be called to update metrics for an address 645 * Function that will be called to update metrics for an address
774 * 646 *
775 * @param cls closure 647 * @param cls closure
@@ -785,25 +657,16 @@ plugin_env_update_metrics (void *cls,
785 const struct GNUNET_ATS_Information *ats, 657 const struct GNUNET_ATS_Information *ats,
786 uint32_t ats_count) 658 uint32_t ats_count)
787{ 659{
788 if ((NULL == ats) || (0 == ats_count)) 660 GST_ats_update_metrics (address,
789 return;
790 GNUNET_assert(NULL != GST_ats);
791
792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
793 "Updating metrics for peer `%s' address %s session %p\n",
794 GNUNET_i2s (&address->peer),
795 GST_plugins_a2s (address),
796 session);
797 GST_ats_update_metrics (&address->peer,
798 address,
799 session, 661 session,
800 ats, ats_count); 662 ats, ats_count);
801} 663}
802 664
803 665
804/** 666/**
805 * Black list check result for try_connect call 667 * Black list check result from blacklist check triggered when a
806 * If connection to the peer is allowed request adddress and 668 * plugin gave us a new session in #plugin_env_session_start(). If
669 * connection to the peer is disallowed, kill the session.
807 * 670 *
808 * @param cls blc_ctx bl context 671 * @param cls blc_ctx bl context
809 * @param peer the peer 672 * @param peer the peer
@@ -811,26 +674,23 @@ plugin_env_update_metrics (void *cls,
811 */ 674 */
812static void 675static void
813plugin_env_session_start_bl_check_cont (void *cls, 676plugin_env_session_start_bl_check_cont (void *cls,
814 const struct GNUNET_PeerIdentity *peer, int result) 677 const struct GNUNET_PeerIdentity *peer,
678 int result)
815{ 679{
816 struct BlacklistCheckContext *blctx = cls; 680 struct BlacklistCheckContext *blctx = cls;
817 681
818 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx); 682 GNUNET_CONTAINER_DLL_remove (bc_head,
683 bc_tail,
684 blctx);
819 blctx->blc = NULL; 685 blctx->blc = NULL;
820 686 if (GNUNET_OK != result)
821 if (GNUNET_OK == result)
822 {
823 GST_ats_add_address (blctx->address, blctx->session,
824 blctx->ats, blctx->ats_count);
825 }
826 else
827 { 687 {
828 cancel_pending_blacklist_checks (blctx->address, blctx->session); 688 cancel_pending_blacklist_checks (blctx->address,
829 kill_session (blctx->address->transport_name, blctx->session); 689 blctx->session);
690 kill_session (blctx->address->transport_name,
691 blctx->session);
830 } 692 }
831
832 GNUNET_HELLO_address_free (blctx->address); 693 GNUNET_HELLO_address_free (blctx->address);
833 GNUNET_free_non_null (blctx->ats);
834 GNUNET_free (blctx); 694 GNUNET_free (blctx);
835} 695}
836 696
@@ -846,14 +706,13 @@ plugin_env_session_start_bl_check_cont (void *cls,
846 */ 706 */
847static void 707static void
848plugin_env_session_start (void *cls, 708plugin_env_session_start (void *cls,
849 struct GNUNET_HELLO_Address *address, 709 const struct GNUNET_HELLO_Address *address,
850 struct Session *session, 710 struct Session *session,
851 const struct GNUNET_ATS_Information *ats, 711 const struct GNUNET_ATS_Information *ats,
852 uint32_t ats_count) 712 uint32_t ats_count)
853{ 713{
854 struct BlacklistCheckContext *blctx; 714 struct BlacklistCheckContext *blctx;
855 struct GST_BlacklistCheck *blc; 715 struct GST_BlacklistCheck *blc;
856 int c;
857 716
858 if (NULL == address) 717 if (NULL == address)
859 { 718 {
@@ -865,30 +724,46 @@ plugin_env_session_start (void *cls,
865 GNUNET_break(0); 724 GNUNET_break(0);
866 return; 725 return;
867 } 726 }
868 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 727 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
869 "Notification from plugin `%s' about new %s session %p from peer `%s' address `%s'\n", 728 "Notification from plugin `%s' about new %s session %p from peer `%s' address `%s'\n",
870 address->transport_name, 729 address->transport_name,
730 GNUNET_HELLO_address_check_option (address,
731 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound",
732 session,
733 GNUNET_i2s (&address->peer),
734 GST_plugins_a2s (address));
735 if (GNUNET_YES ==
871 GNUNET_HELLO_address_check_option (address, 736 GNUNET_HELLO_address_check_option (address,
872 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", 737 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
873 session, GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); 738 {
874 739 /* inbound is always new */
740 GST_ats_add_address (address,
741 session,
742 ats,
743 ats_count);
744 }
745 else
746 {
747 /* outbound should already be known */
748 GST_ats_new_session (address,
749 session);
750 GST_ats_update_metrics (address,
751 session,
752 ats,
753 ats_count);
754 }
875 /* Do blacklist check if communication with this peer is allowed */ 755 /* Do blacklist check if communication with this peer is allowed */
876 blctx = GNUNET_new (struct BlacklistCheckContext); 756 blctx = GNUNET_new (struct BlacklistCheckContext);
877 blctx->address = GNUNET_HELLO_address_copy (address); 757 blctx->address = GNUNET_HELLO_address_copy (address);
878 blctx->session = session; 758 blctx->session = session;
879 if (ats_count > 0) 759 GNUNET_CONTAINER_DLL_insert (bc_head,
880 { 760 bc_tail,
881 blctx->ats = GNUNET_malloc (ats_count * sizeof (struct GNUNET_ATS_Information)); 761 blctx);
882 for (c = 0; c < ats_count; c++) 762 if (NULL !=
883 { 763 (blc = GST_blacklist_test_allowed (&address->peer,
884 blctx->ats[c].type = ats[c].type; 764 address->transport_name,
885 blctx->ats[c].value = ats[c].value; 765 &plugin_env_session_start_bl_check_cont,
886 } 766 blctx)))
887 }
888
889 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx);
890 if (NULL != (blc = GST_blacklist_test_allowed (&address->peer, address->transport_name,
891 &plugin_env_session_start_bl_check_cont, blctx)))
892 { 767 {
893 blctx->blc = blc; 768 blctx->blc = blc;
894 } 769 }
@@ -927,9 +802,9 @@ ats_request_address_change (void *cls,
927 /* ATS tells me to disconnect from peer */ 802 /* ATS tells me to disconnect from peer */
928 if ((0 == bw_in) && (0 == bw_out)) 803 if ((0 == bw_in) && (0 == bw_out))
929 { 804 {
930 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 805 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
931 "ATS tells me to disconnect from peer `%s'\n", 806 "ATS tells me to disconnect from peer `%s'\n",
932 GNUNET_i2s (&address->peer)); 807 GNUNET_i2s (&address->peer));
933 GST_neighbours_force_disconnect (&address->peer); 808 GST_neighbours_force_disconnect (&address->peer);
934 return; 809 return;
935 } 810 }
@@ -952,9 +827,9 @@ ats_request_address_change (void *cls,
952 */ 827 */
953static void 828static void
954neighbours_connect_notification (void *cls, 829neighbours_connect_notification (void *cls,
955 const struct GNUNET_PeerIdentity *peer, 830 const struct GNUNET_PeerIdentity *peer,
956 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 831 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
957 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 832 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
958{ 833{
959 size_t len = sizeof(struct ConnectInfoMessage); 834 size_t len = sizeof(struct ConnectInfoMessage);
960 char buf[len] GNUNET_ALIGN; 835 char buf[len] GNUNET_ALIGN;
@@ -962,8 +837,9 @@ neighbours_connect_notification (void *cls,
962 837
963 connections++; 838 connections++;
964 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 839 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
965 "We are now connected to peer `%s' and %u peers in total\n", 840 "We are now connected to peer `%s' and %u peers in total\n",
966 GNUNET_i2s (peer), connections); 841 GNUNET_i2s (peer),
842 connections);
967 connect_msg->header.size = htons (sizeof(buf)); 843 connect_msg->header.size = htons (sizeof(buf));
968 connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 844 connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
969 connect_msg->id = *peer; 845 connect_msg->id = *peer;
@@ -988,8 +864,8 @@ neighbours_disconnect_notification (void *cls,
988 864
989 connections--; 865 connections--;
990 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 866 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
991 "Peer `%s' disconnected and we are connected to %u peers\n", 867 "Peer `%s' disconnected and we are connected to %u peers\n",
992 GNUNET_i2s (peer), connections); 868 GNUNET_i2s (peer), connections);
993 869
994 GST_manipulation_peer_disconnect (peer); 870 GST_manipulation_peer_disconnect (peer);
995 disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage)); 871 disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage));
@@ -1021,12 +897,12 @@ neighbours_changed_notification (void *cls,
1021 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 897 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
1022 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 898 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
1023{ 899{
1024 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1025 "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n", 901 "Notifying about change for peer `%s' with address `%s' in state `%s' timing out at %s\n",
1026 GNUNET_i2s (peer), 902 GNUNET_i2s (peer),
1027 (NULL != address) ? GST_plugins_a2s (address) : "<none>", 903 (NULL != address) ? GST_plugins_a2s (address) : "<none>",
1028 GNUNET_TRANSPORT_ps2s (state), 904 GNUNET_TRANSPORT_ps2s (state),
1029 GNUNET_STRINGS_absolute_time_to_string (state_timeout)); 905 GNUNET_STRINGS_absolute_time_to_string (state_timeout));
1030 906
1031 GST_clients_broadcast_peer_notification (peer, 907 GST_clients_broadcast_peer_notification (peer,
1032 address, 908 address,
@@ -1043,12 +919,13 @@ neighbours_changed_notification (void *cls,
1043 * @param tc task context (unused) 919 * @param tc task context (unused)
1044 */ 920 */
1045static void 921static void
1046shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 922shutdown_task (void *cls,
923 const struct GNUNET_SCHEDULER_TaskContext *tc)
1047{ 924{
1048 GST_neighbours_stop (); 925 GST_neighbours_stop ();
1049 GST_validation_stop (); 926 GST_validation_stop ();
1050 GST_plugins_unload (); 927 GST_plugins_unload ();
1051 928 GST_ats_done ();
1052 GNUNET_ATS_scheduling_done (GST_ats); 929 GNUNET_ATS_scheduling_done (GST_ats);
1053 GST_ats = NULL; 930 GST_ats = NULL;
1054 GST_clients_stop (); 931 GST_clients_stop ();
@@ -1083,8 +960,9 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1083 * @param c configuration to use 960 * @param c configuration to use
1084 */ 961 */
1085static void 962static void
1086run (void *cls, struct GNUNET_SERVER_Handle *server, 963run (void *cls,
1087 const struct GNUNET_CONFIGURATION_Handle *c) 964 struct GNUNET_SERVER_Handle *server,
965 const struct GNUNET_CONFIGURATION_Handle *c)
1088{ 966{
1089 char *keyfile; 967 char *keyfile;
1090 struct GNUNET_CRYPTO_EddsaPrivateKey *pk; 968 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
@@ -1121,15 +999,16 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1121 GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg); 999 GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
1122 GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg); 1000 GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg);
1123 GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key, 1001 GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
1124 &GST_my_identity.public_key); 1002 &GST_my_identity.public_key);
1125 GNUNET_assert(NULL != GST_my_private_key); 1003 GNUNET_assert(NULL != GST_my_private_key);
1126 1004
1127 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1005 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1128 "My identity is `%4s'\n", 1006 "My identity is `%4s'\n",
1129 GNUNET_i2s_full (&GST_my_identity)); 1007 GNUNET_i2s_full (&GST_my_identity));
1130 1008
1131 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, 1009 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
1132 NULL ); 1010 &shutdown_task,
1011 NULL);
1133 if (NULL == GST_peerinfo) 1012 if (NULL == GST_peerinfo)
1134 { 1013 {
1135 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1014 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
@@ -1152,8 +1031,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1152 } 1031 }
1153 max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport */ 1032 max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport */
1154#endif 1033#endif
1155 GNUNET_CONFIGURATION_get_value_number (GST_cfg, "transport", "MAX_FD", 1034 GNUNET_CONFIGURATION_get_value_number (GST_cfg,
1156 &max_fd_cfg); 1035 "transport",
1036 "MAX_FD",
1037 &max_fd_cfg);
1157 1038
1158 if (max_fd_cfg > max_fd_rlimit) 1039 if (max_fd_cfg > max_fd_rlimit)
1159 max_fd = max_fd_cfg; 1040 max_fd = max_fd_cfg;
@@ -1162,9 +1043,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1162 if (max_fd < DEFAULT_MAX_FDS) 1043 if (max_fd < DEFAULT_MAX_FDS)
1163 max_fd = DEFAULT_MAX_FDS; 1044 max_fd = DEFAULT_MAX_FDS;
1164 1045
1165 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1166 "Limiting number of sockets to %u: validation %u, neighbors: %u\n", 1047 "Limiting number of sockets to %u: validation %u, neighbors: %u\n",
1167 max_fd, (max_fd / 3), (max_fd / 3) * 2); 1048 max_fd, (max_fd / 3), (max_fd / 3) * 2);
1168 1049
1169 friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology", 1050 friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology",
1170 "FRIENDS-ONLY"); 1051 "FRIENDS-ONLY");
@@ -1176,7 +1057,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
1176 GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity); 1057 GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity);
1177 GST_ats = GNUNET_ATS_scheduling_init (GST_cfg, 1058 GST_ats = GNUNET_ATS_scheduling_init (GST_cfg,
1178 &ats_request_address_change, 1059 &ats_request_address_change,
1179 NULL ); 1060 NULL);
1061 GST_ats_init ();
1180 GST_manipulation_init (GST_cfg); 1062 GST_manipulation_init (GST_cfg);
1181 GST_plugins_load (&GST_manipulation_recv, 1063 GST_plugins_load (&GST_manipulation_recv,
1182 &GST_neighbours_register_quota_notification, 1064 &GST_neighbours_register_quota_notification,