Menu

Diff of /src/gnet/glocal.cpp [000000] .. [r1]  Maximize  Restore

Switch to side-by-side view

--- a
+++ b/src/gnet/glocal.cpp
@@ -0,0 +1,117 @@
+//
+// Copyright (C) 2017 Graeme Walker
+// 
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+// ===
+//
+// glocal.cpp
+//
+
+#include "gdef.h"
+#include "glocal.h"
+#include "ghostname.h"
+#include "gresolver.h"
+#include "gassert.h"
+#include "gdebug.h"
+#include <sstream>
+
+std::string GNet::Local::m_name_override ;
+bool GNet::Local::m_name_override_set = false ;
+
+std::string GNet::Local::hostname()
+{
+	std::string name = G::hostname() ;
+	if( name.empty() )
+		return "localhost" ;
+	return name ;
+}
+
+std::string GNet::Local::resolvedHostname()
+{
+	static Location location( hostname() , "0" ) ;
+	if( !location.resolved() )
+	{
+		std::string error = Resolver::resolve( location ) ;
+		if( !error.empty() )
+			return hostname() + ".localnet" ;
+	}
+	return location.name() ;
+}
+
+std::string GNet::Local::canonicalName()
+{
+	return m_name_override_set ? m_name_override : resolvedHostname() ;
+}
+
+void GNet::Local::canonicalName( const std::string & name_override )
+{
+	m_name_override = name_override ;
+	m_name_override_set = true ;
+}
+
+std::string GNet::Local::name()
+{
+	return canonicalName().empty() ? hostname() : canonicalName() ;
+}
+
+bool GNet::Local::isLocal( const Address & address , std::string & reason )
+{
+	// TODO use getifaddrs(3) and GetAdaptersAddresses()
+
+	// local if a loopback address
+	if( address.isLoopback() ) 
+		return true ;
+
+	// ipv6 is easier - no need to use dns
+	if( address.family() == Address::Family::ipv6() )
+		return address.isLocal( reason ) ;
+
+	// look up and cache the hostname() addresses
+	typedef std::vector<Address> List ;
+	static List list ;
+	static bool done = false ;
+	if( !done )
+	{
+		list = Resolver::resolve( hostname() , "0" , AF_INET ) ;
+		done = true ;
+	}
+
+	// local if a hostname() address
+	for( List::iterator p = list.begin() ; p != list.end() ; ++p )
+	{
+		if( (*p).sameHostPart(address) )
+			return true ;
+	}
+
+	// format a reason string
+	std::stringstream ss ;
+	if( list.empty() )
+	{
+		ss << address.hostPartString() << " is not a loopback address" ;
+	}
+	else
+	{
+		ss << address.hostPartString() << " is not a loopback address or " ;
+		const char * sep = "" ;
+		for( List::iterator p = list.begin() ; p != list.end() ; ++p , sep = " or " )
+		{
+			ss << sep << (*p).hostPartString() ;
+		}
+	}
+	reason = ss.str() ;
+
+	return false ;
+}
+
+/// \file glocal.cpp