mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Allow updating Listen during runtime
This commit is contained in:
		
							parent
							
								
									f96747181d
								
							
						
					
					
						commit
						cb4495902b
					
				
					 3 changed files with 62 additions and 15 deletions
				
			
		| 
						 | 
					@ -109,13 +109,14 @@ func (c *Core) UpdateConfig(config *config.NodeConfig) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	components := []chan chan error{
 | 
						components := []chan chan error{
 | 
				
			||||||
		c.admin.reconfigure,
 | 
							c.admin.reconfigure,
 | 
				
			||||||
		c.searches.reconfigure,
 | 
							//c.searches.reconfigure,
 | 
				
			||||||
		c.dht.reconfigure,
 | 
							//c.dht.reconfigure,
 | 
				
			||||||
		c.sessions.reconfigure,
 | 
							//c.sessions.reconfigure,
 | 
				
			||||||
 | 
							//c.peers.reconfigure,
 | 
				
			||||||
 | 
							//c.router.reconfigure,
 | 
				
			||||||
 | 
							//c.switchTable.reconfigure,
 | 
				
			||||||
 | 
							c.tcp.reconfigure,
 | 
				
			||||||
		c.multicast.reconfigure,
 | 
							c.multicast.reconfigure,
 | 
				
			||||||
		c.peers.reconfigure,
 | 
					 | 
				
			||||||
		c.router.reconfigure,
 | 
					 | 
				
			||||||
		c.switchTable.reconfigure,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, component := range components {
 | 
						for _, component := range components {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/ipv6"
 | 
						"golang.org/x/net/ipv6"
 | 
				
			||||||
| 
						 | 
					@ -14,6 +15,8 @@ type multicast struct {
 | 
				
			||||||
	reconfigure chan chan error
 | 
						reconfigure chan chan error
 | 
				
			||||||
	sock        *ipv6.PacketConn
 | 
						sock        *ipv6.PacketConn
 | 
				
			||||||
	groupAddr   string
 | 
						groupAddr   string
 | 
				
			||||||
 | 
						myAddr      *net.TCPAddr
 | 
				
			||||||
 | 
						myAddrMutex sync.RWMutex
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *multicast) init(core *Core) {
 | 
					func (m *multicast) init(core *Core) {
 | 
				
			||||||
| 
						 | 
					@ -23,6 +26,9 @@ func (m *multicast) init(core *Core) {
 | 
				
			||||||
		for {
 | 
							for {
 | 
				
			||||||
			select {
 | 
								select {
 | 
				
			||||||
			case e := <-m.reconfigure:
 | 
								case e := <-m.reconfigure:
 | 
				
			||||||
 | 
									m.myAddrMutex.Lock()
 | 
				
			||||||
 | 
									m.myAddr = m.core.tcp.getAddr()
 | 
				
			||||||
 | 
									m.myAddrMutex.Unlock()
 | 
				
			||||||
				e <- nil
 | 
									e <- nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -95,13 +101,14 @@ func (m *multicast) interfaces() []net.Interface {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *multicast) announce() {
 | 
					func (m *multicast) announce() {
 | 
				
			||||||
 | 
						var anAddr net.TCPAddr
 | 
				
			||||||
 | 
						m.myAddrMutex.Lock()
 | 
				
			||||||
 | 
						m.myAddr = m.core.tcp.getAddr()
 | 
				
			||||||
 | 
						m.myAddrMutex.Unlock()
 | 
				
			||||||
	groupAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
 | 
						groupAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var anAddr net.TCPAddr
 | 
					 | 
				
			||||||
	myAddr := m.core.tcp.getAddr()
 | 
					 | 
				
			||||||
	anAddr.Port = myAddr.Port
 | 
					 | 
				
			||||||
	destAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
 | 
						destAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
| 
						 | 
					@ -113,6 +120,9 @@ func (m *multicast) announce() {
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				panic(err)
 | 
									panic(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								m.myAddrMutex.RLock()
 | 
				
			||||||
 | 
								anAddr.Port = m.myAddr.Port
 | 
				
			||||||
 | 
								m.myAddrMutex.RUnlock()
 | 
				
			||||||
			for _, addr := range addrs {
 | 
								for _, addr := range addrs {
 | 
				
			||||||
				addrIP, _, _ := net.ParseCIDR(addr.String())
 | 
									addrIP, _, _ := net.ParseCIDR(addr.String())
 | 
				
			||||||
				if addrIP.To4() != nil {
 | 
									if addrIP.To4() != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,9 @@ const tcp_ping_interval = (default_tcp_timeout * 2 / 3)
 | 
				
			||||||
// The TCP listener and information about active TCP connections, to avoid duplication.
 | 
					// The TCP listener and information about active TCP connections, to avoid duplication.
 | 
				
			||||||
type tcpInterface struct {
 | 
					type tcpInterface struct {
 | 
				
			||||||
	core        *Core
 | 
						core        *Core
 | 
				
			||||||
 | 
						reconfigure chan chan error
 | 
				
			||||||
	serv        net.Listener
 | 
						serv        net.Listener
 | 
				
			||||||
 | 
						serv_stop   chan bool
 | 
				
			||||||
	tcp_timeout time.Duration
 | 
						tcp_timeout time.Duration
 | 
				
			||||||
	tcp_addr    string
 | 
						tcp_addr    string
 | 
				
			||||||
	mutex       sync.Mutex // Protecting the below
 | 
						mutex       sync.Mutex // Protecting the below
 | 
				
			||||||
| 
						 | 
					@ -83,10 +85,37 @@ func (iface *tcpInterface) connectSOCKS(socksaddr, peeraddr string) {
 | 
				
			||||||
// Initializes the struct.
 | 
					// Initializes the struct.
 | 
				
			||||||
func (iface *tcpInterface) init(core *Core) (err error) {
 | 
					func (iface *tcpInterface) init(core *Core) (err error) {
 | 
				
			||||||
	iface.core = core
 | 
						iface.core = core
 | 
				
			||||||
 | 
						iface.serv_stop = make(chan bool, 1)
 | 
				
			||||||
 | 
						iface.reconfigure = make(chan chan error, 1)
 | 
				
			||||||
 | 
						go func() {
 | 
				
			||||||
 | 
							for {
 | 
				
			||||||
 | 
								select {
 | 
				
			||||||
 | 
								case e := <-iface.reconfigure:
 | 
				
			||||||
 | 
									iface.core.configMutex.RLock()
 | 
				
			||||||
 | 
									updated := iface.core.config.Listen != iface.core.configOld.Listen
 | 
				
			||||||
 | 
									iface.core.configMutex.RUnlock()
 | 
				
			||||||
 | 
									if updated {
 | 
				
			||||||
 | 
										iface.serv_stop <- true
 | 
				
			||||||
 | 
										iface.serv.Close()
 | 
				
			||||||
 | 
										e <- iface.listen()
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										e <- nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return iface.listen()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (iface *tcpInterface) listen() error {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	iface.core.configMutex.RLock()
 | 
						iface.core.configMutex.RLock()
 | 
				
			||||||
	iface.tcp_addr = iface.core.config.Listen
 | 
						iface.tcp_addr = iface.core.config.Listen
 | 
				
			||||||
	iface.tcp_timeout = time.Duration(iface.core.config.ReadTimeout) * time.Millisecond
 | 
						iface.tcp_timeout = time.Duration(iface.core.config.ReadTimeout) * time.Millisecond
 | 
				
			||||||
	iface.core.configMutex.RUnlock()
 | 
						iface.core.configMutex.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if iface.tcp_timeout >= 0 && iface.tcp_timeout < default_tcp_timeout {
 | 
						if iface.tcp_timeout >= 0 && iface.tcp_timeout < default_tcp_timeout {
 | 
				
			||||||
		iface.tcp_timeout = default_tcp_timeout
 | 
							iface.tcp_timeout = default_tcp_timeout
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -96,6 +125,7 @@ func (iface *tcpInterface) init(core *Core) (err error) {
 | 
				
			||||||
		iface.calls = make(map[string]struct{})
 | 
							iface.calls = make(map[string]struct{})
 | 
				
			||||||
		iface.conns = make(map[tcpInfo](chan struct{}))
 | 
							iface.conns = make(map[tcpInfo](chan struct{}))
 | 
				
			||||||
		go iface.listener()
 | 
							go iface.listener()
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
| 
						 | 
					@ -107,10 +137,16 @@ func (iface *tcpInterface) listener() {
 | 
				
			||||||
	iface.core.log.Println("Listening for TCP on:", iface.serv.Addr().String())
 | 
						iface.core.log.Println("Listening for TCP on:", iface.serv.Addr().String())
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		sock, err := iface.serv.Accept()
 | 
							sock, err := iface.serv.Accept()
 | 
				
			||||||
		if err != nil {
 | 
							select {
 | 
				
			||||||
			panic(err)
 | 
							case <-iface.serv_stop:
 | 
				
			||||||
 | 
								iface.core.log.Println("Stopping listener")
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									panic(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								go iface.handler(sock, true)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		go iface.handler(sock, true)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -363,12 +399,12 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) {
 | 
				
			||||||
	themAddr := address.AddrForNodeID(themNodeID)
 | 
						themAddr := address.AddrForNodeID(themNodeID)
 | 
				
			||||||
	themAddrString := net.IP(themAddr[:]).String()
 | 
						themAddrString := net.IP(themAddr[:]).String()
 | 
				
			||||||
	themString := fmt.Sprintf("%s@%s", themAddrString, them)
 | 
						themString := fmt.Sprintf("%s@%s", themAddrString, them)
 | 
				
			||||||
	iface.core.log.Println("Connected:", themString, "source", us)
 | 
						iface.core.log.Printf("Connected: %s, source: %s", themString, us)
 | 
				
			||||||
	err = iface.reader(sock, in) // In this goroutine, because of defers
 | 
						err = iface.reader(sock, in) // In this goroutine, because of defers
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
		iface.core.log.Println("Disconnected:", themString, "source", us)
 | 
							iface.core.log.Printf("Disconnected: %s, source: %s", themString, us)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		iface.core.log.Println("Disconnected:", themString, "source", us, "with error:", err)
 | 
							iface.core.log.Printf("Disconnected: %s, source: %s, error: %s", themString, us, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue