/* * Copyright (C) 2024 Jonni Liljamo * * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for * more information. */ // Package dns implements all required DNS functionality for the program. package dns import ( "git.src.quest/~liljamo/felu/internal/config" "github.com/miekg/dns" ) // Run starts the DNS server. func Run(addr string, net string) error { dns.HandleFunc(config.FeluConfig.Domain, handleDNSRequest) server := &dns.Server{ Addr: addr, Net: net, MsgAcceptFunc: msgAcceptFunc, TsigProvider: tsigProvider{}, } return server.ListenAndServe() } // https://github.com/miekg/dns/blob/b77d1ed8e9282cadf21c4124f53a660fed55c8ca/types.go#L192 const _QR = 1 << 15 // query/response (response=1) // Otherwise the same as the original, but: // // 1: Commented out dynamic update rejection. // 2: Commented out dh.Nscount > 1, for dynamic updates. // // TODO: Consider looking this over properly, and maybe ditching the default. // // https://github.com/miekg/dns/blob/b77d1ed8e9282cadf21c4124f53a660fed55c8ca/acceptfunc.go func msgAcceptFunc(dh dns.Header) dns.MsgAcceptAction { if isResponse := dh.Bits&_QR != 0; isResponse { return dns.MsgIgnore } /* // Don't allow dynamic updates, because then the sections can contain a whole bunch of RRs. opcode := int(dh.Bits>>11) & 0xF if opcode != dns.OpcodeQuery && opcode != dns.OpcodeNotify { return dns.MsgRejectNotImplemented } */ if dh.Qdcount != 1 { return dns.MsgReject } // NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11. if dh.Ancount > 1 { return dns.MsgReject } /* // IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3. if dh.Nscount > 1 { return dns.MsgReject } */ if dh.Arcount > 2 { return dns.MsgReject } return dns.MsgAccept }