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)); }
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); } }