update listeners when netlink reports an address change
related to issue #21
This commit is contained in:
parent
5fb3d517ed
commit
63803ab95e
25
gokrazy.go
25
gokrazy.go
@ -17,6 +17,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gokrazy/gokrazy/internal/iface"
|
"github.com/gokrazy/gokrazy/internal/iface"
|
||||||
@ -145,6 +146,30 @@ func Supervise(commands []*exec.Cmd) error {
|
|||||||
return fmt.Errorf("updating listeners: %v", err)
|
return fmt.Errorf("updating listeners: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nl, err := listenNetlink(); err == nil {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
msgs, err := nl.ReadMsgs()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("netlink.ReadMsgs: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range msgs {
|
||||||
|
if m.Header.Type != syscall.RTM_NEWADDR &&
|
||||||
|
m.Header.Type != syscall.RTM_DELADDR {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := updateListeners("80"); err != nil {
|
||||||
|
log.Printf("updating listeners: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
} else {
|
||||||
|
log.Printf("cannot listen for new IP addresses: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, unix.SIGHUP)
|
signal.Notify(c, unix.SIGHUP)
|
||||||
|
49
netlink.go
Normal file
49
netlink.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package gokrazy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type netlinkListener struct {
|
||||||
|
fd int
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func listenNetlink() (*netlinkListener, error) {
|
||||||
|
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM, syscall.NETLINK_ROUTE)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE): %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
saddr := &syscall.SockaddrNetlink{
|
||||||
|
Family: syscall.AF_NETLINK,
|
||||||
|
Groups: (1 << (syscall.RTNLGRP_IPV4_IFADDR - 1)) |
|
||||||
|
(1 << (syscall.RTNLGRP_IPV6_IFADDR - 1)),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := syscall.Bind(fd, saddr); err != nil {
|
||||||
|
return nil, fmt.Errorf("bind: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &netlinkListener{
|
||||||
|
fd: fd,
|
||||||
|
// use the page size as buffer size, like libnl
|
||||||
|
buf: make([]byte, os.Getpagesize()),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *netlinkListener) ReadMsgs() ([]syscall.NetlinkMessage, error) {
|
||||||
|
n, err := syscall.Read(l.fd, l.buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Read: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msgs, err := syscall.ParseNetlinkMessage(l.buf[:n])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("ParseNetlinkMessage: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return msgs, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user