From 6dfceca43327f6bbc9d9d8662dba6ca542ec8928 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 3 Feb 2018 12:25:02 -0600 Subject: [PATCH] get the tcp version compiling again --- misc/yggdrasil.go.tcp | 376 +++++++++++++++++++++++++----------------- 1 file changed, 225 insertions(+), 151 deletions(-) diff --git a/misc/yggdrasil.go.tcp b/misc/yggdrasil.go.tcp index a2b174d6..b3946568 100644 --- a/misc/yggdrasil.go.tcp +++ b/misc/yggdrasil.go.tcp @@ -10,6 +10,7 @@ import "net" import "os" import "os/signal" import "time" +import "regexp" import _ "net/http/pprof" import "net/http" @@ -25,130 +26,187 @@ import . "yggdrasil" * It can generate a new config (--genconf) * It can read a config from stdin (--useconf) * It can run with an automatic config (--autoconf) -*/ + */ type nodeConfig struct { - Listen string - Peers []string - BoxPub string - BoxPriv string - SigPub string - SigPriv string - Multicast bool + Listen string + AdminListen string + Peers []string + BoxPub string + BoxPriv string + SigPub string + SigPriv string + Multicast bool + LinkLocal string + IfName string } type node struct { - core Core - sock *ipv6.PacketConn + core Core + sock *ipv6.PacketConn } func (n *node) init(cfg *nodeConfig, logger *log.Logger) { - boxPub, err := hex.DecodeString(cfg.BoxPub) - if err != nil { panic(err) } - boxPriv, err := hex.DecodeString(cfg.BoxPriv) - if err != nil { panic(err) } - sigPub, err := hex.DecodeString(cfg.SigPub) - if err != nil { panic(err) } - sigPriv, err := hex.DecodeString(cfg.SigPriv) - if err != nil { panic(err) } - n.core.DEBUG_init(boxPub, boxPriv, sigPub, sigPriv) - n.core.DEBUG_setLogger(logger) - logger.Println("Starting interface...") - n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) - logger.Println("Started interface") - go func () { - if len(cfg.Peers) == 0 { return } - for { - for _, p := range cfg.Peers { - n.core.DEBUG_addTCPConn(p) - time.Sleep(time.Second) - } - } - }() + boxPub, err := hex.DecodeString(cfg.BoxPub) + if err != nil { + panic(err) + } + boxPriv, err := hex.DecodeString(cfg.BoxPriv) + if err != nil { + panic(err) + } + sigPub, err := hex.DecodeString(cfg.SigPub) + if err != nil { + panic(err) + } + sigPriv, err := hex.DecodeString(cfg.SigPriv) + if err != nil { + panic(err) + } + n.core.DEBUG_init(boxPub, boxPriv, sigPub, sigPriv) + 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...") + n.core.DEBUG_setupAndStartGlobalTCPInterface(cfg.Listen) + logger.Println("Started interface") + logger.Println("Starting admin socket...") + n.core.DEBUG_setupAndStartAdminInterface(cfg.AdminListen) + logger.Println("Started admin socket") + go func() { + if len(cfg.Peers) == 0 { + return + } + for { + for _, p := range cfg.Peers { + n.core.DEBUG_addTCPConn(p) + time.Sleep(time.Second) + } + time.Sleep(time.Minute) + } + }() } func generateConfig() *nodeConfig { - core := Core{} - bpub, bpriv := core.DEBUG_newBoxKeys() - spub, spriv := core.DEBUG_newSigKeys() - cfg := nodeConfig{} - cfg.Listen = "[::]:0" - cfg.BoxPub = hex.EncodeToString(bpub[:]) - cfg.BoxPriv = hex.EncodeToString(bpriv[:]) - cfg.SigPub = hex.EncodeToString(spub[:]) - cfg.SigPriv = hex.EncodeToString(spriv[:]) - cfg.Peers = []string{} - cfg.Multicast = true - return &cfg + core := Core{} + bpub, bpriv := core.DEBUG_newBoxKeys() + spub, spriv := core.DEBUG_newSigKeys() + cfg := nodeConfig{} + cfg.Listen = "[::]:0" + cfg.AdminListen = "localhost:9001" + cfg.BoxPub = hex.EncodeToString(bpub[:]) + cfg.BoxPriv = hex.EncodeToString(bpriv[:]) + cfg.SigPub = hex.EncodeToString(spub[:]) + cfg.SigPriv = hex.EncodeToString(spriv[:]) + cfg.Peers = []string{} + cfg.Multicast = true + cfg.LinkLocal = "" + cfg.IfName = "auto" + return &cfg } func doGenconf() string { - cfg := generateConfig() - bs, err := json.MarshalIndent(cfg, "", " ") - if err != nil { panic(err) } - return string(bs) + cfg := generateConfig() + bs, err := json.MarshalIndent(cfg, "", " ") + if err != nil { + panic(err) + } + return string(bs) } var multicastAddr = "[ff02::114]:9001" func (n *node) listen() { - groupAddr, err := net.ResolveUDPAddr("udp", 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.Dst.IsLinkLocalMulticast() { continue } - if !rcm.Dst.Equal(groupAddr.IP) { continue } - anAddr := string(bs[:nBytes]) - addr, err := net.ResolveTCPAddr("tcp", 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) - } + 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("udp", multicastAddr) - if err != nil { panic(err) } - tcpaddr := n.core.DEBUG_getGlobalTCPAddr() - anAddr, err := net.ResolveTCPAddr("tcp", tcpaddr.String()) - if err != nil { panic(err) } - 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) - } + groupAddr, err := net.ResolveUDPAddr("udp6", multicastAddr) + if err != nil { + panic(err) + } + var anAddr net.TCPAddr + tcpAddr := n.core.DEBUG_getGlobalTCPAddr() + anAddr.Port = tcpAddr.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/") @@ -157,53 +215,69 @@ var useconf = flag.Bool("useconf", false, "read config from stdin") var autoconf = flag.Bool("autoconf", false, "automatic mode (dynamic IP, peer with IPv6 neighbors)") func main() { - flag.Parse() - var cfg *nodeConfig - switch { - case *autoconf: cfg = generateConfig() - case *useconf: - config, err := ioutil.ReadAll(os.Stdin) - if err != nil { panic(err) } - decoder := json.NewDecoder(bytes.NewReader(config)) - err = decoder.Decode(&cfg) - if err != nil { panic(err) } - case *genconf: fmt.Println(doGenconf()) - default: flag.PrintDefaults() - } - if cfg == nil { return } - logger := log.New(os.Stdout, "", log.Flags()) - if *pprof { - runtime.SetBlockProfileRate(1) - go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }() - } - // Setup - logger.Println("Initializing...") - n := node{} - n.init(cfg, logger) - logger.Println("Starting tun...") - //n.core.DEBUG_startTun() // 1280, the smallest supported MTU - n.core.DEBUG_startTunWithMTU(65535) // Largest supported MTU - defer func() { - logger.Println("Closing...") - n.core.DEBUG_stopTun() - }() - logger.Println("Started...") - 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 { panic(err) } - go n.listen() - go n.announce() - } - // Catch interrupt to exit gracefully - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - <-c - logger.Println("Stopping...") + flag.Parse() + var cfg *nodeConfig + switch { + case *autoconf: + cfg = generateConfig() + case *useconf: + config, err := ioutil.ReadAll(os.Stdin) + if err != nil { + panic(err) + } + decoder := json.NewDecoder(bytes.NewReader(config)) + cfg = generateConfig() + err = decoder.Decode(cfg) + if err != nil { + panic(err) + } + case *genconf: + fmt.Println(doGenconf()) + default: + flag.PrintDefaults() + } + if cfg == nil { + return + } + logger := log.New(os.Stdout, "", log.Flags()) + if *pprof { + runtime.SetBlockProfileRate(1) + go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }() + } + // Setup + logger.Println("Initializing...") + n := node{} + n.init(cfg, logger) + logger.Println("Starting tun...") + n.core.DEBUG_startTun(cfg.IfName) // 1280, the smallest supported MTU + //n.core.DEBUG_startTunWithMTU(cfg.IfName, 65535) // Largest supported MTU + defer func() { + logger.Println("Closing...") + n.core.DEBUG_stopTun() + }() + logger.Println("Started...") + 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 + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, os.Kill) + <-c + logger.Println("Stopping...") } -