55 "fmt"
66 "math/rand"
77 "net"
8+ "os"
9+ "runtime/debug"
810 "strings"
911 "time"
1012
@@ -108,7 +110,7 @@ func applyOpts(options ...ClientOption) clientOpts {
108110 return conf
109111}
110112
111- func (c * client ) run (ctx context.Context , params * lookupParams ) error {
113+ func (c * client ) run (ctx context.Context , params * lookupParams ) ( err error ) {
112114 ctx , cancel := context .WithCancel (ctx )
113115 done := make (chan struct {})
114116 go func () {
@@ -118,7 +120,7 @@ func (c *client) run(ctx context.Context, params *lookupParams) error {
118120
119121 // If previous probe was ok, it should be fine now. In case of an error later on,
120122 // the entries' queue is closed.
121- err : = c .periodicQuery (ctx , params )
123+ err = c .periodicQuery (ctx , params )
122124 cancel ()
123125 <- done
124126 return err
@@ -165,6 +167,12 @@ var cleanupFreq = 10 * time.Second
165167
166168// Start listeners and waits for the shutdown signal from exit channel
167169func (c * client ) mainloop (ctx context.Context , params * lookupParams ) {
170+ defer func () {
171+ if rerr := recover (); rerr != nil {
172+ fmt .Fprintf (os .Stderr , "caught panic: %s\n %s\n " , rerr , debug .Stack ())
173+ }
174+ }()
175+
168176 // start listening for responses
169177 msgCh := make (chan * dns.Msg , 32 )
170178 if c .ipv4conn != nil {
@@ -313,6 +321,12 @@ func (c *client) shutdown() {
313321// Data receiving routine reads from connection, unpacks packets into dns.Msg
314322// structures and sends them to a given msgCh channel
315323func (c * client ) recv (ctx context.Context , l interface {}, msgCh chan * dns.Msg ) {
324+ defer func () {
325+ if rerr := recover (); rerr != nil {
326+ fmt .Fprintf (os .Stderr , "caught panic: %s\n %s\n " , rerr , debug .Stack ())
327+ }
328+ }()
329+
316330 var readFrom func ([]byte ) (n int , src net.Addr , err error )
317331
318332 switch pConn := l .(type ) {
@@ -408,7 +422,14 @@ func (c *client) periodicQuery(ctx context.Context, params *lookupParams) error
408422
409423// Performs the actual query by service name (browse) or service instance name (lookup),
410424// start response listeners goroutines and loops over the entries channel.
411- func (c * client ) query (params * lookupParams ) error {
425+ func (c * client ) query (params * lookupParams ) (err error ) {
426+ defer func () {
427+ if rerr := recover (); rerr != nil {
428+ fmt .Fprintf (os .Stderr , "caught panic: %s\n %s\n " , rerr , debug .Stack ())
429+ err = fmt .Errorf ("panic in zeroconf query: %s" , rerr )
430+ }
431+ }()
432+
412433 var serviceName , serviceInstanceName string
413434 serviceName = fmt .Sprintf ("%s.%s." , trimDot (params .Service ), trimDot (params .Domain ))
414435
0 commit comments