Skip to content

Commit

Permalink
fix(publisher): reuse EntryGroup - reset+(re)commit
Browse files Browse the repository at this point in the history
  • Loading branch information
grishy committed Jan 31, 2024
1 parent a0c130f commit d20f8da
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 16 deletions.
36 changes: 22 additions & 14 deletions avahi/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ const (
)

type Publisher struct {
dbusConn *dbus.Conn
avahiServer *avahi.Server
fqdn string
rdataField []byte
dbusConn *dbus.Conn
avahiServer *avahi.Server
avahiEntryGroup *avahi.EntryGroup
fqdn string
rdataField []byte
}

// NewPublisher creates a new service for Publisher.
Expand All @@ -39,6 +40,11 @@ func NewPublisher() (*Publisher, error) {
return nil, fmt.Errorf("failed to get FQDN from Avahi: %v", err)
}

group, err := server.EntryGroupNew()
if err != nil {
return nil, fmt.Errorf("failed to create entry group: %v", err)
}

fqdn := dns.Fqdn(avahiFqdn)

// RDATA: a variable length string of octets that describes the resource. CNAME in our case
Expand All @@ -50,10 +56,11 @@ func NewPublisher() (*Publisher, error) {
}

return &Publisher{
dbusConn: conn,
avahiServer: server,
fqdn: fqdn,
rdataField: rdataField,
dbusConn: conn,
avahiServer: server,
avahiEntryGroup: group,
fqdn: fqdn,
rdataField: rdataField,
}, nil
}

Expand All @@ -64,13 +71,14 @@ func (p *Publisher) Fqdn() string {

// PublishCNAMES send via Avahi-daemon CNAME records with the provided TTL.
func (p *Publisher) PublishCNAMES(cnames []string, ttl uint32) error {
group, err := p.avahiServer.EntryGroupNew()
if err != nil {
return fmt.Errorf("failed to create entry group: %v", err)
// Reset the entry group to remove all records.
// Because we can't update records without it after the `Commit`.
if err := p.avahiEntryGroup.Reset(); err != nil {
return fmt.Errorf("failed to reset entry group: %v", err)
}

for _, cname := range cnames {
err := group.AddRecord(
err := p.avahiEntryGroup.AddRecord(
avahi.InterfaceUnspec,
avahi.ProtoUnspec,
uint32(0), // From Avahi Python bindings https://gist.github.com/gdamjan/3168336#file-avahi-alias-py-L42
Expand All @@ -85,7 +93,7 @@ func (p *Publisher) PublishCNAMES(cnames []string, ttl uint32) error {
}
}

if err := group.Commit(); err != nil {
if err := p.avahiEntryGroup.Commit(); err != nil {
return fmt.Errorf("failed to commit entry group: %v", err)
}

Expand All @@ -94,5 +102,5 @@ func (p *Publisher) PublishCNAMES(cnames []string, ttl uint32) error {

// Close associated resources.
func (p *Publisher) Close() {
p.avahiServer.Close() // It also close the DBus connection
p.avahiServer.Close() // It also closes the DBus connection and free the entry group
}
3 changes: 1 addition & 2 deletions cmd/subdomain.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ func runSubdomain(ctx context.Context, publisher *avahi.Publisher, fqdn string,

if len(found) > 0 {
if err := publisher.PublishCNAMES(found, ttl); err != nil {
log.Printf("Failed to publish CNAMEs: %v", err)
continue
return fmt.Errorf("failed to publish CNAMEs: %w", err)
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"time"

"github.com/carlmjohnson/versioninfo"
"github.com/urfave/cli/v2"
Expand All @@ -16,6 +18,15 @@ func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer stop()

// Add a handler for force exiting if we don't exit gracefully (stuck)
go func() {
<-ctx.Done()
time.Sleep(3 * time.Second)

log.Print("Force exit")
os.Exit(1)
}()

app := &cli.App{
Name: "go-avahi-cname",
Usage: "A tool for publishing CNAME records with Avahi",
Expand Down

0 comments on commit d20f8da

Please sign in to comment.