mirror of https://github.com/aria2/aria2
				
				
				
			2009-12-24 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Use AI_ADDRCONFIG flag if it is available. Refactored so that getaddrinfo calls are not scattered around. Unset AI_ADDRCONFIG when conducting unit tests because they fail if networking interface is not configured with IPv4 address. * src/NameResolver.cc * src/SocketCore.cc * src/SocketCore.h * src/a2netcompat.h * test/AllTest.ccpull/1/head
							parent
							
								
									0190564ad3
								
							
						
					
					
						commit
						88bcc6e681
					
				
							
								
								
									
										12
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										12
									
								
								ChangeLog
								
								
								
								
							|  | @ -1,3 +1,15 @@ | |||
| 2009-12-24  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net> | ||||
| 
 | ||||
| 	Use AI_ADDRCONFIG flag if it is available. Refactored so that | ||||
| 	getaddrinfo calls are not scattered around. Unset AI_ADDRCONFIG | ||||
| 	when conducting unit tests because they fail if networking | ||||
| 	interface is not configured with IPv4 address. | ||||
| 	* src/NameResolver.cc | ||||
| 	* src/SocketCore.cc | ||||
| 	* src/SocketCore.h | ||||
| 	* src/a2netcompat.h | ||||
| 	* test/AllTest.cc | ||||
| 
 | ||||
| 2009-12-24  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net> | ||||
| 
 | ||||
| 	Fixed unit test error | ||||
|  |  | |||
|  | @ -40,6 +40,7 @@ | |||
| #include "message.h" | ||||
| #include "StringFormat.h" | ||||
| #include "util.h" | ||||
| #include "SocketCore.h" | ||||
| 
 | ||||
| namespace aria2 { | ||||
| 
 | ||||
|  | @ -48,26 +49,20 @@ NameResolver::NameResolver():_socktype(0), _family(AF_UNSPEC) {} | |||
| void NameResolver::resolve(std::deque<std::string>& resolvedAddresses, | ||||
| 			   const std::string& hostname) | ||||
| { | ||||
|   struct addrinfo hints; | ||||
|   struct addrinfo* res; | ||||
|   memset(&hints, 0, sizeof(hints)); | ||||
|   hints.ai_family = _family; | ||||
|   hints.ai_socktype = _socktype; | ||||
|   hints.ai_flags = 0; | ||||
|   hints.ai_protocol = 0; | ||||
|   int s; | ||||
|   s = getaddrinfo(hostname.c_str(), 0, &hints, &res); | ||||
|   s = callGetaddrinfo(&res, hostname.c_str(), 0, _family, _socktype, 0, 0); | ||||
|   if(s) { | ||||
|     throw DL_ABORT_EX(StringFormat(EX_RESOLVE_HOSTNAME, | ||||
| 				 hostname.c_str(), gai_strerror(s)).str()); | ||||
|   } | ||||
|   auto_delete<struct addrinfo*> resDeleter(res, freeaddrinfo); | ||||
|   struct addrinfo* rp; | ||||
|   for(rp = res; rp; rp = rp->ai_next) { | ||||
|     std::pair<std::string, uint16_t> addressPort | ||||
|       = util::getNumericNameInfo(rp->ai_addr, rp->ai_addrlen); | ||||
|     resolvedAddresses.push_back(addressPort.first); | ||||
|   } | ||||
|   freeaddrinfo(res); | ||||
| } | ||||
| 
 | ||||
| void NameResolver::setSocktype(int socktype) | ||||
|  |  | |||
|  | @ -191,14 +191,9 @@ 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); | ||||
|   int s = callGetaddrinfo(&res, host, uitos(port).c_str(), family, sockType, | ||||
| 			  getaddrinfoFlags, 0);   | ||||
|   if(s) { | ||||
|     error = gai_strerror(s); | ||||
|     return -1; | ||||
|  | @ -307,19 +302,15 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port) | |||
| { | ||||
|   closeConnection(); | ||||
| 
 | ||||
|   struct addrinfo hints; | ||||
|   struct addrinfo* res; | ||||
|   memset(&hints, 0, sizeof(hints)); | ||||
|   hints.ai_family = _protocolFamily; | ||||
|   hints.ai_socktype = _sockType; | ||||
|   hints.ai_flags = 0; | ||||
|   hints.ai_protocol = 0; | ||||
|   int s; | ||||
|   s = getaddrinfo(host.c_str(), uitos(port).c_str(), &hints, &res); | ||||
|   s = callGetaddrinfo(&res, host.c_str(), uitos(port).c_str(), _protocolFamily, | ||||
| 		      _sockType, 0, 0); | ||||
|   if(s) { | ||||
|     throw DL_ABORT_EX(StringFormat(EX_RESOLVE_HOSTNAME, | ||||
| 				 host.c_str(), gai_strerror(s)).str()); | ||||
|   } | ||||
|   auto_delete<struct addrinfo*> resDeleter(res, freeaddrinfo); | ||||
|   struct addrinfo* rp; | ||||
|   for(rp = res; rp; rp = rp->ai_next) { | ||||
|     sock_t fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); | ||||
|  | @ -362,7 +353,6 @@ void SocketCore::establishConnection(const std::string& host, uint16_t port) | |||
|     // later. In such case, next ai_addr should be tried.
 | ||||
|     break; | ||||
|   } | ||||
|   freeaddrinfo(res); | ||||
|   if(sockfd == (sock_t) -1) { | ||||
|     throw DL_ABORT_EX(StringFormat(EX_SOCKET_CONNECT, host.c_str(), | ||||
| 				   strerror(errno)).str()); | ||||
|  | @ -1058,18 +1048,14 @@ ssize_t SocketCore::writeData(const char* data, size_t len, | |||
|   _wantRead = false; | ||||
|   _wantWrite = false; | ||||
| 
 | ||||
|   struct addrinfo hints; | ||||
|   struct addrinfo* res; | ||||
|   memset(&hints, 0, sizeof(hints)); | ||||
|   hints.ai_family = _protocolFamily; | ||||
|   hints.ai_socktype = _sockType; | ||||
|   hints.ai_flags = 0; | ||||
|   hints.ai_protocol = 0; | ||||
|   int s; | ||||
|   s = getaddrinfo(host.c_str(), uitos(port).c_str(), &hints, &res); | ||||
|   s = callGetaddrinfo(&res, host.c_str(), uitos(port).c_str(), _protocolFamily, | ||||
| 		      _sockType, 0, 0); | ||||
|   if(s) { | ||||
|     throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND, gai_strerror(s)).str()); | ||||
|   } | ||||
|   auto_delete<struct addrinfo*> resDeleter(res, freeaddrinfo); | ||||
|   struct addrinfo* rp; | ||||
|   ssize_t r = -1; | ||||
|   for(rp = res; rp; rp = rp->ai_next) { | ||||
|  | @ -1083,7 +1069,6 @@ ssize_t SocketCore::writeData(const char* data, size_t len, | |||
|       break; | ||||
|     } | ||||
|   } | ||||
|   freeaddrinfo(res); | ||||
|   if(r == -1) { | ||||
|     throw DL_ABORT_EX(StringFormat(EX_SOCKET_SEND, errorMsg()).str()); | ||||
|   } | ||||
|  | @ -1200,15 +1185,10 @@ void SocketCore::bindAddress(const std::string& interface) | |||
|   } | ||||
| #endif // HAVE_GETIFADDRS
 | ||||
|   if(bindAddrs.empty()) { | ||||
|     struct addrinfo hints; | ||||
|     struct addrinfo* res = 0; | ||||
|     memset(&hints, 0, sizeof(hints)); | ||||
|     hints.ai_family = _protocolFamily; | ||||
|     hints.ai_socktype = SOCK_STREAM; | ||||
|     hints.ai_flags = 0; | ||||
|     hints.ai_protocol = 0; | ||||
|     struct addrinfo* res; | ||||
|     int s; | ||||
|     s = getaddrinfo(interface.c_str(), 0, &hints, &res); | ||||
|     s = callGetaddrinfo(&res, interface.c_str(), 0, _protocolFamily, | ||||
| 			SOCK_STREAM, 0, 0); | ||||
|     if(s) { | ||||
|       throw DL_ABORT_EX | ||||
| 	(StringFormat(MSG_INTERFACE_NOT_FOUND, | ||||
|  | @ -1255,4 +1235,34 @@ void SocketCore::bindAddress(const std::string& interface) | |||
|   } | ||||
| } | ||||
| 
 | ||||
| namespace { | ||||
| 
 | ||||
| int defaultAIFlags = DEFAULT_AI_FLAGS; | ||||
| 
 | ||||
| int getDefaultAIFlags() | ||||
| { | ||||
|   return defaultAIFlags; | ||||
| } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void setDefaultAIFlags(int flags) | ||||
| { | ||||
|   defaultAIFlags = flags; | ||||
| } | ||||
| 
 | ||||
| int callGetaddrinfo | ||||
| (struct addrinfo** resPtr, const char* host, const char* service, int family, | ||||
|  int sockType, int flags, int protocol) | ||||
| { | ||||
|   struct addrinfo hints; | ||||
|   memset(&hints, 0, sizeof(hints)); | ||||
|   hints.ai_family = family; | ||||
|   hints.ai_socktype = sockType; | ||||
|   hints.ai_flags = getDefaultAIFlags(); | ||||
|   hints.ai_flags |= flags; | ||||
|   hints.ai_protocol = protocol; | ||||
|   return getaddrinfo(host, service, &hints, resPtr);   | ||||
| } | ||||
| 
 | ||||
| } // namespace aria2
 | ||||
|  |  | |||
|  | @ -363,6 +363,18 @@ public: | |||
|   static void bindAddress(const std::string& interface); | ||||
| }; | ||||
| 
 | ||||
| // Set default ai_flags. hints.ai_flags is initialized with this
 | ||||
| // value.
 | ||||
| void setDefaultAIFlags(int flags); | ||||
| 
 | ||||
| // Wrapper function for getaddrinfo(). The value
 | ||||
| // flags|DEFAULT_AI_FLAGS is used as ai_flags.  You can override
 | ||||
| // DEFAULT_AI_FLAGS value by calling setDefaultAIFlags() with new
 | ||||
| // flags.
 | ||||
| int callGetaddrinfo | ||||
| (struct addrinfo** resPtr, const char* host, const char* service, int family, | ||||
|  int sockType, int flags, int protocol); | ||||
| 
 | ||||
| } // namespace aria2
 | ||||
| 
 | ||||
| #endif // _D_SOCKET_CORE_H_
 | ||||
|  |  | |||
|  | @ -97,4 +97,10 @@ | |||
| # define sock_t int | ||||
| #endif | ||||
| 
 | ||||
| #ifdef AI_ADDRCONFIG | ||||
| # define DEFAULT_AI_FLAGS AI_ADDRCONFIG | ||||
| #else // !AI_ADDRCONFIG
 | ||||
| # define DEFAULT_AI_FLAGS 0 | ||||
| #endif // !AI_ADDRCONFIG
 | ||||
| 
 | ||||
| #endif // _D_A2NETCOMPAT_H_
 | ||||
|  |  | |||
|  | @ -24,6 +24,9 @@ int main(int argc, char* argv[]) { | |||
|   // and latter cannot connect to former. To avoid this situation, we
 | ||||
|   // limit protocol family to AF_INET for unit tests.
 | ||||
|   aria2::SocketCore::setProtocolFamily(AF_INET); | ||||
|   // If AI_ADDRCONFIG is set, tests fail if IPv4 address is not
 | ||||
|   // configured.
 | ||||
|   aria2::setDefaultAIFlags(0); | ||||
| 
 | ||||
|   CppUnit::Test* suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); | ||||
|   CppUnit::TextUi::TestRunner runner; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Tatsuhiro Tsujikawa
						Tatsuhiro Tsujikawa