mirror of https://github.com/aria2/aria2
More code cleanups
parent
8526ceeb45
commit
cf6f58ceec
|
@ -37,6 +37,7 @@
|
|||
#include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#include "array_fun.h"
|
||||
#include "a2functional.h"
|
||||
#include "HashFuncEntry.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
@ -117,29 +118,31 @@ std::unique_ptr<MessageDigestImpl> MessageDigestImpl::create
|
|||
(const std::string& hashType)
|
||||
{
|
||||
if (hashType == "sha-1") {
|
||||
return std::unique_ptr<MessageDigestImpl>(new MessageDigestSHA1());
|
||||
return make_unique<MessageDigestSHA1>();
|
||||
}
|
||||
if (hashType == "sha-224") {
|
||||
return std::unique_ptr<MessageDigestImpl>(new MessageDigestSHA224());
|
||||
return make_unique<MessageDigestSHA224>();
|
||||
}
|
||||
if (hashType == "sha-256") {
|
||||
return std::unique_ptr<MessageDigestImpl>(new MessageDigestSHA256());
|
||||
return make_unique<MessageDigestSHA256>();
|
||||
}
|
||||
if (hashType == "sha-384") {
|
||||
return std::unique_ptr<MessageDigestImpl>(new MessageDigestSHA384());
|
||||
return make_unique<MessageDigestSHA384>();
|
||||
}
|
||||
if (hashType == "sha-512") {
|
||||
return std::unique_ptr<MessageDigestImpl>(new MessageDigestSHA512());
|
||||
return make_unique<MessageDigestSHA512>();
|
||||
}
|
||||
if (hashType == "md5") {
|
||||
return std::unique_ptr<MessageDigestImpl>(new MessageDigestMD5());
|
||||
return make_unique<MessageDigestMD5>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool MessageDigestImpl::supports(const std::string& hashType)
|
||||
{
|
||||
return hashType == "sha-1" || hashType == "sha-224" || hashType == "sha-256" || hashType == "sha-384" || hashType == "sha-512" || hashType == "md5";
|
||||
return hashType == "sha-1" || hashType == "sha-224" ||
|
||||
hashType == "sha-256" || hashType == "sha-384" ||
|
||||
hashType == "sha-512" || hashType == "md5";
|
||||
}
|
||||
|
||||
size_t MessageDigestImpl::getDigestLength(const std::string& hashType)
|
||||
|
|
|
@ -58,11 +58,11 @@ namespace {
|
|||
};
|
||||
#endif // defined(__MAC_10_7)
|
||||
|
||||
class cfrelease {
|
||||
class CFReleaser {
|
||||
const void *ptr_;
|
||||
public:
|
||||
inline cfrelease(const void *ptr) : ptr_(ptr) {}
|
||||
inline ~cfrelease() { if (ptr_) CFRelease(ptr_); }
|
||||
inline CFReleaser(const void *ptr) : ptr_(ptr) {}
|
||||
inline ~CFReleaser() { if (ptr_) CFRelease(ptr_); }
|
||||
};
|
||||
|
||||
static inline bool isWhitespace(char c)
|
||||
|
@ -123,13 +123,13 @@ namespace {
|
|||
A2_LOG_ERROR("Failed to get a certref!");
|
||||
return false;
|
||||
}
|
||||
cfrelease del_ref(ref);
|
||||
CFReleaser del_ref(ref);
|
||||
CFDataRef data = SecCertificateCopyData(ref);
|
||||
if (!data) {
|
||||
A2_LOG_ERROR("Failed to get a data!");
|
||||
return false;
|
||||
}
|
||||
cfrelease del_data(data);
|
||||
CFReleaser del_data(data);
|
||||
|
||||
// Do try all supported hash algorithms.
|
||||
// Usually the fingerprint would be sha1 or md5, however this is more
|
||||
|
@ -183,12 +183,12 @@ SecIdentityRef AppleTLSContext::getCredentials()
|
|||
|
||||
bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
||||
{
|
||||
std::string fp = stripWhitespace(fingerprint);
|
||||
auto fp = stripWhitespace(fingerprint);
|
||||
// Verify this is a valid hex representation and normalize.
|
||||
fp = util::toHex(util::fromHex(fp.begin(), fp.end()));
|
||||
|
||||
// Verify this can represent a hash
|
||||
std::vector<std::string> ht = MessageDigest::getSupportedHashTypes();
|
||||
auto ht = MessageDigest::getSupportedHashTypes();
|
||||
if (std::find_if(ht.begin(), ht.end(), hash_validator(fp)) == ht.end()) {
|
||||
A2_LOG_INFO(fmt("%s is not a fingerprint, invalid hash representation", fingerprint.c_str()));
|
||||
return false;
|
||||
|
@ -198,25 +198,25 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
|||
A2_LOG_DEBUG(fmt("Looking for cert with fingerprint %s", fp.c_str()));
|
||||
|
||||
// Build and run the KeyChain the query.
|
||||
SecPolicyRef policy = SecPolicyCreateSSL(true, nullptr);
|
||||
auto policy = SecPolicyCreateSSL(true, nullptr);
|
||||
if (!policy) {
|
||||
A2_LOG_ERROR("Failed to create SecPolicy");
|
||||
return false;
|
||||
}
|
||||
cfrelease del_policy(policy);
|
||||
CFReleaser del_policy(policy);
|
||||
const void *query_values[] = {
|
||||
kSecClassIdentity,
|
||||
kCFBooleanTrue,
|
||||
policy,
|
||||
kSecMatchLimitAll
|
||||
};
|
||||
CFDictionaryRef query = CFDictionaryCreate(nullptr, query_keys, query_values,
|
||||
4, nullptr, nullptr);
|
||||
auto query = CFDictionaryCreate(nullptr, query_keys, query_values, 4,
|
||||
nullptr, nullptr);
|
||||
if (!query) {
|
||||
A2_LOG_ERROR("Failed to create identity query");
|
||||
return false;
|
||||
}
|
||||
cfrelease del_query(query);
|
||||
CFReleaser del_query(query);
|
||||
CFArrayRef identities;
|
||||
OSStatus err = SecItemCopyMatching(query, (CFTypeRef*)&identities);
|
||||
if (err != errSecSuccess) {
|
||||
|
@ -254,7 +254,7 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
|||
if (err != errSecSuccess) {
|
||||
A2_LOG_ERROR("Certificate search failed: " + errToString(err));
|
||||
}
|
||||
cfrelease del_search(search);
|
||||
CFReleaser del_search(search);
|
||||
|
||||
SecIdentityRef id;
|
||||
while (SecIdentitySearchCopyNext(search, &id) == errSecSuccess) {
|
||||
|
|
|
@ -326,8 +326,8 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
|||
state_ = st_error;
|
||||
return;
|
||||
}
|
||||
for (SSLCipherSuiteList::iterator i = enabled.begin(), e = enabled.end(); i != e; ++i) {
|
||||
A2_LOG_INFO(fmt("AppleTLS: Enabled suite %s", suiteToString(*i)));
|
||||
for (const auto& suite: enabled) {
|
||||
A2_LOG_INFO(fmt("AppleTLS: Enabled suite %s", suiteToString(suite)));
|
||||
}
|
||||
if (SSLSetEnabledCiphers(sslCtx_, &enabled[0], enabled.size()) != noErr) {
|
||||
A2_LOG_ERROR("AppleTLS: Failed to set enabled ciphers list");
|
||||
|
@ -336,37 +336,39 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (ctx->getSide() == TLS_SERVER) {
|
||||
SecIdentityRef creds = ctx->getCredentials();
|
||||
if (!creds) {
|
||||
A2_LOG_ERROR("AppleTLS: No credentials");
|
||||
state_ = st_error;
|
||||
return;
|
||||
}
|
||||
CFArrayRef certs = CFArrayCreate(nullptr, (const void**)&creds, 1, nullptr);
|
||||
if (!certs) {
|
||||
A2_LOG_ERROR("AppleTLS: Failed to setup credentials");
|
||||
state_ = st_error;
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<void, decltype(&CFRelease)> del_certs((void*)certs, CFRelease);
|
||||
lastError_ = SSLSetCertificate(sslCtx_, certs);
|
||||
if (lastError_ != noErr) {
|
||||
A2_LOG_ERROR(fmt("AppleTLS: Failed to set credentials: %s", getLastErrorString().c_str()));
|
||||
state_ = st_error;
|
||||
return;
|
||||
}
|
||||
if (ctx->getSide() != TLS_SERVER) {
|
||||
// Done with client-only initialization
|
||||
return;
|
||||
}
|
||||
|
||||
SecIdentityRef creds = ctx->getCredentials();
|
||||
if (!creds) {
|
||||
A2_LOG_ERROR("AppleTLS: No credentials");
|
||||
state_ = st_error;
|
||||
return;
|
||||
}
|
||||
CFArrayRef certs = CFArrayCreate(nullptr, (const void**)&creds, 1, nullptr);
|
||||
if (!certs) {
|
||||
A2_LOG_ERROR("AppleTLS: Failed to setup credentials");
|
||||
state_ = st_error;
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<void, decltype(&CFRelease)> del_certs((void*)certs, CFRelease);
|
||||
lastError_ = SSLSetCertificate(sslCtx_, certs);
|
||||
if (lastError_ != noErr) {
|
||||
A2_LOG_ERROR(fmt("AppleTLS: Failed to set credentials: %s", getLastErrorString().c_str()));
|
||||
state_ = st_error;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef CIPHER_NO_DHPARAM
|
||||
lastError_ = SSLSetDiffieHellmanParams(sslCtx_, dhparam, sizeof(dhparam));
|
||||
if (lastError_ != noErr) {
|
||||
A2_LOG_WARN(fmt("AppleTLS: Failed to set DHParams: %s", getLastErrorString().c_str()));
|
||||
// Engine will still generate some for us, so this is no problem, except
|
||||
// it will take longer.
|
||||
}
|
||||
#endif // CIPHER_NO_DHPARAM
|
||||
|
||||
lastError_ = SSLSetDiffieHellmanParams(sslCtx_, dhparam, sizeof(dhparam));
|
||||
if (lastError_ != noErr) {
|
||||
A2_LOG_WARN(fmt("AppleTLS: Failed to set DHParams: %s", getLastErrorString().c_str()));
|
||||
// Engine will still generate some for us, so this is no problem, except
|
||||
// it will take longer.
|
||||
}
|
||||
#endif // CIPHER_NO_DHPARAM
|
||||
}
|
||||
|
||||
AppleTLSSession::~AppleTLSSession()
|
||||
|
|
|
@ -124,27 +124,28 @@ void executeCommand(std::deque<std::unique_ptr<Command>>& commands,
|
|||
for(size_t i = 0; i < max; ++i) {
|
||||
auto com = std::move(commands.front());
|
||||
commands.pop_front();
|
||||
if(com->statusMatch(statusFilter)) {
|
||||
com->transitStatus();
|
||||
if(com->execute()) {
|
||||
com.reset();
|
||||
} else {
|
||||
com->clearIOEvents();
|
||||
com.release();
|
||||
}
|
||||
} else {
|
||||
if (!com->statusMatch(statusFilter)) {
|
||||
com->clearIOEvents();
|
||||
commands.push_back(std::move(com));
|
||||
continue;
|
||||
}
|
||||
com->transitStatus();
|
||||
if (com->execute()) {
|
||||
com.reset();
|
||||
}
|
||||
else {
|
||||
com->clearIOEvents();
|
||||
com.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
class GHR {
|
||||
class GlobalHaltRequestedFinalizer {
|
||||
public:
|
||||
GHR() {}
|
||||
~GHR()
|
||||
GlobalHaltRequestedFinalizer() {}
|
||||
~GlobalHaltRequestedFinalizer()
|
||||
{
|
||||
global::globalHaltRequested = 5;
|
||||
}
|
||||
|
@ -153,7 +154,7 @@ public:
|
|||
|
||||
int DownloadEngine::run(bool oneshot)
|
||||
{
|
||||
GHR ghr;
|
||||
GlobalHaltRequestedFinalizer ghrf;
|
||||
while(!commands_.empty() || !routineCommands_.empty()) {
|
||||
if(!commands_.empty()) {
|
||||
waitData();
|
||||
|
@ -243,12 +244,16 @@ void DownloadEngine::afterEachIteration()
|
|||
global::globalHaltRequested = 2;
|
||||
setNoWait(true);
|
||||
setRefreshInterval(0);
|
||||
} else if(global::globalHaltRequested == 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(global::globalHaltRequested == 3) {
|
||||
A2_LOG_NOTICE(_("Emergency shutdown sequence commencing..."));
|
||||
requestForceHalt();
|
||||
global::globalHaltRequested = 4;
|
||||
setNoWait(true);
|
||||
setRefreshInterval(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,20 +305,21 @@ void DownloadEngine::poolSocket(const std::string& key,
|
|||
std::multimap<std::string, SocketPoolEntry>::value_type p(key, entry);
|
||||
socketPool_.insert(p);
|
||||
|
||||
if(lastSocketPoolScan_.difference(global::wallclock()) >= 60) {
|
||||
std::multimap<std::string, SocketPoolEntry> newPool;
|
||||
A2_LOG_DEBUG("Scaning SocketPool and erasing timed out entry.");
|
||||
lastSocketPoolScan_ = global::wallclock();
|
||||
for(auto & elem : socketPool_) {
|
||||
if(!elem.second.isTimeout()) {
|
||||
newPool.insert(elem);
|
||||
}
|
||||
}
|
||||
A2_LOG_DEBUG(fmt("%lu entries removed.",
|
||||
static_cast<unsigned long>
|
||||
(socketPool_.size()-newPool.size())));
|
||||
socketPool_ = newPool;
|
||||
if(lastSocketPoolScan_.difference(global::wallclock()) < 60) {
|
||||
return;
|
||||
}
|
||||
std::multimap<std::string, SocketPoolEntry> newPool;
|
||||
A2_LOG_DEBUG("Scaning SocketPool and erasing timed out entry.");
|
||||
lastSocketPoolScan_ = global::wallclock();
|
||||
for(auto & elem : socketPool_) {
|
||||
if(!elem.second.isTimeout()) {
|
||||
newPool.insert(elem);
|
||||
}
|
||||
}
|
||||
A2_LOG_DEBUG(fmt("%lu entries removed.",
|
||||
static_cast<unsigned long>
|
||||
(socketPool_.size()-newPool.size())));
|
||||
socketPool_ = newPool;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -382,17 +388,18 @@ void DownloadEngine::poolSocket(const std::shared_ptr<Request>& request,
|
|||
const std::shared_ptr<SocketCore>& socket,
|
||||
time_t timeout)
|
||||
{
|
||||
if(!proxyRequest) {
|
||||
std::pair<std::string, uint16_t> peerInfo;
|
||||
if(getPeerInfo(peerInfo, socket)) {
|
||||
poolSocket(peerInfo.first, peerInfo.second,
|
||||
A2STR::NIL, 0, socket, timeout);
|
||||
}
|
||||
} else {
|
||||
if(proxyRequest) {
|
||||
// If proxy is defined, then pool socket with its hostname.
|
||||
poolSocket(request->getHost(), request->getPort(),
|
||||
proxyRequest->getHost(), proxyRequest->getPort(),
|
||||
socket, timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<std::string, uint16_t> peerInfo;
|
||||
if(getPeerInfo(peerInfo, socket)) {
|
||||
poolSocket(peerInfo.first, peerInfo.second,
|
||||
A2STR::NIL, 0, socket, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,17 +411,18 @@ void DownloadEngine::poolSocket
|
|||
const std::string& options,
|
||||
time_t timeout)
|
||||
{
|
||||
if(!proxyRequest) {
|
||||
std::pair<std::string, uint16_t> peerInfo;
|
||||
if(getPeerInfo(peerInfo, socket)) {
|
||||
poolSocket(peerInfo.first, peerInfo.second, username,
|
||||
A2STR::NIL, 0, socket, options, timeout);
|
||||
}
|
||||
} else {
|
||||
if(proxyRequest) {
|
||||
// If proxy is defined, then pool socket with its hostname.
|
||||
poolSocket(request->getHost(), request->getPort(), username,
|
||||
proxyRequest->getHost(), proxyRequest->getPort(),
|
||||
socket, options, timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<std::string, uint16_t> peerInfo;
|
||||
if(getPeerInfo(peerInfo, socket)) {
|
||||
poolSocket(peerInfo.first, peerInfo.second, username,
|
||||
A2STR::NIL, 0, socket, options, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,58 +91,54 @@ std::unique_ptr<EventPoll> createEventPoll(Option* op)
|
|||
#ifdef HAVE_LIBUV
|
||||
if (pollMethod == V_LIBUV) {
|
||||
auto ep = make_unique<LibuvEventPoll>();
|
||||
if(ep->good()) {
|
||||
return std::move(ep);
|
||||
} else {
|
||||
if(!ep->good()) {
|
||||
throw DL_ABORT_EX("Initializing LibuvEventPoll failed."
|
||||
" Try --event-poll=select");
|
||||
}
|
||||
return std::move(ep);
|
||||
}
|
||||
else
|
||||
#endif // HAVE_LIBUV
|
||||
#ifdef HAVE_EPOLL
|
||||
if(pollMethod == V_EPOLL) {
|
||||
auto ep = make_unique<EpollEventPoll>();
|
||||
if(ep->good()) {
|
||||
return std::move(ep);
|
||||
} else {
|
||||
if(!ep->good()) {
|
||||
throw DL_ABORT_EX("Initializing EpollEventPoll failed."
|
||||
" Try --event-poll=select");
|
||||
}
|
||||
return std::move(ep);
|
||||
} else
|
||||
#endif // HAVE_EPLL
|
||||
#ifdef HAVE_KQUEUE
|
||||
if(pollMethod == V_KQUEUE) {
|
||||
auto kp = make_unique<KqueueEventPoll>();
|
||||
if(kp->good()) {
|
||||
return std::move(kp);
|
||||
} else {
|
||||
throw DL_ABORT_EX("Initializing KqueueEventPoll failed."
|
||||
" Try --event-poll=select");
|
||||
}
|
||||
} else
|
||||
if(pollMethod == V_KQUEUE) {
|
||||
auto kp = make_unique<KqueueEventPoll>();
|
||||
if(!kp->good()) {
|
||||
throw DL_ABORT_EX("Initializing KqueueEventPoll failed."
|
||||
" Try --event-poll=select");
|
||||
}
|
||||
return std::move(kp);
|
||||
} else
|
||||
#endif // HAVE_KQUEUE
|
||||
#ifdef HAVE_PORT_ASSOCIATE
|
||||
if(pollMethod == V_PORT) {
|
||||
auto pp = make_unique<PortEventPoll>();
|
||||
if(pp->good()) {
|
||||
return std::move(pp);
|
||||
} else {
|
||||
throw DL_ABORT_EX("Initializing PortEventPoll failed."
|
||||
" Try --event-poll=select");
|
||||
}
|
||||
} else
|
||||
if(pollMethod == V_PORT) {
|
||||
auto pp = make_unique<PortEventPoll>();
|
||||
if(!pp->good()) {
|
||||
throw DL_ABORT_EX("Initializing PortEventPoll failed."
|
||||
" Try --event-poll=select");
|
||||
}
|
||||
return std::move(pp);
|
||||
} else
|
||||
#endif // HAVE_PORT_ASSOCIATE
|
||||
#ifdef HAVE_POLL
|
||||
if(pollMethod == V_POLL) {
|
||||
return make_unique<PollEventPoll>();
|
||||
} else
|
||||
if(pollMethod == V_POLL) {
|
||||
return make_unique<PollEventPoll>();
|
||||
} else
|
||||
#endif // HAVE_POLL
|
||||
if(pollMethod == V_SELECT) {
|
||||
return make_unique<SelectEventPoll>();
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
if(pollMethod == V_SELECT) {
|
||||
return make_unique<SelectEventPoll>();
|
||||
}
|
||||
assert(0);
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -107,8 +107,8 @@ LibuvEventPoll::LibuvEventPoll()
|
|||
|
||||
LibuvEventPoll::~LibuvEventPoll()
|
||||
{
|
||||
for (KPolls::iterator i = polls_.begin(), e = polls_.end(); i != e; ++i) {
|
||||
i->second->close();
|
||||
for (auto& p: polls_) {
|
||||
p.second->close();
|
||||
}
|
||||
// Actually kill the polls, and timers, if any.
|
||||
uv_run(loop_, (uv_run_mode)(UV_RUN_ONCE | UV_RUN_NOWAIT));
|
||||
|
@ -256,8 +256,8 @@ bool LibuvEventPoll::addEvents(sock_t socket, Command* command, int events,
|
|||
bool LibuvEventPoll::deleteEvents(sock_t socket,
|
||||
const LibuvEventPoll::KEvent& event)
|
||||
{
|
||||
std::shared_ptr<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
||||
KSocketEntrySet::iterator i = socketEntries_.find(socketEntry);
|
||||
auto socketEntry = std::make_shared<KSocketEntry>(socket);
|
||||
auto i = socketEntries_.find(socketEntry);
|
||||
|
||||
if (i == socketEntries_.end()) {
|
||||
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
|
||||
|
@ -266,7 +266,7 @@ bool LibuvEventPoll::deleteEvents(sock_t socket,
|
|||
|
||||
event.removeSelf(*i);
|
||||
|
||||
KPolls::iterator poll = polls_.find(socket);
|
||||
auto poll = polls_.find(socket);
|
||||
if (poll == polls_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ private:
|
|||
uv_poll_t handle_;
|
||||
|
||||
static void poll_callback(uv_poll_t* handle, int status, int events) {
|
||||
KPoll* poll = static_cast<KPoll*>(handle->data);
|
||||
auto poll = static_cast<KPoll*>(handle->data);
|
||||
poll->eventer_->pollCallback(poll, status, events);
|
||||
}
|
||||
static void close_callback(uv_handle_t* handle) {
|
||||
|
@ -87,8 +87,8 @@ private:
|
|||
inline KPoll(LibuvEventPoll* eventer, KSocketEntry* entry, sock_t sock)
|
||||
: eventer_(eventer), entry_(entry)
|
||||
{
|
||||
uv_poll_init_socket(eventer->loop_, &handle_, sock);
|
||||
handle_.data = this;
|
||||
uv_poll_init_socket(eventer->loop_, &handle_, sock);
|
||||
handle_.data = this;
|
||||
}
|
||||
inline void start() {
|
||||
uv_poll_start(&handle_, entry_->getEvents() & IEV_RW, poll_callback);
|
||||
|
|
|
@ -134,14 +134,12 @@ std::unique_ptr<StatCalc> getStatCalc(const std::shared_ptr<Option>& op)
|
|||
{
|
||||
if(op->getAsBool(PREF_QUIET)) {
|
||||
return make_unique<NullStatCalc>();
|
||||
} else {
|
||||
auto impl = make_unique<ConsoleStatCalc>
|
||||
(op->getAsInt(PREF_SUMMARY_INTERVAL),
|
||||
op->getAsBool(PREF_HUMAN_READABLE));
|
||||
impl->setReadoutVisibility(op->getAsBool(PREF_SHOW_CONSOLE_READOUT));
|
||||
impl->setTruncate(op->getAsBool(PREF_TRUNCATE_CONSOLE_READOUT));
|
||||
return std::move(impl);
|
||||
}
|
||||
auto impl = make_unique<ConsoleStatCalc>(op->getAsInt(PREF_SUMMARY_INTERVAL),
|
||||
op->getAsBool(PREF_HUMAN_READABLE));
|
||||
impl->setReadoutVisibility(op->getAsBool(PREF_SHOW_CONSOLE_READOUT));
|
||||
impl->setTruncate(op->getAsBool(PREF_TRUNCATE_CONSOLE_READOUT));
|
||||
return std::move(impl);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -183,21 +181,20 @@ int MultiUrlRequestInfo::prepare()
|
|||
#ifdef ENABLE_SSL
|
||||
if(option_->getAsBool(PREF_ENABLE_RPC) &&
|
||||
option_->getAsBool(PREF_RPC_SECURE)) {
|
||||
if(!option_->blank(PREF_RPC_CERTIFICATE)
|
||||
if(option_->blank(PREF_RPC_CERTIFICATE)
|
||||
#ifndef HAVE_APPLETLS
|
||||
&& !option_->blank(PREF_RPC_PRIVATE_KEY)
|
||||
|| option_->blank(PREF_RPC_PRIVATE_KEY)
|
||||
#endif // HAVE_APPLETLS
|
||||
) {
|
||||
// We set server TLS context to the SocketCore before creating
|
||||
// DownloadEngine instance.
|
||||
std::shared_ptr<TLSContext> svTlsContext(TLSContext::make(TLS_SERVER));
|
||||
svTlsContext->addCredentialFile(option_->get(PREF_RPC_CERTIFICATE),
|
||||
option_->get(PREF_RPC_PRIVATE_KEY));
|
||||
SocketCore::setServerTLSContext(svTlsContext);
|
||||
} else {
|
||||
throw DL_ABORT_EX("Specify --rpc-certificate and --rpc-private-key "
|
||||
"options in order to use secure RPC.");
|
||||
}
|
||||
// We set server TLS context to the SocketCore before creating
|
||||
// DownloadEngine instance.
|
||||
std::shared_ptr<TLSContext> svTlsContext(TLSContext::make(TLS_SERVER));
|
||||
svTlsContext->addCredentialFile(option_->get(PREF_RPC_CERTIFICATE),
|
||||
option_->get(PREF_RPC_PRIVATE_KEY));
|
||||
SocketCore::setServerTLSContext(svTlsContext);
|
||||
}
|
||||
#endif // ENABLE_SSL
|
||||
|
||||
|
|
|
@ -270,9 +270,8 @@ void SocketCore::bindWithFamily(uint16_t port, int family, int flags)
|
|||
sock_t fd = bindTo(nullptr, port, family, sockType_, flags, error);
|
||||
if(fd == (sock_t) -1) {
|
||||
throw DL_ABORT_EX(fmt(EX_SOCKET_BIND, error.c_str()));
|
||||
} else {
|
||||
sockfd_ = fd;
|
||||
}
|
||||
sockfd_ = fd;
|
||||
}
|
||||
|
||||
void SocketCore::bind
|
||||
|
@ -288,30 +287,30 @@ void SocketCore::bind
|
|||
}
|
||||
if(!(flags&AI_PASSIVE) || bindAddrs_.empty()) {
|
||||
sock_t fd = bindTo(addrp, port, family, sockType_, flags, error);
|
||||
if(fd != (sock_t) -1) {
|
||||
sockfd_ = fd;
|
||||
if(fd == (sock_t) -1) {
|
||||
throw DL_ABORT_EX(fmt(EX_SOCKET_BIND, error.c_str()));
|
||||
}
|
||||
} else {
|
||||
for(std::vector<std::pair<sockaddr_union, socklen_t> >::
|
||||
const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end();
|
||||
i != eoi; ++i) {
|
||||
char host[NI_MAXHOST];
|
||||
int s;
|
||||
s = getnameinfo(&(*i).first.sa, (*i).second, host, NI_MAXHOST, nullptr, 0,
|
||||
NI_NUMERICHOST);
|
||||
if(s) {
|
||||
error = gai_strerror(s);
|
||||
continue;
|
||||
}
|
||||
if(addrp && strcmp(host, addrp) != 0) {
|
||||
error = "Given address and resolved address do not match.";
|
||||
continue;
|
||||
}
|
||||
sock_t fd = bindTo(host, port, family, sockType_, flags, error);
|
||||
if(fd != (sock_t)-1) {
|
||||
sockfd_ = fd;
|
||||
break;
|
||||
}
|
||||
sockfd_ = fd;
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& a : bindAddrs_) {
|
||||
char host[NI_MAXHOST];
|
||||
int s;
|
||||
s = getnameinfo(&a.first.sa, a.second, host, NI_MAXHOST, nullptr, 0,
|
||||
NI_NUMERICHOST);
|
||||
if(s) {
|
||||
error = gai_strerror(s);
|
||||
continue;
|
||||
}
|
||||
if(addrp && strcmp(host, addrp) != 0) {
|
||||
error = "Given address and resolved address do not match.";
|
||||
continue;
|
||||
}
|
||||
sock_t fd = bindTo(host, port, family, sockType_, flags, error);
|
||||
if(fd != (sock_t)-1) {
|
||||
sockfd_ = fd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(sockfd_ == (sock_t) -1) {
|
||||
|
@ -329,11 +328,10 @@ void SocketCore::bind(const struct sockaddr* addr, socklen_t addrlen)
|
|||
closeConnection();
|
||||
std::string error;
|
||||
sock_t fd = bindInternal(addr->sa_family, sockType_, 0, addr, addrlen, error);
|
||||
if(fd != (sock_t)-1) {
|
||||
sockfd_ = fd;
|
||||
} else {
|
||||
if(fd == (sock_t)-1) {
|
||||
throw DL_ABORT_EX(fmt(EX_SOCKET_BIND, error.c_str()));
|
||||
}
|
||||
sockfd_ = fd;
|
||||
}
|
||||
|
||||
void SocketCore::beginListen()
|
||||
|
@ -486,11 +484,10 @@ void SocketCore::setMulticastInterface(const std::string& localAddr)
|
|||
in_addr addr;
|
||||
if(localAddr.empty()) {
|
||||
addr.s_addr = htonl(INADDR_ANY);
|
||||
} else {
|
||||
if(inetPton(AF_INET, localAddr.c_str(), &addr) != 0) {
|
||||
throw DL_ABORT_EX(fmt("%s is not valid IPv4 numeric address",
|
||||
localAddr.c_str()));
|
||||
}
|
||||
}
|
||||
else if(inetPton(AF_INET, localAddr.c_str(), &addr) != 0) {
|
||||
throw DL_ABORT_EX(fmt("%s is not valid IPv4 numeric address",
|
||||
localAddr.c_str()));
|
||||
}
|
||||
setSockOpt(IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));
|
||||
}
|
||||
|
@ -517,11 +514,10 @@ void SocketCore::joinMulticastGroup
|
|||
in_addr ifAddr;
|
||||
if(localAddr.empty()) {
|
||||
ifAddr.s_addr = htonl(INADDR_ANY);
|
||||
} else {
|
||||
if(inetPton(AF_INET, localAddr.c_str(), &ifAddr) != 0) {
|
||||
throw DL_ABORT_EX(fmt("%s is not valid IPv4 numeric address",
|
||||
localAddr.c_str()));
|
||||
}
|
||||
}
|
||||
else if(inetPton(AF_INET, localAddr.c_str(), &ifAddr) != 0) {
|
||||
throw DL_ABORT_EX(fmt("%s is not valid IPv4 numeric address",
|
||||
localAddr.c_str()));
|
||||
}
|
||||
struct ip_mreq mreq;
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
|
@ -605,11 +601,11 @@ bool SocketCore::isWritable(time_t timeout)
|
|||
int errNum = SOCKET_ERRNO;
|
||||
if(r > 0) {
|
||||
return p.revents&(POLLOUT|POLLHUP|POLLERR);
|
||||
} else if(r == 0) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_CHECK_WRITABLE, errorMsg(errNum).c_str()));
|
||||
}
|
||||
if(r == 0) {
|
||||
return false;
|
||||
}
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_CHECK_WRITABLE, errorMsg(errNum).c_str()));
|
||||
#else // !HAVE_POLL
|
||||
# ifndef __MINGW32__
|
||||
CHECK_FD(sockfd_);
|
||||
|
@ -626,17 +622,15 @@ bool SocketCore::isWritable(time_t timeout)
|
|||
int errNum = SOCKET_ERRNO;
|
||||
if(r == 1) {
|
||||
return true;
|
||||
} else if(r == 0) {
|
||||
}
|
||||
if(r == 0) {
|
||||
// time out
|
||||
return false;
|
||||
} else {
|
||||
if(errNum == A2_EINPROGRESS || errNum == A2_EINTR) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(fmt(EX_SOCKET_CHECK_WRITABLE, errorMsg(errNum).c_str()));
|
||||
}
|
||||
}
|
||||
if(errNum == A2_EINPROGRESS || errNum == A2_EINTR) {
|
||||
return false;
|
||||
}
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_CHECK_WRITABLE, errorMsg(errNum).c_str()));
|
||||
#endif // !HAVE_POLL
|
||||
}
|
||||
|
||||
|
@ -651,11 +645,11 @@ bool SocketCore::isReadable(time_t timeout)
|
|||
int errNum = SOCKET_ERRNO;
|
||||
if(r > 0) {
|
||||
return p.revents&(POLLIN|POLLHUP|POLLERR);
|
||||
} else if(r == 0) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_CHECK_READABLE, errorMsg(errNum).c_str()));
|
||||
}
|
||||
if(r == 0) {
|
||||
return false;
|
||||
}
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_CHECK_READABLE, errorMsg(errNum).c_str()));
|
||||
#else // !HAVE_POLL
|
||||
# ifndef __MINGW32__
|
||||
CHECK_FD(sockfd_);
|
||||
|
@ -672,17 +666,15 @@ bool SocketCore::isReadable(time_t timeout)
|
|||
int errNum = SOCKET_ERRNO;
|
||||
if(r == 1) {
|
||||
return true;
|
||||
} else if(r == 0) {
|
||||
}
|
||||
if(r == 0) {
|
||||
// time out
|
||||
return false;
|
||||
} else {
|
||||
if(errNum == A2_EINPROGRESS || errNum == A2_EINTR) {
|
||||
return false;
|
||||
} else {
|
||||
throw DL_RETRY_EX
|
||||
(fmt(EX_SOCKET_CHECK_READABLE, errorMsg(errNum).c_str()));
|
||||
}
|
||||
}
|
||||
if(errNum == A2_EINPROGRESS || errNum == A2_EINTR) {
|
||||
return false;
|
||||
}
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_CHECK_READABLE, errorMsg(errNum).c_str()));
|
||||
#endif // !HAVE_POLL
|
||||
}
|
||||
|
||||
|
@ -706,12 +698,11 @@ ssize_t SocketCore::writeVector(a2iovec *iov, size_t iovcnt)
|
|||
#endif // !__MINGW32__
|
||||
int errNum = SOCKET_ERRNO;
|
||||
if(ret == -1) {
|
||||
if(A2_WOULDBLOCK(errNum)) {
|
||||
wantWrite_ = true;
|
||||
ret = 0;
|
||||
} else {
|
||||
if(!A2_WOULDBLOCK(errNum)) {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_SEND, errorMsg(errNum).c_str()));
|
||||
}
|
||||
wantWrite_ = true;
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
// For SSL/TLS, we could not use writev, so just iterate vector
|
||||
|
@ -739,28 +730,26 @@ ssize_t SocketCore::writeData(const void* data, size_t len)
|
|||
len, 0)) == -1 && SOCKET_ERRNO == A2_EINTR);
|
||||
int errNum = SOCKET_ERRNO;
|
||||
if(ret == -1) {
|
||||
if(A2_WOULDBLOCK(errNum)) {
|
||||
wantWrite_ = true;
|
||||
ret = 0;
|
||||
} else {
|
||||
if(!A2_WOULDBLOCK(errNum)) {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_SEND, errorMsg(errNum).c_str()));
|
||||
}
|
||||
wantWrite_ = true;
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
#ifdef ENABLE_SSL
|
||||
ret = tlsSession_->writeData(data, len);
|
||||
if(ret < 0) {
|
||||
if(ret == TLS_ERR_WOULDBLOCK) {
|
||||
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
|
||||
wantRead_ = true;
|
||||
} else {
|
||||
wantWrite_ = true;
|
||||
}
|
||||
ret = 0;
|
||||
} else {
|
||||
if(ret != TLS_ERR_WOULDBLOCK) {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_SEND,
|
||||
tlsSession_->getLastErrorString().c_str()));
|
||||
}
|
||||
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
|
||||
wantRead_ = true;
|
||||
} else {
|
||||
wantWrite_ = true;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
#endif // ENABLE_SSL
|
||||
}
|
||||
|
@ -779,28 +768,26 @@ void SocketCore::readData(void* data, size_t& len)
|
|||
SOCKET_ERRNO == A2_EINTR);
|
||||
int errNum = SOCKET_ERRNO;
|
||||
if(ret == -1) {
|
||||
if(A2_WOULDBLOCK(errNum)) {
|
||||
wantRead_ = true;
|
||||
ret = 0;
|
||||
} else {
|
||||
if(!A2_WOULDBLOCK(errNum)) {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_RECV, errorMsg(errNum).c_str()));
|
||||
}
|
||||
wantRead_ = true;
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
#ifdef ENABLE_SSL
|
||||
ret = tlsSession_->readData(data, len);
|
||||
if(ret < 0) {
|
||||
if(ret == TLS_ERR_WOULDBLOCK) {
|
||||
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
|
||||
wantRead_ = true;
|
||||
} else {
|
||||
wantWrite_ = true;
|
||||
}
|
||||
ret = 0;
|
||||
} else {
|
||||
if(ret != TLS_ERR_WOULDBLOCK) {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_SEND,
|
||||
tlsSession_->getLastErrorString().c_str()));
|
||||
}
|
||||
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
|
||||
wantRead_ = true;
|
||||
} else {
|
||||
wantWrite_ = true;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
#endif // ENABLE_SSL
|
||||
}
|
||||
|
@ -855,20 +842,20 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
|
|||
}
|
||||
if(rv == TLS_ERR_OK) {
|
||||
secure_ = A2_TLS_CONNECTED;
|
||||
} else if(rv == TLS_ERR_WOULDBLOCK) {
|
||||
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
|
||||
wantRead_ = true;
|
||||
} else {
|
||||
wantWrite_ = true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if(rv != TLS_ERR_WOULDBLOCK) {
|
||||
throw DL_ABORT_EX(fmt("SSL/TLS handshake failure: %s",
|
||||
handshakeError.empty() ?
|
||||
tlsSession_->getLastErrorString().c_str() :
|
||||
handshakeError.c_str()));
|
||||
}
|
||||
break;
|
||||
if(tlsSession_->checkDirection() == TLS_WANT_READ) {
|
||||
wantRead_ = true;
|
||||
} else {
|
||||
wantWrite_ = true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -931,12 +918,11 @@ ssize_t SocketCore::readDataFrom(void* data, size_t len,
|
|||
&& A2_EINTR == SOCKET_ERRNO);
|
||||
int errNum = SOCKET_ERRNO;
|
||||
if(r == -1) {
|
||||
if(A2_WOULDBLOCK(errNum)) {
|
||||
wantRead_ = true;
|
||||
r = 0;
|
||||
} else {
|
||||
if(!A2_WOULDBLOCK(errNum)) {
|
||||
throw DL_RETRY_EX(fmt(EX_SOCKET_RECV, errorMsg(errNum).c_str()));
|
||||
}
|
||||
wantRead_ = true;
|
||||
r = 0;
|
||||
} else {
|
||||
sender = util::getNumericNameInfo(&sockaddr.sa, sockaddrlen);
|
||||
}
|
||||
|
@ -957,9 +943,8 @@ std::string SocketCore::getSocketError() const
|
|||
}
|
||||
if(error != 0) {
|
||||
return errorMsg(error);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool SocketCore::wantRead() const
|
||||
|
@ -977,20 +962,17 @@ void SocketCore::bindAddress(const std::string& iface)
|
|||
std::vector<std::pair<sockaddr_union, socklen_t> > bindAddrs;
|
||||
getInterfaceAddress(bindAddrs, iface, protocolFamily_);
|
||||
if(bindAddrs.empty()) {
|
||||
throw DL_ABORT_EX
|
||||
(fmt(MSG_INTERFACE_NOT_FOUND, iface.c_str(), "not available"));
|
||||
} else {
|
||||
bindAddrs_.swap(bindAddrs);
|
||||
for(std::vector<std::pair<sockaddr_union, socklen_t> >::
|
||||
const_iterator i = bindAddrs_.begin(), eoi = bindAddrs_.end();
|
||||
i != eoi; ++i) {
|
||||
char host[NI_MAXHOST];
|
||||
int s;
|
||||
s = getnameinfo(&(*i).first.sa, (*i).second, host, NI_MAXHOST, nullptr, 0,
|
||||
NI_NUMERICHOST);
|
||||
if(s == 0) {
|
||||
A2_LOG_DEBUG(fmt("Sockets will bind to %s", host));
|
||||
}
|
||||
throw DL_ABORT_EX(fmt(MSG_INTERFACE_NOT_FOUND, iface.c_str(),
|
||||
"not available"));
|
||||
}
|
||||
bindAddrs_.swap(bindAddrs);
|
||||
for (const auto& a: bindAddrs_) {
|
||||
char host[NI_MAXHOST];
|
||||
int s;
|
||||
s = getnameinfo(&a.first.sa, a.second, host, NI_MAXHOST, nullptr, 0,
|
||||
NI_NUMERICHOST);
|
||||
if(s == 0) {
|
||||
A2_LOG_DEBUG(fmt("Sockets will bind to %s", host));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1101,7 +1083,6 @@ int callGetaddrinfo
|
|||
|
||||
int inetNtop(int af, const void* src, char* dst, socklen_t size)
|
||||
{
|
||||
int s;
|
||||
sockaddr_union su;
|
||||
memset(&su, 0, sizeof(su));
|
||||
if(af == AF_INET) {
|
||||
|
@ -1110,20 +1091,19 @@ int inetNtop(int af, const void* src, char* dst, socklen_t size)
|
|||
su.in.sin_len = sizeof(su.in);
|
||||
#endif // HAVE_SOCKADDR_IN_SIN_LEN
|
||||
memcpy(&su.in.sin_addr, src, sizeof(su.in.sin_addr));
|
||||
s = getnameinfo(&su.sa, sizeof(su.in),
|
||||
dst, size, nullptr, 0, NI_NUMERICHOST);
|
||||
} else if(af == AF_INET6) {
|
||||
return getnameinfo(&su.sa, sizeof(su.in), dst, size, nullptr, 0,
|
||||
NI_NUMERICHOST);
|
||||
}
|
||||
if(af == AF_INET6) {
|
||||
su.in6.sin6_family = AF_INET6;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_LEN
|
||||
su.in6.sin6_len = sizeof(su.in6);
|
||||
#endif // HAVE_SOCKADDR_IN6_SIN6_LEN
|
||||
memcpy(&su.in6.sin6_addr, src, sizeof(su.in6.sin6_addr));
|
||||
s = getnameinfo(&su.sa, sizeof(su.in6),
|
||||
dst, size, nullptr, 0, NI_NUMERICHOST);
|
||||
} else {
|
||||
s = EAI_FAMILY;
|
||||
return getnameinfo(&su.sa, sizeof(su.in6), dst, size, nullptr, 0,
|
||||
NI_NUMERICHOST);
|
||||
}
|
||||
return s;
|
||||
return EAI_FAMILY;
|
||||
}
|
||||
|
||||
int inetPton(int af, const char* src, void* dst)
|
||||
|
@ -1139,16 +1119,17 @@ int inetPton(int af, const char* src, void* dst)
|
|||
}
|
||||
in_addr* addr = reinterpret_cast<in_addr*>(dst);
|
||||
addr->s_addr = binaddr.ipv4_addr;
|
||||
} else if(af == AF_INET6) {
|
||||
return 0;
|
||||
}
|
||||
if(af == AF_INET6) {
|
||||
if(len != 16) {
|
||||
return -1;
|
||||
}
|
||||
in6_addr* addr = reinterpret_cast<in6_addr*>(dst);
|
||||
memcpy(addr->s6_addr, binaddr.ipv6_addr, sizeof(addr->s6_addr));
|
||||
} else {
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
|
@ -1200,14 +1181,15 @@ bool verifyHostname(const std::string& hostname,
|
|||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(dnsNames.empty()) {
|
||||
return util::tlsHostnameMatch(commonName, hostname);
|
||||
}
|
||||
for(auto i = dnsNames.begin(), eoi = dnsNames.end(); i != eoi; ++i) {
|
||||
if(util::tlsHostnameMatch(*i, hostname)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(dnsNames.empty()) {
|
||||
return util::tlsHostnameMatch(commonName, hostname);
|
||||
}
|
||||
for(auto i = dnsNames.begin(), eoi = dnsNames.end(); i != eoi; ++i) {
|
||||
if(util::tlsHostnameMatch(*i, hostname)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -1237,12 +1219,11 @@ void checkAddrconfig()
|
|||
do {
|
||||
buf = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(bufsize));
|
||||
retval = GetAdaptersAddresses(AF_UNSPEC, 0, 0, buf, &bufsize);
|
||||
if(retval == ERROR_BUFFER_OVERFLOW) {
|
||||
free(buf);
|
||||
buf = 0;
|
||||
} else {
|
||||
if(retval != ERROR_BUFFER_OVERFLOW) {
|
||||
break;
|
||||
}
|
||||
free(buf);
|
||||
buf = 0;
|
||||
} while(retval == ERROR_BUFFER_OVERFLOW && numTry < MAX_TRY);
|
||||
if(retval != NO_ERROR) {
|
||||
A2_LOG_INFO("GetAdaptersAddresses failed. Assume both IPv4 and IPv6 "
|
||||
|
@ -1261,44 +1242,46 @@ void checkAddrconfig()
|
|||
continue;
|
||||
}
|
||||
PIP_ADAPTER_UNICAST_ADDRESS ucaddr = p->FirstUnicastAddress;
|
||||
if(ucaddr) {
|
||||
for(PIP_ADAPTER_UNICAST_ADDRESS i = ucaddr; i; i = i->Next) {
|
||||
bool found = false;
|
||||
switch(i->Address.iSockaddrLength) {
|
||||
case sizeof(sockaddr_in): {
|
||||
memcpy(&ad.storage, i->Address.lpSockaddr,
|
||||
i->Address.iSockaddrLength);
|
||||
uint32_t haddr = ntohl(ad.in.sin_addr.s_addr);
|
||||
if(haddr != INADDR_LOOPBACK &&
|
||||
(haddr < APIPA_IPV4_BEGIN || APIPA_IPV4_END <= haddr)) {
|
||||
ipv4AddrConfigured = true;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
if(!ucaddr) {
|
||||
continue;
|
||||
}
|
||||
for(PIP_ADAPTER_UNICAST_ADDRESS i = ucaddr; i; i = i->Next) {
|
||||
bool found = false;
|
||||
switch(i->Address.iSockaddrLength) {
|
||||
case sizeof(sockaddr_in): {
|
||||
memcpy(&ad.storage, i->Address.lpSockaddr,
|
||||
i->Address.iSockaddrLength);
|
||||
uint32_t haddr = ntohl(ad.in.sin_addr.s_addr);
|
||||
if(haddr != INADDR_LOOPBACK &&
|
||||
(haddr < APIPA_IPV4_BEGIN || APIPA_IPV4_END <= haddr)) {
|
||||
ipv4AddrConfigured = true;
|
||||
found = true;
|
||||
}
|
||||
case sizeof(sockaddr_in6):
|
||||
memcpy(&ad.storage, i->Address.lpSockaddr,
|
||||
i->Address.iSockaddrLength);
|
||||
if(!IN6_IS_ADDR_LOOPBACK(&ad.in6.sin6_addr) &&
|
||||
!IN6_IS_ADDR_LINKLOCAL(&ad.in6.sin6_addr)) {
|
||||
ipv6AddrConfigured = true;
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case sizeof(sockaddr_in6):
|
||||
memcpy(&ad.storage, i->Address.lpSockaddr,
|
||||
i->Address.iSockaddrLength);
|
||||
if(!IN6_IS_ADDR_LOOPBACK(&ad.in6.sin6_addr) &&
|
||||
!IN6_IS_ADDR_LINKLOCAL(&ad.in6.sin6_addr)) {
|
||||
ipv6AddrConfigured = true;
|
||||
found = true;
|
||||
}
|
||||
rv = getnameinfo(i->Address.lpSockaddr, i->Address.iSockaddrLength,
|
||||
host, NI_MAXHOST, 0, 0, NI_NUMERICHOST);
|
||||
if(rv == 0) {
|
||||
if(found) {
|
||||
A2_LOG_INFO(fmt("Found configured address: %s", host));
|
||||
} else {
|
||||
A2_LOG_INFO(fmt("Not considered: %s", host));
|
||||
}
|
||||
break;
|
||||
}
|
||||
rv = getnameinfo(i->Address.lpSockaddr, i->Address.iSockaddrLength,
|
||||
host, NI_MAXHOST, 0, 0, NI_NUMERICHOST);
|
||||
if(rv == 0) {
|
||||
if(found) {
|
||||
A2_LOG_INFO(fmt("Found configured address: %s", host));
|
||||
} else {
|
||||
A2_LOG_INFO(fmt("Not considered: %s", host));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
|
||||
A2_LOG_INFO(fmt("IPv4 configured=%d, IPv6 configured=%d",
|
||||
ipv4AddrConfigured, ipv6AddrConfigured));
|
||||
#elif defined(HAVE_GETIFADDRS)
|
||||
|
|
Loading…
Reference in New Issue