private void TcpConnectCompleted(IAsyncResult ar) { DnsAsyncState state = (DnsAsyncState)ar.AsyncState; if (state.Timer != null) { state.Timer.Dispose(); } if (state.TimedOut) { state.ServerIndex++; TcpBeginConnect(state); } else { state.TcpClient.EndConnect(ar); state.TcpStream = state.TcpClient.GetStream(); int tmp = 0; state.TcpBuffer = new byte[2]; DnsMessageBase.EncodeUShort(state.TcpBuffer, ref tmp, (ushort)state.QueryLength); IAsyncResult asyncResult = state.TcpStream.BeginWrite(state.TcpBuffer, 0, 2, TcpSendLengthCompleted, state); state.Timer = new Timer(TcpTimedOut, asyncResult, QueryTimeout, Timeout.Infinite); } }
private void TcpReceiveLengthCompleted(IAsyncResult ar) { DnsAsyncState state = (DnsAsyncState)ar.AsyncState; if (state.Timer != null) { state.Timer.Dispose(); } if (state.TimedOut) { state.ServerIndex++; TcpBeginConnect(state); } else { state.TcpStream.EndRead(ar); int tmp = 0; int responseLength = DnsMessageBase.ParseUShort(state.TcpBuffer, ref tmp); state.TcpBuffer = new byte[responseLength]; IAsyncResult asyncResult = state.TcpStream.BeginRead(state.TcpBuffer, 0, responseLength, TcpReceiveCompleted, state); state.Timer = new Timer(TcpTimedOut, asyncResult, QueryTimeout, Timeout.Infinite); } }
private static void UdpTimedOut(object ar) { IAsyncResult asyncResult = (IAsyncResult)ar; if (!asyncResult.IsCompleted) { DnsAsyncState state = (DnsAsyncState)asyncResult.AsyncState; state.TimedOut = true; state.UdpClient.Close(); } }
private void UdpReceiveCompleted(IAsyncResult ar) { DnsAsyncState state = (DnsAsyncState)ar.AsyncState; if (state.Timer != null) { state.Timer.Dispose(); } if (state.TimedOut) { state.ServerIndex++; UdpBeginSend(state); } else { byte[] responseData = state.UdpClient.EndReceive(ar, ref state.UdpEndpoint); state.UdpClient.Close(); state.UdpClient = null; state.UdpEndpoint = null; state.Response = new DnsMessage(); state.Response.Parse(responseData, false, state.TSigKeySelector, state.TSigOriginalMac); if (state.Response.ReturnCode == ReturnCode.ServerFailure) { if (state.ServerIndex++ < state.Servers.Count) { UdpBeginSend(state); return; } else { state.SetCompleted(); } } else { if (state.Response.IsTruncated) { TcpBeginConnect(state); return; } else { state.SetCompleted(); } } } }
private static void TcpTimedOut(object ar) { IAsyncResult asyncResult = (IAsyncResult)ar; if (!asyncResult.IsCompleted) { DnsAsyncState state = (DnsAsyncState)asyncResult.AsyncState; state.TimedOut = true; if (state.TcpStream != null) { state.TcpStream.Close(); } state.TcpClient.Close(); } }
/// <summary> /// Send a custom message to the dns server and returns the answer asynchronously. /// </summary> /// <param name="message">Message, that should be send to the dns server</param> /// <param name="requestCallback">An <see cref="System.AsyncCallback"/> delegate that references the method to invoked then the operation is complete.</param> /// <param name="state">A user-defined object that contains information about the receive operation. This object is passed to the <paramref name="requestCallback"/> delegate when the operation is complete.</param> /// <returns>An <see cref="System.IAsyncResult"/> IAsyncResult object that references the asynchronous receive.</returns> public IAsyncResult BeginSendMessage(DnsMessage message, AsyncCallback requestCallback, object state) { if (message == null) { throw new ArgumentNullException("message"); } if ((message.Questions == null) || (message.Questions.Count == 0)) { throw new ArgumentException("At least one question must be provided", "message"); } if (message.TransactionID == 0) { message.TransactionID = (ushort)new Random().Next(0xffff); } byte[] queryData; int queryLength = message.Encode(out queryData, true); DnsAsyncState asyncResult = new DnsAsyncState() { QueryData = queryData, QueryLength = queryLength, UserCallback = requestCallback, AsyncState = state, Servers = _dnsServers, ServerIndex = 0 }; if (message.TSigOptions != null) { asyncResult.TSigKeySelector = (a, n) => message.TSigOptions.KeyData; asyncResult.TSigOriginalMac = message.TSigOptions.OriginalMac; } bool sendByTcp = ((queryLength > 512) || (message.Questions[0].RecordType == RecordType.Axfr) || (message.Questions[0].RecordType == RecordType.Ixfr)); if (sendByTcp) { TcpBeginConnect(asyncResult); } else { UdpBeginSend(asyncResult); } return(asyncResult); }
private void TcpBeginConnect(DnsAsyncState state) { if (state.ServerIndex == state.Servers.Count) { state.Response = null; state.TcpStream = null; state.TcpClient = null; state.SetCompleted(); return; } IPAddress server = state.Servers[state.ServerIndex]; state.TcpClient = new TcpClient(server.AddressFamily); state.TimedOut = false; IAsyncResult asyncResult = state.TcpClient.BeginConnect(server, _DNS_PORT, TcpConnectCompleted, state); state.Timer = new Timer(TcpTimedOut, asyncResult, QueryTimeout, Timeout.Infinite); }
private void UdpBeginSend(DnsAsyncState state) { if (state.ServerIndex == state.Servers.Count) { state.Response = null; state.UdpClient = null; state.UdpEndpoint = null; state.SetCompleted(); return; } state.UdpEndpoint = new IPEndPoint(state.Servers[state.ServerIndex], _DNS_PORT); state.UdpClient = new UdpClient(state.UdpEndpoint.AddressFamily); state.UdpClient.Connect(state.UdpEndpoint); state.TimedOut = false; IAsyncResult asyncResult = state.UdpClient.BeginSend(state.QueryData, state.QueryLength, UdpSendCompleted, state); state.Timer = new Timer(UdpTimedOut, asyncResult, QueryTimeout, Timeout.Infinite); }
private void TcpReceiveCompleted(IAsyncResult ar) { DnsAsyncState state = (DnsAsyncState)ar.AsyncState; if (state.Timer != null) { state.Timer.Dispose(); } if (state.TimedOut) { state.ServerIndex++; TcpBeginConnect(state); } else { state.TcpStream.EndRead(ar); state.TcpStream.Close(); state.TcpClient.Close(); state.TcpStream = null; state.TcpClient = null; state.TcpBuffer = null; state.Response = new DnsMessage(); state.Response.Parse(state.TcpBuffer, false, state.TSigKeySelector, state.TSigOriginalMac); if ((state.Response.ReturnCode == ReturnCode.ServerFailure) && (state.ServerIndex++ < state.Servers.Count)) { TcpBeginConnect(state); return; } else { state.SetCompleted(); } } }
private void TcpSendCompleted(IAsyncResult ar) { DnsAsyncState state = (DnsAsyncState)ar.AsyncState; if (state.Timer != null) { state.Timer.Dispose(); } if (state.TimedOut) { state.ServerIndex++; TcpBeginConnect(state); } else { state.TcpStream.EndWrite(ar); IAsyncResult asyncResult = state.TcpStream.BeginRead(state.TcpBuffer, 0, 2, TcpReceiveLengthCompleted, state); state.Timer = new Timer(TcpTimedOut, asyncResult, QueryTimeout, Timeout.Infinite); } }
private void UdpSendCompleted(IAsyncResult ar) { DnsAsyncState state = (DnsAsyncState)ar.AsyncState; if (state.Timer != null) { state.Timer.Dispose(); } if (state.TimedOut) { state.ServerIndex++; UdpBeginSend(state); } else { state.UdpClient.EndSend(ar); IAsyncResult asyncResult = state.UdpClient.BeginReceive(UdpReceiveCompleted, state); state.Timer = new Timer(UdpTimedOut, asyncResult, QueryTimeout, Timeout.Infinite); } }
/// <summary> /// Ends a pending asynchronous operation. /// </summary> /// <param name="ar">An <see cref="System.IAsyncResult"/> object returned by a call to <see cref="ARSoft.Tools.Net.Dns.DnsClient.BeginSendMessage"/>.</param> /// <returns>The complete response of the dns server</returns> public DnsMessage EndSendMessage(IAsyncResult ar) { DnsAsyncState state = (DnsAsyncState)ar; return(state.Response); }