Merge pull request #453 from yggdrasil-network/stopfix

Bug fixes
This commit is contained in:
Neil Alexander 2019-07-06 12:36:46 +01:00 committed by GitHub
commit 912c181581
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 15 deletions

View File

@ -172,7 +172,7 @@ func main() {
logger = log.New(syslogger, "", log.Flags()) logger = log.New(syslogger, "", log.Flags())
} }
default: default:
if logfd, err := os.Create(*logto); err == nil { if logfd, err := os.OpenFile(*logto, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
logger = log.New(logfd, "", log.Flags()) logger = log.New(logfd, "", log.Flags())
} }
} }
@ -231,11 +231,6 @@ func main() {
} else { } else {
logger.Errorln("Unable to get Listener:", err) logger.Errorln("Unable to get Listener:", err)
} }
// The Stop function ensures that the TUN/TAP adapter is correctly shut down
// before the program exits.
defer func() {
n.core.Stop()
}()
// Make some nice output that tells us what our IPv6 address and subnet are. // Make some nice output that tells us what our IPv6 address and subnet are.
// This is just logged to stdout for the user. // This is just logged to stdout for the user.
address := n.core.Address() address := n.core.Address()
@ -247,15 +242,15 @@ func main() {
r := make(chan os.Signal, 1) r := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM) signal.Notify(c, os.Interrupt, syscall.SIGTERM)
signal.Notify(r, os.Interrupt, syscall.SIGHUP) signal.Notify(r, os.Interrupt, syscall.SIGHUP)
// Create a function to capture the service being stopped on Windows. // Capture the service being stopped on Windows.
winTerminate := func() { minwinsvc.SetOnExit(n.shutdown)
c <- os.Interrupt defer n.shutdown()
}
minwinsvc.SetOnExit(winTerminate)
// Wait for the terminate/interrupt signal. Once a signal is received, the // Wait for the terminate/interrupt signal. Once a signal is received, the
// deferred Stop function above will run which will shut down TUN/TAP. // deferred Stop function above will run which will shut down TUN/TAP.
for { for {
select { select {
case _ = <-c:
goto exit
case _ = <-r: case _ = <-r:
if *useconffile != "" { if *useconffile != "" {
cfg = readConfig(useconf, useconffile, normaliseconf) cfg = readConfig(useconf, useconffile, normaliseconf)
@ -265,13 +260,19 @@ func main() {
} else { } else {
logger.Errorln("Reloading config at runtime is only possible with -useconffile") logger.Errorln("Reloading config at runtime is only possible with -useconffile")
} }
case _ = <-c:
goto exit
} }
} }
exit: exit:
} }
func (n *node) shutdown() {
n.core.Stop()
n.admin.Stop()
n.multicast.Stop()
n.tuntap.Stop()
os.Exit(0)
}
func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool { func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
n.state.Mutex.RLock() n.state.Mutex.RLock()
defer n.state.Mutex.RUnlock() defer n.state.Mutex.RUnlock()

View File

@ -26,6 +26,7 @@ type Multicast struct {
groupAddr string groupAddr string
listeners map[string]*yggdrasil.TcpListener listeners map[string]*yggdrasil.TcpListener
listenPort uint16 listenPort uint16
isOpen bool
} }
// Init prepares the multicast interface for use. // Init prepares the multicast interface for use.
@ -61,6 +62,7 @@ func (m *Multicast) Start() error {
// Windows can't set this flag, so we need to handle it in other ways // Windows can't set this flag, so we need to handle it in other ways
} }
m.isOpen = true
go m.multicastStarted() go m.multicastStarted()
go m.listen() go m.listen()
go m.announce() go m.announce()
@ -70,6 +72,8 @@ func (m *Multicast) Start() error {
// Stop is not implemented for multicast yet. // Stop is not implemented for multicast yet.
func (m *Multicast) Stop() error { func (m *Multicast) Stop() error {
m.isOpen = false
m.sock.Close()
return nil return nil
} }
@ -246,6 +250,9 @@ func (m *Multicast) listen() {
for { for {
nBytes, rcm, fromAddr, err := m.sock.ReadFrom(bs) nBytes, rcm, fromAddr, err := m.sock.ReadFrom(bs)
if err != nil { if err != nil {
if !m.isOpen {
return
}
panic(err) panic(err)
} }
if rcm != nil { if rcm != nil {

View File

@ -98,6 +98,9 @@ func (tun *TunAdapter) writer() error {
util.PutBytes(b) util.PutBytes(b)
} }
if err != nil { if err != nil {
if !tun.isOpen {
return err
}
tun.log.Errorln("TUN/TAP iface write error:", err) tun.log.Errorln("TUN/TAP iface write error:", err)
continue continue
} }
@ -114,6 +117,9 @@ func (tun *TunAdapter) reader() error {
// Wait for a packet to be delivered to us through the TUN/TAP adapter // Wait for a packet to be delivered to us through the TUN/TAP adapter
n, err := tun.iface.Read(bs) n, err := tun.iface.Read(bs)
if err != nil { if err != nil {
if !tun.isOpen {
return err
}
panic(err) panic(err)
} }
if n == 0 { if n == 0 {

View File

@ -181,6 +181,16 @@ func (tun *TunAdapter) Start() error {
return nil return nil
} }
// Start the setup process for the TUN/TAP adapter. If successful, starts the
// read/write goroutines to handle packets on that interface.
func (tun *TunAdapter) Stop() error {
tun.isOpen = false
// TODO: we have nothing that cleanly stops all the various goroutines opened
// by TUN/TAP, e.g. readers/writers, sessions
tun.iface.Close()
return nil
}
// UpdateConfig updates the TUN/TAP module with the provided config.NodeConfig // UpdateConfig updates the TUN/TAP module with the provided config.NodeConfig
// and then signals the various module goroutines to reconfigure themselves if // and then signals the various module goroutines to reconfigure themselves if
// needed. // needed.

View File

@ -88,14 +88,14 @@ func (c *Core) addPeerLoop() {
// Add peers from the Peers section // Add peers from the Peers section
for _, peer := range current.Peers { for _, peer := range current.Peers {
c.AddPeer(peer, "") go c.AddPeer(peer, "")
time.Sleep(time.Second) time.Sleep(time.Second)
} }
// Add peers from the InterfacePeers section // Add peers from the InterfacePeers section
for intf, intfpeers := range current.InterfacePeers { for intf, intfpeers := range current.InterfacePeers {
for _, peer := range intfpeers { for _, peer := range intfpeers {
c.AddPeer(peer, intf) go c.AddPeer(peer, intf)
time.Sleep(time.Second) time.Sleep(time.Second)
} }
} }