void Tunnel::handleResponses(std::list<BuildRecordPtr> const &records) { bool allgood = true; auto itr = m_hops.crbegin(); ++itr; for(; itr != m_hops.crend(); ++itr) { BuildRequestRecordPtr h = std::static_pointer_cast<BuildRequestRecord>(*itr); for(auto r: records) r->decrypt(h->getReplyIV(), h->getReplyKey()); for(auto r: records) { BuildResponseRecord resp = *r; resp.parse(); if(resp.getReply() == BuildResponseRecord::Reply::SUCCESS) { // TODO Record the success in the router's profile. } else { // TODO Record the failure in the router's profile. allgood = false; } } } if(allgood) m_state = Tunnel::State::OPERATIONAL; else m_state = Tunnel::State::FAILED; }
OutboundTunnel::OutboundTunnel(std::vector<RouterIdentity> const &hops, RouterHash const &replyHash, uint32_t const replyTunnelId) { /* Zero hop tunnel */ if(hops.empty()) { m_state = State::OPERATIONAL; return; } uint32_t lastTunnelId; RouterHash lastRouterHash; for(int i = hops.size() - 1; i >= 0; i--) { BuildRequestRecordPtr h; if(i == hops.size() - 1) { h = std::make_shared<BuildRequestRecord>(hops[i], replyHash); h->setType(BuildRequestRecord::Type::ENDPOINT); h->setNextTunnelId(replyTunnelId); m_tunnelId = h->getNextTunnelId(); m_nextMsgId = h->getNextMsgId(); } else { h = std::make_shared<BuildRequestRecord>(hops[i], lastRouterHash, lastTunnelId); } lastTunnelId = h->getTunnelId(); lastRouterHash = h->getLocalHash(); m_hops.push_front(h); } secureRecords(); }
void Tunnel::secureRecords() { for(auto itr = m_hops.cbegin(); itr != m_hops.cend(); ++itr) { BuildRequestRecordPtr h = std::static_pointer_cast<BuildRequestRecord>(*itr); const RouterHash hopHash = h->getLocalHash(); StaticByteArray<16> truncatedHash; std::copy(hopHash.cbegin(), hopHash.cbegin() + 16, truncatedHash.begin()); h->setHeader(truncatedHash); h->compile(); h->encrypt(h->getEncryptionKey()); std::list<BuildRecordPtr>::const_reverse_iterator ritr(itr); for(; ritr != m_hops.crend(); ++ritr) { BuildRequestRecordPtr r = std::static_pointer_cast<BuildRequestRecord>(*ritr); h->decrypt(r->getReplyIV(), r->getReplyKey()); } } }