← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2785: add a tool to test port mappings (build with scons utils=1)

 

------------------------------------------------------------
revno: 2785
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2012-01-01 21:42:31 +0100
message:
  add a tool to test port mappings (build with scons utils=1)
added:
  utils/portmap.cpp
modified:
  test/SConscript
  utils/SConscript
  win32/Mapper_MiniUPnPc.cpp
  win32/Mapper_WinUPnP.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 'test/SConscript'
--- test/SConscript	2011-12-31 11:50:24 +0000
+++ test/SConscript	2012-01-01 20:42:31 +0000
@@ -27,13 +27,15 @@
 
 if '-mwindows' in env['CCFLAGS']:
 	env['CCFLAGS'].remove('-mwindows')
+	env.Append(CCFLAGS = ['-mconsole'])
 
 if '-mwindows' in env['LINKFLAGS']:
 	env['LINKFLAGS'].remove('-mwindows')
-
-env.Append(CCFLAGS = ['-mconsole'])	
-env.Append(LINKFLAGS = ['-mconsole'])	
-	
+	env.Append(LINKFLAGS = ['-mconsole'])
+
+if '/SUBSYSTEM:WINDOWS' in env['LINKFLAGS']:
+	env['LINKFLAGS'].remove('/SUBSYSTEM:WINDOWS')
+
 openssl_lib = '#/openssl/lib/'
 if env['arch'] != 'x86':
 	openssl_lib += env['arch'] + '/'

=== modified file 'utils/SConscript'
--- utils/SConscript	2011-12-31 11:50:24 +0000
+++ utils/SConscript	2012-01-01 20:42:31 +0000
@@ -2,7 +2,7 @@
  
 Import('dev source_path')
 
-env, target, sources = dev.prepare_build(source_path, 'xsum', source_glob="xsum.cpp", in_bin=False)
+env = dev.env.Clone()
 
 if 'msvc' in env['TOOLS']:
 	if env['mode'] == 'debug':
@@ -21,18 +21,26 @@
 
 if '-mwindows' in env['CCFLAGS']:
 	env['CCFLAGS'].remove('-mwindows')
+	env.Append(CCFLAGS = ['-mconsole'])
 
 if '-mwindows' in env['LINKFLAGS']:
 	env['LINKFLAGS'].remove('-mwindows')
-
-env.Append(CCFLAGS = ['-mconsole'])	
-env.Append(LINKFLAGS = ['-mconsole'])	
-	
+	env.Append(LINKFLAGS = ['-mconsole'])
+
+if '/SUBSYSTEM:WINDOWS' in env['LINKFLAGS']:
+	env['LINKFLAGS'].remove('/SUBSYSTEM:WINDOWS')
+
 openssl_lib = '#/openssl/lib/'
 if env['arch'] != 'x86':
 	openssl_lib += env['arch'] + '/'
 env.Append(LIBPATH = [openssl_lib])
 
-ret = env.Program(target, [sources, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.intl])
+# imitate build_util's prepare_build
+env.VariantDir(dev.get_build_path(source_path), '.', duplicate = 0)
+import os
+ret = []
+for f in Glob('*.cpp'):
+	sources = dev.get_sources(source_path, str(f))
+	ret.append(env.Program(dev.get_target(source_path, os.path.basename(str(f)).replace('.cpp', ''), in_bin = False), [sources, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.intl]))
 
 Return('ret')

=== added file 'utils/portmap.cpp'
--- utils/portmap.cpp	1970-01-01 00:00:00 +0000
+++ utils/portmap.cpp	2012-01-01 20:42:31 +0000
@@ -0,0 +1,109 @@
+// Tool to add or remove port mapping rules using the interfaces provided by DC++.
+
+#include <dcpp/stdinc.h>
+
+#include <iostream>
+
+#include <dcpp/Mapper.h>
+#include <dcpp/ScopedFunctor.h>
+#include <dcpp/Util.h>
+
+using namespace std;
+using namespace dcpp;
+
+#define PORTMAPTOOL
+string getLocalIp() {
+	// imitate Util::getLocalIp
+	string tmp;
+
+	char buf[256];
+	gethostname(buf, 255);
+	hostent* he = gethostbyname(buf);
+	if(he == NULL || he->h_addr_list[0] == 0)
+		return string();
+	sockaddr_in dest;
+	int i = 0;
+
+	// We take the first ip as default, but if we can find a better one, use it instead...
+	memcpy(&(dest.sin_addr), he->h_addr_list[i++], he->h_length);
+	tmp = inet_ntoa(dest.sin_addr);
+	if(Util::isPrivateIp(tmp) || strncmp(tmp.c_str(), "169", 3) == 0) {
+		while(he->h_addr_list[i]) {
+			memcpy(&(dest.sin_addr), he->h_addr_list[i], he->h_length);
+			string tmp2 = inet_ntoa(dest.sin_addr);
+			if(!Util::isPrivateIp(tmp2) && strncmp(tmp2.c_str(), "169", 3) != 0) {
+				tmp = tmp2;
+			}
+			i++;
+		}
+	}
+	return tmp;
+}
+
+#include <win32/Mapper_MiniUPnPc.cpp>
+#include <win32/Mapper_NATPMP.cpp>
+#include <win32/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;
+	WSAStartup(MAKEWORD(2, 2), &wsaData);
+	ScopedFunctor([] { WSACleanup(); });
+#endif
+
+	if(argc <= LastCompulsory) {
+		help();
+		return 1;
+	}
+
+	auto type = argv[Type][0];
+	if(type != '0' && type != '1') {
+		cout << "Error: invalid type." << endl;
+		help();
+		return 1;
+	}
+	auto tcp = type == '0';
+
+	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;
+	default: cout << "Error: invalid method." << endl; help(); return 1;
+	}
+	auto& mapper = *pMapper;
+
+	ScopedFunctor([&mapper] { mapper.uninit(); });
+	if(!mapper.init()) {
+		cout << "Failed to initalize the " << mapper.getName() << " interface." << endl;
+		return 2;
+	}
+	cout << "Successfully initalized the " << mapper.getName() << " interface." << endl;
+
+	if(!mapper.open(argv[Port], tcp ? Mapper::PROTOCOL_TCP : Mapper::PROTOCOL_UDP, argv[Description])) {
+		cout << "Failed to map the " << argv[Port] << " " << (tcp ? "TCP" : "UDP") << " port with the " << mapper.getName() << " interface." << endl;
+		return 3;
+	}
+	cout << "Successfully mapped the " << argv[Port] << " " << (tcp ? "TCP" : "UDP") << " port with the " << mapper.getName() << " interface." << endl;
+
+	if(argc > Remove && argv[Remove][0] == '1') {
+		if(mapper.close()) {
+			cout << "Successfully removed the rule." << endl;
+		} else {
+			cout << "Failed to remove the rule." << endl;
+		}
+	}
+
+	return 0;
+}

=== modified file 'win32/Mapper_MiniUPnPc.cpp'
--- win32/Mapper_MiniUPnPc.cpp	2011-12-04 22:17:45 +0000
+++ win32/Mapper_MiniUPnPc.cpp	2012-01-01 20:42:31 +0000
@@ -38,10 +38,14 @@
 	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
 	if(!devices)
 		return false;
 
@@ -68,9 +72,13 @@
 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(),
-		Util::getLocalIp().c_str(), description.c_str(), protocols[protocol], 0, 0) == UPNPCOMMAND_SUCCESS;
+		getLocalIp().c_str(), description.c_str(), protocols[protocol], 0, 0) == UPNPCOMMAND_SUCCESS;
 }
 
 bool Mapper_MiniUPnPc::remove(const string& port, const Protocol protocol) {

=== modified file 'win32/Mapper_WinUPnP.cpp'
--- win32/Mapper_WinUPnP.cpp	2011-10-25 06:12:55 +0000
+++ win32/Mapper_WinUPnP.cpp	2012-01-01 20:42:31 +0000
@@ -56,6 +56,10 @@
 	::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)
@@ -64,7 +68,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(Util::getLocalIp()).c_str());
+	BSTR localIP = SysAllocString(Text::toT(getLocalIp()).c_str());
 	auto port_ = Util::toInt(port);
 
 	IStaticPortMapping* pSPM = 0;