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 PeerStateList::addPeer(PeerState ps) { PeerStateContainer psc(ps); auto timer = std::make_unique<boost::asio::deadline_timer>(m_context.ios, boost::posix_time::time_duration(0, 20, 0)); timer->async_wait(boost::bind(&PeerStateList::timerCallback, this, boost::asio::placeholders::error, ps.getHash())); psc.timer = std::move(timer); auto itr = m_container.get<1>().find(ps.getHash()); if(itr == m_container.get<1>().end()) m_container.insert(std::move(psc)); else m_container.get<1>().replace(itr, std::move(psc)); }
void PacketHandler::handleSessionDestroyed(PeerState const &ps) { // m_peers is already locked above m_context.peers.delPeer(ps.getEndpoint()); m_context.ios.post(boost::bind(boost::ref(m_context.disconnectedSignal), ps.getHash())); }