ar->bandwidth_out = sbc->bw_out;
GNUNET_BANDWIDTH_tracker_update_quota (&ar->available_recv_window,
ar->bandwidth_in);
- sbc->atc->alloc_cb (sbc->atc->alloc_cb_cls,
- (const struct GNUNET_PeerIdentity *) key,
- ar->plugin_name, ar->session, ar->plugin_addr,
- ar->plugin_addr_len, ar->bandwidth_out, ar->bandwidth_in);
+ if (NULL != sbc->atc->alloc_cb)
+ sbc->atc->alloc_cb (sbc->atc->alloc_cb_cls,
+ (const struct GNUNET_PeerIdentity *) key,
+ ar->plugin_name, ar->session, ar->plugin_addr,
+ ar->plugin_addr_len, ar->bandwidth_out, ar->bandwidth_in);
}
else if (ntohl (ar->bandwidth_out.value__) > 0)
{
ar->bandwidth_in = GNUNET_BANDWIDTH_value_init (0);
ar->bandwidth_out = GNUNET_BANDWIDTH_value_init (0);
- sbc->atc->alloc_cb (sbc->atc->alloc_cb_cls,
- (const struct GNUNET_PeerIdentity *) key,
- ar->plugin_name, ar->session, ar->plugin_addr,
- ar->plugin_addr_len, ar->bandwidth_out, ar->bandwidth_in);
+ if (NULL != sbc->atc->alloc_cb)
+ sbc->atc->alloc_cb (sbc->atc->alloc_cb_cls,
+ (const struct GNUNET_PeerIdentity *) key,
+ ar->plugin_name, ar->session, ar->plugin_addr,
+ ar->plugin_addr_len, ar->bandwidth_out, ar->bandwidth_in);
}
return GNUNET_YES;
}
check_PROGRAMS = \
test_core_api_start_only \
test_core_api \
- test_core_api_preferences \
test_core_api_reliability \
test_core_quota_compliance_symmetric \
test_core_quota_compliance_asymmetric_send_limited \
};
-/**
- * Message sent to the core asking for configuration
- * information and possibly preference changes.
- */
-struct RequestInfoMessage
-{
- /**
- * Header with type GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Unique request ID.
- */
- uint32_t rim_id GNUNET_PACKED;
-
- /**
- * Reserved, always zero.
- */
- uint32_t reserved GNUNET_PACKED;
-
- /**
- * Number of bytes of inbound traffic to reserve, can
- * be negative (to unreserve). NBO.
- */
- int32_t reserve_inbound GNUNET_PACKED;
-
- /**
- * Increment the current traffic preference for the given peer by
- * the specified amont. The traffic preference is used to determine
- * the share of bandwidth this peer will typcially be assigned.
- */
- uint64_t preference_change GNUNET_PACKED;
-
- /**
- * Identity of the peer being configured.
- */
- struct GNUNET_PeerIdentity peer;
-
-};
-
-
-/**
- * Response from the core to a "RequestInfoMessage"
- * providing traffic status information for a peer.
- */
-struct ConfigurationInfoMessage
-{
- /**
- * Header with type GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Amount of traffic (inbound number of bytes) that was reserved in
- * response to the configuration change request. Negative for
- * "unreserved" bytes.
- */
- int32_t reserved_amount GNUNET_PACKED;
-
- /**
- * If the reservation request could not be satisfied (reserved_amount
- * was zero), how long should the client wait until retrying? 0 if
- * bandwidth was reserved.
- */
- struct GNUNET_TIME_RelativeNBO reserve_delay;
-
- /**
- * Unique request ID.
- */
- uint32_t rim_id GNUNET_PACKED;
-
- /**
- * Available bandwidth out for this peer,
- * 0 if we have been disconnected.
- */
- struct GNUNET_BANDWIDTH_Value32NBO bw_out;
-
- /**
- * Current traffic preference for the peer.
- * 0 if we have been disconnected.
- */
- uint64_t preference;
-
- /**
- * Identity of the peer.
- */
- struct GNUNET_PeerIdentity peer;
-
-};
-
-
/**
* Client notifying core about the maximum-priority
* message it has in the queue for a particular target.
*/
struct GNUNET_CORE_TransmitHandle *pending_tail;
- /**
- * Pending callback waiting for peer information, or NULL for none.
- */
- GNUNET_CORE_PeerConfigurationInfoCallback pcic;
-
- /**
- * Closure for pcic.
- */
- void *pcic_cls;
-
- /**
- * Pointer to free when we call pcic and to use to cancel
- * preference change on disconnect.
- */
- struct GNUNET_CORE_InformationRequestContext *pcic_ptr;
-
- /**
- * Request information ID for the given pcic (needed in case a
- * request is cancelled after being submitted to core and a new
- * one is generated; in this case, we need to avoid matching the
- * reply to the first (cancelled) request to the second request).
- */
- uint32_t rim_id;
-
/**
* ID of timeout task for the 'pending_head' handle
* which is the one with the smallest timeout.
*/
struct GNUNET_TIME_Relative retry_backoff;
- /**
- * Request information ID generator.
- */
- uint32_t rim_id_gen;
-
/**
* Number of messages we are allowed to queue per target.
*/
struct GNUNET_CORE_Handle *h = cls;
struct GNUNET_CORE_TransmitHandle *th;
struct PeerRecord *pr = value;
- GNUNET_CORE_PeerConfigurationInfoCallback pcic;
- void *pcic_cls;
if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
{
h->disconnects (h->cls, &pr->peer);
/* all requests should have been cancelled, clean up anyway, just in case */
GNUNET_break (pr->queue_size == 0);
- if (NULL != (pcic = pr->pcic))
- {
- GNUNET_break (0);
- pcic_cls = pr->pcic_cls;
- GNUNET_CORE_peer_change_preference_cancel (pr->pcic_ptr);
- pcic (pcic_cls, &pr->peer, 0, GNUNET_TIME_UNIT_FOREVER_REL);
- }
while (NULL != (th = pr->pending_head))
{
GNUNET_break (0);
const struct DisconnectNotifyMessage *dnm;
const struct NotifyTrafficMessage *ntm;
const struct GNUNET_MessageHeader *em;
- const struct ConfigurationInfoMessage *cim;
const struct PeerStatusNotifyMessage *psnm;
const struct SendMessageReady *smr;
const struct GNUNET_CORE_MessageHandler *mh;
GNUNET_CORE_StartupCallback init;
- GNUNET_CORE_PeerConfigurationInfoCallback pcic;
struct PeerRecord *pr;
struct GNUNET_CORE_TransmitHandle *th;
unsigned int hpos;
GNUNET_CONTAINER_DLL_insert (h->ready_peer_head, h->ready_peer_tail, pr);
trigger_next_request (h, GNUNET_NO);
break;
- case GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO:
- if (ntohs (msg->size) != sizeof (struct ConfigurationInfoMessage))
- {
- GNUNET_break (0);
- reconnect_later (h);
- return;
- }
- cim = (const struct ConfigurationInfoMessage *) msg;
- if (0 == memcmp (&h->me, &cim->peer, sizeof (struct GNUNET_PeerIdentity)))
- {
- /* self-change!? */
- GNUNET_break (0);
- return;
- }
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received notification about configuration update for `%s' with RIM %u.\n",
- GNUNET_i2s (&cim->peer), (unsigned int) ntohl (cim->rim_id));
-#endif
- pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &cim->peer.hashPubKey);
- if (pr == NULL)
- {
- GNUNET_break (0);
- reconnect_later (h);
- return;
- }
- if (pr->rim_id != ntohl (cim->rim_id))
- {
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Reservation ID mismatch in notification...\n");
-#endif
- break;
- }
- pcic = pr->pcic;
- pr->pcic = NULL;
- GNUNET_free_non_null (pr->pcic_ptr);
- pr->pcic_ptr = NULL;
- if (pcic != NULL)
- pcic (pr->pcic_cls, &pr->peer, ntohl (cim->reserved_amount),
- GNUNET_TIME_relative_ntoh (cim->reserve_delay));
- break;
default:
reconnect_later (h);
return;
}
-/* ****************** GNUNET_CORE_peer_change_preference ******************** */
-
-
-struct GNUNET_CORE_InformationRequestContext
-{
-
- /**
- * Our connection to the service.
- */
- struct GNUNET_CORE_Handle *h;
-
- /**
- * Link to control message, NULL if CM was sent.
- */
- struct ControlMessage *cm;
-
- /**
- * Link to peer record.
- */
- struct PeerRecord *pr;
-};
-
-
-/**
- * CM was sent, remove link so we don't double-free.
- *
- * @param cls the 'struct GNUNET_CORE_InformationRequestContext'
- * @param success were we successful?
- */
-static void
-change_preference_send_continuation (void *cls, int success)
-{
- struct GNUNET_CORE_InformationRequestContext *irc = cls;
-
- irc->cm = NULL;
-}
-
-
-/**
- * Obtain statistics and/or change preferences for the given peer.
- *
- * @param h core handle
- * @param peer identifies the peer
- * @param amount reserve N bytes for receiving, negative
- * amounts can be used to undo a (recent) reservation;
- * @param preference increase incoming traffic share preference by this amount;
- * in the absence of "amount" reservations, we use this
- * preference value to assign proportional bandwidth shares
- * to all connected peers
- * @param info function to call with the resulting configuration information
- * @param info_cls closure for info
- * @return NULL on error
- */
-struct GNUNET_CORE_InformationRequestContext *
-GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
- const struct GNUNET_PeerIdentity *peer,
- int32_t amount, uint64_t preference,
- GNUNET_CORE_PeerConfigurationInfoCallback
- info, void *info_cls)
-{
- struct GNUNET_CORE_InformationRequestContext *irc;
- struct PeerRecord *pr;
- struct RequestInfoMessage *rim;
- struct ControlMessage *cm;
-
- pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &peer->hashPubKey);
- if (NULL == pr)
- {
- /* attempt to change preference on peer that is not connected */
- GNUNET_assert (0);
- return NULL;
- }
- if (pr->pcic != NULL)
- {
- /* second change before first one is done */
- GNUNET_break (0);
- return NULL;
- }
- irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
- irc->h = h;
- irc->pr = pr;
- cm = GNUNET_malloc (sizeof (struct ControlMessage) +
- sizeof (struct RequestInfoMessage));
- cm->cont = &change_preference_send_continuation;
- cm->cont_cls = irc;
- irc->cm = cm;
- rim = (struct RequestInfoMessage *) &cm[1];
- rim->header.size = htons (sizeof (struct RequestInfoMessage));
- rim->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO);
- rim->rim_id = htonl (pr->rim_id = h->rim_id_gen++);
- rim->reserved = htonl (0);
- rim->reserve_inbound = htonl (amount);
- rim->preference_change = GNUNET_htonll (preference);
- rim->peer = *peer;
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Queueing CHANGE PREFERENCE request for peer `%s' with RIM %u\n",
- GNUNET_i2s (peer), (unsigned int) pr->rim_id);
-#endif
- GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
- h->control_pending_tail, cm);
- pr->pcic = info;
- pr->pcic_cls = info_cls;
- pr->pcic_ptr = irc; /* for free'ing irc */
- if (NULL != h->client)
- trigger_next_request (h, GNUNET_NO);
- return irc;
-}
-
-
-/**
- * Cancel request for getting information about a peer.
- * Note that an eventual change in preference, trust or bandwidth
- * assignment MAY have already been committed at the time,
- * so cancelling a request is NOT sure to undo the original
- * request. The original request may or may not still commit.
- * The only thing cancellation ensures is that the callback
- * from the original request will no longer be called.
- *
- * @param irc context returned by the original GNUNET_CORE_peer_get_info call
- */
-void
-GNUNET_CORE_peer_change_preference_cancel (struct
- GNUNET_CORE_InformationRequestContext
- *irc)
-{
- struct GNUNET_CORE_Handle *h = irc->h;
- struct PeerRecord *pr = irc->pr;
-
- GNUNET_assert (pr->pcic_ptr == irc);
- if (irc->cm != NULL)
- {
- GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
- h->control_pending_tail, irc->cm);
- GNUNET_free (irc->cm);
- }
- pr->pcic = NULL;
- pr->pcic_cls = NULL;
- pr->pcic_ptr = NULL;
- GNUNET_free (irc);
-}
-
-
/* end of core_api.c */
*/
struct GNUNET_BANDWIDTH_Tracker available_send_window;
- /**
- * Tracking bandwidth for receiving from this peer.
- */
- struct GNUNET_BANDWIDTH_Tracker available_recv_window;
-
/**
* How valueable were the messages of this peer recently?
*/
}
-/**
- * Helper function for update_preference_sum.
- */
-static int
-update_preference (void *cls, const GNUNET_HashCode * key, void *value)
-{
- unsigned long long *ps = cls;
- struct Neighbour *n = value;
-
- n->current_preference /= 2;
- *ps += n->current_preference;
- return GNUNET_OK;
-}
-
-
-/**
- * A preference value for a neighbour was update. Update
- * the preference sum accordingly.
- *
- * @param inc how much was a preference value increased?
- */
-static void
-update_preference_sum (unsigned long long inc)
-{
- unsigned long long os;
-
- os = preference_sum;
- preference_sum += inc;
- if (preference_sum >= os)
- return; /* done! */
- /* overflow! compensate by cutting all values in half! */
- preference_sum = 0;
- GNUNET_CONTAINER_multihashmap_iterate (neighbours, &update_preference,
- &preference_sum);
- GNUNET_STATISTICS_set (stats, gettext_noop ("# total peer preference"),
- preference_sum, GNUNET_NO);
-}
-
-
/**
* Find the entry for the given neighbour.
*
}
-/**
- * Handle REQUEST_INFO request.
- *
- * @param cls unused
- * @param client client sending the request
- * @param message iteration request message
- */
-static void
-handle_client_request_info (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- const struct RequestInfoMessage *rcm;
- struct Client *pos;
- struct Neighbour *n;
- struct ConfigurationInfoMessage cim;
- int32_t want_reserv;
- int32_t got_reserv;
- unsigned long long old_preference;
- struct GNUNET_TIME_Relative rdelay;
-
- rdelay = GNUNET_TIME_relative_get_zero ();
-#if DEBUG_CORE_CLIENT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service receives `%s' request.\n",
- "REQUEST_INFO");
-#endif
- pos = clients;
- while (pos != NULL)
- {
- if (client == pos->client_handle)
- break;
- pos = pos->next;
- }
- if (pos == NULL)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- rcm = (const struct RequestInfoMessage *) message;
- n = find_neighbour (&rcm->peer);
- memset (&cim, 0, sizeof (cim));
- if ((n != NULL) && (GNUNET_YES == n->is_connected))
- {
- want_reserv = ntohl (rcm->reserve_inbound);
- if (want_reserv < 0)
- {
- got_reserv = want_reserv;
- }
- else if (want_reserv > 0)
- {
- rdelay =
- GNUNET_BANDWIDTH_tracker_get_delay (&n->available_recv_window,
- want_reserv);
- if (rdelay.rel_value == 0)
- got_reserv = want_reserv;
- else
- got_reserv = 0; /* all or nothing */
- }
- else
- got_reserv = 0;
- GNUNET_BANDWIDTH_tracker_consume (&n->available_recv_window, got_reserv);
- old_preference = n->current_preference;
- n->current_preference += GNUNET_ntohll (rcm->preference_change);
- if (old_preference > n->current_preference)
- {
- /* overflow; cap at maximum value */
- n->current_preference = ULLONG_MAX;
- }
- update_preference_sum (n->current_preference - old_preference);
-#if DEBUG_CORE_QUOTA
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received reservation request for %d bytes for peer `%4s', reserved %d bytes, suggesting delay of %llu ms\n",
- (int) want_reserv, GNUNET_i2s (&rcm->peer), (int) got_reserv,
- (unsigned long long) rdelay.rel_value);
-#endif
- cim.reserved_amount = htonl (got_reserv);
- cim.reserve_delay = GNUNET_TIME_relative_hton (rdelay);
- cim.bw_out = n->bw_out;
- cim.preference = n->current_preference;
- }
- else
- {
- /* Technically, this COULD happen (due to asynchronous behavior),
- * but it should be rare, so we should generate an info event
- * to help diagnosis of serious errors that might be masked by this */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _
- ("Client asked for preference change with peer `%s', which is not connected!\n"),
- GNUNET_i2s (&rcm->peer));
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
- cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
- cim.peer = rcm->peer;
- cim.rim_id = rcm->rim_id;
-#if DEBUG_CORE_CLIENT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
- "CONFIGURATION_INFO");
-#endif
- send_to_client (pos, &cim.header, GNUNET_NO);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
/**
* Free the given entry for the neighbour (it has
* already been removed from the list at this point).
(n->bw_out.value__ != q_out_min.value__))
{
if (n->bw_in.value__ != q_in.value__)
- {
n->bw_in = q_in;
- GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
- n->bw_in);
- }
if (n->bw_out.value__ != q_out_min.value__)
n->bw_out = q_out_min;
if (GNUNET_YES == n->is_connected)
update_neighbour_performance (n, ats, ats_count);
GNUNET_BANDWIDTH_tracker_init (&n->available_send_window, n->bw_out,
MAX_WINDOW_TIME_S);
- GNUNET_BANDWIDTH_tracker_init (&n->available_recv_window, n->bw_in,
- MAX_WINDOW_TIME_S);
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received connection from `%4s'.\n",
GNUNET_i2s (&n->peer));
GNUNET_MESSAGE_TYPE_CORE_PEER_CONNECTED,
sizeof (struct GNUNET_MessageHeader) +
sizeof (struct GNUNET_PeerIdentity)},
- {&handle_client_request_info, NULL,
- GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
- sizeof (struct RequestInfoMessage)},
{&handle_client_send_request, NULL,
GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
sizeof (struct SendMessageRequest)},
GNUNET_MESSAGE_TYPE_CORE_PEER_CONNECTED,
sizeof (struct GNUNET_MessageHeader) +
sizeof (struct GNUNET_PeerIdentity)},
- {&GSC_SESSIONS_handle_client_request_info, NULL,
- GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
- sizeof (struct RequestInfoMessage)},
{&handle_client_send_request, NULL,
GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
sizeof (struct SendMessageRequest)},
*/
GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task;
- /**
- * Tracking bandwidth for sending to this peer.
- */
- struct GNUNET_BANDWIDTH_Tracker available_recv_window;
-
};
#endif
n = GNUNET_malloc (sizeof (struct Neighbour));
n->peer = *peer;
- GNUNET_BANDWIDTH_tracker_init (&n->available_recv_window,
- GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT,
- MAX_WINDOW_TIME_S);
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (neighbours,
&n->peer.hashPubKey, n,
*/
GNUNET_SCHEDULER_TaskIdentifier cork_task;
- /**
- * Tracking bandwidth for receiving from this peer.
- * // FIXME: need to set it!
- */
- struct GNUNET_BANDWIDTH_Tracker available_recv_window;
-
/**
* Available bandwidth out for this peer (current target). This
* value should be the 'MIN' of 'bw_out_internal_limit' and
}
-/**
- * Handle REQUEST_INFO request. For this request type, the client must
- * have transmitted an INIT first.
- *
- * @param cls unused
- * @param client client sending the request
- * @param message iteration request message
- */
-void
-GSC_SESSIONS_handle_client_request_info (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- const struct RequestInfoMessage *rcm;
- struct Session *session;
- struct ConfigurationInfoMessage cim;
- int32_t want_reserv;
- int32_t got_reserv;
- struct GNUNET_TIME_Relative rdelay;
-
- rdelay = GNUNET_TIME_UNIT_ZERO;
-#if DEBUG_CORE_CLIENT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Core service receives `%s' request.\n",
- "REQUEST_INFO");
-#endif
- rcm = (const struct RequestInfoMessage *) message;
- session = find_session (&rcm->peer);
- if (NULL == session)
- {
- /* Technically, this COULD happen (due to asynchronous behavior),
- * but it should be rare, so we should generate an info event
- * to help diagnosis of serious errors that might be masked by this */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Client asked for preference change with peer `%s', which is not connected!\n"),
- GNUNET_i2s (&rcm->peer));
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
-
- want_reserv = ntohl (rcm->reserve_inbound);
- if (want_reserv < 0)
- {
- got_reserv = want_reserv;
- }
- else if (want_reserv > 0)
- {
- rdelay =
- GNUNET_BANDWIDTH_tracker_get_delay (&session->available_recv_window,
- want_reserv);
- if (rdelay.rel_value == 0)
- got_reserv = want_reserv;
- else
- got_reserv = 0; /* all or nothing */
- }
- else
- got_reserv = 0;
- GNUNET_BANDWIDTH_tracker_consume (&session->available_recv_window, got_reserv);
-#if DEBUG_CORE_QUOTA
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received reservation request for %d bytes for peer `%4s', reserved %d bytes, suggesting delay of %llu ms\n",
- (int) want_reserv, GNUNET_i2s (&rcm->peer), (int) got_reserv,
- (unsigned long long) rdelay.rel_value);
-#endif
- cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
- cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
- cim.reserved_amount = htonl (got_reserv);
- cim.reserve_delay = GNUNET_TIME_relative_hton (rdelay);
- cim.rim_id = rcm->rim_id;
- cim.bw_out = session->bw_out;
- cim.preference = 0; /* FIXME: remove */
- cim.peer = rcm->peer;
- GSC_CLIENTS_send_to_client (client, &cim.header, GNUNET_NO);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
/**
* Update information about a session.
*
const struct GNUNET_MessageHeader *message);
-/**
- * Handle REQUEST_INFO request. For this request type, the client must have
- * transmitted an INIT first.
- *
- * @param cls unused
- * @param client client sending the request
- * @param message iteration request message
- */
-void
-GSC_SESSIONS_handle_client_request_info (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message);
-
/**
* Initialize sessions subsystem.
+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2009, 2010, 2011 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
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- 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.
-*/
-/**
- * @file core/test_core_api_preferences.c
- * @brief testcase for core_api.c's GNUNET_CORE_change_preference
- */
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_arm_service.h"
-#include "gnunet_core_service.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_os_lib.h"
-#include "gnunet_program_lib.h"
-#include "gnunet_scheduler_lib.h"
-#include "gnunet_transport_service.h"
-
-#define VERBOSE GNUNET_EXTRA_LOGGING
-
-#define START_ARM GNUNET_YES
-
-#define MTYPE 12345
-
-struct PeerContext
-{
- struct GNUNET_CONFIGURATION_Handle *cfg;
- struct GNUNET_CORE_Handle *ch;
- struct GNUNET_PeerIdentity id;
- struct GNUNET_TRANSPORT_Handle *th;
- struct GNUNET_TRANSPORT_GetHelloHandle *ghh;
- struct GNUNET_MessageHeader *hello;
- int connect_status;
-#if START_ARM
- struct GNUNET_OS_Process *arm_proc;
-#endif
-};
-
-static struct PeerContext p1;
-
-static struct PeerContext p2;
-
-static GNUNET_SCHEDULER_TaskIdentifier err_task;
-
-static int ok;
-
-#if VERBOSE
-#define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
-#else
-#define OKPP do { ok++; } while (0)
-#endif
-
-static struct GNUNET_CORE_InformationRequestContext *irc;
-
-static struct GNUNET_CORE_TransmitHandle *th;
-
-static GNUNET_SCHEDULER_TaskIdentifier irc_task;
-
-static GNUNET_SCHEDULER_TaskIdentifier ask_task;
-
-static unsigned int total_reserve = 5;
-
-
-static void
-process_hello (void *cls, const struct GNUNET_MessageHeader *message);
-
-static void
-terminate_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-#if VERBOSE
- fprintf (stderr, "Regular shutdown\n");
-#endif
- GNUNET_assert (ok == 6);
- GNUNET_assert (NULL == irc);
- GNUNET_TRANSPORT_get_hello_cancel (p1.ghh);
- GNUNET_TRANSPORT_get_hello_cancel (p2.ghh);
- GNUNET_CORE_disconnect (p1.ch);
- GNUNET_CORE_disconnect (p2.ch);
- GNUNET_TRANSPORT_disconnect (p1.th);
- GNUNET_TRANSPORT_disconnect (p2.th);
- ok = 0;
-}
-
-
-static void
-terminate_task_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- err_task = GNUNET_SCHEDULER_NO_TASK;
-#if VERBOSE
- fprintf (stderr, "ENDING ANGRILY %u\n", ok);
-#endif
- GNUNET_break (0);
- if (NULL != irc)
- {
- GNUNET_CORE_peer_change_preference_cancel (irc);
- irc = NULL;
- }
- if (GNUNET_SCHEDULER_NO_TASK != irc_task)
- {
- GNUNET_SCHEDULER_cancel (irc_task);
- irc_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (GNUNET_SCHEDULER_NO_TASK != ask_task)
- {
- GNUNET_SCHEDULER_cancel (ask_task);
- ask_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_TRANSPORT_get_hello_cancel (p1.ghh);
- GNUNET_TRANSPORT_get_hello_cancel (p2.ghh);
- GNUNET_CORE_disconnect (p1.ch);
- GNUNET_CORE_disconnect (p2.ch);
- GNUNET_TRANSPORT_disconnect (p1.th);
- GNUNET_TRANSPORT_disconnect (p2.th);
- ok = 42;
-}
-
-
-static size_t
-transmit_ready (void *cls, size_t size, void *buf)
-{
- struct PeerContext *p = cls;
- struct GNUNET_MessageHeader *m;
-
- th = NULL;
- GNUNET_assert (ok == 4);
- OKPP;
- GNUNET_assert (p == &p1);
- GNUNET_assert (buf != NULL);
- m = (struct GNUNET_MessageHeader *) buf;
- m->type = htons (MTYPE);
- m->size = htons (sizeof (struct GNUNET_MessageHeader));
- err_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 120),
- &terminate_task_error, NULL);
-
- return sizeof (struct GNUNET_MessageHeader);
-}
-
-static void
-preference_cb (void *cls, const struct GNUNET_PeerIdentity *peer,
- int32_t amount,
- struct GNUNET_TIME_Relative res_delay);
-
-static void
-do_reserve (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct PeerContext *pc = cls;
-
- irc_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Aborted during attempt to request reservation\n");
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting reservatin of 32k from core in 1s!\n");
- irc =
- GNUNET_CORE_peer_change_preference (p1.ch, &p2.id,
- 1000000 /* bandwidth for 1s */ ,
- 0, &preference_cb, pc);
-}
-
-static void
-preference_cb (void *cls, const struct GNUNET_PeerIdentity *peer,
- int32_t amount,
- struct GNUNET_TIME_Relative res_delay)
-{
- struct PeerContext *pc = cls;
-
- irc = NULL;
- if (0 == amount)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Delaying reservation request by %llu ms!\n",
- (unsigned long long) res_delay.rel_value);
- irc_task = GNUNET_SCHEDULER_add_delayed (res_delay, &do_reserve, pc);
- return;
- }
- total_reserve--;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reservation done!\n");
- if (total_reserve > 0)
- {
- irc_task = GNUNET_SCHEDULER_add_now (&do_reserve, pc);
- return;
- }
- GNUNET_SCHEDULER_cancel (err_task);
- err_task = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Asking core (1) for transmission to peer `%4s'\n",
- GNUNET_i2s (&p2.id));
- if (NULL ==
- (th =
- GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_YES, 0,
- GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 45),
- &p2.id,
- sizeof (struct GNUNET_MessageHeader),
- &transmit_ready, &p1)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n",
- GNUNET_i2s (&p2.id));
- }
-}
-
-
-static void
-connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_TRANSPORT_ATS_Information *atsi)
-{
- struct PeerContext *pc = cls;
-
- if (0 == memcmp (&pc->id, peer, sizeof (struct GNUNET_PeerIdentity)))
- return;
- GNUNET_assert (pc->connect_status == 0);
- pc->connect_status = 1;
- if (pc == &p1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Encrypted connection established to peer `%4s'\n",
- GNUNET_i2s (peer));
- if (GNUNET_SCHEDULER_NO_TASK != ask_task)
- {
- GNUNET_SCHEDULER_cancel (ask_task);
- ask_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_SCHEDULER_cancel (err_task);
- err_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 120),
- &terminate_task_error, NULL);
- irc_task = GNUNET_SCHEDULER_add_now (&do_reserve, pc);
- }
-}
-
-
-static void
-disconnect_notify (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- struct PeerContext *pc = cls;
-
- if (0 == memcmp (&pc->id, peer, sizeof (struct GNUNET_PeerIdentity)))
- return;
- pc->connect_status = 0;
- if (GNUNET_SCHEDULER_NO_TASK != irc_task)
- {
- GNUNET_SCHEDULER_cancel (irc_task);
- irc_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (0 == memcmp (peer, &p1.id, sizeof (struct GNUNET_PeerIdentity)))
- {
- if (irc != NULL)
- {
- GNUNET_CORE_peer_change_preference_cancel (irc);
- irc = NULL;
- }
- if (th != NULL)
- {
- GNUNET_CORE_notify_transmit_ready_cancel (th);
- th = NULL;
- }
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted connection to `%4s' cut\n",
- GNUNET_i2s (peer));
-}
-
-
-static int
-inbound_notify (void *cls, const struct GNUNET_PeerIdentity *other,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_TRANSPORT_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Core provides inbound data from `%4s'.\n", GNUNET_i2s (other));
- return GNUNET_OK;
-}
-
-
-static int
-outbound_notify (void *cls, const struct GNUNET_PeerIdentity *other,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_TRANSPORT_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Core notifies about outbound data for `%4s'.\n",
- GNUNET_i2s (other));
- return GNUNET_OK;
-}
-
-
-
-static int
-process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_TRANSPORT_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving message from `%4s'.\n",
- GNUNET_i2s (peer));
- GNUNET_assert (ok == 5);
- OKPP;
- GNUNET_SCHEDULER_cancel (err_task);
- err_task = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_SCHEDULER_add_now (&terminate_task, NULL);
- return GNUNET_OK;
-}
-
-
-static struct GNUNET_CORE_MessageHandler handlers[] = {
- {&process_mtype, MTYPE, sizeof (struct GNUNET_MessageHeader)},
- {NULL, 0, 0}
-};
-
-
-
-static void
-ask_connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- ask_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &ask_connect_task,
- NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Asking core (1) AGAIN to connect to peer `%4s'\n",
- GNUNET_i2s (&p2.id));
- GNUNET_TRANSPORT_try_connect (p1.th, &p2.id);
-}
-
-
-static void
-init_notify (void *cls, struct GNUNET_CORE_Handle *server,
- const struct GNUNET_PeerIdentity *my_identity)
-{
- struct PeerContext *p = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core connection to `%4s' established\n",
- GNUNET_i2s (my_identity));
- GNUNET_assert (server != NULL);
- p->id = *my_identity;
- p->ch = server;
- if (cls == &p1)
- {
- GNUNET_assert (ok == 2);
- OKPP;
- /* connect p2 */
- GNUNET_CORE_connect (p2.cfg, 1, &p2, &init_notify, &connect_notify,
- &disconnect_notify, NULL, &inbound_notify, GNUNET_YES,
- &outbound_notify, GNUNET_YES, handlers);
- }
- else
- {
- GNUNET_assert (ok == 3);
- OKPP;
- GNUNET_assert (cls == &p2);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Asking core (1) to connect to peer `%4s'\n",
- GNUNET_i2s (&p2.id));
- err_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 60),
- &terminate_task_error, NULL);
- if (GNUNET_SCHEDULER_NO_TASK != ask_task)
- GNUNET_SCHEDULER_cancel (ask_task);
- ask_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &ask_connect_task, NULL);
- GNUNET_TRANSPORT_try_connect (p1.th, &p2.id);
- }
-}
-
-
-static void
-process_hello (void *cls, const struct GNUNET_MessageHeader *message)
-{
- struct PeerContext *p = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received (my) `%s' from transport service\n", "HELLO");
- GNUNET_assert (message != NULL);
- p->hello = GNUNET_malloc (ntohs (message->size));
- memcpy (p->hello, message, ntohs (message->size));
- if ((p == &p1) && (p2.th != NULL))
- GNUNET_TRANSPORT_offer_hello (p2.th, message, NULL, NULL);
- if ((p == &p2) && (p1.th != NULL))
- GNUNET_TRANSPORT_offer_hello (p1.th, message, NULL, NULL);
-
- if ((p == &p1) && (p2.hello != NULL) && (p1.th != NULL))
- GNUNET_TRANSPORT_offer_hello (p1.th, p2.hello, NULL, NULL);
- if ((p == &p2) && (p1.hello != NULL) && (p2.th != NULL))
- GNUNET_TRANSPORT_offer_hello (p2.th, p1.hello, NULL, NULL);
-}
-
-
-
-static void
-setup_peer (struct PeerContext *p, const char *cfgname)
-{
- p->cfg = GNUNET_CONFIGURATION_create ();
-#if START_ARM
- p->arm_proc =
- GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
- "gnunet-service-arm",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
- "-c", cfgname, NULL);
-#endif
- GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
- p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL, p, NULL, NULL, NULL);
- GNUNET_assert (p->th != NULL);
- p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p);
-}
-
-
-static void
-run (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- GNUNET_assert (ok == 1);
- OKPP;
- setup_peer (&p1, "test_core_quota_asymmetric_recv_limited_peer1.conf");
- setup_peer (&p2, "test_core_quota_asymmetric_recv_limited_peer2.conf");
- GNUNET_CORE_connect (p1.cfg, 1, &p1, &init_notify, &connect_notify,
- &disconnect_notify, NULL, &inbound_notify, GNUNET_YES,
- &outbound_notify, GNUNET_YES, handlers);
-}
-
-static void
-stop_arm (struct PeerContext *p)
-{
-#if START_ARM
- if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
- if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK)
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
- GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
- p->arm_proc = NULL;
-#endif
- GNUNET_CONFIGURATION_destroy (p->cfg);
-}
-
-static int
-check ()
-{
- char *const argv[] = { "test-core-api-preferences",
- "-c",
- "test_core_api_data.conf",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
- NULL
- };
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
- ok = 1;
- GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv,
- "test-core-api-preferences", "nohelp", options, &run,
- &ok);
- stop_arm (&p1);
- stop_arm (&p2);
- return ok;
-}
-
-int
-main (int argc, char *argv[])
-{
- int ret;
-
- GNUNET_log_setup ("test-core-api",
-#if VERBOSE
- "DEBUG",
-#else
- "WARNING",
-#endif
- NULL);
- ret = check ();
- GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-1");
- GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-2");
-
- return ret;
-}
-
-/* end of test_core_api_preferences.c */
GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle);
-/**
- * Function called with perference change information about the given peer.
- *
- * @param cls closure
- * @param peer identifies the peer
- * @param amount set to the amount that was actually reserved or unreserved;
- * either the full requested amount or zero (no partial reservations)
- * @param res_delay if the reservation could not be satisfied (amount was 0), how
- * long should the client wait until re-trying?
- */
-typedef void (*GNUNET_CORE_PeerConfigurationInfoCallback) (void *cls,
- const struct
- GNUNET_PeerIdentity *
- peer,
- int32_t amount,
- struct
- GNUNET_TIME_Relative
- res_delay);
-
-
-
-/**
- * Context that can be used to cancel a peer information request.
- */
-struct GNUNET_CORE_InformationRequestContext;
-
-
-/**
- * Obtain statistics and/or change preferences for the given peer.
- * You can only have one such pending request per peer.
- *
- * @param h core handle
- * @param peer identifies the peer
- * @param amount reserve N bytes for receiving, negative
- * amounts can be used to undo a (recent) reservation;
- * @param preference increase incoming traffic share preference by this amount;
- * in the absence of "amount" reservations, we use this
- * preference value to assign proportional bandwidth shares
- * to all connected peers
- * @param info function to call with the resulting configuration information
- * @param info_cls closure for info
- * @return NULL on error
- * @deprecated will be replaced soon
- */
-struct GNUNET_CORE_InformationRequestContext *
-GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
- const struct GNUNET_PeerIdentity *peer,
- int32_t amount, uint64_t preference,
- GNUNET_CORE_PeerConfigurationInfoCallback
- info, void *info_cls);
-
-
-/**
- * Cancel request for getting information about a peer.
- * Note that an eventual change in preference, trust or bandwidth
- * assignment MAY have already been committed at the time,
- * so cancelling a request is NOT sure to undo the original
- * request. The original request may or may not still commit.
- * The only thing cancellation ensures is that the callback
- * from the original request will no longer be called.
- *
- * @param irc context returned by the original GNUNET_CORE_peer_get_info call
- * @deprecated will be replaced soon
- */
-void
-GNUNET_CORE_peer_change_preference_cancel (struct
- GNUNET_CORE_InformationRequestContext
- *irc);
-
-
/**
* Iterate over all connected peers. Calls peer_cb with each
* connected peer, and then once with NULL to indicate that all peers
*/
#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 71
-/**
- * Request from client to "configure" P2P connection.
- */
-#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO 72
-
/**
* Response from server about (possibly updated) P2P
* connection configuration.