private void OnReceive(IAsyncResult ar) { lock (this) { int length; try { if (_socket == null) { return; } length = _socket.EndReceive(ar); } catch (Exception) { return; } var stream = new MemoryStream(_buffer, 0, length); var reader = new DnsMessageReader(stream); Header header = reader.ReadHeader(); if (header.IsQuery && header.AnswerCount == 0) { for (int i = 0; i < header.QuestionCount; i++) { Question question = reader.ReadQuestion(); Name serviceName = question.QName; if (_serviceHandlers.ContainsKey(serviceName)) { if (header.TransactionID != _lastQueryId) { OnServiceQuery(serviceName); } } } } if (header.IsResponse && header.IsNoError && header.IsAuthorativeAnswer) { for (int i = 0; i < header.QuestionCount; i++) { reader.ReadQuestion(); } _packetServiceInfos.Clear(); _packetHostAddresses.Clear(); for (int i = 0; i < (header.AnswerCount + header.AuthorityCount + header.AdditionalCount); i++) { RecordHeader recordHeader = reader.ReadRecordHeader(); if ((recordHeader.Type == RecordType.A) || (recordHeader.Type == RecordType.AAAA)) // A or AAAA { IPAddress address = reader.ReadARecord(); if (address.AddressFamily == AddressFamily.InterNetworkV6) { if (!NetworkInterface.Information.Supports(NetworkInterfaceComponent.IPv6)) { continue; } // Mono does not support IPv6 properties and always throws NotImplementedException. // Lets handle the case as with Supports. try { address.ScopeId = NetworkInterface.Information.GetIPProperties().GetIPv6Properties().Index; } catch (NotImplementedException) { continue; } } OnARecord(recordHeader.Name, address, recordHeader.Ttl); } else if ((recordHeader.Type == RecordType.SRV) || (recordHeader.Type == RecordType.TXT) || (recordHeader.Type == RecordType.PTR)) { Name serviceName; Name instanceName; if (recordHeader.Type == RecordType.PTR) { serviceName = recordHeader.Name; instanceName = reader.ReadPtrRecord(); } else { instanceName = recordHeader.Name; serviceName = instanceName.SubName(1); } if (_serviceHandlers.ContainsKey(serviceName)) { if (recordHeader.Ttl == 0) { PacketRemovesService(instanceName); } else { ServiceInfo service = FindOrCreatePacketService(instanceName); if (recordHeader.Type == RecordType.SRV) { SrvRecord srvRecord = reader.ReadSrvRecord(); service.HostName = srvRecord.Target; service.Port = srvRecord.Port; } else if (recordHeader.Type == RecordType.TXT) { List<string> txts = reader.ReadTxtRecord(); service.Txt = txts; } } } } } HandlePacketHostAddresses(); HandlePacketServiceInfos(); } StartReceive(); } }
private void OnReceive(IAsyncResult ar) #endif { lock (this) { #if NETSTANDARD1_3 if (args.SocketError != SocketError.Success || _socket == null) { return; } int length = args.BytesTransferred; #else int length; try { if (_socket == null) { return; } length = _socket.EndReceive(ar); } catch (Exception) { return; } #endif var stream = new MemoryStream(_buffer, 0, length); var reader = new DnsMessageReader(stream); bool validPacket = true; _packetServiceInfos.Clear(); _packetHostAddresses.Clear(); try { Header header = reader.ReadHeader(); if (header.IsQuery && header.AnswerCount == 0) { for (int i = 0; i < header.QuestionCount; i++) { Question question = reader.ReadQuestion(); Name serviceName = question.QName; if (_serviceHandlers.ContainsKey(serviceName)) { if (header.TransactionID != _lastQueryId) { OnServiceQuery(serviceName); } } } } if (header.IsResponse && header.IsNoError) { for (int i = 0; i < header.QuestionCount; i++) { reader.ReadQuestion(); } for (int i = 0; i < (header.AnswerCount + header.AuthorityCount + header.AdditionalCount); i++) { RecordHeader recordHeader = reader.ReadRecordHeader(); if ((recordHeader.Type == RecordType.A) || (recordHeader.Type == RecordType.AAAA)) // A or AAAA { IPAddress address = reader.ReadARecord(); if (address.AddressFamily == AddressFamily.InterNetworkV6) { if (!NetworkInterface.Supports(NetworkInterfaceComponent.IPv6)) { continue; } // Mono does not support IPv6 properties and always throws NotImplementedException. // Lets handle the case as with Supports. try { address.ScopeId = NetworkInterface.GetIPProperties().GetIPv6Properties().Index; } catch (NotImplementedException) { continue; } } OnARecord(recordHeader.Name, address, recordHeader.Ttl); } else if ((recordHeader.Type == RecordType.SRV) || (recordHeader.Type == RecordType.TXT) || (recordHeader.Type == RecordType.PTR)) { Name serviceName; Name instanceName; if (recordHeader.Type == RecordType.PTR) { serviceName = recordHeader.Name; instanceName = reader.ReadPtrRecord(); } else { instanceName = recordHeader.Name; serviceName = instanceName.SubName(1); } if (_serviceHandlers.ContainsKey(serviceName)) { if (recordHeader.Ttl == 0) { PacketRemovesService(instanceName); } else { ServiceInfo service = FindOrCreatePacketService(instanceName); if (recordHeader.Type == RecordType.SRV) { SrvRecord srvRecord = reader.ReadSrvRecord(); service.HostName = srvRecord.Target; service.Port = srvRecord.Port; } else if (recordHeader.Type == RecordType.TXT) { List <string> txts = reader.ReadTxtRecord(); service.Txt = txts; } } } } } } } catch { validPacket = false; } if (validPacket) { HandlePacketHostAddresses(); HandlePacketServiceInfos(); } StartReceive(); } }