RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

RunUO 2.1 behind a proxy server. Verifying account problem.

LdNS88i

Sorceror
To hide the real ip address of the server is behind a proxy server.

Clients -> Proxy -> RunUO
Clients <- Proxy <- RunUO

The following changes have been made:

Code:
e.AddServer( ServerName, new IPEndPoint( m_PublicAddress, localPort ) );

instead

Code:
e.AddServer( ServerName, new IPEndPoint( localAddress, localPort ) );

in ServerList.cs

Full:
Code:
using System;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using Server;
using Server.Network;
 
namespace Server.Misc
{
    public class ServerList
    {
 
 
        public static readonly string Address = "11.22.33.44"; // Proxy adress
       
        public static readonly string ServerName = "1234";
 
        public static readonly bool AutoDetect = true;
 
        public static void Initialize()
        {
            if (Address == null)
            {
                if (AutoDetect)
                    AutoDetection();
            }
            else
            {
                Resolve(Address, out m_PublicAddress);
            }
 
            EventSink.ServerList += new ServerListEventHandler(EventSink_ServerList);
        }
 
        private static IPAddress m_PublicAddress;
 
        private static void EventSink_ServerList(ServerListEventArgs e)
        {
            try
            {
                NetState ns = e.State;
                Socket s = ns.Socket;
 
                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(m_PublicAddress, localPort));
            }
            catch
            {
                e.Rejected = true;
            }
        }
 
        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 void Resolve(string addr, out IPAddress outValue)
        {
            if (IPAddress.TryParse(addr, out outValue))
                return;
 
            try
            {
                IPHostEntry iphe = Dns.GetHostEntry(addr);
 
                if (iphe.AddressList.Length > 0)
                    outValue = iphe.AddressList[iphe.AddressList.Length - 1];
            }
            catch
            {
            }
        }
 
        private static bool HasPublicIPAddress()
        {
            NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
 
            foreach (NetworkInterface adapter in adapters)
            {
                IPInterfaceProperties properties = adapter.GetIPProperties();
 
                foreach (IPAddressInformation unicast in properties.UnicastAddresses)
                {
                    IPAddress ip = unicast.Address;
 
                    if (!IPAddress.IsLoopback(ip) && ip.AddressFamily != AddressFamily.InterNetworkV6 && !IsPrivateNetwork(ip))
                        return true;
                }
            }
 
            return false;
 
 
            /*
            IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() );
 
            IPAddress[] ips = iphe.AddressList;
 
            for ( int i = 0; i < ips.Length; ++i )
            {
                if ( ips[i].AddressFamily != AddressFamily.InterNetworkV6 && !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 (ip.AddressFamily == AddressFamily.InterNetworkV6)
                return false;
 
            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;
        }
 
        public 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;
            }
        }
    }
}

This solution works and allows you to completely hide the real address of the server.

But there is a problem. At first everything is fine. After some time, the problem starts with the connection.
When trying to connect, we obtain - Verifying account. This may continue for 2-3 minutes and then start up the game. A may simply remain in this state for 5 minutes and longer. The problem occurs on all clients simultaneously. After some time again, you can connect without any problems and expectations. Then again, you can not connect. Then again - you can. Such periods can last for 10-20 minutes.
Tried with two different proxy servers, a problem somewhere in RunUO core. But where?

For example, 20 minutes of all clients - Verifying account (on the server after a while disconnects due to inactivity). The next 5 minutes, people come into the game with no problems at all, instantly. Server sees it as if all the clients are connected to one address (the address of the proxy server). All the people in the game with one ip address. Everything works fine, the only problem is this.
If a person in the game - he has no problems.

No restrictions in scripts (iplimiter or accounthandler). I think it is because too many connections with one address. But why does it work first, then not working, then working again? After intervals.

Sorry for bad English.
 

fwiffo

Sorceror
what is the purpose of use a proxy server for the server itself?

You obtain a slow link, high ping, unless this proxy server is one of your and you have control in the quality of the link.
 

tindo

Sorceror
This is just a complete guess, but I would imagine there would be issues with many clients having the same ip. So many scripts rely on netstate that there are bound to be socket or packets issues.
 

LdNS88i

Sorceror
what is the purpose of use a proxy server for the server itself?
You obtain a slow link, high ping, unless this proxy server is one of your and you have control in the quality of the link.
The purpose - hide the real ip address. No problems with ping. We tried two servers, 50-60ms and 15ms. If a person in game - he plays with no lag and disconnections. The problem only occurs when entering the game.

This is just a complete guess, but I would imagine there would be issues with many clients having the same ip. So many scripts rely on netstate that there are bound to be socket or packets issues.
I think so too, it seems the only option. Problem is only with the entering to the server, the game has no problems. And the problem does not occur constantly. May not work for 20 minutes.
Once again this may work for 10 minutes. And then did not work again, etc.The problem somewhere in RunUO scripts, but where?
 

tindo

Sorceror
You might look at Listener.cs at how it is binding sockets.

My thinking is that Windows 7 puts a limit on the number of sockets that can be bound to a single IP address, but after I lot of googling, I couldn't find a definitive answer.
 

LdNS88i

Sorceror
Not Windows 7. We use Windows Server 2008 R2 Standart. He has no limits as far as I know. I also thought about it. But it's probably not a problem.
 

Juzzver

Sorceror
The problem is solved by AccountAttackLimiter.cs
It is necessary to disable standard system of protection of RunUO of the server since all connections go on the server from one IP address.
Solution:
Scripts\Accounting\AccountAttackLimiter.cs

public static bool Enabled = true;
change to
public static bool Enabled = false;
 
Top