mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	Fix configuration reloading support
This commit is contained in:
		
							parent
							
								
									71ccaf753e
								
							
						
					
					
						commit
						ae2cc13d14
					
				
					 4 changed files with 71 additions and 66 deletions
				
			
		| 
						 | 
					@ -280,69 +280,6 @@ func main() {
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		n.core.Stop()
 | 
							n.core.Stop()
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	// Listen for new sessions
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
		go func() {
 | 
					 | 
				
			||||||
			listener, err := n.core.ListenConn()
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				logger.Errorln("Unable to listen for sessions:", err)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			for {
 | 
					 | 
				
			||||||
				conn, err := listener.Accept()
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					logger.Errorln("Accept:", err)
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				logger.Println("Accepted")
 | 
					 | 
				
			||||||
				for {
 | 
					 | 
				
			||||||
					b := make([]byte, 100)
 | 
					 | 
				
			||||||
					if n, err := conn.Read(b); err != nil {
 | 
					 | 
				
			||||||
						logger.Errorln("Read failed:", err)
 | 
					 | 
				
			||||||
						time.Sleep(time.Second * 2)
 | 
					 | 
				
			||||||
					} else {
 | 
					 | 
				
			||||||
						logger.Println("Read", n, "bytes:", b)
 | 
					 | 
				
			||||||
						b = []byte{5, 5, 5}
 | 
					 | 
				
			||||||
						if n, err := conn.Write(b); err != nil {
 | 
					 | 
				
			||||||
							logger.Errorln("Write failed:", err)
 | 
					 | 
				
			||||||
							time.Sleep(time.Second * 2)
 | 
					 | 
				
			||||||
						} else {
 | 
					 | 
				
			||||||
							logger.Println("Wrote", n, "bytes:", b)
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}()
 | 
					 | 
				
			||||||
		// Try creating new sessions
 | 
					 | 
				
			||||||
		go func() {
 | 
					 | 
				
			||||||
			if cfg.EncryptionPublicKey != "533574224115f835b7c7db6433986bc5aef855ff9c9568c01abeb0fbed3e8810" {
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			time.Sleep(time.Second * 2)
 | 
					 | 
				
			||||||
			conn, err := n.core.Dial("nodeid", "9890e135604e8aa6039a909e40c629824d852042a70e51957d5b9d700195663d50552e8e869af132b4617d76f8ef00314d94cce23aa8d6b051b3b952a32a4966")
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				logger.Errorln("Dial:", err)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			go func() {
 | 
					 | 
				
			||||||
				for {
 | 
					 | 
				
			||||||
					time.Sleep(time.Second * 2)
 | 
					 | 
				
			||||||
					b := []byte{1, 2, 3, 4, 5}
 | 
					 | 
				
			||||||
					if n, err := conn.Write(b); err != nil {
 | 
					 | 
				
			||||||
						logger.Errorln("Write failed:", err)
 | 
					 | 
				
			||||||
					} else {
 | 
					 | 
				
			||||||
						logger.Println("Wrote", n, "bytes:", b)
 | 
					 | 
				
			||||||
						b = make([]byte, 100)
 | 
					 | 
				
			||||||
						if n, err := conn.Read(b); err != nil {
 | 
					 | 
				
			||||||
							logger.Errorln("Read failed:", err)
 | 
					 | 
				
			||||||
						} else {
 | 
					 | 
				
			||||||
							logger.Println("Read", n, "bytes:", b)
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}()
 | 
					 | 
				
			||||||
		}()
 | 
					 | 
				
			||||||
	*/
 | 
					 | 
				
			||||||
	// 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()
 | 
				
			||||||
| 
						 | 
					@ -367,6 +304,8 @@ func main() {
 | 
				
			||||||
			if *useconffile != "" {
 | 
								if *useconffile != "" {
 | 
				
			||||||
				cfg = readConfig(useconf, useconffile, normaliseconf)
 | 
									cfg = readConfig(useconf, useconffile, normaliseconf)
 | 
				
			||||||
				n.core.UpdateConfig(cfg)
 | 
									n.core.UpdateConfig(cfg)
 | 
				
			||||||
 | 
									n.tuntap.UpdateConfig(cfg)
 | 
				
			||||||
 | 
									n.multicast.UpdateConfig(cfg)
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				logger.Errorln("Reloading config at runtime is only possible with -useconffile")
 | 
									logger.Errorln("Reloading config at runtime is only possible with -useconffile")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,10 @@ func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		for {
 | 
							for {
 | 
				
			||||||
			e := <-m.reconfigure
 | 
								e := <-m.reconfigure
 | 
				
			||||||
 | 
								// There's nothing particularly to do here because the multicast module
 | 
				
			||||||
 | 
								// already consults the config.NodeState when enumerating multicast
 | 
				
			||||||
 | 
								// interfaces on each pass. We just need to return nil so that the
 | 
				
			||||||
 | 
								// reconfiguration doesn't block indefinitely
 | 
				
			||||||
			e <- nil
 | 
								e <- nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
| 
						 | 
					@ -89,6 +93,36 @@ func (m *Multicast) Stop() error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UpdateConfig updates the multicast module with the provided config.NodeConfig
 | 
				
			||||||
 | 
					// and then signals the various module goroutines to reconfigure themselves if
 | 
				
			||||||
 | 
					// needed.
 | 
				
			||||||
 | 
					func (m *Multicast) UpdateConfig(config *config.NodeConfig) {
 | 
				
			||||||
 | 
						m.log.Debugln("Reloading multicast configuration...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m.config.Replace(*config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errors := 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						components := []chan chan error{
 | 
				
			||||||
 | 
							m.reconfigure,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, component := range components {
 | 
				
			||||||
 | 
							response := make(chan error)
 | 
				
			||||||
 | 
							component <- response
 | 
				
			||||||
 | 
							if err := <-response; err != nil {
 | 
				
			||||||
 | 
								m.log.Errorln(err)
 | 
				
			||||||
 | 
								errors++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if errors > 0 {
 | 
				
			||||||
 | 
							m.log.Warnln(errors, "multicast module(s) reported errors during configuration reload")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							m.log.Infoln("Multicast configuration reloaded successfully")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Multicast) interfaces() map[string]net.Interface {
 | 
					func (m *Multicast) interfaces() map[string]net.Interface {
 | 
				
			||||||
	// Get interface expressions from config
 | 
						// Get interface expressions from config
 | 
				
			||||||
	current, _ := m.config.Get()
 | 
						current, _ := m.config.Get()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,6 +148,7 @@ func (tun *TunAdapter) Start() error {
 | 
				
			||||||
	tun.mutex.Lock()
 | 
						tun.mutex.Lock()
 | 
				
			||||||
	tun.isOpen = true
 | 
						tun.isOpen = true
 | 
				
			||||||
	tun.send = make(chan []byte, 32) // TODO: is this a sensible value?
 | 
						tun.send = make(chan []byte, 32) // TODO: is this a sensible value?
 | 
				
			||||||
 | 
						tun.reconfigure = make(chan chan error)
 | 
				
			||||||
	tun.mutex.Unlock()
 | 
						tun.mutex.Unlock()
 | 
				
			||||||
	if iftapmode {
 | 
						if iftapmode {
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
| 
						 | 
					@ -178,6 +179,37 @@ func (tun *TunAdapter) Start() error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UpdateConfig updates the TUN/TAP module with the provided config.NodeConfig
 | 
				
			||||||
 | 
					// and then signals the various module goroutines to reconfigure themselves if
 | 
				
			||||||
 | 
					// needed.
 | 
				
			||||||
 | 
					func (tun *TunAdapter) UpdateConfig(config *config.NodeConfig) {
 | 
				
			||||||
 | 
						tun.log.Debugln("Reloading TUN/TAP configuration...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tun.config.Replace(*config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errors := 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						components := []chan chan error{
 | 
				
			||||||
 | 
							tun.reconfigure,
 | 
				
			||||||
 | 
							tun.ckr.reconfigure,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, component := range components {
 | 
				
			||||||
 | 
							response := make(chan error)
 | 
				
			||||||
 | 
							component <- response
 | 
				
			||||||
 | 
							if err := <-response; err != nil {
 | 
				
			||||||
 | 
								tun.log.Errorln(err)
 | 
				
			||||||
 | 
								errors++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if errors > 0 {
 | 
				
			||||||
 | 
							tun.log.Warnln(errors, "TUN/TAP module(s) reported errors during configuration reload")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							tun.log.Infoln("TUN/TAP configuration reloaded successfully")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tun *TunAdapter) handler() error {
 | 
					func (tun *TunAdapter) handler() error {
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		// Accept the incoming connection
 | 
							// Accept the incoming connection
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,7 @@ func (c *Core) addPeerLoop() {
 | 
				
			||||||
// config.NodeConfig and then signals the various module goroutines to
 | 
					// config.NodeConfig and then signals the various module goroutines to
 | 
				
			||||||
// reconfigure themselves if needed.
 | 
					// reconfigure themselves if needed.
 | 
				
			||||||
func (c *Core) UpdateConfig(config *config.NodeConfig) {
 | 
					func (c *Core) UpdateConfig(config *config.NodeConfig) {
 | 
				
			||||||
	c.log.Infoln("Reloading configuration...")
 | 
						c.log.Debugln("Reloading node configuration...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.config.Replace(*config)
 | 
						c.config.Replace(*config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,9 +141,9 @@ func (c *Core) UpdateConfig(config *config.NodeConfig) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if errors > 0 {
 | 
						if errors > 0 {
 | 
				
			||||||
		c.log.Warnln(errors, "modules reported errors during configuration reload")
 | 
							c.log.Warnln(errors, "node module(s) reported errors during configuration reload")
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		c.log.Infoln("Configuration reloaded successfully")
 | 
							c.log.Infoln("Node configuration reloaded successfully")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue