📄 identity.c
字号:
GNUNET_PeerIdentity hi; unsigned short proto; HostEntry *entry; int ret; ret = GNUNET_OK; GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_); count = 0; GNUNET_mutex_lock (lock_); for (i = 0; i < numberOfHosts_; i++) { entry = hosts_[i]; if (0 == memcmp (&entry->identity, &myIdentity, sizeof (GNUNET_PeerIdentity))) continue; if ((now == 0) || (now >= entry->until)) { count++; if (callback != NULL) { hi = entry->identity; for (j = 0; j < entry->protocolCount; j++) { proto = entry->protocols[j]; GNUNET_mutex_unlock (lock_); ret = callback (&hi, proto, GNUNET_YES, data); GNUNET_mutex_lock (lock_); if (ret != GNUNET_OK) break; /* we gave up the lock, need to re-acquire entry (if possible)! */ if (i >= numberOfHosts_) break; entry = hosts_[i]; if (0 == memcmp (&entry->identity, &myIdentity, sizeof (GNUNET_PeerIdentity))) break; } } } else {#if 0#if DEBUG_IDENTITY GNUNET_EncName enc; IF_GELOG (ectx, GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK, GNUNET_hash_to_enc (&entry->identity.hashPubKey, &enc)); GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_BULK, entry->strict ? _ ("Peer `%s' is currently strictly blacklisted (for another %llums).\n") : _ ("Peer `%s' is currently blacklisted (for another %llums).\n"), &enc, entry->until - now);#endif#endif } if (ret != GNUNET_OK) break; } for (i = 0; i < MAX_TEMP_HOSTS; i++) { if (ret != GNUNET_OK) break; entry = &tempHosts[i]; if (entry->helloCount == 0) continue; if ((now == 0) || (now >= entry->until)) { count++; if (callback != NULL) { hi = entry->identity; proto = entry->protocols[0]; GNUNET_mutex_unlock (lock_); ret = callback (&hi, proto, GNUNET_YES, data); GNUNET_mutex_lock (lock_); } } } GNUNET_mutex_unlock (lock_); return count;}/** * Write host-trust information to a file - flush the buffer entry! * Assumes synchronized access. */static voidflushHostCredit (HostEntry * host){ GNUNET_EncName fil; char *fn; unsigned int trust; if ((host->trust & TRUST_REFRESH_MASK) == 0) return; /* unchanged */ host->trust = host->trust & TRUST_ACTUAL_MASK; GNUNET_hash_to_enc (&host->identity.hashPubKey, &fil); fn = GNUNET_malloc (strlen (trustDirectory) + sizeof (GNUNET_EncName) + 1); strcpy (fn, trustDirectory); strcat (fn, (char *) &fil); if (host->trust == 0) { if ((0 != UNLINK (fn)) && (errno != ENOENT)) GNUNET_GE_LOG_STRERROR_FILE (ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "unlink", fn); } else { trust = htonl (host->trust); GNUNET_disk_file_write (ectx, fn, &trust, sizeof (unsigned int), "644"); } GNUNET_free (fn);}/** * Call once in a while to synchronize trust values with the disk. */static voidcronFlushTrustBuffer (void *unused){ int i; GNUNET_mutex_lock (lock_); for (i = 0; i < numberOfHosts_; i++) flushHostCredit (hosts_[i]); GNUNET_mutex_unlock (lock_);}/** * @brief delete expired HELLO entries in data/hosts/ */static intdiscardHostsHelper (const char *filename, const char *dirname, void *now){ char *fn; struct stat hostStat; int hostFile; fn = GNUNET_malloc (strlen (filename) + strlen (dirname) + 2); sprintf (fn, "%s%s%s", dirname, DIR_SEPARATOR_STR, filename); hostFile = GNUNET_disk_file_open (ectx, fn, O_WRONLY); if (hostFile != -1) { if (FSTAT (hostFile, &hostStat) == 0) { CLOSE (hostFile); if (hostStat.st_mtime + (CRON_DISCARDS_HOSTS_AFTER / GNUNET_CRON_SECONDS) < *((time_t *) now)) UNLINK (fn); } } GNUNET_free (fn); return GNUNET_OK;}/** * @brief scan host directory for expired entries */static voidcronDiscardHosts (void *unused){ time_t timeNow; timeNow = time (NULL); GNUNET_disk_directory_scan (ectx, networkIdDirectory, &discardHostsHelper, (void *) &timeNow);}static intidentityRequestConnectHandler (struct GNUNET_ClientHandle *sock, const GNUNET_MessageHeader * message){ const CS_identity_connect_MESSAGE *msg; int ret; if (sizeof (CS_identity_connect_MESSAGE) != ntohs (message->size)) return GNUNET_SYSERR; msg = (const CS_identity_connect_MESSAGE *) message; whitelistHost (&msg->other); coreAPI->ciphertext_send (&msg->other, NULL, 0, 0); ret = coreAPI->p2p_connection_status_check (&msg->other, NULL, NULL); return coreAPI->cs_send_value (sock, ret != GNUNET_OK ? GNUNET_NO : GNUNET_YES);}static intidentityHelloHandler (struct GNUNET_ClientHandle *sock, const GNUNET_MessageHeader * message){ const GNUNET_MessageHello *msg; GNUNET_MessageHello *hello; if (sizeof (GNUNET_MessageHello) > ntohs (message->size)) { GNUNET_GE_BREAK (NULL, 0); return GNUNET_SYSERR; } msg = (const GNUNET_MessageHello *) message; if (GNUNET_sizeof_hello (msg) != ntohs (message->size)) { GNUNET_GE_BREAK (NULL, 0); return GNUNET_SYSERR; } hello = GNUNET_malloc (ntohs (msg->header.size)); memcpy (hello, msg, ntohs (msg->header.size)); hello->header.type = htons (GNUNET_P2P_PROTO_HELLO); coreAPI->loopback_send (NULL, (const char *) hello, ntohs (msg->header.size), GNUNET_NO, NULL); GNUNET_free (hello); return GNUNET_OK;}static intidentityRequestHelloHandler (struct GNUNET_ClientHandle *sock, const GNUNET_MessageHeader * message){ /* transport types in order of preference for location URIs (by best guess at what people are most likely to actually run) */ static unsigned short types[] = { GNUNET_TRANSPORT_PROTOCOL_NUMBER_TCP, GNUNET_TRANSPORT_PROTOCOL_NUMBER_UDP, GNUNET_TRANSPORT_PROTOCOL_NUMBER_HTTP, GNUNET_TRANSPORT_PROTOCOL_NUMBER_SMTP, GNUNET_TRANSPORT_PROTOCOL_NUMBER_NAT, 0, }; GNUNET_Transport_ServiceAPI *tapi; GNUNET_MessageHello *hello; int pos; int ret; /* we cannot permanently load transport since that would cause a cyclic dependency; however, we can request it briefly here */ tapi = coreAPI->service_request ("transport"); if (tapi == NULL) return GNUNET_SYSERR; hello = NULL; pos = 0; while ((hello == NULL) && (types[pos] != 0)) hello = tapi->hello_create (types[pos++]); coreAPI->service_release (tapi); if (hello == NULL) return GNUNET_SYSERR; hello->header.type = htons (GNUNET_CS_PROTO_IDENTITY_HELLO); ret = coreAPI->cs_send_message (sock, &hello->header, GNUNET_YES); GNUNET_free (hello); return ret;}static intidentityRequestSignatureHandler (struct GNUNET_ClientHandle *sock, const GNUNET_MessageHeader * message){ CS_identity_signature_MESSAGE reply; if (ntohs (message->size) <= sizeof (GNUNET_MessageHeader)) return GNUNET_SYSERR; reply.header.size = htons (sizeof (CS_identity_signature_MESSAGE)); reply.header.type = htons (GNUNET_CS_PROTO_IDENTITY_SIGNATURE); if (GNUNET_OK != signData (&message[1], ntohs (message->size) - sizeof (GNUNET_MessageHeader), &reply.sig)) return GNUNET_SYSERR; return coreAPI->cs_send_message (sock, &reply.header, GNUNET_YES);}static inthostInfoIterator (const GNUNET_PeerIdentity * identity, unsigned short protocol, int confirmed, void *data){ struct GNUNET_ClientHandle *sock = data; GNUNET_Transport_ServiceAPI *transport; CS_identity_peer_info_MESSAGE *reply; GNUNET_MessageHello *hello; void *address; int ret; unsigned int len; unsigned int bpm; GNUNET_CronTime last; if (confirmed == GNUNET_NO) return GNUNET_OK; hello = identity2Hello (identity, protocol, GNUNET_YES); if (hello == NULL) return GNUNET_OK; /* ignore -- happens if HELLO just expired */ transport = coreAPI->service_request ("transport"); if (transport == NULL) { GNUNET_free (hello); return GNUNET_OK; } len = 0; address = NULL; transport->hello_to_address (hello, &address, &len); GNUNET_free (hello); coreAPI->service_release (transport); if (len >= GNUNET_MAX_BUFFER_SIZE - sizeof (CS_identity_peer_info_MESSAGE)) { GNUNET_free (address); address = NULL; len = 0; } if (GNUNET_OK != coreAPI->p2p_connection_status_check (identity, &bpm, &last)) { last = 0; bpm = 0; } reply = GNUNET_malloc (sizeof (CS_identity_peer_info_MESSAGE) + len); reply->header.size = htons (sizeof (CS_identity_peer_info_MESSAGE) + len); reply->header.type = htons (GNUNET_CS_PROTO_IDENTITY_INFO); reply->peer = *identity; reply->last_message = GNUNET_htonll (last); reply->trust = htonl (getHostTrust (identity)); reply->bpm = htonl (bpm); memcpy (&reply[1], address, len); GNUNET_free_non_null (address); ret = coreAPI->cs_send_message (sock, &reply->header, GNUNET_YES); GNUNET_free (reply); return ret;}static intidentityRequestInfoHandler (struct GNUNET_ClientHandle *sock, const GNUNET_MessageHeader * message){ forEachHost (0, &hostInfoIterator, sock); return coreAPI->cs_send_value (sock, GNUNET_OK);}/** * Provide the Identity service. * * @param capi the core API * @return NULL on errors, ID_API otherwise */GNUNET_Identity_ServiceAPI *provide_module_identity (GNUNET_CoreAPIForPlugins * capi){ static GNUNET_Identity_ServiceAPI id; char *gnHome; char *tmp; int i; coreAPI = capi; ectx = coreAPI->ectx; id.getPublicPrivateKey = &getPublicPrivateKey; id.getPeerIdentity = &getPeerIdentity; id.signData = &signData; id.decryptData = &decryptData; id.delHostFromKnown = &delHostFromKnown; id.addHostTemporarily = &addHostTemporarily; id.addHost = &bindAddress; id.forEachHost = &forEachHost; id.identity2Hello = &identity2Hello; id.verifyPeerSignature = &verifyPeerSignature; id.blacklistHost = &blacklistHost; id.isBlacklisted = &isBlacklisted; id.whitelistHost = &whitelistHost; id.changeHostTrust = &changeHostTrust; id.getHostTrust = &getHostTrust; for (i = 0; i < MAX_TEMP_HOSTS; i++) memset (&tempHosts[i], 0, sizeof (HostEntry)); numberOfHosts_ = 0; gnHome = NULL; GNUNET_GE_ASSERT (ectx, -1 != GNUNET_GC_get_configuration_value_filename (coreAPI->cfg, "GNUNETD", "GNUNETD_HOME", GNUNET_DEFAULT_DAEMON_VAR_DIRECTORY, &gnHome)); if (gnHome == NULL) return NULL; GNUNET_disk_directory_create (ectx, gnHome); tmp = GNUNET_malloc (strlen (gnHome) + strlen (HOST_DIR) + 2); strcpy (tmp, gnHome); strcat (tmp, DIR_SEPARATOR_STR); strcat (tmp, HOST_DIR); networkIdDirectory = NULL; GNUNET_GE_ASSERT (ectx, -1 != GNUNET_GC_get_configuration_value_filename (coreAPI->cfg, "GNUNETD", "HOSTS", tmp, &networkIdDirectory)); GNUNET_free (tmp); GNUNET_disk_directory_create (ectx, networkIdDirectory); trustDirectory = GNUNET_malloc (strlen (gnHome) + strlen (TRUSTDIR) + 2); strcpy (trustDirectory, gnHome); strcat (trustDirectory, DIR_SEPARATOR_STR); strcat (trustDirectory, TRUSTDIR); GNUNET_disk_directory_create (ectx, trustDirectory); GNUNET_free (gnHome); lock_ = GNUNET_mutex_create (GNUNET_YES); initPrivateKey (capi->ectx, capi->cfg); getPeerIdentity (getPublicPrivateKey (), &myIdentity); cronScanDirectoryDataHosts (NULL); GNUNET_cron_add_job (coreAPI->cron, &cronScanDirectoryDataHosts, CRON_DATA_HOST_FREQ, CRON_DATA_HOST_FREQ, NULL); GNUNET_cron_add_job (coreAPI->cron, &cronFlushTrustBuffer, CRON_TRUST_FLUSH_FREQ, CRON_TRUST_FLUSH_FREQ, NULL); GNUNET_cron_add_job (coreAPI->cron, &cronDiscardHosts, 0, CRON_DISCARD_HOSTS_INTERVAL, NULL); coreAPI->cs_handler_register (GNUNET_CS_PROTO_IDENTITY_CONNECT, &identityRequestConnectHandler); coreAPI->cs_handler_register (GNUNET_CS_PROTO_IDENTITY_HELLO, &identityHelloHandler); coreAPI->cs_handler_register (GNUNET_CS_PROTO_IDENTITY_REQUEST_HELLO, &identityRequestHelloHandler); coreAPI->cs_handler_register (GNUNET_CS_PROTO_IDENTITY_REQUEST_SIGNATURE, &identityRequestSignatureHandler); coreAPI->cs_handler_register (GNUNET_CS_PROTO_IDENTITY_REQUEST_INFO, &identityRequestInfoHandler); return &id;}/** * Shutdown Identity service. */voidrelease_module_identity (){ int i; int j; HostEntry *entry; coreAPI->cs_handler_unregister (GNUNET_CS_PROTO_IDENTITY_CONNECT, &identityRequestConnectHandler); coreAPI->cs_handler_unregister (GNUNET_CS_PROTO_IDENTITY_HELLO, &identityHelloHandler); coreAPI->cs_handler_unregister (GNUNET_CS_PROTO_IDENTITY_REQUEST_HELLO, &identityRequestHelloHandler); coreAPI->cs_handler_unregister (GNUNET_CS_PROTO_IDENTITY_REQUEST_SIGNATURE, &identityRequestSignatureHandler); coreAPI->cs_handler_unregister (GNUNET_CS_PROTO_IDENTITY_REQUEST_INFO, &identityRequestInfoHandler); for (i = 0; i < MAX_TEMP_HOSTS; i++) { entry = &tempHosts[i]; for (j = 0; j < entry->helloCount; j++) GNUNET_free (entry->hellos[j]); GNUNET_array_grow (entry->hellos, entry->helloCount, 0); GNUNET_array_grow (entry->protocols, entry->protocolCount, 0); } GNUNET_cron_del_job (coreAPI->cron, &cronScanDirectoryDataHosts, CRON_DATA_HOST_FREQ, NULL); GNUNET_cron_del_job (coreAPI->cron, &cronFlushTrustBuffer, CRON_TRUST_FLUSH_FREQ, NULL); GNUNET_cron_del_job (coreAPI->cron, &cronDiscardHosts, CRON_DISCARD_HOSTS_INTERVAL, NULL); cronFlushTrustBuffer (NULL); GNUNET_mutex_destroy (lock_); lock_ = NULL; for (i = 0; i < numberOfHosts_; i++) { entry = hosts_[i]; for (j = 0; j < entry->helloCount; j++) GNUNET_free (entry->hellos[j]); GNUNET_array_grow (entry->hellos, entry->helloCount, 0); GNUNET_array_grow (entry->protocols, entry->protocolCount, 0); GNUNET_free (entry); } GNUNET_array_grow (hosts_, sizeOfHosts_, 0); numberOfHosts_ = 0; GNUNET_free (networkIdDirectory); networkIdDirectory = NULL; GNUNET_free (trustDirectory); trustDirectory = NULL; donePrivateKey ();}/* end of identity.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -