← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2813: port mappers: cache the local IP

 

------------------------------------------------------------
revno: 2813
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2012-01-12 18:03:28 +0100
message:
  port mappers: cache the local IP
modified:
  dcpp/Mapper.cpp
  dcpp/Mapper.h
  dcpp/Mapper_MiniUPnPc.cpp
  dcpp/Mapper_MiniUPnPc.h
  dcpp/Mapper_NATPMP.cpp
  dcpp/Mapper_NATPMP.h
  dcpp/Mapper_WinUPnP.cpp
  dcpp/Mapper_WinUPnP.h
  dcpp/MappingManager.cpp
  dcpp/MappingManager.h
  utils/portmap.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/Mapper.cpp'
--- dcpp/Mapper.cpp	2012-01-11 21:42:27 +0000
+++ dcpp/Mapper.cpp	2012-01-12 17:03:28 +0000
@@ -28,6 +28,11 @@
 	"UDP"
 };
 
+Mapper::Mapper(string&& localIp) :
+localIp(std::forward<string>(localIp))
+{
+}
+
 bool Mapper::open(const string& port, const Protocol protocol, const string& description) {
 	if(!add(port, protocol, description))
 		return false;

=== modified file 'dcpp/Mapper.h'
--- dcpp/Mapper.h	2011-10-22 16:41:13 +0000
+++ dcpp/Mapper.h	2012-01-12 17:03:28 +0000
@@ -31,7 +31,7 @@
 class Mapper : boost::noncopyable
 {
 public:
-	Mapper() { }
+	Mapper(string&& localIp);
 	virtual ~Mapper() { }
 
 	enum Protocol {
@@ -63,6 +63,9 @@
 	/** user-friendly name for this implementation. */
 	virtual const string& getName() const = 0;
 
+protected:
+	const string localIp;
+
 private:
 	/** add a port mapping rule. */
 	virtual bool add(const string& port, const Protocol protocol, const string& description) = 0;

=== modified file 'dcpp/Mapper_MiniUPnPc.cpp'
--- dcpp/Mapper_MiniUPnPc.cpp	2012-01-11 21:42:27 +0000
+++ dcpp/Mapper_MiniUPnPc.cpp	2012-01-12 17:03:28 +0000
@@ -19,8 +19,6 @@
 #include "stdinc.h"
 #include "Mapper_MiniUPnPc.h"
 
-#include "ConnectivityManager.h"
-#include "SettingsManager.h"
 #include "Util.h"
 
 extern "C" {
@@ -35,18 +33,16 @@
 
 const string Mapper_MiniUPnPc::name = "MiniUPnP";
 
+Mapper_MiniUPnPc::Mapper_MiniUPnPc(string&& localIp) :
+Mapper(std::forward<string>(localIp))
+{
+}
+
 bool Mapper_MiniUPnPc::init() {
 	if(!url.empty())
 		return true;
 
-#ifndef PORTMAPTOOL
-	const auto& bindAddr = CONNSETTING(BIND_ADDRESS);
-	UPNPDev* devices = upnpDiscover(2000,
-		(bindAddr.empty() || bindAddr == SettingsManager::getInstance()->getDefault(SettingsManager::BIND_ADDRESS)) ? nullptr : bindAddr.c_str(),
-		0, 0, 0, 0);
-#else
-	UPNPDev* devices = upnpDiscover(2000, nullptr, 0, 0, 0, 0);
-#endif
+	UPNPDev* devices = upnpDiscover(2000, localIp.empty() ? nullptr : localIp.c_str(), 0, 0, 0, 0);
 	if(!devices)
 		return false;
 
@@ -73,13 +69,9 @@
 void Mapper_MiniUPnPc::uninit() {
 }
 
-#ifndef PORTMAPTOOL
-namespace { string getLocalIp() { return Util::getLocalIp(); } }
-#endif
-
 bool Mapper_MiniUPnPc::add(const string& port, const Protocol protocol, const string& description) {
 	return UPNP_AddPortMapping(url.c_str(), service.c_str(), port.c_str(), port.c_str(),
-		getLocalIp().c_str(), description.c_str(), protocols[protocol], 0, 0) == UPNPCOMMAND_SUCCESS;
+		localIp.c_str(), description.c_str(), protocols[protocol], 0, 0) == UPNPCOMMAND_SUCCESS;
 }
 
 bool Mapper_MiniUPnPc::remove(const string& port, const Protocol protocol) {

=== modified file 'dcpp/Mapper_MiniUPnPc.h'
--- dcpp/Mapper_MiniUPnPc.h	2012-01-11 21:42:27 +0000
+++ dcpp/Mapper_MiniUPnPc.h	2012-01-12 17:03:28 +0000
@@ -26,7 +26,7 @@
 class Mapper_MiniUPnPc : public Mapper
 {
 public:
-	Mapper_MiniUPnPc() : Mapper() { }
+	Mapper_MiniUPnPc(string&& localIp);
 
 	static const string name;
 

=== modified file 'dcpp/Mapper_NATPMP.cpp'
--- dcpp/Mapper_NATPMP.cpp	2012-01-11 21:42:27 +0000
+++ dcpp/Mapper_NATPMP.cpp	2012-01-12 17:03:28 +0000
@@ -29,12 +29,20 @@
 #include <natpmp/natpmp.h>
 }
 
+///@todo should bind to the local IP
+
 namespace dcpp {
 
 const string Mapper_NATPMP::name = "NAT-PMP";
 
 static natpmp_t nat;
 
+Mapper_NATPMP::Mapper_NATPMP(string&& localIp) :
+Mapper(std::forward<string>(localIp)),
+lifetime(0)
+{
+}
+
 bool Mapper_NATPMP::init() {
 	// the lib normally handles this but we call it manually to store the result (IP of the router).
 	in_addr addr;

=== modified file 'dcpp/Mapper_NATPMP.h'
--- dcpp/Mapper_NATPMP.h	2012-01-11 21:42:27 +0000
+++ dcpp/Mapper_NATPMP.h	2012-01-12 17:03:28 +0000
@@ -26,7 +26,7 @@
 class Mapper_NATPMP : public Mapper
 {
 public:
-	Mapper_NATPMP() : Mapper(), lifetime(0) { }
+	Mapper_NATPMP(string&& localIp);
 
 	static const string name;
 

=== modified file 'dcpp/Mapper_WinUPnP.cpp'
--- dcpp/Mapper_WinUPnP.cpp	2012-01-11 21:42:27 +0000
+++ dcpp/Mapper_WinUPnP.cpp	2012-01-12 17:03:28 +0000
@@ -26,12 +26,22 @@
 #ifdef HAVE_NATUPNP_H
 #include <ole2.h>
 #include <natupnp.h>
+#else // HAVE_NATUPNP_H
+struct IUPnPNAT { };
+struct IStaticPortMappingCollection { };
 #endif // HAVE_NATUPNP_H
 
 namespace dcpp {
 
 const string Mapper_WinUPnP::name = "Windows UPnP";
 
+Mapper_WinUPnP::Mapper_WinUPnP(string&& localIp) :
+Mapper(std::forward<string>(localIp)),
+pUN(0),
+lastPort(0)
+{
+}
+
 #ifdef HAVE_NATUPNP_H
 
 bool Mapper_WinUPnP::init() {
@@ -60,10 +70,6 @@
 	::CoUninitialize();
 }
 
-#ifndef PORTMAPTOOL
-namespace { string getLocalIp() { return Util::getLocalIp(); } }
-#endif
-
 bool Mapper_WinUPnP::add(const string& port, const Protocol protocol, const string& description) {
 	IStaticPortMappingCollection* pSPMC = getStaticPortMappingCollection();
 	if(!pSPMC)
@@ -72,7 +78,7 @@
 	/// @todo use a BSTR wrapper
 	BSTR protocol_ = SysAllocString(Text::toT(protocols[protocol]).c_str());
 	BSTR description_ = SysAllocString(Text::toT(description).c_str());
-	BSTR localIP = SysAllocString(Text::toT(getLocalIp()).c_str());
+	BSTR localIP = SysAllocString(Text::toT(localIp).c_str());
 	auto port_ = Util::toInt(port);
 
 	IStaticPortMapping* pSPM = 0;
@@ -176,9 +182,6 @@
 
 #else // HAVE_NATUPNP_H
 
-struct IUPnPNAT { };
-struct IStaticPortMappingCollection { };
-
 bool Mapper_WinUPnP::init() {
 	return false;
 }

=== modified file 'dcpp/Mapper_WinUPnP.h'
--- dcpp/Mapper_WinUPnP.h	2012-01-11 21:42:27 +0000
+++ dcpp/Mapper_WinUPnP.h	2012-01-12 17:03:28 +0000
@@ -30,7 +30,7 @@
 class Mapper_WinUPnP : public Mapper
 {
 public:
-	Mapper_WinUPnP() : Mapper(), pUN(0), lastPort(0) { }
+	Mapper_WinUPnP(string&& localIp);
 
 	static const string name;
 

=== modified file 'dcpp/MappingManager.cpp'
--- dcpp/MappingManager.cpp	2012-01-11 21:42:27 +0000
+++ dcpp/MappingManager.cpp	2012-01-12 17:03:28 +0000
@@ -35,9 +35,7 @@
 MappingManager::MappingManager() : busy(false), renewal(0) {
 	addMapper<Mapper_NATPMP>();
 	addMapper<Mapper_MiniUPnPc>();
-#ifdef HAVE_NATUPNP_H
 	addMapper<Mapper_WinUPnP>();
-#endif
 }
 
 StringList MappingManager::getMappers() const {
@@ -133,7 +131,7 @@
 	}
 
 	for(auto i = mappers.begin(); i != mappers.end(); ++i) {
-		unique_ptr<Mapper> pMapper(i->second());
+		unique_ptr<Mapper> pMapper(i->second(Util::getLocalIp()));
 		Mapper& mapper = *pMapper;
 
 		ScopedFunctor([&mapper] { mapper.uninit(); });

=== modified file 'dcpp/MappingManager.h'
--- dcpp/MappingManager.h	2012-01-11 21:42:27 +0000
+++ dcpp/MappingManager.h	2012-01-12 17:03:28 +0000
@@ -44,7 +44,18 @@
 public:
 	/** add an implementation derived from the base Mapper class, passed as template parameter.
 	the first added mapper will be tried first, unless the "MAPPER" setting is not empty. */
-	template<typename T> void addMapper() { mappers.push_back(make_pair(T::name, [] { return new T(); })); }
+	template<typename T> void addMapper() {
+#ifndef _MSC_VER
+		mappers.push_back(make_pair(T::name, [](string&& localIp) {
+			return new T(std::forward<string>(localIp));
+		}));
+#else
+		// the rvalue ref deal is too smart for MSVC; resort to a string copy...
+		mappers.push_back(make_pair(T::name, [](string localIp) {
+			return new T(std::move(localIp));
+		}));
+#endif
+	}
 	StringList getMappers() const;
 
 	bool open();
@@ -54,7 +65,11 @@
 private:
 	friend class Singleton<MappingManager>;
 
-	vector<pair<string, function<Mapper* ()>>> mappers;
+#ifndef _MSC_VER
+	vector<pair<string, function<Mapper* (string&&)>>> mappers;
+#else
+	vector<pair<string, function<Mapper* (const string&)>>> mappers;
+#endif
 
 	atomic_flag busy;
 	unique_ptr<Mapper> working; /// currently working implementation.

=== modified file 'utils/portmap.cpp'
--- utils/portmap.cpp	2012-01-11 21:42:27 +0000
+++ utils/portmap.cpp	2012-01-12 17:03:28 +0000
@@ -4,23 +4,36 @@
 
 #include <iostream>
 
-#include <dcpp/Mapper.h>
+#include <dcpp/Mapper_MiniUPnPc.h>
+#include <dcpp/Mapper_NATPMP.h>
+#include <dcpp/Mapper_WinUPnP.h>
 #include <dcpp/ScopedFunctor.h>
 #include <dcpp/Util.h>
 
 using namespace std;
 using namespace dcpp;
 
-#define PORTMAPTOOL
+void help() {
+	cout << "Arguments to run portmap with:" << endl << "\t portmap <port> <type> <description> <method> [remove]" << endl
+		<< "<port> is a port number to forward." << endl
+		<< "<type> must be either 0 (for TCP) or 1 (for UDP)." << endl
+		<< "<description> is the description of the port forwarding rule." << endl
+		<< "<method> must be either 0, 1, 2 (for NAT-PMP, MiniUPnP, Win UPnP)." << endl
+		<< "[remove] (optional) may be set to 1 to remove the rule." << endl;
+}
+
+enum { Port = 1, Type, Description, Method, LastCompulsory = Method, Remove };
+
 string getLocalIp() {
-	// imitate Util::getLocalIp
+	// imitate Util::getLocalIp but avoid calls to managers that haven't been initialized.
+
 	string tmp;
 
 	char buf[256];
 	gethostname(buf, 255);
 	hostent* he = gethostbyname(buf);
 	if(he == NULL || he->h_addr_list[0] == 0)
-		return string();
+		return Util::emptyString;
 	sockaddr_in dest;
 	int i = 0;
 
@@ -40,21 +53,6 @@
 	return tmp;
 }
 
-#include <dcpp/Mapper_MiniUPnPc.cpp>
-#include <dcpp/Mapper_NATPMP.cpp>
-#include <dcpp/Mapper_WinUPnP.cpp>
-
-void help() {
-	cout << "Arguments to run portmap with:" << endl << "\t portmap <port> <type> <description> <method> [remove]" << endl
-		<< "<port> is a port number to forward." << endl
-		<< "<type> must be either 0 (for TCP) or 1 (for UDP)." << endl
-		<< "<description> is the description of the port forwarding rule." << endl
-		<< "<method> must be either 0, 1, 2 (for NAT-PMP, MiniUPnP, Win UPnP)." << endl
-		<< "[remove] (optional) may be set to 1 to remove the rule." << endl;
-}
-
-enum { Port = 1, Type, Description, Method, LastCompulsory = Method, Remove };
-
 int main(int argc, char* argv[]) {
 #ifdef _WIN32
 	WSADATA wsaData;
@@ -77,9 +75,9 @@
 
 	unique_ptr<Mapper> pMapper;
 	switch(argv[Method][0]) {
-	case '0': pMapper.reset(new Mapper_NATPMP()); break;
-	case '1': pMapper.reset(new Mapper_MiniUPnPc()); break;
-	case '2': pMapper.reset(new Mapper_WinUPnP()); break;
+	case '0': pMapper.reset(new Mapper_NATPMP(getLocalIp())); break;
+	case '1': pMapper.reset(new Mapper_MiniUPnPc(getLocalIp())); break;
+	case '2': pMapper.reset(new Mapper_WinUPnP(getLocalIp())); break;
 	default: cout << "Error: invalid method." << endl; help(); return 1;
 	}
 	auto& mapper = *pMapper;