From a4c562c06d26f4b20cab027a06c8b03db41e0fb7 Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 17 Nov 2007 07:10:29 +0000 Subject: [PATCH] support for listening on specific ip addresses and additional ports --- Scripts/Misc/ServerList.cs | 10 +---- Scripts/Misc/SocketOptions.cs | 18 ++++----- Server/Main.cs | 2 +- Server/Network/Listener.cs | 72 ++++++++++++++++++----------------- Server/Network/MessagePump.cs | 26 +++++++++++-- 5 files changed, 72 insertions(+), 56 deletions(-) diff --git a/Scripts/Misc/ServerList.cs b/Scripts/Misc/ServerList.cs index 1b8e67a43..19093b77c 100644 --- a/Scripts/Misc/ServerList.cs +++ b/Scripts/Misc/ServerList.cs @@ -33,12 +33,8 @@ namespace Server.Misc * locally private address, the server will direct the client to either the AutoDetected IP address or the manually entered * IP address or hostname, whichever is applicable. Loopback clients will be directed to loopback. * - * If you would like to change the default port RunUO listens on, you can do so by modifying the 'Listener.Port' assignment - * found below. If you would like to listen on additional ports (i.e. 22, 23, 80, for clients behind highly restrictive egress - * firewalls) you can do so by modifying the file SocketOptions.cs found in this directory. - * - * RunUO currently has no provision to bind on specific interfaces. If you need to run multiple instances of RunUO, you must - * bind the listener to a unique port. + * If you would like to listen on additional ports (i.e. 22, 23, 80, for clients behind highly restrictive egress + * firewalls) or specific IP adddresses you can do so by modifying the file SocketOptions.cs found in this directory. */ public static readonly string Address = null; @@ -48,8 +44,6 @@ namespace Server.Misc public static void Initialize() { - Listener.Port = 2593; - if ( Address == null ) { if ( AutoDetect ) AutoDetection(); diff --git a/Scripts/Misc/SocketOptions.cs b/Scripts/Misc/SocketOptions.cs index 52f5bc2d7..36c6c99d0 100644 --- a/Scripts/Misc/SocketOptions.cs +++ b/Scripts/Misc/SocketOptions.cs @@ -14,8 +14,13 @@ namespace Server private const int CoalesceBufferSize = 512; // MSS that the core will use when buffering packets private const int PooledSockets = 32; // The number of sockets to initially pool. Ideal value is expected client count. - private static int[] m_AdditionalPorts = new int[0]; - //private static int[] m_AdditionalPorts = new int[]{ 2594 }; + private static IPEndPoint[] m_ListenerEndPoints = new IPEndPoint[] { + new IPEndPoint( IPAddress.Any, 2593 ), // Default: Listen on port 2593 on all IP addresses + + // Examples: + // new IPEndPoint( IPAddress.Any, 80 ), // Listen on port 80 on all IP addresses + // new IPEndPoint( IPAddress.Parse( "1.2.3.4" ), 2593 ), // Listen on port 2593 on IP address 1.2.3.4 + }; public static void Initialize() { @@ -24,14 +29,7 @@ namespace Server EventSink.SocketConnect += new SocketConnectEventHandler( EventSink_SocketConnect ); - if ( m_AdditionalPorts.Length > 0 ) - EventSink.ServerStarted += new ServerStartedEventHandler( EventSink_ServerStarted ); - } - - public static void EventSink_ServerStarted() - { - for ( int i = 0; i < m_AdditionalPorts.Length; ++i ) - Core.MessagePump.AddListener( new Listener( m_AdditionalPorts[i] ) ); + Listener.EndPoints = m_ListenerEndPoints; } private static void EventSink_SocketConnect( SocketConnectEventArgs e ) diff --git a/Server/Main.cs b/Server/Main.cs index 430596385..955a91444 100644 --- a/Server/Main.cs +++ b/Server/Main.cs @@ -448,7 +448,7 @@ namespace Server SocketPool.Create(); - MessagePump ms = m_MessagePump = new MessagePump( new Listener( Listener.Port ) ); + MessagePump ms = m_MessagePump = new MessagePump(); timerThread.Start(); diff --git a/Server/Network/Listener.cs b/Server/Network/Listener.cs index 653070e21..a6c833878 100644 --- a/Server/Network/Listener.cs +++ b/Server/Network/Listener.cs @@ -39,48 +39,23 @@ namespace Server.Network private static Socket[] m_EmptySockets = new Socket[0]; - private static int m_Port = 2593; + private static IPEndPoint[] m_EndPoints; - public static int Port - { - get - { - return m_Port; - } - set - { - m_Port = value; - } + public static IPEndPoint[] EndPoints { + get { return m_EndPoints; } + set { m_EndPoints = value; } } - public Listener( int port ) + public Listener( IPEndPoint ipep ) { m_Accepted = new Queue(); m_AcceptedSyncRoot = ((ICollection)m_Accepted).SyncRoot; m_OnAccept = new AsyncCallback( OnAccept ); - - m_Listener = Bind( IPAddress.Any, port ); - - try - { - IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() ); - - Console.WriteLine( "Address: {0}:{1}", IPAddress.Loopback, port ); - - IPAddress[] ip = iphe.AddressList; - - for ( int i = 0; i < ip.Length; ++i ) - Console.WriteLine( "Address: {0}:{1}", ip[i], port ); - } - catch - { - } + m_Listener = Bind( ipep ); } - private Socket Bind( IPAddress ip, int port ) + private Socket Bind( IPEndPoint ipep ) { - IPEndPoint ipep = new IPEndPoint( ip, port ); - Socket s = SocketPool.AcquireSocket(); try @@ -93,14 +68,43 @@ namespace Server.Network s.Bind( ipep ); s.Listen( 8 ); + if ( ipep.Address.Equals( IPAddress.Any ) ) { + try { + Console.WriteLine( "Listening: {0}:{1}", IPAddress.Loopback, ipep.Port ); + + IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() ); + + IPAddress[] ip = iphe.AddressList; + + for ( int i = 0; i < ip.Length; ++i ) + Console.WriteLine( "Listening: {0}:{1}", ip[i], ipep.Port ); + } + catch { } + } + else { + Console.WriteLine( "Listening: {0}:{1}", ipep.Address, ipep.Port ); + } + IAsyncResult res = s.BeginAccept( SocketPool.AcquireSocket(), 0, m_OnAccept, s ); return s; } catch ( Exception e ) { - Console.WriteLine( "Listener bind exception:" ); - Console.WriteLine( e ); + if ( e is SocketException ) { + SocketException se = (SocketException)e; + + if ( se.ErrorCode == 10048 ) { // WSAEADDRINUSE + Console.WriteLine( "Listener Failed: {0}:{1} (In Use)", ipep.Address, ipep.Port ); + } + else if ( se.ErrorCode == 10049 ) { // WSAEADDRNOTAVAIL + Console.WriteLine( "Listener Failed: {0}:{1} (Unavailable)", ipep.Address, ipep.Port ); + } + else { + Console.WriteLine( "Listener Exception:" ); + Console.WriteLine( e ); + } + } return null; } diff --git a/Server/Network/MessagePump.cs b/Server/Network/MessagePump.cs index 47ceeeb0b..355da4bb6 100644 --- a/Server/Network/MessagePump.cs +++ b/Server/Network/MessagePump.cs @@ -24,9 +24,10 @@ using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; +using System.Threading; using Server; -using Server.Network; using Server.Diagnostics; +using Server.Network; namespace Server.Network { @@ -38,9 +39,28 @@ namespace Server.Network private Queue m_Throttled; private byte[] m_Peek; - public MessagePump( Listener l ) + public MessagePump() { - m_Listeners = new Listener[]{ l }; + IPEndPoint[] ipep = Listener.EndPoints; + + m_Listeners = new Listener[ipep.Length]; + + bool success = false; + + do { + for ( int i = 0; i < ipep.Length; i++ ) { + Listener l = new Listener( ipep[i] ); + if ( !success && l != null ) + success = true; + m_Listeners[i] = l; + } + + if ( !success ) { + Console.WriteLine( "Retrying..." ); + Thread.Sleep( 10000 ); + } + } while ( !success ); + m_Queue = new Queue(); m_WorkingQueue = new Queue(); m_Throttled = new Queue();