diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index ab0e33e..9051d3f 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -6,6 +6,7 @@ import "bytes" import "fmt" import "sort" import "strings" +import "strconv" // TODO? Make all of this JSON // TODO: Add authentication @@ -55,6 +56,45 @@ func (a *admin) init(c *Core, listenaddr string) { a.addHandler("getSessions", nil, func(out *[]byte, _ ...string) { *out = []byte(a.printInfos(a.getData_getSessions())) }) + a.addHandler("addPeer", []string{""}, func(out *[]byte, saddr ...string) { + if a.addPeer(saddr[0]) == nil { + *out = []byte("Adding peer: " + saddr[0] + "\n") + } else { + *out = []byte("Failed to add peer: " + saddr[0] + "\n") + } + }) + a.addHandler("setTunTap", []string{"", "[]", "[]"}, func(out *[]byte, ifparams ...string) { + // Set sane defaults + iftapmode := false + ifmtu := 1280 + var err error + // Check we have enough params for TAP mode + if len(ifparams) > 1 { + // Is it a TAP adapter? + if ifparams[1] == "tap" { + iftapmode = true + } + } + // Check we have enough params for MTU + if len(ifparams) > 2 { + // Make sure the MTU is sane + ifmtu, err = strconv.Atoi(ifparams[2]) + if err != nil || ifmtu < 1280 || ifmtu > 65535 { + ifmtu = 1280 + } + } + // Start the TUN adapter + if err := a.startTunWithMTU(ifparams[0], iftapmode, ifmtu); err != nil { + *out = []byte(fmt.Sprintf("Failed to set TUN: %v\n", err)) + } else { + info := admin_nodeInfo{ + {"Interface name", ifparams[0]}, + {"TAP mode", strconv.FormatBool(iftapmode)}, + {"MTU", strconv.Itoa(ifmtu)}, + } + *out = []byte(a.printInfos([]admin_nodeInfo{info})) + } + }) go a.listen() } @@ -143,6 +183,56 @@ func (a *admin) printInfos(infos []admin_nodeInfo) string { return strings.Join(out, "\n") } +func (a *admin) addPeer(p string) error { + pAddr := p + if p[:4] == "tcp:" || p[:4] == "udp:" { + pAddr = p[4:] + } + switch { + case len(p) >= 4 && p[:4] == "udp:": + // Connect to peer over UDP + udpAddr, err := net.ResolveUDPAddr("udp", pAddr) + if err != nil { + return err + } + var addr connAddr + addr.fromUDPAddr(udpAddr) + a.core.udp.mutex.RLock() + _, isIn := a.core.udp.conns[addr] + a.core.udp.mutex.RUnlock() + if !isIn { + a.core.udp.sendKeys(addr) + } + return nil + case len(p) >= 4 && p[:4] == "tcp:": + default: + // Connect to peer over TCP + _, err := net.ResolveTCPAddr("tcp", pAddr) + if err != nil { + return err + } + a.core.tcp.call(p) + } + return nil +} + +func (a *admin) startTunWithMTU(ifname string, iftapmode bool, ifmtu int) error { + // Close the TUN first if open + _ = a.core.tun.close() + // Then reconfigure and start it + addr := a.core.router.addr + straddr := fmt.Sprintf("%s/%v", net.IP(addr[:]).String(), 8*len(address_prefix)) + if ifname != "none" { + err := a.core.tun.setup(ifname, iftapmode, straddr, ifmtu) + if err != nil { + return err + } + go a.core.tun.read() + } + go a.core.tun.write() + return nil +} + func (a *admin) getData_getSelf() *admin_nodeInfo { table := a.core.switchTable.table.Load().(lookupTable) addr := a.core.router.addr diff --git a/src/yggdrasil/tun.go b/src/yggdrasil/tun.go index bbe98d2..49acff6 100644 --- a/src/yggdrasil/tun.go +++ b/src/yggdrasil/tun.go @@ -66,7 +66,8 @@ func (tun *tunDevice) read() error { for { n, err := tun.iface.Read(buf) if err != nil { - panic(err) + // panic(err) + return err } o := 0 if tun.iface.IsTAP() {