feat: add small check for ability to bind to address

This commit is contained in:
xaos 2023-02-25 11:09:56 +01:00
parent 225057c6e9
commit f0c0cbc16b

19
stub.go
View file

@ -2,6 +2,7 @@ package stub
import ( import (
"context" "context"
"net"
"github.com/miekg/dns" "github.com/miekg/dns"
"github.com/mholt/acmez" "github.com/mholt/acmez"
@ -82,6 +83,14 @@ func (s *StubDNS) Present(ctx context.Context, challenge acme.Challenge) error {
// get challenge parameters // get challenge parameters
fqdn := dns.Fqdn(challenge.DNS01TXTRecordName()) fqdn := dns.Fqdn(challenge.DNS01TXTRecordName())
content := challenge.DNS01KeyAuthorization() 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 // spawn the server
handler := s.make_handler(fqdn, content) handler := s.make_handler(fqdn, content)
dns.HandleFunc(".", handler) 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 { func (s *StubDNS) make_handler(fqdn string, txt string) dns.HandlerFunc {
handler := func(w dns.ResponseWriter, r *dns.Msg) { handler := func(w dns.ResponseWriter, r *dns.Msg) {
m := new(dns.Msg) m := new(dns.Msg)