From 4b61e7363dbc0e8bf595da06840db4175e3b86c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Mon, 26 Sep 2011 22:44:41 +0200
Subject: Refactoring NetworkEnvironments.


diff --git a/Swiften/FileTransfer/ConnectivityManager.cpp b/Swiften/FileTransfer/ConnectivityManager.cpp
index cfb0729..1002b45 100644
--- a/Swiften/FileTransfer/ConnectivityManager.cpp
+++ b/Swiften/FileTransfer/ConnectivityManager.cpp
@@ -59,8 +59,9 @@ std::vector<HostAddressPort> ConnectivityManager::getHostAddressPorts() const {
 
 	std::vector<HostAddress> addresses;
 
-	foreach (NetworkInterface::ref iface, env.getNetworkInterfaces()) {
-		foreach (HostAddress address, iface->getAddresses()) {
+	std::vector<NetworkInterface> networkInterfaces;
+	foreach (const NetworkInterface& iface, networkInterfaces) {
+		foreach (const HostAddress& address, iface.getAddresses()) {
 			foreach (int port, ports) {
 				results.push_back(HostAddressPort(address, port));
 			}
diff --git a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp b/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp
index a21383c..8ba20a6 100644
--- a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp
+++ b/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.cpp
@@ -67,19 +67,4 @@ void NATPMPNATTraversalRemovePortForwardingRequest::runBlocking() {
 	onResult(result);
 }
 
-HostAddress NATPMPNATTraversalRemovePortForwardingRequest::getLocalClient() {
-	PlatformNetworkEnvironment env;
-
-	foreach (NetworkInterface::ref iface, env.getNetworkInterfaces()) {
-		if (!iface->isLoopback()) {
-			foreach (HostAddress address, iface->getAddresses()) {
-				if (address.getRawAddress().is_v4()) {
-					return address;
-				}
-			}
-		}
-	}
-	return HostAddress();
-}
-
 }
diff --git a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h b/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h
index 3eb2b15..aefbdc0 100644
--- a/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h
+++ b/Swiften/Network/NATPMPNATTraversalRemovePortForwardingRequest.h
@@ -23,9 +23,6 @@ public:
 	}
 
 private:
-	HostAddress getLocalClient();
-
-private:
 	PortMapping mapping;
 };
 
diff --git a/Swiften/Network/NetworkEnvironment.cpp b/Swiften/Network/NetworkEnvironment.cpp
new file mode 100644
index 0000000..52ceb01
--- /dev/null
+++ b/Swiften/Network/NetworkEnvironment.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Network/NetworkEnvironment.h>
+
+#include <Swiften/Network/NetworkInterface.h>
+#include <Swiften/Network/HostAddress.h>
+#include <Swiften/Base/foreach.h>
+
+namespace Swift {
+
+NetworkEnvironment::~NetworkEnvironment() {
+}
+
+HostAddress NetworkEnvironment::getLocalAddress() const {
+	std::vector<NetworkInterface> networkInterfaces = getNetworkInterfaces();
+	foreach (const NetworkInterface& iface, networkInterfaces) {
+		if (!iface.isLoopback()) {
+			foreach (const HostAddress& address, iface.getAddresses()) {
+				if (address.getRawAddress().is_v4()) {
+					return address;
+				}
+			}
+		}
+	}
+	return HostAddress();
+}
+
+}
diff --git a/Swiften/Network/NetworkEnvironment.h b/Swiften/Network/NetworkEnvironment.h
index 348bdb9..fbff0cb 100644
--- a/Swiften/Network/NetworkEnvironment.h
+++ b/Swiften/Network/NetworkEnvironment.h
@@ -12,13 +12,12 @@
 #include <Swiften/Network/NetworkInterface.h>
 
 namespace Swift {
+	class NetworkEnvironment {
+	public:
+		virtual ~NetworkEnvironment();
 
-class NetworkEnvironment {
-public:
-	virtual ~NetworkEnvironment() {};
-	virtual std::vector<NetworkInterface::ref> getNetworkInterfaces() = 0;
-
-	boost::signal <void (NetworkInterface::ref)> onNetworkInterfaceChange;
-};
+		virtual std::vector<NetworkInterface> getNetworkInterfaces() const = 0;
 
+		HostAddress getLocalAddress() const;
+	};
 }
diff --git a/Swiften/Network/NetworkInterface.h b/Swiften/Network/NetworkInterface.h
index 062e1f9..6395758 100644
--- a/Swiften/Network/NetworkInterface.h
+++ b/Swiften/Network/NetworkInterface.h
@@ -7,29 +7,44 @@
 #pragma once
 
 #include <vector>
-#include <boost/shared_ptr.hpp>
 
 #include <Swiften/Network/HostAddress.h>
 
 namespace Swift {
-
-class NetworkInterface {
-public:
-	typedef boost::shared_ptr<NetworkInterface> ref;
-
-public:
-	enum InterfaceType {
-		WLAN,
-		Ethernet,
-		Mobile,
-		VPN,
+	class NetworkInterface {
+		public:
+			enum Type {
+				Unknown,
+				WLAN,
+				Ethernet,
+				Mobile,
+				VPN,
+			};
+
+		public:
+			NetworkInterface(const std::string& name, bool loopback, Type type = Unknown) : name(name), loopback(loopback), type(type) {
+			}
+
+			void addAddress(const HostAddress& address) {
+				addresses.push_back(address);
+			}
+
+			const std::vector<HostAddress>& getAddresses() const {
+				return addresses;
+			}
+
+			const std::string& getName() const {
+				return name;
+			}
+
+			bool isLoopback() const {
+				return loopback;
+			}
+
+		private:
+			std::string name;
+			bool loopback;
+			Type type;
+			std::vector<HostAddress> addresses;
 	};
-
-public:
-	virtual ~NetworkInterface() {};
-	virtual std::vector<HostAddress> getAddresses() = 0;
-	virtual std::string getName() = 0;
-	virtual bool isLoopback() = 0;
-};
-
 }
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index 66dd974..e44f868 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -37,6 +37,7 @@ sourceList = [
 			"HostAddressPort.cpp",
 			"NetworkFactories.cpp",
 			"BoostNetworkFactories.cpp",
+			"NetworkEnvironment.cpp",
 			"Timer.cpp",
 			"BoostTimer.cpp",
 			"ProxyProvider.cpp",
diff --git a/Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp b/Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp
index 065efbc..6fcc01a 100644
--- a/Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp
+++ b/Swiften/Network/UPnPNATTraversalForwardPortRequest.cpp
@@ -35,7 +35,7 @@ void UPnPNATTraversalForwardPortRequest::runBlocking() {
 
 	std::string publicPort = str(boost::format("%d") % mapping.publicPort);
 	std::string localPort = str(boost::format("%d") % mapping.localPort);
-	std::string internalClient = getLocalClient().toString();
+	std::string internalClient = PlatformNetworkEnvironment().getLocalAddress().toString();
 	std::string leaseSeconds = str(boost::format("%d") % mapping.leaseInSeconds);
 	UPNPUrls urls;
 	IGDdatas data;
@@ -68,19 +68,4 @@ void UPnPNATTraversalForwardPortRequest::runBlocking() {
 	onResult(result);
 }
 
-HostAddress UPnPNATTraversalForwardPortRequest::getLocalClient() {
-	PlatformNetworkEnvironment env;
-
-	foreach (NetworkInterface::ref iface, env.getNetworkInterfaces()) {
-		if (!iface->isLoopback()) {
-			foreach (HostAddress address, iface->getAddresses()) {
-				if (address.getRawAddress().is_v4()) {
-					return address;
-				}
-			}
-		}
-	}
-	return HostAddress();
-}
-
 }
diff --git a/Swiften/Network/UPnPNATTraversalForwardPortRequest.h b/Swiften/Network/UPnPNATTraversalForwardPortRequest.h
index ae63a80..777ab26 100644
--- a/Swiften/Network/UPnPNATTraversalForwardPortRequest.h
+++ b/Swiften/Network/UPnPNATTraversalForwardPortRequest.h
@@ -23,9 +23,6 @@ public:
 	}
 
 private:
-	HostAddress getLocalClient();
-
-private:
 	NATTraversalForwardPortRequest::PortMapping mapping;
 };
 
diff --git a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp b/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp
index 6e4d0eb..9b83173 100644
--- a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp
+++ b/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.cpp
@@ -36,7 +36,7 @@ void UPnPNATTraversalRemovePortForwardingRequest::runBlocking() {
 
 	std::string publicPort = str(boost::format("%d") % mapping.publicPort);
 	std::string localPort = str(boost::format("%d") % mapping.localPort);
-	std::string internalClient = getLocalClient().toString();
+	std::string internalClient = PlatformNetworkEnvironment().getLocalAddress().toString();
 	std::string leaseSeconds = str(boost::format("%d") % mapping.leaseInSeconds);
 	UPNPUrls urls;
 	IGDdatas data;
@@ -74,19 +74,4 @@ void UPnPNATTraversalRemovePortForwardingRequest::runBlocking() {
 	onResult(result);
 }
 
-HostAddress UPnPNATTraversalRemovePortForwardingRequest::getLocalClient() {
-	PlatformNetworkEnvironment env;
-
-	foreach (NetworkInterface::ref iface, env.getNetworkInterfaces()) {
-		if (!iface->isLoopback()) {
-			foreach (HostAddress address, iface->getAddresses()) {
-				if (address.getRawAddress().is_v4()) {
-					return address;
-				}
-			}
-		}
-	}
-	return HostAddress();
-}
-
 }
diff --git a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h b/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h
index af6d3b0..644eae7 100644
--- a/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h
+++ b/Swiften/Network/UPnPNATTraversalRemovePortForwardingRequest.h
@@ -23,9 +23,6 @@ public:
 	}
 
 private:
-	HostAddress getLocalClient();
-
-private:
 	NATTraversalRemovePortForwardingRequest::PortMapping mapping;
 };
 
diff --git a/Swiften/Network/UnixNetworkEnvironment.cpp b/Swiften/Network/UnixNetworkEnvironment.cpp
index 649855d..52c5cbe 100644
--- a/Swiften/Network/UnixNetworkEnvironment.cpp
+++ b/Swiften/Network/UnixNetworkEnvironment.cpp
@@ -4,68 +4,54 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
-#include "UnixNetworkEnvironment.h"
+#include <Swiften/Network/UnixNetworkEnvironment.h>
 
 #include <string>
 #include <vector>
 #include <map>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/Network/HostAddress.h>
-#include <Swiften/Network/NetworkInterface.h>
-
+#include <boost/optional.hpp>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <ifaddrs.h>
 
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Network/HostAddress.h>
+#include <Swiften/Network/NetworkInterface.h>
+
 namespace Swift {
 
-std::vector<NetworkInterface::ref> UnixNetworkEnvironment::getNetworkInterfaces() {
-	std::map<std::string, UnixNetworkInterface::ref> interfaces;
-	std::vector<NetworkInterface::ref> result;
+std::vector<NetworkInterface> UnixNetworkEnvironment::getNetworkInterfaces() const {
+	std::map<std::string, NetworkInterface> interfaces;
 
-	ifaddrs *addrs = 0;
+	ifaddrs* addrs = 0;
 	int ret = getifaddrs(&addrs);
 	if (ret != 0) {
-		return result;
+		return std::vector<NetworkInterface>();
 	}
 
-	for (ifaddrs *a = addrs; a != 0; a = a->ifa_next) {
+	for (ifaddrs* a = addrs; a != 0; a = a->ifa_next) {
 		std::string name(a->ifa_name);
-		std::string ip;
+		boost::optional<HostAddress> address;
 		if (a->ifa_addr->sa_family == PF_INET) {
 			sockaddr_in* sa = reinterpret_cast<sockaddr_in*>(a->ifa_addr);
-			char str[INET_ADDRSTRLEN];
-			inet_ntop(AF_INET, &(sa->sin_addr), str, INET_ADDRSTRLEN);
-			ip.assign(str);
+			address = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin_addr)), 4);
 		}
 		else if (a->ifa_addr->sa_family == PF_INET6) {
 			sockaddr_in6* sa = reinterpret_cast<sockaddr_in6*>(a->ifa_addr);
-			char str[INET6_ADDRSTRLEN];
-			/*if (IN6_IS_ADDR_LINKLOCAL(sa)) {
-				continue;
-			}*/
-			inet_ntop(AF_INET6, &(sa->sin6_addr), str, INET6_ADDRSTRLEN);
-			ip.assign(str);
+			address = HostAddress(reinterpret_cast<const unsigned char*>(&(sa->sin6_addr)), 16);
 		}
-		if (!ip.empty()) {
-			if (interfaces.find(name) == interfaces.end()) {
-				interfaces[name] = boost::make_shared<UnixNetworkInterface>(name);
-				if (a->ifa_flags & IFF_LOOPBACK) {
-					interfaces[name]->setLoopback(true);
-				}
-			}
-			interfaces[name]->addHostAddress(HostAddress(ip));
+		if (address) {
+			std::map<std::string, NetworkInterface>::iterator i = interfaces.insert(std::make_pair(name, NetworkInterface(name, a->ifa_flags & IFF_LOOPBACK))).first;
+			i->second.addAddress(*address);
 		}
 	}
 
 	freeifaddrs(addrs);
 
-	for(std::map<std::string, UnixNetworkInterface::ref>::iterator i = interfaces.begin(); i != interfaces.end(); ++i) {
+	std::vector<NetworkInterface> result;
+	for (std::map<std::string,NetworkInterface>::const_iterator i = interfaces.begin(); i != interfaces.end(); ++i) {
 		result.push_back(i->second);
 	}
 	return result;
diff --git a/Swiften/Network/UnixNetworkEnvironment.h b/Swiften/Network/UnixNetworkEnvironment.h
index e4b2f37..8b51cae 100644
--- a/Swiften/Network/UnixNetworkEnvironment.h
+++ b/Swiften/Network/UnixNetworkEnvironment.h
@@ -16,44 +16,8 @@
 namespace Swift {
 
 class UnixNetworkEnvironment : public NetworkEnvironment {
-	class UnixNetworkInterface : public NetworkInterface {
 	public:
-		typedef boost::shared_ptr<UnixNetworkInterface> ref;
-
-	public:
-		UnixNetworkInterface(std::string name) : name(name), loopback(false) { }
-
-		std::vector<HostAddress> getAddresses() {
-			return addresses;
-		}
-
-		std::string getName() {
-			return name;
-		}
-
-		bool isLoopback() {
-			return loopback;
-		}
-
-	private:
-		void addHostAddress(HostAddress address) {
-			addresses.push_back(address);
-		}
-
-		void setLoopback(bool loopback) {
-			this->loopback = loopback;
-		}
-
-	private:
-		friend class UnixNetworkEnvironment;
-		std::vector<HostAddress> addresses;
-		std::string name;
-		InterfaceType type;
-		bool loopback;
-	};
-
-public:
-	std::vector<NetworkInterface::ref> getNetworkInterfaces();
+		std::vector<NetworkInterface> getNetworkInterfaces() const;
 };
 
 }
diff --git a/Swiften/Network/WindowsNetworkEnvironment.cpp b/Swiften/Network/WindowsNetworkEnvironment.cpp
index 5163f43..0eedea0 100644
--- a/Swiften/Network/WindowsNetworkEnvironment.cpp
+++ b/Swiften/Network/WindowsNetworkEnvironment.cpp
@@ -4,7 +4,7 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
-#include "WindowsNetworkEnvironment.h"
+#include <Swiften/Network/WindowsNetworkEnvironment.h>
 
 #include <string>
 #include <vector>
@@ -33,9 +33,9 @@ std::string winSocketAddressToStdString(const SOCKET_ADDRESS& socketAddress) {
 	return result;
 }
 
-std::vector<NetworkInterface::ref> WindowsNetworkEnvironment::getNetworkInterfaces() {
-	std::map<std::string, WindowsNetworkInterface::ref> interfaces;
-	std::vector<NetworkInterface::ref> result;
+std::vector<NetworkInterface> WindowsNetworkEnvironment::getNetworkInterfaces() {
+	std::vector<NetworkInterface> result;
+	std::map<std::string, WindowsNetworkInterface> interfaces;
 
 	IP_ADAPTER_ADDRESSES preBuffer[5];
 	PIP_ADAPTER_ADDRESSES adapterStart = preBuffer;
@@ -78,7 +78,7 @@ std::vector<NetworkInterface::ref> WindowsNetworkEnvironment::getNetworkInterfac
 						interfaces[name] = boost::make_shared<WindowsNetworkInterface>();
 						interfaces[name]->setName(name);
 					}
-					interfaces[name]->addHostAddress(HostAddress(ip));
+					interfaces[name]->addAddress(HostAddress(ip));
 				}
 			}
 		}
@@ -88,7 +88,7 @@ std::vector<NetworkInterface::ref> WindowsNetworkEnvironment::getNetworkInterfac
 		//delete adapterStart;
 	}
 
-	for(std::map<std::string, WindowsNetworkInterface::ref>::iterator i = interfaces.begin(); i != interfaces.end(); ++i) {
+	for (std::map<std::string, WindowsNetworkInterface>::const_iterator i = interfaces.begin(); i != interfaces.end(); ++i) {
 		result.push_back(i->second);
 	}
 	return result;
diff --git a/Swiften/Network/WindowsNetworkEnvironment.h b/Swiften/Network/WindowsNetworkEnvironment.h
index 2b79504..f43b951 100644
--- a/Swiften/Network/WindowsNetworkEnvironment.h
+++ b/Swiften/Network/WindowsNetworkEnvironment.h
@@ -7,50 +7,13 @@
 #pragma once
 
 #include <vector>
-
 #include <Swiften/Base/boost_bsignals.h>
 
 #include <Swiften/Network/NetworkEnvironment.h>
-#include <Swiften/Network/NetworkInterface.h>
 
 namespace Swift {
-
-class WindowsNetworkEnvironment : public NetworkEnvironment {
-	class WindowsNetworkInterface : public NetworkInterface {
-	public:
-		typedef boost::shared_ptr<WindowsNetworkInterface> ref;
-
-	public:
-		virtual ~WindowsNetworkInterface() { }
-		virtual std::vector<HostAddress> getAddresses() {
-			return addresses;
-		}
-
-		virtual std::string getName() {
-			return name;
-		}
-
-		virtual bool isLoopback() {
-			return false;
-		}
-
-	public:
-		void addHostAddress(HostAddress address) {
-			addresses.push_back(address);
-		}
-
-		void setName(const std::string& name) {
-			this->name = name;
-		}
-
-	private:
-		std::vector<HostAddress> addresses;
-		InterfaceType type;
-		std::string name;
+	class WindowsNetworkEnvironment : public NetworkEnvironment {
+		public:
+			std::vector<NetworkInterface> getNetworkInterfaces() const;
 	};
-
-public:
-	std::vector<NetworkInterface::ref> getNetworkInterfaces();
-};
-
 }
-- 
cgit v0.10.2-6-g49f6