Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET2 DNS rejects hostnames over 126 characters as "too long"

Tags:

c#

.net

ping

dns

While working on a program I recently found that hostnames in .net (or at least in the ping class) are not supposed to have more than 126 characters. The ping class throws an exception if a hostname is longer.

However Wikipedia states that up to 255 characters are allowed. And it looks that indeed there are machines with a hostname longer than 126 chars out there, so the question is: can this limit be changed, who is right and how to resolve names if it cannot?

like image 807
FinalNotriX Avatar asked Oct 30 '11 21:10

FinalNotriX


4 Answers

The .NET Dns class has a hard upper limit of 126 characters for hostnames (checked for .NET4).

However, you can use the lower-level Win32 DnsQuery method using P/Invoke to translate host names into IP addresses and then use those raw addresses with the .NET networking classes.

Here is a sample DnsAddr class using this approach:

public static class DnsAddr
{
    [DllImport("dnsapi", EntryPoint = "DnsQuery_W", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
    private static extern int DnsQuery([MarshalAs(UnmanagedType.VBByRefStr)]ref string pszName, QueryTypes wType, QueryOptions options, int         aipServers, ref IntPtr ppQueryResults, int pReserved);

    [DllImport("dnsapi", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern void DnsRecordListFree(IntPtr pRecordList, int FreeType);

    public static IEnumerable<IPAddress> GetAddress(string domain)
    {
        IntPtr ptr1 = IntPtr.Zero;
        IntPtr ptr2 = IntPtr.Zero;
        List<IPAddress> list = new List<IPAddress>();
        DnsRecord record = new DnsRecord();
        int num1 = DnsAddr.DnsQuery(ref domain, QueryTypes.DNS_TYPE_A, QueryOptions.DNS_QUERY_NONE, 0, ref ptr1, 0);
        if (num1 != 0)
            throw new Win32Exception(num1);
        for (ptr2 = ptr1; !ptr2.Equals(IntPtr.Zero); ptr2 = record.pNext)
        {
            record = (DnsRecord)Marshal.PtrToStructure(ptr2, typeof(DnsRecord));
            list.Add(new IPAddress(record.ipAddress));
        }
        DnsAddr.DnsRecordListFree(ptr1, 0);
        return list;
    }

    private enum QueryOptions
    {     
        DNS_QUERY_NONE = 0,
    }

    private enum QueryTypes
    {
        DNS_TYPE_A = 1,
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct DnsRecord
    {
        public IntPtr pNext;
        public string pName;
        public short wType;
        public short wDataLength;
        public int flags;
        public int dwTtl;
        public int dwReserved;
        public uint ipAddress;
    }
}

Here is a sample test program:

class Program
{
    static void Main(string[] args)
    {
        var addresses = DnsAddr.GetAddress("google.com");
        foreach (var address in addresses)
            Console.WriteLine(address.ToString());
    }
}

which on my machine produces this output:

173.194.33.51
173.194.33.50
173.194.33.49
173.194.33.52
173.194.33.48
like image 191
Rick Sladkey Avatar answered Nov 19 '22 16:11

Rick Sladkey


Call gethostbyname, then pass an IP address (which is never more than a couple dozen characters, even for IPv6) to the ping class.

like image 31
Ben Voigt Avatar answered Nov 19 '22 16:11

Ben Voigt


Both informations are right.

The 255 character limit refers to the entire hostname (e.g. some.thing.example.com).

In turn, each label (e.g. example or com) is limited to 63 characters. So top-level domains have a theoretical limit of 126 non-dot characters.

like image 37
Dennis Avatar answered Nov 19 '22 16:11

Dennis


Apparently it is like Joel and Dennis explained. .Net is not capable of resolving names longer than 126 chars.

However if somebody has the same problem, take a look here at DNS Plus: http://www.simpledns.com/dns-client-lib.aspx#download

like image 1
FinalNotriX Avatar answered Nov 19 '22 16:11

FinalNotriX