//===----------------------------------------------------------------------===// // Copyright © 2025 Apple Inc. and the container project authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //===----------------------------------------------------------------------===// import Foundation import NIOCore import NIOPosix extension DNSServer { /// Handles the DNS request. /// - Parameters: /// - outbound: The NIOAsyncChannelOutboundWriter for which to respond. /// - packet: The request packet. func handle( outbound: NIOAsyncChannelOutboundWriter>, packet: inout AddressedEnvelope ) async throws { let chunkSize = 512 var data = Data() self.log?.debug("reading data") while packet.data.readableBytes > 0 { if let chunk = packet.data.readBytes(length: min(chunkSize, packet.data.readableBytes)) { data.append(contentsOf: chunk) } } self.log?.debug("deserializing message") let query = try Message(deserialize: data) self.log?.debug("processing query: \(query.questions)") // always send response let responseData: Data do { self.log?.debug("awaiting processing") var response = try await handler.answer(query: query) ?? Message( id: query.id, type: .response, returnCode: .notImplemented, questions: query.questions, answers: [] ) // no responses if response.answers.isEmpty { response.returnCode = .nonExistentDomain } self.log?.debug("serializing response") responseData = try response.serialize() } catch { self.log?.error("error processing message from \(query): \(error)") let response = Message( id: query.id, type: .response, returnCode: .notImplemented, questions: query.questions, answers: [] ) responseData = try response.serialize() } self.log?.debug("sending response for \(query.id)") let rData = ByteBuffer(bytes: responseData) try? await outbound.write(AddressedEnvelope(remoteAddress: packet.remoteAddress, data: rData)) self.log?.debug("processing done") } }