Protocol is defined here: http://www.menden.org/gnutella/hsep.html
Jeroen Asselman
Obtaining horizon size information on demand:
To obtain horizon size information, use the global HSEP table or the per-connection HSEP table, obtained using hsep_get_global_table(...) or hsep_get_connection_table (...), respectively (never access the internal arrays directly). To check if the global table has changed, use hsep_has_global_table_changed(...). The usable array indexes are between 1 (for 1 hop) and HSEP_N_MAX (for n_max hops). Note that the arrays only consider other nodes (i.e. exclude what we share ourselves), so the array index 0 always contains zeros. Note also that each triple represents the reachable resources *within* the number of hops, not at *exactly* the number of hops. To get the values for exactly the number of hops, simply subtract the preceeding triple from the desired triple.
Obtaining horizon size information using event-driven callbacks (only for the global HSEP table):
You can register a callback function for being informed whenever the global HSEP table changes by calling hsep_add_global_table_listener(...). On change of the global HSEP table the callback will be called with a pointer to a copy of the HSEP table and the number of provided triples. You must remove the listener later using hsep_remove_global_table_listener(...).
#include "common.h"
#include "gmsg.h"
#include "routing.h"
#include "nodes.h"
#include "hsep.h"
#include "uploads.h"
#include "share.h"
#include "features.h"
#include "if/gnet_property.h"
#include "if/gnet_property_priv.h"
#include "lib/endian.h"
#include "lib/glib-missing.h"
#include "lib/tm.h"
#include "lib/walloc.h"
#include "lib/override.h"
Functions | |
RCSID ("$Id:hsep.c, v 1.20 2005/09/10 08:17:28 daichik Exp $") | |
void | hsep_fire_global_table_changed (time_t now) |
Fires a change event for the global HSEP table. | |
gboolean | hsep_check_monotony (hsep_triple *table, unsigned int triples) |
Checks the monotony of the given triples. | |
void | hsep_sanity_check (void) |
Sanity check for the global and per-connection HSEP tables. | |
void | hsep_dump_table (void) |
Outputs the global HSEP table to the console. | |
unsigned int | hsep_triples_to_send (const hsep_triple *table, unsigned int triples) |
Takes a list of triples and returns the optimal number of triples to send in a HSEP message. | |
void | hsep_init (void) |
Initializes HSEP. | |
void | hsep_add_global_table_listener (GCallback cb, frequency_t t, guint32 interval) |
Adds the specified listener to the list of subscribers for global HSEP table change events. | |
void | hsep_remove_global_table_listener (GCallback cb) |
void | hsep_reset (void) |
Resets all HSEP data. | |
void | hsep_connection_init (struct gnutella_node *n) |
Initializes the connection's HSEP data. | |
void | hsep_timer (time_t now) |
Sends a HSEP message to all nodes where the last message has been sent some time ago. | |
void | hsep_connection_close (struct gnutella_node *n) |
Updates the global HSEP table when a connection is about to be closed. | |
void | hsep_process_msg (struct gnutella_node *n, time_t now) |
Processes a received HSEP message by updating the connection's and the global HSEP table. | |
void | hsep_send_msg (struct gnutella_node *n, time_t now) |
Sends a HSEP message to the given node, but only if data to send has changed. | |
void | hsep_notify_shared (guint64 own_files, guint64 own_kibibytes) |
This should be called whenever the number of shared files or kibibytes change. | |
unsigned int | hsep_get_global_table (hsep_triple *buffer, unsigned int maxtriples) |
Copies the first maxtriples triples from the global HSEP table into the specified buffer. | |
unsigned int | hsep_get_connection_table (const struct gnutella_node *n, hsep_triple *buffer, unsigned int maxtriples) |
Copies the first maxtriples triples from the connection's HSEP table into the specified buffer. | |
void | hsep_close (void) |
Used to shutdown HSEP. | |
gboolean | hsep_has_global_table_changed (time_t since) |
Checks whether the global HSEP table has changed since the specified point in time. | |
void | hsep_get_non_hsep_triple (hsep_triple *tripledest) |
Gets a HSEP-compatible triple for all non-HSEP nodes. | |
const gchar * | hsep_get_static_str (gint row, gint column) |
gint | hsep_get_table_size (void) |
Variables | |
hsep_triple | hsep_global_table [HSEP_N_MAX+1] |
global HSEP table | |
hsep_triple | hsep_own = {1, 0, 0} |
event_t * | hsep_global_table_changed_event |
time_t | hsep_last_global_table_change = 0 |
|
Adds the specified listener to the list of subscribers for global HSEP table change events. The specified callback is called once immediately, independent of the given frequency type and time interval. This function must be called after hsep_init() has been called. |
|
Checks the monotony of the given triples. TRUE is returned if 0 or 1 triple is given. Returns TRUE if monotony is ok, FALSE otherwise. |
|
Used to shutdown HSEP.
|
|
Updates the global HSEP table when a connection is about to be closed. The connection's HSEP data is restored to zero and the CAN_HSEP attribute is cleared. |
|
Initializes the connection's HSEP data.
|
|
Outputs the global HSEP table to the console.
|
|
Fires a change event for the global HSEP table.
|
|
Copies the first maxtriples triples from the connection's HSEP table into the specified buffer. If maxtriples is larger than the number of triples in the table, it is truncated appropriately. Note that also the 0'th triple is copied, which is always zero.
|
|
Copies the first maxtriples triples from the global HSEP table into the specified buffer. If maxtriples is larger than the number of triples in the table, it is truncated appropriately. Note that also the 0'th triple is copied, which is always zero.
|
|
Gets a HSEP-compatible triple for all non-HSEP nodes. The number of nodes is just the number of established non-HSEP connections, the number of shared files and KiB is the sum of the known PONG-based library sizes of those connections. Note that this takes only direct neighbor connections into account. Also note that the shared library size in KiB is not accurate due to Gnutella protocol limitations. The determined values are stored in the provided triple address. |
|
|
|
|
|
Checks whether the global HSEP table has changed since the specified point in time. Returns TRUE if this is the case, FALSE otherwise. |
|
Initializes HSEP.
|
|
This should be called whenever the number of shared files or kibibytes change. The values are checked for changes, nothing is done if nothing has changed. Note that kibibytes are determined by shifting the number of bytes right by 10 bits, not by dividing by 1000. |
|
Processes a received HSEP message by updating the connection's and the global HSEP table.
|
|
|
|
Resets all HSEP data. The global HSEP table and all connections' HSEP tables are reset to zero. The number of own shared files and kibibytes is untouched. This can be used to watch how quickly the HSEP data converges back to the correct "static" state. As soon as we have received a HSEP message from each of our peers, this state should be reached. Use with care, because this reset will temporarily affect all HSEP-capable nodes in the radius of N_MAX hops! |
|
Sanity check for the global and per-connection HSEP tables. Assertions are made for all these checks. If HSEP is implemented and used correctly, the sanity check will succed. Performed checks (* stands for an arbitrary value):
|
|
Sends a HSEP message to the given node, but only if data to send has changed. Should be called about every 30-60 seconds per node. Will automatically be called by hsep_timer() and hsep_connection_init(). Node must be HSEP-capable. |
|
Sends a HSEP message to all nodes where the last message has been sent some time ago. This should be called frequently (e.g. every second or every few seconds). |
|
Takes a list of triples and returns the optimal number of triples to send in a HSEP message. The number of triples to send is n_opt, defined as (triple indices counted from 0): n_opt := 1 + min {n | triple[n] = triple[k] for all k in [n+1,triples-1]} If there is no such n_opt, n_opt := triples. If all triples are equal, 1 is returned, which is correct.
|
|
|
|
global HSEP table
|
|
|
|
|
|
|