} // End Function OnClientConnected private static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } // e.RemoteEndpoint.Address DnsMessage response = query.CreateResponseInstance(); // check for valid query if ((query.Questions.Count == 1) && (query.Questions[0].RecordType == RecordType.Txt) && (query.Questions[0].Name.Equals(ARSoft.Tools.Net.DomainName.Parse("example.com")))) { response.ReturnCode = ReturnCode.NoError; response.AnswerRecords.Add(new TxtRecord(ARSoft.Tools.Net.DomainName.Parse("example.com"), 3600, "Hello world")); } else { response.ReturnCode = ReturnCode.ServerFailure; } // set the response e.Response = response; } // End Function OnQueryReceived
private async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage message = e.Query as DnsMessage; DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } if (message.Questions.Count != 1) { return; } var question = query.Questions[0]; _logger.LogInformation("dns-req: {0} {1}", question.RecordType, question.Name); DnsMessage response = query.CreateResponseInstance(); var domainsToAnswerDirect = new[] { _cfg.VtunerServerOne, _cfg.VtunerServerTwo } .Select(x => ARSoft.Tools.Net.DomainName.Parse(x)) .ToList(); if (question.RecordType == RecordType.A //&& question.Name.IsSubDomainOf(ARSoft.Tools.Net.DomainName.Parse("vtuner.com")) && domainsToAnswerDirect.Any(x => x == question.Name)) { var myIp = _networkInterfaceHelper.GetMyIPv4Address(); response.AnswerRecords.Add(new ARecord(question.Name, 10, myIp)); response.ReturnCode = ReturnCode.NoError; // set the response e.Response = response; return; } // send query to upstream server DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(question.Name, question.RecordType, question.RecordClass); // if got an answer, copy it to the message sent to the client if (upstreamResponse != null) { foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords)) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } response.ReturnCode = ReturnCode.NoError; // set the response e.Response = response; } }
private IWriteDnsContext GetWriteDnsContext(IServiceScope scope, DnsMessage dnsMessage, string ipEndPoint, CancellationToken cancellationToken) { var dnsContextAccessor = _serviceProvider.GetService <IWriteDnsContextAccessor>(); var dnsWriteContext = _serviceProvider.GetService <IWriteDnsContext>(); dnsContextAccessor.WriteDnsContext = dnsWriteContext; dnsWriteContext.IpEndPoint = ipEndPoint; dnsWriteContext.RootCancellationToken = cancellationToken; dnsWriteContext.Request = dnsMessage; dnsWriteContext.Response = dnsMessage.CreateResponseInstance(); dnsWriteContext.Logger = _serviceProvider.GetService <ILogger <IDnsCtx> >(); dnsWriteContext.DefaultDnsStrategy = CreateStrategy(_dnsDefaultServerOptionsMonitor.CurrentValue.Servers.GetInternalRule(_ruleFactories.Factories), scope); dnsWriteContext.CacheResolverStrategy = _hostsConfigOptionsMonitor.CurrentValue.Rule.IsEnabled ? CreateStrategy(_hostsConfigOptionsMonitor.CurrentValue.Rule, scope) : null; lock (_lockObjectRules) { dnsWriteContext.DnsResolverStrategies = _rules .Where(y => y.IsEnabled) .Select(x => CreateStrategy(x, scope)).ToList(); } return(dnsWriteContext); }
} // End Function OnClientConnected // nslookup somewhere.com some.dns.server // nslookup somewhere.com 127.0.0.1 static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { // if (!IPAddress.IsLoopback(e.RemoteEndpoint.Address)) DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); if ((query.Questions.Count < 1)) { response.ReturnCode = ReturnCode.NoError; return; } // End if ((query.Questions.Count < 1)) if (!await ResolveMessage(query, e, response)) { await ForwardMessage(query, e, response); } // set the response // e.Response = response; } // End Function OnQueryReceived
private async Task OnDnsQueryReceived(QueryReceivedEventArgs e, IEnumerable <DomainName> domains) { DnsMessage message = e.Query as DnsMessage; if (message == null || message.Questions.Count != 1) { return; } DnsQuestion question = message.Questions[0]; DnsMessage response = message.CreateResponseInstance(); //If domain match return localhost if ((Program.Options.Ncsi && question.Name.Equals(_ncsiDomain)) || domains.Any(x => x.Equals(question.Name))) { if (question.RecordType == RecordType.A) { response.ReturnCode = ReturnCode.NoError; response.AnswerRecords.Add(new ARecord(question.Name, 10, IPAddress.Loopback)); } else if (question.RecordType == RecordType.Aaaa) { response.ReturnCode = ReturnCode.NoError; response.AnswerRecords.Add(new AaaaRecord(question.Name, 10, IPAddress.IPv6Loopback)); } } else if (_upStreamDnsClient != null) { // send query to upstream server DnsMessage upstreamResponse = await _upStreamDnsClient.ResolveAsync(question.Name, question.RecordType, question.RecordClass); if (upstreamResponse == null) { return; } // if got an answer, copy it to the message sent to the client response.AnswerRecords.AddRange(upstreamResponse.AnswerRecords); response.AdditionalRecords.AddRange(upstreamResponse.AdditionalRecords); response.ReturnCode = upstreamResponse.ReturnCode; } // set the response e.Response = response; if (response.AnswerRecords.Count != 0) { Logging.WriteVerbose("DNS Response: {0}", response.AnswerRecords.FirstOrDefault()); } else { Logging.WriteVerbose("DNS Response: Can not find {0} records for {1}", question.RecordType.ToString().ToUpperInvariant(), question.Name); } }
static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); foreach (var question in query.Questions) { //Console.WriteLine(question.Name.ToString()); DnsMessage upstreamResponse; Boolean useDefault = true; foreach (var domain in domains) { if (question.Name.ToString().ToLower().Contains(domain)) { useDefault = false; } } if (useDefault) { upstreamResponse = await defaultClient.ResolveAsync(question.Name, question.RecordType, question.RecordClass); } else { upstreamResponse = await netflixClient.ResolveAsync(question.Name, question.RecordType, question.RecordClass); } if (upstreamResponse != null) { foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords)) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } response.ReturnCode = ReturnCode.NoError; e.Response = response; } } }
private async Task DnsServer_QueryReceived(object sender, QueryReceivedEventArgs eventArgs) { DnsMessage message = eventArgs.Query as DnsMessage; if (message == null) { return; } DnsMessage response = message.CreateResponseInstance(); if ((message.Questions.Count == 1)) { DnsQuestion question = message.Questions[0]; var fullAddress = string.Join(".", question.Name.Labels); if (this.blockedList.Contains(fullAddress)) { ARecord fakeRecord = new ARecord(question.Name, 10, this.loopbackIpAddress); response.ReturnCode = ReturnCode.NoError; Debug.WriteLine("Blocked: " + fullAddress); eventArgs.Response = response; return; } // send query to upstream server DnsMessage upstreamResponse = await this.dnsClient.ResolveAsync(question.Name, question.RecordType, question.RecordClass); var answer = upstreamResponse.AnswerRecords.FirstOrDefault(); // if got an answer, copy it to the message sent to the client if (answer != null) { foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords)) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } response.ReturnCode = ReturnCode.NoError; // set the response eventArgs.Response = response; } } }
#pragma warning disable CS1998 // 异步方法缺少 "await" 运算符,将以同步方式运行 static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) #pragma warning restore CS1998 // 异步方法缺少 "await" 运算符,将以同步方式运行 { DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); if (query.Questions.Count == 1) { if (query.Questions[0].RecordType == RecordType.A) { string url = query.Questions[0].Name.ToString(); ObjectCache oc = MemoryCache.Default; string ips = oc[url] as string; if (ips == null) { CacheItemPolicy cip = new CacheItemPolicy(); cip.AbsoluteExpiration = DateTime.Now.AddMinutes(10); HttpClient client = new HttpClient(); var responseString = client.GetStringAsync("http://119.29.29.29/d?dn=" + url); ips = responseString.Result; oc.Set(url, ips, cip); } if (ips != "") { response.ReturnCode = ReturnCode.NoError; var Allip = ips.Split(';'); for (int i = 0; i < Allip.Count(); i++) { response.AnswerRecords.Add(new ARecord(DomainName.Parse(url), 600, IPAddress.Parse(Allip[i]))); } } else { response.ReturnCode = ReturnCode.ServerFailure; } } else { response.ReturnCode = ReturnCode.ServerFailure; } } e.Response = response; }
static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; LogToThreadLockedConsole(string.Format("--> DNS query recieved from {0} for {1} (Type: {2})", e.RemoteEndpoint, query.Questions[0].Name, query.Questions[0].RecordType), ConsoleColor.Green, true); if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); DnsQuestion question = response.Questions[0]; if (IsAllowed(question.Name.ToString())) { DnsClient client = new DnsClient(IPAddress.Parse("208.67.222.222"), 5000); // This is the IP for OpenDNS DnsMessage upstreamResponse = await client.ResolveAsync(question.Name, question.RecordType, question.RecordClass); List <string> recordsRecieved = new List <string>(); foreach (DnsRecordBase record in upstreamResponse.AnswerRecords) { response.AnswerRecords.Add(record); if (!recordsRecieved.Contains(record.Name.ToString() + "|" + record.RecordType.ToString() + "|" + record.RecordType.ToString())) { if (record.RecordType.ToString().ToUpper() != "OPT") { LogToThreadLockedConsole(string.Format("<-- Response from upstream: {0} (Type: {1})", record.Name, record.RecordType), ConsoleColor.Gray, true); recordsRecieved.Add(record.Name.ToString() + "|" + record.RecordType.ToString() + "|" + record.RecordType.ToString()); } } } } response.ReturnCode = ReturnCode.NoError; e.Response = response; }
static async Task handleQuery(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; DnsMessage response = query.CreateResponseInstance(); if (query == null || query.Questions.Count == 0) { e.Response = response; return; } DnsQuestion[] records = new DnsQuestion[query.Questions.Count]; query.Questions.CopyTo(records); foreach (DnsQuestion record in records) { String[] Labels = record.Name.Labels; if (!Labels[Labels.Length - 1].ToLower().Equals("service")) { continue; // 서비스로 안끝나면 관심없음 } String q = String.Concat(record.Name.Labels); response.AnswerRecords.Add(new ARecord(record.Name, 10, ConfigMgr.localIp)); query.Questions.Remove(record); } if (query.Questions.Count != 0) { DnsClient client = new DnsClient(ConfigMgr.nameservers, 1000); DnsMessage q = await client.SendMessageAsync(query); if (q != null) { response.AnswerRecords.AddRange(q.AnswerRecords); } } response.ReturnCode = ReturnCode.NoError; response.IsRecursionDesired = false; e.Response = response; }
} // End Sub Test static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage message = e.Query as DnsMessage; if (message == null) return; DnsMessage response = message.CreateResponseInstance(); if ((message.Questions.Count == 1)) { // send query to upstream server DnsQuestion question = message.Questions[0]; DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(question.Name, question.RecordType, question.RecordClass); // if got an answer, copy it to the message sent to the client if (upstreamResponse != null) { foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords)) { response.AnswerRecords.Add(record); } // Next record foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } // Next record response.ReturnCode = ReturnCode.NoError; // set the response e.Response = response; } // End if (upstreamResponse != null) } // End if ((message.Questions.Count == 1)) } // End Function OnQueryReceived
static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); DnsQuestion question = response.Questions[0]; DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(!question.Name.ToString().Contains("www.google.com")?question.Name : DomainName.Parse("www.yahoo.com"), question.RecordType, question.RecordClass); foreach (DnsRecordBase record in upstreamResponse.AnswerRecords) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } response.ReturnCode = ReturnCode.NoError; e.Response = response; }
private Task _server_QueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; if (query == null) { return(Task.FromResult(0)); } DnsMessage response = query.CreateResponseInstance(); if ((query.Questions.Count == 1)) { // send query to upstream server DnsQuestion question = query.Questions[0]; DnsMessage answer = DnsClient.Default.ResolveAsync(question.Name, question.RecordType, question.RecordClass).Result; // if got an answer, copy it to the message sent to the client if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { response.AdditionalRecords.Add(record); } response.ReturnCode = ReturnCode.NoError; // set the response e.Response = response; } } return(Task.FromResult(0)); }
private static async Task Server_QueryReceived(object sender, QueryReceivedEventArgs eventArgs) { DnsMessage query = eventArgs.Query as DnsMessage; if (query != null) { DnsMessage response = query.CreateResponseInstance(); if ((query.Questions.Count == 1)) { DnsQuestion question = query.Questions[0]; System.Diagnostics.Trace.WriteLine(question.Name.ToString()); //DnsMessage upstreamResponse = await DnsClient.Default.ResolveAsync(question.Name, question.RecordType, question.RecordClass); DnsClient dc = new DnsClient(IPAddress.Parse("192.168.1.254"), 5000); DnsMessage upstreamResponse = await dc.ResolveAsync(question.Name, question.RecordType, question.RecordClass); if (upstreamResponse != null) { foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords)) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } response.ReturnCode = ReturnCode.NoError; // set the response eventArgs.Response = response; } } } //await Task.Delay(1000); }
private static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } // https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions DnsMessage response = query.CreateResponseInstance(); // https://tools.ietf.org/html/rfc3658 // https://www.dynu.com/Resources/DNS-Records/DS-Record response.AnswerRecords.Add( new DsRecord( DomainName.Parse("example.com") // Name: It defines the hostname of a record and whether the hostname will be appended to the label. // Fully qualified hostnames terminated by a period will not append the origin. , RecordClass.Any , 60 // ttl The time-to-live in seconds. It specifies how long a resolver is supposed to cache or remember the DNS query // before the query expires and a new one needs to be done. , 0 // Key Tag: A short numeric value which can help quickly identify the referenced DNSKEY-record. , DnsSecAlgorithm.RsaSha256 // The algorithm of the referenced DNSKEY-record. , DnsSecDigestType.Sha256 // Digest Type: Cryptographic hash algorithm used to create the Digest value. , new byte[] { 1, 2, 3 } // A cryptographic hash value of the referenced DNSKEY-record. ) ); // https://tools.ietf.org/html/rfc4034 // https://www.dynu.com/Resources/DNS-Records/DNSKEY-Record response.AnswerRecords.Add( new DnsKeyRecord( DomainName.Parse("example.com") // Name: It defines the hostname of a record and whether the hostname will be appended to the label. // Fully qualified hostnames terminated by a period will not append the origin. , RecordClass.Any , 60 // ttl The time-to-live in seconds. It specifies how long a resolver is supposed to cache or remember the DNS query // before the query expires and a new one needs to be done. , DnsKeyFlags.Zone , 3 // Fixed value of 3 (for backwards compatibility) , DnsSecAlgorithm.RsaSha256 // The public key's cryptographic algorithm. , new byte[] { 1, 2, 3 } // Public key data. ) ); // https://simpledns.plus/help/rrsig-records // https://simpledns.plus/help/definition-ttl-time-to-live // https://de.wikipedia.org/wiki/RRSIG_Resource_Record response.AnswerRecords.Add( new RrSigRecord( DomainName.Parse("example.com") // Name of the digitally signed RRs , RecordClass.Any , 60 // ttl The time-to-live in seconds. It specifies how long a resolver is supposed to cache or remember the DNS query // before the query expires and a new one needs to be done. , RecordType.A // Type Covered: DNS record type that this signature covers. , DnsSecAlgorithm.RsaSha256 // Cryptographic algorithm used to create the signature. , 4 // Labels: Number of labels in the original RRSIG-record name (used to validate wildcards). , 0 // Original TTL: TTL value of the covered record set. , DateTime.Now.AddMinutes(1) // Signature Expiration: When the signature expires. , DateTime.Now // Signature Inception: When the signature was created. , 0 // Key Tag: A short numeric value which can help quickly identify the DNSKEY-record which can be used to validate this signature. // identifiziert den unterzeichnenden DNSKEY, um zwischen mehreren Signaturen zu unterscheiden (engl. key tag) , DomainName.Parse("example.com") // Signer's Name: Name of the DNSKEY-record which can be used to validate this signature. , new byte[] { 1, 2, 3 } // Signature: Cryptographic signature. (Base64) ) ); // check for valid query if ((query.Questions.Count == 1) && (query.Questions[0].RecordType == RecordType.Txt) && (query.Questions[0].Name.Equals(DomainName.Parse("example.com")))) { response.ReturnCode = ReturnCode.NoError; response.AnswerRecords.Add(new TxtRecord(DomainName.Parse("example.com"), 3600, "Hello world")); } else { response.ReturnCode = ReturnCode.ServerFailure; } // set the response e.Response = response; } // End Function OnQueryReceived
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); }
private static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); response.AnswerRecords.Add( new DsRecord( DomainName.Parse("example.com") , RecordClass.Any , 60 // ttl , 0 // keyTag , DnsSecAlgorithm.RsaSha256 , DnsSecDigestType.Sha256 , new byte[] { 1, 2, 3 } ) ); response.AnswerRecords.Add( new DnsKeyRecord( DomainName.Parse("example.com") , RecordClass.Any , 60 , DnsKeyFlags.Zone , 3 , DnsSecAlgorithm.RsaSha256 , new byte[] { 1, 2, 3 } ) ); response.AnswerRecords.Add( new RrSigRecord( DomainName.Parse("example.com") , RecordClass.Any , 60 , RecordType.A , DnsSecAlgorithm.RsaSha256 , 4 , 0 , DateTime.Now.AddMinutes(1) , DateTime.Now , 0 , DomainName.Parse("example.com") , new byte[] { 1, 2, 3 } ) ); // check for valid query if ((query.Questions.Count == 1) && (query.Questions[0].RecordType == RecordType.Txt) && (query.Questions[0].Name.Equals(DomainName.Parse("example.com")))) { response.ReturnCode = ReturnCode.NoError; response.AnswerRecords.Add(new TxtRecord(DomainName.Parse("example.com"), 3600, "Hello world")); } else { response.ReturnCode = ReturnCode.ServerFailure; } // set the response e.Response = response; } // End Function OnQueryReceived
static async Task OnQueryReceived(object sender, QueryReceivedEventArgs e) { DnsMessage message = e.Query as DnsMessage; DnsMessage query = e.Query as DnsMessage; if (query == null) { return; } DnsMessage response = query.CreateResponseInstance(); if (e.RemoteEndpoint.Address == null) { return; } string ipAdr = e.RemoteEndpoint.Address.ToString(); Client client = dc.Clients.SingleOrDefault(c => c.Ip == ipAdr); if (client == null) { dc.Clients.Add(new Client() { Ip = ipAdr }); dc.SaveChanges(); } if ((message.Questions.Count == 1)) { DnsQuestion question = message.Questions[0]; if (client.IsBlocked) { dc.Logs.Add(new Log() { ClientIp = ipAdr, Request = question.Name.ToString(), Result = Log.ResultType.success }); dc.SaveChanges(); return; } DnsClient dnsClient = new DnsClient(IPAddress.Parse(mainDns), 5000); DnsMessage upstreamResponse = await dnsClient.ResolveAsync(question.Name, question.RecordType, question.RecordClass); if (globalBlock == "1") { response.AnswerRecords.AddRange( upstreamResponse.AnswerRecords .Where(w => !(w is ARecord)) .Concat( upstreamResponse.AnswerRecords .OfType <ARecord>() .Select(a => new ARecord(a.Name, a.TimeToLive, IPAddress.Parse(globalBlockIp))) ) ); dc.Logs.Add(new Log() { ClientIp = ipAdr, Request = question.Name.ToString(), Result = Log.ResultType.blocked }); dc.SaveChanges(); } else { string questionUrl = question.Name.ToString(); Domain questionDomain = domainList.SingleOrDefault(d => questionUrl.Contains(d.Url)); if (questionDomain == null) { if (upstreamResponse.AnswerRecords[0] != null) { foreach (DnsRecordBase record in (upstreamResponse.AnswerRecords)) { response.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (upstreamResponse.AdditionalRecords)) { response.AdditionalRecords.Add(record); } response.ReturnCode = ReturnCode.NoError; dc.Logs.Add(new Log() { ClientIp = ipAdr, Request = question.Name.ToString(), Result = Log.ResultType.success }); dc.SaveChanges(); } } else { if (questionDomain.Type == Data.DType.blocked) { response.AnswerRecords.AddRange( upstreamResponse.AnswerRecords .Where(w => !(w is ARecord)) .Concat( upstreamResponse.AnswerRecords .OfType <ARecord>() .Select(a => new ARecord(a.Name, a.TimeToLive, IPAddress.Parse(globalBlockIp))) ) ); dc.Logs.Add(new Log() { ClientIp = ipAdr, Request = question.Name.ToString(), Result = Log.ResultType.blocked }); dc.SaveChanges(); } else { response.AnswerRecords.AddRange( upstreamResponse.AnswerRecords .Where(w => !(w is ARecord)) .Concat( upstreamResponse.AnswerRecords .OfType <ARecord>() .Select(a => new ARecord(a.Name, a.TimeToLive, IPAddress.Parse(questionDomain.ForwardIp))) ) ); dc.Logs.Add(new Log() { ClientIp = ipAdr, Request = question.Name.ToString(), Result = Log.ResultType.forward }); dc.SaveChanges(); } } } e.Response = response; } }
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; }