← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2613: Switch to binary GeoIP databases and add IPv6 support

 

------------------------------------------------------------
revno: 2613
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2011-09-23 13:47:15 +0200
message:
  Switch to binary GeoIP databases and add IPv6 support
added:
  dcpp/GeoIP.cpp
  dcpp/GeoIP.h
modified:
  SConstruct
  changelog.txt
  dcpp/OnlineUser.h
  dcpp/SConscript
  dcpp/User.cpp
  dcpp/Util.cpp
  dcpp/Util.h
  help/links.html
  help/settings_appearance.html
  help/window_main.html
  installer/DCPlusPlus.nsi
  win32/MainWindow.cpp
  win32/MainWindow.h
  win32/SConscript
  win32/SearchFrame.cpp
  win32/TransferView.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 'SConstruct'
--- SConstruct	2011-07-20 09:51:18 +0000
+++ SConstruct	2011-09-23 11:47:15 +0000
@@ -251,6 +251,7 @@
 dev.dwarf = dev.build('dwarf/')
 dev.zlib = dev.build('zlib/')
 dev.bzip2 = dev.build('bzip2/')
+dev.geoip = dev.build('geoip/')
 dev.intl = dev.build('intl/')
 dev.miniupnpc = dev.build('miniupnpc/')
 dev.natpmp = dev.build('natpmp/')

=== modified file 'changelog.txt'
--- changelog.txt	2011-08-22 18:49:16 +0000
+++ changelog.txt	2011-09-23 11:47:15 +0000
@@ -43,6 +43,7 @@
 * COM initialization fix for the Windows UPnP mapper (thanks bigmuscle)
 * Show country codes next to country names (poy)
 * [L#425667] More accurate indexing time left calculation (poy)
+* Switch to binary GeoIP databases and add IPv6 support (poy)
 
 -- 0.782 2011-03-05 --
 * Prevent a remote crash triggered via malformed user commands (poy)

=== added file 'dcpp/GeoIP.cpp'
--- dcpp/GeoIP.cpp	1970-01-01 00:00:00 +0000
+++ dcpp/GeoIP.cpp	2011-09-23 11:47:15 +0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2001-2011 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdinc.h"
+#include "GeoIP.h"
+
+#include "File.h"
+#include "format.h"
+#include "Util.h"
+
+#include <zlib.h>
+
+namespace dcpp {
+
+GeoIP::GeoIP() : geo(0) {
+}
+
+GeoIP::~GeoIP() {
+	GeoIP_delete(geo);
+}
+
+void GeoIP::init(const string& path) {
+	if(File::getSize(path) <= 0) {
+		if(File::getSize(path + ".gz") <= 0) {
+			return;
+		}
+
+		// decompress the file.
+		try {
+			auto gz = gzopen((path + ".gz").c_str(), "rb");
+			if(!gz) {
+				return;
+			}
+			File dat(path, File::WRITE, File::CREATE);
+
+			const size_t BUF_SIZE = 64 * 1024;
+			ByteVector buf(BUF_SIZE);
+
+			while(true) {
+				auto read = gzread(gz, &buf[0], BUF_SIZE);
+				if(read >= 0) {
+					dat.write(&buf[0], read);
+				}
+				if(read < BUF_SIZE) {
+					break;
+				}
+			}
+
+			gzclose(gz);
+		} catch(const Exception&) {
+			return;
+		}
+	}
+
+	geo = GeoIP_open(path.c_str(), GEOIP_STANDARD);
+	if(geo) {
+		GeoIP_set_charset(geo, GEOIP_CHARSET_UTF8);
+	}
+}
+
+string GeoIP::getCountry(const string& ip) const {
+	if(geo) {
+
+		auto id = (v6() ? GeoIP_id_by_addr_v6 : GeoIP_id_by_addr)(geo, ip.c_str());
+		if(id > 0) {
+
+			auto code = GeoIP_code_by_id(id);
+			auto name = GeoIP_country_name_by_id(geo, id);
+
+			if(code && name)
+				return str(F_("%1% - %2%") % code % name);
+
+			if(code && !name)
+				return code;
+
+			if(name && !code)
+				return name;
+		}
+	}
+
+	return Util::emptyString;
+}
+
+bool GeoIP::v6() const {
+	return geo->databaseType == GEOIP_COUNTRY_EDITION_V6 || geo->databaseType == GEOIP_LARGE_COUNTRY_EDITION_V6;
+}
+
+} // namespace dcpp

=== added file 'dcpp/GeoIP.h'
--- dcpp/GeoIP.h	1970-01-01 00:00:00 +0000
+++ dcpp/GeoIP.h	2011-09-23 11:47:15 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2001-2011 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DCPLUSPLUS_DCPP_GEOIP_H
+#define DCPLUSPLUS_DCPP_GEOIP_H
+
+#include <GeoIP.h>
+
+namespace dcpp {
+
+using std::string;
+
+class GeoIP {
+public:
+	GeoIP();
+	~GeoIP();
+
+	void init(const string& path);
+	string getCountry(const string& ip) const;
+
+private:
+	bool v6() const;
+
+	::GeoIP* geo;
+};
+
+} // namespace dcpp
+
+#endif // !defined(DCPLUSPLUS_DCPP_GEOIP_H)

=== modified file 'dcpp/OnlineUser.h'
--- dcpp/OnlineUser.h	2011-08-22 20:33:02 +0000
+++ dcpp/OnlineUser.h	2011-09-23 11:47:15 +0000
@@ -81,7 +81,7 @@
 	string getTag() const;
 	string getApplication() const;
 	string getConnection() const;
-	const string& getCountry() const;
+	string getCountry() const;
 	bool supports(const string& name) const;
 	bool isHub() const { return isClientType(CT_HUB) || isSet("HU"); }
 	bool isOp() const { return isClientType(CT_OP) || isClientType(CT_SU) || isClientType(CT_OWNER) || isSet("OP"); }

=== modified file 'dcpp/SConscript'
--- dcpp/SConscript	2010-06-21 15:21:26 +0000
+++ dcpp/SConscript	2011-09-23 11:47:15 +0000
@@ -28,7 +28,7 @@
 
 env, target, sources = dev.prepare_build(source_path, 'dcpp', in_bin = False, precompiled_header = 'stdinc')
 
-env.Append(CPPPATH = ['#/openssl/include', '#/bzip2', '#/zlib'])
+env.Append(CPPPATH = ['#/openssl/include', '#/bzip2', '#/zlib', '#/geoip'])
 
 env.Append(CPPDEFINES=["BUILDING_DCPP=1"])
 

=== modified file 'dcpp/User.cpp'
--- dcpp/User.cpp	2011-09-22 19:45:17 +0000
+++ dcpp/User.cpp	2011-09-23 11:47:15 +0000
@@ -142,8 +142,9 @@
 	return get("CO");
 }
 
-const string& Identity::getCountry() const {
-	return Util::getIpCountry(getIp());
+string Identity::getCountry() const {
+	bool v6 = !getIp6().empty();
+	return Util::getCountry(v6 ? getIp6() : getIp4(), v6 ? Util::V6 : Util::V4);
 }
 
 string Identity::get(const char* name) const {

=== modified file 'dcpp/Util.cpp'
--- dcpp/Util.cpp	2011-09-07 18:31:43 +0000
+++ dcpp/Util.cpp	2011-09-23 11:47:15 +0000
@@ -30,6 +30,7 @@
 #include "ClientManager.h"
 #include "FastAlloc.h"
 #include "File.h"
+#include "GeoIP.h"
 #include "LogManager.h"
 #include "SettingsManager.h"
 #include "SimpleXML.h"
@@ -54,6 +55,8 @@
 FastCriticalSection FastAllocBase::cs;
 #endif
 
+GeoIP geo6, geo4;
+
 string Util::emptyString;
 wstring Util::emptyStringW;
 tstring Util::emptyStringT;
@@ -63,9 +66,6 @@
 string Util::awayMsg;
 time_t Util::awayTime;
 
-Util::CountryList Util::countries;
-StringList Util::countryNames;
-
 string Util::paths[Util::PATH_LAST];
 
 bool Util::localMode = true;
@@ -197,59 +197,8 @@
 	File::ensureDirectory(paths[PATH_USER_CONFIG]);
 	File::ensureDirectory(paths[PATH_USER_LOCAL]);
 
-	try {
-		// This product includes GeoIP data created by MaxMind, available from http://maxmind.com/
-		// Updates at http://www.maxmind.com/app/geoip_country
-		string file = getPath(PATH_RESOURCES) + "GeoIpCountryWhois.csv";
-		string data = File(file, File::READ, File::OPEN).read();
-
-		const char* start = data.c_str();
-		string::size_type linestart = 0, lineend, pos, pos2;
-		auto last = countries.end();
-		uint32_t startIP = 0, endIP = 0, endIPprev = 0;
-
-		countryNames.push_back(_("Unknown"));
-		auto addCountry = [](const string& countryName) -> size_t {
-			auto begin = countryNames.cbegin(), end = countryNames.cend();
-			auto pos = std::find(begin, end, countryName);
-			if(pos != end)
-				return pos - begin;
-			countryNames.push_back(countryName);
-			return countryNames.size() - 1;
-		};
-
-		while(true) {
-			pos = data.find(',', linestart);
-			if(pos == string::npos) break;
-			pos = data.find(',', pos + 1);
-			if(pos == string::npos) break;
-			startIP = toUInt32(start + pos + 2) - 1;
-
-			pos = data.find(',', pos + 1);
-			if(pos == string::npos) break;
-			endIP = toUInt32(start + pos + 2);
-
-			pos = data.find(',', pos + 1);
-			if(pos == string::npos) break;
-
-			pos2 = data.find(',', pos + 1);
-			if(pos2 == string::npos) break;
-
-			lineend = data.find('\n', pos2);
-			if(lineend == string::npos) break;
-
-			if(startIP != endIPprev)
-				last = countries.insert(last, make_pair(startIP, 0));
-			pos += 2;
-			pos2 += 2;
-			last = countries.insert(last, make_pair(endIP, addCountry(str(F_("%1% - %2%") %
-				data.substr(pos, 2) % data.substr(pos2, lineend - 1 - pos2)))));
-
-			endIPprev = endIP;
-			linestart = lineend + 1;
-		}
-	} catch(const FileException&) {
-	}
+	geo6.init(getPath(PATH_USER_LOCAL) + "GeoIPv6.dat");
+	geo4.init(getPath(PATH_USER_LOCAL) + "GeoIP.dat");
 }
 
 void Util::migrate(const string& file) {
@@ -996,29 +945,17 @@
 	return y;
 }
 
-/*	getIpCountry
-	This function returns the full country name of an ip, eg "Portugal".
-	more info: http://www.maxmind.com/app/csv
-*/
-const string& Util::getIpCountry(const string& IP) {
-	if(BOOLSETTING(GET_USER_COUNTRY)) {
-		if(count(IP.begin(), IP.end(), '.') != 3)
-			return emptyString;
-
-		//e.g IP 23.24.25.26 : w=23, x=24, y=25, z=26
-		string::size_type a = IP.find('.');
-		string::size_type b = IP.find('.', a+1);
-		string::size_type c = IP.find('.', b+2);
-
-		/// @todo this is impl dependant and is working by chance because we are currently using atoi!
-		uint32_t ipnum = (toUInt32(IP.c_str()) << 24) |
-			(toUInt32(IP.c_str() + a + 1) << 16) |
-			(toUInt32(IP.c_str() + b + 1) << 8) |
-			(toUInt32(IP.c_str() + c + 1) );
-
-		auto i = countries.lower_bound(ipnum);
-		if(i != countries.end()) {
-			return countryNames[i->second];
+string Util::getCountry(const string& ip, int flags) {
+	if(BOOLSETTING(GET_USER_COUNTRY) && !ip.empty()) {
+
+		if(flags & V6) {
+			auto ret = geo6.getCountry(ip);
+			if(!ret.empty())
+				return ret;
+		}
+
+		if(flags & V4) {
+			return geo4.getCountry(ip);
 		}
 	}
 

=== modified file 'dcpp/Util.h'
--- dcpp/Util.h	2011-08-11 13:02:19 +0000
+++ dcpp/Util.h	2011-09-23 11:47:15 +0000
@@ -428,7 +428,8 @@
 	static int stricmp(const wstring& a, const wstring& b) { return stricmp(a.c_str(), b.c_str()); }
 	static int strnicmp(const wstring& a, const wstring& b, size_t n) { return strnicmp(a.c_str(), b.c_str(), n); }
 
-	static const string& getIpCountry(const string& IP);
+	enum { V6 = 1 << 1, V4 = 1 << 2 };
+	static string getCountry(const string& ip, int flags = V6 | V4);
 
 	static bool getAway();
 	static void setAway(bool aAway);
@@ -456,10 +457,6 @@
 	static string awayMsg;
 	static time_t awayTime;
 
-	typedef map<uint32_t, size_t> CountryList;
-	static CountryList countries;
-	static StringList countryNames;
-
 	static void loadBootConfig();
 };
 

=== modified file 'help/links.html'
--- help/links.html	2008-11-13 16:27:41 +0000
+++ help/links.html	2011-09-23 11:47:15 +0000
@@ -18,8 +18,12 @@
       <td><untranslated><a href="http://dcplusplus.sourceforge.net/download/"; target="_blank" class="external">http://dcplusplus.sourceforge.net/download/</a></untranslated></td>
     </tr>
     <tr>
-      <td id="geoip">GeoIP database update</td>
-      <td><untranslated><a href="http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip"; target="_blank" class="external">http://www.maxmind.com/ ...</a></untranslated></td>
+      <td id="geoip">GeoIP database update (IPv6)</td>
+      <td><untranslated><a href="http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz"; target="_blank" class="external">http://geolite.maxmind.com/download/ ...</a></untranslated></td>
+    </tr>
+    <tr>
+      <td id="geoip">GeoIP database update (IPv4)</td>
+      <td><untranslated><a href="http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz"; target="_blank" class="external">http://geolite.maxmind.com/download/ ...</a></untranslated></td>
     </tr>
     <tr>
       <td>Frequently asked questions</td>

=== modified file 'help/settings_appearance.html'
--- help/settings_appearance.html	2011-06-28 20:07:49 +0000
+++ help/settings_appearance.html	2011-09-23 11:47:15 +0000
@@ -48,9 +48,12 @@
 from Windows Explorer. <i>Turning
 on this option slows browsing file lists a bit.</i></dd>
   <dt id="guessip">Guess user country from IP</dt>
-  <dd cshelp="IDH_SETTINGS_APPEARANCE_GET_USER_COUNTRY">When selected, country codes for your uploaders and downloaders
-appear in the <a href="window_connections.html">Connections</a> window. This function
-uses the <a href="links.html#geoip">GeoIPCountryWhois.csv</a> database provided by <a href="http://www.maxmind.com"; target="_blank" class="external">MaxMind</a>.</dd>
+  <dd cshelp="IDH_SETTINGS_APPEARANCE_GET_USER_COUNTRY">
+  When selected, country codes for connected users appear in the
+  <a href="window_connections.html">Connections</a> window. This function uses the
+  <a href="links.html#geoip">GeoIP</a> databases provided by
+  <a href="http://www.maxmind.com"; target="_blank" class="external">MaxMind</a>.
+  </dd>
 </dl>
 <h2>Miscellaneous</h2>
 <dl style="margin-left: 40px;">

=== modified file 'help/window_main.html'
--- help/window_main.html	2011-06-28 20:07:49 +0000
+++ help/window_main.html	2011-09-23 11:47:15 +0000
@@ -185,13 +185,20 @@
 			<dd>Opens the DC++ blog in your web browser.</dd>
 			<dt>Community news</dt>
 			<dd>Opens ADCPortal in your web browser.</dd>
-			<dt>GeoIP database update</dt>
-			<dd>Opens a web page where the latest GeoIP database can be obtained. The database file
-			is called GeoIPCountryWhoIs.csv and should be saved into the DC++ program folder. GeoIP
-			is used to determine the country of uploaders and downloaders in the
-			<a href="window_connections.html">Connections</a> window. The database file is
-			frequently updated; the newer your GeoIP file is, the more exact country information
-			will be in the Connections window.</dd>
+			<dt>GeoIP database update (IPv6)</dt>
+			<dd>Opens a web page where the latest GeoIP database for
+			<placeholder>IPv6</placeholder> addresses can be obtained. The file is called
+			<placeholder>GeoIPv6.dat.gz</placeholder>; it should be saved to the DC++ settings
+			directory, where the previous file should reside. This database is used to determine
+			the country of connected users. The database is frequently updated; the newer your
+			GeoIP files are, the more accurate the country information you will see.</dd>
+			<dt>GeoIP database update (IPv4)</dt>
+			<dd>Opens a web page where the latest GeoIP database for
+			<placeholder>IPv4</placeholder> addresses can be obtained. The file is called
+			<placeholder>GeoIP.dat.gz</placeholder>; it should be saved to the DC++ settings
+			directory, where the previous file should reside. This database is used to determine
+			the country of connected users. The database is frequently updated; the newer your
+			GeoIP files are, the more accurate the country information you will see.</dd>
 			</dl>
 
 			</dd>

=== modified file 'installer/DCPlusPlus.nsi'
--- installer/DCPlusPlus.nsi	2011-06-12 22:41:02 +0000
+++ installer/DCPlusPlus.nsi	2011-09-23 11:47:15 +0000
@@ -125,8 +125,9 @@
 SectionEnd
 
 Section $(SECTION_IP_COUNTRY)
-  SetOutPath $INSTDIR
-  File "GeoIPCountryWhois.csv"
+  SetOutPath "$LOCALAPPDATA\DC++"
+  File "GeoIPv6.dat.gz"
+  File "GeoIP.dat.gz"
 SectionEnd
 
 Section $(SECTION_START_MENU)
@@ -204,7 +205,7 @@
   Delete "$INSTDIR\LICENSE-GeoIP.txt" ; now in ThirdPartyLicenses; remove if present.
   Delete "$INSTDIR\LICENSE-OpenSSL.txt" ; now in ThirdPartyLicenses; remove if present.
   Delete "$INSTDIR\mingwm10.dll" ; no longer required, remove if present.
-  Delete "$INSTDIR\GeoIPCountryWhois.csv"
+  Delete "$INSTDIR\GeoIPCountryWhois.csv" ; no longer required, remove if present.
   Delete "$INSTDIR\ThirdPartyLicenses.txt"
 
   ; Delete the whole locale directory

=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp	2011-08-05 20:59:14 +0000
+++ win32/MainWindow.cpp	2011-09-23 11:47:15 +0000
@@ -107,7 +107,8 @@
 {
 	links.homepage = _T("http://dcplusplus.sourceforge.net/";);
 	links.downloads = links.homepage + _T("download/");
-	links.geoipfile = _T("http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip";);
+	links.geoip6 = _T("http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz";);
+	links.geoip4 = _T("http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz";);
 	links.faq = links.homepage + _T("faq/");
 	links.help = links.homepage + _T("help/");
 	links.discuss = links.homepage + _T("discussion/");
@@ -360,7 +361,8 @@
 		help->appendItem(T_("Community news"), [this] { WinUtil::openLink(links.community); });
 		help->appendSeparator();
 
-		help->appendItem(T_("GeoIP database update"), [this] { WinUtil::openLink(links.geoipfile); });
+		help->appendItem(T_("GeoIP database update (IPv6)"), [this] { WinUtil::openLink(links.geoip6); });
+		help->appendItem(T_("GeoIP database update (IPv4)"), [this] { WinUtil::openLink(links.geoip4); });
 	}
 
 	mainMenu->setMenu();
@@ -1259,8 +1261,11 @@
 				links.downloads = Text::toT(xml.getChildData());
 			}
 			xml.resetCurrentChild();
-			if(xml.findChild("GeoIP database update")) {
-				links.geoipfile = Text::toT(xml.getChildData());
+			if(xml.findChild("GeoIPv6")) {
+				links.geoip6 = Text::toT(xml.getChildData());
+			}
+			if(xml.findChild("GeoIPv4")) {
+				links.geoip4 = Text::toT(xml.getChildData());
 			}
 			xml.resetCurrentChild();
 			if(xml.findChild("Faq")) {

=== modified file 'win32/MainWindow.h'
--- win32/MainWindow.h	2011-05-29 21:40:28 +0000
+++ win32/MainWindow.h	2011-09-23 11:47:15 +0000
@@ -90,7 +90,8 @@
 	struct {
 		tstring homepage;
 		tstring downloads;
-		tstring geoipfile;
+		tstring geoip6;
+		tstring geoip4;
 		tstring faq;
 		tstring help;
 		tstring discuss;

=== modified file 'win32/SConscript'
--- win32/SConscript	2011-06-24 18:55:47 +0000
+++ win32/SConscript	2011-09-23 11:47:15 +0000
@@ -24,7 +24,7 @@
 elif env['LINK'] == 'link': # MSVC
 	env.Append(LIBS = ['dbghelp'])
 
-env.Append(CPPPATH = ['#/openssl/include', '#/bzip2', '#/zlib', '#/miniupnpc', '#/dwt/include'])
+env.Append(CPPPATH = ['#/openssl/include', '#/bzip2', '#/dwt/include'])
 
 openssl_lib = '#/openssl/lib/'
 if env['arch'] != 'x86':
@@ -44,7 +44,7 @@
 headers=dev.get_sources(source_path, "*.h")
 dev.i18n(source_path, env, [sources,headers], 'dcpp-win32')
 
-ret = env.Program(target, [sources, res, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.miniupnpc, dev.natpmp, dev.dwt, dev.intl])
+ret = env.Program(target, [sources, res, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.dwt, dev.intl])
 
 if 'gcc' in env['TOOLS']:
 	# strip debug info to a separate PDB file

=== modified file 'win32/SearchFrame.cpp'
--- win32/SearchFrame.cpp	2011-08-06 07:00:02 +0000
+++ win32/SearchFrame.cpp	2011-09-23 11:47:15 +0000
@@ -489,7 +489,7 @@
 		columns[COLUMN_IP] = Text::toT(sr->getIP());
 		if(!columns[COLUMN_IP].empty()) {
 			// Only attempt to grab a country mapping if we actually have an IP address
-			const string& country = Util::getIpCountry(sr->getIP());
+			auto country = Util::getCountry(sr->getIP());
 			if(!country.empty())
 				columns[COLUMN_IP] = Text::toT(country) + _T(" (") + columns[COLUMN_IP] + _T(")");
 		}

=== modified file 'win32/TransferView.cpp'
--- win32/TransferView.cpp	2011-06-27 16:46:13 +0000
+++ win32/TransferView.cpp	2011-09-23 11:47:15 +0000
@@ -734,7 +734,7 @@
 	ui->setChunk(t->getPos(), t->getSize());
 	const UserConnection& uc = t->getUserConnection();
 	ui->setCipher(Text::toT(uc.getCipherName()));
-	const string& country = Util::getIpCountry(uc.getRemoteIp());
+	auto country = Util::getCountry(uc.getRemoteIp());
 	if(!country.empty())
 		ui->setCountry(Text::toT(country));
 	ui->setIP(Text::toT(uc.getRemoteIp()));