* @author Christian Grothoff
*
* POST-TESTING:
- * - revisit API (which arguments are used, needed)?
- * - add code to send PINGs if we are about to time-out otherwise (?)
- * ? add heuristic to do another send_key in "handle_set_key"
- * in case previous attempt failed / didn't work / persist
- * (but don't do it always to avoid storm of SET_KEY's going
- * back and forth!) --- alternatively, add "status" field
- * of the other peer to the set key message, that way we'd
- * know for sure!
- * - check that hostkey used by transport (for HELLOs) is the
- * same as the hostkey that we are using!
* - topology management:
* + bootstrapping (transport offer hello, plugins)
* + internal neighbour selection
- * + update bandwidth usage statistics
- * + bandwidth allocation (transport set quota)
+ *
+ * Considerations for later:
+ * - check that hostkey used by transport (for HELLOs) is the
+ * same as the hostkey that we are using!
+ * - add code to send PINGs if we are about to time-out otherwise
* - optimize lookup (many O(n) list traversals
* could ideally be changed to O(1) hash map lookups)
*/
* bandwidth-hogs are sampled at a frequency of about 78s!);
* may get negative if we have VERY high priority content.
*/
- long long available_send_window;
+ long long available_send_window;
/**
* How much downstream capacity of this peer has been reserved for
* make sure that this reserved amount of bandwidth is actually
* available).
*/
- long long available_recv_window;
+ long long available_recv_window;
/**
* How valueable were the messages of this peer recently?
uint32_t bpm_out_external_limit;
/**
- * What was our PING challenge number?
+ * What was our PING challenge number (for this peer)?
*/
uint32_t ping_challenge;
* Recalculate the number of bytes we expect to
* receive or transmit in a given window.
*
+ * @param force force an update now (even if not much time has passed)
* @param window pointer to the byte counter (updated)
* @param ts pointer to the timestamp (updated)
* @param bpm number of bytes per minute that should
* be added to the window.
*/
static void
-update_window (long long *window,
+update_window (int force,
+ long long *window,
struct GNUNET_TIME_Absolute *ts, unsigned int bpm)
{
struct GNUNET_TIME_Relative since;
since = GNUNET_TIME_absolute_get_duration (*ts);
- if (since.value < 60 * 1000)
+ if ( (force == GNUNET_NO) &&
+ (since.value < 60 * 1000) )
return; /* not even a minute has passed */
*ts = GNUNET_TIME_absolute_get ();
*window += (bpm * since.value) / 60 / 1000;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending `%s' message to client.\n", "NOTIFY_CONNECT");
#endif
- cnm.bpm_available = htonl (n->bpm_out);
- cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
+ cnm.reserved = htonl (0);
cnm.peer = n->peer;
send_to_client (c, &cnm.header, GNUNET_NO);
n = n->next;
memset (&cim, 0, sizeof (cim));
if ((n != NULL) && (n->status == PEER_STATE_KEY_CONFIRMED))
{
+ update_window (GNUNET_YES,
+ &n->available_send_window,
+ &n->last_asw_update,
+ n->bpm_out);
n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm);
n->bpm_out = GNUNET_MAX (n->bpm_out_internal_limit,
n->bpm_out_external_limit);
}
else if (reserv > 0)
{
- update_window (&n->available_recv_window,
+ update_window (GNUNET_NO,
+ &n->available_recv_window,
&n->last_arw_update, n->bpm_in);
if (n->available_recv_window < reserv)
reserv = n->available_recv_window;
GNUNET_assert (size >= m->size);
memcpy (cbuf, &m[1], m->size);
ret = m->size;
+ n->available_send_window -= m->size;
process_encrypted_neighbour_queue (n);
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
n->th =
GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer,
n->encrypted_head->size,
+ n->encrypted_head->priority,
GNUNET_TIME_absolute_get_remaining
(n->encrypted_head->deadline),
¬ify_encrypted_transmit_ready,
min = NULL;
min_prio = -1;
discard_low_prio = GNUNET_NO;
- /* number of bytes available for transmission at time "t" */
+ /* calculate number of bytes available for transmission at time "t" */
+ update_window (GNUNET_NO,
+ &n->available_send_window,
+ &n->last_asw_update,
+ n->bpm_out);
avail = n->available_send_window;
t = n->last_asw_update;
- /* how many bytes have we (hyptothetically) scheduled so far */
+ /* how many bytes have we (hypothetically) scheduled so far */
off = 0;
/* maximum time we can wait before transmitting anything
and still make all of our deadlines */
if (NULL ==
GNUNET_TRANSPORT_notify_transmit_ready (transport,
&sm->peer,
- 0,
+ 0, 0,
GNUNET_TIME_absolute_get_remaining
(GNUNET_TIME_absolute_ntoh
(sm->deadline)),
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Core service receives `%s' request from `%4s'.\n",
"ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
-#endif
+#endif
/* decrypt */
if (GNUNET_OK !=
do_decrypt (n,
}
/* process decrypted message(s) */
+ update_window (GNUNET_YES,
+ &n->available_send_window,
+ &n->last_asw_update,
+ n->bpm_out);
n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit);
n->bpm_out = GNUNET_MAX (n->bpm_out_external_limit,
n->bpm_out_internal_limit);
schedule_quota_update (n);
cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- cnm.bpm_available = htonl (n->bpm_out);
+ cnm.reserved = htonl (0);
cnm.peer = *peer;
- cnm.last_activity = GNUNET_TIME_absolute_hton (now);
send_to_all_clients (&cnm.header, GNUNET_YES);
}
neighbour_count--;
cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
- cnm.bpm_available = htonl (0);
+ cnm.reserved = htonl (0);
cnm.peer = *peer;
- cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
send_to_all_clients (&cnm.header, GNUNET_YES);
free_neighbour (n);
}