📄 connect.c
字号:
return GNUNET_SYSERR; /* rejected */ } memset (&key, 0, sizeof (GNUNET_AES_SessionKey)); size = identity->decryptData (&newMsg->key, &key, sizeof (GNUNET_AES_SessionKey)); if (size != sizeof (GNUNET_AES_SessionKey)) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_USER | GNUNET_GE_BULK, _("Invalid `%s' message received from peer `%s'.\n"), "setkey", &enc); return GNUNET_SYSERR; } if (key.crc32 != htonl (GNUNET_crc32_n (&key, GNUNET_SESSIONKEY_LEN))) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_USER | GNUNET_GE_BULK, _ ("setkey `%s' from `%s' fails CRC check (have: %u, want %u).\n"), printSKEY (&key), &enc, ntohl (key.crc32), GNUNET_crc32_n (&key, GNUNET_SESSIONKEY_LEN));#endif GNUNET_GE_BREAK_OP (ectx, 0); stats->change (stat_skeyRejected, 1); return GNUNET_SYSERR; }#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Received setkey message from `%s' with %u bytes of data and key `%s'.\n", &enc, ntohs (newMsg->header.size), printSKEY (&key));#endif if (stats != NULL) stats->change (stat_skeyAccepted, 1); /* notify core about session key */ coreAPI->p2p_session_key_set (&key, sender, ntohl (newMsg->creationTime), GNUNET_NO); pos = sizeof (P2P_setkey_MESSAGE); ping = NULL; pong = NULL; plaintext = NULL; size = ntohs (newMsg->header.size); sig = &newMsg->signature; if (sizeof (P2P_setkey_MESSAGE) < size) { size -= sizeof (P2P_setkey_MESSAGE); end = &newMsg[1]; plaintext = GNUNET_malloc (size);#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Decrypting %d bytes of PINGPONG from `%s' with key `%s' and IV %u\n", size, &enc, printSKEY (&key), *(int *) sig);#endif GNUNET_GE_ASSERT (ectx, -1 != GNUNET_AES_decrypt (&key, end, size, (const GNUNET_AES_InitializationVector *) sig, plaintext)); pos = 0; /* find pings & pongs! */ while (pos + sizeof (GNUNET_MessageHeader) < size) { GNUNET_MessageHeader *hdr; hdr = (GNUNET_MessageHeader *) & plaintext[pos]; if (htons (hdr->size) + pos > size) { GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_USER | GNUNET_GE_BULK, _ ("Error parsing encrypted session key from `%s', " "given message part size is invalid.\n"), &enc); break; } if (htons (hdr->type) == GNUNET_P2P_PROTO_PING) ping = hdr; else if (htons (hdr->type) == GNUNET_P2P_PROTO_PONG) pong = hdr; else GNUNET_GE_LOG (ectx, GNUNET_GE_WARNING | GNUNET_GE_DEVELOPER | GNUNET_GE_USER | GNUNET_GE_BULK, _ ("Unknown type in embedded message from `%s': %u (size: %u)\n"), &enc, htons (hdr->type), htons (hdr->size)); pos += ntohs (hdr->size); } } if (pong != NULL) { /* we initiated, this is the response */ /* notify ourselves about encapsulated pong */#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Received PONG in session key from `%s', injecting!\n", &enc);#endif coreAPI->loopback_send (sender, (char *) pong, ntohs (pong->size), GNUNET_YES, tsession); if (ping != NULL) { /* should always be true for well-behaved peers */ /* pong can go out over ordinary channels */#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Received PING in session key from `%s', " "sending PONG over normal encrypted session!\n", &enc);#endif ping->type = htons (GNUNET_P2P_PROTO_PONG); if (stats != NULL) stats->change (stat_pongSent, 1); coreAPI->ciphertext_send (sender, ping, GNUNET_EXTREME_PRIORITY, 0); } } else { if (ping != NULL) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Received PING in session key from `%s', " "sending PONG together with my session key!\n", &enc);#endif ping->type = htons (GNUNET_P2P_PROTO_PONG); if (stats != NULL) stats->change (stat_pongSent, 1); GNUNET_mutex_lock (lock); exchangeKey (sender, tsession, ping); /* ping is now pong */ GNUNET_mutex_unlock (lock); } else { GNUNET_GE_BREAK_OP (ectx, 0); /* PING not included in SKEY - bug (in other peer!?) */ } } GNUNET_free_non_null (plaintext); return GNUNET_OK;}/** * Try to connect to the given peer. * * @return GNUNET_SYSERR if that is impossible, * GNUNET_YES if a connection is established upon return, * GNUNET_NO if we're going to try to establish one asynchronously */static inttryConnect (const GNUNET_PeerIdentity * peer){#if DEBUG_SESSION GNUNET_EncName enc; IF_GELOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, GNUNET_hash_to_enc (&peer->hashPubKey, &enc));#endif if ((topology != NULL) && (topology->allowConnectionFrom (peer) == GNUNET_SYSERR)) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Topology rejected connecting to `%s'.\n", &enc);#endif return GNUNET_SYSERR; } if (coreAPI->p2p_connection_status_check (peer, NULL, NULL) == GNUNET_OK) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Connection to `%s' already up\n", &enc);#endif return GNUNET_YES; /* trivial case */ } if (GNUNET_YES == identity->isBlacklisted (peer, GNUNET_NO)) {#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Peer `%s' blacklisted, cannot connect right now\n", &enc);#endif return GNUNET_NO; /* not allowed right now! */ } GNUNET_mutex_lock (lock);#if DEBUG_SESSION GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_USER | GNUNET_GE_REQUEST, "Trying to exchange key with `%s'.\n", &enc);#endif if (GNUNET_OK == exchangeKey (peer, NULL, NULL)) { GNUNET_mutex_unlock (lock); return GNUNET_NO; } GNUNET_mutex_unlock (lock); return GNUNET_SYSERR;}/** * We have received an (encrypted) setkey message. * The reaction is to update our key to the new * value. (Rekeying). */static intacceptSessionKeyUpdate (const GNUNET_PeerIdentity * sender, const GNUNET_MessageHeader * msg){ acceptSessionKey (sender, msg, NULL); return GNUNET_OK;}/** * Initialize the module. */GNUNET_Session_ServiceAPI *provide_module_session (GNUNET_CoreAPIForPlugins * capi){ static GNUNET_Session_ServiceAPI ret; ectx = capi->ectx; coreAPI = capi; identity = capi->service_request ("identity"); if (identity == NULL) { GNUNET_GE_BREAK (ectx, 0); return NULL; } transport = capi->service_request ("transport"); if (transport == NULL) { GNUNET_GE_BREAK (ectx, 0); coreAPI->service_release (identity); identity = NULL; return NULL; } pingpong = capi->service_request ("pingpong"); if (pingpong == NULL) { GNUNET_GE_BREAK (ectx, 0); coreAPI->service_release (transport); transport = NULL; coreAPI->service_release (identity); identity = NULL; return NULL; } topology = capi->service_request ("topology"); stats = capi->service_request ("stats"); if (stats != NULL) { stat_skeySent = stats->create (gettext_noop ("# session keys sent")); stat_skeyRejected = stats->create (gettext_noop ("# session keys rejected")); stat_skeyAccepted = stats->create (gettext_noop ("# session keys accepted")); stat_sessionEstablished = stats->create (gettext_noop ("# sessions established")); stat_pingSent = stats->create (gettext_noop ("# encrypted PING messages sent")); stat_pongSent = stats->create (gettext_noop ("# encrypted PONG messages sent")); } lock = capi->global_lock_get (); GNUNET_GE_LOG (ectx, GNUNET_GE_INFO | GNUNET_GE_USER | GNUNET_GE_REQUEST, _ ("`%s' registering handler %d (plaintext and ciphertext)\n"), "session", GNUNET_P2P_PROTO_SET_KEY); coreAPI->p2p_plaintext_handler_register (GNUNET_P2P_PROTO_SET_KEY, &acceptSessionKey); coreAPI->p2p_ciphertext_handler_register (GNUNET_P2P_PROTO_SET_KEY, &acceptSessionKeyUpdate); ret.tryConnect = &tryConnect; return &ret;}/** * Shutdown the module. */intrelease_module_session (){ coreAPI->p2p_plaintext_handler_unregister (GNUNET_P2P_PROTO_SET_KEY, &acceptSessionKey); coreAPI->p2p_ciphertext_handler_unregister (GNUNET_P2P_PROTO_SET_KEY, &acceptSessionKeyUpdate); if (topology != NULL) { coreAPI->service_release (topology); topology = NULL; } coreAPI->service_release (stats); stats = NULL; coreAPI->service_release (identity); identity = NULL; coreAPI->service_release (transport); transport = NULL; coreAPI->service_release (pingpong); pingpong = NULL; coreAPI = NULL; lock = NULL; return GNUNET_OK;}/* end of connect.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -