From 2533ee486ac7f66078ada31e7ec6b3cc3d44a6a5 Mon Sep 17 00:00:00 2001 From: mark Date: Mon, 27 Aug 2007 22:29:58 +0000 Subject: [PATCH] initial attempt at serverlist autoconfiguration, please let me know in irc if any issues are encountered. --- Scripts/Accounting/IPLimiter.cs | 4 +- Scripts/Misc/ServerList.cs | 120 ++++++++++++++++++++++++-------- Server/Main.cs | 2 +- Server/Network/Listener.cs | 2 +- 4 files changed, 96 insertions(+), 32 deletions(-) diff --git a/Scripts/Accounting/IPLimiter.cs b/Scripts/Accounting/IPLimiter.cs index 47558763d..f43c2e5d4 100644 --- a/Scripts/Accounting/IPLimiter.cs +++ b/Scripts/Accounting/IPLimiter.cs @@ -13,7 +13,7 @@ namespace Server.Misc public static bool Enabled = true; public static bool SocketBlock = true; // true to block at connection, false to block at login request - public const int MaxAddresses = 10; + public static int MaxAddresses = 10; public static IPAddress[] Exemptions = new IPAddress[] //For hosting services where there are cases where IPs can be proxied { @@ -42,7 +42,7 @@ namespace Server.Misc for ( int i = 0; i < netStates.Count; ++i ) { - NetState compState = (NetState)netStates[i]; + NetState compState = netStates[i]; if ( ourAddress.Equals( compState.Address ) ) { diff --git a/Scripts/Misc/ServerList.cs b/Scripts/Misc/ServerList.cs index eefaffa6b..0e8342a7d 100644 --- a/Scripts/Misc/ServerList.cs +++ b/Scripts/Misc/ServerList.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Net; using System.Net.Sockets; using Server; @@ -20,27 +21,47 @@ namespace Server.Misc * private const string Address = "shard.host.com"; */ - public static readonly string Address = null; + public static readonly string Address = null; + public static readonly string ServerName = "RunUO TC"; - public const string ServerName = "RunUO TC"; + public static readonly bool AutoDetect = true; public static void Initialize() { Listener.Port = 2593; + if ( Address == null ) { + if ( AutoDetect ) + AutoDetection(); + } + else { + Resolve( Address, out m_PublicAddress ); + } + EventSink.ServerList += new ServerListEventHandler( EventSink_ServerList ); } - public static void EventSink_ServerList( ServerListEventArgs e ) + private static IPAddress m_PublicAddress; + + private static void EventSink_ServerList( ServerListEventArgs e ) { try { - IPAddress ipAddr; + NetState ns = e.State; + Socket s = ns.Socket; - if ( Resolve( Address != null && !IsLocalMachine( e.State ) ? Address : Dns.GetHostName(), out ipAddr ) ) - e.AddServer( ServerName, new IPEndPoint( ipAddr, Listener.Port ) ); - else - e.Rejected = true; + IPEndPoint ipep = (IPEndPoint)s.LocalEndPoint; + + IPAddress localAddress = ipep.Address; + int localPort = ipep.Port; + + if ( IsPrivateNetwork( localAddress ) ) { + ipep = (IPEndPoint)s.RemoteEndPoint; + if ( !IsPrivateNetwork( ipep.Address ) && m_PublicAddress != null ) + localAddress = m_PublicAddress; + } + + e.AddServer( ServerName, new IPEndPoint( localAddress, localPort ) ); } catch { @@ -48,45 +69,88 @@ namespace Server.Misc } } - public static bool Resolve( string addr, out IPAddress outValue ) + private static void AutoDetection() { + if ( !HasPublicIPAddress() ) { + Console.Write( "ServerList: Auto-detecting public IP address..." ); + m_PublicAddress = FindPublicAddress(); + + if ( m_PublicAddress != null ) + Console.WriteLine( "done ({0})", m_PublicAddress.ToString() ); + else + Console.WriteLine( "failed" ); + } + } + private static bool Resolve( string addr, out IPAddress outValue ) + { if ( IPAddress.TryParse( addr, out outValue ) ) return true; - try - { + try { IPHostEntry iphe = Dns.GetHostEntry( addr ); - if ( iphe.AddressList.Length > 0 ) - { + if ( iphe.AddressList.Length > 0 ) { outValue = iphe.AddressList[iphe.AddressList.Length - 1]; return true; } } - catch - { - } + catch {} - outValue = IPAddress.None; return false; } - private static bool IsLocalMachine( NetState state ) + private static bool HasPublicIPAddress() { - IPAddress theirAddress = state.Address; - - if ( IPAddress.IsLoopback( theirAddress ) ) - return true; - - bool contains = false; - IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() ); - for ( int i = 0; !contains && i < iphe.AddressList.Length; ++i ) - contains = theirAddress.Equals( iphe.AddressList[i] ); + IPAddress[] ips = iphe.AddressList; - return contains; + for ( int i = 0; i < ips.Length; ++i ) + if ( !IsPrivateNetwork( ips[i] ) ) + return true; + + return false; + } + + private static bool IsPrivateNetwork( IPAddress ip ) + { + // 10.0.0.0/8 + // 172.16.0.0/12 + // 192.168.0.0/16 + + if ( Utility.IPMatch( "192.168.*", ip ) ) + return true; + else if ( Utility.IPMatch( "10.*", ip ) ) + return true; + else if ( Utility.IPMatch( "172.16-31.*", ip ) ) + return true; + else + return false; + } + + private static IPAddress FindPublicAddress() + { + try { + WebRequest req = HttpWebRequest.Create( "http://www.runuo.com/ip.php" ); + req.Timeout = 15000; + + WebResponse res = req.GetResponse(); + + Stream s = res.GetResponseStream(); + + StreamReader sr = new StreamReader( s ); + + IPAddress ip = IPAddress.Parse( sr.ReadLine() ); + + sr.Close(); + s.Close(); + res.Close(); + + return ip; + } catch { + return null; + } } } } \ No newline at end of file diff --git a/Server/Main.cs b/Server/Main.cs index b1976c224..a3c449cb6 100644 --- a/Server/Main.cs +++ b/Server/Main.cs @@ -346,7 +346,7 @@ namespace Server if( SocketPool.Created ) SocketPool.Destroy(); - Timer.Set(); + Timer.TimerThread.Set(); Console.WriteLine( "done" ); } diff --git a/Server/Network/Listener.cs b/Server/Network/Listener.cs index 3c04d7026..ae70d0d14 100644 --- a/Server/Network/Listener.cs +++ b/Server/Network/Listener.cs @@ -70,7 +70,7 @@ namespace Server.Network IPAddress[] ip = iphe.AddressList; for ( int i = 0; i < ip.Length; ++i ) - Console.WriteLine( "Address: {0}:{1}", ip[i], port ); + Console.WriteLine( "Address: {0}:{1}", ip[i], port ); } catch {