diff --git a/ChangeLog b/ChangeLog index c52cda23..8fb64bfa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-12-08 Tatsuhiro Tsujikawa + + Fixed the bug that aria2 listens wrong port if --interface option + is used. + * src/SocketCore.cc + 2009-12-07 Tatsuhiro Tsujikawa Fixed the bug that query parameter in magnet URI is not decoded. diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 8dcece60..83d5c068 100644 --- a/src/SocketCore.cc +++ b/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 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 >:: const_iterator i = _bindAddrs.begin(); i != _bindAddrs.end(); ++i) { - sock_t fd = bindInternal - ((*i).first.ss_family, _sockType, 0, - reinterpret_cast - (&(*i).first), (*i).second); + char host[NI_MAXHOST]; + int s; + s = getnameinfo(reinterpret_cast(&(*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()); } }