static void Main(string[] args) { // Start P2P thread Thread p2pListener = new Thread(new ThreadStart(P2P.Run)); p2pListener.Start(); // Open UDP socket UdpClient listener = new UdpClient(listenPort); IPEndPoint groupEP; // Receive a packet try { byte[] recv_buf; while (true) { // Set listen address groupEP = new IPEndPoint(IPAddress.Any, listenPort); // Receive data, client will be placed in groupEP recv_buf = listener.Receive(ref groupEP); // Parse DNS data MemoryStream ms = new MemoryStream(recv_buf); BinaryReader br = new BinaryReader(ms); DNS_header header = new DNS_header(); header.Read(br); if (header.QDcount != 1) { Console.WriteLine("Cannot parse DNS request where QDcount != 1"); continue; } DNS_question question = new DNS_question(); question.Read(br); // Get the answer to the query byte[] ans_ip = new byte[4]; DNScache.resolve(question.name, ref ans_ip); // Send a response MemoryStream ms_out = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms_out); // Modify DNS header header.qr = true; header.rcode = 0; header.ANcount = 1; // Write DNS header header.Write(bw); // Write question question.Write(bw); // Generate answer DNS_answer answer = new DNS_answer(); answer.name = question.name; answer.atype = 1; answer.aclass = 1; answer.ttl = 60; answer.rdlen = 4; answer.rdata = ans_ip; // Write answer answer.Write(bw); // Send the packet byte[] buf_out = ms_out.ToArray(); listener.Send(buf_out, buf_out.Length, groupEP); } } catch (Exception e) { Console.WriteLine(e.ToString()); Console.ReadLine(); } p2pListener.Interrupt(); }
public static void Run() { UdpClient udpClient = new UdpClient(); udpClient.EnableBroadcast = true; IPEndPoint recv_groupep = new IPEndPoint(IPAddress.Any, _P2P_PORT); udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); udpClient.ExclusiveAddressUse = false; udpClient.Client.Bind(recv_groupep); while (true) { IPEndPoint recv_ipep = null; try { byte[] packet = udpClient.Receive(ref recv_ipep); MemoryStream ms = new MemoryStream(packet); BinaryReader br = new BinaryReader(ms); UInt32 id = br.ReadUInt32(); byte isRequest = br.ReadByte(); if (isRequest == 1) { string name = DNS.ReadName(br); DNScache.clean(); lock (DNScache._lock_cache) { if (DNScache._cache.ContainsKey(name)) { MemoryStream ms_res = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms_res); bw.Write(id); bw.Write((byte)0); DNScache.cache_entry ce = DNScache._cache[name]; if (ce.success) { bw.Write((byte)1); UInt32 ttl = (UInt32)((ce.expiry - DateTime.Now).TotalSeconds); bw.Write((UInt32)IPAddress.HostToNetworkOrder((int)ttl)); bw.Write(ce.address, 0, 4); } else { bw.Write((byte)0); UInt32 ttl = (UInt32)((ce.expiry - DateTime.Now).TotalSeconds); bw.Write((UInt32)IPAddress.HostToNetworkOrder((int)ttl)); bw.Write((byte)0); bw.Write((byte)0); bw.Write((byte)0); bw.Write((byte)0); } byte[] packet_res = ms_res.ToArray(); udpClient.Send(packet_res, packet_res.Length, recv_ipep); } } } } catch (ThreadInterruptedException ex) { return; } } }