Procházet zdrojové kódy

2009-12-08 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Fixed the bug that aria2 listens wrong port if --interface option
	is used.
	* src/SocketCore.cc
Tatsuhiro Tsujikawa před 16 roky
rodič
revize
cc4a14a1bc
2 změnil soubory, kde provedl 51 přidání a 28 odebrání
  1. 6 0
      ChangeLog
  2. 45 28
      src/SocketCore.cc

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+2009-12-08  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Fixed the bug that aria2 listens wrong port if --interface option
+	is used.
+	* src/SocketCore.cc
+
 2009-12-07  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Fixed the bug that query parameter in magnet URI is not decoded.

+ 45 - 28
src/SocketCore.cc

@@ -187,41 +187,58 @@ static sock_t bindInternal(int family, int socktype, int protocol,
   return fd;
 }
 
+static sock_t bindTo
+(const char* host, uint16_t port, int family, int sockType,
+ int getaddrinfoFlags, std::string& error)
+{
+  struct addrinfo hints;
+  struct addrinfo* res;
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = family;
+  hints.ai_socktype = sockType;
+  hints.ai_flags = getaddrinfoFlags;
+  hints.ai_protocol = 0;
+  int s = getaddrinfo(host, uitos(port).c_str(), &hints, &res);
+  if(s) {
+    error = gai_strerror(s);
+    return -1;
+  }
+  auto_delete<struct addrinfo*> resDeleter(res, freeaddrinfo);
+  struct addrinfo* rp;
+  for(rp = res; rp; rp = rp->ai_next) {
+    sock_t fd = bindInternal(rp->ai_family, rp->ai_socktype, rp->ai_protocol,
+			     rp->ai_addr, rp->ai_addrlen);
+    if(fd != (sock_t)-1) {
+      return fd;
+    }
+  }
+  error = strerror(errno);
+  return -1;
+}
+
 void SocketCore::bind(uint16_t port, int flags)
 {
   closeConnection();
-
-  if(flags == 0 || _bindAddrs.empty()) {
-    struct addrinfo hints;
-    struct addrinfo* res;
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = _protocolFamily;
-    hints.ai_socktype = _sockType;
-    hints.ai_flags = flags;
-    hints.ai_protocol = 0;
-    int s;
-    s = getaddrinfo(0, uitos(port).c_str(), &hints, &res);
-    if(s) {
-      throw DL_ABORT_EX(StringFormat(EX_SOCKET_BIND, gai_strerror(s)).str());
-    }
-    struct addrinfo* rp;
-    for(rp = res; rp; rp = rp->ai_next) {
-      sock_t fd = bindInternal(rp->ai_family, rp->ai_socktype, rp->ai_protocol,
-			       rp->ai_addr, rp->ai_addrlen);
-      if(fd == (sock_t) -1) {
-	continue;
-      }
+  std::string error;
+  if(!(flags&AI_PASSIVE) || _bindAddrs.empty()) {
+    sock_t fd = bindTo(0, port, _protocolFamily, _sockType, flags, error);
+    if(fd != (sock_t) -1) {
       sockfd = fd;
-      break;
     }
-    freeaddrinfo(res);
   } else {
     for(std::vector<std::pair<struct sockaddr_storage, socklen_t> >::
 	  const_iterator i = _bindAddrs.begin(); i != _bindAddrs.end(); ++i) {
-      sock_t fd = bindInternal
-	((*i).first.ss_family, _sockType, 0,
-	 reinterpret_cast<const struct sockaddr*>
-	 (&(*i).first), (*i).second);
+      char host[NI_MAXHOST];
+      int s;
+      s = getnameinfo(reinterpret_cast<const struct sockaddr*>(&(*i).first),
+		      (*i).second,
+		      host, NI_MAXHOST, 0, NI_MAXSERV,
+		      NI_NUMERICHOST);
+      if(s) {
+	error = gai_strerror(s);
+	continue;
+      }
+      sock_t fd = bindTo(host, port, _protocolFamily, _sockType, flags, error);
       if(fd != (sock_t)-1) {
 	sockfd = fd;
 	break;
@@ -229,7 +246,7 @@ void SocketCore::bind(uint16_t port, int flags)
     }
   }
   if(sockfd == (sock_t) -1) {
-    throw DL_ABORT_EX(StringFormat(EX_SOCKET_BIND, strerror(errno)).str());
+    throw DL_ABORT_EX(StringFormat(EX_SOCKET_BIND, error.c_str()).str());
   }
 }