void OutboundMessageFragments::timerCallback(const boost::system::error_code& e, PeerState ps, uint32_t const msgId) { if(!e) { std::lock_guard<std::mutex> lock(m_mutex); auto itr = m_states.find(msgId); if(itr != m_states.end()) { OutboundMessageState& oms = itr->second; if(oms.getTries() > 5) { m_states.erase(msgId); return; } PacketBuilder::FragmentPtr frag = oms.getNextUnackdFragment(); if(frag) { std::vector<PacketBuilder::FragmentPtr> fragList; fragList.push_back(frag); oms.markFragmentSent(fragList[0]->fragNum); PacketPtr p = PacketBuilder::buildData(ps.getEndpoint(), false, CompleteAckList(), PartialAckList(), fragList); p->encrypt(ps.getCurrentSessionKey(), ps.getCurrentMacKey()); m_context.sendPacket(p); oms.incrementTries(); oms.getTimer().expires_at(oms.getTimer().expires_at() + boost::posix_time::time_duration(0, 0, 2)); oms.getTimer().async_wait(boost::bind(&OutboundMessageFragments::timerCallback, this, boost::asio::placeholders::error, ps, msgId)); } } } }
void OutboundMessageFragments::sendDataCallback(PeerState ps, uint32_t const msgId) { std::lock_guard<std::mutex> lock(m_mutex); auto itr = m_states.find(msgId); if(itr != m_states.end()) { OutboundMessageState& oms = itr->second; std::vector<PacketBuilder::FragmentPtr> fragList; auto fragment = oms.getNextFragment(); if (fragment == nullptr) { throw std::runtime_error("no ssu fragment when sending"); } fragList.push_back(fragment); oms.markFragmentSent(fragList[0]->fragNum); PacketPtr p = PacketBuilder::buildData(ps.getEndpoint(), false, CompleteAckList(), PartialAckList(), fragList); p->encrypt(ps.getCurrentSessionKey(), ps.getCurrentMacKey()); m_context.sendPacket(p); if(!oms.allFragmentsSent()) m_context.ios.post(boost::bind(&OutboundMessageFragments::sendDataCallback, this, ps, msgId)); } }
void EstablishmentManager::processCreated(EstablishmentStatePtr const &state) { state->calculateDHSecret(); if(!state->verifyCreationSignature()) { I2P_LOG(m_log, warning) << "creation signature verification failed"; state->setState(EstablishmentState::State::FAILURE); return; } const ByteArray& dhSecret = state->getDHSecret(); SessionKey newKey(toSessionKey(dhSecret)), newMacKey; state->setSessionKey(newKey); copy(dhSecret.begin() + 32, dhSecret.begin() + 32 + 32, newMacKey.begin()); state->setMacKey(newMacKey); Endpoint ep = state->getTheirEndpoint(); PeerState ps(ep, state->getTheirIdentity().getHash()); ps.setCurrentSessionKey(state->getSessionKey()); ps.setCurrentMacKey(state->getMacKey()); std::lock_guard<std::mutex> lock(m_context.peers.getMutex()); m_context.peers.addPeer(std::move(ps)); PacketPtr p = PacketBuilder::buildSessionConfirmed(state); p->encrypt(state->getSessionKey(), state->getMacKey()); m_context.sendPacket(p); state->setState(EstablishmentState::State::CONFIRMED_SENT); post(state); }
void EstablishmentManager::sendRequest(EstablishmentStatePtr const &state) { PacketPtr p = PacketBuilder::buildSessionRequest(state); p->encrypt(state->getSessionKey(), state->getMacKey()); m_context.sendPacket(p); state->setState(EstablishmentState::State::REQUEST_SENT); post(state); }
void EstablishmentManager::processRequest(EstablishmentStatePtr const &state) { state->calculateDHSecret(); PacketPtr p = PacketBuilder::buildSessionCreated(state); p->encrypt(state->getIV(), state->getSessionKey(), state->getMacKey()); const ByteArray& dhSecret = state->getDHSecret(); SessionKey newKey(toSessionKey(dhSecret)), newMacKey; state->setSessionKey(newKey); copy(dhSecret.begin() + 32, dhSecret.begin() + 32 + 32, newMacKey.begin()); state->setMacKey(newMacKey); m_context.sendPacket(p); state->setState(EstablishmentState::State::CREATED_SENT); post(state); }