/*
This file is part of GNUnet.
- (C) 2010-2015 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
-
/**
* @file transport/gnunet-service-transport.c
* @brief main for gnunet-service-transport
#include "gnunet-service-transport_manipulation.h"
#include "transport.h"
+
/**
* Information we need for an asynchronous session kill.
*/
/**
* The kill task.
*/
- struct GNUNET_SCHEDULER_Task * task;
+ struct GNUNET_SCHEDULER_Task *task;
};
-struct BlacklistCheckContext
-{
- struct BlacklistCheckContext *prev;
-
- struct BlacklistCheckContext *next;
-
- struct GST_BlacklistCheck *blc;
-
- struct GNUNET_HELLO_Address *address;
-
- struct Session *session;
-
- struct GNUNET_MessageHeader *msg;
-
-};
-
/* globals */
/**
/**
* Interface scanner determines our LAN address range(s).
*/
-static struct GNUNET_ATS_InterfaceScanner *is;
-
-/**
- * FIXME
- */
-struct BlacklistCheckContext *bc_head;
-
-/**
- * FIXME
- */
-struct BlacklistCheckContext *bc_tail;
+struct GNUNET_ATS_InterfaceScanner *GST_is;
/**
{
const struct GNUNET_MessageHeader *hello = cls;
+ if (0 ==
+ memcmp (peer,
+ &GST_my_identity,
+ sizeof (struct GNUNET_PeerIdentity)))
+ return; /* not to ourselves */
if (GNUNET_NO == GST_neighbours_test_connected (peer))
return;
* @param hello new HELLO
*/
static void
-process_hello_update (void *cls, const struct GNUNET_MessageHeader *hello)
+process_hello_update (void *cls,
+ const struct GNUNET_MessageHeader *hello)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Broadcasting HELLO to clients\n");
GST_clients_broadcast (hello, GNUNET_NO);
- GST_neighbours_iterate (&transmit_our_hello, (void *) hello);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Broadcasting HELLO to neighbours\n");
+ GST_neighbours_iterate (&transmit_our_hello,
+ (void *) hello);
}
* @param tc scheduler context
*/
static void
-kill_session_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+kill_session_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct SessionKiller *sk = cls;
sk->task = NULL;
- GNUNET_CONTAINER_DLL_remove(sk_head, sk_tail, sk);
+ GNUNET_CONTAINER_DLL_remove (sk_head, sk_tail, sk);
sk->plugin->disconnect_session (sk->plugin->cls, sk->session);
GNUNET_free(sk);
}
-/**
- * FIXME. Also, consider moving the "bc_*" logic into
- * blacklist.h?
- */
-static void
-cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address,
- struct Session *session)
-{
- struct BlacklistCheckContext *blctx;
- struct BlacklistCheckContext *next;
-
- next = bc_head;
- for (blctx = next; NULL != blctx; blctx = next)
- {
- next = blctx->next;
- if ( (NULL != blctx->address) &&
- (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) &&
- (blctx->session == session))
- {
- GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
- if (NULL != blctx->blc)
- {
- GST_blacklist_test_cancel (blctx->blc);
- blctx->blc = NULL;
- }
- GNUNET_HELLO_address_free (blctx->address);
- GNUNET_free_non_null (blctx->msg);
- GNUNET_free (blctx);
- }
- }
-}
-
-
/**
* Force plugin to terminate session due to communication
* issue.
* Black list check result for try_connect call
* If connection to the peer is allowed request adddress and ???
*
- * @param cls blc_ctx bl context
+ * @param cls the message
* @param peer the peer
+ * @param address the address
+ * @param session the session
* @param result the result
*/
static void
connect_bl_check_cont (void *cls,
const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
int result)
{
- struct BlacklistCheckContext *blctx = cls;
-
- GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, blctx);
- blctx->blc = NULL;
+ struct GNUNET_MessageHeader *msg = cls;
if (GNUNET_OK == result)
{
/* Blacklist allows to speak to this peer, forward SYN to neighbours */
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Received SYN message from peer `%s' with `%s' %p\n",
+ "Received SYN message from peer `%s' at `%s'\n",
GNUNET_i2s (peer),
- GST_plugins_a2s (blctx->address),
- blctx->session);
-
+ GST_plugins_a2s (address));
if (GNUNET_OK !=
- GST_neighbours_handle_session_syn (blctx->msg,
- &blctx->address->peer))
+ GST_neighbours_handle_session_syn (msg,
+ peer))
{
- cancel_pending_blacklist_checks (blctx->address, blctx->session);
- kill_session (blctx->address->transport_name, blctx->session);
+ GST_blacklist_abort_matching (address,
+ session);
+ kill_session (address->transport_name,
+ session);
}
+ GNUNET_free (msg);
+ return;
}
- else
- {
- /* Blacklist denies to speak to this peer */
-
- GNUNET_log(GNUNET_ERROR_TYPE_INFO,
- "Discarding SYN message from `%s' due to denied blacklist check\n",
- GNUNET_i2s (peer));
- cancel_pending_blacklist_checks (blctx->address, blctx->session);
- kill_session (blctx->address->transport_name, blctx->session);
- }
-
- if (NULL != blctx->address)
- GNUNET_HELLO_address_free (blctx->address);
- GNUNET_free (blctx->msg);
- GNUNET_free (blctx);
+ GNUNET_free (msg);
+ if (GNUNET_SYSERR == result)
+ return; /* check was aborted, session destroyed */
+ /* Blacklist denies to speak to this peer */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Discarding SYN message from `%s' due to denied blacklist check\n",
+ GNUNET_i2s (peer));
+ kill_session (address->transport_name,
+ session);
}
{
const char *plugin_name = cls;
struct GNUNET_TIME_Relative ret;
- struct BlacklistCheckContext *blctx;
- struct GST_BlacklistCheck *blc;
uint16_t type;
ret = GNUNET_TIME_UNIT_ZERO;
goto end;
type = ntohs (message->type);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received Message with type %u from peer `%s'\n",
+ "Received message with type %u from peer `%s'\n",
type,
GNUNET_i2s (&address->peer));
if (GNUNET_OK != GST_validation_handle_hello (message))
{
GNUNET_break_op (0);
- cancel_pending_blacklist_checks (address,
- session);
+ GST_blacklist_abort_matching (address,
+ session);
}
return ret;
case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Processing `%s' from `%s'\n", "PING",
+ "Processing PING from `%s'\n",
GST_plugins_a2s (address));
if (GNUNET_OK !=
GST_validation_handle_ping (&address->peer,
address,
session))
{
- cancel_pending_blacklist_checks (address,
- session);
+ GST_blacklist_abort_matching (address,
+ session);
kill_session (plugin_name,
session);
}
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_PONG:
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
- "Processing `%s' from `%s'\n", "PONG",
+ "Processing PONG from `%s'\n",
GST_plugins_a2s (address));
if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message))
{
- GNUNET_break_op(0);
- cancel_pending_blacklist_checks (address, session);
+ GNUNET_break_op (0);
+ GST_blacklist_abort_matching (address,
+ session);
kill_session (plugin_name, session);
}
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN:
/* Do blacklist check if communication with this peer is allowed */
- blctx = GNUNET_new (struct BlacklistCheckContext);
- blctx->address = GNUNET_HELLO_address_copy (address);
- blctx->session = session;
- blctx->msg = GNUNET_malloc (ntohs(message->size));
- memcpy (blctx->msg, message, ntohs(message->size));
- GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, blctx);
- if (NULL != (blc = GST_blacklist_test_allowed (&address->peer, NULL,
- &connect_bl_check_cont,
- blctx)))
- {
- blctx->blc = blc;
- }
+ (void) GST_blacklist_test_allowed (&address->peer,
+ NULL,
+ &connect_bl_check_cont,
+ GNUNET_copy_message (message),
+ address,
+ session);
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK:
if (GNUNET_OK !=
address,
session))
{
- cancel_pending_blacklist_checks (address, session);
+ GST_blacklist_abort_matching (address, session);
kill_session (plugin_name, session);
}
break;
session))
{
GNUNET_break_op(0);
- cancel_pending_blacklist_checks (address, session);
+ GST_blacklist_abort_matching (address, session);
kill_session (plugin_name, session);
}
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_DISCONNECT:
- GST_neighbours_handle_disconnect_message (&address->peer, message);
+ GST_neighbours_handle_disconnect_message (&address->peer,
+ message);
+ break;
+ case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA:
+ GST_neighbours_handle_quota_message (&address->peer,
+ message);
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE:
- GST_neighbours_keepalive (&address->peer, message);
+ GST_neighbours_keepalive (&address->peer,
+ message);
break;
case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE:
- GST_neighbours_keepalive_response (&address->peer, message);
+ GST_neighbours_keepalive_response (&address->peer,
+ message);
break;
default:
/* should be payload */
gettext_noop ("# bytes payload received"),
ntohs (message->size),
GNUNET_NO);
- GST_neighbours_notify_payload_recv (address,
- message);
ret = process_payload (address,
session,
message);
break;
}
- end:
+ end:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Allowing receive from peer %s to continue in %s\n",
GNUNET_i2s (&address->peer),
if (GNUNET_YES == add_remove)
{
addresses ++;
- GNUNET_STATISTICS_update (cfg, "# transport addresses", 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (cfg,
+ "# transport addresses",
+ 1,
+ GNUNET_NO);
}
else if (GNUNET_NO == add_remove)
{
if (0 == addresses)
+ {
GNUNET_break (0);
+ }
else
{
addresses --;
- GNUNET_STATISTICS_update (cfg, "# transport addresses", -1, GNUNET_NO);
+ GNUNET_STATISTICS_update (cfg,
+ "# transport addresses",
+ -1,
+ GNUNET_NO);
}
}
-
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Transport now has %u addresses to communicate\n",
addresses);
- GST_hello_modify_addresses (add_remove, address);
+ GST_hello_modify_addresses (add_remove,
+ address);
}
}
GNUNET_assert (strlen (address->transport_name) > 0);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Notification from plugin `%s' about terminated %s session %p from peer `%s' address `%s'\n",
- address->transport_name,
- GNUNET_HELLO_address_check_option (address,
- GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound",
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Notification from plugin about terminated session %p from peer `%s' address `%s'\n",
session,
GNUNET_i2s (&address->peer),
GST_plugins_a2s (address));
GST_neighbours_session_terminated (&address->peer, session);
GST_ats_del_session (address, session);
- cancel_pending_blacklist_checks (address, session);
+ GST_blacklist_abort_matching (address, session);
for (sk = sk_head; NULL != sk; sk = sk->next)
{
}
-/**
- * Function that will be called to figure if an address is an loopback,
- * LAN, WAN etc. address
- *
- * @param cls closure
- * @param addr binary address
- * @param addrlen length of the @a addr
- * @return type of the network @a addr belongs to
- */
-static enum GNUNET_ATS_Network_Type
-plugin_env_address_to_type (void *cls,
- const struct sockaddr *addr,
- size_t addrlen)
-{
- if (NULL == GST_ats)
- {
- GNUNET_break(0);
- return GNUNET_ATS_NET_UNSPECIFIED;
- }
- return GNUNET_ATS_scanner_address_get_type (is,
- addr,
- addrlen);
-}
-
-
-/**
- * Function that will be called to update metrics for an address
- *
- * @param cls closure
- * @param address address to update metrics for
- * @param session the session
- * @param ats the ats information to update
- * @param ats_count the number of @a ats elements
- */
-static void
-plugin_env_update_metrics (void *cls,
- const struct GNUNET_HELLO_Address *address,
- struct Session *session,
- const struct GNUNET_ATS_Information *ats,
- uint32_t ats_count)
-{
- GST_ats_update_metrics (address,
- session,
- ats, ats_count);
-}
-
-
/**
* Black list check result from blacklist check triggered when a
* plugin gave us a new session in #plugin_env_session_start(). If
* connection to the peer is disallowed, kill the session.
*
- * @param cls blc_ctx bl context
+ * @param cls NULL
* @param peer the peer
+ * @param address address associated with the request
+ * @param session session associated with the request
* @param result the result
*/
static void
plugin_env_session_start_bl_check_cont (void *cls,
const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
int result)
{
- struct BlacklistCheckContext *blctx = cls;
-
- GNUNET_CONTAINER_DLL_remove (bc_head,
- bc_tail,
- blctx);
- blctx->blc = NULL;
if (GNUNET_OK != result)
{
- cancel_pending_blacklist_checks (blctx->address,
- blctx->session);
- kill_session (blctx->address->transport_name,
- blctx->session);
+ kill_session (address->transport_name,
+ session);
+ return;
+ }
+ if (GNUNET_YES !=
+ GNUNET_HELLO_address_check_option (address,
+ GNUNET_HELLO_ADDRESS_INFO_INBOUND))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Informing verifier about inbound session's address `%s'\n",
+ GST_plugins_a2s (address));
+ GST_validation_handle_address (address);
}
- GNUNET_HELLO_address_free (blctx->address);
- GNUNET_free (blctx);
}
* @param cls unused
* @param address the address
* @param session the new session
- * @param ats ats information
- * @param ats_count number of @a ats information
+ * @param scope network scope information
*/
static void
plugin_env_session_start (void *cls,
const struct GNUNET_HELLO_Address *address,
struct Session *session,
- const struct GNUNET_ATS_Information *ats,
- uint32_t ats_count)
+ enum GNUNET_ATS_Network_Type scope)
{
- struct BlacklistCheckContext *blctx;
- struct GST_BlacklistCheck *blc;
+ struct GNUNET_ATS_Properties prop;
if (NULL == address)
{
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Notification from plugin `%s' about new %s session %p from peer `%s' address `%s'\n",
+ "Notification from plugin `%s' about new session from peer `%s' address `%s'\n",
address->transport_name,
- GNUNET_HELLO_address_check_option (address,
- GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound",
- session,
GNUNET_i2s (&address->peer),
GST_plugins_a2s (address));
- if ( (GNUNET_YES ==
- GNUNET_HELLO_address_check_option (address,
- GNUNET_HELLO_ADDRESS_INFO_INBOUND)) ||
- (GNUNET_NO ==
- GST_ats_is_known (address, NULL) ) )
+ if (GNUNET_YES ==
+ GNUNET_HELLO_address_check_option (address,
+ GNUNET_HELLO_ADDRESS_INFO_INBOUND))
{
/* inbound is always new, but outbound MAY already be known, but
for example for UNIX, we have symmetric connections and thus we
may not know the address yet; add if necessary! */
- GST_ats_add_address (address,
- session,
- ats,
- ats_count);
- }
- else
- {
- GST_ats_new_session (address,
- session);
- GST_ats_update_metrics (address,
- session,
- ats,
- ats_count);
+ /* FIXME: maybe change API here so we just pass scope? */
+ memset (&prop, 0, sizeof (prop));
+ GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != scope);
+ prop.scope = scope;
+ GST_ats_add_inbound_address (address,
+ session,
+ &prop);
}
/* Do blacklist check if communication with this peer is allowed */
- blctx = GNUNET_new (struct BlacklistCheckContext);
- blctx->address = GNUNET_HELLO_address_copy (address);
- blctx->session = session;
- GNUNET_CONTAINER_DLL_insert (bc_head,
- bc_tail,
- blctx);
- if (NULL !=
- (blc = GST_blacklist_test_allowed (&address->peer,
- address->transport_name,
- &plugin_env_session_start_bl_check_cont,
- blctx)))
- {
- blctx->blc = blc;
- }
+ (void) GST_blacklist_test_allowed (&address->peer,
+ address->transport_name,
+ &plugin_env_session_start_bl_check_cont,
+ NULL,
+ address,
+ session);
}
uint32_t bw_in = ntohl (bandwidth_in.value__);
uint32_t bw_out = ntohl (bandwidth_out.value__);
+ if (NULL == peer)
+ {
+ /* ATS service died, all suggestions become invalid!
+ (but we'll keep using the allocations for a little
+ while, to keep going while ATS restarts) */
+ /* FIXME: We should drop all
+ connections now, as ATS won't explicitly tell
+ us and be unaware of ongoing resource allocations! */
+ return;
+ }
/* ATS tells me to disconnect from peer */
if ((0 == bw_in) && (0 == bw_out))
{
GST_neighbours_force_disconnect (peer);
return;
}
+ GNUNET_assert (NULL != address);
GNUNET_STATISTICS_update (GST_stats,
"# ATS suggestions received",
1,
GNUNET_NO);
GST_neighbours_switch_to_address (address,
session,
- bandwidth_in, bandwidth_out);
+ bandwidth_in,
+ bandwidth_out);
}
GST_ats = NULL;
GNUNET_ATS_connectivity_done (GST_ats_connect);
GST_ats_connect = NULL;
- GNUNET_ATS_scanner_done (is);
- is = NULL;
+ GNUNET_ATS_scanner_done (GST_is);
+ GST_is = NULL;
GST_clients_stop ();
GST_blacklist_stop ();
GST_hello_stop ();
"Limiting number of sockets to %u: validation %u, neighbors: %u\n",
max_fd, (max_fd / 3), (max_fd / 3) * 2);
- friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology",
- "FRIENDS-ONLY");
+ friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg,
+ "topology",
+ "FRIENDS-ONLY");
if (GNUNET_SYSERR == friend_only)
friend_only = GNUNET_NO; /* According to topology defaults */
/* start subsystems */
- GST_hello_start (friend_only, &process_hello_update, NULL );
- GNUNET_assert(NULL != GST_hello_get());
- GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity);
- is = GNUNET_ATS_scanner_init ();
+ GST_blacklist_start (GST_server,
+ GST_cfg,
+ &GST_my_identity);
+ GST_is = GNUNET_ATS_scanner_init ();
GST_ats_connect = GNUNET_ATS_connectivity_init (GST_cfg);
GST_ats = GNUNET_ATS_scheduling_init (GST_cfg,
&ats_request_address_change,
NULL);
GST_ats_init ();
- GST_manipulation_init (GST_cfg);
+ GST_manipulation_init ();
GST_plugins_load (&GST_manipulation_recv,
&plugin_env_address_change_notification,
&plugin_env_session_start,
- &plugin_env_session_end,
- &plugin_env_address_to_type,
- &plugin_env_update_metrics);
+ &plugin_env_session_end);
+ GST_hello_start (friend_only,
+ &process_hello_update,
+ NULL);
GST_neighbours_start ((max_fd / 3) * 2);
GST_clients_start (GST_server);
GST_validation_start ((max_fd / 3));
* @return 0 ok, 1 on error
*/
int
-main (int argc, char * const *argv)
+main (int argc,
+ char * const *argv)
{
return
(GNUNET_OK