Question

I'm creating an application for Minecraft Classic to send "Heartbeats" to an external website and my application wants to send IPv6 heartbeats rather than IPv4 heartbeats if both IPv6 and IPv4 are present on the system.

Here's what I've tried (through looking through Google search):

Ipv6Element DisableIPv6 = null;
DisableIPv6.enabled = false;

The issue here is that when I add the System.Net.Configuration import, my other portions of code from a .dll won't work anymore because I've attempted to use this method of disabling IPv6.

Here's an example of the .cs file where the heartbeat is sent to the external website (Either Minecraft.net or ClassiCube.net. Since Minecraft.net only supports IPv4 for its Classic servers, the software works fine, but since ClassiCube accepts both 4 and 6, if the machine the server is running has both, it will only take 6, but my software doesn't support IPv6 yet. The .cs file is here. (the Pastebin link expires in 2 weeks)

I've been trying to disable IPv6 if this is the case, but now that I realize that IPv6 will someday replace IPv4, I know I need to support IPv6 now before it is too late

I want to be able to support IPv6 in the application. How can I fix my code to support both IPv4 and 6?





Disclaimer

This code, in fact, is Visual C#, not java. The software has been created in Visual Studio 2013. This program is used to host Minecraft Classic Servers, (Not Premium). Many people don't believe the program was writen in C#, but I'm going to state that now so there is no confusion down the road.

Was it helpful?

Solution

Under the salt initialization:

       // Dns lookup, to make sure that IPv4 is preferred for heartbeats
    static readonly Dictionary<string, IPAddress> TargetAddresses = new Dictionary<string, IPAddress>();
    static DateTime nextDnsLookup = DateTime.MinValue;
    static readonly TimeSpan DnsRefreshInterval = TimeSpan.FromMinutes(30);


    static IPAddress RefreshTargetAddress([NotNull] Uri requestUri)
    {
        if (requestUri == null) throw new ArgumentNullException("requestUri");

        string hostName = requestUri.Host.ToLowerInvariant();
        IPAddress targetAddress;
        if (!TargetAddresses.TryGetValue(hostName, out targetAddress) || DateTime.UtcNow >= nextDnsLookup)
        {
            try
            {
                // Perform a DNS lookup on given host. Throws SocketException if no host found.
                IPAddress[] allAddresses = Dns.GetHostAddresses(requestUri.Host);
                // Find a suitable IPv4 address. Throws InvalidOperationException if none found.
                targetAddress = allAddresses.First(ip => ip.AddressFamily == AddressFamily.InterNetwork);
            }
            catch (SocketException ex)
            {
                Logger.Log(LogType.Error,
                           "Heartbeat.RefreshTargetAddress: Error looking up heartbeat server URLs: {0}",
                           ex);
            }
            catch (InvalidOperationException)
            {
                Logger.Log(LogType.Warning,
                           "Heartbeat.RefreshTargetAddress: {0} does not have an IPv4 address!", requestUri.Host);
            }
            TargetAddresses[hostName] = targetAddress;
            nextDnsLookup = DateTime.UtcNow + DnsRefreshInterval;
        }
        return targetAddress;
    }

And then, within static HttpWebRequest CreateRequest, under request.UserAgent, insert

          if (uri.Scheme == "http")
        {
            request.Proxy = new WebProxy("http://" + RefreshTargetAddress(uri) + ":" + uri.Port);
        }

That should work, I have no way of testing it. Hopefully you or someone else has ipv6 so they can test. All of this code was basically taken from fCraft by the way, all credit to them. http://www.fcraft.net

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top