From f0c0cbc16b9742d10e313ac3c46cf3ef5a79bb7e Mon Sep 17 00:00:00 2001 From: xaos Date: Sat, 25 Feb 2023 11:09:56 +0100 Subject: [PATCH] feat: add small check for ability to bind to address --- stub.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/stub.go b/stub.go index 361b2e0..1205852 100644 --- a/stub.go +++ b/stub.go @@ -2,6 +2,7 @@ package stub import ( "context" + "net" "github.com/miekg/dns" "github.com/mholt/acmez" @@ -82,6 +83,14 @@ func (s *StubDNS) Present(ctx context.Context, challenge acme.Challenge) error { // get challenge parameters fqdn := dns.Fqdn(challenge.DNS01TXTRecordName()) content := challenge.DNS01KeyAuthorization() + + // dns.Server.ListenAndServe blocks when it binds successfully, + // so it has to run in a separate task and can't return errors directly + + if err := try_bind(ctx, s.Address); err != nil { + return err + } + // spawn the server handler := s.make_handler(fqdn, content) dns.HandleFunc(".", handler) @@ -101,6 +110,16 @@ func (p *StubDNS) CleanUp(ctx context.Context, _ acme.Challenge) error { } } +// quickly check whether it's possible to bind to the address +func try_bind(ctx context.Context, address string) error { + var lc net.ListenConfig + conn, err := lc.ListenPacket(ctx, "udp", address) + if conn != nil { + return conn.Close() + } + return err +} + func (s *StubDNS) make_handler(fqdn string, txt string) dns.HandlerFunc { handler := func(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg)