📄 topology.c
字号:
} active = coreAPI->p2p_connections_iterate (&checkNeedForPing, NULL); saturation = 1.0 * active / slotCount;}static intestimateNetworkSize (){ unsigned int active; unsigned int known; active = coreAPI->p2p_connections_iterate (NULL, NULL); if (active == 0) return 0; known = identity->forEachHost (0, NULL, NULL); if (active > known) return active; /* should not be possible */ /* Assumption: if we only connect to X% of all machines that we know, we probably also only know X% of all peers that exist; Then the total number of machines is 1/X * known, or known * known / active. Of course, we may know more than X% of the machines, in which case this estimate is too high. Well, that is why it is an estimate :-). Example: - we connect to all machines we have ever heard of => network size == # active - we connect to only 1% of the machines we have heard of => network size = 100 * # active */ if (known * known / active < known) return 0x7FFFFFFF; /* integer overflow, return max int */ return known * known / active;}static doubleestimateSaturation (){ return saturation;}static intis_friend (const GNUNET_PeerIdentity * peer){ unsigned int i; for (i = 0; i < friendCount; i++) if (0 == memcmp (&friends[i], peer, sizeof (GNUNET_PeerIdentity))) return 1; return 0;}static voidfriend_counter (const GNUNET_PeerIdentity * peer, void *cls){ unsigned int *cnt = cls; if (is_friend (peer)) (*cnt)++;}static unsigned intcount_connected_friends (GNUNET_ConnectionIterator connectionIterator, void *cls){ unsigned int i; i = 0; connectionIterator (&friend_counter, &i, cls); return i;}static intcore_wrapper (GNUNET_NodeIteratorCallback callback, void *cb_arg, void *unused){ return coreAPI->p2p_connections_iterate (callback, cb_arg);}static intallowConnection (const GNUNET_PeerIdentity * peer){ if ((coreAPI->my_identity != NULL) && (0 == memcmp (coreAPI->my_identity, peer, sizeof (GNUNET_PeerIdentity)))) return GNUNET_SYSERR; /* disallow connections to self */ if (is_friend (peer)) return GNUNET_OK; if (friends_only) return GNUNET_SYSERR; if (count_connected_friends (&core_wrapper, NULL) >= minimum_friend_count) return GNUNET_OK; return GNUNET_SYSERR;}/** * Would it be ok to drop the connection to this * peer? */static intisConnectionGuarded (const GNUNET_PeerIdentity * peer, GNUNET_ConnectionIterator connectionIterator, void *cls){ if (!is_friend (peer)) return GNUNET_NO; if (count_connected_friends (connectionIterator, cls) <= minimum_friend_count) return GNUNET_YES; return GNUNET_NO;}static unsigned intcountGuardedConnections (){ return minimum_friend_count;}/** * @return 0 on success. */static intrereadConfiguration (void *ctx, struct GNUNET_GC_Configuration *cfg, struct GNUNET_GE_Context *ectx, const char *section, const char *option){ char *fn; char *data; unsigned long long size; size_t pos; GNUNET_EncName enc; GNUNET_HashCode hc; unsigned long long opt; if (0 != strcmp (section, "F2F")) return 0; friends_only = GNUNET_GC_get_configuration_value_yesno (cfg, "F2F", "FRIENDS-ONLY", GNUNET_NO); if (friends_only == GNUNET_SYSERR) return GNUNET_SYSERR; /* invalid */ opt = 0; GNUNET_GC_get_configuration_value_number (cfg, "F2F", "MINIMUM", 0, 1024 * 1024, 0, &opt); minimum_friend_count = (unsigned int) opt; GNUNET_array_grow (friends, friendCount, 0); fn = NULL; GNUNET_GC_get_configuration_value_filename (cfg, "F2F", "FRIENDS", GNUNET_DEFAULT_DAEMON_VAR_DIRECTORY "/friends", &fn); /**Nate change, don't beat me up if it's not pretty!*/ if (GNUNET_OK != GNUNET_disk_file_test (ectx, fn)) { GNUNET_disk_file_write (ectx, fn, NULL, 0, "600"); } if ((0 == GNUNET_disk_file_test (ectx, fn)) || (GNUNET_OK != GNUNET_disk_file_size (ectx, fn, &size, GNUNET_YES))) { GNUNET_free (fn); fn = NULL; if ((friends_only) || (minimum_friend_count > 0)) { GNUNET_GE_LOG (ectx, GNUNET_GE_USER | GNUNET_GE_ADMIN | GNUNET_GE_ERROR | GNUNET_GE_IMMEDIATE, _("Could not read friends list `%s'\n"), fn); return GNUNET_SYSERR; } } if ((fn != NULL) && (size > 0)) { data = GNUNET_malloc (size); if (size != GNUNET_disk_file_read (ectx, fn, size, data)) { GNUNET_GE_LOG (ectx, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER, _("Failed to read friends list from `%s'\n"), fn); GNUNET_free (fn); GNUNET_free (data); return GNUNET_SYSERR; } GNUNET_free (fn); fn = NULL; pos = 0; while ((pos < size) && isspace (data[pos])) pos++; while ((size >= sizeof (GNUNET_EncName)) && (pos <= size - sizeof (GNUNET_EncName))) { memcpy (&enc, &data[pos], sizeof (GNUNET_EncName)); if (!isspace (enc.encoding[sizeof (GNUNET_EncName) - 1])) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER, _ ("Syntax error in topology specification, skipping bytes.\n")); pos++; while ((pos < size) && (!isspace (data[pos]))) pos++; continue; } enc.encoding[sizeof (GNUNET_EncName) - 1] = '\0'; if (GNUNET_OK == GNUNET_enc_to_hash ((char *) &enc, &hc)) { GNUNET_array_grow (friends, friendCount, friendCount + 1); friends[friendCount - 1].hashPubKey = hc; } else { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER, _ ("Syntax error in topology specification, skipping bytes `%s'.\n"), &enc); } pos = pos + sizeof (GNUNET_EncName); while ((pos < size) && isspace (data[pos])) pos++; } if ((minimum_friend_count > friendCount) && (friends_only == GNUNET_NO)) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER, _ ("Fewer friends specified than required by minimum friend count. Will only connect to friends.\n")); } if ((minimum_friend_count > coreAPI->core_slots_count ()) && (friends_only == GNUNET_NO)) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER, _ ("More friendly connections required than target total number of connections.\n")); } GNUNET_free (data); } GNUNET_free_non_null (fn); return 0;}GNUNET_Topology_ServiceAPI *provide_module_topology_default (GNUNET_CoreAPIForPlugins * capi){ static GNUNET_Topology_ServiceAPI api; coreAPI = capi; identity = capi->service_request ("identity"); if (identity == NULL) { GNUNET_GE_BREAK (capi->ectx, 0); return NULL; } transport = capi->service_request ("transport"); if (transport == NULL) { GNUNET_GE_BREAK (capi->ectx, 0); capi->service_release (identity); identity = NULL; return NULL; } pingpong = capi->service_request ("pingpong"); if (pingpong == NULL) { GNUNET_GE_BREAK (capi->ectx, 0); capi->service_release (identity); identity = NULL; capi->service_release (transport); transport = NULL; return NULL; } if (0 != GNUNET_GC_attach_change_listener (coreAPI->cfg, &rereadConfiguration, NULL)) { GNUNET_GE_BREAK (coreAPI->ectx, 0); capi->service_release (identity); identity = NULL; capi->service_release (transport); transport = NULL; capi->service_release (pingpong); pingpong = NULL; return NULL; } GNUNET_cron_add_job (capi->cron, &cronCheckLiveness, LIVE_SCAN_FREQUENCY, LIVE_SCAN_FREQUENCY, NULL); api.estimateNetworkSize = &estimateNetworkSize; api.getSaturation = &estimateSaturation; api.allowConnectionFrom = &allowConnection; api.isConnectionGuarded = &isConnectionGuarded; api.countGuardedConnections = &countGuardedConnections; return &api;}intrelease_module_topology_default (){ GNUNET_cron_del_job (coreAPI->cron, &cronCheckLiveness, LIVE_SCAN_FREQUENCY, NULL); GNUNET_GC_detach_change_listener (coreAPI->cfg, &rereadConfiguration, NULL); coreAPI->service_release (identity); identity = NULL; coreAPI->service_release (transport); transport = NULL; coreAPI->service_release (pingpong); pingpong = NULL; coreAPI = NULL; GNUNET_array_grow (friends, friendCount, 0); return GNUNET_OK;}/** * Update topology module. */voidupdate_module_topology_default (GNUNET_UpdateAPI * uapi){ uapi->service_update ("state"); uapi->service_update ("identity"); uapi->service_update ("transport"); uapi->service_update ("pingpong");}static GNUNET_CoreAPIForPlugins *myCapi;static GNUNET_Topology_ServiceAPI *myTopology;intinitialize_module_topology_default (GNUNET_CoreAPIForPlugins * capi){ myCapi = capi; myTopology = capi->service_request ("topology"); GNUNET_GE_ASSERT (capi->ectx, myTopology != NULL); GNUNET_GE_ASSERT (capi->ectx, 0 == GNUNET_GC_set_configuration_value_string (capi->cfg, capi->ectx, "ABOUT", "topology", gettext_noop ("maintains GNUnet default mesh topology"))); return GNUNET_OK;}voiddone_module_topology_default (){ myCapi->service_release (myTopology); myCapi = NULL; myTopology = NULL;}/* end of topology.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -