multiple interface support for link aggregation

fix: wrong variable
pull/364/head
Sarim Khan 2015-04-19 18:53:59 +06:00
parent 8ed8ac0fe8
commit 34d773a465
7 changed files with 69 additions and 0 deletions

View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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 \