Beispiel #1
0
        public unsafe Task <DnsEntry[]> TryResolve()
        {
            var records = new List <DnsEntry>();

            byte[] dataBuffer = new byte[1024];
            int    dataLen    = LinuxLib.res_query(Query, C_IN, (int)Type, dataBuffer, dataBuffer.Length);

            if (dataLen > 0)
            {
                GCHandle handle = GCHandle.Alloc(dataBuffer, GCHandleType.Pinned);

                try
                {
                    fixed(byte *pBuffer = dataBuffer)
                    {
                        var reader = new LDnsReader
                        {
                            Buffer  = pBuffer,
                            Current = pBuffer,
                            End     = pBuffer + dataLen
                        };

                        // Response Header
                        int queryId = reader.UInt16();  // Query Identifier (Read & Ignore)

                        byte[] hBits = reader.Bytes(2); // Header Bits & Flags (Read & Ignore)

                        int qdCount = reader.UInt16();  // Question Count (Use Below)
                        int anCount = reader.UInt16();  // Answer Count (Use Below)

                        int nsCount = reader.UInt16();  // NameServer Count (Read & Ignore)
                        int arCount = reader.UInt16();  // Resource Count (Read & Ignore)

                        // Question Section (read and ignore)
                        for (int q = 0; q < qdCount && reader.OK(); q++)
                        {
                            string qName  = reader.Name();
                            ushort qType  = reader.UInt16();
                            ushort qClass = reader.UInt16();
                        }

                        // Answers (the good stuff)
                        for (int a = 0; a < anCount && reader.OK(); a++)
                        {
                            var      ansHead  = new LDnsHeader(reader);
                            DnsEntry dnsEntry = DnsEntry.Create(ansHead, reader);

                            records.Add(dnsEntry);
                        }
                    }
                }
                finally
                {
                    handle.Free();
                }
            }

            _allRecords  = records.ToArray();
            _typeRecords = records.Where(r => r.Type == Type).ToArray();

            if (Type == DnsRecordType.SRV || Type == DnsRecordType.MX)    // sort
            {
                _typeRecords = _typeRecords.OrderBy(r => ((IOrderedDnsEntry)r).SortOrder).ToArray();
            }

            return(Task.FromResult(_typeRecords));
        }
Beispiel #2
0
        private void QueryComplete(IntPtr contextPtr, IntPtr resultPtr)
        {
            lock (_syncLock)
            {
                if (_completed)
                {
                    return;
                }
                _completed = true;

                // stop timer
                if (_timer != null)
                {
                    _timer.Dispose();
                    _timer = null;
                }
            }

            try
            {
                // check if timed out
                if (_timedOut)
                {
                    _taskCompletion.SetException(new DnsTimeoutException(Query));
                    return;
                }

                // process results
                var records = new List <DnsEntry>();
                if (resultPtr != IntPtr.Zero)
                {
                    var queryResult = Marshal.PtrToStructure <Win32.DNS_QUERY_RESULT>(resultPtr);
                    if (queryResult.QueryStatus == 0)   // SUCCESS
                    {
                        IntPtr ptr = queryResult.QueryRecords;
                        while (ptr != IntPtr.Zero)
                        {
                            var record = Marshal.PtrToStructure <Win32.DNS_RECORD>(ptr);
                            records.Add(DnsEntry.Create(record, ptr));

                            ptr = record.Next;  // Next Record
                        }

                        if (queryResult.QueryRecords != IntPtr.Zero)
                        {
                            Win32.DnsRecordListFree(queryResult.QueryRecords, (int)Win32.DNS_FREE_TYPE.DnsFreeRecordList);
                        }
                    }
                }

                _allRecords  = records.ToArray();
                _typeRecords = records.Where(r => r.Type == Type).ToArray();

                if (Type == DnsRecordType.SRV || Type == DnsRecordType.MX)    // sort
                {
                    _typeRecords = _typeRecords.OrderBy(r => ((IOrderedDnsEntry)r).SortOrder).ToArray();
                }

                _taskCompletion.SetResult(_typeRecords);
            }
            catch (Exception ex)
            {
                _taskCompletion.SetException(ex);
            }
            finally
            {
                if (resultPtr != _resultPtr)
                {
                    Win32.FreeHGlobal(ref resultPtr);
                }

                Win32.FreeHGlobal(ref _resultPtr);
                Win32.FreeHGlobal(ref _requestPtr);

                _runningWait.Set();
                GC.SuppressFinalize(this);
            }
        }