mirror of https://github.com/aria2/aria2
make clang-format using clang-format-3.6
parent
4abad2f64c
commit
b1132d6b10
|
@ -43,7 +43,7 @@
|
|||
int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
|
||||
aria2::A2Gid gid, void* userData)
|
||||
{
|
||||
switch(event) {
|
||||
switch (event) {
|
||||
case aria2::EVENT_ON_DOWNLOAD_COMPLETE:
|
||||
std::cerr << "COMPLETE";
|
||||
break;
|
||||
|
@ -55,15 +55,17 @@ int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
|
|||
}
|
||||
std::cerr << " [" << aria2::gidToHex(gid) << "] ";
|
||||
aria2::DownloadHandle* dh = aria2::getDownloadHandle(session, gid);
|
||||
if(!dh) return 0;
|
||||
if(dh->getNumFiles() > 0) {
|
||||
if (!dh)
|
||||
return 0;
|
||||
if (dh->getNumFiles() > 0) {
|
||||
aria2::FileData f = dh->getFile(1);
|
||||
// Path may be empty if the file name has not been determined yet.
|
||||
if(f.path.empty()) {
|
||||
if(!f.uris.empty()) {
|
||||
if (f.path.empty()) {
|
||||
if (!f.uris.empty()) {
|
||||
std::cerr << f.uris[0].uri;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
std::cerr << f.path;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +77,7 @@ int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
int rv;
|
||||
if(argc < 2) {
|
||||
if (argc < 2) {
|
||||
std::cerr << "Usage: libaria2ex URI [URI...]\n"
|
||||
<< "\n"
|
||||
<< " Download given URIs in parallel in the current directory."
|
||||
|
@ -92,46 +94,45 @@ int main(int argc, char** argv)
|
|||
config.downloadEventCallback = downloadEventCallback;
|
||||
session = aria2::sessionNew(aria2::KeyVals(), config);
|
||||
// Add download item to session
|
||||
for(int i = 1; i < argc; ++i) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
std::vector<std::string> uris = {argv[i]};
|
||||
aria2::KeyVals options;
|
||||
rv = aria2::addUri(session, nullptr, uris, options);
|
||||
if(rv < 0) {
|
||||
if (rv < 0) {
|
||||
std::cerr << "Failed to add download " << uris[0] << std::endl;
|
||||
}
|
||||
}
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
rv = aria2::run(session, aria2::RUN_ONCE);
|
||||
if(rv != 1) {
|
||||
if (rv != 1) {
|
||||
break;
|
||||
}
|
||||
// the application can call aria2 API to add URI or query progress
|
||||
// here
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto count = std::chrono::duration_cast<std::chrono::milliseconds>
|
||||
(now - start).count();
|
||||
auto count = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now - start).count();
|
||||
// Print progress information once per 500ms
|
||||
if(count >= 500) {
|
||||
if (count >= 500) {
|
||||
start = now;
|
||||
aria2::GlobalStat gstat = aria2::getGlobalStat(session);
|
||||
std::cerr << "Overall #Active:" << gstat.numActive
|
||||
<< " #waiting:" << gstat.numWaiting
|
||||
<< " D:" << gstat.downloadSpeed/1024 << "KiB/s"
|
||||
<< " U:"<< gstat.uploadSpeed/1024 << "KiB/s " << std::endl;
|
||||
<< " D:" << gstat.downloadSpeed / 1024 << "KiB/s"
|
||||
<< " U:" << gstat.uploadSpeed / 1024 << "KiB/s " << std::endl;
|
||||
std::vector<aria2::A2Gid> gids = aria2::getActiveDownload(session);
|
||||
for(const auto& gid : gids) {
|
||||
for (const auto& gid : gids) {
|
||||
aria2::DownloadHandle* dh = aria2::getDownloadHandle(session, gid);
|
||||
if(dh) {
|
||||
if (dh) {
|
||||
std::cerr << " [" << aria2::gidToHex(gid) << "] "
|
||||
<< dh->getCompletedLength() << "/"
|
||||
<< dh->getTotalLength() << "("
|
||||
<< (dh->getTotalLength() > 0 ?
|
||||
(100*dh->getCompletedLength()/dh->getTotalLength())
|
||||
: 0) << "%)"
|
||||
<< " D:"
|
||||
<< dh->getDownloadSpeed()/1024 << "KiB/s, U:"
|
||||
<< dh->getUploadSpeed()/1024 << "KiB/s"
|
||||
<< dh->getCompletedLength() << "/" << dh->getTotalLength()
|
||||
<< "(" << (dh->getTotalLength() > 0
|
||||
? (100 * dh->getCompletedLength() /
|
||||
dh->getTotalLength())
|
||||
: 0) << "%)"
|
||||
<< " D:" << dh->getDownloadSpeed() / 1024
|
||||
<< "KiB/s, U:" << dh->getUploadSpeed() / 1024 << "KiB/s"
|
||||
<< std::endl;
|
||||
aria2::deleteDownloadHandle(dh);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
// the main window.
|
||||
//
|
||||
// Compile and link like this:
|
||||
// $ g++ -O2 -Wall -g -std=c++11 `wx-config --cflags` -o libaria2wx libaria2wx.cc `wx-config --libs` -laria2 -pthread
|
||||
// $ g++ -O2 -Wall -g -std=c++11 `wx-config --cflags` -o libaria2wx
|
||||
// libaria2wx.cc `wx-config --libs` -laria2 -pthread
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
@ -51,7 +52,7 @@
|
|||
|
||||
// Interface to send message to downloader thread from UI thread
|
||||
struct Job {
|
||||
virtual ~Job() {};
|
||||
virtual ~Job(){};
|
||||
virtual void execute(aria2::Session* session) = 0;
|
||||
};
|
||||
|
||||
|
@ -59,15 +60,14 @@ class MainFrame;
|
|||
|
||||
// Interface to report back to UI thread from downloader thread
|
||||
struct Notification {
|
||||
virtual ~Notification() {};
|
||||
virtual ~Notification(){};
|
||||
virtual void notify(MainFrame* frame) = 0;
|
||||
};
|
||||
|
||||
// std::queue<T> wrapper synchronized by mutex. In this example
|
||||
// program, only one thread consumes from the queue, so separating
|
||||
// empty() and pop() is not a problem.
|
||||
template<typename T>
|
||||
class SynchronizedQueue {
|
||||
template <typename T> class SynchronizedQueue {
|
||||
public:
|
||||
SynchronizedQueue() {}
|
||||
~SynchronizedQueue() {}
|
||||
|
@ -88,8 +88,9 @@ public:
|
|||
std::lock_guard<std::mutex> l(m_);
|
||||
return q_.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<std::unique_ptr<T> > q_;
|
||||
std::queue<std::unique_ptr<T>> q_;
|
||||
std::mutex m_;
|
||||
};
|
||||
|
||||
|
@ -109,8 +110,9 @@ struct ShutdownJob : public Job {
|
|||
// Job to send URI to download and options to downloader thread
|
||||
struct AddUriJob : public Job {
|
||||
AddUriJob(std::vector<std::string>&& uris, aria2::KeyVals&& options)
|
||||
: uris(uris), options(options)
|
||||
{}
|
||||
: uris(uris), options(options)
|
||||
{
|
||||
}
|
||||
virtual void execute(aria2::Session* session)
|
||||
{
|
||||
// TODO check return value
|
||||
|
@ -148,6 +150,7 @@ public:
|
|||
void OnTimer(wxTimerEvent& event);
|
||||
void OnAddUri(wxCommandEvent& event);
|
||||
void UpdateActiveStatus(const std::vector<DownloadStatus>& v);
|
||||
|
||||
private:
|
||||
wxTextCtrl* text_;
|
||||
wxTimer timer_;
|
||||
|
@ -157,13 +160,9 @@ private:
|
|||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
enum {
|
||||
TIMER_ID = 1
|
||||
};
|
||||
enum { TIMER_ID = 1 };
|
||||
|
||||
enum {
|
||||
MI_ADD_URI = 1
|
||||
};
|
||||
enum { MI_ADD_URI = 1 };
|
||||
|
||||
BEGIN_EVENT_TABLE(MainFrame, wxFrame)
|
||||
EVT_CLOSE(MainFrame::OnCloseWindow)
|
||||
|
@ -177,6 +176,7 @@ public:
|
|||
void OnButton(wxCommandEvent& event);
|
||||
wxString GetUri();
|
||||
wxString GetOption();
|
||||
|
||||
private:
|
||||
wxTextCtrl* uriText_;
|
||||
wxTextCtrl* optionText_;
|
||||
|
@ -193,7 +193,8 @@ IMPLEMENT_APP(Aria2App)
|
|||
|
||||
bool Aria2App::OnInit()
|
||||
{
|
||||
if(!wxApp::OnInit()) return false;
|
||||
if (!wxApp::OnInit())
|
||||
return false;
|
||||
aria2::libraryInit();
|
||||
MainFrame* frame = new MainFrame(wxT("libaria2 GUI example"));
|
||||
frame->Show(true);
|
||||
|
@ -207,14 +208,12 @@ int Aria2App::OnExit()
|
|||
}
|
||||
|
||||
MainFrame::MainFrame(const wxString& title)
|
||||
: wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition,
|
||||
wxSize(640, 400)),
|
||||
timer_(this, TIMER_ID),
|
||||
downloaderThread_(downloaderJob, std::ref(jobq_), std::ref(notifyq_))
|
||||
: wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxSize(640, 400)),
|
||||
timer_(this, TIMER_ID),
|
||||
downloaderThread_(downloaderJob, std::ref(jobq_), std::ref(notifyq_))
|
||||
{
|
||||
wxMenu* downloadMenu = new wxMenu;
|
||||
downloadMenu->Append(MI_ADD_URI, wxT("&Add URI"),
|
||||
wxT("Add URI to download"));
|
||||
downloadMenu->Append(MI_ADD_URI, wxT("&Add URI"), wxT("Add URI to download"));
|
||||
|
||||
wxMenuBar* menuBar = new wxMenuBar();
|
||||
menuBar->Append(downloadMenu, wxT("&Download"));
|
||||
|
@ -237,35 +236,36 @@ void MainFrame::OnAddUri(wxCommandEvent& WXUNUSED(event))
|
|||
{
|
||||
AddUriDialog dlg(this);
|
||||
int ret = dlg.ShowModal();
|
||||
if(ret == 0) {
|
||||
if(dlg.GetUri().IsEmpty()) {
|
||||
if (ret == 0) {
|
||||
if (dlg.GetUri().IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> uris = { std::string(dlg.GetUri().mb_str()) };
|
||||
std::vector<std::string> uris = {std::string(dlg.GetUri().mb_str())};
|
||||
std::string optstr(dlg.GetOption().mb_str());
|
||||
aria2::KeyVals options;
|
||||
int keyfirst = 0;
|
||||
for(int i = 0; i < (int)optstr.size(); ++i) {
|
||||
if(optstr[i] == '\n') {
|
||||
keyfirst = i+1;
|
||||
} else if(optstr[i] == '=') {
|
||||
for (int i = 0; i < (int)optstr.size(); ++i) {
|
||||
if (optstr[i] == '\n') {
|
||||
keyfirst = i + 1;
|
||||
}
|
||||
else if (optstr[i] == '=') {
|
||||
int j;
|
||||
for(j = i+1; j < (int)optstr.size(); ++j) {
|
||||
if(optstr[j] == '\n') {
|
||||
for (j = i + 1; j < (int)optstr.size(); ++j) {
|
||||
if (optstr[j] == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i - keyfirst > 0) {
|
||||
options.push_back
|
||||
(std::make_pair(optstr.substr(keyfirst, i - keyfirst),
|
||||
optstr.substr(i + 1, j - i - 1)));
|
||||
if (i - keyfirst > 0) {
|
||||
options.push_back(
|
||||
std::make_pair(optstr.substr(keyfirst, i - keyfirst),
|
||||
optstr.substr(i + 1, j - i - 1)));
|
||||
}
|
||||
keyfirst = j + 1;
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
jobq_.push(std::unique_ptr<Job>(new AddUriJob(std::move(uris),
|
||||
std::move(options))));
|
||||
jobq_.push(std::unique_ptr<Job>(
|
||||
new AddUriJob(std::move(uris), std::move(options))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,56 +281,47 @@ void MainFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
|
|||
|
||||
void MainFrame::OnTimer(wxTimerEvent& event)
|
||||
{
|
||||
while(!notifyq_.empty()) {
|
||||
while (!notifyq_.empty()) {
|
||||
std::unique_ptr<Notification> nt = notifyq_.pop();
|
||||
nt->notify(this);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string abbrevsize(T size)
|
||||
template <typename T> std::string abbrevsize(T size)
|
||||
{
|
||||
if(size >= 1024*1024*1024) {
|
||||
return std::to_string(size/1024/1024/1024)+"G";
|
||||
} else if(size >= 1024*1024) {
|
||||
return std::to_string(size/1024/1024)+"M";
|
||||
} else if(size >= 1024) {
|
||||
return std::to_string(size/1024)+"K";
|
||||
} else {
|
||||
if (size >= 1024 * 1024 * 1024) {
|
||||
return std::to_string(size / 1024 / 1024 / 1024) + "G";
|
||||
}
|
||||
else if (size >= 1024 * 1024) {
|
||||
return std::to_string(size / 1024 / 1024) + "M";
|
||||
}
|
||||
else if (size >= 1024) {
|
||||
return std::to_string(size / 1024) + "K";
|
||||
}
|
||||
else {
|
||||
return std::to_string(size);
|
||||
}
|
||||
}
|
||||
|
||||
wxString towxs(const std::string& s)
|
||||
{
|
||||
return wxString(s.c_str(), wxConvUTF8);
|
||||
}
|
||||
wxString towxs(const std::string& s) { return wxString(s.c_str(), wxConvUTF8); }
|
||||
|
||||
void MainFrame::UpdateActiveStatus(const std::vector<DownloadStatus>& v)
|
||||
{
|
||||
text_->Clear();
|
||||
for(auto& a : v) {
|
||||
*text_ << wxT("[")
|
||||
<< towxs(aria2::gidToHex(a.gid))
|
||||
<< wxT("] ")
|
||||
<< towxs(abbrevsize(a.completedLength))
|
||||
<< wxT("/")
|
||||
<< towxs(abbrevsize(a.totalLength))
|
||||
<< wxT("(")
|
||||
<< (a.totalLength != 0 ? a.completedLength*100/a.totalLength : 0)
|
||||
<< wxT("%)")
|
||||
<< wxT(" D:")
|
||||
<< towxs(abbrevsize(a.downloadSpeed))
|
||||
<< wxT(" U:")
|
||||
<< towxs(abbrevsize(a.uploadSpeed))
|
||||
<< wxT("\n")
|
||||
for (auto& a : v) {
|
||||
*text_ << wxT("[") << towxs(aria2::gidToHex(a.gid)) << wxT("] ")
|
||||
<< towxs(abbrevsize(a.completedLength)) << wxT("/")
|
||||
<< towxs(abbrevsize(a.totalLength)) << wxT("(")
|
||||
<< (a.totalLength != 0 ? a.completedLength * 100 / a.totalLength : 0)
|
||||
<< wxT("%)") << wxT(" D:") << towxs(abbrevsize(a.downloadSpeed))
|
||||
<< wxT(" U:") << towxs(abbrevsize(a.uploadSpeed)) << wxT("\n")
|
||||
<< wxT("File:") << towxs(a.filename) << wxT("\n");
|
||||
}
|
||||
}
|
||||
|
||||
AddUriDialog::AddUriDialog(wxWindow* parent)
|
||||
: wxDialog(parent, wxID_ANY, wxT("Add URI"), wxDefaultPosition,
|
||||
wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
: wxDialog(parent, wxID_ANY, wxT("Add URI"), wxDefaultPosition,
|
||||
wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
{
|
||||
wxPanel* panel = new wxPanel(this, wxID_ANY);
|
||||
wxBoxSizer* box = new wxBoxSizer(wxVERTICAL);
|
||||
|
@ -339,9 +330,8 @@ AddUriDialog::AddUriDialog(wxWindow* parent)
|
|||
uriText_ = new wxTextCtrl(panel, wxID_ANY);
|
||||
box->Add(uriText_, wxSizerFlags().Align(wxGROW));
|
||||
// Option multi text input
|
||||
box->Add(new wxStaticText
|
||||
(panel, wxID_ANY,
|
||||
wxT("Options (key=value pair per line, e.g. dir=/tmp")));
|
||||
box->Add(new wxStaticText(
|
||||
panel, wxID_ANY, wxT("Options (key=value pair per line, e.g. dir=/tmp")));
|
||||
optionText_ = new wxTextCtrl(panel, wxID_ANY, wxT(""), wxDefaultPosition,
|
||||
wxDefaultSize, wxTE_MULTILINE);
|
||||
box->Add(optionText_, wxSizerFlags().Align(wxGROW));
|
||||
|
@ -363,38 +353,25 @@ AddUriDialog::AddUriDialog(wxWindow* parent)
|
|||
void AddUriDialog::OnButton(wxCommandEvent& event)
|
||||
{
|
||||
int ret = -1;
|
||||
if(event.GetEventObject() == okBtn_) {
|
||||
if (event.GetEventObject() == okBtn_) {
|
||||
ret = 0;
|
||||
}
|
||||
EndModal(ret);
|
||||
}
|
||||
|
||||
wxString AddUriDialog::GetUri()
|
||||
{
|
||||
return uriText_->GetValue();
|
||||
}
|
||||
wxString AddUriDialog::GetUri() { return uriText_->GetValue(); }
|
||||
|
||||
wxString AddUriDialog::GetOption()
|
||||
{
|
||||
return optionText_->GetValue();
|
||||
}
|
||||
wxString AddUriDialog::GetOption() { return optionText_->GetValue(); }
|
||||
|
||||
struct DownloadStatusNotification : public Notification {
|
||||
DownloadStatusNotification(std::vector<DownloadStatus>&& v)
|
||||
: v(v) {}
|
||||
virtual void notify(MainFrame* frame)
|
||||
{
|
||||
frame->UpdateActiveStatus(v);
|
||||
}
|
||||
DownloadStatusNotification(std::vector<DownloadStatus>&& v) : v(v) {}
|
||||
virtual void notify(MainFrame* frame) { frame->UpdateActiveStatus(v); }
|
||||
std::vector<DownloadStatus> v;
|
||||
};
|
||||
|
||||
struct ShutdownNotification : public Notification {
|
||||
ShutdownNotification() {}
|
||||
virtual void notify(MainFrame* frame)
|
||||
{
|
||||
frame->Close();
|
||||
}
|
||||
virtual void notify(MainFrame* frame) { frame->Close(); }
|
||||
};
|
||||
|
||||
int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
|
||||
|
@ -406,32 +383,32 @@ int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
|
|||
config.keepRunning = true;
|
||||
session = aria2::sessionNew(aria2::KeyVals(), config);
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
int rv = aria2::run(session, aria2::RUN_ONCE);
|
||||
if(rv != 1) {
|
||||
if (rv != 1) {
|
||||
break;
|
||||
}
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto count = std::chrono::duration_cast<std::chrono::milliseconds>
|
||||
(now - start).count();
|
||||
while(!jobq.empty()) {
|
||||
auto count = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now - start).count();
|
||||
while (!jobq.empty()) {
|
||||
std::unique_ptr<Job> job = jobq.pop();
|
||||
job->execute(session);
|
||||
}
|
||||
if(count >= 900) {
|
||||
if (count >= 900) {
|
||||
start = now;
|
||||
std::vector<aria2::A2Gid> gids = aria2::getActiveDownload(session);
|
||||
std::vector<DownloadStatus> v;
|
||||
for(auto gid : gids) {
|
||||
for (auto gid : gids) {
|
||||
aria2::DownloadHandle* dh = aria2::getDownloadHandle(session, gid);
|
||||
if(dh) {
|
||||
if (dh) {
|
||||
DownloadStatus st;
|
||||
st.gid = gid;
|
||||
st.totalLength = dh->getTotalLength();
|
||||
st.completedLength = dh->getCompletedLength();
|
||||
st.downloadSpeed = dh->getDownloadSpeed();
|
||||
st.uploadSpeed = dh->getUploadSpeed();
|
||||
if(dh->getNumFiles() > 0) {
|
||||
if (dh->getNumFiles() > 0) {
|
||||
aria2::FileData file = dh->getFile(1);
|
||||
st.filename = file.path;
|
||||
}
|
||||
|
@ -439,8 +416,8 @@ int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
|
|||
aria2::deleteDownloadHandle(dh);
|
||||
}
|
||||
}
|
||||
notifyq.push(std::unique_ptr<Notification>
|
||||
(new DownloadStatusNotification(std::move(v))));
|
||||
notifyq.push(std::unique_ptr<Notification>(
|
||||
new DownloadStatusNotification(std::move(v))));
|
||||
}
|
||||
}
|
||||
int rv = aria2::sessionFinal(session);
|
||||
|
@ -449,4 +426,3 @@ int downloaderJob(JobQueue& jobq, NotifyQueue& notifyq)
|
|||
notifyq.push(std::unique_ptr<Notification>(new ShutdownNotification()));
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,13 +38,13 @@
|
|||
#include "common.h"
|
||||
|
||||
#ifdef USE_INTERNAL_ARC4
|
||||
# include "InternalARC4Encryptor.h"
|
||||
#include "InternalARC4Encryptor.h"
|
||||
#elif HAVE_LIBNETTLE
|
||||
# include "LibnettleARC4Encryptor.h"
|
||||
#include "LibnettleARC4Encryptor.h"
|
||||
#elif HAVE_LIBGCRYPT
|
||||
# include "LibgcryptARC4Encryptor.h"
|
||||
#include "LibgcryptARC4Encryptor.h"
|
||||
#elif HAVE_OPENSSL
|
||||
# include "LibsslARC4Encryptor.h"
|
||||
#include "LibsslARC4Encryptor.h"
|
||||
#endif
|
||||
|
||||
#endif // D_ARC4_ENCRYPTOR_H
|
||||
|
|
|
@ -42,8 +42,8 @@ AbstractAuthResolver::AbstractAuthResolver() {}
|
|||
|
||||
AbstractAuthResolver::~AbstractAuthResolver() {}
|
||||
|
||||
void AbstractAuthResolver::setUserDefinedCred
|
||||
(std::string user, std::string password)
|
||||
void AbstractAuthResolver::setUserDefinedCred(std::string user,
|
||||
std::string password)
|
||||
{
|
||||
userDefinedUser_ = std::move(user);
|
||||
userDefinedPassword_ = std::move(password);
|
||||
|
@ -55,8 +55,8 @@ AbstractAuthResolver::getUserDefinedAuthConfig() const
|
|||
return AuthConfig::create(userDefinedUser_, userDefinedPassword_);
|
||||
}
|
||||
|
||||
void AbstractAuthResolver::setDefaultCred
|
||||
(std::string user, std::string password)
|
||||
void AbstractAuthResolver::setDefaultCred(std::string user,
|
||||
std::string password)
|
||||
{
|
||||
defaultUser_ = std::move(user);
|
||||
defaultPassword_ = std::move(password);
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
void setDefaultCred(std::string user, std::string password);
|
||||
|
||||
std::unique_ptr<AuthConfig> getDefaultAuthConfig() const;
|
||||
|
||||
private:
|
||||
std::string userDefinedUser_;
|
||||
std::string userDefinedPassword_;
|
||||
|
|
|
@ -40,18 +40,19 @@
|
|||
namespace aria2 {
|
||||
|
||||
AbstractBtMessage::AbstractBtMessage(uint8_t id, const char* name)
|
||||
: BtMessage(id),
|
||||
invalidate_(false),
|
||||
uploading_(false),
|
||||
cuid_(0),
|
||||
name_(name),
|
||||
pieceStorage_(nullptr),
|
||||
dispatcher_(nullptr),
|
||||
messageFactory_(nullptr),
|
||||
requestFactory_(nullptr),
|
||||
peerConnection_(nullptr),
|
||||
metadataGetMode_(false)
|
||||
{}
|
||||
: BtMessage(id),
|
||||
invalidate_(false),
|
||||
uploading_(false),
|
||||
cuid_(0),
|
||||
name_(name),
|
||||
pieceStorage_(nullptr),
|
||||
dispatcher_(nullptr),
|
||||
messageFactory_(nullptr),
|
||||
requestFactory_(nullptr),
|
||||
peerConnection_(nullptr),
|
||||
metadataGetMode_(false)
|
||||
{
|
||||
}
|
||||
|
||||
AbstractBtMessage::~AbstractBtMessage() {}
|
||||
|
||||
|
@ -62,14 +63,13 @@ void AbstractBtMessage::setPeer(const std::shared_ptr<Peer>& peer)
|
|||
|
||||
void AbstractBtMessage::validate()
|
||||
{
|
||||
if(validator_) {
|
||||
if (validator_) {
|
||||
validator_->validate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AbstractBtMessage::setBtMessageValidator
|
||||
(std::unique_ptr<BtMessageValidator> validator)
|
||||
void AbstractBtMessage::setBtMessageValidator(
|
||||
std::unique_ptr<BtMessageValidator> validator)
|
||||
{
|
||||
validator_ = std::move(validator);
|
||||
}
|
||||
|
|
|
@ -71,69 +71,38 @@ private:
|
|||
std::unique_ptr<BtMessageValidator> validator_;
|
||||
|
||||
bool metadataGetMode_;
|
||||
|
||||
protected:
|
||||
PieceStorage* getPieceStorage() const
|
||||
{
|
||||
return pieceStorage_;
|
||||
}
|
||||
PieceStorage* getPieceStorage() const { return pieceStorage_; }
|
||||
|
||||
PeerConnection* getPeerConnection() const
|
||||
{
|
||||
return peerConnection_;
|
||||
}
|
||||
PeerConnection* getPeerConnection() const { return peerConnection_; }
|
||||
|
||||
BtMessageDispatcher* getBtMessageDispatcher() const
|
||||
{
|
||||
return dispatcher_;
|
||||
}
|
||||
BtMessageDispatcher* getBtMessageDispatcher() const { return dispatcher_; }
|
||||
|
||||
BtRequestFactory* getBtRequestFactory() const
|
||||
{
|
||||
return requestFactory_;
|
||||
}
|
||||
BtRequestFactory* getBtRequestFactory() const { return requestFactory_; }
|
||||
|
||||
BtMessageFactory* getBtMessageFactory() const
|
||||
{
|
||||
return messageFactory_;
|
||||
}
|
||||
BtMessageFactory* getBtMessageFactory() const { return messageFactory_; }
|
||||
|
||||
bool isMetadataGetMode() const { return metadataGetMode_; }
|
||||
|
||||
bool isMetadataGetMode() const
|
||||
{
|
||||
return metadataGetMode_;
|
||||
}
|
||||
public:
|
||||
AbstractBtMessage(uint8_t id, const char* name);
|
||||
|
||||
virtual ~AbstractBtMessage();
|
||||
|
||||
virtual bool isInvalidate() CXX11_OVERRIDE {
|
||||
return invalidate_;
|
||||
}
|
||||
virtual bool isInvalidate() CXX11_OVERRIDE { return invalidate_; }
|
||||
|
||||
void setInvalidate(bool invalidate) {
|
||||
invalidate_ = invalidate;
|
||||
}
|
||||
void setInvalidate(bool invalidate) { invalidate_ = invalidate; }
|
||||
|
||||
virtual bool isUploading() CXX11_OVERRIDE {
|
||||
return uploading_;
|
||||
}
|
||||
virtual bool isUploading() CXX11_OVERRIDE { return uploading_; }
|
||||
|
||||
void setUploading(bool uploading) {
|
||||
uploading_ = uploading;
|
||||
}
|
||||
void setUploading(bool uploading) { uploading_ = uploading; }
|
||||
|
||||
cuid_t getCuid() const {
|
||||
return cuid_;
|
||||
}
|
||||
cuid_t getCuid() const { return cuid_; }
|
||||
|
||||
void setCuid(cuid_t cuid) {
|
||||
cuid_ = cuid;
|
||||
}
|
||||
void setCuid(cuid_t cuid) { cuid_ = cuid; }
|
||||
|
||||
const std::shared_ptr<Peer>& getPeer() const
|
||||
{
|
||||
return peer_;
|
||||
}
|
||||
const std::shared_ptr<Peer>& getPeer() const { return peer_; }
|
||||
|
||||
void setPeer(const std::shared_ptr<Peer>& peer);
|
||||
|
||||
|
@ -143,11 +112,15 @@ public:
|
|||
|
||||
virtual void onQueued() CXX11_OVERRIDE {}
|
||||
|
||||
virtual void onAbortOutstandingRequestEvent
|
||||
(const BtAbortOutstandingRequestEvent& event) CXX11_OVERRIDE {}
|
||||
virtual void onAbortOutstandingRequestEvent(
|
||||
const BtAbortOutstandingRequestEvent& event) CXX11_OVERRIDE
|
||||
{
|
||||
}
|
||||
|
||||
virtual void onCancelSendingPieceEvent
|
||||
(const BtCancelSendingPieceEvent& event) CXX11_OVERRIDE {}
|
||||
virtual void onCancelSendingPieceEvent(const BtCancelSendingPieceEvent& event)
|
||||
CXX11_OVERRIDE
|
||||
{
|
||||
}
|
||||
|
||||
virtual void onChokingEvent(const BtChokingEvent& event) CXX11_OVERRIDE {}
|
||||
|
||||
|
@ -163,15 +136,9 @@ public:
|
|||
|
||||
void setBtRequestFactory(BtRequestFactory* factory);
|
||||
|
||||
const char* getName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
const char* getName() const { return name_; }
|
||||
|
||||
void enableMetadataGetMode()
|
||||
{
|
||||
metadataGetMode_ = true;
|
||||
}
|
||||
void enableMetadataGetMode() { metadataGetMode_ = true; }
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -74,31 +74,28 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
AbstractCommand::AbstractCommand
|
||||
(cuid_t cuid,
|
||||
const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry,
|
||||
RequestGroup* requestGroup,
|
||||
DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& s,
|
||||
const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer,
|
||||
bool incNumConnection)
|
||||
: Command(cuid),
|
||||
req_(req),
|
||||
fileEntry_(fileEntry),
|
||||
socket_(s),
|
||||
socketRecvBuffer_(socketRecvBuffer),
|
||||
AbstractCommand::AbstractCommand(
|
||||
cuid_t cuid, const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
|
||||
DownloadEngine* e, const std::shared_ptr<SocketCore>& s,
|
||||
const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer,
|
||||
bool incNumConnection)
|
||||
: Command(cuid),
|
||||
req_(req),
|
||||
fileEntry_(fileEntry),
|
||||
socket_(s),
|
||||
socketRecvBuffer_(socketRecvBuffer),
|
||||
#ifdef ENABLE_ASYNC_DNS
|
||||
asyncNameResolverMan_(make_unique<AsyncNameResolverMan>()),
|
||||
asyncNameResolverMan_(make_unique<AsyncNameResolverMan>()),
|
||||
#endif // ENABLE_ASYNC_DNS
|
||||
requestGroup_(requestGroup),
|
||||
e_(e),
|
||||
checkPoint_(global::wallclock()),
|
||||
serverStatTimer_(global::wallclock()),
|
||||
timeout_(requestGroup->getTimeout()),
|
||||
checkSocketIsReadable_(false),
|
||||
checkSocketIsWritable_(false),
|
||||
incNumConnection_(incNumConnection)
|
||||
requestGroup_(requestGroup),
|
||||
e_(e),
|
||||
checkPoint_(global::wallclock()),
|
||||
serverStatTimer_(global::wallclock()),
|
||||
timeout_(requestGroup->getTimeout()),
|
||||
checkSocketIsReadable_(false),
|
||||
checkSocketIsWritable_(false),
|
||||
incNumConnection_(incNumConnection)
|
||||
{
|
||||
if (socket_ && socket_->isOpen()) {
|
||||
setReadCheckSocket(socket_);
|
||||
|
@ -127,19 +124,18 @@ AbstractCommand::~AbstractCommand()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
AbstractCommand::useFasterRequest(const std::shared_ptr<Request>& fasterRequest)
|
||||
void AbstractCommand::useFasterRequest(
|
||||
const std::shared_ptr<Request>& fasterRequest)
|
||||
{
|
||||
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Use faster Request hostname=%s, port=%u",
|
||||
getCuid(),
|
||||
fasterRequest->getHost().c_str(),
|
||||
getCuid(), fasterRequest->getHost().c_str(),
|
||||
fasterRequest->getPort()));
|
||||
// Cancel current Request object and use faster one.
|
||||
fileEntry_->removeRequest(req_);
|
||||
e_->setNoWait(true);
|
||||
e_->addCommand
|
||||
(InitiateConnectionCommandFactory::createInitiateConnectionCommand
|
||||
(getCuid(), fasterRequest, fileEntry_, requestGroup_, e_));
|
||||
e_->addCommand(
|
||||
InitiateConnectionCommandFactory::createInitiateConnectionCommand(
|
||||
getCuid(), fasterRequest, fileEntry_, requestGroup_, e_));
|
||||
}
|
||||
|
||||
bool AbstractCommand::shouldProcess() const
|
||||
|
@ -167,7 +163,7 @@ bool AbstractCommand::shouldProcess() const
|
|||
if (!checkSocketIsReadable_ && !checkSocketIsWritable_ && !resolverChecked) {
|
||||
return true;
|
||||
}
|
||||
#else // ENABLE_ASYNC_DNS
|
||||
#else // ENABLE_ASYNC_DNS
|
||||
if (!checkSocketIsReadable_ && !checkSocketIsWritable_) {
|
||||
return true;
|
||||
}
|
||||
|
@ -180,11 +176,8 @@ bool AbstractCommand::execute()
|
|||
{
|
||||
A2_LOG_DEBUG(fmt("CUID#%" PRId64
|
||||
" - socket: read:%d, write:%d, hup:%d, err:%d",
|
||||
getCuid(),
|
||||
readEventEnabled(),
|
||||
writeEventEnabled(),
|
||||
hupEventEnabled(),
|
||||
errorEventEnabled()));
|
||||
getCuid(), readEventEnabled(), writeEventEnabled(),
|
||||
hupEventEnabled(), errorEventEnabled()));
|
||||
try {
|
||||
if (requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
|
||||
return true;
|
||||
|
@ -194,8 +187,7 @@ bool AbstractCommand::execute()
|
|||
A2_LOG_DEBUG(fmt("CUID#%" PRId64
|
||||
" - Discard original URI=%s because it is"
|
||||
" requested.",
|
||||
getCuid(),
|
||||
req_->getUri().c_str()));
|
||||
getCuid(), req_->getUri().c_str()));
|
||||
return prepareForRetry(0);
|
||||
}
|
||||
|
||||
|
@ -243,8 +235,8 @@ bool AbstractCommand::execute()
|
|||
if (getOption()->getAsBool(PREF_SELECT_LEAST_USED_HOST)) {
|
||||
getDownloadEngine()->getRequestGroupMan()->getUsedHosts(usedHosts);
|
||||
}
|
||||
auto fasterRequest = fileEntry_->findFasterRequest
|
||||
(req_, usedHosts, e_->getRequestGroupMan()->getServerStatMan());
|
||||
auto fasterRequest = fileEntry_->findFasterRequest(
|
||||
req_, usedHosts, e_->getRequestGroupMan()->getServerStatMan());
|
||||
if (fasterRequest) {
|
||||
useFasterRequest(fasterRequest);
|
||||
return true;
|
||||
|
@ -296,8 +288,8 @@ bool AbstractCommand::execute()
|
|||
size_t minSplitSize = calculateMinSplitSize();
|
||||
size_t maxSegments = req_->getMaxPipelinedRequest();
|
||||
if (segments_.size() < maxSegments) {
|
||||
sm->getSegment
|
||||
(segments_, getCuid(), minSplitSize, fileEntry_, maxSegments);
|
||||
sm->getSegment(segments_, getCuid(), minSplitSize, fileEntry_,
|
||||
maxSegments);
|
||||
}
|
||||
if (segments_.empty()) {
|
||||
return prepareForRetry(0);
|
||||
|
@ -308,22 +300,21 @@ bool AbstractCommand::execute()
|
|||
}
|
||||
|
||||
if (errorEventEnabled()) {
|
||||
throw DL_RETRY_EX
|
||||
(fmt(MSG_NETWORK_PROBLEM, socket_->getSocketError().c_str()));
|
||||
throw DL_RETRY_EX(
|
||||
fmt(MSG_NETWORK_PROBLEM, socket_->getSocketError().c_str()));
|
||||
}
|
||||
|
||||
if (checkPoint_.difference(global::wallclock()) >= timeout_) {
|
||||
// timeout triggers ServerStat error state.
|
||||
auto ss = e_->getRequestGroupMan()->getOrCreateServerStat
|
||||
(req_->getHost(), req_->getProtocol());
|
||||
auto ss = e_->getRequestGroupMan()->getOrCreateServerStat(
|
||||
req_->getHost(), req_->getProtocol());
|
||||
ss->setError();
|
||||
// When DNS query was timeout, req_->getConnectedAddr() is
|
||||
// empty.
|
||||
if (!req_->getConnectedAddr().empty()) {
|
||||
// Purging IP address cache to renew IP address.
|
||||
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Marking IP address %s as bad",
|
||||
getCuid(),
|
||||
req_->getConnectedAddr().c_str()));
|
||||
getCuid(), req_->getConnectedAddr().c_str()));
|
||||
e_->markBadIPAddress(req_->getConnectedHostname(),
|
||||
req_->getConnectedAddr(),
|
||||
req_->getConnectedPort());
|
||||
|
@ -345,9 +336,9 @@ bool AbstractCommand::execute()
|
|||
catch (DlAbortEx& err) {
|
||||
requestGroup_->setLastErrorCode(err.getErrorCode(), err.what());
|
||||
if (req_) {
|
||||
A2_LOG_ERROR_EX
|
||||
(fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
|
||||
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
|
||||
A2_LOG_ERROR_EX(
|
||||
fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
|
||||
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
|
||||
fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
|
||||
if (err.getErrorCode() == error_code::CANNOT_RESUME) {
|
||||
requestGroup_->increaseResumeFailureCount();
|
||||
|
@ -362,9 +353,9 @@ bool AbstractCommand::execute()
|
|||
}
|
||||
catch (DlRetryEx& err) {
|
||||
assert(req_);
|
||||
A2_LOG_INFO_EX
|
||||
(fmt(MSG_RESTARTING_DOWNLOAD, getCuid(), req_->getUri().c_str()),
|
||||
DL_RETRY_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
|
||||
A2_LOG_INFO_EX(
|
||||
fmt(MSG_RESTARTING_DOWNLOAD, getCuid(), req_->getUri().c_str()),
|
||||
DL_RETRY_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
|
||||
req_->addTryCount();
|
||||
req_->resetRedirectCount();
|
||||
req_->resetUri();
|
||||
|
@ -373,8 +364,8 @@ bool AbstractCommand::execute()
|
|||
bool isAbort = maxTries != 0 && req_->getTryCount() >= maxTries;
|
||||
if (isAbort) {
|
||||
A2_LOG_INFO(fmt(MSG_MAX_TRY, getCuid(), req_->getTryCount()));
|
||||
A2_LOG_ERROR_EX
|
||||
(fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), err);
|
||||
A2_LOG_ERROR_EX(
|
||||
fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()), err);
|
||||
fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
|
||||
requestGroup_->setLastErrorCode(err.getErrorCode(), err.what());
|
||||
if (err.getErrorCode() == error_code::CANNOT_RESUME) {
|
||||
|
@ -394,11 +385,12 @@ bool AbstractCommand::execute()
|
|||
catch (DownloadFailureException& err) {
|
||||
requestGroup_->setLastErrorCode(err.getErrorCode(), err.what());
|
||||
if (req_) {
|
||||
A2_LOG_ERROR_EX
|
||||
(fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
|
||||
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
|
||||
A2_LOG_ERROR_EX(
|
||||
fmt(MSG_DOWNLOAD_ABORTED, getCuid(), req_->getUri().c_str()),
|
||||
DL_ABORT_EX2(fmt("URI=%s", req_->getCurrentUri().c_str()), err));
|
||||
fileEntry_->addURIResult(req_->getUri(), err.getErrorCode());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, err);
|
||||
}
|
||||
requestGroup_->setHaltRequested(true);
|
||||
|
@ -422,8 +414,8 @@ void AbstractCommand::tryReserved()
|
|||
return;
|
||||
}
|
||||
}
|
||||
A2_LOG_DEBUG
|
||||
(fmt("CUID#%" PRId64 " - Trying reserved/pooled request.", getCuid()));
|
||||
A2_LOG_DEBUG(
|
||||
fmt("CUID#%" PRId64 " - Trying reserved/pooled request.", getCuid()));
|
||||
std::vector<std::unique_ptr<Command>> commands;
|
||||
requestGroup_->createNextCommand(commands, e_, 1);
|
||||
e_->setNoWait(true);
|
||||
|
@ -443,8 +435,7 @@ bool AbstractCommand::prepareForRetry(time_t wait)
|
|||
req_->setMaxPipelinedRequest(1);
|
||||
|
||||
fileEntry_->poolRequest(req_);
|
||||
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Pooling request URI=%s",
|
||||
getCuid(),
|
||||
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Pooling request URI=%s", getCuid(),
|
||||
req_->getUri().c_str()));
|
||||
if (getSegmentMan()) {
|
||||
getSegmentMan()->recognizeSegmentFor(fileEntry_);
|
||||
|
@ -518,8 +509,7 @@ void AbstractCommand::onAbort()
|
|||
uris.reserve(res.size());
|
||||
std::transform(std::begin(res), std::end(res), std::back_inserter(uris),
|
||||
std::mem_fn(&URIResult::getURI));
|
||||
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - %lu URIs found.",
|
||||
getCuid(),
|
||||
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - %lu URIs found.", getCuid(),
|
||||
static_cast<unsigned long int>(uris.size())));
|
||||
fileEntry_->addUris(std::begin(uris), std::end(uris));
|
||||
getSegmentMan()->recognizeSegmentFor(fileEntry_);
|
||||
|
@ -536,8 +526,8 @@ void AbstractCommand::disableReadCheckSocket()
|
|||
readCheckTarget_.reset();
|
||||
}
|
||||
|
||||
void
|
||||
AbstractCommand::setReadCheckSocket(const std::shared_ptr<SocketCore>& socket)
|
||||
void AbstractCommand::setReadCheckSocket(
|
||||
const std::shared_ptr<SocketCore>& socket)
|
||||
{
|
||||
if (!socket->isOpen()) {
|
||||
disableReadCheckSocket();
|
||||
|
@ -558,9 +548,8 @@ AbstractCommand::setReadCheckSocket(const std::shared_ptr<SocketCore>& socket)
|
|||
readCheckTarget_ = socket;
|
||||
}
|
||||
|
||||
void
|
||||
AbstractCommand::setReadCheckSocketIf(const std::shared_ptr<SocketCore>& socket,
|
||||
bool pred)
|
||||
void AbstractCommand::setReadCheckSocketIf(
|
||||
const std::shared_ptr<SocketCore>& socket, bool pred)
|
||||
{
|
||||
if (pred) {
|
||||
setReadCheckSocket(socket);
|
||||
|
@ -580,8 +569,8 @@ void AbstractCommand::disableWriteCheckSocket()
|
|||
writeCheckTarget_.reset();
|
||||
}
|
||||
|
||||
void
|
||||
AbstractCommand::setWriteCheckSocket(const std::shared_ptr<SocketCore>& socket)
|
||||
void AbstractCommand::setWriteCheckSocket(
|
||||
const std::shared_ptr<SocketCore>& socket)
|
||||
{
|
||||
if (!socket->isOpen()) {
|
||||
disableWriteCheckSocket();
|
||||
|
@ -602,8 +591,8 @@ AbstractCommand::setWriteCheckSocket(const std::shared_ptr<SocketCore>& socket)
|
|||
writeCheckTarget_ = socket;
|
||||
}
|
||||
|
||||
void AbstractCommand::setWriteCheckSocketIf
|
||||
(const std::shared_ptr<SocketCore>& socket, bool pred)
|
||||
void AbstractCommand::setWriteCheckSocketIf(
|
||||
const std::shared_ptr<SocketCore>& socket, bool pred)
|
||||
{
|
||||
if (pred) {
|
||||
setWriteCheckSocket(socket);
|
||||
|
@ -623,10 +612,8 @@ void AbstractCommand::swapSocket(std::shared_ptr<SocketCore>& socket)
|
|||
namespace {
|
||||
// Constructs proxy URI, merging username and password if they are
|
||||
// defined.
|
||||
std::string makeProxyUri(PrefPtr proxyPref,
|
||||
PrefPtr proxyUser,
|
||||
PrefPtr proxyPasswd,
|
||||
const Option* option)
|
||||
std::string makeProxyUri(PrefPtr proxyPref, PrefPtr proxyUser,
|
||||
PrefPtr proxyPasswd, const Option* option)
|
||||
{
|
||||
uri::UriStruct us;
|
||||
if (!uri::parse(us, option->get(proxyPref))) {
|
||||
|
@ -645,15 +632,13 @@ std::string makeProxyUri(PrefPtr proxyPref,
|
|||
|
||||
namespace {
|
||||
// Returns proxy option value for the given protocol.
|
||||
std::string getProxyOptionFor(PrefPtr proxyPref,
|
||||
PrefPtr proxyUser,
|
||||
PrefPtr proxyPasswd,
|
||||
const Option* option)
|
||||
std::string getProxyOptionFor(PrefPtr proxyPref, PrefPtr proxyUser,
|
||||
PrefPtr proxyPasswd, const Option* option)
|
||||
{
|
||||
std::string uri = makeProxyUri(proxyPref, proxyUser, proxyPasswd, option);
|
||||
if (uri.empty()) {
|
||||
return makeProxyUri
|
||||
(PREF_ALL_PROXY, PREF_ALL_PROXY_USER, PREF_ALL_PROXY_PASSWD, option);
|
||||
return makeProxyUri(PREF_ALL_PROXY, PREF_ALL_PROXY_USER,
|
||||
PREF_ALL_PROXY_PASSWD, option);
|
||||
}
|
||||
|
||||
return uri;
|
||||
|
@ -665,20 +650,18 @@ std::string getProxyOptionFor(PrefPtr proxyPref,
|
|||
std::string getProxyUri(const std::string& protocol, const Option* option)
|
||||
{
|
||||
if (protocol == "http") {
|
||||
return getProxyOptionFor
|
||||
(PREF_HTTP_PROXY, PREF_HTTP_PROXY_USER, PREF_HTTP_PROXY_PASSWD, option);
|
||||
return getProxyOptionFor(PREF_HTTP_PROXY, PREF_HTTP_PROXY_USER,
|
||||
PREF_HTTP_PROXY_PASSWD, option);
|
||||
}
|
||||
|
||||
if (protocol == "https") {
|
||||
return getProxyOptionFor(PREF_HTTPS_PROXY,
|
||||
PREF_HTTPS_PROXY_USER,
|
||||
PREF_HTTPS_PROXY_PASSWD,
|
||||
option);
|
||||
return getProxyOptionFor(PREF_HTTPS_PROXY, PREF_HTTPS_PROXY_USER,
|
||||
PREF_HTTPS_PROXY_PASSWD, option);
|
||||
}
|
||||
|
||||
if (protocol == "ftp" || protocol == "sftp") {
|
||||
return getProxyOptionFor
|
||||
(PREF_FTP_PROXY, PREF_FTP_PROXY_USER, PREF_FTP_PROXY_PASSWD, option);
|
||||
return getProxyOptionFor(PREF_FTP_PROXY, PREF_FTP_PROXY_USER,
|
||||
PREF_FTP_PROXY_PASSWD, option);
|
||||
}
|
||||
|
||||
return A2STR::NIL;
|
||||
|
@ -752,8 +735,8 @@ std::shared_ptr<Request> AbstractCommand::createProxyRequest() const
|
|||
A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - Using proxy", getCuid()));
|
||||
}
|
||||
else {
|
||||
A2_LOG_DEBUG
|
||||
(fmt("CUID#%" PRId64 " - Failed to parse proxy string", getCuid()));
|
||||
A2_LOG_DEBUG(
|
||||
fmt("CUID#%" PRId64 " - Failed to parse proxy string", getCuid()));
|
||||
proxyRequest.reset();
|
||||
}
|
||||
}
|
||||
|
@ -790,8 +773,7 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
|
|||
->getOrCreateServerStat(req_->getHost(), req_->getProtocol())
|
||||
->setError();
|
||||
}
|
||||
throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED,
|
||||
getCuid(),
|
||||
throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(),
|
||||
hostname.c_str(),
|
||||
asyncNameResolverMan_->getLastError().c_str()),
|
||||
error_code::NAME_RESOLVE_ERROR);
|
||||
|
@ -801,10 +783,8 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
|
|||
case 1:
|
||||
asyncNameResolverMan_->getResolvedAddress(addrs);
|
||||
if (addrs.empty()) {
|
||||
throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED,
|
||||
getCuid(),
|
||||
hostname.c_str(),
|
||||
"No address returned"),
|
||||
throw DL_ABORT_EX2(fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(),
|
||||
hostname.c_str(), "No address returned"),
|
||||
error_code::NAME_RESOLVE_ERROR);
|
||||
}
|
||||
break;
|
||||
|
@ -829,21 +809,20 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
|
|||
return ipaddr;
|
||||
}
|
||||
|
||||
void AbstractCommand::prepareForNextAction
|
||||
(std::unique_ptr<CheckIntegrityEntry> checkEntry)
|
||||
void AbstractCommand::prepareForNextAction(
|
||||
std::unique_ptr<CheckIntegrityEntry> checkEntry)
|
||||
{
|
||||
std::vector<std::unique_ptr<Command>> commands;
|
||||
requestGroup_->processCheckIntegrityEntry
|
||||
(commands, std::move(checkEntry), e_);
|
||||
requestGroup_->processCheckIntegrityEntry(commands, std::move(checkEntry),
|
||||
e_);
|
||||
e_->addCommand(std::move(commands));
|
||||
e_->setNoWait(true);
|
||||
}
|
||||
|
||||
bool AbstractCommand::checkIfConnectionEstablished
|
||||
(const std::shared_ptr<SocketCore>& socket,
|
||||
const std::string& connectedHostname,
|
||||
const std::string& connectedAddr,
|
||||
uint16_t connectedPort)
|
||||
bool AbstractCommand::checkIfConnectionEstablished(
|
||||
const std::shared_ptr<SocketCore>& socket,
|
||||
const std::string& connectedHostname, const std::string& connectedAddr,
|
||||
uint16_t connectedPort)
|
||||
{
|
||||
std::string error = socket->getSocketError();
|
||||
if (error.empty()) {
|
||||
|
@ -864,14 +843,12 @@ bool AbstractCommand::checkIfConnectionEstablished
|
|||
throw DL_RETRY_EX(fmt(MSG_ESTABLISHING_CONNECTION_FAILED, error.c_str()));
|
||||
}
|
||||
|
||||
A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY,
|
||||
getCuid(),
|
||||
connectedAddr.c_str(),
|
||||
connectedPort));
|
||||
A2_LOG_INFO(fmt(MSG_CONNECT_FAILED_AND_RETRY, getCuid(),
|
||||
connectedAddr.c_str(), connectedPort));
|
||||
e_->setNoWait(true);
|
||||
e_->addCommand
|
||||
(InitiateConnectionCommandFactory::createInitiateConnectionCommand
|
||||
(getCuid(), req_, fileEntry_, requestGroup_, e_));
|
||||
e_->addCommand(
|
||||
InitiateConnectionCommandFactory::createInitiateConnectionCommand(
|
||||
getCuid(), req_, fileEntry_, requestGroup_, e_));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -909,10 +886,7 @@ void AbstractCommand::setRequest(const std::shared_ptr<Request>& request)
|
|||
req_ = request;
|
||||
}
|
||||
|
||||
void AbstractCommand::resetRequest()
|
||||
{
|
||||
req_.reset();
|
||||
}
|
||||
void AbstractCommand::resetRequest() { req_.reset(); }
|
||||
|
||||
void AbstractCommand::setFileEntry(const std::shared_ptr<FileEntry>& fileEntry)
|
||||
{
|
||||
|
|
|
@ -62,8 +62,7 @@ class AsyncNameResolver;
|
|||
class AsyncNameResolverMan;
|
||||
#endif // ENABLE_ASYNC_DNS
|
||||
|
||||
class AbstractCommand : public Command
|
||||
{
|
||||
class AbstractCommand : public Command {
|
||||
private:
|
||||
std::shared_ptr<Request> req_;
|
||||
std::shared_ptr<FileEntry> fileEntry_;
|
||||
|
@ -97,15 +96,9 @@ private:
|
|||
bool shouldProcess() const;
|
||||
|
||||
public:
|
||||
RequestGroup* getRequestGroup() const
|
||||
{
|
||||
return requestGroup_;
|
||||
}
|
||||
RequestGroup* getRequestGroup() const { return requestGroup_; }
|
||||
|
||||
const std::shared_ptr<Request>& getRequest() const
|
||||
{
|
||||
return req_;
|
||||
}
|
||||
const std::shared_ptr<Request>& getRequest() const { return req_; }
|
||||
|
||||
void setRequest(const std::shared_ptr<Request>& request);
|
||||
|
||||
|
@ -113,27 +106,15 @@ public:
|
|||
// setRequest(std::shared_ptr<Request>());
|
||||
void resetRequest();
|
||||
|
||||
const std::shared_ptr<FileEntry>& getFileEntry() const
|
||||
{
|
||||
return fileEntry_;
|
||||
}
|
||||
const std::shared_ptr<FileEntry>& getFileEntry() const { return fileEntry_; }
|
||||
|
||||
void setFileEntry(const std::shared_ptr<FileEntry>& fileEntry);
|
||||
|
||||
DownloadEngine* getDownloadEngine() const
|
||||
{
|
||||
return e_;
|
||||
}
|
||||
DownloadEngine* getDownloadEngine() const { return e_; }
|
||||
|
||||
const std::shared_ptr<SocketCore>& getSocket() const
|
||||
{
|
||||
return socket_;
|
||||
}
|
||||
const std::shared_ptr<SocketCore>& getSocket() const { return socket_; }
|
||||
|
||||
std::shared_ptr<SocketCore>& getSocket()
|
||||
{
|
||||
return socket_;
|
||||
}
|
||||
std::shared_ptr<SocketCore>& getSocket() { return socket_; }
|
||||
|
||||
void setSocket(const std::shared_ptr<SocketCore>& s);
|
||||
|
||||
|
@ -155,8 +136,7 @@ public:
|
|||
// arguments until resolved address is returned. Exception is
|
||||
// thrown on error. port is used for retrieving cached addresses.
|
||||
std::string resolveHostname(std::vector<std::string>& addrs,
|
||||
const std::string& hostname,
|
||||
uint16_t port);
|
||||
const std::string& hostname, uint16_t port);
|
||||
|
||||
void tryReserved();
|
||||
|
||||
|
@ -185,10 +165,7 @@ public:
|
|||
// check.
|
||||
void swapSocket(std::shared_ptr<SocketCore>& socket);
|
||||
|
||||
std::chrono::seconds getTimeout() const
|
||||
{
|
||||
return timeout_;
|
||||
}
|
||||
std::chrono::seconds getTimeout() const { return timeout_; }
|
||||
|
||||
void setTimeout(std::chrono::seconds timeout)
|
||||
{
|
||||
|
@ -229,10 +206,7 @@ public:
|
|||
const std::shared_ptr<SegmentMan>& getSegmentMan() const;
|
||||
const std::shared_ptr<PieceStorage>& getPieceStorage() const;
|
||||
|
||||
Timer& getCheckPoint()
|
||||
{
|
||||
return checkPoint_;
|
||||
}
|
||||
Timer& getCheckPoint() { return checkPoint_; }
|
||||
|
||||
void checkSocketRecvBuffer();
|
||||
|
||||
|
@ -247,21 +221,15 @@ protected:
|
|||
|
||||
// Returns true if the derived class wants to execute
|
||||
// executeInternal() unconditionally
|
||||
virtual bool noCheck() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool noCheck() const { return false; }
|
||||
|
||||
public:
|
||||
AbstractCommand(cuid_t cuid,
|
||||
const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry,
|
||||
RequestGroup* requestGroup,
|
||||
DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& s = nullptr,
|
||||
const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer =
|
||||
nullptr,
|
||||
bool incNumConnection = true);
|
||||
AbstractCommand(
|
||||
cuid_t cuid, const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
|
||||
DownloadEngine* e, const std::shared_ptr<SocketCore>& s = nullptr,
|
||||
const std::shared_ptr<SocketRecvBuffer>& socketRecvBuffer = nullptr,
|
||||
bool incNumConnection = true);
|
||||
|
||||
virtual ~AbstractCommand();
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_MMAP
|
||||
# include <sys/mman.h>
|
||||
#include <sys/mman.h>
|
||||
#endif // HAVE_MMAP
|
||||
#include <fcntl.h>
|
||||
|
||||
|
@ -57,24 +57,22 @@
|
|||
namespace aria2 {
|
||||
|
||||
AbstractDiskWriter::AbstractDiskWriter(const std::string& filename)
|
||||
: filename_(filename),
|
||||
fd_(A2_BAD_FD),
|
||||
: filename_(filename),
|
||||
fd_(A2_BAD_FD),
|
||||
#ifdef __MINGW32__
|
||||
mapView_(0),
|
||||
#else // !__MINGW32__
|
||||
mapView_(0),
|
||||
#else // !__MINGW32__
|
||||
#endif // !__MINGW32__
|
||||
readOnly_(false),
|
||||
enableMmap_(false),
|
||||
mapaddr_(nullptr),
|
||||
maplen_(0)
|
||||
readOnly_(false),
|
||||
enableMmap_(false),
|
||||
mapaddr_(nullptr),
|
||||
maplen_(0)
|
||||
|
||||
{}
|
||||
|
||||
AbstractDiskWriter::~AbstractDiskWriter()
|
||||
{
|
||||
closeFile();
|
||||
}
|
||||
|
||||
AbstractDiskWriter::~AbstractDiskWriter() { closeFile(); }
|
||||
|
||||
namespace {
|
||||
// Returns error code depending on the platform. For MinGW32, return
|
||||
// the value of GetLastError(). Otherwise, return errno.
|
||||
|
@ -82,7 +80,7 @@ int fileError()
|
|||
{
|
||||
#ifdef __MINGW32__
|
||||
return GetLastError();
|
||||
#else // !__MINGW32__
|
||||
#else // !__MINGW32__
|
||||
return errno;
|
||||
#endif // !__MINGW32__
|
||||
}
|
||||
|
@ -96,18 +94,15 @@ std::string fileStrerror(int errNum)
|
|||
{
|
||||
#ifdef __MINGW32__
|
||||
static char buf[256];
|
||||
if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0,
|
||||
errNum,
|
||||
// Default language
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
||||
(LPTSTR) &buf,
|
||||
sizeof(buf),
|
||||
0) == 0) {
|
||||
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, errNum,
|
||||
// Default language
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPTSTR)&buf,
|
||||
sizeof(buf), 0) == 0) {
|
||||
snprintf(buf, sizeof(buf), "File I/O error %x", errNum);
|
||||
}
|
||||
return buf;
|
||||
#else // !__MINGW32__
|
||||
#else // !__MINGW32__
|
||||
return util::safeStrerror(errNum);
|
||||
#endif // !__MINGW32__
|
||||
}
|
||||
|
@ -117,17 +112,19 @@ void AbstractDiskWriter::openFile(int64_t totalLength)
|
|||
{
|
||||
try {
|
||||
openExistingFile(totalLength);
|
||||
} catch(RecoverableException& e) {
|
||||
if(
|
||||
}
|
||||
catch (RecoverableException& e) {
|
||||
if (
|
||||
#ifdef __MINGW32__
|
||||
e.getErrNum() == ERROR_FILE_NOT_FOUND ||
|
||||
e.getErrNum() == ERROR_PATH_NOT_FOUND
|
||||
#else // !__MINGW32__
|
||||
e.getErrNum() == ENOENT
|
||||
e.getErrNum() == ERROR_FILE_NOT_FOUND ||
|
||||
e.getErrNum() == ERROR_PATH_NOT_FOUND
|
||||
#else // !__MINGW32__
|
||||
e.getErrNum() == ENOENT
|
||||
#endif // !__MINGW32__
|
||||
) {
|
||||
) {
|
||||
initAndOpenFile(totalLength);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -136,34 +133,35 @@ void AbstractDiskWriter::openFile(int64_t totalLength)
|
|||
void AbstractDiskWriter::closeFile()
|
||||
{
|
||||
#if defined(HAVE_MMAP) || defined(__MINGW32__)
|
||||
if(mapaddr_) {
|
||||
if (mapaddr_) {
|
||||
int errNum = 0;
|
||||
#ifdef __MINGW32__
|
||||
if(!UnmapViewOfFile(mapaddr_)) {
|
||||
if (!UnmapViewOfFile(mapaddr_)) {
|
||||
errNum = GetLastError();
|
||||
}
|
||||
CloseHandle(mapView_);
|
||||
mapView_ = INVALID_HANDLE_VALUE;
|
||||
#else // !__MINGW32__
|
||||
if(munmap(mapaddr_, maplen_) == -1) {
|
||||
#else // !__MINGW32__
|
||||
if (munmap(mapaddr_, maplen_) == -1) {
|
||||
errNum = errno;
|
||||
}
|
||||
#endif // !__MINGW32__
|
||||
if(errNum != 0) {
|
||||
if (errNum != 0) {
|
||||
int errNum = fileError();
|
||||
A2_LOG_ERROR(fmt("Unmapping file %s failed: %s",
|
||||
filename_.c_str(), fileStrerror(errNum).c_str()));
|
||||
} else {
|
||||
A2_LOG_ERROR(fmt("Unmapping file %s failed: %s", filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()));
|
||||
}
|
||||
else {
|
||||
A2_LOG_INFO(fmt("Unmapping file %s succeeded", filename_.c_str()));
|
||||
}
|
||||
mapaddr_ = nullptr;
|
||||
maplen_ = 0;
|
||||
}
|
||||
#endif // HAVE_MMAP || defined __MINGW32__
|
||||
if(fd_ != A2_BAD_FD) {
|
||||
if (fd_ != A2_BAD_FD) {
|
||||
#ifdef __MINGW32__
|
||||
CloseHandle(fd_);
|
||||
#else // !__MINGW32__
|
||||
#else // !__MINGW32__
|
||||
close(fd_);
|
||||
#endif // !__MINGW32__
|
||||
fd_ = A2_BAD_FD;
|
||||
|
@ -180,29 +178,32 @@ HANDLE openFileWithFlags(const std::string& filename, int flags,
|
|||
DWORD sharedMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
DWORD creationDisp = 0;
|
||||
|
||||
if(flags & O_RDWR) {
|
||||
if (flags & O_RDWR) {
|
||||
desiredAccess = GENERIC_READ | GENERIC_WRITE;
|
||||
} else if(flags & O_WRONLY) {
|
||||
}
|
||||
else if (flags & O_WRONLY) {
|
||||
desiredAccess = GENERIC_WRITE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
desiredAccess = GENERIC_READ;
|
||||
}
|
||||
if(flags & O_CREAT) {
|
||||
if(flags & O_TRUNC) {
|
||||
if (flags & O_CREAT) {
|
||||
if (flags & O_TRUNC) {
|
||||
creationDisp |= CREATE_ALWAYS;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
creationDisp |= CREATE_NEW;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
creationDisp |= OPEN_EXISTING;
|
||||
}
|
||||
hn = CreateFileW(utf8ToWChar(filename).c_str(), desiredAccess, sharedMode,
|
||||
/* lpSecurityAttributes */ 0, creationDisp,
|
||||
FILE_ATTRIBUTE_NORMAL, /* hTemplateFile */ 0);
|
||||
if(hn == INVALID_HANDLE_VALUE) {
|
||||
if (hn == INVALID_HANDLE_VALUE) {
|
||||
int errNum = GetLastError();
|
||||
throw DL_ABORT_EX3(errNum, fmt(EX_FILE_OPEN,
|
||||
filename.c_str(),
|
||||
throw DL_ABORT_EX3(errNum, fmt(EX_FILE_OPEN, filename.c_str(),
|
||||
fileStrerror(errNum).c_str()),
|
||||
errCode);
|
||||
}
|
||||
|
@ -213,9 +214,10 @@ int openFileWithFlags(const std::string& filename, int flags,
|
|||
error_code::Value errCode)
|
||||
{
|
||||
int fd;
|
||||
while((fd = a2open(utf8ToWChar(filename).c_str(), flags, OPEN_MODE)) == -1
|
||||
&& errno == EINTR);
|
||||
if(fd < 0) {
|
||||
while ((fd = a2open(utf8ToWChar(filename).c_str(), flags, OPEN_MODE)) == -1 &&
|
||||
errno == EINTR)
|
||||
;
|
||||
if (fd < 0) {
|
||||
int errNum = errno;
|
||||
throw DL_ABORT_EX3(errNum, fmt(EX_FILE_OPEN, filename.c_str(),
|
||||
util::safeStrerror(errNum).c_str()),
|
||||
|
@ -233,9 +235,10 @@ int openFileWithFlags(const std::string& filename, int flags,
|
|||
void AbstractDiskWriter::openExistingFile(int64_t totalLength)
|
||||
{
|
||||
int flags = O_BINARY;
|
||||
if(readOnly_) {
|
||||
if (readOnly_) {
|
||||
flags |= O_RDONLY;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
flags |= O_RDWR;
|
||||
}
|
||||
fd_ = openFileWithFlags(filename_, flags, error_code::FILE_OPEN_ERROR);
|
||||
|
@ -245,32 +248,38 @@ void AbstractDiskWriter::createFile(int addFlags)
|
|||
{
|
||||
assert(!filename_.empty());
|
||||
util::mkdirs(File(filename_).getDirname());
|
||||
fd_ = openFileWithFlags(filename_, O_CREAT|O_RDWR|O_TRUNC|O_BINARY|addFlags,
|
||||
fd_ = openFileWithFlags(filename_,
|
||||
O_CREAT | O_RDWR | O_TRUNC | O_BINARY | addFlags,
|
||||
error_code::FILE_CREATE_ERROR);
|
||||
}
|
||||
|
||||
ssize_t AbstractDiskWriter::writeDataInternal(const unsigned char* data,
|
||||
size_t len, int64_t offset)
|
||||
{
|
||||
if(mapaddr_) {
|
||||
if (mapaddr_) {
|
||||
memcpy(mapaddr_ + offset, data, len);
|
||||
return len;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ssize_t writtenLength = 0;
|
||||
seek(offset);
|
||||
while((size_t)writtenLength < len) {
|
||||
while ((size_t)writtenLength < len) {
|
||||
#ifdef __MINGW32__
|
||||
DWORD nwrite;
|
||||
if(WriteFile(fd_, data+writtenLength, len-writtenLength, &nwrite, 0)) {
|
||||
if (WriteFile(fd_, data + writtenLength, len - writtenLength, &nwrite,
|
||||
0)) {
|
||||
writtenLength += nwrite;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
#else // !__MINGW32__
|
||||
#else // !__MINGW32__
|
||||
ssize_t ret = 0;
|
||||
while((ret = write(fd_, data+writtenLength, len-writtenLength)) == -1 &&
|
||||
errno == EINTR);
|
||||
if(ret == -1) {
|
||||
while ((ret = write(fd_, data + writtenLength, len - writtenLength)) ==
|
||||
-1 &&
|
||||
errno == EINTR)
|
||||
;
|
||||
if (ret == -1) {
|
||||
return -1;
|
||||
}
|
||||
writtenLength += ret;
|
||||
|
@ -283,25 +292,28 @@ ssize_t AbstractDiskWriter::writeDataInternal(const unsigned char* data,
|
|||
ssize_t AbstractDiskWriter::readDataInternal(unsigned char* data, size_t len,
|
||||
int64_t offset)
|
||||
{
|
||||
if(mapaddr_) {
|
||||
if (mapaddr_) {
|
||||
if (offset >= maplen_) {
|
||||
return 0;
|
||||
}
|
||||
auto readlen = std::min(maplen_ - offset, static_cast<int64_t>(len));
|
||||
memcpy(data, mapaddr_ + offset, readlen);
|
||||
return readlen;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
seek(offset);
|
||||
#ifdef __MINGW32__
|
||||
DWORD nread;
|
||||
if(ReadFile(fd_, data, len, &nread, 0)) {
|
||||
if (ReadFile(fd_, data, len, &nread, 0)) {
|
||||
return nread;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
#else // !__MINGW32__
|
||||
#else // !__MINGW32__
|
||||
ssize_t ret = 0;
|
||||
while((ret = read(fd_, data, len)) == -1 && errno == EINTR);
|
||||
while ((ret = read(fd_, data, len)) == -1 && errno == EINTR)
|
||||
;
|
||||
return ret;
|
||||
#endif // !__MINGW32__
|
||||
}
|
||||
|
@ -313,45 +325,46 @@ void AbstractDiskWriter::seek(int64_t offset)
|
|||
#ifdef __MINGW32__
|
||||
LARGE_INTEGER fileLength;
|
||||
fileLength.QuadPart = offset;
|
||||
if(SetFilePointerEx(fd_, fileLength, 0, FILE_BEGIN) == 0)
|
||||
#else // !__MINGW32__
|
||||
if(a2lseek(fd_, offset, SEEK_SET) == (a2_off_t)-1)
|
||||
if (SetFilePointerEx(fd_, fileLength, 0, FILE_BEGIN) == 0)
|
||||
#else // !__MINGW32__
|
||||
if (a2lseek(fd_, offset, SEEK_SET) == (a2_off_t)-1)
|
||||
#endif // !__MINGW32__
|
||||
{
|
||||
int errNum = fileError();
|
||||
throw DL_ABORT_EX2(fmt(EX_FILE_SEEK, filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
{
|
||||
int errNum = fileError();
|
||||
throw DL_ABORT_EX2(
|
||||
fmt(EX_FILE_SEEK, filename_.c_str(), fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
|
||||
{
|
||||
#if defined(HAVE_MMAP) || defined(__MINGW32__)
|
||||
if(enableMmap_) {
|
||||
if(mapaddr_) {
|
||||
if(static_cast<int64_t>(len + offset) > maplen_) {
|
||||
if (enableMmap_) {
|
||||
if (mapaddr_) {
|
||||
if (static_cast<int64_t>(len + offset) > maplen_) {
|
||||
int errNum = 0;
|
||||
#ifdef __MINGW32__
|
||||
if(!UnmapViewOfFile(mapaddr_)) {
|
||||
if (!UnmapViewOfFile(mapaddr_)) {
|
||||
errNum = GetLastError();
|
||||
}
|
||||
CloseHandle(mapView_);
|
||||
mapView_ = INVALID_HANDLE_VALUE;
|
||||
#else // !__MINGW32__
|
||||
if(munmap(mapaddr_, maplen_) == -1) {
|
||||
#else // !__MINGW32__
|
||||
if (munmap(mapaddr_, maplen_) == -1) {
|
||||
errNum = errno;
|
||||
}
|
||||
#endif // !__MINGW32__
|
||||
if(errNum != 0) {
|
||||
A2_LOG_ERROR(fmt("Unmapping file %s failed: %s",
|
||||
filename_.c_str(), fileStrerror(errNum).c_str()));
|
||||
if (errNum != 0) {
|
||||
A2_LOG_ERROR(fmt("Unmapping file %s failed: %s", filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()));
|
||||
}
|
||||
mapaddr_ = nullptr;
|
||||
maplen_ = 0;
|
||||
enableMmap_ = false;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
int64_t filesize = size();
|
||||
|
||||
if (filesize == 0) {
|
||||
|
@ -362,37 +375,37 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
|
|||
}
|
||||
|
||||
int errNum = 0;
|
||||
if(static_cast<int64_t>(len + offset) <= filesize) {
|
||||
if (static_cast<int64_t>(len + offset) <= filesize) {
|
||||
#ifdef __MINGW32__
|
||||
mapView_ = CreateFileMapping(fd_, 0, PAGE_READWRITE,
|
||||
filesize >> 32, filesize & 0xffffffffu,
|
||||
0);
|
||||
if(mapView_) {
|
||||
mapaddr_ = reinterpret_cast<unsigned char*>
|
||||
(MapViewOfFile(mapView_, FILE_MAP_WRITE, 0, 0, 0));
|
||||
if(!mapaddr_) {
|
||||
mapView_ = CreateFileMapping(fd_, 0, PAGE_READWRITE, filesize >> 32,
|
||||
filesize & 0xffffffffu, 0);
|
||||
if (mapView_) {
|
||||
mapaddr_ = reinterpret_cast<unsigned char*>(
|
||||
MapViewOfFile(mapView_, FILE_MAP_WRITE, 0, 0, 0));
|
||||
if (!mapaddr_) {
|
||||
errNum = GetLastError();
|
||||
CloseHandle(mapView_);
|
||||
mapView_ = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
errNum = GetLastError();
|
||||
}
|
||||
#else // !__MINGW32__
|
||||
mapaddr_ = reinterpret_cast<unsigned char*>
|
||||
(mmap(nullptr, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
|
||||
if(!mapaddr_) {
|
||||
#else // !__MINGW32__
|
||||
mapaddr_ = reinterpret_cast<unsigned char*>(mmap(
|
||||
nullptr, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
|
||||
if (!mapaddr_) {
|
||||
errNum = errno;
|
||||
}
|
||||
#endif // !__MINGW32__
|
||||
if(mapaddr_) {
|
||||
if (mapaddr_) {
|
||||
A2_LOG_DEBUG(fmt("Mapping file %s succeeded, length=%" PRId64 "",
|
||||
filename_.c_str(),
|
||||
static_cast<uint64_t>(filesize)));
|
||||
filename_.c_str(), static_cast<uint64_t>(filesize)));
|
||||
maplen_ = filesize;
|
||||
} else {
|
||||
A2_LOG_WARN(fmt("Mapping file %s failed: %s",
|
||||
filename_.c_str(), fileStrerror(errNum).c_str()));
|
||||
}
|
||||
else {
|
||||
A2_LOG_WARN(fmt("Mapping file %s failed: %s", filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()));
|
||||
enableMmap_ = false;
|
||||
}
|
||||
}
|
||||
|
@ -401,158 +414,142 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
|
|||
#endif // HAVE_MMAP || __MINGW32__
|
||||
}
|
||||
|
||||
void AbstractDiskWriter::writeData(const unsigned char* data, size_t len, int64_t offset)
|
||||
void AbstractDiskWriter::writeData(const unsigned char* data, size_t len,
|
||||
int64_t offset)
|
||||
{
|
||||
ensureMmapWrite(len, offset);
|
||||
if(writeDataInternal(data, len, offset) < 0) {
|
||||
if (writeDataInternal(data, len, offset) < 0) {
|
||||
int errNum = fileError();
|
||||
if(
|
||||
// If the error indicates disk full situation, throw
|
||||
// DownloadFailureException and abort download instantly.
|
||||
if (
|
||||
// If the error indicates disk full situation, throw
|
||||
// DownloadFailureException and abort download instantly.
|
||||
#ifdef __MINGW32__
|
||||
errNum == ERROR_DISK_FULL || errNum == ERROR_HANDLE_DISK_FULL
|
||||
#else // !__MINGW32__
|
||||
errNum == ENOSPC
|
||||
errNum == ERROR_DISK_FULL || errNum == ERROR_HANDLE_DISK_FULL
|
||||
#else // !__MINGW32__
|
||||
errNum == ENOSPC
|
||||
#endif // !__MINGW32__
|
||||
) {
|
||||
throw DOWNLOAD_FAILURE_EXCEPTION3
|
||||
(errNum, fmt(EX_FILE_WRITE, filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()),
|
||||
error_code::NOT_ENOUGH_DISK_SPACE);
|
||||
} else {
|
||||
throw DL_ABORT_EX3
|
||||
(errNum, fmt(EX_FILE_WRITE, filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
) {
|
||||
throw DOWNLOAD_FAILURE_EXCEPTION3(
|
||||
errNum,
|
||||
fmt(EX_FILE_WRITE, filename_.c_str(), fileStrerror(errNum).c_str()),
|
||||
error_code::NOT_ENOUGH_DISK_SPACE);
|
||||
}
|
||||
else {
|
||||
throw DL_ABORT_EX3(errNum, fmt(EX_FILE_WRITE, filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t AbstractDiskWriter::readData(unsigned char* data, size_t len, int64_t offset)
|
||||
ssize_t AbstractDiskWriter::readData(unsigned char* data, size_t len,
|
||||
int64_t offset)
|
||||
{
|
||||
ssize_t ret;
|
||||
if((ret = readDataInternal(data, len, offset)) < 0) {
|
||||
if ((ret = readDataInternal(data, len, offset)) < 0) {
|
||||
int errNum = fileError();
|
||||
throw DL_ABORT_EX3
|
||||
(errNum, fmt(EX_FILE_READ, filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
throw DL_ABORT_EX3(errNum, fmt(EX_FILE_READ, filename_.c_str(),
|
||||
fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AbstractDiskWriter::truncate(int64_t length)
|
||||
{
|
||||
if(fd_ == A2_BAD_FD) {
|
||||
if (fd_ == A2_BAD_FD) {
|
||||
throw DL_ABORT_EX("File not yet opened.");
|
||||
}
|
||||
#ifdef __MINGW32__
|
||||
// Since mingw32's ftruncate cannot handle over 2GB files, we use
|
||||
// SetEndOfFile instead.
|
||||
seek(length);
|
||||
if(SetEndOfFile(fd_) == 0)
|
||||
#else // !__MINGW32__
|
||||
if(a2ftruncate(fd_, length) == -1)
|
||||
if (SetEndOfFile(fd_) == 0)
|
||||
#else // !__MINGW32__
|
||||
if (a2ftruncate(fd_, length) == -1)
|
||||
#endif // !__MINGW32__
|
||||
{
|
||||
int errNum = fileError();
|
||||
throw DL_ABORT_EX2(fmt("File truncation failed. cause: %s",
|
||||
fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
{
|
||||
int errNum = fileError();
|
||||
throw DL_ABORT_EX2(
|
||||
fmt("File truncation failed. cause: %s", fileStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractDiskWriter::allocate(int64_t offset, int64_t length, bool sparse)
|
||||
{
|
||||
if(fd_ == A2_BAD_FD) {
|
||||
if (fd_ == A2_BAD_FD) {
|
||||
throw DL_ABORT_EX("File not yet opened.");
|
||||
}
|
||||
if(sparse) {
|
||||
if (sparse) {
|
||||
#ifdef __MINGW32__
|
||||
DWORD bytesReturned;
|
||||
if(!DeviceIoControl(fd_, FSCTL_SET_SPARSE, 0, 0, 0, 0,
|
||||
&bytesReturned, 0)) {
|
||||
if (!DeviceIoControl(fd_, FSCTL_SET_SPARSE, 0, 0, 0, 0, &bytesReturned,
|
||||
0)) {
|
||||
A2_LOG_WARN(fmt("Making file sparse failed or pending: %s",
|
||||
fileStrerror(GetLastError()).c_str()));
|
||||
}
|
||||
#endif // __MINGW32__
|
||||
truncate(offset+length);
|
||||
truncate(offset + length);
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_SOME_FALLOCATE
|
||||
# ifdef __MINGW32__
|
||||
truncate(offset+length);
|
||||
# elif defined(__APPLE__) && defined(__MACH__)
|
||||
#ifdef HAVE_SOME_FALLOCATE
|
||||
#ifdef __MINGW32__
|
||||
truncate(offset + length);
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
auto toalloc = offset + length - size();
|
||||
while (toalloc > 0) {
|
||||
fstore_t fstore = {
|
||||
F_ALLOCATECONTIG | F_ALLOCATEALL,
|
||||
F_PEOFPOSMODE,
|
||||
0,
|
||||
// Allocate in 1GB chunks or else some OSX versions may choke.
|
||||
std::min(toalloc, (int64_t)1<<30),
|
||||
0
|
||||
};
|
||||
F_ALLOCATECONTIG | F_ALLOCATEALL, F_PEOFPOSMODE, 0,
|
||||
// Allocate in 1GB chunks or else some OSX versions may choke.
|
||||
std::min(toalloc, (int64_t)1 << 30), 0};
|
||||
if (fcntl(fd_, F_PREALLOCATE, &fstore) == -1) {
|
||||
// Retry non-contig.
|
||||
fstore.fst_flags = F_ALLOCATEALL;
|
||||
if (fcntl(fd_, F_PREALLOCATE, &fstore) == -1) {
|
||||
int err = errno;
|
||||
throw DL_ABORT_EX3(err,
|
||||
fmt("fcntl(F_PREALLOCATE) of %" PRId64 " failed. cause: %s",
|
||||
fstore.fst_length, util::safeStrerror(err).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
throw DL_ABORT_EX3(
|
||||
err, fmt("fcntl(F_PREALLOCATE) of %" PRId64 " failed. cause: %s",
|
||||
fstore.fst_length, util::safeStrerror(err).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
}
|
||||
toalloc -= fstore.fst_bytesalloc;
|
||||
}
|
||||
// This forces the allocation on disk.
|
||||
ftruncate(fd_, offset + length);
|
||||
# elif HAVE_FALLOCATE
|
||||
#elif HAVE_FALLOCATE
|
||||
// For linux, we use fallocate to detect file system supports
|
||||
// fallocate or not.
|
||||
int r;
|
||||
while((r = fallocate(fd_, 0, offset, length)) == -1 && errno == EINTR);
|
||||
while ((r = fallocate(fd_, 0, offset, length)) == -1 && errno == EINTR)
|
||||
;
|
||||
int errNum = errno;
|
||||
if(r == -1) {
|
||||
throw DL_ABORT_EX3(errNum,
|
||||
fmt("fallocate failed. cause: %s",
|
||||
util::safeStrerror(errNum).c_str()),
|
||||
if (r == -1) {
|
||||
throw DL_ABORT_EX3(errNum, fmt("fallocate failed. cause: %s",
|
||||
util::safeStrerror(errNum).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
# elif HAVE_POSIX_FALLOCATE
|
||||
#elif HAVE_POSIX_FALLOCATE
|
||||
int r = posix_fallocate(fd_, offset, length);
|
||||
if(r != 0) {
|
||||
throw DL_ABORT_EX3(r,
|
||||
fmt("posix_fallocate failed. cause: %s",
|
||||
util::safeStrerror(r).c_str()),
|
||||
if (r != 0) {
|
||||
throw DL_ABORT_EX3(r, fmt("posix_fallocate failed. cause: %s",
|
||||
util::safeStrerror(r).c_str()),
|
||||
error_code::FILE_IO_ERROR);
|
||||
}
|
||||
# else
|
||||
# error "no *_fallocate function available."
|
||||
# endif
|
||||
#else
|
||||
#error "no *_fallocate function available."
|
||||
#endif
|
||||
#endif // HAVE_SOME_FALLOCATE
|
||||
}
|
||||
|
||||
int64_t AbstractDiskWriter::size()
|
||||
{
|
||||
return File(filename_).size();
|
||||
}
|
||||
int64_t AbstractDiskWriter::size() { return File(filename_).size(); }
|
||||
|
||||
void AbstractDiskWriter::enableReadOnly()
|
||||
{
|
||||
readOnly_ = true;
|
||||
}
|
||||
void AbstractDiskWriter::enableReadOnly() { readOnly_ = true; }
|
||||
|
||||
void AbstractDiskWriter::disableReadOnly()
|
||||
{
|
||||
readOnly_ = false;
|
||||
}
|
||||
void AbstractDiskWriter::disableReadOnly() { readOnly_ = false; }
|
||||
|
||||
void AbstractDiskWriter::enableMmap()
|
||||
{
|
||||
enableMmap_ = true;
|
||||
}
|
||||
void AbstractDiskWriter::enableMmap() { enableMmap_ = true; }
|
||||
|
||||
void AbstractDiskWriter::dropCache(int64_t len, int64_t offset)
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@ private:
|
|||
HANDLE fd_;
|
||||
// The handle for memory mapped file. mmap equivalent in Windows.
|
||||
HANDLE mapView_;
|
||||
#else // !__MINGW32__
|
||||
#else // !__MINGW32__
|
||||
int fd_;
|
||||
#endif // !__MINGW32__
|
||||
|
||||
|
@ -65,8 +65,10 @@ private:
|
|||
void seek(int64_t offset);
|
||||
|
||||
void ensureMmapWrite(size_t len, int64_t offset);
|
||||
|
||||
protected:
|
||||
void createFile(int addFlags = 0);
|
||||
|
||||
public:
|
||||
AbstractDiskWriter(const std::string& filename);
|
||||
virtual ~AbstractDiskWriter();
|
||||
|
@ -77,17 +79,17 @@ public:
|
|||
|
||||
virtual void openExistingFile(int64_t totalLength = 0) CXX11_OVERRIDE;
|
||||
|
||||
virtual void writeData(const unsigned char* data, size_t len, int64_t offset)
|
||||
CXX11_OVERRIDE;
|
||||
virtual void writeData(const unsigned char* data, size_t len,
|
||||
int64_t offset) CXX11_OVERRIDE;
|
||||
|
||||
virtual ssize_t readData(unsigned char* data, size_t len, int64_t offset)
|
||||
CXX11_OVERRIDE;
|
||||
virtual ssize_t readData(unsigned char* data, size_t len,
|
||||
int64_t offset) CXX11_OVERRIDE;
|
||||
|
||||
virtual void truncate(int64_t length) CXX11_OVERRIDE;
|
||||
|
||||
// File must be opened before calling this function.
|
||||
virtual void allocate(int64_t offset, int64_t length, bool sparse)
|
||||
CXX11_OVERRIDE;
|
||||
virtual void allocate(int64_t offset, int64_t length,
|
||||
bool sparse) CXX11_OVERRIDE;
|
||||
|
||||
virtual int64_t size() CXX11_OVERRIDE;
|
||||
|
||||
|
|
|
@ -47,17 +47,15 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
AbstractHttpServerResponseCommand::AbstractHttpServerResponseCommand
|
||||
(cuid_t cuid,
|
||||
const std::shared_ptr<HttpServer>& httpServer,
|
||||
DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& socket)
|
||||
: Command(cuid),
|
||||
e_(e),
|
||||
socket_(socket),
|
||||
httpServer_(httpServer),
|
||||
readCheck_(false),
|
||||
writeCheck_(true)
|
||||
AbstractHttpServerResponseCommand::AbstractHttpServerResponseCommand(
|
||||
cuid_t cuid, const std::shared_ptr<HttpServer>& httpServer,
|
||||
DownloadEngine* e, const std::shared_ptr<SocketCore>& socket)
|
||||
: Command(cuid),
|
||||
e_(e),
|
||||
socket_(socket),
|
||||
httpServer_(httpServer),
|
||||
readCheck_(false),
|
||||
writeCheck_(true)
|
||||
{
|
||||
setStatus(Command::STATUS_ONESHOT_REALTIME);
|
||||
e_->addSocketForWriteCheck(socket_, this);
|
||||
|
@ -65,31 +63,33 @@ AbstractHttpServerResponseCommand::AbstractHttpServerResponseCommand
|
|||
|
||||
AbstractHttpServerResponseCommand::~AbstractHttpServerResponseCommand()
|
||||
{
|
||||
if(readCheck_) {
|
||||
if (readCheck_) {
|
||||
e_->deleteSocketForReadCheck(socket_, this);
|
||||
}
|
||||
if(writeCheck_) {
|
||||
if (writeCheck_) {
|
||||
e_->deleteSocketForWriteCheck(socket_, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractHttpServerResponseCommand::updateReadWriteCheck()
|
||||
{
|
||||
if(httpServer_->wantRead()) {
|
||||
if(!readCheck_) {
|
||||
if (httpServer_->wantRead()) {
|
||||
if (!readCheck_) {
|
||||
readCheck_ = true;
|
||||
e_->addSocketForReadCheck(socket_, this);
|
||||
}
|
||||
} else if(readCheck_) {
|
||||
}
|
||||
else if (readCheck_) {
|
||||
readCheck_ = false;
|
||||
e_->deleteSocketForReadCheck(socket_, this);
|
||||
}
|
||||
if(httpServer_->wantWrite()) {
|
||||
if(!writeCheck_) {
|
||||
if (httpServer_->wantWrite()) {
|
||||
if (!writeCheck_) {
|
||||
writeCheck_ = true;
|
||||
e_->addSocketForWriteCheck(socket_, this);
|
||||
}
|
||||
} else if(writeCheck_) {
|
||||
}
|
||||
else if (writeCheck_) {
|
||||
writeCheck_ = false;
|
||||
e_->deleteSocketForWriteCheck(socket_, this);
|
||||
}
|
||||
|
@ -97,34 +97,36 @@ void AbstractHttpServerResponseCommand::updateReadWriteCheck()
|
|||
|
||||
bool AbstractHttpServerResponseCommand::execute()
|
||||
{
|
||||
if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) {
|
||||
if (e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
ssize_t len = httpServer_->sendResponse();
|
||||
if(len > 0) {
|
||||
if (len > 0) {
|
||||
timeoutTimer_ = global::wallclock();
|
||||
}
|
||||
} catch(RecoverableException& e) {
|
||||
A2_LOG_INFO_EX
|
||||
(fmt("CUID#%" PRId64
|
||||
" - Error occurred while transmitting response body.",
|
||||
getCuid()),
|
||||
e);
|
||||
}
|
||||
catch (RecoverableException& e) {
|
||||
A2_LOG_INFO_EX(fmt("CUID#%" PRId64
|
||||
" - Error occurred while transmitting response body.",
|
||||
getCuid()),
|
||||
e);
|
||||
return true;
|
||||
}
|
||||
if(httpServer_->sendBufferIsEmpty()) {
|
||||
if (httpServer_->sendBufferIsEmpty()) {
|
||||
A2_LOG_INFO(fmt("CUID#%" PRId64 " - HttpServer: all response transmitted.",
|
||||
getCuid()));
|
||||
afterSend(httpServer_, e_);
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (timeoutTimer_.difference(global::wallclock()) >= 30_s) {
|
||||
A2_LOG_INFO(fmt("CUID#%" PRId64
|
||||
" - HttpServer: Timeout while trasmitting response.",
|
||||
getCuid()));
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
updateReadWriteCheck();
|
||||
e_->addCommand(std::unique_ptr<Command>(this));
|
||||
return false;
|
||||
|
|
|
@ -57,19 +57,17 @@ private:
|
|||
bool writeCheck_;
|
||||
|
||||
void updateReadWriteCheck();
|
||||
|
||||
protected:
|
||||
DownloadEngine* getDownloadEngine()
|
||||
{
|
||||
return e_;
|
||||
}
|
||||
DownloadEngine* getDownloadEngine() { return e_; }
|
||||
// Called after content body is completely sent.
|
||||
virtual void afterSend(const std::shared_ptr<HttpServer>& httpServer,
|
||||
DownloadEngine* e) = 0;
|
||||
|
||||
public:
|
||||
AbstractHttpServerResponseCommand(cuid_t cuid,
|
||||
const std::shared_ptr<HttpServer>& httpServer,
|
||||
DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& socket);
|
||||
AbstractHttpServerResponseCommand(
|
||||
cuid_t cuid, const std::shared_ptr<HttpServer>& httpServer,
|
||||
DownloadEngine* e, const std::shared_ptr<SocketCore>& socket);
|
||||
|
||||
virtual ~AbstractHttpServerResponseCommand();
|
||||
|
||||
|
|
|
@ -44,20 +44,19 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
AbstractOptionHandler::AbstractOptionHandler
|
||||
(PrefPtr pref,
|
||||
const char* description,
|
||||
const std::string& defaultValue,
|
||||
ARG_TYPE argType,
|
||||
char shortName)
|
||||
: pref_(pref),
|
||||
description_(description),
|
||||
defaultValue_(defaultValue),
|
||||
argType_(argType),
|
||||
shortName_(shortName),
|
||||
tags_(0),
|
||||
flags_(0)
|
||||
{}
|
||||
AbstractOptionHandler::AbstractOptionHandler(PrefPtr pref,
|
||||
const char* description,
|
||||
const std::string& defaultValue,
|
||||
ARG_TYPE argType, char shortName)
|
||||
: pref_(pref),
|
||||
description_(description),
|
||||
defaultValue_(defaultValue),
|
||||
argType_(argType),
|
||||
shortName_(shortName),
|
||||
tags_(0),
|
||||
flags_(0)
|
||||
{
|
||||
}
|
||||
|
||||
AbstractOptionHandler::~AbstractOptionHandler() {}
|
||||
|
||||
|
@ -65,7 +64,8 @@ void AbstractOptionHandler::parse(Option& option, const std::string& arg) const
|
|||
{
|
||||
try {
|
||||
parseArg(option, arg);
|
||||
} catch(Exception& e) {
|
||||
}
|
||||
catch (Exception& e) {
|
||||
throw OPTION_HANDLER_EXCEPTION2(pref_, e);
|
||||
}
|
||||
}
|
||||
|
@ -75,49 +75,38 @@ bool AbstractOptionHandler::hasTag(uint32_t tag) const
|
|||
return (tags_ & (1 << tag));
|
||||
}
|
||||
|
||||
void AbstractOptionHandler::addTag(uint32_t tag)
|
||||
{
|
||||
tags_ |= (1 << tag);
|
||||
}
|
||||
void AbstractOptionHandler::addTag(uint32_t tag) { tags_ |= (1 << tag); }
|
||||
|
||||
std::string AbstractOptionHandler::toTagString() const
|
||||
{
|
||||
std::string s;
|
||||
for(int i = 0; i < MAX_HELP_TAG; ++i) {
|
||||
if(tags_ & (1 << i)) {
|
||||
for (int i = 0; i < MAX_HELP_TAG; ++i) {
|
||||
if (tags_ & (1 << i)) {
|
||||
s += strHelpTag(i);
|
||||
s += ", ";
|
||||
}
|
||||
}
|
||||
if(!s.empty()) {
|
||||
if (!s.empty()) {
|
||||
s.resize(s.size() - 2);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
const char* AbstractOptionHandler::getName() const
|
||||
{
|
||||
return pref_->k;
|
||||
}
|
||||
const char* AbstractOptionHandler::getName() const { return pref_->k; }
|
||||
|
||||
void AbstractOptionHandler::updateFlags(int flag, bool val)
|
||||
{
|
||||
if(val) {
|
||||
if (val) {
|
||||
flags_ |= flag;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
flags_ &= ~flag;
|
||||
}
|
||||
}
|
||||
|
||||
bool AbstractOptionHandler::isHidden() const
|
||||
{
|
||||
return flags_ & FLAG_HIDDEN;
|
||||
}
|
||||
bool AbstractOptionHandler::isHidden() const { return flags_ & FLAG_HIDDEN; }
|
||||
|
||||
void AbstractOptionHandler::hide()
|
||||
{
|
||||
updateFlags(FLAG_HIDDEN, true);
|
||||
}
|
||||
void AbstractOptionHandler::hide() { updateFlags(FLAG_HIDDEN, true); }
|
||||
|
||||
bool AbstractOptionHandler::getEraseAfterParse() const
|
||||
{
|
||||
|
|
|
@ -55,17 +55,16 @@ protected:
|
|||
char shortName_;
|
||||
|
||||
virtual void parseArg(Option& option, const std::string& arg) const = 0;
|
||||
|
||||
public:
|
||||
AbstractOptionHandler(PrefPtr pref,
|
||||
const char* description = NO_DESCRIPTION,
|
||||
const std::string& defaultValue = NO_DEFAULT_VALUE,
|
||||
ARG_TYPE argType = REQ_ARG,
|
||||
char shortName = 0);
|
||||
AbstractOptionHandler(PrefPtr pref, const char* description = NO_DESCRIPTION,
|
||||
const std::string& defaultValue = NO_DEFAULT_VALUE,
|
||||
ARG_TYPE argType = REQ_ARG, char shortName = 0);
|
||||
|
||||
virtual ~AbstractOptionHandler();
|
||||
|
||||
virtual void parse(Option& option, const std::string& arg) const
|
||||
CXX11_OVERRIDE;
|
||||
virtual void parse(Option& option,
|
||||
const std::string& arg) const CXX11_OVERRIDE;
|
||||
|
||||
virtual bool hasTag(uint32_t tag) const CXX11_OVERRIDE;
|
||||
|
||||
|
@ -85,15 +84,9 @@ public:
|
|||
return defaultValue_;
|
||||
}
|
||||
|
||||
virtual PrefPtr getPref() const CXX11_OVERRIDE
|
||||
{
|
||||
return pref_;
|
||||
}
|
||||
virtual PrefPtr getPref() const CXX11_OVERRIDE { return pref_; }
|
||||
|
||||
virtual char getShortName() const CXX11_OVERRIDE
|
||||
{
|
||||
return shortName_;
|
||||
}
|
||||
virtual char getShortName() const CXX11_OVERRIDE { return shortName_; }
|
||||
|
||||
virtual OptionHandler::ARG_TYPE getArgType() const CXX11_OVERRIDE
|
||||
{
|
||||
|
@ -137,6 +130,7 @@ public:
|
|||
FLAG_CHANGE_GLOBAL_OPTION = 1 << 5,
|
||||
FLAG_CUMULATIVE = 1 << 6
|
||||
};
|
||||
|
||||
private:
|
||||
// bitwise OR of (1 << HelpTag value) defined in help_tags.h.
|
||||
uint32_t tags_;
|
||||
|
|
|
@ -49,20 +49,15 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
AbstractProxyRequestCommand::AbstractProxyRequestCommand
|
||||
(cuid_t cuid,
|
||||
const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry,
|
||||
RequestGroup* requestGroup,
|
||||
DownloadEngine* e,
|
||||
const std::shared_ptr<Request>& proxyRequest,
|
||||
const std::shared_ptr<SocketCore>& s)
|
||||
:
|
||||
AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
|
||||
proxyRequest_(proxyRequest),
|
||||
httpConnection_
|
||||
(std::make_shared<HttpConnection>
|
||||
(cuid, s, std::make_shared<SocketRecvBuffer>(s)))
|
||||
AbstractProxyRequestCommand::AbstractProxyRequestCommand(
|
||||
cuid_t cuid, const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
|
||||
DownloadEngine* e, const std::shared_ptr<Request>& proxyRequest,
|
||||
const std::shared_ptr<SocketCore>& s)
|
||||
: AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
|
||||
proxyRequest_(proxyRequest),
|
||||
httpConnection_(std::make_shared<HttpConnection>(
|
||||
cuid, s, std::make_shared<SocketRecvBuffer>(s)))
|
||||
{
|
||||
setTimeout(std::chrono::seconds(getOption()->getAsInt(PREF_CONNECT_TIMEOUT)));
|
||||
disableReadCheckSocket();
|
||||
|
@ -71,22 +66,25 @@ AbstractProxyRequestCommand::AbstractProxyRequestCommand
|
|||
|
||||
AbstractProxyRequestCommand::~AbstractProxyRequestCommand() {}
|
||||
|
||||
bool AbstractProxyRequestCommand::executeInternal() {
|
||||
//socket->setBlockingMode();
|
||||
if(httpConnection_->sendBufferIsEmpty()) {
|
||||
bool AbstractProxyRequestCommand::executeInternal()
|
||||
{
|
||||
// socket->setBlockingMode();
|
||||
if (httpConnection_->sendBufferIsEmpty()) {
|
||||
auto httpRequest = make_unique<HttpRequest>();
|
||||
httpRequest->setUserAgent(getOption()->get(PREF_USER_AGENT));
|
||||
httpRequest->setRequest(getRequest());
|
||||
httpRequest->setProxyRequest(proxyRequest_);
|
||||
|
||||
httpConnection_->sendProxyRequest(std::move(httpRequest));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
httpConnection_->sendPendingData();
|
||||
}
|
||||
if(httpConnection_->sendBufferIsEmpty()) {
|
||||
if (httpConnection_->sendBufferIsEmpty()) {
|
||||
getDownloadEngine()->addCommand(getNextCommand());
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
setWriteCheckSocket(getSocket());
|
||||
addCommandSelf();
|
||||
return false;
|
||||
|
|
|
@ -47,6 +47,7 @@ private:
|
|||
std::shared_ptr<Request> proxyRequest_;
|
||||
|
||||
std::shared_ptr<HttpConnection> httpConnection_;
|
||||
|
||||
protected:
|
||||
virtual bool executeInternal() CXX11_OVERRIDE;
|
||||
|
||||
|
@ -59,12 +60,11 @@ protected:
|
|||
{
|
||||
return proxyRequest_;
|
||||
}
|
||||
|
||||
public:
|
||||
AbstractProxyRequestCommand(cuid_t cuid,
|
||||
const std::shared_ptr<Request>& req,
|
||||
AbstractProxyRequestCommand(cuid_t cuid, const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry,
|
||||
RequestGroup* requestGroup,
|
||||
DownloadEngine* e,
|
||||
RequestGroup* requestGroup, DownloadEngine* e,
|
||||
const std::shared_ptr<Request>& proxyRequest,
|
||||
const std::shared_ptr<SocketCore>& s);
|
||||
|
||||
|
|
|
@ -50,27 +50,28 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
AbstractProxyResponseCommand::AbstractProxyResponseCommand
|
||||
(cuid_t cuid,
|
||||
const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry,
|
||||
RequestGroup* requestGroup,
|
||||
const std::shared_ptr<HttpConnection>& httpConnection,
|
||||
DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& s)
|
||||
:AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
|
||||
httpConnection_(httpConnection) {}
|
||||
AbstractProxyResponseCommand::AbstractProxyResponseCommand(
|
||||
cuid_t cuid, const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
|
||||
const std::shared_ptr<HttpConnection>& httpConnection, DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& s)
|
||||
: AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
|
||||
httpConnection_(httpConnection)
|
||||
{
|
||||
}
|
||||
|
||||
AbstractProxyResponseCommand::~AbstractProxyResponseCommand() {}
|
||||
|
||||
bool AbstractProxyResponseCommand::executeInternal() {
|
||||
std::shared_ptr<HttpResponse> httpResponse = httpConnection_->receiveResponse();
|
||||
if(!httpResponse) {
|
||||
bool AbstractProxyResponseCommand::executeInternal()
|
||||
{
|
||||
std::shared_ptr<HttpResponse> httpResponse =
|
||||
httpConnection_->receiveResponse();
|
||||
if (!httpResponse) {
|
||||
// the server has not responded our request yet.
|
||||
addCommandSelf();
|
||||
return false;
|
||||
}
|
||||
if(httpResponse->getStatusCode() != 200) {
|
||||
if (httpResponse->getStatusCode() != 200) {
|
||||
throw DL_RETRY_EX(EX_PROXY_CONNECTION_FAILED);
|
||||
}
|
||||
getDownloadEngine()->addCommand(getNextCommand());
|
||||
|
|
|
@ -45,6 +45,7 @@ class SocketCore;
|
|||
class AbstractProxyResponseCommand : public AbstractCommand {
|
||||
private:
|
||||
std::shared_ptr<HttpConnection> httpConnection_;
|
||||
|
||||
protected:
|
||||
virtual bool executeInternal() CXX11_OVERRIDE;
|
||||
|
||||
|
@ -52,15 +53,13 @@ protected:
|
|||
{
|
||||
return httpConnection_;
|
||||
}
|
||||
|
||||
public:
|
||||
AbstractProxyResponseCommand
|
||||
(cuid_t cuid,
|
||||
const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry,
|
||||
RequestGroup* requestGroup,
|
||||
const std::shared_ptr<HttpConnection>& httpConnection,
|
||||
DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& s);
|
||||
AbstractProxyResponseCommand(
|
||||
cuid_t cuid, const std::shared_ptr<Request>& req,
|
||||
const std::shared_ptr<FileEntry>& fileEntry, RequestGroup* requestGroup,
|
||||
const std::shared_ptr<HttpConnection>& httpConnection, DownloadEngine* e,
|
||||
const std::shared_ptr<SocketCore>& s);
|
||||
|
||||
virtual ~AbstractProxyResponseCommand();
|
||||
|
||||
|
|
|
@ -41,13 +41,15 @@
|
|||
#include "WrDiskCacheEntry.h"
|
||||
#include "LogFactory.h"
|
||||
#ifdef HAVE_SOME_FALLOCATE
|
||||
# include "FallocFileAllocationIterator.h"
|
||||
#include "FallocFileAllocationIterator.h"
|
||||
#endif // HAVE_SOME_FALLOCATE
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
AbstractSingleDiskAdaptor::AbstractSingleDiskAdaptor():
|
||||
totalLength_(0), readOnly_(false) {}
|
||||
AbstractSingleDiskAdaptor::AbstractSingleDiskAdaptor()
|
||||
: totalLength_(0), readOnly_(false)
|
||||
{
|
||||
}
|
||||
|
||||
AbstractSingleDiskAdaptor::~AbstractSingleDiskAdaptor() {}
|
||||
|
||||
|
@ -61,34 +63,31 @@ void AbstractSingleDiskAdaptor::openFile()
|
|||
diskWriter_->openFile(totalLength_);
|
||||
}
|
||||
|
||||
void AbstractSingleDiskAdaptor::closeFile()
|
||||
{
|
||||
diskWriter_->closeFile();
|
||||
}
|
||||
void AbstractSingleDiskAdaptor::closeFile() { diskWriter_->closeFile(); }
|
||||
|
||||
void AbstractSingleDiskAdaptor::openExistingFile()
|
||||
{
|
||||
diskWriter_->openExistingFile(totalLength_);
|
||||
}
|
||||
|
||||
void AbstractSingleDiskAdaptor::writeData
|
||||
(const unsigned char* data, size_t len, int64_t offset)
|
||||
void AbstractSingleDiskAdaptor::writeData(const unsigned char* data, size_t len,
|
||||
int64_t offset)
|
||||
{
|
||||
diskWriter_->writeData(data, len, offset);
|
||||
}
|
||||
|
||||
ssize_t AbstractSingleDiskAdaptor::readData
|
||||
(unsigned char* data, size_t len, int64_t offset)
|
||||
ssize_t AbstractSingleDiskAdaptor::readData(unsigned char* data, size_t len,
|
||||
int64_t offset)
|
||||
{
|
||||
return diskWriter_->readData(data, len, offset);
|
||||
}
|
||||
|
||||
ssize_t AbstractSingleDiskAdaptor::readDataDropCache
|
||||
(unsigned char* data, size_t len, int64_t offset)
|
||||
ssize_t AbstractSingleDiskAdaptor::readDataDropCache(unsigned char* data,
|
||||
size_t len, int64_t offset)
|
||||
{
|
||||
auto rv = readData(data, len, offset);
|
||||
|
||||
if(rv > 0) {
|
||||
if (rv > 0) {
|
||||
diskWriter_->dropCache(len, offset);
|
||||
}
|
||||
|
||||
|
@ -106,31 +105,32 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
|
|||
size_t buflen = 0;
|
||||
size_t buffoffset = 0;
|
||||
const WrDiskCacheEntry::DataCellSet& dataSet = entry->getDataSet();
|
||||
for(auto & d : dataSet) {
|
||||
if(start+static_cast<ssize_t>(buflen) < d->goff) {
|
||||
A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu",
|
||||
start, static_cast<unsigned long>(buflen)));
|
||||
writeData(buf+buffoffset, buflen-buffoffset, start);
|
||||
for (auto& d : dataSet) {
|
||||
if (start + static_cast<ssize_t>(buflen) < d->goff) {
|
||||
A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start,
|
||||
static_cast<unsigned long>(buflen)));
|
||||
writeData(buf + buffoffset, buflen - buffoffset, start);
|
||||
start = d->goff;
|
||||
buflen = buffoffset = 0;
|
||||
}
|
||||
if(buflen == 0 && (d->goff & 0xfff) == 0 && (d->len & 0xfff) == 0) {
|
||||
if (buflen == 0 && (d->goff & 0xfff) == 0 && (d->len & 0xfff) == 0) {
|
||||
// Already aligned. Write it without copy.
|
||||
A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu",
|
||||
start, static_cast<unsigned long>(d->len)));
|
||||
A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start,
|
||||
static_cast<unsigned long>(d->len)));
|
||||
writeData(d->data + d->offset, d->len, start);
|
||||
start += d->len;
|
||||
} else {
|
||||
if(buflen == 0) {
|
||||
}
|
||||
else {
|
||||
if (buflen == 0) {
|
||||
buflen = buffoffset = d->goff & 0xfff;
|
||||
}
|
||||
size_t wlen = std::min(sizeof(buf) - buflen, d->len);
|
||||
memcpy(buf+buflen, d->data + d->offset, wlen);
|
||||
memcpy(buf + buflen, d->data + d->offset, wlen);
|
||||
buflen += wlen;
|
||||
if(buflen == sizeof(buf)) {
|
||||
A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu",
|
||||
start, static_cast<unsigned long>(buflen)));
|
||||
writeData(buf+buffoffset, buflen-buffoffset, start);
|
||||
if (buflen == sizeof(buf)) {
|
||||
A2_LOG_DEBUG(fmt("Cache flush goff=%" PRId64 ", len=%lu", start,
|
||||
static_cast<unsigned long>(buflen)));
|
||||
writeData(buf + buffoffset, buflen - buffoffset, start);
|
||||
memcpy(buf, d->data + d->offset + wlen, d->len - wlen);
|
||||
start += sizeof(buf) - buffoffset;
|
||||
buflen = d->len - wlen;
|
||||
|
@ -138,7 +138,7 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
|
|||
}
|
||||
}
|
||||
}
|
||||
writeData(buf+buffoffset, buflen-buffoffset, start);
|
||||
writeData(buf + buffoffset, buflen - buffoffset, start);
|
||||
}
|
||||
|
||||
bool AbstractSingleDiskAdaptor::fileExists()
|
||||
|
@ -146,10 +146,7 @@ bool AbstractSingleDiskAdaptor::fileExists()
|
|||
return File(getFilePath()).exists();
|
||||
}
|
||||
|
||||
int64_t AbstractSingleDiskAdaptor::size()
|
||||
{
|
||||
return File(getFilePath()).size();
|
||||
}
|
||||
int64_t AbstractSingleDiskAdaptor::size() { return File(getFilePath()).size(); }
|
||||
|
||||
void AbstractSingleDiskAdaptor::truncate(int64_t length)
|
||||
{
|
||||
|
@ -159,18 +156,18 @@ void AbstractSingleDiskAdaptor::truncate(int64_t length)
|
|||
std::unique_ptr<FileAllocationIterator>
|
||||
AbstractSingleDiskAdaptor::fileAllocationIterator()
|
||||
{
|
||||
switch(getFileAllocationMethod()) {
|
||||
switch (getFileAllocationMethod()) {
|
||||
#ifdef HAVE_SOME_FALLOCATE
|
||||
case(DiskAdaptor::FILE_ALLOC_FALLOC):
|
||||
return make_unique<FallocFileAllocationIterator>
|
||||
(diskWriter_.get(), size() ,totalLength_);
|
||||
case (DiskAdaptor::FILE_ALLOC_FALLOC):
|
||||
return make_unique<FallocFileAllocationIterator>(diskWriter_.get(), size(),
|
||||
totalLength_);
|
||||
#endif // HAVE_SOME_FALLOCATE
|
||||
case(DiskAdaptor::FILE_ALLOC_TRUNC):
|
||||
return make_unique<TruncFileAllocationIterator>
|
||||
(diskWriter_.get(), size(), totalLength_);
|
||||
case (DiskAdaptor::FILE_ALLOC_TRUNC):
|
||||
return make_unique<TruncFileAllocationIterator>(diskWriter_.get(), size(),
|
||||
totalLength_);
|
||||
default:
|
||||
return make_unique<AdaptiveFileAllocationIterator>
|
||||
(diskWriter_.get(), size(), totalLength_);
|
||||
return make_unique<AdaptiveFileAllocationIterator>(diskWriter_.get(),
|
||||
size(), totalLength_);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,20 +183,17 @@ void AbstractSingleDiskAdaptor::disableReadOnly()
|
|||
readOnly_ = false;
|
||||
}
|
||||
|
||||
void AbstractSingleDiskAdaptor::enableMmap()
|
||||
{
|
||||
diskWriter_->enableMmap();
|
||||
}
|
||||
void AbstractSingleDiskAdaptor::enableMmap() { diskWriter_->enableMmap(); }
|
||||
|
||||
void AbstractSingleDiskAdaptor::cutTrailingGarbage()
|
||||
{
|
||||
if(File(getFilePath()).size() > totalLength_) {
|
||||
if (File(getFilePath()).size() > totalLength_) {
|
||||
diskWriter_->truncate(totalLength_);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractSingleDiskAdaptor::setDiskWriter
|
||||
(std::unique_ptr<DiskWriter> diskWriter)
|
||||
void AbstractSingleDiskAdaptor::setDiskWriter(
|
||||
std::unique_ptr<DiskWriter> diskWriter)
|
||||
{
|
||||
diskWriter_ = std::move(diskWriter);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ private:
|
|||
std::unique_ptr<DiskWriter> diskWriter_;
|
||||
int64_t totalLength_;
|
||||
bool readOnly_;
|
||||
|
||||
public:
|
||||
AbstractSingleDiskAdaptor();
|
||||
|
||||
|
@ -63,12 +64,11 @@ public:
|
|||
virtual void writeData(const unsigned char* data, size_t len,
|
||||
int64_t offset) CXX11_OVERRIDE;
|
||||
|
||||
virtual ssize_t readData(unsigned char* data, size_t len, int64_t offset)
|
||||
CXX11_OVERRIDE;
|
||||
virtual ssize_t readData(unsigned char* data, size_t len,
|
||||
int64_t offset) CXX11_OVERRIDE;
|
||||
|
||||
virtual ssize_t readDataDropCache(unsigned char* data, size_t len,
|
||||
int64_t offset)
|
||||
CXX11_OVERRIDE;
|
||||
int64_t offset) CXX11_OVERRIDE;
|
||||
|
||||
virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
|
||||
|
||||
|
@ -78,8 +78,8 @@ public:
|
|||
|
||||
virtual void truncate(int64_t length) CXX11_OVERRIDE;
|
||||
|
||||
virtual std::unique_ptr<FileAllocationIterator> fileAllocationIterator()
|
||||
CXX11_OVERRIDE;
|
||||
virtual std::unique_ptr<FileAllocationIterator>
|
||||
fileAllocationIterator() CXX11_OVERRIDE;
|
||||
|
||||
// Make sure that DiskWriter is set before calling this function.
|
||||
virtual void enableReadOnly() CXX11_OVERRIDE;
|
||||
|
@ -104,10 +104,7 @@ public:
|
|||
|
||||
void setTotalLength(int64_t totalLength);
|
||||
|
||||
int64_t getTotalLength() const
|
||||
{
|
||||
return totalLength_;
|
||||
}
|
||||
int64_t getTotalLength() const { return totalLength_; }
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -56,16 +56,14 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
ActivePeerConnectionCommand::ActivePeerConnectionCommand
|
||||
(cuid_t cuid,
|
||||
RequestGroup* requestGroup,
|
||||
DownloadEngine* e,
|
||||
std::chrono::seconds interval)
|
||||
: Command(cuid),
|
||||
requestGroup_(requestGroup),
|
||||
interval_(std::move(interval)),
|
||||
e_(e),
|
||||
numNewConnection_(5)
|
||||
ActivePeerConnectionCommand::ActivePeerConnectionCommand(
|
||||
cuid_t cuid, RequestGroup* requestGroup, DownloadEngine* e,
|
||||
std::chrono::seconds interval)
|
||||
: Command(cuid),
|
||||
requestGroup_(requestGroup),
|
||||
interval_(std::move(interval)),
|
||||
e_(e),
|
||||
numNewConnection_(5)
|
||||
{
|
||||
requestGroup_->increaseNumCommand();
|
||||
}
|
||||
|
@ -75,50 +73,53 @@ ActivePeerConnectionCommand::~ActivePeerConnectionCommand()
|
|||
requestGroup_->decreaseNumCommand();
|
||||
}
|
||||
|
||||
bool ActivePeerConnectionCommand::execute() {
|
||||
if(btRuntime_->isHalt()) {
|
||||
bool ActivePeerConnectionCommand::execute()
|
||||
{
|
||||
if (btRuntime_->isHalt()) {
|
||||
return true;
|
||||
}
|
||||
if(checkPoint_.difference(global::wallclock()) >= interval_) {
|
||||
if (checkPoint_.difference(global::wallclock()) >= interval_) {
|
||||
checkPoint_ = global::wallclock();
|
||||
NetStat& stat = requestGroup_->getDownloadContext()->getNetStat();
|
||||
const int maxDownloadLimit = requestGroup_->getMaxDownloadSpeedLimit();
|
||||
const int maxUploadLimit = requestGroup_->getMaxUploadSpeedLimit();
|
||||
int thresholdSpeed;
|
||||
if(!bittorrent::getTorrentAttrs
|
||||
(requestGroup_->getDownloadContext())->metadata.empty()) {
|
||||
thresholdSpeed =
|
||||
requestGroup_->getOption()->getAsInt(PREF_BT_REQUEST_PEER_SPEED_LIMIT);
|
||||
} else {
|
||||
if (!bittorrent::getTorrentAttrs(requestGroup_->getDownloadContext())
|
||||
->metadata.empty()) {
|
||||
thresholdSpeed = requestGroup_->getOption()->getAsInt(
|
||||
PREF_BT_REQUEST_PEER_SPEED_LIMIT);
|
||||
}
|
||||
else {
|
||||
thresholdSpeed = 0;
|
||||
}
|
||||
if(maxDownloadLimit > 0) {
|
||||
if (maxDownloadLimit > 0) {
|
||||
thresholdSpeed = std::min(maxDownloadLimit, thresholdSpeed);
|
||||
}
|
||||
if(// for seeder state
|
||||
(pieceStorage_->downloadFinished() && btRuntime_->lessThanMaxPeers() &&
|
||||
(maxUploadLimit == 0 ||
|
||||
stat.calculateUploadSpeed() < maxUploadLimit*0.8)) ||
|
||||
// for leecher state
|
||||
(!pieceStorage_->downloadFinished() &&
|
||||
(stat.calculateDownloadSpeed() < thresholdSpeed ||
|
||||
btRuntime_->lessThanMinPeers()))) {
|
||||
if ( // for seeder state
|
||||
(pieceStorage_->downloadFinished() && btRuntime_->lessThanMaxPeers() &&
|
||||
(maxUploadLimit == 0 ||
|
||||
stat.calculateUploadSpeed() < maxUploadLimit * 0.8)) ||
|
||||
// for leecher state
|
||||
(!pieceStorage_->downloadFinished() &&
|
||||
(stat.calculateDownloadSpeed() < thresholdSpeed ||
|
||||
btRuntime_->lessThanMinPeers()))) {
|
||||
|
||||
int numConnection = 0;
|
||||
if(pieceStorage_->downloadFinished()) {
|
||||
if(btRuntime_->getMaxPeers() > btRuntime_->getConnections()) {
|
||||
if (pieceStorage_->downloadFinished()) {
|
||||
if (btRuntime_->getMaxPeers() > btRuntime_->getConnections()) {
|
||||
numConnection =
|
||||
std::min(numNewConnection_,
|
||||
btRuntime_->getMaxPeers()-btRuntime_->getConnections());
|
||||
std::min(numNewConnection_, btRuntime_->getMaxPeers() -
|
||||
btRuntime_->getConnections());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
numConnection = numNewConnection_;
|
||||
}
|
||||
|
||||
makeNewConnections(numConnection);
|
||||
|
||||
if(btRuntime_->getConnections() == 0 &&
|
||||
!pieceStorage_->downloadFinished()) {
|
||||
if (btRuntime_->getConnections() == 0 &&
|
||||
!pieceStorage_->downloadFinished()) {
|
||||
btAnnounce_->overrideMinInterval(BtAnnounce::DEFAULT_ANNOUNCE_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
@ -129,43 +130,43 @@ bool ActivePeerConnectionCommand::execute() {
|
|||
|
||||
void ActivePeerConnectionCommand::makeNewConnections(int num)
|
||||
{
|
||||
for(; num && peerStorage_->isPeerAvailable(); --num) {
|
||||
for (; num && peerStorage_->isPeerAvailable(); --num) {
|
||||
cuid_t ncuid = e_->newCUID();
|
||||
std::shared_ptr<Peer> peer = peerStorage_->checkoutPeer(ncuid);
|
||||
// sanity check
|
||||
if(!peer) {
|
||||
if (!peer) {
|
||||
break;
|
||||
}
|
||||
auto command = make_unique<PeerInitiateConnectionCommand>
|
||||
(ncuid, requestGroup_, peer, e_, btRuntime_);
|
||||
auto command = make_unique<PeerInitiateConnectionCommand>(
|
||||
ncuid, requestGroup_, peer, e_, btRuntime_);
|
||||
command->setPeerStorage(peerStorage_);
|
||||
command->setPieceStorage(pieceStorage_);
|
||||
e_->addCommand(std::move(command));
|
||||
A2_LOG_INFO(fmt(MSG_CONNECTING_TO_PEER, getCuid(),
|
||||
peer->getIPAddress().c_str()));
|
||||
A2_LOG_INFO(
|
||||
fmt(MSG_CONNECTING_TO_PEER, getCuid(), peer->getIPAddress().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
void ActivePeerConnectionCommand::setBtRuntime
|
||||
(const std::shared_ptr<BtRuntime>& btRuntime)
|
||||
void ActivePeerConnectionCommand::setBtRuntime(
|
||||
const std::shared_ptr<BtRuntime>& btRuntime)
|
||||
{
|
||||
btRuntime_ = btRuntime;
|
||||
}
|
||||
|
||||
void ActivePeerConnectionCommand::setPieceStorage
|
||||
(const std::shared_ptr<PieceStorage>& pieceStorage)
|
||||
void ActivePeerConnectionCommand::setPieceStorage(
|
||||
const std::shared_ptr<PieceStorage>& pieceStorage)
|
||||
{
|
||||
pieceStorage_ = pieceStorage;
|
||||
}
|
||||
|
||||
void ActivePeerConnectionCommand::setPeerStorage
|
||||
(const std::shared_ptr<PeerStorage>& peerStorage)
|
||||
void ActivePeerConnectionCommand::setPeerStorage(
|
||||
const std::shared_ptr<PeerStorage>& peerStorage)
|
||||
{
|
||||
peerStorage_ = peerStorage;
|
||||
}
|
||||
|
||||
void ActivePeerConnectionCommand::setBtAnnounce
|
||||
(const std::shared_ptr<BtAnnounce>& btAnnounce)
|
||||
void ActivePeerConnectionCommand::setBtAnnounce(
|
||||
const std::shared_ptr<BtAnnounce>& btAnnounce)
|
||||
{
|
||||
btAnnounce_ = btAnnounce;
|
||||
}
|
||||
|
|
|
@ -64,10 +64,8 @@ private:
|
|||
Timer checkPoint_;
|
||||
int numNewConnection_; // the number of the connection to establish.
|
||||
public:
|
||||
ActivePeerConnectionCommand(cuid_t cuid,
|
||||
RequestGroup* requestGroup,
|
||||
DownloadEngine* e,
|
||||
std::chrono::seconds interval);
|
||||
ActivePeerConnectionCommand(cuid_t cuid, RequestGroup* requestGroup,
|
||||
DownloadEngine* e, std::chrono::seconds interval);
|
||||
|
||||
virtual ~ActivePeerConnectionCommand();
|
||||
|
||||
|
|
|
@ -40,68 +40,71 @@
|
|||
#include "Logger.h"
|
||||
#include "a2functional.h"
|
||||
#ifdef HAVE_FALLOCATE
|
||||
# include "FallocFileAllocationIterator.h"
|
||||
#include "FallocFileAllocationIterator.h"
|
||||
#endif // HAVE_FALLOCATE
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
AdaptiveFileAllocationIterator::AdaptiveFileAllocationIterator
|
||||
(BinaryStream* stream, int64_t offset, int64_t totalLength)
|
||||
: stream_(stream),
|
||||
offset_(offset),
|
||||
totalLength_(totalLength)
|
||||
{}
|
||||
AdaptiveFileAllocationIterator::AdaptiveFileAllocationIterator(
|
||||
BinaryStream* stream, int64_t offset, int64_t totalLength)
|
||||
: stream_(stream), offset_(offset), totalLength_(totalLength)
|
||||
{
|
||||
}
|
||||
|
||||
AdaptiveFileAllocationIterator::~AdaptiveFileAllocationIterator() {}
|
||||
|
||||
void AdaptiveFileAllocationIterator::allocateChunk()
|
||||
{
|
||||
if(!allocator_) {
|
||||
if (!allocator_) {
|
||||
#ifdef HAVE_FALLOCATE
|
||||
try {
|
||||
A2_LOG_DEBUG("Testing file system supports fallocate.");
|
||||
if(offset_ < totalLength_) {
|
||||
if (offset_ < totalLength_) {
|
||||
int64_t len =
|
||||
std::min(totalLength_ - offset_, static_cast<int64_t>(4_k));
|
||||
stream_->allocate(offset_, len, false);
|
||||
offset_ += len;
|
||||
}
|
||||
A2_LOG_DEBUG("File system supports fallocate.");
|
||||
allocator_ = make_unique<FallocFileAllocationIterator>
|
||||
(stream_, offset_, totalLength_);
|
||||
} catch(RecoverableException& e) {
|
||||
allocator_ = make_unique<FallocFileAllocationIterator>(stream_, offset_,
|
||||
totalLength_);
|
||||
}
|
||||
catch (RecoverableException& e) {
|
||||
A2_LOG_DEBUG("File system does not support fallocate.");
|
||||
auto salloc = make_unique<SingleFileAllocationIterator>
|
||||
(stream_, offset_, totalLength_);
|
||||
auto salloc = make_unique<SingleFileAllocationIterator>(stream_, offset_,
|
||||
totalLength_);
|
||||
salloc->init();
|
||||
allocator_ = std::move(salloc);
|
||||
}
|
||||
#else // !HAVE_FALLOCATE
|
||||
auto salloc = make_unique<SingleFileAllocationIterator>
|
||||
(stream_, offset_, totalLength_);
|
||||
#else // !HAVE_FALLOCATE
|
||||
auto salloc = make_unique<SingleFileAllocationIterator>(stream_, offset_,
|
||||
totalLength_);
|
||||
salloc->init();
|
||||
allocator_ = std::move(salloc);
|
||||
#endif // !HAVE_FALLOCATE
|
||||
allocator_->allocateChunk();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
allocator_->allocateChunk();
|
||||
}
|
||||
}
|
||||
|
||||
bool AdaptiveFileAllocationIterator::finished()
|
||||
{
|
||||
if(!allocator_) {
|
||||
if (!allocator_) {
|
||||
return offset_ == totalLength_;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return allocator_->finished();
|
||||
}
|
||||
}
|
||||
|
||||
int64_t AdaptiveFileAllocationIterator::getCurrentLength()
|
||||
{
|
||||
if(!allocator_) {
|
||||
if (!allocator_) {
|
||||
return offset_;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return allocator_->getCurrentLength();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,8 +43,7 @@ namespace aria2 {
|
|||
|
||||
class BinaryStream;
|
||||
|
||||
class AdaptiveFileAllocationIterator:public FileAllocationIterator
|
||||
{
|
||||
class AdaptiveFileAllocationIterator : public FileAllocationIterator {
|
||||
private:
|
||||
std::unique_ptr<FileAllocationIterator> allocator_;
|
||||
|
||||
|
@ -53,9 +52,10 @@ private:
|
|||
int64_t offset_;
|
||||
|
||||
int64_t totalLength_;
|
||||
|
||||
public:
|
||||
AdaptiveFileAllocationIterator
|
||||
(BinaryStream* stream, int64_t offset, int64_t totalLength);
|
||||
AdaptiveFileAllocationIterator(BinaryStream* stream, int64_t offset,
|
||||
int64_t totalLength);
|
||||
|
||||
virtual ~AdaptiveFileAllocationIterator();
|
||||
|
||||
|
|
|
@ -65,22 +65,21 @@ namespace aria2 {
|
|||
* be tested again. Otherwise, it doesn't return anymore mirrors.
|
||||
*/
|
||||
|
||||
AdaptiveURISelector::AdaptiveURISelector
|
||||
(std::shared_ptr<ServerStatMan> serverStatMan, RequestGroup* requestGroup)
|
||||
: serverStatMan_(std::move(serverStatMan)),
|
||||
requestGroup_(requestGroup)
|
||||
AdaptiveURISelector::AdaptiveURISelector(
|
||||
std::shared_ptr<ServerStatMan> serverStatMan, RequestGroup* requestGroup)
|
||||
: serverStatMan_(std::move(serverStatMan)), requestGroup_(requestGroup)
|
||||
{
|
||||
resetCounters();
|
||||
}
|
||||
|
||||
AdaptiveURISelector::~AdaptiveURISelector() {}
|
||||
|
||||
std::string AdaptiveURISelector::select
|
||||
(FileEntry* fileEntry,
|
||||
const std::vector<std::pair<size_t, std::string> >& usedHosts)
|
||||
std::string AdaptiveURISelector::select(
|
||||
FileEntry* fileEntry,
|
||||
const std::vector<std::pair<size_t, std::string>>& usedHosts)
|
||||
{
|
||||
A2_LOG_DEBUG(fmt("AdaptiveURISelector: called %d",
|
||||
requestGroup_->getNumConnection()));
|
||||
A2_LOG_DEBUG(
|
||||
fmt("AdaptiveURISelector: called %d", requestGroup_->getNumConnection()));
|
||||
std::deque<std::string>& uris = fileEntry->getRemainingUris();
|
||||
if (uris.empty() && requestGroup_->getNumConnection() <= 1) {
|
||||
// here we know the download will fail, trying to find previously
|
||||
|
@ -90,7 +89,7 @@ std::string AdaptiveURISelector::select
|
|||
|
||||
std::string selected = selectOne(uris);
|
||||
|
||||
if(selected != A2STR::NIL) {
|
||||
if (selected != A2STR::NIL) {
|
||||
uris.erase(std::find(std::begin(uris), std::end(uris), selected));
|
||||
}
|
||||
return selected;
|
||||
|
@ -102,8 +101,9 @@ constexpr auto MAX_TIMEOUT = 60_s;
|
|||
|
||||
void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
|
||||
{
|
||||
if (requestGroup_->getTimeout()*2 >= MAX_TIMEOUT) return;
|
||||
requestGroup_->setTimeout(requestGroup_->getTimeout()*2);
|
||||
if (requestGroup_->getTimeout() * 2 >= MAX_TIMEOUT)
|
||||
return;
|
||||
requestGroup_->setTimeout(requestGroup_->getTimeout() * 2);
|
||||
|
||||
std::deque<std::string>& uris = fileEntry->getRemainingUris();
|
||||
// looking for retries
|
||||
|
@ -112,7 +112,7 @@ void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
|
|||
std::transform(std::begin(timeouts), std::end(timeouts),
|
||||
std::back_inserter(uris), std::mem_fn(&URIResult::getURI));
|
||||
|
||||
if(A2_LOG_DEBUG_ENABLED) {
|
||||
if (A2_LOG_DEBUG_ENABLED) {
|
||||
for (const auto& uri : uris) {
|
||||
A2_LOG_DEBUG(
|
||||
fmt("AdaptiveURISelector: will retry server with increased"
|
||||
|
@ -126,25 +126,27 @@ void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
|
|||
std::string AdaptiveURISelector::selectOne(const std::deque<std::string>& uris)
|
||||
{
|
||||
|
||||
if(uris.empty()) {
|
||||
if (uris.empty()) {
|
||||
return A2STR::NIL;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
const size_t numPieces =
|
||||
requestGroup_->getDownloadContext()->getNumPieces();
|
||||
requestGroup_->getDownloadContext()->getNumPieces();
|
||||
|
||||
bool reservedContext = numPieces > 0 &&
|
||||
static_cast<size_t>(nbConnections_) > std::min
|
||||
(numPieces,
|
||||
static_cast<size_t>(requestGroup_->getNumConcurrentCommand()));
|
||||
bool reservedContext =
|
||||
numPieces > 0 &&
|
||||
static_cast<size_t>(nbConnections_) >
|
||||
std::min(numPieces, static_cast<size_t>(
|
||||
requestGroup_->getNumConcurrentCommand()));
|
||||
bool selectBest = numPieces == 0 || reservedContext;
|
||||
|
||||
if(numPieces > 0)
|
||||
if (numPieces > 0)
|
||||
++nbConnections_;
|
||||
|
||||
/* At least, 3 mirrors must be tested */
|
||||
if(getNbTestedServers(uris) < 3) {
|
||||
if (getNbTestedServers(uris) < 3) {
|
||||
std::string notTested = getFirstNotTestedUri(uris);
|
||||
if(notTested != A2STR::NIL) {
|
||||
if (notTested != A2STR::NIL) {
|
||||
A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing the first non tested"
|
||||
" mirror: %s",
|
||||
notTested.c_str()));
|
||||
|
@ -153,24 +155,26 @@ std::string AdaptiveURISelector::selectOne(const std::deque<std::string>& uris)
|
|||
}
|
||||
}
|
||||
|
||||
if(!selectBest && nbConnections_ > 1 && nbServerToEvaluate_ > 0) {
|
||||
if (!selectBest && nbConnections_ > 1 && nbServerToEvaluate_ > 0) {
|
||||
nbServerToEvaluate_--;
|
||||
std::string notTested = getFirstNotTestedUri(uris);
|
||||
if(notTested != A2STR::NIL) {
|
||||
if (notTested != A2STR::NIL) {
|
||||
/* Here we return the first untested mirror */
|
||||
A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing non tested mirror %s"
|
||||
" for connection #%d",
|
||||
notTested.c_str(), nbConnections_));
|
||||
return notTested;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* Here we return a mirror which need to be tested again */
|
||||
std::string toReTest = getFirstToTestUri(uris);
|
||||
if(toReTest != A2STR::NIL) {
|
||||
if (toReTest != A2STR::NIL) {
|
||||
A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing mirror %s which has"
|
||||
" not been tested recently for connection #%d",
|
||||
toReTest.c_str(), nbConnections_));
|
||||
return toReTest;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return getBestMirror(uris);
|
||||
}
|
||||
}
|
||||
|
@ -181,28 +185,26 @@ std::string AdaptiveURISelector::selectOne(const std::deque<std::string>& uris)
|
|||
}
|
||||
}
|
||||
|
||||
std::string AdaptiveURISelector::getBestMirror
|
||||
(const std::deque<std::string>& uris) const
|
||||
std::string
|
||||
AdaptiveURISelector::getBestMirror(const std::deque<std::string>& uris) const
|
||||
{
|
||||
/* Here we return one of the bests mirrors */
|
||||
int max = getMaxDownloadSpeed(uris);
|
||||
int min = max-(int)(max*0.25);
|
||||
int min = max - (int)(max * 0.25);
|
||||
std::deque<std::string> bests = getUrisBySpeed(uris, min);
|
||||
|
||||
if (bests.size() < 2) {
|
||||
std::string uri = getMaxDownloadSpeedUri(uris);
|
||||
A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing the best mirror :"
|
||||
" %.2fKB/s %s (other mirrors are at least 25%% slower)",
|
||||
(float) max/1024,
|
||||
uri.c_str()));
|
||||
(float)max / 1024, uri.c_str()));
|
||||
return uri;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
std::string uri = selectRandomUri(bests);
|
||||
A2_LOG_DEBUG(fmt("AdaptiveURISelector: choosing randomly one of the best"
|
||||
" mirrors (range [%.2fKB/s, %.2fKB/s]): %s",
|
||||
(float) min/1024,
|
||||
(float) max/1024,
|
||||
uri.c_str()));
|
||||
(float)min / 1024, (float)max / 1024, uri.c_str()));
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
@ -210,36 +212,32 @@ std::string AdaptiveURISelector::getBestMirror
|
|||
void AdaptiveURISelector::resetCounters()
|
||||
{
|
||||
nbConnections_ = 1;
|
||||
nbServerToEvaluate_ =
|
||||
requestGroup_->getOption()->getAsInt(PREF_SPLIT) - 1;
|
||||
nbServerToEvaluate_ = requestGroup_->getOption()->getAsInt(PREF_SPLIT) - 1;
|
||||
}
|
||||
|
||||
void AdaptiveURISelector::tuneDownloadCommand
|
||||
(const std::deque<std::string>& uris, DownloadCommand* command)
|
||||
void AdaptiveURISelector::tuneDownloadCommand(
|
||||
const std::deque<std::string>& uris, DownloadCommand* command)
|
||||
{
|
||||
adjustLowestSpeedLimit(uris, command);
|
||||
}
|
||||
|
||||
void AdaptiveURISelector::adjustLowestSpeedLimit
|
||||
(const std::deque<std::string>& uris, DownloadCommand* command) const
|
||||
void AdaptiveURISelector::adjustLowestSpeedLimit(
|
||||
const std::deque<std::string>& uris, DownloadCommand* command) const
|
||||
{
|
||||
int lowest =
|
||||
requestGroup_->getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT);
|
||||
int lowest = requestGroup_->getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT);
|
||||
if (lowest > 0) {
|
||||
int low_lowest = 4_k;
|
||||
int max = getMaxDownloadSpeed(uris);
|
||||
if (max > 0 && lowest > max / 4) {
|
||||
A2_LOG_NOTICE(fmt(_("Lowering lowest-speed-limit since known max speed is"
|
||||
" too near (new:%d was:%d max:%d)"),
|
||||
max / 4,
|
||||
lowest,
|
||||
max));
|
||||
max / 4, lowest, max));
|
||||
command->setLowestDownloadSpeedLimit(max / 4);
|
||||
} else if (max == 0 && lowest > low_lowest) {
|
||||
}
|
||||
else if (max == 0 && lowest > low_lowest) {
|
||||
A2_LOG_NOTICE(fmt(_("Lowering lowest-speed-limit since we have no clue"
|
||||
" about available speed (now:%d was:%d)"),
|
||||
low_lowest,
|
||||
lowest));
|
||||
low_lowest, lowest));
|
||||
command->setLowestDownloadSpeedLimit(low_lowest);
|
||||
}
|
||||
}
|
||||
|
@ -253,30 +251,30 @@ int getUriMaxSpeed(std::shared_ptr<ServerStat> ss)
|
|||
}
|
||||
} // namespace
|
||||
|
||||
int AdaptiveURISelector::getMaxDownloadSpeed
|
||||
(const std::deque<std::string>& uris) const
|
||||
int AdaptiveURISelector::getMaxDownloadSpeed(
|
||||
const std::deque<std::string>& uris) const
|
||||
{
|
||||
std::string uri = getMaxDownloadSpeedUri(uris);
|
||||
if(uri == A2STR::NIL)
|
||||
if (uri == A2STR::NIL)
|
||||
return 0;
|
||||
return getUriMaxSpeed(getServerStats(uri));
|
||||
}
|
||||
|
||||
std::string AdaptiveURISelector::getMaxDownloadSpeedUri
|
||||
(const std::deque<std::string>& uris) const
|
||||
std::string AdaptiveURISelector::getMaxDownloadSpeedUri(
|
||||
const std::deque<std::string>& uris) const
|
||||
{
|
||||
int max = -1;
|
||||
std::string uri = A2STR::NIL;
|
||||
for(auto& u : uris) {
|
||||
for (auto& u : uris) {
|
||||
std::shared_ptr<ServerStat> ss = getServerStats(u);
|
||||
if(!ss)
|
||||
if (!ss)
|
||||
continue;
|
||||
|
||||
if((int)ss->getSingleConnectionAvgSpeed() > max) {
|
||||
if ((int)ss->getSingleConnectionAvgSpeed() > max) {
|
||||
max = ss->getSingleConnectionAvgSpeed();
|
||||
uri = u;
|
||||
}
|
||||
if((int)ss->getMultiConnectionAvgSpeed() > max) {
|
||||
if ((int)ss->getMultiConnectionAvgSpeed() > max) {
|
||||
max = ss->getMultiConnectionAvgSpeed();
|
||||
uri = u;
|
||||
}
|
||||
|
@ -284,84 +282,86 @@ std::string AdaptiveURISelector::getMaxDownloadSpeedUri
|
|||
return uri;
|
||||
}
|
||||
|
||||
std::deque<std::string> AdaptiveURISelector::getUrisBySpeed
|
||||
(const std::deque<std::string>& uris, int min) const
|
||||
std::deque<std::string>
|
||||
AdaptiveURISelector::getUrisBySpeed(const std::deque<std::string>& uris,
|
||||
int min) const
|
||||
{
|
||||
std::deque<std::string> bests;
|
||||
for(auto& uri : uris) {
|
||||
for (auto& uri : uris) {
|
||||
std::shared_ptr<ServerStat> ss = getServerStats(uri);
|
||||
if(!ss)
|
||||
if (!ss)
|
||||
continue;
|
||||
if(ss->getSingleConnectionAvgSpeed() > min ||
|
||||
ss->getMultiConnectionAvgSpeed() > min) {
|
||||
if (ss->getSingleConnectionAvgSpeed() > min ||
|
||||
ss->getMultiConnectionAvgSpeed() > min) {
|
||||
bests.push_back(uri);
|
||||
}
|
||||
}
|
||||
return bests;
|
||||
}
|
||||
|
||||
std::string AdaptiveURISelector::selectRandomUri
|
||||
(const std::deque<std::string>& uris) const
|
||||
std::string
|
||||
AdaptiveURISelector::selectRandomUri(const std::deque<std::string>& uris) const
|
||||
{
|
||||
int pos = SimpleRandomizer::getInstance()->getRandomNumber(uris.size());
|
||||
auto i = std::begin(uris);
|
||||
i = i+pos;
|
||||
i = i + pos;
|
||||
return *i;
|
||||
}
|
||||
|
||||
std::string AdaptiveURISelector::getFirstNotTestedUri
|
||||
(const std::deque<std::string>& uris) const
|
||||
std::string AdaptiveURISelector::getFirstNotTestedUri(
|
||||
const std::deque<std::string>& uris) const
|
||||
{
|
||||
for (const auto& i : uris) {
|
||||
std::shared_ptr<ServerStat> ss = getServerStats(i);
|
||||
if(!ss)
|
||||
if (!ss)
|
||||
return i;
|
||||
}
|
||||
return A2STR::NIL;
|
||||
}
|
||||
|
||||
std::string AdaptiveURISelector::getFirstToTestUri
|
||||
(const std::deque<std::string>& uris) const
|
||||
std::string AdaptiveURISelector::getFirstToTestUri(
|
||||
const std::deque<std::string>& uris) const
|
||||
{
|
||||
int counter;
|
||||
int power;
|
||||
for (const auto& u : uris) {
|
||||
std::shared_ptr<ServerStat> ss = getServerStats(u);
|
||||
if(!ss)
|
||||
if (!ss)
|
||||
continue;
|
||||
counter = ss->getCounter();
|
||||
if(counter > 8)
|
||||
if (counter > 8)
|
||||
continue;
|
||||
power = (int)pow(2.0, (float)counter);
|
||||
/* We test the mirror another time if it has not been
|
||||
* tested since 2^counter days */
|
||||
if(ss->getLastUpdated().difference() > std::chrono::hours(power * 24)) {
|
||||
if (ss->getLastUpdated().difference() > std::chrono::hours(power * 24)) {
|
||||
return u;
|
||||
}
|
||||
}
|
||||
return A2STR::NIL;
|
||||
}
|
||||
|
||||
std::shared_ptr<ServerStat> AdaptiveURISelector::getServerStats
|
||||
(const std::string& uri) const
|
||||
std::shared_ptr<ServerStat>
|
||||
AdaptiveURISelector::getServerStats(const std::string& uri) const
|
||||
{
|
||||
uri_split_result us;
|
||||
if(uri_split(&us, uri.c_str()) == 0) {
|
||||
if (uri_split(&us, uri.c_str()) == 0) {
|
||||
std::string host = uri::getFieldString(us, USR_HOST, uri.c_str());
|
||||
std::string protocol = uri::getFieldString(us, USR_SCHEME, uri.c_str());
|
||||
return serverStatMan_->find(host, protocol);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int AdaptiveURISelector::getNbTestedServers
|
||||
(const std::deque<std::string>& uris) const
|
||||
int AdaptiveURISelector::getNbTestedServers(
|
||||
const std::deque<std::string>& uris) const
|
||||
{
|
||||
int counter = 0;
|
||||
for(const auto& u : uris) {
|
||||
for (const auto& u : uris) {
|
||||
std::shared_ptr<ServerStat> ss = getServerStats(u);
|
||||
if(!ss)
|
||||
if (!ss)
|
||||
++counter;
|
||||
}
|
||||
return uris.size() - counter;
|
||||
|
|
|
@ -46,7 +46,7 @@ class ServerStatMan;
|
|||
class RequestGroup;
|
||||
class ServerStat;
|
||||
|
||||
class AdaptiveURISelector:public URISelector {
|
||||
class AdaptiveURISelector : public URISelector {
|
||||
private:
|
||||
std::shared_ptr<ServerStatMan> serverStatMan_;
|
||||
// No need to delete requestGroup_
|
||||
|
@ -69,20 +69,20 @@ private:
|
|||
std::shared_ptr<ServerStat> getServerStats(const std::string& uri) const;
|
||||
int getNbTestedServers(const std::deque<std::string>& uris) const;
|
||||
std::string getBestMirror(const std::deque<std::string>& uris) const;
|
||||
|
||||
public:
|
||||
AdaptiveURISelector(std::shared_ptr<ServerStatMan> serverStatMan,
|
||||
RequestGroup* requestGroup);
|
||||
|
||||
virtual ~AdaptiveURISelector();
|
||||
|
||||
virtual std::string select
|
||||
(FileEntry* fileEntry,
|
||||
const std::vector<std::pair<size_t, std::string> >& usedHosts)
|
||||
CXX11_OVERRIDE;
|
||||
virtual std::string
|
||||
select(FileEntry* fileEntry,
|
||||
const std::vector<std::pair<size_t, std::string>>& usedHosts)
|
||||
CXX11_OVERRIDE;
|
||||
|
||||
virtual void tuneDownloadCommand(const std::deque<std::string>& uris,
|
||||
DownloadCommand* command)
|
||||
CXX11_OVERRIDE;
|
||||
DownloadCommand* command) CXX11_OVERRIDE;
|
||||
|
||||
virtual void resetCounters() CXX11_OVERRIDE;
|
||||
};
|
||||
|
|
|
@ -43,23 +43,18 @@
|
|||
namespace aria2 {
|
||||
|
||||
Adler32MessageDigestImpl::Adler32MessageDigestImpl()
|
||||
: adler_(adler32(0, Z_NULL, 0))
|
||||
{}
|
||||
|
||||
size_t Adler32MessageDigestImpl::getDigestLength() const
|
||||
: adler_(adler32(0, Z_NULL, 0))
|
||||
{
|
||||
return length();
|
||||
}
|
||||
|
||||
void Adler32MessageDigestImpl::reset()
|
||||
{
|
||||
adler_ = adler32(0, Z_NULL, 0);
|
||||
}
|
||||
size_t Adler32MessageDigestImpl::getDigestLength() const { return length(); }
|
||||
|
||||
void Adler32MessageDigestImpl::reset() { adler_ = adler32(0, Z_NULL, 0); }
|
||||
|
||||
void Adler32MessageDigestImpl::update(const void* data, size_t length)
|
||||
{
|
||||
adler_ = adler32(adler_, reinterpret_cast<const unsigned char*>(data),
|
||||
length);
|
||||
adler_ =
|
||||
adler32(adler_, reinterpret_cast<const unsigned char*>(data), length);
|
||||
}
|
||||
|
||||
void Adler32MessageDigestImpl::digest(unsigned char* md)
|
||||
|
@ -68,9 +63,6 @@ void Adler32MessageDigestImpl::digest(unsigned char* md)
|
|||
memcpy(md, &adler, getDigestLength());
|
||||
}
|
||||
|
||||
size_t Adler32MessageDigestImpl::length()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
size_t Adler32MessageDigestImpl::length() { return 4; }
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -41,8 +41,11 @@ namespace aria2 {
|
|||
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
#define ADLER32_MESSAGE_DIGEST \
|
||||
{ "adler32", make_hi<Adler32MessageDigestImpl>() },
|
||||
#define ADLER32_MESSAGE_DIGEST \
|
||||
{ \
|
||||
"adler32", make_hi<Adler32MessageDigestImpl>() \
|
||||
} \
|
||||
,
|
||||
|
||||
class Adler32MessageDigestImpl : public MessageDigestImpl {
|
||||
public:
|
||||
|
@ -52,6 +55,7 @@ public:
|
|||
virtual void update(const void* data, size_t length) CXX11_OVERRIDE;
|
||||
virtual void digest(unsigned char* md) CXX11_OVERRIDE;
|
||||
static size_t length();
|
||||
|
||||
private:
|
||||
unsigned long adler_;
|
||||
};
|
||||
|
|
|
@ -42,64 +42,71 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
AnnounceList::AnnounceList():currentTrackerInitialized_(false) {}
|
||||
AnnounceList::AnnounceList() : currentTrackerInitialized_(false) {}
|
||||
|
||||
AnnounceList::AnnounceList
|
||||
(const std::vector<std::vector<std::string>>& announceList):
|
||||
currentTrackerInitialized_(false) {
|
||||
AnnounceList::AnnounceList(
|
||||
const std::vector<std::vector<std::string>>& announceList)
|
||||
: currentTrackerInitialized_(false)
|
||||
{
|
||||
reconfigure(announceList);
|
||||
}
|
||||
|
||||
AnnounceList::AnnounceList
|
||||
(const std::deque<std::shared_ptr<AnnounceTier>>& announceTiers):
|
||||
tiers_(announceTiers), currentTrackerInitialized_(false) {
|
||||
AnnounceList::AnnounceList(
|
||||
const std::deque<std::shared_ptr<AnnounceTier>>& announceTiers)
|
||||
: tiers_(announceTiers), currentTrackerInitialized_(false)
|
||||
{
|
||||
resetIterator();
|
||||
}
|
||||
|
||||
AnnounceList::~AnnounceList() {}
|
||||
|
||||
void AnnounceList::reconfigure
|
||||
(const std::vector<std::vector<std::string>>& announceList)
|
||||
void AnnounceList::reconfigure(
|
||||
const std::vector<std::vector<std::string>>& announceList)
|
||||
{
|
||||
for (const auto& vec: announceList) {
|
||||
if(vec.empty()) {
|
||||
for (const auto& vec : announceList) {
|
||||
if (vec.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::deque<std::string> uris(std::begin(vec), std::end(vec));
|
||||
auto tier =
|
||||
std::make_shared<AnnounceTier>(std::move(uris));
|
||||
auto tier = std::make_shared<AnnounceTier>(std::move(uris));
|
||||
tiers_.push_back(std::move(tier));
|
||||
}
|
||||
resetIterator();
|
||||
}
|
||||
|
||||
void AnnounceList::reconfigure(const std::string& url) {
|
||||
std::deque<std::string> urls{ url };
|
||||
void AnnounceList::reconfigure(const std::string& url)
|
||||
{
|
||||
std::deque<std::string> urls{url};
|
||||
tiers_.push_back(std::make_shared<AnnounceTier>(std::move(urls)));
|
||||
resetIterator();
|
||||
}
|
||||
|
||||
void AnnounceList::resetIterator() {
|
||||
void AnnounceList::resetIterator()
|
||||
{
|
||||
currentTier_ = std::begin(tiers_);
|
||||
if(currentTier_ != std::end(tiers_) && (*currentTier_)->urls.size()) {
|
||||
if (currentTier_ != std::end(tiers_) && (*currentTier_)->urls.size()) {
|
||||
currentTracker_ = std::begin((*currentTier_)->urls);
|
||||
currentTrackerInitialized_ = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
currentTrackerInitialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string AnnounceList::getAnnounce() const {
|
||||
if(currentTrackerInitialized_) {
|
||||
std::string AnnounceList::getAnnounce() const
|
||||
{
|
||||
if (currentTrackerInitialized_) {
|
||||
return *currentTracker_;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return A2STR::NIL;
|
||||
}
|
||||
}
|
||||
|
||||
void AnnounceList::announceSuccess() {
|
||||
if(currentTrackerInitialized_) {
|
||||
void AnnounceList::announceSuccess()
|
||||
{
|
||||
if (currentTrackerInitialized_) {
|
||||
(*currentTier_)->nextEvent();
|
||||
auto url = *currentTracker_;
|
||||
(*currentTier_)->urls.erase(currentTracker_);
|
||||
|
@ -109,39 +116,45 @@ void AnnounceList::announceSuccess() {
|
|||
}
|
||||
}
|
||||
|
||||
void AnnounceList::announceFailure() {
|
||||
if(currentTrackerInitialized_) {
|
||||
void AnnounceList::announceFailure()
|
||||
{
|
||||
if (currentTrackerInitialized_) {
|
||||
++currentTracker_;
|
||||
if(currentTracker_ == std::end((*currentTier_)->urls)) {
|
||||
if (currentTracker_ == std::end((*currentTier_)->urls)) {
|
||||
// force next event
|
||||
(*currentTier_)->nextEventIfAfterStarted();
|
||||
++currentTier_;
|
||||
if(currentTier_ == std::end(tiers_)) {
|
||||
if (currentTier_ == std::end(tiers_)) {
|
||||
currentTrackerInitialized_ = false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
currentTracker_ = std::begin((*currentTier_)->urls);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnnounceTier::AnnounceEvent AnnounceList::getEvent() const {
|
||||
if(currentTrackerInitialized_) {
|
||||
AnnounceTier::AnnounceEvent AnnounceList::getEvent() const
|
||||
{
|
||||
if (currentTrackerInitialized_) {
|
||||
return (*currentTier_)->event;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return AnnounceTier::STARTED;
|
||||
}
|
||||
}
|
||||
|
||||
void AnnounceList::setEvent(AnnounceTier::AnnounceEvent event) {
|
||||
if(currentTrackerInitialized_) {
|
||||
void AnnounceList::setEvent(AnnounceTier::AnnounceEvent event)
|
||||
{
|
||||
if (currentTrackerInitialized_) {
|
||||
(*currentTier_)->event = event;
|
||||
}
|
||||
}
|
||||
|
||||
const char* AnnounceList::getEventString() const {
|
||||
if(currentTrackerInitialized_) {
|
||||
switch((*currentTier_)->event) {
|
||||
const char* AnnounceList::getEventString() const
|
||||
{
|
||||
if (currentTrackerInitialized_) {
|
||||
switch ((*currentTier_)->event) {
|
||||
case AnnounceTier::STARTED:
|
||||
case AnnounceTier::STARTED_AFTER_COMPLETION:
|
||||
return "started";
|
||||
|
@ -152,7 +165,8 @@ const char* AnnounceList::getEventString() const {
|
|||
default:
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@ -160,8 +174,9 @@ const char* AnnounceList::getEventString() const {
|
|||
namespace {
|
||||
class FindStoppedAllowedTier {
|
||||
public:
|
||||
bool operator()(const std::shared_ptr<AnnounceTier>& tier) const {
|
||||
switch(tier->event) {
|
||||
bool operator()(const std::shared_ptr<AnnounceTier>& tier) const
|
||||
{
|
||||
switch (tier->event) {
|
||||
case AnnounceTier::DOWNLOADING:
|
||||
case AnnounceTier::STOPPED:
|
||||
case AnnounceTier::COMPLETED:
|
||||
|
@ -177,8 +192,9 @@ public:
|
|||
namespace {
|
||||
class FindCompletedAllowedTier {
|
||||
public:
|
||||
bool operator()(const std::shared_ptr<AnnounceTier>& tier) const {
|
||||
switch(tier->event) {
|
||||
bool operator()(const std::shared_ptr<AnnounceTier>& tier) const
|
||||
{
|
||||
switch (tier->event) {
|
||||
case AnnounceTier::DOWNLOADING:
|
||||
case AnnounceTier::COMPLETED:
|
||||
return true;
|
||||
|
@ -189,38 +205,44 @@ public:
|
|||
};
|
||||
} // namespace
|
||||
|
||||
size_t AnnounceList::countStoppedAllowedTier() const {
|
||||
size_t AnnounceList::countStoppedAllowedTier() const
|
||||
{
|
||||
return count_if(std::begin(tiers_), std::end(tiers_),
|
||||
FindStoppedAllowedTier());
|
||||
}
|
||||
|
||||
size_t AnnounceList::countCompletedAllowedTier() const {
|
||||
size_t AnnounceList::countCompletedAllowedTier() const
|
||||
{
|
||||
return count_if(std::begin(tiers_), std::end(tiers_),
|
||||
FindCompletedAllowedTier());
|
||||
}
|
||||
|
||||
void AnnounceList::setCurrentTier
|
||||
(std::deque<std::shared_ptr<AnnounceTier>>::iterator itr) {
|
||||
if(itr != std::end(tiers_)) {
|
||||
void AnnounceList::setCurrentTier(
|
||||
std::deque<std::shared_ptr<AnnounceTier>>::iterator itr)
|
||||
{
|
||||
if (itr != std::end(tiers_)) {
|
||||
currentTier_ = std::move(itr);
|
||||
currentTracker_ = std::begin((*currentTier_)->urls);
|
||||
}
|
||||
}
|
||||
|
||||
void AnnounceList::moveToStoppedAllowedTier() {
|
||||
void AnnounceList::moveToStoppedAllowedTier()
|
||||
{
|
||||
auto itr = find_wrap_if(std::begin(tiers_), std::end(tiers_), currentTier_,
|
||||
FindStoppedAllowedTier());
|
||||
setCurrentTier(std::move(itr));
|
||||
}
|
||||
|
||||
void AnnounceList::moveToCompletedAllowedTier() {
|
||||
void AnnounceList::moveToCompletedAllowedTier()
|
||||
{
|
||||
auto itr = find_wrap_if(std::begin(tiers_), std::end(tiers_), currentTier_,
|
||||
FindCompletedAllowedTier());
|
||||
setCurrentTier(std::move(itr));
|
||||
}
|
||||
|
||||
void AnnounceList::shuffle() {
|
||||
for (const auto& tier: tiers_) {
|
||||
void AnnounceList::shuffle()
|
||||
{
|
||||
for (const auto& tier : tiers_) {
|
||||
auto& urls = tier->urls;
|
||||
std::shuffle(std::begin(urls), std::end(urls),
|
||||
*SimpleRandomizer::getInstance());
|
||||
|
@ -232,14 +254,11 @@ bool AnnounceList::allTiersFailed() const
|
|||
return currentTier_ == std::end(tiers_);
|
||||
}
|
||||
|
||||
void AnnounceList::resetTier()
|
||||
{
|
||||
resetIterator();
|
||||
}
|
||||
void AnnounceList::resetTier() { resetIterator(); }
|
||||
|
||||
bool AnnounceList::currentTierAcceptsStoppedEvent() const
|
||||
{
|
||||
if(currentTrackerInitialized_) {
|
||||
if (currentTrackerInitialized_) {
|
||||
return FindStoppedAllowedTier()(*currentTier_);
|
||||
}
|
||||
|
||||
|
@ -248,16 +267,13 @@ bool AnnounceList::currentTierAcceptsStoppedEvent() const
|
|||
|
||||
bool AnnounceList::currentTierAcceptsCompletedEvent() const
|
||||
{
|
||||
if(currentTrackerInitialized_) {
|
||||
if (currentTrackerInitialized_) {
|
||||
return FindCompletedAllowedTier()(*currentTier_);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t AnnounceList::countTier() const
|
||||
{
|
||||
return tiers_.size();
|
||||
}
|
||||
size_t AnnounceList::countTier() const { return tiers_.size(); }
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -56,8 +56,8 @@ private:
|
|||
bool currentTrackerInitialized_;
|
||||
|
||||
void resetIterator();
|
||||
void setCurrentTier
|
||||
(std::deque<std::shared_ptr<AnnounceTier>>::iterator itr);
|
||||
void setCurrentTier(std::deque<std::shared_ptr<AnnounceTier>>::iterator itr);
|
||||
|
||||
public:
|
||||
AnnounceList();
|
||||
AnnounceList(const std::vector<std::vector<std::string>>& announceList);
|
||||
|
|
|
@ -37,14 +37,15 @@
|
|||
namespace aria2 {
|
||||
|
||||
AnnounceTier::AnnounceTier(std::deque<std::string> urls)
|
||||
: event(STARTED), urls(std::move(urls))
|
||||
{}
|
||||
: event(STARTED), urls(std::move(urls))
|
||||
{
|
||||
}
|
||||
|
||||
AnnounceTier::~AnnounceTier() {}
|
||||
|
||||
void AnnounceTier::nextEvent()
|
||||
{
|
||||
switch(event) {
|
||||
switch (event) {
|
||||
case STARTED:
|
||||
event = DOWNLOADING;
|
||||
break;
|
||||
|
@ -64,7 +65,7 @@ void AnnounceTier::nextEvent()
|
|||
|
||||
void AnnounceTier::nextEventIfAfterStarted()
|
||||
{
|
||||
switch(event) {
|
||||
switch (event) {
|
||||
case STOPPED:
|
||||
event = HALTED;
|
||||
break;
|
||||
|
|
|
@ -42,14 +42,14 @@ namespace aria2 {
|
|||
|
||||
// DiskwriterFactory class template to create DiskWriter derived
|
||||
// object, ignoring filename.
|
||||
template<class DiskWriterType>
|
||||
class AnonDiskWriterFactory:public DiskWriterFactory {
|
||||
template <class DiskWriterType>
|
||||
class AnonDiskWriterFactory : public DiskWriterFactory {
|
||||
public:
|
||||
AnonDiskWriterFactory() {}
|
||||
virtual ~AnonDiskWriterFactory() {}
|
||||
|
||||
virtual std::unique_ptr<DiskWriter> newDiskWriter(const std::string& filename)
|
||||
CXX11_OVERRIDE
|
||||
virtual std::unique_ptr<DiskWriter>
|
||||
newDiskWriter(const std::string& filename) CXX11_OVERRIDE
|
||||
{
|
||||
return make_unique<DiskWriterType>();
|
||||
}
|
||||
|
|
|
@ -37,19 +37,16 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
ApiCallbackDownloadEventListener::ApiCallbackDownloadEventListener
|
||||
(Session* session,
|
||||
DownloadEventCallback callback,
|
||||
void* userData)
|
||||
: session_(session),
|
||||
callback_(callback),
|
||||
userData_(userData)
|
||||
{}
|
||||
ApiCallbackDownloadEventListener::ApiCallbackDownloadEventListener(
|
||||
Session* session, DownloadEventCallback callback, void* userData)
|
||||
: session_(session), callback_(callback), userData_(userData)
|
||||
{
|
||||
}
|
||||
|
||||
ApiCallbackDownloadEventListener::~ApiCallbackDownloadEventListener() {}
|
||||
|
||||
void ApiCallbackDownloadEventListener::onEvent
|
||||
(DownloadEvent event, const RequestGroup* group)
|
||||
void ApiCallbackDownloadEventListener::onEvent(DownloadEvent event,
|
||||
const RequestGroup* group)
|
||||
{
|
||||
callback_(session_, event, group->getGID(), userData_);
|
||||
}
|
||||
|
|
|
@ -45,8 +45,9 @@ public:
|
|||
DownloadEventCallback callback,
|
||||
void* userData);
|
||||
virtual ~ApiCallbackDownloadEventListener();
|
||||
virtual void onEvent(DownloadEvent event, const RequestGroup* group)
|
||||
CXX11_OVERRIDE;
|
||||
virtual void onEvent(DownloadEvent event,
|
||||
const RequestGroup* group) CXX11_OVERRIDE;
|
||||
|
||||
private:
|
||||
Session* session_;
|
||||
DownloadEventCallback callback_;
|
||||
|
|
|
@ -42,77 +42,50 @@
|
|||
namespace aria2 {
|
||||
namespace {
|
||||
|
||||
template<size_t dlen,
|
||||
typename ctx_t,
|
||||
int (*init_fn)(ctx_t*),
|
||||
int (*update_fn)(ctx_t*, const void*, CC_LONG),
|
||||
int(*final_fn)(unsigned char*, ctx_t*)>
|
||||
template <size_t dlen, typename ctx_t, int (*init_fn)(ctx_t*),
|
||||
int (*update_fn)(ctx_t*, const void*, CC_LONG),
|
||||
int (*final_fn)(unsigned char*, ctx_t*)>
|
||||
class MessageDigestBase : public MessageDigestImpl {
|
||||
public:
|
||||
MessageDigestBase() { reset(); }
|
||||
virtual ~MessageDigestBase() {}
|
||||
|
||||
static size_t length() {
|
||||
return dlen;
|
||||
}
|
||||
virtual size_t getDigestLength() const CXX11_OVERRIDE {
|
||||
return dlen;
|
||||
}
|
||||
virtual void reset() CXX11_OVERRIDE {
|
||||
init_fn(&ctx_);
|
||||
}
|
||||
virtual void update(const void* data, size_t length) CXX11_OVERRIDE {
|
||||
static size_t length() { return dlen; }
|
||||
virtual size_t getDigestLength() const CXX11_OVERRIDE { return dlen; }
|
||||
virtual void reset() CXX11_OVERRIDE { init_fn(&ctx_); }
|
||||
virtual void update(const void* data, size_t length) CXX11_OVERRIDE
|
||||
{
|
||||
auto bytes = reinterpret_cast<const char*>(data);
|
||||
while (length) {
|
||||
CC_LONG l = std::min(length, (size_t)std::numeric_limits<uint32_t>::max());
|
||||
CC_LONG l =
|
||||
std::min(length, (size_t)std::numeric_limits<uint32_t>::max());
|
||||
update_fn(&ctx_, bytes, l);
|
||||
length -= l;
|
||||
bytes += l;
|
||||
}
|
||||
}
|
||||
virtual void digest(unsigned char* md) CXX11_OVERRIDE {
|
||||
final_fn(md, &ctx_);
|
||||
}
|
||||
virtual void digest(unsigned char* md) CXX11_OVERRIDE { final_fn(md, &ctx_); }
|
||||
|
||||
private:
|
||||
ctx_t ctx_;
|
||||
};
|
||||
|
||||
typedef MessageDigestBase<CC_MD5_DIGEST_LENGTH,
|
||||
CC_MD5_CTX,
|
||||
CC_MD5_Init,
|
||||
CC_MD5_Update,
|
||||
CC_MD5_Final>
|
||||
MessageDigestMD5;
|
||||
typedef MessageDigestBase<CC_SHA1_DIGEST_LENGTH,
|
||||
CC_SHA1_CTX,
|
||||
CC_SHA1_Init,
|
||||
CC_SHA1_Update,
|
||||
CC_SHA1_Final>
|
||||
MessageDigestSHA1;
|
||||
typedef MessageDigestBase<CC_SHA224_DIGEST_LENGTH,
|
||||
CC_SHA256_CTX,
|
||||
CC_SHA224_Init,
|
||||
CC_SHA224_Update,
|
||||
CC_SHA224_Final>
|
||||
MessageDigestSHA224;
|
||||
typedef MessageDigestBase<CC_SHA256_DIGEST_LENGTH,
|
||||
CC_SHA256_CTX,
|
||||
CC_SHA256_Init,
|
||||
CC_SHA256_Update,
|
||||
CC_SHA256_Final>
|
||||
MessageDigestSHA256;
|
||||
typedef MessageDigestBase<CC_SHA384_DIGEST_LENGTH,
|
||||
CC_SHA512_CTX,
|
||||
CC_SHA384_Init,
|
||||
CC_SHA384_Update,
|
||||
CC_SHA384_Final>
|
||||
MessageDigestSHA384;
|
||||
typedef MessageDigestBase<CC_SHA512_DIGEST_LENGTH,
|
||||
CC_SHA512_CTX,
|
||||
CC_SHA512_Init,
|
||||
CC_SHA512_Update,
|
||||
CC_SHA512_Final>
|
||||
MessageDigestSHA512;
|
||||
typedef MessageDigestBase<CC_MD5_DIGEST_LENGTH, CC_MD5_CTX, CC_MD5_Init,
|
||||
CC_MD5_Update, CC_MD5_Final> MessageDigestMD5;
|
||||
typedef MessageDigestBase<CC_SHA1_DIGEST_LENGTH, CC_SHA1_CTX, CC_SHA1_Init,
|
||||
CC_SHA1_Update, CC_SHA1_Final> MessageDigestSHA1;
|
||||
typedef MessageDigestBase<CC_SHA224_DIGEST_LENGTH, CC_SHA256_CTX,
|
||||
CC_SHA224_Init, CC_SHA224_Update,
|
||||
CC_SHA224_Final> MessageDigestSHA224;
|
||||
typedef MessageDigestBase<CC_SHA256_DIGEST_LENGTH, CC_SHA256_CTX,
|
||||
CC_SHA256_Init, CC_SHA256_Update,
|
||||
CC_SHA256_Final> MessageDigestSHA256;
|
||||
typedef MessageDigestBase<CC_SHA384_DIGEST_LENGTH, CC_SHA512_CTX,
|
||||
CC_SHA384_Init, CC_SHA384_Update,
|
||||
CC_SHA384_Final> MessageDigestSHA384;
|
||||
typedef MessageDigestBase<CC_SHA512_DIGEST_LENGTH, CC_SHA512_CTX,
|
||||
CC_SHA512_Init, CC_SHA512_Update,
|
||||
CC_SHA512_Final> MessageDigestSHA512;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -122,13 +95,12 @@ std::unique_ptr<MessageDigestImpl> MessageDigestImpl::sha1()
|
|||
}
|
||||
|
||||
MessageDigestImpl::hashes_t MessageDigestImpl::hashes = {
|
||||
{ "sha-1", make_hi<MessageDigestSHA1>() },
|
||||
{ "sha-224", make_hi<MessageDigestSHA224>() },
|
||||
{ "sha-256", make_hi<MessageDigestSHA256>() },
|
||||
{ "sha-384", make_hi<MessageDigestSHA384>() },
|
||||
{ "sha-512", make_hi<MessageDigestSHA512>() },
|
||||
{ "md5", make_hi<MessageDigestMD5>() },
|
||||
ADLER32_MESSAGE_DIGEST
|
||||
};
|
||||
{"sha-1", make_hi<MessageDigestSHA1>()},
|
||||
{"sha-224", make_hi<MessageDigestSHA224>()},
|
||||
{"sha-256", make_hi<MessageDigestSHA256>()},
|
||||
{"sha-384", make_hi<MessageDigestSHA384>()},
|
||||
{"sha-512", make_hi<MessageDigestSHA512>()},
|
||||
{"md5", make_hi<MessageDigestMD5>()},
|
||||
ADLER32_MESSAGE_DIGEST};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -56,17 +56,11 @@ using namespace aria2;
|
|||
#if defined(__MAC_10_6)
|
||||
|
||||
#if defined(__MAC_10_7)
|
||||
static const void* query_keys[] = {
|
||||
kSecClass,
|
||||
kSecReturnRef,
|
||||
kSecMatchPolicy,
|
||||
kSecMatchLimit
|
||||
};
|
||||
static const void* query_keys[] = {kSecClass, kSecReturnRef, kSecMatchPolicy,
|
||||
kSecMatchLimit};
|
||||
#endif // defined(__MAC_10_7)
|
||||
|
||||
template <typename T>
|
||||
class CFRef
|
||||
{
|
||||
template <typename T> class CFRef {
|
||||
T ref_;
|
||||
|
||||
public:
|
||||
|
@ -74,10 +68,7 @@ public:
|
|||
|
||||
CFRef(T ref) : ref_(ref) {}
|
||||
|
||||
~CFRef()
|
||||
{
|
||||
reset(nullptr);
|
||||
}
|
||||
~CFRef() { reset(nullptr); }
|
||||
|
||||
void reset(T ref)
|
||||
{
|
||||
|
@ -87,20 +78,11 @@ public:
|
|||
ref_ = ref;
|
||||
}
|
||||
|
||||
T get()
|
||||
{
|
||||
return ref_;
|
||||
}
|
||||
T get() { return ref_; }
|
||||
|
||||
const T get() const
|
||||
{
|
||||
return ref_;
|
||||
}
|
||||
const T get() const { return ref_; }
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return !!ref_;
|
||||
}
|
||||
operator bool() const { return !!ref_; }
|
||||
};
|
||||
|
||||
static inline bool isWhitespace(char c)
|
||||
|
@ -116,8 +98,7 @@ static inline std::string stripWhitespace(std::string str)
|
|||
return str;
|
||||
}
|
||||
|
||||
struct hash_validator
|
||||
{
|
||||
struct hash_validator {
|
||||
const std::string& hash_;
|
||||
|
||||
hash_validator(const std::string& hash) : hash_(hash) {}
|
||||
|
@ -128,14 +109,14 @@ struct hash_validator
|
|||
}
|
||||
};
|
||||
|
||||
struct hash_finder
|
||||
{
|
||||
struct hash_finder {
|
||||
CFDataRef data_;
|
||||
const std::string& hash_;
|
||||
|
||||
hash_finder(CFDataRef data, const std::string& hash)
|
||||
: data_(data), hash_(hash)
|
||||
{}
|
||||
: data_(data), hash_(hash)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool operator()(std::string type) const
|
||||
{
|
||||
|
@ -163,8 +144,7 @@ std::string errToString(OSStatus err)
|
|||
return rv;
|
||||
}
|
||||
|
||||
bool checkIdentity(const SecIdentityRef id,
|
||||
const std::string& fingerPrint,
|
||||
bool checkIdentity(const SecIdentityRef id, const std::string& fingerPrint,
|
||||
const std::vector<std::string> supported)
|
||||
{
|
||||
CFRef<SecCertificateRef> ref;
|
||||
|
@ -235,10 +215,7 @@ bool AppleTLSContext::addTrustedCACertFile(const std::string& certfile)
|
|||
return false;
|
||||
}
|
||||
|
||||
SecIdentityRef AppleTLSContext::getCredentials()
|
||||
{
|
||||
return credentials_;
|
||||
}
|
||||
SecIdentityRef AppleTLSContext::getCredentials() { return credentials_; }
|
||||
|
||||
bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
||||
{
|
||||
|
@ -264,12 +241,8 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
|||
A2_LOG_ERROR("Failed to create SecPolicy");
|
||||
return false;
|
||||
}
|
||||
const void* query_values[] = {
|
||||
kSecClassIdentity,
|
||||
kCFBooleanTrue,
|
||||
policy.get(),
|
||||
kSecMatchLimitAll
|
||||
};
|
||||
const void* query_values[] = {kSecClassIdentity, kCFBooleanTrue, policy.get(),
|
||||
kSecMatchLimitAll};
|
||||
CFRef<CFDictionaryRef> query(CFDictionaryCreate(
|
||||
nullptr, query_keys, query_values, 4, nullptr, nullptr));
|
||||
if (!query) {
|
||||
|
@ -372,18 +345,12 @@ bool AppleTLSContext::tryAsPKCS12(CFDataRef data, const char* password)
|
|||
#if defined(__MAC_10_6)
|
||||
CFRef<CFStringRef> passwordRef;
|
||||
if (password) {
|
||||
passwordRef.reset(CFStringCreateWithBytes(nullptr,
|
||||
(const UInt8*)password,
|
||||
passwordRef.reset(CFStringCreateWithBytes(nullptr, (const UInt8*)password,
|
||||
strlen(password),
|
||||
kCFStringEncodingUTF8,
|
||||
false));
|
||||
kCFStringEncodingUTF8, false));
|
||||
}
|
||||
const void* keys[] = {
|
||||
kSecImportExportPassphrase
|
||||
};
|
||||
const void* values[] = {
|
||||
passwordRef.get()
|
||||
};
|
||||
const void* keys[] = {kSecImportExportPassphrase};
|
||||
const void* values[] = {passwordRef.get()};
|
||||
CFRef<CFDictionaryRef> options(
|
||||
CFDictionaryCreate(nullptr, keys, values, 1, nullptr, nullptr));
|
||||
if (!options) {
|
||||
|
|
|
@ -46,12 +46,12 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
class AppleTLSContext : public TLSContext
|
||||
{
|
||||
class AppleTLSContext : public TLSContext {
|
||||
public:
|
||||
AppleTLSContext(TLSSessionSide side, TLSVersion ver)
|
||||
: side_(side), minTLSVer_(ver), verifyPeer_(true), credentials_(nullptr)
|
||||
{}
|
||||
: side_(side), minTLSVer_(ver), verifyPeer_(true), credentials_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~AppleTLSContext();
|
||||
|
||||
|
@ -59,28 +59,16 @@ public:
|
|||
virtual bool addCredentialFile(const std::string& certfile,
|
||||
const std::string& keyfile) CXX11_OVERRIDE;
|
||||
|
||||
virtual bool addSystemTrustedCACerts() CXX11_OVERRIDE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool addSystemTrustedCACerts() CXX11_OVERRIDE { return true; }
|
||||
|
||||
// certfile can contain multiple certificates.
|
||||
virtual bool addTrustedCACertFile(const std::string& certfile) CXX11_OVERRIDE;
|
||||
|
||||
virtual bool good() const CXX11_OVERRIDE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool good() const CXX11_OVERRIDE { return true; }
|
||||
|
||||
virtual TLSSessionSide getSide() const CXX11_OVERRIDE
|
||||
{
|
||||
return side_;
|
||||
}
|
||||
virtual TLSSessionSide getSide() const CXX11_OVERRIDE { return side_; }
|
||||
|
||||
virtual bool getVerifyPeer() const CXX11_OVERRIDE
|
||||
{
|
||||
return verifyPeer_;
|
||||
}
|
||||
virtual bool getVerifyPeer() const CXX11_OVERRIDE { return verifyPeer_; }
|
||||
|
||||
virtual void setVerifyPeer(bool verify) CXX11_OVERRIDE
|
||||
{
|
||||
|
@ -89,10 +77,7 @@ public:
|
|||
|
||||
SecIdentityRef getCredentials();
|
||||
|
||||
TLSVersion getMinTLSVersion() const
|
||||
{
|
||||
return minTLSVer_;
|
||||
}
|
||||
TLSVersion getMinTLSVersion() const { return minTLSVer_; }
|
||||
|
||||
private:
|
||||
TLSSessionSide side_;
|
||||
|
|
|
@ -101,172 +101,168 @@ static inline const char* protoToString(SSLProtocol proto)
|
|||
{ \
|
||||
n, #s \
|
||||
}
|
||||
static struct
|
||||
{
|
||||
static struct {
|
||||
SSLCipherSuite suite;
|
||||
const char* name;
|
||||
} kSuites[] = {
|
||||
// From CipherSuite.h (10.9)
|
||||
SUITE(SSL_NULL_WITH_NULL_NULL, 0x0000),
|
||||
SUITE(SSL_RSA_WITH_NULL_MD5, 0x0001),
|
||||
SUITE(SSL_RSA_WITH_NULL_SHA, 0x0002),
|
||||
SUITE(SSL_RSA_EXPORT_WITH_RC4_40_MD5, 0x0003),
|
||||
SUITE(SSL_RSA_WITH_RC4_128_MD5, 0x0004),
|
||||
SUITE(SSL_RSA_WITH_RC4_128_SHA, 0x0005),
|
||||
SUITE(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0x0006),
|
||||
SUITE(SSL_RSA_WITH_IDEA_CBC_SHA, 0x0007),
|
||||
SUITE(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0008),
|
||||
SUITE(SSL_RSA_WITH_DES_CBC_SHA, 0x0009),
|
||||
SUITE(SSL_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
|
||||
SUITE(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x000B),
|
||||
SUITE(SSL_DH_DSS_WITH_DES_CBC_SHA, 0x000C),
|
||||
SUITE(SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
|
||||
SUITE(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x000E),
|
||||
SUITE(SSL_DH_RSA_WITH_DES_CBC_SHA, 0x000F),
|
||||
SUITE(SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
|
||||
SUITE(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x0011),
|
||||
SUITE(SSL_DHE_DSS_WITH_DES_CBC_SHA, 0x0012),
|
||||
SUITE(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
|
||||
SUITE(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0014),
|
||||
SUITE(SSL_DHE_RSA_WITH_DES_CBC_SHA, 0x0015),
|
||||
SUITE(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
|
||||
SUITE(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 0x0017),
|
||||
SUITE(SSL_DH_anon_WITH_RC4_128_MD5, 0x0018),
|
||||
SUITE(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 0x0019),
|
||||
SUITE(SSL_DH_anon_WITH_DES_CBC_SHA, 0x001A),
|
||||
SUITE(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
|
||||
SUITE(SSL_FORTEZZA_DMS_WITH_NULL_SHA, 0x001C),
|
||||
SUITE(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, 0x001D),
|
||||
SUITE(TLS_RSA_WITH_AES_128_CBC_SHA, 0x002F),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA, 0x0030),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA, 0x0031),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 0x0032),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 0x0033),
|
||||
SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA, 0x0034),
|
||||
SUITE(TLS_RSA_WITH_AES_256_CBC_SHA, 0x0035),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA, 0x0036),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA, 0x0037),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 0x0038),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 0x0039),
|
||||
SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA, 0x003A),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_NULL_SHA, 0xC001),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, 0xC002),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC003),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, 0xC004),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, 0xC005),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_NULL_SHA, 0xC006),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 0xC007),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC008),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 0xC009),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 0xC00A),
|
||||
SUITE(TLS_ECDH_RSA_WITH_NULL_SHA, 0xC00B),
|
||||
SUITE(TLS_ECDH_RSA_WITH_RC4_128_SHA, 0xC00C),
|
||||
SUITE(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, 0xC00D),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, 0xC00E),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, 0xC00F),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_NULL_SHA, 0xC010),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_RC4_128_SHA, 0xC011),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 0xC012),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0xC013),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0xC014),
|
||||
SUITE(TLS_ECDH_anon_WITH_NULL_SHA, 0xC015),
|
||||
SUITE(TLS_ECDH_anon_WITH_RC4_128_SHA, 0xC016),
|
||||
SUITE(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, 0xC017),
|
||||
SUITE(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, 0xC018),
|
||||
SUITE(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, 0xC019),
|
||||
SUITE(TLS_NULL_WITH_NULL_NULL, 0x0000),
|
||||
SUITE(TLS_RSA_WITH_NULL_MD5, 0x0001),
|
||||
SUITE(TLS_RSA_WITH_NULL_SHA, 0x0002),
|
||||
SUITE(TLS_RSA_WITH_RC4_128_MD5, 0x0004),
|
||||
SUITE(TLS_RSA_WITH_RC4_128_SHA, 0x0005),
|
||||
SUITE(TLS_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
|
||||
SUITE(TLS_RSA_WITH_NULL_SHA256, 0x003B),
|
||||
SUITE(TLS_RSA_WITH_AES_128_CBC_SHA256, 0x003C),
|
||||
SUITE(TLS_RSA_WITH_AES_256_CBC_SHA256, 0x003D),
|
||||
SUITE(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
|
||||
SUITE(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
|
||||
SUITE(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
|
||||
SUITE(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, 0x003E),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, 0x003F),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, 0x0040),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 0x0067),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, 0x0068),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, 0x0069),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 0x006A),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 0x006B),
|
||||
SUITE(TLS_DH_anon_WITH_RC4_128_MD5, 0x0018),
|
||||
SUITE(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
|
||||
SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA256, 0x006C),
|
||||
SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA256, 0x006D),
|
||||
SUITE(TLS_PSK_WITH_RC4_128_SHA, 0x008A),
|
||||
SUITE(TLS_PSK_WITH_3DES_EDE_CBC_SHA, 0x008B),
|
||||
SUITE(TLS_PSK_WITH_AES_128_CBC_SHA, 0x008C),
|
||||
SUITE(TLS_PSK_WITH_AES_256_CBC_SHA, 0x008D),
|
||||
SUITE(TLS_DHE_PSK_WITH_RC4_128_SHA, 0x008E),
|
||||
SUITE(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, 0x008F),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, 0x0090),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, 0x0091),
|
||||
SUITE(TLS_RSA_PSK_WITH_RC4_128_SHA, 0x0092),
|
||||
SUITE(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, 0x0093),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, 0x0094),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, 0x0095),
|
||||
SUITE(TLS_PSK_WITH_NULL_SHA, 0x002C),
|
||||
SUITE(TLS_DHE_PSK_WITH_NULL_SHA, 0x002D),
|
||||
SUITE(TLS_RSA_PSK_WITH_NULL_SHA, 0x002E),
|
||||
SUITE(TLS_RSA_WITH_AES_128_GCM_SHA256, 0x009C),
|
||||
SUITE(TLS_RSA_WITH_AES_256_GCM_SHA384, 0x009D),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0x009E),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 0x009F),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, 0x00A0),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, 0x00A1),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, 0x00A2),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, 0x00A3),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, 0x00A4),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, 0x00A5),
|
||||
SUITE(TLS_DH_anon_WITH_AES_128_GCM_SHA256, 0x00A6),
|
||||
SUITE(TLS_DH_anon_WITH_AES_256_GCM_SHA384, 0x00A7),
|
||||
SUITE(TLS_PSK_WITH_AES_128_GCM_SHA256, 0x00A8),
|
||||
SUITE(TLS_PSK_WITH_AES_256_GCM_SHA384, 0x00A9),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, 0x00AA),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, 0x00AB),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, 0x00AC),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, 0x00AD),
|
||||
SUITE(TLS_PSK_WITH_AES_128_CBC_SHA256, 0x00AE),
|
||||
SUITE(TLS_PSK_WITH_AES_256_CBC_SHA384, 0x00AF),
|
||||
SUITE(TLS_PSK_WITH_NULL_SHA256, 0x00B0),
|
||||
SUITE(TLS_PSK_WITH_NULL_SHA384, 0x00B1),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, 0x00B2),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, 0x00B3),
|
||||
SUITE(TLS_DHE_PSK_WITH_NULL_SHA256, 0x00B4),
|
||||
SUITE(TLS_DHE_PSK_WITH_NULL_SHA384, 0x00B5),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, 0x00B6),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, 0x00B7),
|
||||
SUITE(TLS_RSA_PSK_WITH_NULL_SHA256, 0x00B8),
|
||||
SUITE(TLS_RSA_PSK_WITH_NULL_SHA384, 0x00B9),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 0xC023),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 0xC024),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, 0xC025),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, 0xC026),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0xC027),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 0xC028),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, 0xC029),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, 0xC02A),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02B),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02C),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02D),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02E),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0xC02F),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0xC030),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, 0xC031),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, 0xC032),
|
||||
SUITE(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, 0x00FF),
|
||||
SUITE(SSL_RSA_WITH_RC2_CBC_MD5, 0xFF80),
|
||||
SUITE(SSL_RSA_WITH_IDEA_CBC_MD5, 0xFF81),
|
||||
SUITE(SSL_RSA_WITH_DES_CBC_MD5, 0xFF82),
|
||||
SUITE(SSL_RSA_WITH_3DES_EDE_CBC_MD5, 0xFF83),
|
||||
SUITE(SSL_NO_SUCH_CIPHERSUITE, 0xFFFF)
|
||||
};
|
||||
// From CipherSuite.h (10.9)
|
||||
SUITE(SSL_NULL_WITH_NULL_NULL, 0x0000),
|
||||
SUITE(SSL_RSA_WITH_NULL_MD5, 0x0001), SUITE(SSL_RSA_WITH_NULL_SHA, 0x0002),
|
||||
SUITE(SSL_RSA_EXPORT_WITH_RC4_40_MD5, 0x0003),
|
||||
SUITE(SSL_RSA_WITH_RC4_128_MD5, 0x0004),
|
||||
SUITE(SSL_RSA_WITH_RC4_128_SHA, 0x0005),
|
||||
SUITE(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0x0006),
|
||||
SUITE(SSL_RSA_WITH_IDEA_CBC_SHA, 0x0007),
|
||||
SUITE(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0008),
|
||||
SUITE(SSL_RSA_WITH_DES_CBC_SHA, 0x0009),
|
||||
SUITE(SSL_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
|
||||
SUITE(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x000B),
|
||||
SUITE(SSL_DH_DSS_WITH_DES_CBC_SHA, 0x000C),
|
||||
SUITE(SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
|
||||
SUITE(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x000E),
|
||||
SUITE(SSL_DH_RSA_WITH_DES_CBC_SHA, 0x000F),
|
||||
SUITE(SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
|
||||
SUITE(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 0x0011),
|
||||
SUITE(SSL_DHE_DSS_WITH_DES_CBC_SHA, 0x0012),
|
||||
SUITE(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
|
||||
SUITE(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 0x0014),
|
||||
SUITE(SSL_DHE_RSA_WITH_DES_CBC_SHA, 0x0015),
|
||||
SUITE(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
|
||||
SUITE(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 0x0017),
|
||||
SUITE(SSL_DH_anon_WITH_RC4_128_MD5, 0x0018),
|
||||
SUITE(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 0x0019),
|
||||
SUITE(SSL_DH_anon_WITH_DES_CBC_SHA, 0x001A),
|
||||
SUITE(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
|
||||
SUITE(SSL_FORTEZZA_DMS_WITH_NULL_SHA, 0x001C),
|
||||
SUITE(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, 0x001D),
|
||||
SUITE(TLS_RSA_WITH_AES_128_CBC_SHA, 0x002F),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA, 0x0030),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA, 0x0031),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 0x0032),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 0x0033),
|
||||
SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA, 0x0034),
|
||||
SUITE(TLS_RSA_WITH_AES_256_CBC_SHA, 0x0035),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA, 0x0036),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA, 0x0037),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 0x0038),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 0x0039),
|
||||
SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA, 0x003A),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_NULL_SHA, 0xC001),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, 0xC002),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC003),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, 0xC004),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, 0xC005),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_NULL_SHA, 0xC006),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 0xC007),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, 0xC008),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 0xC009),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 0xC00A),
|
||||
SUITE(TLS_ECDH_RSA_WITH_NULL_SHA, 0xC00B),
|
||||
SUITE(TLS_ECDH_RSA_WITH_RC4_128_SHA, 0xC00C),
|
||||
SUITE(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, 0xC00D),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, 0xC00E),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, 0xC00F),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_NULL_SHA, 0xC010),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_RC4_128_SHA, 0xC011),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 0xC012),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0xC013),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0xC014),
|
||||
SUITE(TLS_ECDH_anon_WITH_NULL_SHA, 0xC015),
|
||||
SUITE(TLS_ECDH_anon_WITH_RC4_128_SHA, 0xC016),
|
||||
SUITE(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, 0xC017),
|
||||
SUITE(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, 0xC018),
|
||||
SUITE(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, 0xC019),
|
||||
SUITE(TLS_NULL_WITH_NULL_NULL, 0x0000),
|
||||
SUITE(TLS_RSA_WITH_NULL_MD5, 0x0001), SUITE(TLS_RSA_WITH_NULL_SHA, 0x0002),
|
||||
SUITE(TLS_RSA_WITH_RC4_128_MD5, 0x0004),
|
||||
SUITE(TLS_RSA_WITH_RC4_128_SHA, 0x0005),
|
||||
SUITE(TLS_RSA_WITH_3DES_EDE_CBC_SHA, 0x000A),
|
||||
SUITE(TLS_RSA_WITH_NULL_SHA256, 0x003B),
|
||||
SUITE(TLS_RSA_WITH_AES_128_CBC_SHA256, 0x003C),
|
||||
SUITE(TLS_RSA_WITH_AES_256_CBC_SHA256, 0x003D),
|
||||
SUITE(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, 0x000D),
|
||||
SUITE(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, 0x0010),
|
||||
SUITE(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 0x0013),
|
||||
SUITE(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 0x0016),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, 0x003E),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, 0x003F),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, 0x0040),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 0x0067),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, 0x0068),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, 0x0069),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 0x006A),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 0x006B),
|
||||
SUITE(TLS_DH_anon_WITH_RC4_128_MD5, 0x0018),
|
||||
SUITE(TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, 0x001B),
|
||||
SUITE(TLS_DH_anon_WITH_AES_128_CBC_SHA256, 0x006C),
|
||||
SUITE(TLS_DH_anon_WITH_AES_256_CBC_SHA256, 0x006D),
|
||||
SUITE(TLS_PSK_WITH_RC4_128_SHA, 0x008A),
|
||||
SUITE(TLS_PSK_WITH_3DES_EDE_CBC_SHA, 0x008B),
|
||||
SUITE(TLS_PSK_WITH_AES_128_CBC_SHA, 0x008C),
|
||||
SUITE(TLS_PSK_WITH_AES_256_CBC_SHA, 0x008D),
|
||||
SUITE(TLS_DHE_PSK_WITH_RC4_128_SHA, 0x008E),
|
||||
SUITE(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, 0x008F),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, 0x0090),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, 0x0091),
|
||||
SUITE(TLS_RSA_PSK_WITH_RC4_128_SHA, 0x0092),
|
||||
SUITE(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, 0x0093),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, 0x0094),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, 0x0095),
|
||||
SUITE(TLS_PSK_WITH_NULL_SHA, 0x002C),
|
||||
SUITE(TLS_DHE_PSK_WITH_NULL_SHA, 0x002D),
|
||||
SUITE(TLS_RSA_PSK_WITH_NULL_SHA, 0x002E),
|
||||
SUITE(TLS_RSA_WITH_AES_128_GCM_SHA256, 0x009C),
|
||||
SUITE(TLS_RSA_WITH_AES_256_GCM_SHA384, 0x009D),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 0x009E),
|
||||
SUITE(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 0x009F),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, 0x00A0),
|
||||
SUITE(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, 0x00A1),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, 0x00A2),
|
||||
SUITE(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, 0x00A3),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, 0x00A4),
|
||||
SUITE(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, 0x00A5),
|
||||
SUITE(TLS_DH_anon_WITH_AES_128_GCM_SHA256, 0x00A6),
|
||||
SUITE(TLS_DH_anon_WITH_AES_256_GCM_SHA384, 0x00A7),
|
||||
SUITE(TLS_PSK_WITH_AES_128_GCM_SHA256, 0x00A8),
|
||||
SUITE(TLS_PSK_WITH_AES_256_GCM_SHA384, 0x00A9),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, 0x00AA),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, 0x00AB),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, 0x00AC),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, 0x00AD),
|
||||
SUITE(TLS_PSK_WITH_AES_128_CBC_SHA256, 0x00AE),
|
||||
SUITE(TLS_PSK_WITH_AES_256_CBC_SHA384, 0x00AF),
|
||||
SUITE(TLS_PSK_WITH_NULL_SHA256, 0x00B0),
|
||||
SUITE(TLS_PSK_WITH_NULL_SHA384, 0x00B1),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, 0x00B2),
|
||||
SUITE(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, 0x00B3),
|
||||
SUITE(TLS_DHE_PSK_WITH_NULL_SHA256, 0x00B4),
|
||||
SUITE(TLS_DHE_PSK_WITH_NULL_SHA384, 0x00B5),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, 0x00B6),
|
||||
SUITE(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, 0x00B7),
|
||||
SUITE(TLS_RSA_PSK_WITH_NULL_SHA256, 0x00B8),
|
||||
SUITE(TLS_RSA_PSK_WITH_NULL_SHA384, 0x00B9),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 0xC023),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 0xC024),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, 0xC025),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, 0xC026),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0xC027),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 0xC028),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, 0xC029),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, 0xC02A),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02B),
|
||||
SUITE(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02C),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, 0xC02D),
|
||||
SUITE(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, 0xC02E),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0xC02F),
|
||||
SUITE(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0xC030),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, 0xC031),
|
||||
SUITE(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, 0xC032),
|
||||
SUITE(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, 0x00FF),
|
||||
SUITE(SSL_RSA_WITH_RC2_CBC_MD5, 0xFF80),
|
||||
SUITE(SSL_RSA_WITH_IDEA_CBC_MD5, 0xFF81),
|
||||
SUITE(SSL_RSA_WITH_DES_CBC_MD5, 0xFF82),
|
||||
SUITE(SSL_RSA_WITH_3DES_EDE_CBC_MD5, 0xFF83),
|
||||
SUITE(SSL_NO_SUCH_CIPHERSUITE, 0xFFFF)};
|
||||
#undef SUITE
|
||||
|
||||
static inline std::string suiteToString(const SSLCipherSuite suite)
|
||||
|
@ -283,9 +279,8 @@ static inline std::string suiteToString(const SSLCipherSuite suite)
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
static const char* kBlocked[] = {
|
||||
"NULL", "anon", "MD5", "EXPORT", "DES", "IDEA", "NO_SUCH", "EMPTY", "PSK"
|
||||
};
|
||||
static const char* kBlocked[] = {"NULL", "anon", "MD5", "EXPORT", "DES",
|
||||
"IDEA", "NO_SUCH", "EMPTY", "PSK"};
|
||||
|
||||
static inline bool isBlockedSuite(SSLCipherSuite suite)
|
||||
{
|
||||
|
@ -309,7 +304,7 @@ static SSLCipherSuiteList constructEnabledSuites(SSLContextRef ctx)
|
|||
#ifndef CIPHER_CONSTRUCT_ALWAYS
|
||||
static
|
||||
#endif
|
||||
SSLCipherSuiteList rv(0);
|
||||
SSLCipherSuiteList rv(0);
|
||||
|
||||
#ifndef CIPHER_CONSTRUCT_ALWAYS
|
||||
if (!rv.empty()) {
|
||||
|
@ -345,17 +340,16 @@ TLSSession* TLSSession::make(TLSContext* ctx)
|
|||
}
|
||||
|
||||
AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
||||
: sslCtx_(nullptr),
|
||||
sockfd_(0),
|
||||
state_(st_constructed),
|
||||
lastError_(noErr),
|
||||
writeBuffered_(0)
|
||||
: sslCtx_(nullptr),
|
||||
sockfd_(0),
|
||||
state_(st_constructed),
|
||||
lastError_(noErr),
|
||||
writeBuffered_(0)
|
||||
{
|
||||
#if defined(__MAC_10_8)
|
||||
sslCtx_ = SSLCreateContext(nullptr,
|
||||
ctx->getSide() == TLS_SERVER ? kSSLServerSide :
|
||||
kSSLClientSide,
|
||||
kSSLStreamType);
|
||||
sslCtx_ = SSLCreateContext(
|
||||
nullptr, ctx->getSide() == TLS_SERVER ? kSSLServerSide : kSSLClientSide,
|
||||
kSSLStreamType);
|
||||
lastError_ = sslCtx_ ? noErr : paramErr;
|
||||
#else
|
||||
lastError_ = SSLNewContext(ctx->getSide() == TLS_SERVER, &sslCtx_);
|
||||
|
@ -388,13 +382,13 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
|||
switch (ctx->getMinTLSVersion()) {
|
||||
case TLS_PROTO_SSL3:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kSSLProtocol3, true);
|
||||
// fall through
|
||||
// fall through
|
||||
case TLS_PROTO_TLS10:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol1, true);
|
||||
// fall through
|
||||
// fall through
|
||||
case TLS_PROTO_TLS11:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol11, true);
|
||||
// fall through
|
||||
// fall through
|
||||
case TLS_PROTO_TLS12:
|
||||
(void)SSLSetProtocolVersionEnabled(sslCtx_, kTLSProtocol12, true);
|
||||
default:
|
||||
|
@ -414,8 +408,8 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
|||
#if defined(__MAC_10_8)
|
||||
if (!ctx->getVerifyPeer()) {
|
||||
// This disables client verification
|
||||
(void)SSLSetSessionOption(
|
||||
sslCtx_, kSSLSessionOptionBreakOnServerAuth, true);
|
||||
(void)SSLSetSessionOption(sslCtx_, kSSLSessionOptionBreakOnServerAuth,
|
||||
true);
|
||||
}
|
||||
#else
|
||||
(void)SSLSetEnableCertVerify(sslCtx_, ctx->getVerifyPeer());
|
||||
|
@ -700,8 +694,7 @@ OSStatus AppleTLSSession::sockRead(void* data, size_t* len)
|
|||
}
|
||||
|
||||
int AppleTLSSession::tlsConnect(const std::string& hostname,
|
||||
TLSVersion& version,
|
||||
std::string& handshakeErr)
|
||||
TLSVersion& version, std::string& handshakeErr)
|
||||
{
|
||||
if (state_ != st_initialized) {
|
||||
return TLS_ERR_ERROR;
|
||||
|
@ -733,27 +726,25 @@ int AppleTLSSession::tlsConnect(const std::string& hostname,
|
|||
(void)SSLGetNegotiatedProtocolVersion(sslCtx_, &proto);
|
||||
SSLCipherSuite suite = SSL_NO_SUCH_CIPHERSUITE;
|
||||
(void)SSLGetNegotiatedCipher(sslCtx_, &suite);
|
||||
A2_LOG_INFO(fmt("AppleTLS: Connected to %s with %s (%s)",
|
||||
hostname.c_str(),
|
||||
protoToString(proto),
|
||||
suiteToString(suite).c_str()));
|
||||
A2_LOG_INFO(fmt("AppleTLS: Connected to %s with %s (%s)", hostname.c_str(),
|
||||
protoToString(proto), suiteToString(suite).c_str()));
|
||||
|
||||
switch (proto) {
|
||||
case kSSLProtocol3:
|
||||
version = TLS_PROTO_SSL3;
|
||||
break;
|
||||
case kTLSProtocol1:
|
||||
version = TLS_PROTO_TLS10;
|
||||
break;
|
||||
case kTLSProtocol11:
|
||||
version = TLS_PROTO_TLS11;
|
||||
break;
|
||||
case kTLSProtocol12:
|
||||
version = TLS_PROTO_TLS12;
|
||||
break;
|
||||
default:
|
||||
version = TLS_PROTO_NONE;
|
||||
break;
|
||||
case kSSLProtocol3:
|
||||
version = TLS_PROTO_SSL3;
|
||||
break;
|
||||
case kTLSProtocol1:
|
||||
version = TLS_PROTO_TLS10;
|
||||
break;
|
||||
case kTLSProtocol11:
|
||||
version = TLS_PROTO_TLS11;
|
||||
break;
|
||||
case kTLSProtocol12:
|
||||
version = TLS_PROTO_TLS12;
|
||||
break;
|
||||
default:
|
||||
version = TLS_PROTO_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
return TLS_ERR_OK;
|
||||
|
|
|
@ -41,8 +41,7 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
class AppleTLSSession : public TLSSession
|
||||
{
|
||||
class AppleTLSSession : public TLSSession {
|
||||
enum state_t {
|
||||
st_constructed,
|
||||
st_initialized,
|
||||
|
@ -95,8 +94,7 @@ public:
|
|||
// if the underlying transport blocks, or TLS_ERR_ERROR.
|
||||
// When returning TLS_ERR_ERROR, provide certificate validation error
|
||||
// in |handshakeErr|.
|
||||
virtual int tlsConnect(const std::string& hostname,
|
||||
TLSVersion& version,
|
||||
virtual int tlsConnect(const std::string& hostname, TLSVersion& version,
|
||||
std::string& handshakeErr) CXX11_OVERRIDE;
|
||||
|
||||
// Performs server side handshake. This function returns TLS_ERR_OK
|
||||
|
@ -108,8 +106,8 @@ public:
|
|||
virtual std::string getLastErrorString() CXX11_OVERRIDE;
|
||||
|
||||
private:
|
||||
static OSStatus
|
||||
SocketWrite(SSLConnectionRef conn, const void* data, size_t* len)
|
||||
static OSStatus SocketWrite(SSLConnectionRef conn, const void* data,
|
||||
size_t* len)
|
||||
{
|
||||
return ((AppleTLSSession*)conn)->sockWrite(data, len);
|
||||
}
|
||||
|
|
|
@ -46,50 +46,47 @@ namespace aria2 {
|
|||
void callback(void* arg, int status, int timeouts, struct hostent* host)
|
||||
{
|
||||
AsyncNameResolver* resolverPtr = reinterpret_cast<AsyncNameResolver*>(arg);
|
||||
if(status != ARES_SUCCESS) {
|
||||
if (status != ARES_SUCCESS) {
|
||||
resolverPtr->error_ = ares_strerror(status);
|
||||
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
|
||||
return;
|
||||
}
|
||||
for(char** ap = host->h_addr_list; *ap; ++ap) {
|
||||
for (char** ap = host->h_addr_list; *ap; ++ap) {
|
||||
char addrstring[NI_MAXHOST];
|
||||
if(inetNtop(host->h_addrtype, *ap, addrstring, sizeof(addrstring)) == 0) {
|
||||
if (inetNtop(host->h_addrtype, *ap, addrstring, sizeof(addrstring)) == 0) {
|
||||
resolverPtr->resolvedAddresses_.push_back(addrstring);
|
||||
}
|
||||
}
|
||||
if(resolverPtr->resolvedAddresses_.empty()) {
|
||||
if (resolverPtr->resolvedAddresses_.empty()) {
|
||||
resolverPtr->error_ = "no address returned or address conversion failed";
|
||||
resolverPtr->status_ = AsyncNameResolver::STATUS_ERROR;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
resolverPtr->status_ = AsyncNameResolver::STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncNameResolver::AsyncNameResolver
|
||||
(int family
|
||||
AsyncNameResolver::AsyncNameResolver(int family
|
||||
#ifdef HAVE_ARES_ADDR_NODE
|
||||
, ares_addr_node* servers
|
||||
,
|
||||
ares_addr_node* servers
|
||||
#endif // HAVE_ARES_ADDR_NODE
|
||||
)
|
||||
: status_(STATUS_READY),
|
||||
family_(family)
|
||||
)
|
||||
: status_(STATUS_READY), family_(family)
|
||||
{
|
||||
// TODO evaluate return value
|
||||
ares_init(&channel_);
|
||||
#if defined(HAVE_ARES_SET_SERVERS) && defined(HAVE_ARES_ADDR_NODE)
|
||||
if(servers) {
|
||||
if (servers) {
|
||||
// ares_set_servers has been added since c-ares 1.7.1
|
||||
if(ares_set_servers(channel_, servers) != ARES_SUCCESS) {
|
||||
if (ares_set_servers(channel_, servers) != ARES_SUCCESS) {
|
||||
A2_LOG_DEBUG("ares_set_servers failed");
|
||||
}
|
||||
}
|
||||
#endif // HAVE_ARES_SET_SERVERS && HAVE_ARES_ADDR_NODE
|
||||
}
|
||||
|
||||
AsyncNameResolver::~AsyncNameResolver()
|
||||
{
|
||||
ares_destroy(channel_);
|
||||
}
|
||||
AsyncNameResolver::~AsyncNameResolver() { ares_destroy(channel_); }
|
||||
|
||||
void AsyncNameResolver::resolve(const std::string& name)
|
||||
{
|
||||
|
@ -148,11 +145,11 @@ ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt)
|
|||
ares_addr_node root;
|
||||
root.next = nullptr;
|
||||
ares_addr_node* tail = &root;
|
||||
for (const auto& s: servers) {
|
||||
for (const auto& s : servers) {
|
||||
auto node = make_unique<ares_addr_node>();
|
||||
|
||||
size_t len = net::getBinAddr(&node->addr, s.c_str());
|
||||
if(len != 0) {
|
||||
if (len != 0) {
|
||||
node->next = nullptr;
|
||||
node->family = (len == 4 ? AF_INET : AF_INET6);
|
||||
tail->next = node.release();
|
||||
|
|
|
@ -47,8 +47,9 @@
|
|||
namespace aria2 {
|
||||
|
||||
class AsyncNameResolver {
|
||||
friend void callback
|
||||
(void* arg, int status, int timeouts, struct hostent* host);
|
||||
friend void callback(void* arg, int status, int timeouts,
|
||||
struct hostent* host);
|
||||
|
||||
public:
|
||||
enum STATUS {
|
||||
STATUS_READY,
|
||||
|
@ -56,6 +57,7 @@ public:
|
|||
STATUS_SUCCESS,
|
||||
STATUS_ERROR,
|
||||
};
|
||||
|
||||
private:
|
||||
STATUS status_;
|
||||
int family_;
|
||||
|
@ -64,13 +66,14 @@ private:
|
|||
std::vector<std::string> resolvedAddresses_;
|
||||
std::string error_;
|
||||
std::string hostname_;
|
||||
|
||||
public:
|
||||
AsyncNameResolver
|
||||
(int family
|
||||
AsyncNameResolver(int family
|
||||
#ifdef HAVE_ARES_ADDR_NODE
|
||||
, ares_addr_node* servers
|
||||
,
|
||||
ares_addr_node* servers
|
||||
#endif // HAVE_ARES_ADDR_NODE
|
||||
);
|
||||
);
|
||||
|
||||
~AsyncNameResolver();
|
||||
|
||||
|
@ -81,24 +84,15 @@ public:
|
|||
return resolvedAddresses_;
|
||||
}
|
||||
|
||||
const std::string& getError() const
|
||||
{
|
||||
return error_;
|
||||
}
|
||||
const std::string& getError() const { return error_; }
|
||||
|
||||
STATUS getStatus() const
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
STATUS getStatus() const { return status_; }
|
||||
|
||||
int getFds(fd_set* rfdsPtr, fd_set* wfdsPtr) const;
|
||||
|
||||
void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
||||
|
||||
int getFamily() const
|
||||
{
|
||||
return family_;
|
||||
}
|
||||
int getFamily() const { return family_; }
|
||||
#ifdef HAVE_LIBCARES
|
||||
|
||||
int getsock(sock_t* sockets) const;
|
||||
|
@ -113,11 +107,7 @@ public:
|
|||
|
||||
void reset();
|
||||
|
||||
const std::string& getHostname() const
|
||||
{
|
||||
return hostname_;
|
||||
}
|
||||
|
||||
const std::string& getHostname() const { return hostname_; }
|
||||
};
|
||||
|
||||
#ifdef HAVE_ARES_ADDR_NODE
|
||||
|
@ -126,7 +116,6 @@ ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt);
|
|||
|
||||
#endif // HAVE_ARES_ADDR_NODE
|
||||
|
||||
|
||||
} // namespace aria2
|
||||
|
||||
#endif // D_ASYNC_NAME_RESOLVER_H
|
||||
|
|
|
@ -49,21 +49,16 @@
|
|||
namespace aria2 {
|
||||
|
||||
AsyncNameResolverMan::AsyncNameResolverMan()
|
||||
: numResolver_(0),
|
||||
resolverCheck_(0),
|
||||
ipv4_(true),
|
||||
ipv6_(true)
|
||||
{}
|
||||
|
||||
AsyncNameResolverMan::~AsyncNameResolverMan()
|
||||
: numResolver_(0), resolverCheck_(0), ipv4_(true), ipv6_(true)
|
||||
{
|
||||
assert(!resolverCheck_);
|
||||
}
|
||||
|
||||
AsyncNameResolverMan::~AsyncNameResolverMan() { assert(!resolverCheck_); }
|
||||
|
||||
bool AsyncNameResolverMan::started() const
|
||||
{
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
if(asyncNameResolver_[i]) {
|
||||
for (size_t i = 0; i < numResolver_; ++i) {
|
||||
if (asyncNameResolver_[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -71,46 +66,44 @@ bool AsyncNameResolverMan::started() const
|
|||
}
|
||||
|
||||
void AsyncNameResolverMan::startAsync(const std::string& hostname,
|
||||
DownloadEngine* e,
|
||||
Command* command)
|
||||
DownloadEngine* e, Command* command)
|
||||
{
|
||||
numResolver_ = 0;
|
||||
// Set IPv6 resolver first, so that we can push IPv6 address in
|
||||
// front of IPv6 address in getResolvedAddress().
|
||||
if(ipv6_) {
|
||||
if (ipv6_) {
|
||||
startAsyncFamily(hostname, AF_INET6, e, command);
|
||||
++numResolver_;
|
||||
}
|
||||
if(ipv4_) {
|
||||
if (ipv4_) {
|
||||
startAsyncFamily(hostname, AF_INET, e, command);
|
||||
++numResolver_;
|
||||
}
|
||||
A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME, command->getCuid(),
|
||||
hostname.c_str()));
|
||||
A2_LOG_INFO(
|
||||
fmt(MSG_RESOLVING_HOSTNAME, command->getCuid(), hostname.c_str()));
|
||||
}
|
||||
|
||||
void AsyncNameResolverMan::startAsyncFamily(const std::string& hostname,
|
||||
int family,
|
||||
DownloadEngine* e,
|
||||
int family, DownloadEngine* e,
|
||||
Command* command)
|
||||
{
|
||||
asyncNameResolver_[numResolver_] = std::make_shared<AsyncNameResolver>
|
||||
(family
|
||||
asyncNameResolver_[numResolver_] =
|
||||
std::make_shared<AsyncNameResolver>(family
|
||||
#ifdef HAVE_ARES_ADDR_NODE
|
||||
,
|
||||
e->getAsyncDNSServers()
|
||||
,
|
||||
e->getAsyncDNSServers()
|
||||
#endif // HAVE_ARES_ADDR_NODE
|
||||
);
|
||||
);
|
||||
asyncNameResolver_[numResolver_]->resolve(hostname);
|
||||
setNameResolverCheck(numResolver_, e, command);
|
||||
}
|
||||
|
||||
void AsyncNameResolverMan::getResolvedAddress(std::vector<std::string>& res)
|
||||
const
|
||||
void AsyncNameResolverMan::getResolvedAddress(
|
||||
std::vector<std::string>& res) const
|
||||
{
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
if(asyncNameResolver_[i]->getStatus() ==
|
||||
AsyncNameResolver::STATUS_SUCCESS) {
|
||||
for (size_t i = 0; i < numResolver_; ++i) {
|
||||
if (asyncNameResolver_[i]->getStatus() ==
|
||||
AsyncNameResolver::STATUS_SUCCESS) {
|
||||
auto& addrs = asyncNameResolver_[i]->getResolvedAddresses();
|
||||
res.insert(std::end(res), std::begin(addrs), std::end(addrs));
|
||||
}
|
||||
|
@ -121,16 +114,15 @@ const
|
|||
void AsyncNameResolverMan::setNameResolverCheck(DownloadEngine* e,
|
||||
Command* command)
|
||||
{
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
for (size_t i = 0; i < numResolver_; ++i) {
|
||||
setNameResolverCheck(i, e, command);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncNameResolverMan::setNameResolverCheck(size_t index,
|
||||
DownloadEngine* e,
|
||||
void AsyncNameResolverMan::setNameResolverCheck(size_t index, DownloadEngine* e,
|
||||
Command* command)
|
||||
{
|
||||
if(asyncNameResolver_[index]) {
|
||||
if (asyncNameResolver_[index]) {
|
||||
assert((resolverCheck_ & (1 << index)) == 0);
|
||||
resolverCheck_ |= 1 << index;
|
||||
e->addNameResolverCheck(asyncNameResolver_[index], command);
|
||||
|
@ -140,7 +132,7 @@ void AsyncNameResolverMan::setNameResolverCheck(size_t index,
|
|||
void AsyncNameResolverMan::disableNameResolverCheck(DownloadEngine* e,
|
||||
Command* command)
|
||||
{
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
for (size_t i = 0; i < numResolver_; ++i) {
|
||||
disableNameResolverCheck(i, e, command);
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +141,7 @@ void AsyncNameResolverMan::disableNameResolverCheck(size_t index,
|
|||
DownloadEngine* e,
|
||||
Command* command)
|
||||
{
|
||||
if(asyncNameResolver_[index] && (resolverCheck_ & (1 << index))) {
|
||||
if (asyncNameResolver_[index] && (resolverCheck_ & (1 << index))) {
|
||||
resolverCheck_ &= ~(1 << index);
|
||||
e->deleteNameResolverCheck(asyncNameResolver_[index], command);
|
||||
}
|
||||
|
@ -160,11 +152,11 @@ int AsyncNameResolverMan::getStatus() const
|
|||
size_t success = 0;
|
||||
size_t error = 0;
|
||||
bool ipv4Success = false;
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
switch(asyncNameResolver_[i]->getStatus()) {
|
||||
for (size_t i = 0; i < numResolver_; ++i) {
|
||||
switch (asyncNameResolver_[i]->getStatus()) {
|
||||
case AsyncNameResolver::STATUS_SUCCESS:
|
||||
++success;
|
||||
if(asyncNameResolver_[i]->getFamily() == AF_INET) {
|
||||
if (asyncNameResolver_[i]->getFamily() == AF_INET) {
|
||||
ipv4Success = true;
|
||||
}
|
||||
break;
|
||||
|
@ -180,19 +172,21 @@ int AsyncNameResolverMan::getStatus() const
|
|||
// have to wait for a long time before timeout. We don't do the
|
||||
// inverse, because, based on today's deployment of DNS servers,
|
||||
// almost all of them can respond to A queries just fine.
|
||||
if((success && ipv4Success) || success == numResolver_) {
|
||||
if ((success && ipv4Success) || success == numResolver_) {
|
||||
return 1;
|
||||
} else if(error == numResolver_) {
|
||||
}
|
||||
else if (error == numResolver_) {
|
||||
return -1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& AsyncNameResolverMan::getLastError() const
|
||||
{
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
if(asyncNameResolver_[i]->getStatus() == AsyncNameResolver::STATUS_ERROR) {
|
||||
for (size_t i = 0; i < numResolver_; ++i) {
|
||||
if (asyncNameResolver_[i]->getStatus() == AsyncNameResolver::STATUS_ERROR) {
|
||||
// TODO This is not last error chronologically.
|
||||
return asyncNameResolver_[i]->getError();
|
||||
}
|
||||
|
@ -204,7 +198,7 @@ void AsyncNameResolverMan::reset(DownloadEngine* e, Command* command)
|
|||
{
|
||||
disableNameResolverCheck(e, command);
|
||||
assert(resolverCheck_ == 0);
|
||||
for(size_t i = 0; i < numResolver_; ++i) {
|
||||
for (size_t i = 0; i < numResolver_; ++i) {
|
||||
asyncNameResolver_[i].reset();
|
||||
}
|
||||
numResolver_ = 0;
|
||||
|
@ -219,14 +213,13 @@ void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan,
|
|||
// before network interfaces up. To workaround this, we check
|
||||
// addresses again if both addresses are not configured at the
|
||||
// startup.
|
||||
if(!net::getIPv4AddrConfigured() && !net::getIPv6AddrConfigured()) {
|
||||
if (!net::getIPv4AddrConfigured() && !net::getIPv6AddrConfigured()) {
|
||||
net::checkAddrconfig();
|
||||
}
|
||||
if(!net::getIPv4AddrConfigured()) {
|
||||
if (!net::getIPv4AddrConfigured()) {
|
||||
asyncNameResolverMan->setIPv4(false);
|
||||
}
|
||||
if(!net::getIPv6AddrConfigured() ||
|
||||
option->getAsBool(PREF_DISABLE_IPV6)) {
|
||||
if (!net::getIPv6AddrConfigured() || option->getAsBool(PREF_DISABLE_IPV6)) {
|
||||
asyncNameResolverMan->setIPv6(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,15 +55,9 @@ public:
|
|||
// must call it before the destruction of this object.
|
||||
~AsyncNameResolverMan();
|
||||
// Enable IPv4 address lookup. default: true
|
||||
void setIPv4(bool ipv4)
|
||||
{
|
||||
ipv4_ = ipv4;
|
||||
}
|
||||
void setIPv4(bool ipv4) { ipv4_ = ipv4; }
|
||||
// Enable IPv6 address lookup. default: true
|
||||
void setIPv6(bool ipv6)
|
||||
{
|
||||
ipv6_ = ipv6;
|
||||
}
|
||||
void setIPv6(bool ipv6) { ipv6_ = ipv6; }
|
||||
// Returns true if asynchronous name resolution has been started.
|
||||
bool started() const;
|
||||
// Starts asynchronous name resolution.
|
||||
|
@ -76,10 +70,7 @@ public:
|
|||
// Removes resolvers from DownloadEngine.
|
||||
void disableNameResolverCheck(DownloadEngine* e, Command* command);
|
||||
// Returns true if any of resolvers are added in DownloadEngine.
|
||||
bool resolverChecked() const
|
||||
{
|
||||
return resolverCheck_;
|
||||
}
|
||||
bool resolverChecked() const { return resolverCheck_; }
|
||||
// Returns status value: 0 for inprogress, 1 for success and -1 for
|
||||
// failure.
|
||||
int getStatus() const;
|
||||
|
@ -87,9 +78,9 @@ public:
|
|||
const std::string& getLastError() const;
|
||||
// Resets state. Also removes resolvers from DownloadEngine.
|
||||
void reset(DownloadEngine* e, Command* command);
|
||||
|
||||
private:
|
||||
void startAsyncFamily(const std::string& hostname,
|
||||
int family,
|
||||
void startAsyncFamily(const std::string& hostname, int family,
|
||||
DownloadEngine* e, Command* command);
|
||||
void setNameResolverCheck(size_t resolverIndex, DownloadEngine* e,
|
||||
Command* command);
|
||||
|
|
|
@ -43,9 +43,9 @@ namespace aria2 {
|
|||
AuthConfig::AuthConfig() {}
|
||||
|
||||
AuthConfig::AuthConfig(std::string user, std::string password)
|
||||
: user_(std::move(user)),
|
||||
password_(std::move(password))
|
||||
{}
|
||||
: user_(std::move(user)), password_(std::move(password))
|
||||
{
|
||||
}
|
||||
|
||||
AuthConfig::~AuthConfig() {}
|
||||
|
||||
|
@ -57,12 +57,13 @@ std::string AuthConfig::getAuthText() const
|
|||
return s;
|
||||
}
|
||||
|
||||
std::unique_ptr<AuthConfig> AuthConfig::create
|
||||
(std::string user, std::string password)
|
||||
std::unique_ptr<AuthConfig> AuthConfig::create(std::string user,
|
||||
std::string password)
|
||||
{
|
||||
if(user.empty()) {
|
||||
if (user.empty()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return make_unique<AuthConfig>(std::move(user), std::move(password));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ private:
|
|||
std::string authScheme_;
|
||||
std::string user_;
|
||||
std::string password_;
|
||||
|
||||
public:
|
||||
AuthConfig();
|
||||
AuthConfig(std::string user, std::string password);
|
||||
|
@ -59,18 +60,12 @@ public:
|
|||
|
||||
std::string getAuthText() const;
|
||||
|
||||
const std::string& getUser() const
|
||||
{
|
||||
return user_;
|
||||
}
|
||||
const std::string& getUser() const { return user_; }
|
||||
|
||||
const std::string& getPassword() const
|
||||
{
|
||||
return password_;
|
||||
}
|
||||
const std::string& getPassword() const { return password_; }
|
||||
|
||||
static std::unique_ptr<AuthConfig> create
|
||||
(std::string user, std::string password);
|
||||
static std::unique_ptr<AuthConfig> create(std::string user,
|
||||
std::string password);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o,
|
||||
|
|
|
@ -57,51 +57,54 @@ AuthConfigFactory::AuthConfigFactory() {}
|
|||
AuthConfigFactory::~AuthConfigFactory() {}
|
||||
|
||||
std::unique_ptr<AuthConfig>
|
||||
AuthConfigFactory::createAuthConfig
|
||||
(const std::shared_ptr<Request>& request, const Option* op)
|
||||
AuthConfigFactory::createAuthConfig(const std::shared_ptr<Request>& request,
|
||||
const Option* op)
|
||||
{
|
||||
if(request->getProtocol() == "http" || request->getProtocol() == "https") {
|
||||
if(op->getAsBool(PREF_HTTP_AUTH_CHALLENGE)) {
|
||||
if(!request->getUsername().empty()) {
|
||||
updateBasicCred(make_unique<BasicCred>(request->getUsername(),
|
||||
request->getPassword(),
|
||||
request->getHost(),
|
||||
request->getPort(),
|
||||
request->getDir(), true));
|
||||
if (request->getProtocol() == "http" || request->getProtocol() == "https") {
|
||||
if (op->getAsBool(PREF_HTTP_AUTH_CHALLENGE)) {
|
||||
if (!request->getUsername().empty()) {
|
||||
updateBasicCred(make_unique<BasicCred>(
|
||||
request->getUsername(), request->getPassword(), request->getHost(),
|
||||
request->getPort(), request->getDir(), true));
|
||||
return AuthConfig::create(request->getUsername(),
|
||||
request->getPassword());
|
||||
}
|
||||
auto i = findBasicCred(request->getHost(), request->getPort(),
|
||||
request->getDir());
|
||||
if(i == std::end(basicCreds_)) {
|
||||
if (i == std::end(basicCreds_)) {
|
||||
return nullptr;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return AuthConfig::create((*i)->user_, (*i)->password_);
|
||||
}
|
||||
} else {
|
||||
if(!request->getUsername().empty()) {
|
||||
}
|
||||
else {
|
||||
if (!request->getUsername().empty()) {
|
||||
return AuthConfig::create(request->getUsername(),
|
||||
request->getPassword());
|
||||
} else {
|
||||
return
|
||||
createHttpAuthResolver(op)->resolveAuthConfig(request->getHost());
|
||||
}
|
||||
else {
|
||||
return createHttpAuthResolver(op)
|
||||
->resolveAuthConfig(request->getHost());
|
||||
}
|
||||
}
|
||||
} else if(request->getProtocol() == "ftp" ||
|
||||
request->getProtocol() == "sftp") {
|
||||
if(!request->getUsername().empty()) {
|
||||
if(request->hasPassword()) {
|
||||
}
|
||||
else if (request->getProtocol() == "ftp" ||
|
||||
request->getProtocol() == "sftp") {
|
||||
if (!request->getUsername().empty()) {
|
||||
if (request->hasPassword()) {
|
||||
return AuthConfig::create(request->getUsername(),
|
||||
request->getPassword());
|
||||
} else {
|
||||
if(!op->getAsBool(PREF_NO_NETRC)) {
|
||||
}
|
||||
else {
|
||||
if (!op->getAsBool(PREF_NO_NETRC)) {
|
||||
// First, check we have password corresponding to host and
|
||||
// username
|
||||
NetrcAuthResolver authResolver;
|
||||
authResolver.setNetrc(netrc_.get());
|
||||
|
||||
auto ac = authResolver.resolveAuthConfig(request->getHost());
|
||||
if(ac && ac->getUser() == request->getUsername()) {
|
||||
if (ac && ac->getUser() == request->getUsername()) {
|
||||
return ac;
|
||||
}
|
||||
}
|
||||
|
@ -110,22 +113,24 @@ AuthConfigFactory::createAuthConfig
|
|||
return AuthConfig::create(request->getUsername(),
|
||||
op->get(PREF_FTP_PASSWD));
|
||||
}
|
||||
} else {
|
||||
return
|
||||
createFtpAuthResolver(op)->resolveAuthConfig(request->getHost());
|
||||
}
|
||||
} else {
|
||||
else {
|
||||
return createFtpAuthResolver(op)->resolveAuthConfig(request->getHost());
|
||||
}
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<AuthResolver> AuthConfigFactory::createHttpAuthResolver
|
||||
(const Option* op) const
|
||||
std::unique_ptr<AuthResolver>
|
||||
AuthConfigFactory::createHttpAuthResolver(const Option* op) const
|
||||
{
|
||||
std::unique_ptr<AbstractAuthResolver> resolver;
|
||||
if(op->getAsBool(PREF_NO_NETRC)) {
|
||||
if (op->getAsBool(PREF_NO_NETRC)) {
|
||||
resolver = make_unique<DefaultAuthResolver>();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
auto authResolver = make_unique<NetrcAuthResolver>();
|
||||
authResolver->setNetrc(netrc_.get());
|
||||
authResolver->ignoreDefault();
|
||||
|
@ -136,13 +141,14 @@ std::unique_ptr<AuthResolver> AuthConfigFactory::createHttpAuthResolver
|
|||
return std::move(resolver);
|
||||
}
|
||||
|
||||
std::unique_ptr<AuthResolver> AuthConfigFactory::createFtpAuthResolver
|
||||
(const Option* op) const
|
||||
std::unique_ptr<AuthResolver>
|
||||
AuthConfigFactory::createFtpAuthResolver(const Option* op) const
|
||||
{
|
||||
std::unique_ptr<AbstractAuthResolver> resolver;
|
||||
if(op->getAsBool(PREF_NO_NETRC)) {
|
||||
if (op->getAsBool(PREF_NO_NETRC)) {
|
||||
resolver = make_unique<DefaultAuthResolver>();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
auto authResolver = make_unique<NetrcAuthResolver>();
|
||||
authResolver->setNetrc(netrc_.get());
|
||||
resolver = std::move(authResolver);
|
||||
|
@ -161,61 +167,55 @@ void AuthConfigFactory::setNetrc(std::unique_ptr<Netrc> netrc)
|
|||
void AuthConfigFactory::updateBasicCred(std::unique_ptr<BasicCred> basicCred)
|
||||
{
|
||||
auto i = basicCreds_.lower_bound(basicCred);
|
||||
if(i != std::end(basicCreds_) && *i == basicCred) {
|
||||
if (i != std::end(basicCreds_) && *i == basicCred) {
|
||||
*(*i) = std::move(*basicCred);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
basicCreds_.insert(i, std::move(basicCred));
|
||||
}
|
||||
}
|
||||
|
||||
bool AuthConfigFactory::activateBasicCred
|
||||
(const std::string& host,
|
||||
uint16_t port,
|
||||
const std::string& path,
|
||||
const Option* op)
|
||||
bool AuthConfigFactory::activateBasicCred(const std::string& host,
|
||||
uint16_t port,
|
||||
const std::string& path,
|
||||
const Option* op)
|
||||
{
|
||||
auto i = findBasicCred(host, port, path);
|
||||
if(i == std::end(basicCreds_)) {
|
||||
if (i == std::end(basicCreds_)) {
|
||||
auto authConfig = createHttpAuthResolver(op)->resolveAuthConfig(host);
|
||||
if(!authConfig) {
|
||||
if (!authConfig) {
|
||||
return false;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
basicCreds_.insert(make_unique<BasicCred>(authConfig->getUser(),
|
||||
authConfig->getPassword(),
|
||||
host, port, path, true));
|
||||
authConfig->getPassword(), host,
|
||||
port, path, true));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
(*i)->activate();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BasicCred::BasicCred
|
||||
(std::string user, std::string password,
|
||||
std::string host, uint16_t port, std::string path,
|
||||
bool activated)
|
||||
: user_(std::move(user)),
|
||||
password_(std::move(password)),
|
||||
host_(std::move(host)),
|
||||
port_(port),
|
||||
path_(std::move(path)),
|
||||
activated_(activated)
|
||||
BasicCred::BasicCred(std::string user, std::string password, std::string host,
|
||||
uint16_t port, std::string path, bool activated)
|
||||
: user_(std::move(user)),
|
||||
password_(std::move(password)),
|
||||
host_(std::move(host)),
|
||||
port_(port),
|
||||
path_(std::move(path)),
|
||||
activated_(activated)
|
||||
{
|
||||
if(path_.empty() || path_[path_.size()-1] != '/') {
|
||||
if (path_.empty() || path_[path_.size() - 1] != '/') {
|
||||
path_ += "/";
|
||||
}
|
||||
}
|
||||
|
||||
void BasicCred::activate()
|
||||
{
|
||||
activated_ = true;
|
||||
}
|
||||
void BasicCred::activate() { activated_ = true; }
|
||||
|
||||
bool BasicCred::isActivated() const
|
||||
{
|
||||
return activated_;
|
||||
}
|
||||
bool BasicCred::isActivated() const { return activated_; }
|
||||
|
||||
bool BasicCred::operator==(const BasicCred& cred) const
|
||||
{
|
||||
|
@ -224,22 +224,21 @@ bool BasicCred::operator==(const BasicCred& cred) const
|
|||
|
||||
bool BasicCred::operator<(const BasicCred& cred) const
|
||||
{
|
||||
return host_ < cred.host_ ||
|
||||
(!(cred.host_ < host_) && (port_ < cred.port_ ||
|
||||
(!(cred.port_ < port_) && path_ > cred.path_)));
|
||||
return host_ < cred.host_ || (!(cred.host_ < host_) &&
|
||||
(port_ < cred.port_ || (!(cred.port_ < port_) &&
|
||||
path_ > cred.path_)));
|
||||
}
|
||||
|
||||
AuthConfigFactory::BasicCredSet::iterator AuthConfigFactory::findBasicCred
|
||||
(const std::string& host,
|
||||
uint16_t port,
|
||||
const std::string& path)
|
||||
AuthConfigFactory::BasicCredSet::iterator
|
||||
AuthConfigFactory::findBasicCred(const std::string& host, uint16_t port,
|
||||
const std::string& path)
|
||||
{
|
||||
auto bc = make_unique<BasicCred>("", "", host, port, path);
|
||||
auto i = basicCreds_.lower_bound(bc);
|
||||
for(; i != std::end(basicCreds_) &&
|
||||
(*i)->host_ == host &&
|
||||
(*i)->port_ == port; ++i) {
|
||||
if(util::startsWith(bc->path_, (*i)->path_)) {
|
||||
for (;
|
||||
i != std::end(basicCreds_) && (*i)->host_ == host && (*i)->port_ == port;
|
||||
++i) {
|
||||
if (util::startsWith(bc->path_, (*i)->path_)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,9 +61,8 @@ public:
|
|||
std::string path_;
|
||||
bool activated_;
|
||||
|
||||
BasicCred(std::string user, std::string password,
|
||||
std::string host, uint16_t port, std::string path,
|
||||
bool activated = false);
|
||||
BasicCred(std::string user, std::string password, std::string host,
|
||||
uint16_t port, std::string path, bool activated = false);
|
||||
|
||||
void activate();
|
||||
|
||||
|
@ -78,6 +77,7 @@ class AuthConfigFactory {
|
|||
public:
|
||||
typedef std::set<std::unique_ptr<BasicCred>,
|
||||
DerefLess<std::unique_ptr<BasicCred>>> BasicCredSet;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Netrc> netrc_;
|
||||
|
||||
|
@ -86,6 +86,7 @@ private:
|
|||
std::unique_ptr<AuthResolver> createFtpAuthResolver(const Option* op) const;
|
||||
|
||||
BasicCredSet basicCreds_;
|
||||
|
||||
public:
|
||||
AuthConfigFactory();
|
||||
|
||||
|
@ -95,8 +96,8 @@ public:
|
|||
// are used in this method: PREF_HTTP_USER, PREF_HTTP_PASSWD,
|
||||
// PREF_FTP_USER, PREF_FTP_PASSWD, PREF_NO_NETRC and
|
||||
// PREF_HTTP_AUTH_CHALLENGE.
|
||||
std::unique_ptr<AuthConfig> createAuthConfig
|
||||
(const std::shared_ptr<Request>& request, const Option* op);
|
||||
std::unique_ptr<AuthConfig>
|
||||
createAuthConfig(const std::shared_ptr<Request>& request, const Option* op);
|
||||
|
||||
void setNetrc(std::unique_ptr<Netrc> netrc);
|
||||
|
||||
|
@ -106,20 +107,14 @@ public:
|
|||
// null, then returns false. Otherwise new BasicCred is created
|
||||
// using this AuthConfig object with given host and path "/" and
|
||||
// returns true.
|
||||
bool activateBasicCred
|
||||
(const std::string& host,
|
||||
uint16_t port,
|
||||
const std::string& path,
|
||||
const Option* op);
|
||||
bool activateBasicCred(const std::string& host, uint16_t port,
|
||||
const std::string& path, const Option* op);
|
||||
|
||||
// Find a BasicCred using host, port and path and return the
|
||||
// iterator pointing to it. If not found, then return
|
||||
// basicCreds_.end().
|
||||
BasicCredSet::iterator
|
||||
findBasicCred
|
||||
(const std::string& host,
|
||||
uint16_t port,
|
||||
const std::string& path);
|
||||
BasicCredSet::iterator findBasicCred(const std::string& host, uint16_t port,
|
||||
const std::string& path);
|
||||
|
||||
// If the same BasicCred is already added, then it is replaced with
|
||||
// given basicCred. Otherwise, insert given basicCred to
|
||||
|
|
|
@ -48,8 +48,8 @@ class AuthResolver {
|
|||
public:
|
||||
virtual ~AuthResolver() {}
|
||||
|
||||
virtual std::unique_ptr<AuthConfig> resolveAuthConfig
|
||||
(const std::string& hostname) = 0;
|
||||
virtual std::unique_ptr<AuthConfig>
|
||||
resolveAuthConfig(const std::string& hostname) = 0;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -40,15 +40,16 @@ namespace aria2 {
|
|||
|
||||
AutoSaveCommand::AutoSaveCommand(cuid_t cuid, DownloadEngine* e,
|
||||
std::chrono::seconds interval)
|
||||
: TimeBasedCommand(cuid, e, std::move(interval), true)
|
||||
{}
|
||||
: TimeBasedCommand(cuid, e, std::move(interval), true)
|
||||
{
|
||||
}
|
||||
|
||||
AutoSaveCommand::~AutoSaveCommand() {}
|
||||
|
||||
void AutoSaveCommand::preProcess()
|
||||
{
|
||||
if(getDownloadEngine()->getRequestGroupMan()->downloadFinished() ||
|
||||
getDownloadEngine()->isHaltRequested()) {
|
||||
if (getDownloadEngine()->getRequestGroupMan()->downloadFinished() ||
|
||||
getDownloadEngine()->isHaltRequested()) {
|
||||
enableExit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
class AutoSaveCommand : public TimeBasedCommand
|
||||
{
|
||||
class AutoSaveCommand : public TimeBasedCommand {
|
||||
public:
|
||||
AutoSaveCommand(cuid_t cuid, DownloadEngine* e,
|
||||
std::chrono::seconds interval);
|
||||
|
|
|
@ -45,24 +45,22 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
BackupConnectInfo::BackupConnectInfo()
|
||||
: cancel(false)
|
||||
{}
|
||||
BackupConnectInfo::BackupConnectInfo() : cancel(false) {}
|
||||
|
||||
BackupIPv4ConnectCommand::BackupIPv4ConnectCommand
|
||||
(cuid_t cuid, const std::string& ipaddr, uint16_t port,
|
||||
const std::shared_ptr<BackupConnectInfo>& info, Command* mainCommand,
|
||||
RequestGroup* requestGroup, DownloadEngine* e)
|
||||
: Command(cuid),
|
||||
ipaddr_(ipaddr),
|
||||
port_(port),
|
||||
info_(info),
|
||||
mainCommand_(mainCommand),
|
||||
requestGroup_(requestGroup),
|
||||
e_(e),
|
||||
startTime_(global::wallclock()),
|
||||
timeoutCheck_(global::wallclock()),
|
||||
timeout_(requestGroup_->getOption()->getAsInt(PREF_CONNECT_TIMEOUT))
|
||||
BackupIPv4ConnectCommand::BackupIPv4ConnectCommand(
|
||||
cuid_t cuid, const std::string& ipaddr, uint16_t port,
|
||||
const std::shared_ptr<BackupConnectInfo>& info, Command* mainCommand,
|
||||
RequestGroup* requestGroup, DownloadEngine* e)
|
||||
: Command(cuid),
|
||||
ipaddr_(ipaddr),
|
||||
port_(port),
|
||||
info_(info),
|
||||
mainCommand_(mainCommand),
|
||||
requestGroup_(requestGroup),
|
||||
e_(e),
|
||||
startTime_(global::wallclock()),
|
||||
timeoutCheck_(global::wallclock()),
|
||||
timeout_(requestGroup_->getOption()->getAsInt(PREF_CONNECT_TIMEOUT))
|
||||
{
|
||||
requestGroup_->increaseStreamCommand();
|
||||
requestGroup_->increaseNumCommand();
|
||||
|
@ -72,7 +70,7 @@ BackupIPv4ConnectCommand::~BackupIPv4ConnectCommand()
|
|||
{
|
||||
requestGroup_->decreaseNumCommand();
|
||||
requestGroup_->decreaseStreamCommand();
|
||||
if(socket_) {
|
||||
if (socket_) {
|
||||
e_->deleteSocketForWriteCheck(socket_, this);
|
||||
}
|
||||
}
|
||||
|
@ -80,60 +78,68 @@ BackupIPv4ConnectCommand::~BackupIPv4ConnectCommand()
|
|||
bool BackupIPv4ConnectCommand::execute()
|
||||
{
|
||||
bool retval = false;
|
||||
if(requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
|
||||
if (requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
|
||||
retval = true;
|
||||
} else if(info_->cancel) {
|
||||
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Backup connection canceled",
|
||||
getCuid()));
|
||||
}
|
||||
else if (info_->cancel) {
|
||||
A2_LOG_INFO(
|
||||
fmt("CUID#%" PRId64 " - Backup connection canceled", getCuid()));
|
||||
retval = true;
|
||||
} else if(socket_) {
|
||||
if(writeEventEnabled()) {
|
||||
}
|
||||
else if (socket_) {
|
||||
if (writeEventEnabled()) {
|
||||
try {
|
||||
std::string error = socket_->getSocketError();
|
||||
if(error.empty()) {
|
||||
if (error.empty()) {
|
||||
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Backup connection to %s "
|
||||
"established", getCuid(), ipaddr_.c_str()));
|
||||
"established",
|
||||
getCuid(), ipaddr_.c_str()));
|
||||
info_->ipaddr = ipaddr_;
|
||||
e_->deleteSocketForWriteCheck(socket_, this);
|
||||
info_->socket.swap(socket_);
|
||||
mainCommand_->setStatus(STATUS_ONESHOT_REALTIME);
|
||||
e_->setNoWait(true);
|
||||
retval = true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Backup connection failed: %s",
|
||||
getCuid(), error.c_str()));
|
||||
retval = true;
|
||||
}
|
||||
} catch(RecoverableException& e) {
|
||||
A2_LOG_INFO_EX(fmt("CUID#%" PRId64 " - Backup connection failed",
|
||||
getCuid()), e);
|
||||
}
|
||||
catch (RecoverableException& e) {
|
||||
A2_LOG_INFO_EX(
|
||||
fmt("CUID#%" PRId64 " - Backup connection failed", getCuid()), e);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
} else if(!socket_) {
|
||||
}
|
||||
else if (!socket_) {
|
||||
// TODO Although we check 300ms initial timeout as described in
|
||||
// RFC 6555, the interval will be much longer and around 1 second
|
||||
// due to the refresh interval mechanism in DownloadEngine.
|
||||
if(startTime_.difference(global::wallclock()) >=
|
||||
std::chrono::milliseconds(300)) {
|
||||
if (startTime_.difference(global::wallclock()) >=
|
||||
std::chrono::milliseconds(300)) {
|
||||
socket_ = std::make_shared<SocketCore>();
|
||||
try {
|
||||
socket_->establishConnection(ipaddr_, port_);
|
||||
e_->addSocketForWriteCheck(socket_, this);
|
||||
timeoutCheck_ = global::wallclock();
|
||||
} catch(RecoverableException& e) {
|
||||
A2_LOG_INFO_EX(fmt("CUID#%" PRId64 " - Backup connection failed",
|
||||
getCuid()), e);
|
||||
}
|
||||
catch (RecoverableException& e) {
|
||||
A2_LOG_INFO_EX(
|
||||
fmt("CUID#%" PRId64 " - Backup connection failed", getCuid()), e);
|
||||
socket_.reset();
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
} else if(timeoutCheck_.difference(global::wallclock()) >= timeout_) {
|
||||
A2_LOG_INFO(fmt("CUID#%" PRId64 " - Backup connection command timeout",
|
||||
getCuid()));
|
||||
}
|
||||
else if (timeoutCheck_.difference(global::wallclock()) >= timeout_) {
|
||||
A2_LOG_INFO(
|
||||
fmt("CUID#%" PRId64 " - Backup connection command timeout", getCuid()));
|
||||
retval = true;
|
||||
}
|
||||
if(!retval) {
|
||||
if (!retval) {
|
||||
e_->addCommand(std::unique_ptr<Command>(this));
|
||||
}
|
||||
return retval;
|
||||
|
|
|
@ -64,13 +64,14 @@ struct BackupConnectInfo {
|
|||
// "Happy Eyeballs" implementation.
|
||||
class BackupIPv4ConnectCommand : public Command {
|
||||
public:
|
||||
BackupIPv4ConnectCommand(cuid_t cuid,
|
||||
const std::string& ipaddr, uint16_t port,
|
||||
BackupIPv4ConnectCommand(cuid_t cuid, const std::string& ipaddr,
|
||||
uint16_t port,
|
||||
const std::shared_ptr<BackupConnectInfo>& info,
|
||||
Command* mainCommand,
|
||||
RequestGroup* requestGroup, DownloadEngine* e);
|
||||
Command* mainCommand, RequestGroup* requestGroup,
|
||||
DownloadEngine* e);
|
||||
~BackupIPv4ConnectCommand();
|
||||
virtual bool execute() CXX11_OVERRIDE;
|
||||
|
||||
private:
|
||||
std::string ipaddr_;
|
||||
uint16_t port_;
|
||||
|
|
|
@ -60,53 +60,54 @@ enum {
|
|||
} // namespace
|
||||
|
||||
BencodeParser::BencodeParser(StructParserStateMachine* psm)
|
||||
: psm_(psm),
|
||||
currentState_(BENCODE_INITIAL),
|
||||
strLength_(0),
|
||||
numberSign_(1),
|
||||
number_(0),
|
||||
numConsumed_(0),
|
||||
lastError_(0)
|
||||
: psm_(psm),
|
||||
currentState_(BENCODE_INITIAL),
|
||||
strLength_(0),
|
||||
numberSign_(1),
|
||||
number_(0),
|
||||
numConsumed_(0),
|
||||
lastError_(0)
|
||||
{
|
||||
stateStack_.push(BENCODE_FINISH);
|
||||
}
|
||||
|
||||
BencodeParser::~BencodeParser()
|
||||
{}
|
||||
BencodeParser::~BencodeParser() {}
|
||||
|
||||
ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
if(currentState_ == BENCODE_FINISH) {
|
||||
if (currentState_ == BENCODE_FINISH) {
|
||||
return 0;
|
||||
} else if(currentState_ == BENCODE_ERROR) {
|
||||
}
|
||||
else if (currentState_ == BENCODE_ERROR) {
|
||||
return lastError_;
|
||||
}
|
||||
for(i = 0; i < size && currentState_ != BENCODE_FINISH; ++i) {
|
||||
for (i = 0; i < size && currentState_ != BENCODE_FINISH; ++i) {
|
||||
char c = data[i];
|
||||
switch(currentState_) {
|
||||
switch (currentState_) {
|
||||
case BENCODE_LIST:
|
||||
if(c == 'e') {
|
||||
if (c == 'e') {
|
||||
onListEnd();
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
int rv = pushState(currentState_);
|
||||
if(rv < 0) {
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
currentState_ = BENCODE_VALUE;
|
||||
runBeginCallback(STRUCT_ARRAY_DATA_T);
|
||||
}
|
||||
// Fall through
|
||||
// Fall through
|
||||
case BENCODE_INITIAL:
|
||||
case BENCODE_VALUE:
|
||||
switch(c) {
|
||||
switch (c) {
|
||||
case 'd': {
|
||||
currentState_ = BENCODE_DICT_KEY;
|
||||
runBeginCallback(STRUCT_DICT_T);
|
||||
break;
|
||||
}
|
||||
case'l':
|
||||
case 'l':
|
||||
currentState_ = BENCODE_LIST;
|
||||
runBeginCallback(STRUCT_ARRAY_T);
|
||||
break;
|
||||
|
@ -118,25 +119,26 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
|||
runBeginCallback(STRUCT_NUMBER_T);
|
||||
break;
|
||||
default:
|
||||
if(util::isDigit(c)) {
|
||||
if (util::isDigit(c)) {
|
||||
strLength_ = c - '0';
|
||||
numConsumed_ = 1;
|
||||
currentState_ = BENCODE_STRING_LEN;
|
||||
runBeginCallback(STRUCT_STRING_T);
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
currentState_ = BENCODE_ERROR;
|
||||
return lastError_ = ERR_UNEXPECTED_CHAR_BEFORE_VAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BENCODE_DICT_KEY: {
|
||||
if(c == 'e') {
|
||||
if (c == 'e') {
|
||||
onDictEnd();
|
||||
break;
|
||||
}
|
||||
int rv = pushState(currentState_);
|
||||
if(rv < 0) {
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
strLength_ = 0;
|
||||
|
@ -147,8 +149,8 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
|||
}
|
||||
case BENCODE_STRING_LEN: {
|
||||
size_t j;
|
||||
for(j = i; j < size && in(data[j], '0', '9'); ++j) {
|
||||
if((INT64_MAX - (data[j] - '0'))/ 10 < strLength_) {
|
||||
for (j = i; j < size && in(data[j], '0', '9'); ++j) {
|
||||
if ((INT64_MAX - (data[j] - '0')) / 10 < strLength_) {
|
||||
currentState_ = BENCODE_ERROR;
|
||||
return lastError_ = ERR_STRING_LENGTH_OUT_OF_RANGE;
|
||||
}
|
||||
|
@ -156,18 +158,19 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
|||
strLength_ += data[j] - '0';
|
||||
}
|
||||
numConsumed_ += j - i;
|
||||
if(j != size) {
|
||||
if(data[j] != ':' || numConsumed_ == 0) {
|
||||
if (j != size) {
|
||||
if (data[j] != ':' || numConsumed_ == 0) {
|
||||
currentState_ = BENCODE_ERROR;
|
||||
return lastError_ = ERR_INVALID_STRING_LENGTH;
|
||||
}
|
||||
i = j;
|
||||
currentState_ = BENCODE_STRING;
|
||||
if(strLength_ == 0) {
|
||||
if (strLength_ == 0) {
|
||||
runCharactersCallback(nullptr, 0);
|
||||
onStringEnd();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
i = j - 1;
|
||||
}
|
||||
break;
|
||||
|
@ -177,13 +180,13 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
|||
runCharactersCallback(&data[i], nread);
|
||||
strLength_ -= nread;
|
||||
i += nread - 1;
|
||||
if(strLength_ == 0) {
|
||||
if (strLength_ == 0) {
|
||||
onStringEnd();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BENCODE_NUMBER_SIGN: {
|
||||
switch(c) {
|
||||
switch (c) {
|
||||
case '+':
|
||||
numberSign_ = 1;
|
||||
currentState_ = BENCODE_NUMBER;
|
||||
|
@ -193,7 +196,7 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
|||
currentState_ = BENCODE_NUMBER;
|
||||
break;
|
||||
default:
|
||||
if(util::isDigit(c)) {
|
||||
if (util::isDigit(c)) {
|
||||
number_ = c - '0';
|
||||
numConsumed_ = 1;
|
||||
currentState_ = BENCODE_NUMBER;
|
||||
|
@ -203,8 +206,8 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
|||
}
|
||||
case BENCODE_NUMBER: {
|
||||
size_t j;
|
||||
for(j = i; j < size && in(data[j], '0', '9'); ++j) {
|
||||
if((INT64_MAX - (data[j] - '0'))/ 10 < number_) {
|
||||
for (j = i; j < size && in(data[j], '0', '9'); ++j) {
|
||||
if ((INT64_MAX - (data[j] - '0')) / 10 < number_) {
|
||||
currentState_ = BENCODE_ERROR;
|
||||
return lastError_ = ERR_NUMBER_OUT_OF_RANGE;
|
||||
}
|
||||
|
@ -212,14 +215,15 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size)
|
|||
number_ += data[j] - '0';
|
||||
}
|
||||
numConsumed_ += j - i;
|
||||
if(j != size) {
|
||||
if(data[j] != 'e' || numConsumed_ == 0) {
|
||||
if (j != size) {
|
||||
if (data[j] != 'e' || numConsumed_ == 0) {
|
||||
currentState_ = BENCODE_ERROR;
|
||||
return lastError_ = ERR_INVALID_NUMBER;
|
||||
}
|
||||
i = j;
|
||||
onNumberEnd();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
i = j - 1;
|
||||
}
|
||||
break;
|
||||
|
@ -233,9 +237,8 @@ ssize_t BencodeParser::parseFinal(const char* data, size_t len)
|
|||
{
|
||||
ssize_t rv;
|
||||
rv = parseUpdate(data, len);
|
||||
if(rv >= 0) {
|
||||
if(currentState_ != BENCODE_FINISH &&
|
||||
currentState_ != BENCODE_INITIAL) {
|
||||
if (rv >= 0) {
|
||||
if (currentState_ != BENCODE_FINISH && currentState_ != BENCODE_INITIAL) {
|
||||
rv = ERR_PREMATURE_DATA;
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +250,7 @@ void BencodeParser::reset()
|
|||
psm_->reset();
|
||||
currentState_ = BENCODE_INITIAL;
|
||||
lastError_ = 0;
|
||||
while(!stateStack_.empty()) {
|
||||
while (!stateStack_.empty()) {
|
||||
stateStack_.pop();
|
||||
}
|
||||
stateStack_.push(BENCODE_FINISH);
|
||||
|
@ -255,8 +258,8 @@ void BencodeParser::reset()
|
|||
|
||||
void BencodeParser::onStringEnd()
|
||||
{
|
||||
runEndCallback(stateTop() == BENCODE_DICT_KEY ?
|
||||
STRUCT_DICT_KEY_T : STRUCT_STRING_T);
|
||||
runEndCallback(stateTop() == BENCODE_DICT_KEY ? STRUCT_DICT_KEY_T
|
||||
: STRUCT_STRING_T);
|
||||
onValueEnd();
|
||||
}
|
||||
|
||||
|
@ -281,7 +284,7 @@ void BencodeParser::onListEnd()
|
|||
|
||||
void BencodeParser::onValueEnd()
|
||||
{
|
||||
switch(stateTop()) {
|
||||
switch (stateTop()) {
|
||||
case BENCODE_DICT_KEY:
|
||||
popState();
|
||||
pushState(BENCODE_DICT_VAL);
|
||||
|
@ -307,18 +310,16 @@ void BencodeParser::onValueEnd()
|
|||
|
||||
int BencodeParser::pushState(int state)
|
||||
{
|
||||
if(stateStack_.size() >= 50) {
|
||||
if (stateStack_.size() >= 50) {
|
||||
return ERR_STRUCTURE_TOO_DEEP;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
stateStack_.push(state);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int BencodeParser::stateTop() const
|
||||
{
|
||||
return stateStack_.top();
|
||||
}
|
||||
int BencodeParser::stateTop() const { return stateStack_.top(); }
|
||||
|
||||
int BencodeParser::popState()
|
||||
{
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
// Resets the internal state of the parser and makes it ready for
|
||||
// reuse.
|
||||
void reset();
|
||||
|
||||
private:
|
||||
int pushState(int state);
|
||||
int stateTop() const;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -92,10 +92,7 @@ public:
|
|||
|
||||
BitfieldMan& operator=(const BitfieldMan& bitfieldMan);
|
||||
|
||||
int32_t getBlockLength() const
|
||||
{
|
||||
return blockLength_;
|
||||
}
|
||||
int32_t getBlockLength() const { return blockLength_; }
|
||||
|
||||
int32_t getLastBlockLength() const;
|
||||
|
||||
|
@ -131,11 +128,9 @@ public:
|
|||
// if such bit index is found. Otherwise returns false.
|
||||
//
|
||||
// affected by filter
|
||||
bool getSparseMissingUnusedIndex
|
||||
(size_t& index,
|
||||
int32_t minSplitSize,
|
||||
const unsigned char* ignoreBitfield,
|
||||
size_t ignoreBitfieldLength) const;
|
||||
bool getSparseMissingUnusedIndex(size_t& index, int32_t minSplitSize,
|
||||
const unsigned char* ignoreBitfield,
|
||||
size_t ignoreBitfieldLength) const;
|
||||
|
||||
// Stores missing bit index to index. This function first try to
|
||||
// select smallest index starting offsetIndex in the order:
|
||||
|
@ -151,13 +146,10 @@ public:
|
|||
// result.
|
||||
//
|
||||
// affected by filter
|
||||
bool getGeomMissingUnusedIndex
|
||||
(size_t& index,
|
||||
int32_t minSplitSize,
|
||||
const unsigned char* ignoreBitfield,
|
||||
size_t ignoreBitfieldLength,
|
||||
double base,
|
||||
size_t offsetIndex) const;
|
||||
bool getGeomMissingUnusedIndex(size_t& index, int32_t minSplitSize,
|
||||
const unsigned char* ignoreBitfield,
|
||||
size_t ignoreBitfieldLength, double base,
|
||||
size_t offsetIndex) const;
|
||||
|
||||
// Stores missing bit index to index. This function selects smallest
|
||||
// index of missing piece, considering minSplitSize. Set bits in
|
||||
|
@ -165,11 +157,9 @@ public:
|
|||
// found. Otherwise returns false.
|
||||
//
|
||||
// affected by filter
|
||||
bool getInorderMissingUnusedIndex
|
||||
(size_t& index,
|
||||
int32_t minSplitSize,
|
||||
const unsigned char* ignoreBitfield,
|
||||
size_t ignoreBitfieldLength) const;
|
||||
bool getInorderMissingUnusedIndex(size_t& index, int32_t minSplitSize,
|
||||
const unsigned char* ignoreBitfield,
|
||||
size_t ignoreBitfieldLength) const;
|
||||
|
||||
// affected by filter
|
||||
bool getAllMissingIndexes(unsigned char* misbitfield, size_t mislen) const;
|
||||
|
@ -206,34 +196,19 @@ public:
|
|||
// filterBitfield_ is NULL, returns false.
|
||||
bool isFilterBitSet(size_t index) const;
|
||||
|
||||
const unsigned char* getBitfield() const
|
||||
{
|
||||
return bitfield_;
|
||||
}
|
||||
const unsigned char* getBitfield() const { return bitfield_; }
|
||||
|
||||
size_t getBitfieldLength() const
|
||||
{
|
||||
return bitfieldLength_;
|
||||
}
|
||||
size_t getBitfieldLength() const { return bitfieldLength_; }
|
||||
|
||||
// affected by filter
|
||||
size_t countFilteredBlock() const
|
||||
{
|
||||
return cachedNumFilteredBlock_;
|
||||
}
|
||||
size_t countFilteredBlock() const { return cachedNumFilteredBlock_; }
|
||||
|
||||
size_t countBlock() const
|
||||
{
|
||||
return blocks_;
|
||||
}
|
||||
size_t countBlock() const { return blocks_; }
|
||||
|
||||
// affected by filter
|
||||
size_t countFilteredBlockNow() const;
|
||||
|
||||
size_t getMaxIndex() const
|
||||
{
|
||||
return blocks_-1;
|
||||
}
|
||||
size_t getMaxIndex() const { return blocks_ - 1; }
|
||||
|
||||
void setBitfield(const unsigned char* bitfield, size_t bitfieldLength);
|
||||
|
||||
|
@ -253,24 +228,15 @@ public:
|
|||
|
||||
void enableFilter();
|
||||
void disableFilter();
|
||||
bool isFilterEnabled() const
|
||||
{
|
||||
return filterEnabled_;
|
||||
}
|
||||
bool isFilterEnabled() const { return filterEnabled_; }
|
||||
|
||||
// affected by filter
|
||||
int64_t getFilteredTotalLength() const
|
||||
{
|
||||
return cachedFilteredTotalLength_;
|
||||
}
|
||||
int64_t getFilteredTotalLength() const { return cachedFilteredTotalLength_; }
|
||||
|
||||
// affected by filter
|
||||
int64_t getFilteredTotalLengthNow() const;
|
||||
|
||||
int64_t getCompletedLength() const
|
||||
{
|
||||
return cachedCompletedLength_;
|
||||
}
|
||||
int64_t getCompletedLength() const { return cachedCompletedLength_; }
|
||||
|
||||
int64_t getCompletedLengthNow() const;
|
||||
|
||||
|
@ -299,10 +265,7 @@ public:
|
|||
|
||||
int64_t getMissingUnusedLength(size_t startingIndex) const;
|
||||
|
||||
const unsigned char* getFilterBitfield() const
|
||||
{
|
||||
return filterBitfield_;
|
||||
}
|
||||
const unsigned char* getFilterBitfield() const { return filterBitfield_; }
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -37,10 +37,11 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
BtAbortOutstandingRequestEvent::BtAbortOutstandingRequestEvent
|
||||
(const std::shared_ptr<Piece>& piece)
|
||||
: piece_(piece)
|
||||
{}
|
||||
BtAbortOutstandingRequestEvent::BtAbortOutstandingRequestEvent(
|
||||
const std::shared_ptr<Piece>& piece)
|
||||
: piece_(piece)
|
||||
{
|
||||
}
|
||||
|
||||
BtAbortOutstandingRequestEvent::~BtAbortOutstandingRequestEvent() {}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ class Piece;
|
|||
class BtAbortOutstandingRequestEvent {
|
||||
private:
|
||||
std::shared_ptr<Piece> piece_;
|
||||
|
||||
public:
|
||||
BtAbortOutstandingRequestEvent(const std::shared_ptr<Piece>& piece);
|
||||
~BtAbortOutstandingRequestEvent();
|
||||
|
|
|
@ -42,22 +42,24 @@ namespace aria2 {
|
|||
|
||||
const char BtAllowedFastMessage::NAME[] = "allowed fast";
|
||||
|
||||
BtAllowedFastMessage::BtAllowedFastMessage(size_t index):
|
||||
IndexBtMessage(ID, NAME, index) {}
|
||||
BtAllowedFastMessage::BtAllowedFastMessage(size_t index)
|
||||
: IndexBtMessage(ID, NAME, index)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<BtAllowedFastMessage> BtAllowedFastMessage::create
|
||||
(const unsigned char* data, size_t dataLength)
|
||||
std::unique_ptr<BtAllowedFastMessage>
|
||||
BtAllowedFastMessage::create(const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
return IndexBtMessage::create<BtAllowedFastMessage>(data, dataLength);
|
||||
}
|
||||
|
||||
void BtAllowedFastMessage::doReceivedAction() {
|
||||
if(!getPeer()->isFastExtensionEnabled()) {
|
||||
throw DL_ABORT_EX
|
||||
(fmt("%s received while fast extension is disabled",
|
||||
toString().c_str()));
|
||||
void BtAllowedFastMessage::doReceivedAction()
|
||||
{
|
||||
if (!getPeer()->isFastExtensionEnabled()) {
|
||||
throw DL_ABORT_EX(fmt("%s received while fast extension is disabled",
|
||||
toString().c_str()));
|
||||
}
|
||||
if(isMetadataGetMode()) {
|
||||
if (isMetadataGetMode()) {
|
||||
return;
|
||||
}
|
||||
getPeer()->addPeerAllowedIndex(getIndex());
|
||||
|
@ -65,11 +67,13 @@ void BtAllowedFastMessage::doReceivedAction() {
|
|||
|
||||
namespace {
|
||||
struct ThisProgressUpdate : public ProgressUpdate {
|
||||
ThisProgressUpdate(std::shared_ptr<Peer> peer, size_t index)
|
||||
: peer(std::move(peer)), index(index) {}
|
||||
ThisProgressUpdate(std::shared_ptr<Peer> peer, size_t index)
|
||||
: peer(std::move(peer)), index(index)
|
||||
{
|
||||
}
|
||||
virtual void update(size_t length, bool complete) CXX11_OVERRIDE
|
||||
{
|
||||
if(complete) {
|
||||
if (complete) {
|
||||
peer->addAmAllowedIndex(index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ public:
|
|||
|
||||
static const char NAME[];
|
||||
|
||||
static std::unique_ptr<BtAllowedFastMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtAllowedFastMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
|
||||
|
|
|
@ -104,8 +104,8 @@ public:
|
|||
virtual void processAnnounceResponse(const unsigned char* trackerResponse,
|
||||
size_t trackerResponseLength) = 0;
|
||||
|
||||
virtual void processUDPTrackerResponse
|
||||
(const std::shared_ptr<UDPTrackerRequest>& req) = 0;
|
||||
virtual void
|
||||
processUDPTrackerResponse(const std::shared_ptr<UDPTrackerRequest>& req) = 0;
|
||||
|
||||
/**
|
||||
* Returns true if no more announce is needed.
|
||||
|
|
|
@ -49,24 +49,23 @@ namespace aria2 {
|
|||
const char BtBitfieldMessage::NAME[] = "bitfield";
|
||||
|
||||
BtBitfieldMessage::BtBitfieldMessage()
|
||||
: SimpleBtMessage(ID, NAME),
|
||||
bitfieldLength_(0)
|
||||
{}
|
||||
: SimpleBtMessage(ID, NAME), bitfieldLength_(0)
|
||||
{
|
||||
}
|
||||
|
||||
BtBitfieldMessage::BtBitfieldMessage
|
||||
(const unsigned char* bitfield, size_t bitfieldLength)
|
||||
: SimpleBtMessage(ID, NAME),
|
||||
bitfieldLength_(0)
|
||||
BtBitfieldMessage::BtBitfieldMessage(const unsigned char* bitfield,
|
||||
size_t bitfieldLength)
|
||||
: SimpleBtMessage(ID, NAME), bitfieldLength_(0)
|
||||
{
|
||||
setBitfield(bitfield, bitfieldLength);
|
||||
}
|
||||
|
||||
BtBitfieldMessage::~BtBitfieldMessage()
|
||||
{}
|
||||
BtBitfieldMessage::~BtBitfieldMessage() {}
|
||||
|
||||
void BtBitfieldMessage::setBitfield
|
||||
(const unsigned char* bitfield, size_t bitfieldLength) {
|
||||
if(bitfield_.get() == bitfield) {
|
||||
void BtBitfieldMessage::setBitfield(const unsigned char* bitfield,
|
||||
size_t bitfieldLength)
|
||||
{
|
||||
if (bitfield_.get() == bitfield) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -78,44 +77,45 @@ void BtBitfieldMessage::setBitfield
|
|||
std::unique_ptr<BtBitfieldMessage>
|
||||
BtBitfieldMessage::create(const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
bittorrent::assertPayloadLengthGreater(1,dataLength, NAME);
|
||||
bittorrent::assertPayloadLengthGreater(1, dataLength, NAME);
|
||||
bittorrent::assertID(ID, data, NAME);
|
||||
auto message = make_unique<BtBitfieldMessage>();
|
||||
message->setBitfield(data+1, dataLength-1);
|
||||
message->setBitfield(data + 1, dataLength - 1);
|
||||
return message;
|
||||
}
|
||||
|
||||
void BtBitfieldMessage::doReceivedAction() {
|
||||
if(isMetadataGetMode()) {
|
||||
void BtBitfieldMessage::doReceivedAction()
|
||||
{
|
||||
if (isMetadataGetMode()) {
|
||||
return;
|
||||
}
|
||||
getPieceStorage()->updatePieceStats(bitfield_.get(), bitfieldLength_,
|
||||
getPeer()->getBitfield());
|
||||
getPeer()->setBitfield(bitfield_.get(), bitfieldLength_);
|
||||
if(getPeer()->isSeeder() && getPieceStorage()->downloadFinished()) {
|
||||
if (getPeer()->isSeeder() && getPieceStorage()->downloadFinished()) {
|
||||
throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* BtBitfieldMessage::createMessage() {
|
||||
unsigned char* BtBitfieldMessage::createMessage()
|
||||
{
|
||||
/**
|
||||
* len --- 1+bitfieldLength, 4bytes
|
||||
* id --- 5, 1byte
|
||||
* bitfield --- bitfield, bitfieldLength bytes
|
||||
* total: 5+bitfieldLength bytes
|
||||
*/
|
||||
const size_t msgLength = 5+bitfieldLength_;
|
||||
const size_t msgLength = 5 + bitfieldLength_;
|
||||
auto msg = new unsigned char[msgLength];
|
||||
bittorrent::createPeerMessageString(msg, msgLength, 1+bitfieldLength_, ID);
|
||||
memcpy(msg+5, bitfield_.get(), bitfieldLength_);
|
||||
bittorrent::createPeerMessageString(msg, msgLength, 1 + bitfieldLength_, ID);
|
||||
memcpy(msg + 5, bitfield_.get(), bitfieldLength_);
|
||||
return msg;
|
||||
}
|
||||
|
||||
size_t BtBitfieldMessage::getMessageLength() {
|
||||
return 5+bitfieldLength_;
|
||||
}
|
||||
size_t BtBitfieldMessage::getMessageLength() { return 5 + bitfieldLength_; }
|
||||
|
||||
std::string BtBitfieldMessage::toString() const {
|
||||
std::string BtBitfieldMessage::toString() const
|
||||
{
|
||||
std::string s = NAME;
|
||||
s += " ";
|
||||
s += util::toHex(bitfield_.get(), bitfieldLength_);
|
||||
|
|
|
@ -43,6 +43,7 @@ class BtBitfieldMessage : public SimpleBtMessage {
|
|||
private:
|
||||
std::unique_ptr<unsigned char[]> bitfield_;
|
||||
size_t bitfieldLength_;
|
||||
|
||||
public:
|
||||
BtBitfieldMessage();
|
||||
|
||||
|
@ -60,8 +61,8 @@ public:
|
|||
|
||||
size_t getBitfieldLength() const { return bitfieldLength_; }
|
||||
|
||||
static std::unique_ptr<BtBitfieldMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtBitfieldMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
|
||||
|
|
|
@ -38,19 +38,18 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
BtBitfieldMessageValidator::BtBitfieldMessageValidator
|
||||
(const BtBitfieldMessage* message, size_t numPiece)
|
||||
: message_(message),
|
||||
numPiece_(numPiece)
|
||||
{}
|
||||
BtBitfieldMessageValidator::BtBitfieldMessageValidator(
|
||||
const BtBitfieldMessage* message, size_t numPiece)
|
||||
: message_(message), numPiece_(numPiece)
|
||||
{
|
||||
}
|
||||
|
||||
BtBitfieldMessageValidator::~BtBitfieldMessageValidator() {}
|
||||
|
||||
void BtBitfieldMessageValidator::validate()
|
||||
{
|
||||
bittorrent::checkBitfield(message_->getBitfield(),
|
||||
message_->getBitfieldLength(),
|
||||
numPiece_);
|
||||
message_->getBitfieldLength(), numPiece_);
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -45,9 +45,9 @@ class BtBitfieldMessageValidator : public BtMessageValidator {
|
|||
private:
|
||||
const BtBitfieldMessage* message_;
|
||||
size_t numPiece_;
|
||||
|
||||
public:
|
||||
BtBitfieldMessageValidator(const BtBitfieldMessage* message,
|
||||
size_t numPiece);
|
||||
BtBitfieldMessageValidator(const BtBitfieldMessage* message, size_t numPiece);
|
||||
~BtBitfieldMessageValidator();
|
||||
|
||||
virtual void validate() CXX11_OVERRIDE;
|
||||
|
|
|
@ -39,23 +39,24 @@ namespace aria2 {
|
|||
|
||||
const char BtCancelMessage::NAME[] = "cancel";
|
||||
|
||||
BtCancelMessage::BtCancelMessage
|
||||
(size_t index, int32_t begin, int32_t length)
|
||||
:RangeBtMessage(ID, NAME, index, begin, length) {}
|
||||
BtCancelMessage::BtCancelMessage(size_t index, int32_t begin, int32_t length)
|
||||
: RangeBtMessage(ID, NAME, index, begin, length)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<BtCancelMessage> BtCancelMessage::create
|
||||
(const unsigned char* data, size_t dataLength)
|
||||
std::unique_ptr<BtCancelMessage>
|
||||
BtCancelMessage::create(const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
return RangeBtMessage::create<BtCancelMessage>(data, dataLength);
|
||||
}
|
||||
|
||||
void BtCancelMessage::doReceivedAction()
|
||||
{
|
||||
if(isMetadataGetMode()) {
|
||||
if (isMetadataGetMode()) {
|
||||
return;
|
||||
}
|
||||
getBtMessageDispatcher()->doCancelSendingPieceAction
|
||||
(getIndex(), getBegin(), getLength());
|
||||
getBtMessageDispatcher()->doCancelSendingPieceAction(getIndex(), getBegin(),
|
||||
getLength());
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -47,8 +47,8 @@ public:
|
|||
|
||||
static const char NAME[];
|
||||
|
||||
static std::unique_ptr<BtCancelMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtCancelMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
};
|
||||
|
|
|
@ -44,9 +44,12 @@ private:
|
|||
size_t index_;
|
||||
int32_t begin_;
|
||||
int32_t length_;
|
||||
|
||||
public:
|
||||
BtCancelSendingPieceEvent(size_t index, int32_t begin, int32_t length):
|
||||
index_(index), begin_(begin), length_(length) {}
|
||||
BtCancelSendingPieceEvent(size_t index, int32_t begin, int32_t length)
|
||||
: index_(index), begin_(begin), length_(length)
|
||||
{
|
||||
}
|
||||
|
||||
size_t getIndex() const { return index_; }
|
||||
|
||||
|
|
|
@ -46,55 +46,52 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
BtCheckIntegrityEntry::BtCheckIntegrityEntry(RequestGroup* requestGroup):
|
||||
PieceHashCheckIntegrityEntry(requestGroup, nullptr) {}
|
||||
BtCheckIntegrityEntry::BtCheckIntegrityEntry(RequestGroup* requestGroup)
|
||||
: PieceHashCheckIntegrityEntry(requestGroup, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
BtCheckIntegrityEntry::~BtCheckIntegrityEntry() {}
|
||||
|
||||
void BtCheckIntegrityEntry::onDownloadIncomplete
|
||||
(std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
void BtCheckIntegrityEntry::onDownloadIncomplete(
|
||||
std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
{
|
||||
auto& ps = getRequestGroup()->getPieceStorage();
|
||||
ps->onDownloadIncomplete();
|
||||
if(getRequestGroup()->getOption()->getAsBool(PREF_HASH_CHECK_ONLY)) {
|
||||
if (getRequestGroup()->getOption()->getAsBool(PREF_HASH_CHECK_ONLY)) {
|
||||
return;
|
||||
}
|
||||
const auto& diskAdaptor = ps->getDiskAdaptor();
|
||||
if(diskAdaptor->isReadOnlyEnabled()) {
|
||||
if (diskAdaptor->isReadOnlyEnabled()) {
|
||||
// Now reopen DiskAdaptor with read only disabled.
|
||||
diskAdaptor->closeFile();
|
||||
diskAdaptor->disableReadOnly();
|
||||
diskAdaptor->openFile();
|
||||
}
|
||||
proceedFileAllocation(commands,
|
||||
make_unique<BtFileAllocationEntry>
|
||||
(getRequestGroup()),
|
||||
e);
|
||||
proceedFileAllocation(
|
||||
commands, make_unique<BtFileAllocationEntry>(getRequestGroup()), e);
|
||||
}
|
||||
|
||||
void BtCheckIntegrityEntry::onDownloadFinished
|
||||
(std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
void BtCheckIntegrityEntry::onDownloadFinished(
|
||||
std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
{
|
||||
auto group = getRequestGroup();
|
||||
const auto& option = group->getOption();
|
||||
if(option->getAsBool(PREF_BT_ENABLE_HOOK_AFTER_HASH_CHECK)) {
|
||||
if (option->getAsBool(PREF_BT_ENABLE_HOOK_AFTER_HASH_CHECK)) {
|
||||
util::executeHookByOptName(group, option.get(),
|
||||
PREF_ON_BT_DOWNLOAD_COMPLETE);
|
||||
SingletonHolder<Notifier>::instance()->notifyDownloadEvent
|
||||
(EVENT_ON_BT_DOWNLOAD_COMPLETE, group);
|
||||
SingletonHolder<Notifier>::instance()->notifyDownloadEvent(
|
||||
EVENT_ON_BT_DOWNLOAD_COMPLETE, group);
|
||||
}
|
||||
// TODO Currently,when all the checksums
|
||||
// are valid, then aria2 goes to seeding mode. Sometimes it is better
|
||||
// to exit rather than doing seeding. So, it would be good to toggle this
|
||||
// behavior.
|
||||
if(!option->getAsBool(PREF_HASH_CHECK_ONLY) &&
|
||||
option->getAsBool(PREF_BT_HASH_CHECK_SEED)) {
|
||||
proceedFileAllocation(commands,
|
||||
make_unique<BtFileAllocationEntry>
|
||||
(getRequestGroup()),
|
||||
e);
|
||||
if (!option->getAsBool(PREF_HASH_CHECK_ONLY) &&
|
||||
option->getAsBool(PREF_BT_HASH_CHECK_SEED)) {
|
||||
proceedFileAllocation(
|
||||
commands, make_unique<BtFileAllocationEntry>(getRequestGroup()), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -45,13 +45,13 @@ public:
|
|||
|
||||
virtual ~BtCheckIntegrityEntry();
|
||||
|
||||
virtual void onDownloadFinished
|
||||
(std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
CXX11_OVERRIDE;
|
||||
virtual void
|
||||
onDownloadFinished(std::vector<std::unique_ptr<Command>>& commands,
|
||||
DownloadEngine* e) CXX11_OVERRIDE;
|
||||
|
||||
virtual void onDownloadIncomplete
|
||||
(std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
CXX11_OVERRIDE;
|
||||
virtual void
|
||||
onDownloadIncomplete(std::vector<std::unique_ptr<Command>>& commands,
|
||||
DownloadEngine* e) CXX11_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -42,17 +42,17 @@ namespace aria2 {
|
|||
|
||||
const char BtChokeMessage::NAME[] = "choke";
|
||||
|
||||
BtChokeMessage::BtChokeMessage():ZeroBtMessage{ID, NAME} {}
|
||||
BtChokeMessage::BtChokeMessage() : ZeroBtMessage{ID, NAME} {}
|
||||
|
||||
std::unique_ptr<BtChokeMessage> BtChokeMessage::create
|
||||
(const unsigned char* data, size_t dataLength)
|
||||
std::unique_ptr<BtChokeMessage>
|
||||
BtChokeMessage::create(const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
return ZeroBtMessage::create<BtChokeMessage>(data, dataLength);
|
||||
}
|
||||
|
||||
void BtChokeMessage::doReceivedAction()
|
||||
{
|
||||
if(isMetadataGetMode()) {
|
||||
if (isMetadataGetMode()) {
|
||||
return;
|
||||
}
|
||||
getPeer()->peerChoking(true);
|
||||
|
@ -60,19 +60,17 @@ void BtChokeMessage::doReceivedAction()
|
|||
getBtRequestFactory()->doChokedAction();
|
||||
}
|
||||
|
||||
bool BtChokeMessage::sendPredicate() const
|
||||
{
|
||||
return !getPeer()->amChoking();
|
||||
}
|
||||
bool BtChokeMessage::sendPredicate() const { return !getPeer()->amChoking(); }
|
||||
|
||||
namespace {
|
||||
struct ThisProgressUpdate : public ProgressUpdate {
|
||||
ThisProgressUpdate(std::shared_ptr<Peer> peer,
|
||||
BtMessageDispatcher* disp)
|
||||
: peer(std::move(peer)), disp(disp) {}
|
||||
ThisProgressUpdate(std::shared_ptr<Peer> peer, BtMessageDispatcher* disp)
|
||||
: peer(std::move(peer)), disp(disp)
|
||||
{
|
||||
}
|
||||
virtual void update(size_t length, bool complete) CXX11_OVERRIDE
|
||||
{
|
||||
if(complete) {
|
||||
if (complete) {
|
||||
peer->amChoking(true);
|
||||
disp->doChokingAction();
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ public:
|
|||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
|
||||
static std::unique_ptr<BtChokeMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtChokeMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual bool sendPredicate() const CXX11_OVERRIDE;
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
class BtChokingEvent {};
|
||||
class BtChokingEvent {
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
||||
|
|
|
@ -53,12 +53,11 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
BtDependency::BtDependency
|
||||
(RequestGroup* dependant,
|
||||
const std::shared_ptr<RequestGroup>& dependee)
|
||||
: dependant_(dependant),
|
||||
dependee_(dependee)
|
||||
{}
|
||||
BtDependency::BtDependency(RequestGroup* dependant,
|
||||
const std::shared_ptr<RequestGroup>& dependee)
|
||||
: dependant_(dependant), dependee_(dependee)
|
||||
{
|
||||
}
|
||||
|
||||
BtDependency::~BtDependency() {}
|
||||
|
||||
|
@ -77,9 +76,8 @@ void copyValues(const std::shared_ptr<FileEntry>& d,
|
|||
|
||||
namespace {
|
||||
struct EntryCmp {
|
||||
bool operator()
|
||||
(const std::shared_ptr<FileEntry>& lhs,
|
||||
const std::shared_ptr<FileEntry>& rhs) const
|
||||
bool operator()(const std::shared_ptr<FileEntry>& lhs,
|
||||
const std::shared_ptr<FileEntry>& rhs) const
|
||||
{
|
||||
return lhs->getOriginalName() < rhs->getOriginalName();
|
||||
}
|
||||
|
@ -88,53 +86,54 @@ struct EntryCmp {
|
|||
|
||||
bool BtDependency::resolve()
|
||||
{
|
||||
if(!dependee_) {
|
||||
if (!dependee_) {
|
||||
return true;
|
||||
}
|
||||
if(dependee_->getNumCommand() == 0 && dependee_->downloadFinished()) {
|
||||
if (dependee_->getNumCommand() == 0 && dependee_->downloadFinished()) {
|
||||
std::shared_ptr<RequestGroup> dependee = dependee_;
|
||||
// cut reference here
|
||||
dependee_.reset();
|
||||
auto context = std::make_shared<DownloadContext>();
|
||||
try {
|
||||
std::shared_ptr<DiskAdaptor> diskAdaptor =
|
||||
dependee->getPieceStorage()->getDiskAdaptor();
|
||||
dependee->getPieceStorage()->getDiskAdaptor();
|
||||
diskAdaptor->openExistingFile();
|
||||
std::string content = util::toString(diskAdaptor);
|
||||
if(dependee->getDownloadContext()->hasAttribute(CTX_ATTR_BT)) {
|
||||
if (dependee->getDownloadContext()->hasAttribute(CTX_ATTR_BT)) {
|
||||
auto attrs =
|
||||
bittorrent::getTorrentAttrs(dependee->getDownloadContext());
|
||||
bittorrent::loadFromMemory
|
||||
(bittorrent::metadata2Torrent(content, attrs), context,
|
||||
dependant_->getOption(), "default");
|
||||
bittorrent::getTorrentAttrs(dependee->getDownloadContext());
|
||||
bittorrent::loadFromMemory(bittorrent::metadata2Torrent(content, attrs),
|
||||
context, dependant_->getOption(), "default");
|
||||
// We don't call bittorrent::adjustAnnounceUri() because it
|
||||
// has already been called with attrs.
|
||||
} else {
|
||||
bittorrent::loadFromMemory
|
||||
(content, context, dependant_->getOption(),
|
||||
File(dependee->getFirstFilePath()).getBasename());
|
||||
}
|
||||
else {
|
||||
bittorrent::loadFromMemory(
|
||||
content, context, dependant_->getOption(),
|
||||
File(dependee->getFirstFilePath()).getBasename());
|
||||
bittorrent::adjustAnnounceUri(bittorrent::getTorrentAttrs(context),
|
||||
dependant_->getOption());
|
||||
}
|
||||
const std::vector<std::shared_ptr<FileEntry> >& fileEntries =
|
||||
context->getFileEntries();
|
||||
for (auto &fe : fileEntries) {
|
||||
auto &uri = fe->getRemainingUris();
|
||||
const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
|
||||
context->getFileEntries();
|
||||
for (auto& fe : fileEntries) {
|
||||
auto& uri = fe->getRemainingUris();
|
||||
std::shuffle(std::begin(uri), std::end(uri),
|
||||
*SimpleRandomizer::getInstance());
|
||||
}
|
||||
const std::vector<std::shared_ptr<FileEntry> >& dependantFileEntries =
|
||||
dependant_->getDownloadContext()->getFileEntries();
|
||||
const std::vector<std::shared_ptr<FileEntry>>& dependantFileEntries =
|
||||
dependant_->getDownloadContext()->getFileEntries();
|
||||
// If dependant's FileEntry::getOriginalName() is empty, we
|
||||
// assume that torrent is single file. In Metalink3, this is
|
||||
// always assumed.
|
||||
if(fileEntries.size() == 1 && dependantFileEntries.size() == 1 &&
|
||||
dependantFileEntries[0]->getOriginalName().empty()) {
|
||||
if (fileEntries.size() == 1 && dependantFileEntries.size() == 1 &&
|
||||
dependantFileEntries[0]->getOriginalName().empty()) {
|
||||
copyValues(fileEntries[0], dependantFileEntries[0]);
|
||||
} else {
|
||||
std::vector<std::shared_ptr<FileEntry> > destFiles;
|
||||
}
|
||||
else {
|
||||
std::vector<std::shared_ptr<FileEntry>> destFiles;
|
||||
destFiles.reserve(fileEntries.size());
|
||||
for(auto & e : fileEntries) {
|
||||
for (auto& e : fileEntries) {
|
||||
e->setRequested(false);
|
||||
destFiles.push_back(e);
|
||||
}
|
||||
|
@ -142,19 +141,21 @@ bool BtDependency::resolve()
|
|||
// Copy file path in dependant_'s FileEntries to newly created
|
||||
// context's FileEntries to endorse the path structure of
|
||||
// dependant_. URIs and singleHostMultiConnection are also copied.
|
||||
for(const auto& e: dependantFileEntries){
|
||||
for (const auto& e : dependantFileEntries) {
|
||||
const auto d = std::lower_bound(std::begin(destFiles),
|
||||
std::end(destFiles), e, EntryCmp());
|
||||
if(d == std::end(destFiles) ||
|
||||
(*d)->getOriginalName() != e->getOriginalName()) {
|
||||
throw DL_ABORT_EX
|
||||
(fmt("No entry %s in torrent file", e->getOriginalName().c_str()));
|
||||
} else {
|
||||
if (d == std::end(destFiles) ||
|
||||
(*d)->getOriginalName() != e->getOriginalName()) {
|
||||
throw DL_ABORT_EX(fmt("No entry %s in torrent file",
|
||||
e->getOriginalName().c_str()));
|
||||
}
|
||||
else {
|
||||
copyValues(*d, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(RecoverableException& e) {
|
||||
}
|
||||
catch (RecoverableException& e) {
|
||||
A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
|
||||
A2_LOG_INFO(fmt("BtDependency for GID#%s failed. Go without Bt.",
|
||||
GroupId::toHex(dependant_->getGID()).c_str()));
|
||||
|
@ -164,14 +165,16 @@ bool BtDependency::resolve()
|
|||
GroupId::toHex(dependant_->getGID()).c_str()));
|
||||
dependant_->setDownloadContext(context);
|
||||
return true;
|
||||
} else if(dependee_->getNumCommand() == 0) {
|
||||
}
|
||||
else if (dependee_->getNumCommand() == 0) {
|
||||
// dependee_'s download failed.
|
||||
// cut reference here
|
||||
dependee_.reset();
|
||||
A2_LOG_INFO(fmt("BtDependency for GID#%s failed. Go without Bt.",
|
||||
GroupId::toHex(dependant_->getGID()).c_str()));
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,11 +44,11 @@ namespace aria2 {
|
|||
class RequestGroup;
|
||||
class Option;
|
||||
|
||||
class BtDependency : public Dependency
|
||||
{
|
||||
class BtDependency : public Dependency {
|
||||
private:
|
||||
RequestGroup* dependant_;
|
||||
std::shared_ptr<RequestGroup> dependee_;
|
||||
|
||||
public:
|
||||
BtDependency(RequestGroup* dependant,
|
||||
const std::shared_ptr<RequestGroup>& dependee);
|
||||
|
|
|
@ -50,12 +50,13 @@ namespace aria2 {
|
|||
|
||||
const char BtExtendedMessage::NAME[] = "extended";
|
||||
|
||||
BtExtendedMessage::BtExtendedMessage
|
||||
(std::unique_ptr<ExtensionMessage> extensionMessage):
|
||||
SimpleBtMessage(ID, NAME),
|
||||
extensionMessage_(std::move(extensionMessage)),
|
||||
msgLength_(0)
|
||||
{}
|
||||
BtExtendedMessage::BtExtendedMessage(
|
||||
std::unique_ptr<ExtensionMessage> extensionMessage)
|
||||
: SimpleBtMessage(ID, NAME),
|
||||
extensionMessage_(std::move(extensionMessage)),
|
||||
msgLength_(0)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char* BtExtendedMessage::createMessage()
|
||||
{
|
||||
|
@ -67,17 +68,18 @@ unsigned char* BtExtendedMessage::createMessage()
|
|||
* total: 6+extpayload.length bytes
|
||||
*/
|
||||
std::string payload = extensionMessage_->getPayload();
|
||||
msgLength_ = 6+payload.size();
|
||||
msgLength_ = 6 + payload.size();
|
||||
auto msg = new unsigned char[msgLength_];
|
||||
bittorrent::createPeerMessageString(msg, msgLength_, 2+payload.size(), ID);
|
||||
*(msg+5) = extensionMessage_->getExtensionMessageID();
|
||||
memcpy(msg+6, payload.data(), payload.size());
|
||||
bittorrent::createPeerMessageString(msg, msgLength_, 2 + payload.size(), ID);
|
||||
*(msg + 5) = extensionMessage_->getExtensionMessageID();
|
||||
memcpy(msg + 6, payload.data(), payload.size());
|
||||
return msg;
|
||||
}
|
||||
|
||||
size_t BtExtendedMessage::getMessageLength() {
|
||||
if(!msgLength_) {
|
||||
msgLength_ = 6+extensionMessage_->getPayload().size();
|
||||
size_t BtExtendedMessage::getMessageLength()
|
||||
{
|
||||
if (!msgLength_) {
|
||||
msgLength_ = 6 + extensionMessage_->getPayload().size();
|
||||
}
|
||||
return msgLength_;
|
||||
}
|
||||
|
@ -87,7 +89,8 @@ bool BtExtendedMessage::sendPredicate() const
|
|||
return getPeer()->isExtendedMessagingEnabled();
|
||||
}
|
||||
|
||||
std::string BtExtendedMessage::toString() const {
|
||||
std::string BtExtendedMessage::toString() const
|
||||
{
|
||||
std::string s = NAME;
|
||||
s += " ";
|
||||
s += extensionMessage_->toString();
|
||||
|
@ -102,13 +105,13 @@ BtExtendedMessage::create(ExtensionMessageFactory* factory,
|
|||
bittorrent::assertPayloadLengthGreater(1, dataLength, NAME);
|
||||
bittorrent::assertID(ID, data, NAME);
|
||||
assert(factory);
|
||||
return make_unique<BtExtendedMessage>
|
||||
(factory->createMessage(data+1, dataLength-1));
|
||||
return make_unique<BtExtendedMessage>(
|
||||
factory->createMessage(data + 1, dataLength - 1));
|
||||
}
|
||||
|
||||
void BtExtendedMessage::doReceivedAction()
|
||||
{
|
||||
if(extensionMessage_) {
|
||||
if (extensionMessage_) {
|
||||
extensionMessage_->doReceivedAction();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,25 +41,23 @@ namespace aria2 {
|
|||
class ExtensionMessage;
|
||||
class ExtensionMessageFactory;
|
||||
|
||||
class BtExtendedMessage:public SimpleBtMessage
|
||||
{
|
||||
class BtExtendedMessage : public SimpleBtMessage {
|
||||
private:
|
||||
std::unique_ptr<ExtensionMessage> extensionMessage_;
|
||||
|
||||
size_t msgLength_;
|
||||
|
||||
public:
|
||||
BtExtendedMessage(std::unique_ptr<ExtensionMessage> extensionMessage =
|
||||
std::unique_ptr<ExtensionMessage>{});
|
||||
std::unique_ptr<ExtensionMessage>{});
|
||||
|
||||
static const uint8_t ID = 20;
|
||||
|
||||
static const char NAME[];
|
||||
|
||||
static std::unique_ptr<BtExtendedMessage> create
|
||||
(ExtensionMessageFactory* factory,
|
||||
const std::shared_ptr<Peer>& peer,
|
||||
const unsigned char* data,
|
||||
size_t dataLength);
|
||||
static std::unique_ptr<BtExtendedMessage>
|
||||
create(ExtensionMessageFactory* factory, const std::shared_ptr<Peer>& peer,
|
||||
const unsigned char* data, size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
|
||||
|
|
|
@ -50,36 +50,39 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
BtFileAllocationEntry::BtFileAllocationEntry(RequestGroup* requestGroup):
|
||||
FileAllocationEntry(requestGroup, nullptr) {}
|
||||
BtFileAllocationEntry::BtFileAllocationEntry(RequestGroup* requestGroup)
|
||||
: FileAllocationEntry(requestGroup, nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
BtFileAllocationEntry::~BtFileAllocationEntry() {}
|
||||
|
||||
void BtFileAllocationEntry::prepareForNextAction
|
||||
(std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
void BtFileAllocationEntry::prepareForNextAction(
|
||||
std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
{
|
||||
auto &option = getRequestGroup()->getOption();
|
||||
auto& option = getRequestGroup()->getOption();
|
||||
|
||||
BtSetup().setup(commands, getRequestGroup(), e, option.get());
|
||||
if(option->getAsBool(PREF_ENABLE_MMAP) &&
|
||||
option->get(PREF_FILE_ALLOCATION) != V_NONE) {
|
||||
if (option->getAsBool(PREF_ENABLE_MMAP) &&
|
||||
option->get(PREF_FILE_ALLOCATION) != V_NONE) {
|
||||
getRequestGroup()->getPieceStorage()->getDiskAdaptor()->enableMmap();
|
||||
}
|
||||
if(!getRequestGroup()->downloadFinished()) {
|
||||
if (!getRequestGroup()->downloadFinished()) {
|
||||
// For DownloadContext::resetDownloadStartTime(), see also
|
||||
// RequestGroup::createInitialCommand()
|
||||
getRequestGroup()->getDownloadContext()->resetDownloadStartTime();
|
||||
const std::vector<std::shared_ptr<FileEntry> >& fileEntries =
|
||||
getRequestGroup()->getDownloadContext()->getFileEntries();
|
||||
if(isUriSuppliedForRequsetFileEntry
|
||||
(std::begin(fileEntries), std::end(fileEntries))) {
|
||||
const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
|
||||
getRequestGroup()->getDownloadContext()->getFileEntries();
|
||||
if (isUriSuppliedForRequsetFileEntry(std::begin(fileEntries),
|
||||
std::end(fileEntries))) {
|
||||
getRequestGroup()->createNextCommandWithAdj(commands, e, 0);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
#ifdef __MINGW32__
|
||||
const std::shared_ptr<DiskAdaptor>& diskAdaptor =
|
||||
getRequestGroup()->getPieceStorage()->getDiskAdaptor();
|
||||
if(!diskAdaptor->isReadOnlyEnabled()) {
|
||||
getRequestGroup()->getPieceStorage()->getDiskAdaptor();
|
||||
if (!diskAdaptor->isReadOnlyEnabled()) {
|
||||
// On Windows, if aria2 opens files with GENERIC_WRITE access
|
||||
// right, some programs cannot open them aria2 is seeding. To
|
||||
// avoid this situation, re-open the files with read-only
|
||||
|
|
|
@ -45,9 +45,9 @@ public:
|
|||
|
||||
virtual ~BtFileAllocationEntry();
|
||||
|
||||
virtual void prepareForNextAction
|
||||
(std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
|
||||
CXX11_OVERRIDE;
|
||||
virtual void
|
||||
prepareForNextAction(std::vector<std::unique_ptr<Command>>& commands,
|
||||
DownloadEngine* e) CXX11_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -45,23 +45,21 @@ namespace aria2 {
|
|||
const char BtHandshakeMessage::NAME[] = "handshake";
|
||||
|
||||
const unsigned char* BtHandshakeMessage::BT_PSTR =
|
||||
reinterpret_cast<const unsigned char*>("BitTorrent protocol");
|
||||
reinterpret_cast<const unsigned char*>("BitTorrent protocol");
|
||||
|
||||
BtHandshakeMessage::BtHandshakeMessage():SimpleBtMessage(ID, NAME)
|
||||
{
|
||||
init();
|
||||
}
|
||||
BtHandshakeMessage::BtHandshakeMessage() : SimpleBtMessage(ID, NAME) { init(); }
|
||||
|
||||
BtHandshakeMessage::BtHandshakeMessage(const unsigned char* infoHash,
|
||||
const unsigned char* peerId):
|
||||
SimpleBtMessage(ID, NAME)
|
||||
const unsigned char* peerId)
|
||||
: SimpleBtMessage(ID, NAME)
|
||||
{
|
||||
init();
|
||||
memcpy(infoHash_, infoHash, INFO_HASH_LENGTH);
|
||||
memcpy(peerId_, peerId, PEER_ID_LENGTH);
|
||||
}
|
||||
|
||||
void BtHandshakeMessage::init() {
|
||||
void BtHandshakeMessage::init()
|
||||
{
|
||||
pstrlen_ = 19;
|
||||
pstr_ = new unsigned char[PSTR_LENGTH];
|
||||
reserved_ = new unsigned char[RESERVED_LENGTH];
|
||||
|
@ -91,37 +89,33 @@ unsigned char* BtHandshakeMessage::createMessage()
|
|||
{
|
||||
auto msg = new unsigned char[MESSAGE_LENGTH];
|
||||
msg[0] = pstrlen_;
|
||||
memcpy(msg+1, pstr_, PSTR_LENGTH);
|
||||
memcpy(msg+20, reserved_, RESERVED_LENGTH);
|
||||
memcpy(msg+28, infoHash_, INFO_HASH_LENGTH);
|
||||
memcpy(msg+48, peerId_, PEER_ID_LENGTH);
|
||||
memcpy(msg + 1, pstr_, PSTR_LENGTH);
|
||||
memcpy(msg + 20, reserved_, RESERVED_LENGTH);
|
||||
memcpy(msg + 28, infoHash_, INFO_HASH_LENGTH);
|
||||
memcpy(msg + 48, peerId_, PEER_ID_LENGTH);
|
||||
return msg;
|
||||
}
|
||||
|
||||
size_t BtHandshakeMessage::getMessageLength() {
|
||||
return MESSAGE_LENGTH;
|
||||
}
|
||||
size_t BtHandshakeMessage::getMessageLength() { return MESSAGE_LENGTH; }
|
||||
|
||||
std::string BtHandshakeMessage::toString() const {
|
||||
return fmt("%s peerId=%s, reserved=%s",
|
||||
NAME,
|
||||
std::string BtHandshakeMessage::toString() const
|
||||
{
|
||||
return fmt("%s peerId=%s, reserved=%s", NAME,
|
||||
util::percentEncode(peerId_, PEER_ID_LENGTH).c_str(),
|
||||
util::toHex(reserved_, RESERVED_LENGTH).c_str());
|
||||
}
|
||||
|
||||
bool BtHandshakeMessage::isFastExtensionSupported() const {
|
||||
return reserved_[7]&0x04u;
|
||||
bool BtHandshakeMessage::isFastExtensionSupported() const
|
||||
{
|
||||
return reserved_[7] & 0x04u;
|
||||
}
|
||||
|
||||
bool BtHandshakeMessage::isExtendedMessagingEnabled() const
|
||||
{
|
||||
return reserved_[5]&0x10u;
|
||||
return reserved_[5] & 0x10u;
|
||||
}
|
||||
|
||||
bool BtHandshakeMessage::isDHTEnabled() const
|
||||
{
|
||||
return reserved_[7]&0x01u;
|
||||
}
|
||||
bool BtHandshakeMessage::isDHTEnabled() const { return reserved_[7] & 0x01u; }
|
||||
|
||||
void BtHandshakeMessage::setInfoHash(const unsigned char* infoHash)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
static const unsigned char* BT_PSTR;
|
||||
static const size_t RESERVED_LENGTH = 8;
|
||||
static const size_t MESSAGE_LENGTH = 68;
|
||||
|
||||
private:
|
||||
uint8_t pstrlen_;
|
||||
unsigned char* pstr_;
|
||||
|
@ -52,29 +53,32 @@ private:
|
|||
unsigned char* infoHash_;
|
||||
unsigned char* peerId_;
|
||||
void init();
|
||||
|
||||
public:
|
||||
BtHandshakeMessage();
|
||||
/**
|
||||
* infoHash must be 20 byte length.
|
||||
* peerId must be 20 byte length.
|
||||
*/
|
||||
BtHandshakeMessage(const unsigned char* infoHash, const unsigned char* peerId);
|
||||
BtHandshakeMessage(const unsigned char* infoHash,
|
||||
const unsigned char* peerId);
|
||||
|
||||
static std::unique_ptr<BtHandshakeMessage>
|
||||
create(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtHandshakeMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual ~BtHandshakeMessage() {
|
||||
delete [] pstr_;
|
||||
delete [] reserved_;
|
||||
delete [] infoHash_;
|
||||
delete [] peerId_;
|
||||
virtual ~BtHandshakeMessage()
|
||||
{
|
||||
delete[] pstr_;
|
||||
delete[] reserved_;
|
||||
delete[] infoHash_;
|
||||
delete[] peerId_;
|
||||
}
|
||||
|
||||
static const uint8_t ID = INT8_MAX;
|
||||
|
||||
static const char NAME[];
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE {};
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE{};
|
||||
|
||||
virtual unsigned char* createMessage() CXX11_OVERRIDE;
|
||||
|
||||
|
@ -90,34 +94,25 @@ public:
|
|||
|
||||
void setDHTEnabled(bool enabled)
|
||||
{
|
||||
if(enabled) {
|
||||
if (enabled) {
|
||||
reserved_[7] |= 0x01u;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
reserved_[7] &= ~0x01u;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t getPstrlen() const {
|
||||
return pstrlen_;
|
||||
}
|
||||
uint8_t getPstrlen() const { return pstrlen_; }
|
||||
|
||||
const unsigned char* getPstr() const {
|
||||
return pstr_;
|
||||
}
|
||||
const unsigned char* getPstr() const { return pstr_; }
|
||||
|
||||
const unsigned char* getReserved() const {
|
||||
return reserved_;
|
||||
}
|
||||
const unsigned char* getReserved() const { return reserved_; }
|
||||
|
||||
const unsigned char* getInfoHash() const {
|
||||
return infoHash_;
|
||||
}
|
||||
const unsigned char* getInfoHash() const { return infoHash_; }
|
||||
|
||||
void setInfoHash(const unsigned char* infoHash);
|
||||
|
||||
const unsigned char* getPeerId() const {
|
||||
return peerId_;
|
||||
}
|
||||
const unsigned char* getPeerId() const { return peerId_; }
|
||||
|
||||
void setPeerId(const unsigned char* peerId);
|
||||
};
|
||||
|
|
|
@ -43,9 +43,9 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
BtHandshakeMessageValidator::BtHandshakeMessageValidator
|
||||
(const BtHandshakeMessage* message, const unsigned char* infoHash)
|
||||
: message_(message)
|
||||
BtHandshakeMessageValidator::BtHandshakeMessageValidator(
|
||||
const BtHandshakeMessage* message, const unsigned char* infoHash)
|
||||
: message_(message)
|
||||
{
|
||||
memcpy(infoHash_, infoHash, sizeof(infoHash_));
|
||||
}
|
||||
|
@ -54,22 +54,20 @@ BtHandshakeMessageValidator::~BtHandshakeMessageValidator() {}
|
|||
|
||||
void BtHandshakeMessageValidator::validate()
|
||||
{
|
||||
if(message_->getPstrlen() != 19) {
|
||||
throw DL_ABORT_EX(fmt("invalid handshake pstrlen=%u",
|
||||
message_->getPstrlen()));
|
||||
if (message_->getPstrlen() != 19) {
|
||||
throw DL_ABORT_EX(
|
||||
fmt("invalid handshake pstrlen=%u", message_->getPstrlen()));
|
||||
}
|
||||
if(memcmp(BtHandshakeMessage::BT_PSTR, message_->getPstr(), 19) != 0) {
|
||||
throw DL_ABORT_EX
|
||||
(fmt("invalid handshake pstr=%s",
|
||||
util::percentEncode
|
||||
(message_->getPstr(), 19).c_str()));
|
||||
if (memcmp(BtHandshakeMessage::BT_PSTR, message_->getPstr(), 19) != 0) {
|
||||
throw DL_ABORT_EX(
|
||||
fmt("invalid handshake pstr=%s",
|
||||
util::percentEncode(message_->getPstr(), 19).c_str()));
|
||||
}
|
||||
if(memcmp(infoHash_, message_->getInfoHash(), sizeof(infoHash_)) != 0) {
|
||||
throw DL_ABORT_EX
|
||||
(fmt("invalid handshake info hash: expected:%s, actual:%s",
|
||||
util::toHex(infoHash_, sizeof(infoHash_)).c_str(),
|
||||
util::toHex(message_->getInfoHash(),
|
||||
INFO_HASH_LENGTH).c_str()));
|
||||
if (memcmp(infoHash_, message_->getInfoHash(), sizeof(infoHash_)) != 0) {
|
||||
throw DL_ABORT_EX(
|
||||
fmt("invalid handshake info hash: expected:%s, actual:%s",
|
||||
util::toHex(infoHash_, sizeof(infoHash_)).c_str(),
|
||||
util::toHex(message_->getInfoHash(), INFO_HASH_LENGTH).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ class BtHandshakeMessageValidator : public BtMessageValidator {
|
|||
private:
|
||||
const BtHandshakeMessage* message_;
|
||||
unsigned char infoHash_[INFO_HASH_LENGTH];
|
||||
|
||||
public:
|
||||
BtHandshakeMessageValidator(const BtHandshakeMessage* message,
|
||||
const unsigned char* infoHash);
|
||||
|
|
|
@ -43,30 +43,29 @@ namespace aria2 {
|
|||
|
||||
const char BtHaveAllMessage::NAME[] = "have all";
|
||||
|
||||
BtHaveAllMessage::BtHaveAllMessage():ZeroBtMessage(ID, NAME) {}
|
||||
BtHaveAllMessage::BtHaveAllMessage() : ZeroBtMessage(ID, NAME) {}
|
||||
|
||||
std::unique_ptr<BtHaveAllMessage> BtHaveAllMessage::create
|
||||
(const unsigned char* data, size_t dataLength)
|
||||
std::unique_ptr<BtHaveAllMessage>
|
||||
BtHaveAllMessage::create(const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
return ZeroBtMessage::create<BtHaveAllMessage>(data, dataLength);
|
||||
}
|
||||
|
||||
void BtHaveAllMessage::doReceivedAction()
|
||||
{
|
||||
if(!getPeer()->isFastExtensionEnabled()) {
|
||||
throw DL_ABORT_EX
|
||||
(fmt("%s received while fast extension is disabled",
|
||||
toString().c_str()));
|
||||
if (!getPeer()->isFastExtensionEnabled()) {
|
||||
throw DL_ABORT_EX(fmt("%s received while fast extension is disabled",
|
||||
toString().c_str()));
|
||||
}
|
||||
if(isMetadataGetMode()) {
|
||||
if (isMetadataGetMode()) {
|
||||
return;
|
||||
}
|
||||
getPieceStorage()->subtractPieceStats(getPeer()->getBitfield(),
|
||||
getPeer()->getBitfieldLength());
|
||||
getPeer()->setAllBitfield();
|
||||
getPieceStorage()->addPieceStats
|
||||
(getPeer()->getBitfield(), getPeer()->getBitfieldLength());
|
||||
if(getPeer()->isSeeder() && getPieceStorage()->downloadFinished()) {
|
||||
getPieceStorage()->addPieceStats(getPeer()->getBitfield(),
|
||||
getPeer()->getBitfieldLength());
|
||||
if (getPeer()->isSeeder() && getPieceStorage()->downloadFinished()) {
|
||||
throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ public:
|
|||
|
||||
static const char NAME[];
|
||||
|
||||
static std::unique_ptr<BtHaveAllMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtHaveAllMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
};
|
||||
|
|
|
@ -42,24 +42,24 @@ namespace aria2 {
|
|||
|
||||
const char BtHaveMessage::NAME[] = "have";
|
||||
|
||||
BtHaveMessage::BtHaveMessage(size_t index):IndexBtMessage(ID, NAME, index) {}
|
||||
BtHaveMessage::BtHaveMessage(size_t index) : IndexBtMessage(ID, NAME, index) {}
|
||||
|
||||
std::unique_ptr<BtHaveMessage> BtHaveMessage::create
|
||||
(const unsigned char* data, size_t dataLength)
|
||||
std::unique_ptr<BtHaveMessage> BtHaveMessage::create(const unsigned char* data,
|
||||
size_t dataLength)
|
||||
{
|
||||
return IndexBtMessage::create<BtHaveMessage>(data, dataLength);
|
||||
}
|
||||
|
||||
void BtHaveMessage::doReceivedAction()
|
||||
{
|
||||
if(isMetadataGetMode()) {
|
||||
if (isMetadataGetMode()) {
|
||||
return;
|
||||
}
|
||||
size_t index = getIndex();
|
||||
if(!getPeer()->hasPiece(index)) {
|
||||
if (!getPeer()->hasPiece(index)) {
|
||||
getPeer()->updateBitfield(index, 1);
|
||||
getPieceStorage()->addPieceStats(index);
|
||||
if(getPeer()->isSeeder() && getPieceStorage()->downloadFinished()) {
|
||||
if (getPeer()->isSeeder() && getPieceStorage()->downloadFinished()) {
|
||||
throw DL_ABORT_EX(MSG_GOOD_BYE_SEEDER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ public:
|
|||
|
||||
static const char NAME[];
|
||||
|
||||
static std::unique_ptr<BtHaveMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtHaveMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
};
|
||||
|
|
|
@ -41,20 +41,19 @@ namespace aria2 {
|
|||
|
||||
const char BtHaveNoneMessage::NAME[] = "have none";
|
||||
|
||||
BtHaveNoneMessage::BtHaveNoneMessage():ZeroBtMessage(ID, NAME) {}
|
||||
BtHaveNoneMessage::BtHaveNoneMessage() : ZeroBtMessage(ID, NAME) {}
|
||||
|
||||
std::unique_ptr<BtHaveNoneMessage> BtHaveNoneMessage::create
|
||||
(const unsigned char* data, size_t dataLength)
|
||||
std::unique_ptr<BtHaveNoneMessage>
|
||||
BtHaveNoneMessage::create(const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
return ZeroBtMessage::create<BtHaveNoneMessage>(data, dataLength);
|
||||
}
|
||||
|
||||
void BtHaveNoneMessage::doReceivedAction()
|
||||
{
|
||||
if(!getPeer()->isFastExtensionEnabled()) {
|
||||
throw DL_ABORT_EX
|
||||
(fmt("%s received while fast extension is disabled",
|
||||
toString().c_str()));
|
||||
if (!getPeer()->isFastExtensionEnabled()) {
|
||||
throw DL_ABORT_EX(fmt("%s received while fast extension is disabled",
|
||||
toString().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ public:
|
|||
|
||||
static const char NAME[];
|
||||
|
||||
static std::unique_ptr<BtHaveNoneMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtHaveNoneMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
namespace aria2 {
|
||||
|
||||
|
||||
class BtHandshakeMessage;
|
||||
|
||||
class BtInteractive {
|
||||
|
@ -50,8 +49,8 @@ public:
|
|||
|
||||
virtual void initiateHandshake() = 0;
|
||||
|
||||
virtual std::unique_ptr<BtHandshakeMessage> receiveHandshake
|
||||
(bool quickReply = false) = 0;
|
||||
virtual std::unique_ptr<BtHandshakeMessage>
|
||||
receiveHandshake(bool quickReply = false) = 0;
|
||||
|
||||
virtual std::unique_ptr<BtHandshakeMessage> receiveAndSendHandshake() = 0;
|
||||
|
||||
|
|
|
@ -42,25 +42,25 @@ namespace aria2 {
|
|||
const char BtInterestedMessage::NAME[] = "interested";
|
||||
|
||||
BtInterestedMessage::BtInterestedMessage()
|
||||
: ZeroBtMessage(ID, NAME),
|
||||
peerStorage_(nullptr)
|
||||
{}
|
||||
: ZeroBtMessage(ID, NAME), peerStorage_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
BtInterestedMessage::~BtInterestedMessage() {}
|
||||
|
||||
std::unique_ptr<BtInterestedMessage> BtInterestedMessage::create
|
||||
(const unsigned char* data, size_t dataLength)
|
||||
std::unique_ptr<BtInterestedMessage>
|
||||
BtInterestedMessage::create(const unsigned char* data, size_t dataLength)
|
||||
{
|
||||
return ZeroBtMessage::create<BtInterestedMessage>(data, dataLength);
|
||||
}
|
||||
|
||||
void BtInterestedMessage::doReceivedAction()
|
||||
{
|
||||
if(isMetadataGetMode()) {
|
||||
if (isMetadataGetMode()) {
|
||||
return;
|
||||
}
|
||||
getPeer()->peerInterested(true);
|
||||
if(!getPeer()->amChoking()) {
|
||||
if (!getPeer()->amChoking()) {
|
||||
peerStorage_->executeChoke();
|
||||
}
|
||||
}
|
||||
|
@ -72,11 +72,10 @@ bool BtInterestedMessage::sendPredicate() const
|
|||
|
||||
namespace {
|
||||
struct ThisProgressUpdate : public ProgressUpdate {
|
||||
ThisProgressUpdate(std::shared_ptr<Peer> peer)
|
||||
: peer(std::move(peer)) {}
|
||||
ThisProgressUpdate(std::shared_ptr<Peer> peer) : peer(std::move(peer)) {}
|
||||
virtual void update(size_t length, bool complete) CXX11_OVERRIDE
|
||||
{
|
||||
if(complete) {
|
||||
if (complete) {
|
||||
peer->amInterested(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class BtInterestedMessage;
|
|||
class BtInterestedMessage : public ZeroBtMessage {
|
||||
private:
|
||||
PeerStorage* peerStorage_;
|
||||
|
||||
public:
|
||||
BtInterestedMessage();
|
||||
virtual ~BtInterestedMessage();
|
||||
|
@ -53,8 +54,8 @@ public:
|
|||
|
||||
static const char NAME[];
|
||||
|
||||
static std::unique_ptr<BtInterestedMessage> create
|
||||
(const unsigned char* data, size_t dataLength);
|
||||
static std::unique_ptr<BtInterestedMessage> create(const unsigned char* data,
|
||||
size_t dataLength);
|
||||
|
||||
virtual void doReceivedAction() CXX11_OVERRIDE;
|
||||
|
||||
|
|
|
@ -50,9 +50,6 @@ unsigned char* BtKeepAliveMessage::createMessage()
|
|||
return msg;
|
||||
}
|
||||
|
||||
size_t BtKeepAliveMessage::getMessageLength()
|
||||
{
|
||||
return MESSAGE_LENGTH;
|
||||
}
|
||||
size_t BtKeepAliveMessage::getMessageLength() { return MESSAGE_LENGTH; }
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -42,8 +42,9 @@ namespace aria2 {
|
|||
class BtKeepAliveMessage : public SimpleBtMessage {
|
||||
private:
|
||||
static const size_t MESSAGE_LENGTH = 4;
|
||||
|
||||
public:
|
||||
BtKeepAliveMessage():SimpleBtMessage(ID, NAME) {}
|
||||
BtKeepAliveMessage() : SimpleBtMessage(ID, NAME) {}
|
||||
|
||||
static const uint8_t ID = 99;
|
||||
|
||||
|
@ -55,10 +56,7 @@ public:
|
|||
|
||||
virtual size_t getMessageLength() CXX11_OVERRIDE;
|
||||
|
||||
virtual std::string toString() const CXX11_OVERRIDE
|
||||
{
|
||||
return NAME;
|
||||
}
|
||||
virtual std::string toString() const CXX11_OVERRIDE { return NAME; }
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -46,27 +46,28 @@
|
|||
namespace aria2 {
|
||||
|
||||
BtLeecherStateChoke::BtLeecherStateChoke()
|
||||
: round_(0),
|
||||
lastRound_(Timer::zero())
|
||||
{}
|
||||
: round_(0), lastRound_(Timer::zero())
|
||||
{
|
||||
}
|
||||
|
||||
BtLeecherStateChoke::~BtLeecherStateChoke() {}
|
||||
|
||||
BtLeecherStateChoke::PeerEntry::PeerEntry(const std::shared_ptr<Peer>& peer)
|
||||
: peer_(peer),
|
||||
downloadSpeed_(peer->calculateDownloadSpeed()),
|
||||
// peer must be interested to us and sent block in the last 30 seconds
|
||||
regularUnchoker_(
|
||||
peer->peerInterested() &&
|
||||
peer->getLastDownloadUpdate().difference(global::wallclock()) < 30_s)
|
||||
: peer_(peer),
|
||||
downloadSpeed_(peer->calculateDownloadSpeed()),
|
||||
// peer must be interested to us and sent block in the last 30 seconds
|
||||
regularUnchoker_(
|
||||
peer->peerInterested() &&
|
||||
peer->getLastDownloadUpdate().difference(global::wallclock()) < 30_s)
|
||||
{
|
||||
}
|
||||
|
||||
BtLeecherStateChoke::PeerEntry::PeerEntry(const PeerEntry& c)
|
||||
: peer_(c.peer_),
|
||||
downloadSpeed_(c.downloadSpeed_),
|
||||
regularUnchoker_(c.regularUnchoker_)
|
||||
{}
|
||||
: peer_(c.peer_),
|
||||
downloadSpeed_(c.downloadSpeed_),
|
||||
regularUnchoker_(c.regularUnchoker_)
|
||||
{
|
||||
}
|
||||
|
||||
void BtLeecherStateChoke::PeerEntry::swap(PeerEntry& c)
|
||||
{
|
||||
|
@ -76,10 +77,10 @@ void BtLeecherStateChoke::PeerEntry::swap(PeerEntry& c)
|
|||
swap(regularUnchoker_, c.regularUnchoker_);
|
||||
}
|
||||
|
||||
BtLeecherStateChoke::PeerEntry& BtLeecherStateChoke::PeerEntry::operator=
|
||||
(const PeerEntry& c)
|
||||
BtLeecherStateChoke::PeerEntry& BtLeecherStateChoke::PeerEntry::
|
||||
operator=(const PeerEntry& c)
|
||||
{
|
||||
if(this != &c) {
|
||||
if (this != &c) {
|
||||
peer_ = c.peer_;
|
||||
downloadSpeed_ = c.downloadSpeed_;
|
||||
regularUnchoker_ = c.regularUnchoker_;
|
||||
|
@ -129,29 +130,27 @@ bool BtLeecherStateChoke::PeerEntry::operator<(const PeerEntry& peerEntry) const
|
|||
return downloadSpeed_ > peerEntry.downloadSpeed_;
|
||||
}
|
||||
|
||||
void swap
|
||||
(BtLeecherStateChoke::PeerEntry& a,
|
||||
BtLeecherStateChoke::PeerEntry& b)
|
||||
void swap(BtLeecherStateChoke::PeerEntry& a, BtLeecherStateChoke::PeerEntry& b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
bool BtLeecherStateChoke::PeerFilter::operator()
|
||||
(const PeerEntry& peerEntry) const
|
||||
bool BtLeecherStateChoke::PeerFilter::
|
||||
operator()(const PeerEntry& peerEntry) const
|
||||
{
|
||||
return peerEntry.getPeer()->amChoking() == amChoking_ &&
|
||||
peerEntry.getPeer()->peerInterested() == peerInterested_;
|
||||
peerEntry.getPeer()->peerInterested() == peerInterested_;
|
||||
}
|
||||
|
||||
void BtLeecherStateChoke::plannedOptimisticUnchoke
|
||||
(std::vector<PeerEntry>& peerEntries)
|
||||
void BtLeecherStateChoke::plannedOptimisticUnchoke(
|
||||
std::vector<PeerEntry>& peerEntries)
|
||||
{
|
||||
std::for_each(std::begin(peerEntries), std::end(peerEntries),
|
||||
std::mem_fn(&PeerEntry::disableOptUnchoking));
|
||||
|
||||
auto i = std::partition(std::begin(peerEntries), std::end(peerEntries),
|
||||
PeerFilter(true, true));
|
||||
if(i != std::begin(peerEntries)) {
|
||||
if (i != std::begin(peerEntries)) {
|
||||
std::shuffle(std::begin(peerEntries), i, *SimpleRandomizer::getInstance());
|
||||
(*std::begin(peerEntries)).enableOptUnchoking();
|
||||
A2_LOG_INFO(
|
||||
|
@ -172,25 +171,26 @@ void BtLeecherStateChoke::regularUnchoke(std::vector<PeerEntry>& peerEntries)
|
|||
|
||||
bool fastOptUnchoker = false;
|
||||
auto peerIter = std::begin(peerEntries);
|
||||
for(;peerIter != rest && count; ++peerIter, --count) {
|
||||
for (; peerIter != rest && count; ++peerIter, --count) {
|
||||
peerIter->disableChokingRequired();
|
||||
A2_LOG_INFO(fmt("RU: %s, dlspd=%d",
|
||||
(*peerIter).getPeer()->getIPAddress().c_str(),
|
||||
(*peerIter).getDownloadSpeed()));
|
||||
if(peerIter->getPeer()->optUnchoking()) {
|
||||
if (peerIter->getPeer()->optUnchoking()) {
|
||||
fastOptUnchoker = true;
|
||||
peerIter->disableOptUnchoking();
|
||||
}
|
||||
}
|
||||
if(fastOptUnchoker) {
|
||||
if (fastOptUnchoker) {
|
||||
std::shuffle(peerIter, std::end(peerEntries),
|
||||
*SimpleRandomizer::getInstance());
|
||||
for (auto& p : peerEntries) {
|
||||
if(p.getPeer()->peerInterested()) {
|
||||
if (p.getPeer()->peerInterested()) {
|
||||
p.enableOptUnchoking();
|
||||
A2_LOG_INFO(fmt("OU: %s", p.getPeer()->getIPAddress().c_str()));
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
p.disableChokingRequired();
|
||||
A2_LOG_INFO(fmt("OU: %s", p.getPeer()->getIPAddress().c_str()));
|
||||
}
|
||||
|
@ -205,26 +205,23 @@ void BtLeecherStateChoke::executeChoke(const PeerSet& peerSet)
|
|||
|
||||
std::vector<PeerEntry> peerEntries;
|
||||
for (const auto& p : peerSet) {
|
||||
if(p->isActive() && !p->snubbing()) {
|
||||
if (p->isActive() && !p->snubbing()) {
|
||||
p->chokingRequired(true);
|
||||
peerEntries.push_back(PeerEntry(p));
|
||||
}
|
||||
}
|
||||
|
||||
// planned optimistic unchoke
|
||||
if(round_ == 0) {
|
||||
if (round_ == 0) {
|
||||
plannedOptimisticUnchoke(peerEntries);
|
||||
}
|
||||
regularUnchoke(peerEntries);
|
||||
|
||||
if(++round_ == 3) {
|
||||
if (++round_ == 3) {
|
||||
round_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const Timer& BtLeecherStateChoke::getLastRound() const
|
||||
{
|
||||
return lastRound_;
|
||||
}
|
||||
const Timer& BtLeecherStateChoke::getLastRound() const { return lastRound_; }
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
std::shared_ptr<Peer> peer_;
|
||||
int downloadSpeed_;
|
||||
bool regularUnchoker_;
|
||||
|
||||
public:
|
||||
PeerEntry(const std::shared_ptr<Peer>& peer);
|
||||
PeerEntry(const PeerEntry& c);
|
||||
|
@ -92,13 +93,16 @@ private:
|
|||
private:
|
||||
bool amChoking_;
|
||||
bool peerInterested_;
|
||||
|
||||
public:
|
||||
PeerFilter(bool amChoking, bool peerInterested):
|
||||
amChoking_(amChoking),
|
||||
peerInterested_(peerInterested) {}
|
||||
PeerFilter(bool amChoking, bool peerInterested)
|
||||
: amChoking_(amChoking), peerInterested_(peerInterested)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(const PeerEntry& peerEntry) const;
|
||||
};
|
||||
|
||||
public:
|
||||
BtLeecherStateChoke();
|
||||
|
||||
|
@ -111,9 +115,7 @@ public:
|
|||
friend void swap(PeerEntry& a, PeerEntry& b);
|
||||
};
|
||||
|
||||
void swap
|
||||
(BtLeecherStateChoke::PeerEntry& a,
|
||||
BtLeecherStateChoke::PeerEntry& b);
|
||||
void swap(BtLeecherStateChoke::PeerEntry& a, BtLeecherStateChoke::PeerEntry& b);
|
||||
|
||||
} // namespace aria2
|
||||
|
||||
|
|
|
@ -50,8 +50,9 @@ class BtEvent;
|
|||
class BtMessage {
|
||||
private:
|
||||
uint8_t id_;
|
||||
|
||||
public:
|
||||
BtMessage(uint8_t id):id_(id) {}
|
||||
BtMessage(uint8_t id) : id_(id) {}
|
||||
|
||||
virtual ~BtMessage() {}
|
||||
|
||||
|
@ -67,18 +68,17 @@ public:
|
|||
|
||||
virtual void validate() = 0;
|
||||
|
||||
virtual void onAbortOutstandingRequestEvent
|
||||
(const BtAbortOutstandingRequestEvent& event) = 0;
|
||||
virtual void onAbortOutstandingRequestEvent(
|
||||
const BtAbortOutstandingRequestEvent& event) = 0;
|
||||
|
||||
virtual void onCancelSendingPieceEvent
|
||||
(const BtCancelSendingPieceEvent& event) = 0;
|
||||
virtual void
|
||||
onCancelSendingPieceEvent(const BtCancelSendingPieceEvent& event) = 0;
|
||||
|
||||
virtual void onChokingEvent(const BtChokingEvent& event) = 0;
|
||||
|
||||
virtual void onQueued() = 0;
|
||||
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -55,12 +55,14 @@ public:
|
|||
|
||||
virtual void sendMessages() = 0;
|
||||
|
||||
virtual void doCancelSendingPieceAction
|
||||
(size_t index, int32_t begin, int32_t length) = 0;
|
||||
virtual void doCancelSendingPieceAction(size_t index, int32_t begin,
|
||||
int32_t length) = 0;
|
||||
|
||||
virtual void doCancelSendingPieceAction(const std::shared_ptr<Piece>& piece) = 0;
|
||||
virtual void
|
||||
doCancelSendingPieceAction(const std::shared_ptr<Piece>& piece) = 0;
|
||||
|
||||
virtual void doAbortOutstandingRequestAction(const std::shared_ptr<Piece>& piece) = 0;
|
||||
virtual void
|
||||
doAbortOutstandingRequestAction(const std::shared_ptr<Piece>& piece) = 0;
|
||||
|
||||
virtual void doChokedAction() = 0;
|
||||
|
||||
|
@ -76,8 +78,8 @@ public:
|
|||
|
||||
virtual bool isOutstandingRequest(size_t index, size_t blockIndex) = 0;
|
||||
|
||||
virtual const RequestSlot* getOutstandingRequest
|
||||
(size_t index, int32_t begin, int32_t length) = 0;
|
||||
virtual const RequestSlot* getOutstandingRequest(size_t index, int32_t begin,
|
||||
int32_t length) = 0;
|
||||
|
||||
virtual void removeOutstandingRequest(const RequestSlot* slot) = 0;
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@ class BtMessageFactory {
|
|||
public:
|
||||
virtual ~BtMessageFactory() {}
|
||||
|
||||
virtual std::unique_ptr<BtMessage>
|
||||
createBtMessage(const unsigned char* msg, size_t msgLength) = 0;
|
||||
virtual std::unique_ptr<BtMessage> createBtMessage(const unsigned char* msg,
|
||||
size_t msgLength) = 0;
|
||||
|
||||
virtual std::unique_ptr<BtHandshakeMessage>
|
||||
createHandshakeMessage(const unsigned char* msg, size_t msgLength) = 0;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue