mirror of https://github.com/aria2/aria2
parent
8ed8ac0fe8
commit
34d773a465
|
@ -229,6 +229,11 @@ Context::Context(bool standalone,
|
|||
std::string iface = op->get(PREF_INTERFACE);
|
||||
SocketCore::bindAddress(iface);
|
||||
}
|
||||
// Bind multiple interfaces
|
||||
if(!op->get(PREF_MULTIPLE_INTERFACE).empty() && op->get(PREF_INTERFACE).empty()) {
|
||||
std::string ifaces = op->get(PREF_MULTIPLE_INTERFACE);
|
||||
SocketCore::bindAllAddress(ifaces);
|
||||
}
|
||||
std::vector<std::shared_ptr<RequestGroup> > requestGroups;
|
||||
std::shared_ptr<UriListParser> uriListParser;
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
|
|
|
@ -470,6 +470,16 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
|||
op->addTag(TAG_ADVANCED);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
{
|
||||
OptionHandler* op(new DefaultOptionHandler
|
||||
(PREF_MULTIPLE_INTERFACE,
|
||||
TEXT_MULTIPLE_INTERFACE,
|
||||
NO_DEFAULT_VALUE,
|
||||
"interface, IP address, hostname",
|
||||
OptionHandler::REQ_ARG));
|
||||
op->addTag(TAG_ADVANCED);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
{
|
||||
OptionHandler* op(new DefaultOptionHandler
|
||||
(PREF_LOG,
|
||||
|
|
|
@ -134,6 +134,10 @@ int SocketCore::ipDscp_ = 0;
|
|||
|
||||
std::vector<std::pair<sockaddr_union, socklen_t> >
|
||||
SocketCore::bindAddrs_;
|
||||
std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >
|
||||
SocketCore::bindAddrsList_;
|
||||
std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >::iterator
|
||||
SocketCore::bindAddrsListIt_;
|
||||
|
||||
#ifdef ENABLE_SSL
|
||||
std::shared_ptr<TLSContext> SocketCore::clTlsContext_;
|
||||
|
@ -448,6 +452,13 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if(!bindAddrsList_.empty()) {
|
||||
++bindAddrsListIt_;
|
||||
if (bindAddrsListIt_ == bindAddrsList_.end()) {
|
||||
bindAddrsListIt_ = bindAddrsList_.begin();
|
||||
}
|
||||
bindAddrs_ = *bindAddrsListIt_;
|
||||
}
|
||||
|
||||
sockfd_ = fd;
|
||||
// make socket non-blocking mode
|
||||
|
@ -1059,6 +1070,37 @@ void SocketCore::bindAddress(const std::string& iface)
|
|||
}
|
||||
}
|
||||
|
||||
void SocketCore::bindAllAddress(const std::string& ifaces)
|
||||
{
|
||||
std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > > bindAddrsList;
|
||||
std::vector<std::string> ifaceList;
|
||||
util::split(ifaces.begin(), ifaces.end(), std::back_inserter(ifaceList), ',', true);
|
||||
if (ifaceList.empty()) {
|
||||
throw DL_ABORT_EX("List of interfaces is empty, one or more interfaces is required");
|
||||
}
|
||||
for (auto& iface: ifaceList) {
|
||||
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"));
|
||||
}
|
||||
bindAddrsList.push_back(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));
|
||||
}
|
||||
}
|
||||
}
|
||||
bindAddrsList_.swap(bindAddrsList);
|
||||
bindAddrsListIt_ = bindAddrsList_.begin();
|
||||
bindAddrs_ = *bindAddrsListIt_;
|
||||
}
|
||||
|
||||
void getInterfaceAddress
|
||||
(std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs,
|
||||
const std::string& iface, int family, int aiFlags)
|
||||
|
|
|
@ -69,6 +69,8 @@ private:
|
|||
static int ipDscp_;
|
||||
|
||||
static std::vector<std::pair<sockaddr_union, socklen_t> > bindAddrs_;
|
||||
static std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > > bindAddrsList_;
|
||||
static std::vector<std::vector<std::pair<sockaddr_union, socklen_t> > >::iterator bindAddrsListIt_;
|
||||
|
||||
bool blocking_;
|
||||
int secure_;
|
||||
|
@ -334,6 +336,7 @@ public:
|
|||
// We cannot use interface as an argument because it is a reserved
|
||||
// keyword in MSVC.
|
||||
static void bindAddress(const std::string& iface);
|
||||
static void bindAllAddress(const std::string& ifaces);
|
||||
|
||||
friend void getInterfaceAddress
|
||||
(std::vector<std::pair<sockaddr_union, socklen_t> >& ifAddrs,
|
||||
|
|
|
@ -308,6 +308,8 @@ PrefPtr PREF_ON_DOWNLOAD_COMPLETE = makePref("on-download-complete");
|
|||
PrefPtr PREF_ON_DOWNLOAD_ERROR = makePref("on-download-error");
|
||||
// value: string
|
||||
PrefPtr PREF_INTERFACE = makePref("interface");
|
||||
// value: string
|
||||
PrefPtr PREF_MULTIPLE_INTERFACE = makePref("multiple-interface");
|
||||
// value: true | false
|
||||
PrefPtr PREF_DISABLE_IPV6 = makePref("disable-ipv6");
|
||||
// value: true | false
|
||||
|
|
|
@ -244,6 +244,8 @@ extern PrefPtr PREF_ON_DOWNLOAD_COMPLETE;
|
|||
extern PrefPtr PREF_ON_DOWNLOAD_ERROR;
|
||||
// value: string
|
||||
extern PrefPtr PREF_INTERFACE;
|
||||
// value: string
|
||||
extern PrefPtr PREF_MULTIPLE_INTERFACE;
|
||||
// value: true | false
|
||||
extern PrefPtr PREF_DISABLE_IPV6;
|
||||
// value: true | false
|
||||
|
|
|
@ -599,6 +599,11 @@
|
|||
#define TEXT_INTERFACE \
|
||||
_(" --interface=INTERFACE Bind sockets to given interface. You can specify\n" \
|
||||
" interface name, IP address and hostname.")
|
||||
#define TEXT_MULTIPLE_INTERFACE \
|
||||
_(" --multiple-interface=INTERFACES Comma separated list of interfaces to bind\n" \
|
||||
" sockets to. Requests will be splited among the\n" \
|
||||
" interfaces to achieve link aggregation. You can\n" \
|
||||
" specify interface name, IP address and hostname.")
|
||||
#define TEXT_DISABLE_IPV6 \
|
||||
_(" --disable-ipv6[=true|false] Disable IPv6.")
|
||||
#define TEXT_BT_SAVE_METADATA \
|
||||
|
|
Loading…
Reference in New Issue