/// <summary> /// Construct a new Dns Question /// </summary> public DnsRequest(DnsQuestion question) : base(question) { this.Header.IsRequest = true; this.Header.IsTruncated = false; this.Header.ResponseCode = DnsStandard.ResponseCode.Success; }
public InfiniteForwardingException(DnsQuestion question) { Question = question; }
/// <summary> /// This method always returns a failed result. /// </summary> /// <param name="question">The question.</param> /// <returns>The <see cref="AK.Net.Dns.DnsCacheResult"/> if the operation.</returns> /// <exception cref="System.ArgumentNullException"> /// Thrown when <paramref name="question"/> is <see langword="null"/>. /// </exception> public DnsCacheResult Get(DnsQuestion question) { Guard.NotNull(question, "question"); return(DnsCacheResult.Failed); }
public Task <DnsResourceRecord> this[DnsQuestion question] => Cache[question].ContinueWith(t => t.Result.ToResourceRecord(question));
/// <summary> /// Provide dummy answers for DNS questions /// </summary> /// <param name="question"></param> /// <returns></returns> public override void HandleQuestion(DnsQuestion question, ref List<DnsAnswer> answerList) { //query.GeoLocation.ToString(); if (question.ZoneType == DnsZoneType.SOA || question.ZoneType == DnsZoneType.ANY) { //Console.WriteLine("SOA RECORD"); answerList.Add(new DnsAnswer(question) { Record = new SoaDnsRecord(900, "ns1.bunnydns.com", "hostmaster.bunnydns.com", 1, 7200, 3600, 1209600, 3600), }); } if (question.ZoneType == DnsZoneType.A || question.ZoneType == DnsZoneType.ANY) { //Console.WriteLine("A RECORD"); answerList.Add(new DnsAnswer(question) { Record = new ADnsRecord(30, IPAddress.Parse("23.249.224.31")), }); } if (question.ZoneType == DnsZoneType.MX || question.ZoneType == DnsZoneType.ANY) { //Console.WriteLine("MX RECORD"); answerList.Add(new DnsAnswer(question) { Record = new MxRecord(30, 1, "ASPMX.L.GOOGLE.com"), }); answerList.Add(new DnsAnswer(question) { Record = new MxRecord(30, 5, "ALT1.ASPMX.L.GOOGLE.com"), }); } // Only do this if NS are requested if (question.ZoneType == DnsZoneType.NS || question.ZoneType == DnsZoneType.ANY) { //Console.WriteLine("NS RECORD"); answerList.Add(new DnsAnswer(question) { Record = new NsDnsRecord(3600, "ns1.bunnydns.com") }); answerList.Add(new DnsAnswer(question) { Record = new NsDnsRecord(3600, "ns2.bunnydns.com") }); } else if (answerList.Count > 0) { //Console.WriteLine("AUTHORITY NS RECORD"); answerList.Add(new DnsAnswer(question) { Record = new NsDnsRecord(3600, "ns1.bunnydns.com") { IsAuthorityRecord = true, } }); answerList.Add(new DnsAnswer(question) { Record = new NsDnsRecord(3600, "ns2.bunnydns.com") { IsAuthorityRecord = true, } }); } }
private static void WriteQuestion(MemoryStream ms, DnsQuestion question) { WriteLabels(ms, question.QNameLabels); WriteUShort(ms, (ushort)question.QType); WriteUShort(ms, (ushort)question.QClass); }
public static ResourceRecord FromQuestion(DnsQuestion question, byte[] data, TimeSpan ttl = default(TimeSpan)) { return(new ResourceRecord(question.Name, data, question.Type, question.Class, ttl)); }
private async Task <DnsMessage> umleitung_process_request(DnsMessage query) { DnsMessage upstreamResponse; DnsMessage response = query.CreateResponseInstance(); DomainName queryhost = DomainName.Parse(query.Questions[0].Name.ToString()); if ((query.Questions.Count == 1)) { m_log.WriteLine("[+] Processing " + query.Questions[0].RecordType + " query for " + queryhost); Boolean match = false; IPAddress ip4 = null; IPAddress ip6 = null; // handle masqueraded entries first m_masq_config.DNSMasqEntries.ForEach(h => { if (queryhost.ToString().StartsWith(h.name)) { match = true; m_log.WriteLine(2, "[d] Using masquerading rules."); response.ReturnCode = ReturnCode.NoError; if (query.Questions[0].RecordType == RecordType.A) { ip4 = IPAddress.Parse(h.a); ARecord new_a = new ARecord(query.Questions[0].Name, 666, ip4); response.AnswerRecords.Add(new_a); } else if (query.Questions[0].RecordType == RecordType.Aaaa) { ip6 = IPAddress.Parse(h.aaaa); AaaaRecord new_aaaa = new AaaaRecord(query.Questions[0].Name, 666, ip6); response.AnswerRecords.Add(new_aaaa); } } }); if (match) { return(response); } // send query to upstream server DnsQuestion question = query.Questions[0]; if (!m_props.UseCustomDns) { m_log.WriteLine(2, "[d] Using system's DNS servers"); upstreamResponse = await DnsClient.Default.ResolveAsync( question.Name, question.RecordType, question.RecordClass); } else { m_props.CustomDnsServers.ForEach(d => { m_log.WriteLine(2, "[d] Using custom DNS servers: " + d.ToString()); }); DnsClient dnsc = new DnsClient(m_props.CustomDnsServers, 10000); upstreamResponse = await dnsc.ResolveAsync( question.Name, question.RecordType, question.RecordClass); } // if we got an answer, copy it to the message sent to the client if (upstreamResponse != null && upstreamResponse.AnswerRecords.Count > 0) { foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords)) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } } else { // no dns record for queried host if (upstreamResponse == null) { m_log.WriteLine(2, "upstreamResponse == null (timeout?)"); } } response.ReturnCode = ReturnCode.NoError; } return(response); }
static DnsMessageBase onDnsQuery(DnsMessageBase message, System.Net.IPAddress clientAddress, ProtocolType protocol) { message.IsQuery = false; DnsMessage query = message as DnsMessage; DnsMessage answer = null; if ((query != null) && (query.Questions.Count == 1)) { //HOOK: //resolve whatsapp.net subdomains if (query.Questions[0].RecordType == RecordType.A && ( query.Questions[0].Name == WA_CERT_HOST || query.Questions[0].Name == WA_REG_HOST || ( //media files query.Questions[0].Name.StartsWith("mms") && query.Questions[0].Name.EndsWith("whatsapp.net") ) ) ) { query.ReturnCode = ReturnCode.NoError; System.Net.IPAddress localIP = GetIP(); if (localIP != null) { query.AnswerRecords.Add(new ARecord(query.Questions[0].Name, 30, localIP)); return(query); } } // send query to upstream server try { DnsQuestion question = query.Questions[0]; answer = DnsClient.Default.Resolve(question.Name, question.RecordType, question.RecordClass); // if got an answer, copy it to the message sent to the client if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { query.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { query.AnswerRecords.Add(record); } query.ReturnCode = ReturnCode.NoError; return(query); } } catch (Exception e) { } } // Not a valid query or upstream server did not answer correct message.ReturnCode = ReturnCode.ServerFailure; return(message); }
private DnsMessage GetDotBitAnswerForName(DnsQuestion question) { string fqdn = question.Name; try { recursionLevel++; if (recursionLevel > maxRecursion) { ConsoleUtils.WriteWarning("Max recursion reached"); return(null); } DomainValue value = GetDomainValue(fqdn); if (value == null) { return(null); } if (!string.IsNullOrWhiteSpace(value.@Delegate)) { ConsoleUtils.WriteWarning("delegate setting not implemented: {0}", value.@Delegate); } value.ImportDefaultMap(); if (!string.IsNullOrWhiteSpace(value.Translate)) { string newLookup; if (value.Translate.EndsWith(".")) { newLookup = value.Translate.Substring(0, value.Translate.Length - 1); } else { newLookup = value.Translate + '.' + fqdn; } DnsQuestion newQuestion = new DnsQuestion(newLookup, question.RecordType, question.RecordClass); return(InternalGetAnswer(newQuestion)); } DnsMessage answer = null; if (value.Alias != null) { string newLookup; if (value.Alias == "") { var sa = fqdn.Split('.'); newLookup = string.Format("{0}.{1}", sa[sa.Length - 2], sa[sa.Length - 1]); } else if (value.Alias.EndsWith(".")) // absolute { newLookup = value.Alias.Substring(0, value.Alias.Length - 1); } else // sub domain { var sa = fqdn.Split('.'); sa[0] = value.Alias; newLookup = string.Join(".", sa); } DnsQuestion newQuestion = new DnsQuestion(newLookup, question.RecordType, question.RecordClass); DnsMessage toReturn = new DnsMessage(); toReturn.AnswerRecords.Add(new CNameRecord(fqdn, defaultTTL, newLookup)); var additional = InternalGetAnswer(newQuestion); toReturn.AdditionalRecords = additional.AnswerRecords; return(toReturn); } answer = new DnsMessage() { Questions = new List <DnsQuestion>() { question } }; bool any = question.RecordType == RecordType.Any; var nsnames = value.Ns; if (nsnames != null && nsnames.Count() > 0) // NS overrides all { List <IPAddress> nameservers = GetNameserverAddresses(nsnames); if (nameservers.Count() > 0) { if (!string.IsNullOrWhiteSpace(value.Translate)) { fqdn = value.Translate; } answer = NameServer.DnsResolve(nameservers, fqdn, question.RecordType, question.RecordClass); } } else { if (any || question.RecordType == RecordType.A) { var addresses = value.Ips; if (addresses.Count() > 0) { foreach (var address in addresses) { answer.AnswerRecords.Add(new ARecord(fqdn, defaultTTL, address)); } } } if (any || question.RecordType == RecordType.Aaaa) { var addresses = value.Ip6s; if (addresses.Count() > 0) { foreach (var address in addresses) { answer.AnswerRecords.Add(new AaaaRecord(fqdn, defaultTTL, address)); } } } } return(answer); } finally { recursionLevel--; } }
//private void StoreInCache(DnsQuestion dnsQuestion, List<DnsRecordBase> data, // MemoryCacheEntryOptions cacheEntryOptions) //{ // _cacheManager.StoreInCache(dnsQuestion, data, cacheEntryOptions); //} private void StoreInCache(DnsQuestion dnsQuestion, List <DnsRecordBase> data) { _cacheManager.StoreInCache(dnsQuestion, data); }
public DnsMessage GetAnswer(DnsQuestion question) { lock (lockResolver) return(InternalGetAnswer(question)); }
private void CheckIPAllowedAccess(IPAddress clientAddress, DnsQuestion question) { //impliment client ip checking - throw exception if not allowed. }
private bool IsRedicted(DnsQuestion question) { return((question.Name.Contains(_redirectRecord) || string.IsNullOrEmpty(_redirectRecord)) && question.RecordType == RecordType.A); }
private bool ForwardMessage(DnsMessage message, IPEndPoint revicepoint, byte[] buf, IPEndPoint targetNameServer, int queryTimeout, bool useCompressionMutation) { DnsQuestion question = null; if (message.Questions.Count > 0) { question = message.Questions[0]; } byte[] responseBuffer = null; try { if ((Equals(targetNameServer.Address, IPAddress.Loopback) || Equals(targetNameServer.Address, IPAddress.IPv6Loopback)) && targetNameServer.Port == ((IPEndPoint)_UdpListener.Client.LocalEndPoint).Port) { throw new InfiniteForwardingException(question); } byte[] sendBuffer; if (useCompressionMutation) { message.Encode(false, out sendBuffer, true); } else { sendBuffer = buf; } _transactionClients[message.TransactionID] = revicepoint; // Send to Forwarder /*await _udpForwarder.SendAsync(sendBuffer, sendBuffer.Length, targetNameServer);*/ _UdpForwarder.Send(sendBuffer, sendBuffer.Length, targetNameServer); if (_transactionTimeoutCancellationTokenSources.ContainsKey(message.TransactionID)) { _transactionTimeoutCancellationTokenSources[message.TransactionID].Cancel(); } MrTe.Threading.Tasks.CancellationTokenSource cancellationTokenSource = new MrTe.Threading.Tasks.CancellationTokenSource(); _transactionTimeoutCancellationTokenSources[message.TransactionID] = cancellationTokenSource; return(true); // Timeout task to cancel the request /*try * {*/ /*await Task.Delay(queryTimeout, cancellationTokenSource.Token);*/ Task.Delay(queryTimeout, cancellationTokenSource.Token); if (!_transactionClients.ContainsKey(message.TransactionID)) { return(false); } IPEndPoint ignoreEndPoint; MrTe.Threading.Tasks.CancellationTokenSource ignoreTokenSource; /* * _transactionClients.TryRemove(message.TransactionID, out ignoreEndPoint); * _transactionTimeoutCancellationTokenSources.TryRemove(message.TransactionID, * out ignoreTokenSource); */ ignoreEndPoint = _transactionClients[message.TransactionID]; ignoreTokenSource = _transactionTimeoutCancellationTokenSources[message.TransactionID]; string warningText = message.Questions.Count > 0 ? message.Questions[0].Name + " (Type " + message.Questions[0].RecordType + ")" : "Transaction #" + message.TransactionID + ""; Logger.Warning("Query timeout for: {0}", warningText); _transactionClients.Remove(message.TransactionID); _transactionTimeoutCancellationTokenSources.Remove(message.TransactionID); /* * } * catch (TaskCanceledException) * { * } */ } catch (InfiniteForwardingException e) { Logger.Warning("[Forwarder.Send] Infinite forwarding detected for: {0} (Type {1})", e.Question.Name, e.Question.RecordType); Utils.ReturnDnsMessageServerFailure(message, out responseBuffer); } catch (SocketException e) { if (e.SocketErrorCode == SocketError.ConnectionReset) // Target name server port unreachable { Logger.Warning("[Forwarder.Send] Name server port unreachable: {0}", targetNameServer); } else { Logger.Error("[Forwarder.Send] Unhandled socket error: {0}", e.Message); } Utils.ReturnDnsMessageServerFailure(message, out responseBuffer); } catch (Exception e) { Logger.Error("[Forwarder] Unexpected exception:\n{0}", e); Utils.ReturnDnsMessageServerFailure(message, out responseBuffer); } // If we got some errors if (responseBuffer != null) { /*await _udpListener.SendAsync(responseBuffer, responseBuffer.Length, originalUdpMessage.RemoteEndPoint);*/ _UdpListener.Send(responseBuffer, responseBuffer.Length, revicepoint); } return(true); }
DnsMessageBase ProcessQuery(DnsMessageBase message, IPAddress clientAddress, ProtocolType protocol) { message.IsQuery = false; DnsMessage query = message as DnsMessage; ret1 : repcnt++; if ((query != null) && (query.Questions.Count == 1)) { // send query to upstream server DnsQuestion question = query.Questions[0]; Random rnd = new Random(); ret2 : if (enb == null) { InitDNS(); goto ret2; } else { //if (question.Name.Contains("xaapi")) //{ // message.ReturnCode = ReturnCode.ServerFailure; // return message; //} var tt = from q in hash where q.key == question.Name select q; if (tt.Any()) { tts = DateTime.Now - tt.ToList()[0].lastupdtime; if (tts.TotalHours > 12) { tt.ToList()[0].answer = null; } //WriteToConsole(question.Name + " returned from hash"); if (tt.ToList()[0].answer != null) { tt.ToList()[0].selected++; return(tt.ToList()[0].answer); } } WriteToConsole(question.Name); templ.Clear(); for (int i = 0; i < retcnt; i++) { ret3 : var q = WeightedRandomization.Choose(enb); if (!templ.Contains(q)) { templ.Add(q); } else { goto ret3; } } System.Threading.Tasks.Parallel.ForEach(templ, (site, state) => { WriteToConsole("Get Info for " + question.Name + " from: " + site.IP); DnsClient cd = new DnsClient(IPAddress.Parse(site.IP), 1000); DnsMessage answer = cd.Resolve(question.Name, question.RecordType, question.RecordClass); if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { lock (query) { query.AnswerRecords.Add(record); } site.Selects++; } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { lock (query) { query.AnswerRecords.Add(record); } site.Selects++; } lock (query) { //site.Weight--; query.ReturnCode = ReturnCode.NoError; } if (tt.Any()) { tt.ToList()[0].answer = query; tt.ToList()[0].lastupdtime = DateTime.Now; tt.ToList()[0].selected++; } else { var t = new hashitem(question.Name, query); lock (hash) { hash.Add(t); if (frst) { qsample = question; frst = false; } } } state.Break(); } }); System.Threading.Tasks.Parallel.ForEach(templ, (site, state) => { WriteToConsole("Get Info from: " + site.IP); DnsClient cd = new DnsClient(IPAddress.Parse(site.IP), 1000); DnsMessage answer = cd.Resolve(question.Name, question.RecordType, question.RecordClass); if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { lock (query) { query.AnswerRecords.Add(record); } site.Selects++; WriteToConsole(record.Name); } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { lock (query) { query.AnswerRecords.Add(record); } site.Selects++; WriteToConsole(record.Name); } lock (query) { site.Weight--; query.ReturnCode = ReturnCode.NoError; state.Break(); } } }); } // if got an answer, copy it to the message sent to the client } if (query.ReturnCode == ReturnCode.NoError) { return(query); } if (repcnt > 5) { message.ReturnCode = ReturnCode.ServerFailure; return(message); } else { goto ret1; } }
private async Task ForwardMessage(DnsMessage message, UdpReceiveResult originalUdpMessage, IPEndPoint targetNameServer, int queryTimeout, bool useCompressionMutation) { DnsQuestion question = null; if (message.Questions.Count > 0) { question = message.Questions[0]; } byte[] responseBuffer = null; try { if ((Equals(targetNameServer.Address, IPAddress.Loopback) || Equals(targetNameServer.Address, IPAddress.IPv6Loopback)) && targetNameServer.Port == ((IPEndPoint)_udpListener.Client.LocalEndPoint).Port) { throw new InfiniteForwardingException(question); } byte[] sendBuffer; if (useCompressionMutation) { message.Encode(false, out sendBuffer, true); } else { sendBuffer = originalUdpMessage.Buffer; } _transactionClients[message.TransactionID] = originalUdpMessage.RemoteEndPoint; // Send to Forwarder await _udpForwarder.SendAsync(sendBuffer, sendBuffer.Length, targetNameServer); if (_transactionTimeoutCancellationTokenSources.ContainsKey(message.TransactionID)) { _transactionTimeoutCancellationTokenSources[message.TransactionID].Cancel(); } var cancellationTokenSource = new CancellationTokenSource(); _transactionTimeoutCancellationTokenSources[message.TransactionID] = cancellationTokenSource; // Timeout task to cancel the request try { await Task.Delay(queryTimeout, cancellationTokenSource.Token); if (!_transactionClients.ContainsKey(message.TransactionID)) { return; } IPEndPoint ignoreEndPoint; CancellationTokenSource ignoreTokenSource; _transactionClients.TryRemove(message.TransactionID, out ignoreEndPoint); _transactionTimeoutCancellationTokenSources.TryRemove(message.TransactionID, out ignoreTokenSource); var warningText = message.Questions.Count > 0 ? $"{message.Questions[0].Name} (Type {message.Questions[0].RecordType})" : $"Transaction #{message.TransactionID}"; Logger.Warning("Query timeout for: {0}", warningText); } catch (TaskCanceledException) { } } catch (InfiniteForwardingException e) { Logger.Warning("[Forwarder.Send] Infinite forwarding detected for: {0} (Type {1})", e.Question.Name, e.Question.RecordType); Utils.ReturnDnsMessageServerFailure(message, out responseBuffer); } catch (SocketException e) { if (e.SocketErrorCode == SocketError.ConnectionReset) // Target name server port unreachable { Logger.Warning("[Forwarder.Send] Name server port unreachable: {0}", targetNameServer); } else { Logger.Error("[Forwarder.Send] Unhandled socket error: {0}", e.Message); } Utils.ReturnDnsMessageServerFailure(message, out responseBuffer); } catch (Exception e) { Logger.Error("[Forwarder] Unexpected exception:\n{0}", e); Utils.ReturnDnsMessageServerFailure(message, out responseBuffer); } // If we got some errors if (responseBuffer != null) { await _udpListener.SendAsync(responseBuffer, responseBuffer.Length, originalUdpMessage.RemoteEndPoint); } }
public DnsRequestMessage(DnsRequestHeader header, DnsQuestion question) { Header = header; Question = question; }
/// <summary> /// Returns a list of DnsAnswer objects that will be returned for the given question /// </summary> /// <param name="question"></param> /// <returns></returns> public abstract void HandleQuestion(DnsQuestion question, ref List<DnsAnswer> answerList);
private async Task Server_QueryReceived(object sender, ARSoft.Tools.Net.Dns.QueryReceivedEventArgs e) { bool foundQuery = false; DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); try { C.WriteLine($"DnsServer: Questions: {query.Questions.Count}", true, "DNS"); for (int idx = 0; idx < query.Questions.Count; idx++) { var question = query.Questions[idx]; using (var connection = db.Connection()) { using (var command = new SqliteCommand( "SELECT * FROM DnsEntries WHERE RecordType = @RecordType AND RecordClass = @RecordClass AND DomainName = @DomainName;", connection)) { command.Parameters.AddWithValue("@RecordType", question.RecordType.ToString()); command.Parameters.AddWithValue("@RecordClass", question.RecordClass.ToString()); command.Parameters.AddWithValue("@DomainName", question.Name.ToString()); using (var reader = command.ExecuteReader()) { C.WriteLine($" Questions [{idx:000}] RES({reader.HasRows}): Type({question.RecordType}), Class({question.RecordClass}), {question.Name}", true, "DNS"); //Every new row will create a new dictionary that holds the columns while (reader.Read()) { try { var dnStr = reader["DomainName"] as string; var dn = DomainName.Parse(dnStr); if (dn == null) { continue; } var ttl = (System.Int64)reader["TTL"]; var rt = (RecordType)Enum.Parse(typeof(RecordType), reader["RecordType"] as string); var rc = (RecordClass)Enum.Parse(typeof(RecordClass), reader["RecordClass"] as string); if (rt == RecordType.A) { if (reader["Address"] == null) { continue; } var addr = reader["Address"] as string; var aRec = new ARecord(dn, Convert.ToInt32(ttl), IPAddress.Parse(addr)); response.AnswerRecords.Add(aRec); foundQuery = true; } } catch (Exception ex) { C.WriteLine($" Questions [{idx:000}]: {C.Red}Exception: {ex.ToString()}", true, "DNS:ERROR"); } } } } } } // Fallback if (dnsFallback != null && !foundQuery) { DnsQuestion question = query.Questions[0]; var resolve = dnsFallback.Resolve(question.Name); DnsMessage upstreamResponse = await dnsFallback.ResolveAsync( question.Name, question.RecordType, question.RecordClass); e.Response = upstreamResponse; return; } response.ReturnCode = ReturnCode.NoError; } catch (Exception ex) { response.ReturnCode = ReturnCode.ServerFailure; C.WriteLine($"{C.Red}{ex.ToString()}", true, "DNS:ERROR"); } // set the response e.Response = response; }