← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2701: error handling of listening socket initialization

 

------------------------------------------------------------
revno: 2701
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Tue 2011-12-06 19:31:57 +0100
message:
  error handling of listening socket initialization
modified:
  dcpp/Socket.cpp


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/Socket.cpp'
--- dcpp/Socket.cpp	2011-12-04 22:17:45 +0000
+++ dcpp/Socket.cpp	2011-12-06 18:31:57 +0000
@@ -273,48 +273,57 @@
 string Socket::listen(const string& port) {
 	disconnect();
 
-	uint16_t ret = 0;
-
 	// For server sockets we create both ipv4 and ipv6 if possible
 	// We use the same port for both sockets to deal with the fact that
 	// there's no way in ADC to have different ports for v4 and v6 TCP sockets
 
+	uint16_t ret = 0;
+	string error;
+
 	if(!v4only) {
 		auto ai = resolveAddr(localIp6, port, AF_INET6, AI_PASSIVE | AI_ADDRCONFIG);
 		for(auto a = ai.get(); a && !sock6.valid(); a = a->ai_next) {
+			try {
+				create(*a);
+				if(ret != 0) {
+					((sockaddr_in6*)a->ai_addr)->sin6_port = ret;
+				}
+
+				check([&] { return ::bind(sock6, a->ai_addr, a->ai_addrlen); });
+				check([&] { return ::getsockname(sock6, a->ai_addr, (socklen_t*)&a->ai_addrlen); });
+				ret = ((sockaddr_in6*)a->ai_addr)->sin6_port;
+
+				if(type == TYPE_TCP) {
+					check([&] { return ::listen(sock6, 20); });
+				}
+			} catch(const SocketException& e) {
+				error = e.getError();
+			}
+		}
+	}
+
+	auto ai = resolveAddr(localIp4, port, AF_INET, AI_PASSIVE | AI_ADDRCONFIG);
+	for(auto a = ai.get(); a && !sock4.valid(); a = a->ai_next) {
+		try {
 			create(*a);
 			if(ret != 0) {
-				((sockaddr_in6*)a->ai_addr)->sin6_port = ret;
+				((sockaddr_in*)a->ai_addr)->sin_port = ret;
 			}
 
-			check([&] { return ::bind(sock6, a->ai_addr, a->ai_addrlen); });
-			check([&] { return ::getsockname(sock6, a->ai_addr, (socklen_t*)&a->ai_addrlen); });
-			ret = ((sockaddr_in6*)a->ai_addr)->sin6_port;
+			check([&] { return ::bind(sock4, a->ai_addr, a->ai_addrlen); });
+			check([&] { return ::getsockname(sock4, a->ai_addr, (socklen_t*)&a->ai_addrlen); });
+			ret = ((sockaddr_in*)a->ai_addr)->sin_port;
 
 			if(type == TYPE_TCP) {
-				check([&] { return ::listen(sock6, 20); });
+				check([&] { return ::listen(sock4, 20); });
 			}
-		}
-	}
-
-	auto ai = resolveAddr(localIp4, port, AF_INET, AI_PASSIVE | AI_ADDRCONFIG);
-	for(auto a = ai.get(); a && !sock4.valid(); a = a->ai_next) {
-		create(*a);
-		if(ret != 0) {
-			((sockaddr_in*)a->ai_addr)->sin_port = ret;
-		}
-
-		check([&] { return ::bind(sock4, a->ai_addr, a->ai_addrlen); });
-		check([&] { return ::getsockname(sock4, a->ai_addr, (socklen_t*)&a->ai_addrlen); });
-		ret = ((sockaddr_in*)a->ai_addr)->sin_port;
-
-		if(type == TYPE_TCP) {
-			check([&] { return ::listen(sock4, 20); });
+		} catch(const SocketException& e) {
+			error = e.getError();
 		}
 	}
 
 	if(ret == 0) {
-		throw SocketException(_("Could not open port for listening"));
+		throw SocketException(error.empty() ? _("Could not open port for listening") : error);
 	}
 	return Util::toString(ntohs(ret));
 }