mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Move multicasting into yggdrasil package
This commit is contained in:
		
							parent
							
								
									388ae09fca
								
							
						
					
					
						commit
						6f79184c9b
					
				
					 6 changed files with 196 additions and 129 deletions
				
			
		| 
						 | 
					@ -10,8 +10,8 @@ type NodeConfig struct {
 | 
				
			||||||
	BoxPriv        string    `json:"EncryptionPrivateKey" comment:"Your private encryption key (do not share this with anyone!)"`
 | 
						BoxPriv        string    `json:"EncryptionPrivateKey" comment:"Your private encryption key (do not share this with anyone!)"`
 | 
				
			||||||
	SigPub         string    `json:"SigningPublicKey" comment:"Your public signing key"`
 | 
						SigPub         string    `json:"SigningPublicKey" comment:"Your public signing key"`
 | 
				
			||||||
	SigPriv        string    `json:"SigningPrivateKey" comment:"Your private signing key (do not share this with anyone!)"`
 | 
						SigPriv        string    `json:"SigningPrivateKey" comment:"Your private signing key (do not share this with anyone!)"`
 | 
				
			||||||
	Multicast      bool      `comment:"Enable or disable automatic peer discovery on the same LAN using multicast"`
 | 
						Multicast      bool      `json:"MulticastEnabled,omitempty" comment:"Enable or disable automatic peer discovery on the same LAN using multicast"`
 | 
				
			||||||
	LinkLocal      string    `json:"MulticastInterfaces" comment:"Regex for which interfaces multicast peer discovery should be enabled on"`
 | 
						LinkLocal      []string  `json:"MulticastInterfaces" comment:"Regexes for which interfaces multicast peer discovery should be enabled\non. If none specified, multicast peer discovery is disabled"`
 | 
				
			||||||
	IfName         string    `comment:"Local network interface name for TUN/TAP adapter, or \"auto\", or \"none\""`
 | 
						IfName         string    `comment:"Local network interface name for TUN/TAP adapter, or \"auto\", or \"none\""`
 | 
				
			||||||
	IfTAPMode      bool      `comment:"Set local network interface to TAP mode rather than TUN mode (if supported\nby your platform, option will be ignored if not)"`
 | 
						IfTAPMode      bool      `comment:"Set local network interface to TAP mode rather than TUN mode (if supported\nby your platform, option will be ignored if not)"`
 | 
				
			||||||
	IfMTU          int       `comment:"Maximux Transmission Unit (MTU) size for your local network interface"`
 | 
						IfMTU          int       `comment:"Maximux Transmission Unit (MTU) size for your local network interface"`
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,10 +19,11 @@ type Core struct {
 | 
				
			||||||
	tun         tunDevice
 | 
						tun         tunDevice
 | 
				
			||||||
	admin       admin
 | 
						admin       admin
 | 
				
			||||||
	searches    searches
 | 
						searches    searches
 | 
				
			||||||
 | 
						multicast   multicast
 | 
				
			||||||
	tcp         *tcpInterface
 | 
						tcp         *tcpInterface
 | 
				
			||||||
	udp         *udpInterface
 | 
						udp         *udpInterface
 | 
				
			||||||
	log         *log.Logger
 | 
						log         *log.Logger
 | 
				
			||||||
	ifceExpr    *regexp.Regexp // the zone of link-local IPv6 peers must match this
 | 
						ifceExpr    []*regexp.Regexp // the zone of link-local IPv6 peers must match this
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Core) Init() {
 | 
					func (c *Core) Init() {
 | 
				
			||||||
| 
						 | 
					@ -49,6 +50,7 @@ func (c *Core) init(bpub *boxPubKey,
 | 
				
			||||||
	c.searches.init(c)
 | 
						c.searches.init(c)
 | 
				
			||||||
	c.dht.init(c)
 | 
						c.dht.init(c)
 | 
				
			||||||
	c.sessions.init(c)
 | 
						c.sessions.init(c)
 | 
				
			||||||
 | 
						c.multicast.init(c)
 | 
				
			||||||
	c.peers.init(c)
 | 
						c.peers.init(c)
 | 
				
			||||||
	c.router.init(c)
 | 
						c.router.init(c)
 | 
				
			||||||
	c.switchTable.init(c, c.sigPub) // TODO move before peers? before router?
 | 
						c.switchTable.init(c, c.sigPub) // TODO move before peers? before router?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -387,6 +387,13 @@ func (c *Core) DEBUG_setupAndStartAdminInterface(addrport string) {
 | 
				
			||||||
	c.admin = a
 | 
						c.admin = a
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Core) DEBUG_setupAndStartMulticastInterface() {
 | 
				
			||||||
 | 
						m := multicast{}
 | 
				
			||||||
 | 
						m.init(c)
 | 
				
			||||||
 | 
						c.multicast = m
 | 
				
			||||||
 | 
						m.Start()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Core) DEBUG_setLogger(log *log.Logger) {
 | 
					func (c *Core) DEBUG_setLogger(log *log.Logger) {
 | 
				
			||||||
| 
						 | 
					@ -394,7 +401,7 @@ func (c *Core) DEBUG_setLogger(log *log.Logger) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Core) DEBUG_setIfceExpr(expr *regexp.Regexp) {
 | 
					func (c *Core) DEBUG_setIfceExpr(expr *regexp.Regexp) {
 | 
				
			||||||
	c.ifceExpr = expr
 | 
						c.ifceExpr = append(c.ifceExpr, expr)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Core) DEBUG_addAllowedBoxPub(boxStr string) {
 | 
					func (c *Core) DEBUG_addAllowedBoxPub(boxStr string) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										160
									
								
								src/yggdrasil/multicast.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/yggdrasil/multicast.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,160 @@
 | 
				
			||||||
 | 
					package yggdrasil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "net"
 | 
				
			||||||
 | 
					import "time"
 | 
				
			||||||
 | 
					import "fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "golang.org/x/net/ipv6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type multicast struct {
 | 
				
			||||||
 | 
						core      *Core
 | 
				
			||||||
 | 
						sock      *ipv6.PacketConn
 | 
				
			||||||
 | 
						groupAddr string
 | 
				
			||||||
 | 
					  interfaces []net.Interface
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *multicast) init(core *Core) {
 | 
				
			||||||
 | 
						m.core = core
 | 
				
			||||||
 | 
						m.groupAddr = "[ff02::114]:9001"
 | 
				
			||||||
 | 
					  // Ask the system for network interfaces
 | 
				
			||||||
 | 
					  allifaces, err := net.Interfaces()
 | 
				
			||||||
 | 
					  if err != nil {
 | 
				
			||||||
 | 
					    panic(err)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Work out which interfaces to announce on
 | 
				
			||||||
 | 
					  for _, iface := range allifaces {
 | 
				
			||||||
 | 
					    if iface.Flags & net.FlagUp == 0 {
 | 
				
			||||||
 | 
					      // Ignore interfaces that are down
 | 
				
			||||||
 | 
					      continue
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if iface.Flags & net.FlagMulticast == 0 {
 | 
				
			||||||
 | 
					      // Ignore non-multicast interfaces
 | 
				
			||||||
 | 
					      continue
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if iface.Flags & net.FlagPointToPoint != 0 {
 | 
				
			||||||
 | 
					      // Ignore point-to-point interfaces
 | 
				
			||||||
 | 
					      continue
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for _, expr := range m.core.ifceExpr {
 | 
				
			||||||
 | 
					      m.core.log.Println(expr)
 | 
				
			||||||
 | 
					      if expr.MatchString(iface.Name) {
 | 
				
			||||||
 | 
					        m.core.log.Println(iface.Name, "matched", expr)
 | 
				
			||||||
 | 
					        m.interfaces = append(m.interfaces, iface)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  m.core.log.Println("Found", len(m.interfaces), "multicast interfaces")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *multicast) Start() {
 | 
				
			||||||
 | 
						if len(m.core.ifceExpr) == 0 {
 | 
				
			||||||
 | 
							m.core.log.Println("Not starting multicast discovery")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
					    m.core.log.Println("Starting multicast discovery...")
 | 
				
			||||||
 | 
					  	addr, err := net.ResolveUDPAddr("udp", m.groupAddr)
 | 
				
			||||||
 | 
					  	if err != nil {
 | 
				
			||||||
 | 
					  		panic(err)
 | 
				
			||||||
 | 
					  	}
 | 
				
			||||||
 | 
					  	listenString := fmt.Sprintf("[::]:%v", addr.Port)
 | 
				
			||||||
 | 
					  	conn, err := net.ListenPacket("udp6", listenString)
 | 
				
			||||||
 | 
					  	if err != nil {
 | 
				
			||||||
 | 
					  		panic(err)
 | 
				
			||||||
 | 
					  	}
 | 
				
			||||||
 | 
					  	//defer conn.Close() // Let it close on its own when the application exits
 | 
				
			||||||
 | 
					  	m.sock = ipv6.NewPacketConn(conn)
 | 
				
			||||||
 | 
					  	if err = m.sock.SetControlMessage(ipv6.FlagDst, true); err != nil {
 | 
				
			||||||
 | 
					  		// Windows can't set this flag, so we need to handle it in other ways
 | 
				
			||||||
 | 
					  		//panic(err)
 | 
				
			||||||
 | 
					  	}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  	go m.listen()
 | 
				
			||||||
 | 
					  	go m.announce()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *multicast) announce() {
 | 
				
			||||||
 | 
						groupAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var anAddr net.TCPAddr
 | 
				
			||||||
 | 
						myAddr := m.core.DEBUG_getGlobalTCPAddr()
 | 
				
			||||||
 | 
						anAddr.Port = myAddr.Port
 | 
				
			||||||
 | 
						destAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							for _, iface := range m.interfaces {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								m.sock.JoinGroup(&iface, groupAddr)
 | 
				
			||||||
 | 
								//err := n.sock.JoinGroup(&iface, groupAddr)
 | 
				
			||||||
 | 
								//if err != nil { panic(err) }
 | 
				
			||||||
 | 
								addrs, err := iface.Addrs()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									panic(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for _, addr := range addrs {
 | 
				
			||||||
 | 
									addrIP, _, _ := net.ParseCIDR(addr.String())
 | 
				
			||||||
 | 
									if addrIP.To4() != nil {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									} // IPv6 only
 | 
				
			||||||
 | 
									if !addrIP.IsLinkLocalUnicast() {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									anAddr.IP = addrIP
 | 
				
			||||||
 | 
									anAddr.Zone = iface.Name
 | 
				
			||||||
 | 
									destAddr.Zone = iface.Name
 | 
				
			||||||
 | 
									msg := []byte(anAddr.String())
 | 
				
			||||||
 | 
									m.sock.WriteTo(msg, nil, destAddr)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								time.Sleep(time.Second)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							time.Sleep(time.Second)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *multicast) listen() {
 | 
				
			||||||
 | 
						groupAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						bs := make([]byte, 2048)
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							nBytes, rcm, fromAddr, err := m.sock.ReadFrom(bs)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								panic(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							//if rcm == nil { continue } // wat
 | 
				
			||||||
 | 
							//fmt.Println("DEBUG:", "packet from:", fromAddr.String())
 | 
				
			||||||
 | 
							if rcm != nil {
 | 
				
			||||||
 | 
								// Windows can't set the flag needed to return a non-nil value here
 | 
				
			||||||
 | 
								// So only make these checks if we get something useful back
 | 
				
			||||||
 | 
								// TODO? Skip them always, I'm not sure if they're really needed...
 | 
				
			||||||
 | 
								if !rcm.Dst.IsLinkLocalMulticast() {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if !rcm.Dst.Equal(groupAddr.IP) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							anAddr := string(bs[:nBytes])
 | 
				
			||||||
 | 
							addr, err := net.ResolveTCPAddr("tcp6", anAddr)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								panic(err)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							} // Panic for testing, remove later
 | 
				
			||||||
 | 
							from := fromAddr.(*net.UDPAddr)
 | 
				
			||||||
 | 
							//fmt.Println("DEBUG:", "heard:", addr.IP.String(), "from:", from.IP.String())
 | 
				
			||||||
 | 
							if addr.IP.String() != from.IP.String() {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							addr.Zone = from.Zone
 | 
				
			||||||
 | 
							saddr := addr.String()
 | 
				
			||||||
 | 
							//if _, isIn := n.peers[saddr]; isIn { continue }
 | 
				
			||||||
 | 
							//n.peers[saddr] = struct{}{}
 | 
				
			||||||
 | 
							m.core.DEBUG_addTCPConn(saddr)
 | 
				
			||||||
 | 
							//fmt.Println("DEBUG:", "added multicast peer:", saddr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -341,11 +341,17 @@ func (iface *udpInterface) reader() {
 | 
				
			||||||
			if them.isValid() {
 | 
								if them.isValid() {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if udpAddr.IP.IsLinkLocalUnicast() &&
 | 
								if udpAddr.IP.IsLinkLocalUnicast() {
 | 
				
			||||||
				!iface.core.ifceExpr.MatchString(udpAddr.Zone) {
 | 
									if len(iface.core.ifceExpr) == 0 {
 | 
				
			||||||
				continue
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									for _, expr := range iface.core.ifceExpr {
 | 
				
			||||||
 | 
										if expr.MatchString(udpAddr.Zone) {
 | 
				
			||||||
 | 
											iface.handleKeys(msg, addr)
 | 
				
			||||||
 | 
											break
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			iface.handleKeys(msg, addr)
 | 
					 | 
				
			||||||
		case udp_isClose(msg):
 | 
							case udp_isClose(msg):
 | 
				
			||||||
			iface.handleClose(msg, addr)
 | 
								iface.handleClose(msg, addr)
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										134
									
								
								yggdrasil.go
									
										
									
									
									
								
							
							
						
						
									
										134
									
								
								yggdrasil.go
									
										
									
									
									
								
							| 
						 | 
					@ -17,8 +17,6 @@ import "net/http"
 | 
				
			||||||
import "log"
 | 
					import "log"
 | 
				
			||||||
import "runtime"
 | 
					import "runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "golang.org/x/net/ipv6"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "yggdrasil"
 | 
					import "yggdrasil"
 | 
				
			||||||
import "yggdrasil/config"
 | 
					import "yggdrasil/config"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +29,6 @@ type Core = yggdrasil.Core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type node struct {
 | 
					type node struct {
 | 
				
			||||||
	core Core
 | 
						core Core
 | 
				
			||||||
	sock *ipv6.PacketConn
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
 | 
					func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
 | 
				
			||||||
| 
						 | 
					@ -53,11 +50,6 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	n.core.DEBUG_init(boxPub, boxPriv, sigPub, sigPriv)
 | 
						n.core.DEBUG_init(boxPub, boxPriv, sigPub, sigPriv)
 | 
				
			||||||
	n.core.DEBUG_setLogger(logger)
 | 
						n.core.DEBUG_setLogger(logger)
 | 
				
			||||||
	ifceExpr, err := regexp.Compile(cfg.LinkLocal)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	n.core.DEBUG_setIfceExpr(ifceExpr)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logger.Println("Starting interface...")
 | 
						logger.Println("Starting interface...")
 | 
				
			||||||
	n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) // Listen for peers on TCP
 | 
						n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) // Listen for peers on TCP
 | 
				
			||||||
| 
						 | 
					@ -69,6 +61,17 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
 | 
				
			||||||
	for _, pBoxStr := range cfg.AllowedBoxPubs {
 | 
						for _, pBoxStr := range cfg.AllowedBoxPubs {
 | 
				
			||||||
		n.core.DEBUG_addAllowedBoxPub(pBoxStr)
 | 
							n.core.DEBUG_addAllowedBoxPub(pBoxStr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						logger.Println(cfg.LinkLocal)
 | 
				
			||||||
 | 
						for _, ll := range cfg.LinkLocal {
 | 
				
			||||||
 | 
							logger.Println("Adding expression", ll)
 | 
				
			||||||
 | 
							ifceExpr, err := regexp.Compile(ll)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								panic(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							logger.Println("Added expression", ifceExpr)
 | 
				
			||||||
 | 
							n.core.DEBUG_setIfceExpr(ifceExpr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						n.core.DEBUG_setupAndStartMulticastInterface()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		if len(cfg.Peers) == 0 {
 | 
							if len(cfg.Peers) == 0 {
 | 
				
			||||||
| 
						 | 
					@ -102,8 +105,8 @@ func generateConfig(isAutoconf bool) *nodeConfig {
 | 
				
			||||||
	cfg.SigPriv = hex.EncodeToString(spriv[:])
 | 
						cfg.SigPriv = hex.EncodeToString(spriv[:])
 | 
				
			||||||
	cfg.Peers = []string{}
 | 
						cfg.Peers = []string{}
 | 
				
			||||||
	cfg.AllowedBoxPubs = []string{}
 | 
						cfg.AllowedBoxPubs = []string{}
 | 
				
			||||||
	cfg.Multicast = true
 | 
						cfg.Multicast = false
 | 
				
			||||||
	cfg.LinkLocal = ""
 | 
						cfg.LinkLocal = []string{}
 | 
				
			||||||
	cfg.IfName = core.DEBUG_GetTUNDefaultIfName()
 | 
						cfg.IfName = core.DEBUG_GetTUNDefaultIfName()
 | 
				
			||||||
	cfg.IfMTU = core.DEBUG_GetTUNDefaultIfMTU()
 | 
						cfg.IfMTU = core.DEBUG_GetTUNDefaultIfMTU()
 | 
				
			||||||
	cfg.IfTAPMode = core.DEBUG_GetTUNDefaultIfTAPMode()
 | 
						cfg.IfTAPMode = core.DEBUG_GetTUNDefaultIfTAPMode()
 | 
				
			||||||
| 
						 | 
					@ -120,98 +123,6 @@ func doGenconf() string {
 | 
				
			||||||
	return string(bs)
 | 
						return string(bs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var multicastAddr = "[ff02::114]:9001"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n *node) listen() {
 | 
					 | 
				
			||||||
	groupAddr, err := net.ResolveUDPAddr("udp6", multicastAddr)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	bs := make([]byte, 2048)
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		nBytes, rcm, fromAddr, err := n.sock.ReadFrom(bs)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			panic(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		//if rcm == nil { continue } // wat
 | 
					 | 
				
			||||||
		//fmt.Println("DEBUG:", "packet from:", fromAddr.String())
 | 
					 | 
				
			||||||
		if rcm != nil {
 | 
					 | 
				
			||||||
			// Windows can't set the flag needed to return a non-nil value here
 | 
					 | 
				
			||||||
			// So only make these checks if we get something useful back
 | 
					 | 
				
			||||||
			// TODO? Skip them always, I'm not sure if they're really needed...
 | 
					 | 
				
			||||||
			if !rcm.Dst.IsLinkLocalMulticast() {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if !rcm.Dst.Equal(groupAddr.IP) {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		anAddr := string(bs[:nBytes])
 | 
					 | 
				
			||||||
		addr, err := net.ResolveTCPAddr("tcp6", anAddr)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			panic(err)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		} // Panic for testing, remove later
 | 
					 | 
				
			||||||
		from := fromAddr.(*net.UDPAddr)
 | 
					 | 
				
			||||||
		//fmt.Println("DEBUG:", "heard:", addr.IP.String(), "from:", from.IP.String())
 | 
					 | 
				
			||||||
		if addr.IP.String() != from.IP.String() {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		addr.Zone = from.Zone
 | 
					 | 
				
			||||||
		saddr := addr.String()
 | 
					 | 
				
			||||||
		//if _, isIn := n.peers[saddr]; isIn { continue }
 | 
					 | 
				
			||||||
		//n.peers[saddr] = struct{}{}
 | 
					 | 
				
			||||||
		n.core.DEBUG_addTCPConn(saddr)
 | 
					 | 
				
			||||||
		//fmt.Println("DEBUG:", "added multicast peer:", saddr)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (n *node) announce() {
 | 
					 | 
				
			||||||
	groupAddr, err := net.ResolveUDPAddr("udp6", multicastAddr)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var anAddr net.TCPAddr
 | 
					 | 
				
			||||||
	myAddr := n.core.DEBUG_getGlobalTCPAddr()
 | 
					 | 
				
			||||||
	anAddr.Port = myAddr.Port
 | 
					 | 
				
			||||||
	destAddr, err := net.ResolveUDPAddr("udp6", multicastAddr)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		panic(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		ifaces, err := net.Interfaces()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			panic(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		for _, iface := range ifaces {
 | 
					 | 
				
			||||||
			n.sock.JoinGroup(&iface, groupAddr)
 | 
					 | 
				
			||||||
			//err := n.sock.JoinGroup(&iface, groupAddr)
 | 
					 | 
				
			||||||
			//if err != nil { panic(err) }
 | 
					 | 
				
			||||||
			addrs, err := iface.Addrs()
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				panic(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			for _, addr := range addrs {
 | 
					 | 
				
			||||||
				addrIP, _, _ := net.ParseCIDR(addr.String())
 | 
					 | 
				
			||||||
				if addrIP.To4() != nil {
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				} // IPv6 only
 | 
					 | 
				
			||||||
				if !addrIP.IsLinkLocalUnicast() {
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				anAddr.IP = addrIP
 | 
					 | 
				
			||||||
				anAddr.Zone = iface.Name
 | 
					 | 
				
			||||||
				destAddr.Zone = iface.Name
 | 
					 | 
				
			||||||
				msg := []byte(anAddr.String())
 | 
					 | 
				
			||||||
				n.sock.WriteTo(msg, nil, destAddr)
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			time.Sleep(time.Second)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		time.Sleep(time.Second)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var pprof = flag.Bool("pprof", false, "Run pprof, see http://localhost:6060/debug/pprof/")
 | 
					var pprof = flag.Bool("pprof", false, "Run pprof, see http://localhost:6060/debug/pprof/")
 | 
				
			||||||
var genconf = flag.Bool("genconf", false, "print a new config to stdout")
 | 
					var genconf = flag.Bool("genconf", false, "print a new config to stdout")
 | 
				
			||||||
var useconf = flag.Bool("useconf", false, "read config from stdin")
 | 
					var useconf = flag.Bool("useconf", false, "read config from stdin")
 | 
				
			||||||
| 
						 | 
					@ -277,25 +188,6 @@ func main() {
 | 
				
			||||||
	subnet = append(subnet, 0, 0, 0, 0, 0, 0, 0, 0)
 | 
						subnet = append(subnet, 0, 0, 0, 0, 0, 0, 0, 0)
 | 
				
			||||||
	logger.Printf("Your IPv6 address is %s", net.IP(address).String())
 | 
						logger.Printf("Your IPv6 address is %s", net.IP(address).String())
 | 
				
			||||||
	logger.Printf("Your IPv6 subnet is %s/64", net.IP(subnet).String())
 | 
						logger.Printf("Your IPv6 subnet is %s/64", net.IP(subnet).String())
 | 
				
			||||||
	if cfg.Multicast {
 | 
					 | 
				
			||||||
		addr, err := net.ResolveUDPAddr("udp", multicastAddr)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			panic(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		listenString := fmt.Sprintf("[::]:%v", addr.Port)
 | 
					 | 
				
			||||||
		conn, err := net.ListenPacket("udp6", listenString)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			panic(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		//defer conn.Close() // Let it close on its own when the application exits
 | 
					 | 
				
			||||||
		n.sock = ipv6.NewPacketConn(conn)
 | 
					 | 
				
			||||||
		if err = n.sock.SetControlMessage(ipv6.FlagDst, true); err != nil {
 | 
					 | 
				
			||||||
			// Windows can't set this flag, so we need to handle it in other ways
 | 
					 | 
				
			||||||
			//panic(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		go n.listen()
 | 
					 | 
				
			||||||
		go n.announce()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Catch interrupt to exit gracefully
 | 
						// Catch interrupt to exit gracefully
 | 
				
			||||||
	c := make(chan os.Signal, 1)
 | 
						c := make(chan os.Signal, 1)
 | 
				
			||||||
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
 | 
						signal.Notify(c, os.Interrupt, syscall.SIGTERM)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue