void ReadCallback(IAsyncResult iar) { IPEndPoint endPoint = new IPEndPoint(Address, Port); byte[] data = Listener.EndReceive(iar, ref endPoint); Listener.BeginReceive(ReadCallback, null); DnsPacket packet = new DnsPacket(data); List <Task <DnsResourceRecord> > answers = new List <Task <DnsResourceRecord> >(); foreach (DnsQuestion question in packet.Questions) { if (question.QueryName.EndsWith(".proxyconfigurer.localhost")) { string query = question.QueryName.Substring(0, question.QueryName.Length - ".proxyconfigurer.localhost".Length); string[] parts = query.Split('.'); string last = parts[parts.Length - 1]; ushort nonce; if (last.StartsWith('n') && ushort.TryParse(last.Substring(1), out nonce)) { if (parts[0] == "p") { answers.Add(Handler.GetConfigurationPacket(nonce).ContinueWith(t => new DnsResourceRecord { Name = question.QueryName, Type = question.Type, Class = question.Class, TimeToLive = t.Result.Item2, Data = t.Result.Item1 })); } else { answers.Add(Handler.ResolveHost(nonce, int.Parse(parts[0].Substring(1))).ContinueWith(t => { Task <DnsResourceRecord> task = Cache[new DnsQuestion { QueryName = t.Result.Item1, Type = question.Type, Class = question.Class }]; task.Wait(); task.Result.Name = question.QueryName; task.Result.TimeToLive = Math.Min(task.Result.TimeToLive, t.Result.Item2); return(task.Result); })); } } else { answers.Add(Handler.GetFirstConfigurationPacket(query).ContinueWith(t => new DnsResourceRecord { Name = question.QueryName, Type = question.Type, Class = question.Class, TimeToLive = t.Result.Item2, Data = t.Result.Item1 })); } } else { answers.Add(Cache[question]); } Console.WriteLine("Query for {0}", question.QueryName); } Task.WhenAll(answers).ContinueWith(t => { byte[] pkt = new DnsPacket { Identification = packet.Identification, QueryResponse = true, Questions = packet.Questions, Answers = t.Result }.ToByteArray(); Listener.Send(pkt, pkt.Length, endPoint); }); }