diff --git a/airdcpp/ConnectionManager.cpp b/airdcpp/ConnectionManager.cpp index 28f67544..fb6bb304 100644 --- a/airdcpp/ConnectionManager.cpp +++ b/airdcpp/ConnectionManager.cpp @@ -304,7 +304,7 @@ void ConnectionManager::attemptDownloads(uint64_t aTick, StringList& removedToke continue; } - cqi->setLastBundle(Util::toString(bundleToken)); + cqi->setLastBundle(bundleToken != 0 ? Util::toString(bundleToken) : Util::emptyString); cqi->setHubUrl(hubHint); if (cqi->getState() == ConnectionQueueItem::WAITING) { @@ -571,13 +571,11 @@ void ConnectionManager::adcConnect(const OnlineUser& aUser, const string& aPort, try { if (aUser.getIdentity().getConnectMode() == Identity::MODE_ACTIVE_DUAL) { - uc->connect(Socket::AddressInfo(aUser.getIdentity().getIp4(), aUser.getIdentity().getIp6()), aPort, localPort, natRole); + uc->connect(Socket::AddressInfo(aUser.getIdentity().getIp4(), aUser.getIdentity().getIp6()), aPort, localPort, natRole, aUser); } else { auto ai = Socket::AddressInfo(aUser.getIdentity().getIp(), aUser.getIdentity().allowV6Connections() ? Socket::AddressInfo::TYPE_V6 : Socket::AddressInfo::TYPE_V4); - uc->connect(move(ai), aPort, localPort, natRole); + uc->connect(move(ai), aPort, localPort, natRole, aUser); } - - uc->setUser(aUser); } catch(const Exception&) { putConnection(uc); delete uc; diff --git a/airdcpp/QueueManager.cpp b/airdcpp/QueueManager.cpp index 19a11cfa..9add79c0 100644 --- a/airdcpp/QueueManager.cpp +++ b/airdcpp/QueueManager.cpp @@ -2038,7 +2038,7 @@ void QueueManager::removeFileSource(QueueItemPtr& q, const UserPtr& aUser, Flags } } -void QueueManager::removeSource(const UserPtr& aUser, Flags::MaskType reason, std::function excludeF /*nullptr*/) noexcept { +int QueueManager::removeSource(const UserPtr& aUser, Flags::MaskType reason, std::function excludeF /*nullptr*/) noexcept { // @todo remove from finished items QueueItemList ql; @@ -2056,6 +2056,7 @@ void QueueManager::removeSource(const UserPtr& aUser, Flags::MaskType reason, st } fire(QueueManagerListener::SourceFilesUpdated(), aUser); + return static_cast(ql.size()); } void QueueManager::setBundlePriority(QueueToken aBundleToken, QueueItemBase::Priority p) noexcept { @@ -3920,7 +3921,7 @@ void QueueManager::removeBundleLists(BundlePtr& aBundle) noexcept{ removeQI(qi); } -MemoryInputStream* QueueManager::generateTTHList(QueueToken aBundleToken, bool isInSharingHub) throw(QueueException) { +MemoryInputStream* QueueManager::generateTTHList(QueueToken aBundleToken, bool isInSharingHub, BundlePtr& bundle_) throw(QueueException) { if(!isInSharingHub) throw QueueException(UserConnection::FILE_NOT_AVAILABLE); @@ -3928,11 +3929,11 @@ MemoryInputStream* QueueManager::generateTTHList(QueueToken aBundleToken, bool i StringOutputStream tthList(tths); { RLock l(cs); - BundlePtr b = bundleQueue.findBundle(aBundleToken); - if (b) { + bundle_ = bundleQueue.findBundle(aBundleToken); + if (bundle_) { //write finished items string tmp2; - for(auto& q: b->getFinishedFiles()) { + for(auto& q: bundle_->getFinishedFiles()) { if (q->isSet(QueueItem::FLAG_MOVED)) { tmp2.clear(); tthList.write(q->getTTH().toBase32(tmp2) + " "); diff --git a/airdcpp/QueueManager.h b/airdcpp/QueueManager.h index ec8ac116..7ef25653 100644 --- a/airdcpp/QueueManager.h +++ b/airdcpp/QueueManager.h @@ -118,7 +118,8 @@ class QueueManager : public Singleton, public Speaker excludeF = nullptr) noexcept; + // Returns the number of files from which the source was removed + int removeSource(const UserPtr& aUser, Flags::MaskType reason, std::function excludeF = nullptr) noexcept; // Set priority for all bundles // Won't affect bundles that are added later @@ -265,7 +266,7 @@ class QueueManager : public Singleton, public SpeakergenerateTTHList(token, *profile != SP_HIDDEN)); + BundlePtr bundle = nullptr; + mis.reset(QueueManager::getInstance()->generateTTHList(Util::toUInt32(aFile), *profile != SP_HIDDEN, bundle)); // We don't want to show the token in transfer view - auto bundle = QueueManager::getInstance()->findBundle(token); if (bundle) { sourceFile = bundle->getName(); + } else { + dcassert(0); } } else { mis.reset(ShareManager::getInstance()->generateTTHList(aFile, listRecursive, *profile)); diff --git a/airdcpp/UserConnection.cpp b/airdcpp/UserConnection.cpp index bcf70e21..29b0a069 100644 --- a/airdcpp/UserConnection.cpp +++ b/airdcpp/UserConnection.cpp @@ -152,14 +152,18 @@ void UserConnection::on(BufferedSocketListener::Line, const string& aLine) throw } } -void UserConnection::connect(const Socket::AddressInfo& aServer, const string& aPort, const string& localPort, BufferedSocket::NatRoles natRole) { +void UserConnection::connect(const Socket::AddressInfo& aServer, const string& aPort, const string& localPort, BufferedSocket::NatRoles natRole, const UserPtr& aUser /*nullptr*/) { dcassert(!socket); socket = BufferedSocket::getSocket(0); socket->addListener(this); - // TODO: verify that this KeyPrint was mediated by a trusted hub? - string expKP = user ? ClientManager::getInstance()->getField(user->getCID(), hubUrl, "KP") : Util::emptyString; + string expKP; + if (aUser) { + expKP = ClientManager::getInstance()->getField(aUser->getCID(), hubUrl, "KP"); + setUser(aUser); + } + socket->connect(aServer, aPort, localPort, natRole, secure, SETTING(ALLOW_UNTRUSTED_CLIENTS), true, expKP); } @@ -203,7 +207,13 @@ void UserConnection::accept(const Socket& aServer) { dcassert(!socket); socket = BufferedSocket::getSocket(0); socket->addListener(this); - socket->accept(aServer, secure, SETTING(ALLOW_UNTRUSTED_CLIENTS)); + + /* + Technically only one side needs to verify KeyPrint, + also since we most likely requested to be connected to (and we have insufficient info otherwise) deal with TLS options check post handshake + -> SSLSocket::verifyKeyprint does full certificate verification after INF + */ + socket->accept(aServer, secure, true); } void UserConnection::inf(bool withToken, int mcnSlots) { diff --git a/airdcpp/UserConnection.h b/airdcpp/UserConnection.h index f8de48cd..ad66a5a2 100644 --- a/airdcpp/UserConnection.h +++ b/airdcpp/UserConnection.h @@ -144,7 +144,7 @@ class UserConnection : public Speaker, void setDataMode(int64_t aBytes = -1) { dcassert(socket); socket->setDataMode(aBytes); } void setLineMode(size_t rollback) { dcassert(socket); socket->setLineMode(rollback); } - void connect(const Socket::AddressInfo& aServer, const string& aPort, const string& localPort, BufferedSocket::NatRoles natRole); + void connect(const Socket::AddressInfo& aServer, const string& aPort, const string& localPort, BufferedSocket::NatRoles natRole, const UserPtr& aUser = nullptr); void accept(const Socket& aServer); void handlePM(const AdcCommand& c, bool echo) noexcept;