浏览代码

Merge branch 'sarim-master'

Tatsuhiro Tsujikawa 10 年之前
父节点
当前提交
3c84aa0745
共有 7 个文件被更改,包括 69 次插入0 次删除
  1. 5 0
      src/Context.cc
  2. 10 0
      src/OptionHandlerFactory.cc
  3. 42 0
      src/SocketCore.cc
  4. 3 0
      src/SocketCore.h
  5. 2 0
      src/prefs.cc
  6. 2 0
      src/prefs.h
  7. 5 0
      src/usage_text.h

+ 5 - 0
src/Context.cc

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

+ 10 - 0
src/OptionHandlerFactory.cc

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

+ 42 - 0
src/SocketCore.cc

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

+ 3 - 0
src/SocketCore.h

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

+ 2 - 0
src/prefs.cc

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

+ 2 - 0
src/prefs.h

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

+ 5 - 0
src/usage_text.h

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