diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 42ea8a51..f8749ce8 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -232,6 +232,54 @@ func (a *admin) init(c *Core, listenaddr string) { }, errors.New("Failed to remove allowed key") } }) + a.addHandler("addSourceSubnet", []string{"subnet"}, func(in admin_info) (admin_info, error) { + var err error + a.core.router.doAdmin(func() { + err = a.core.router.cryptokey.addSourceSubnet(in["subnet"].(string)) + }) + if err == nil { + return admin_info{"added": []string{in["subnet"].(string)}}, nil + } else { + return admin_info{"not_added": []string{in["subnet"].(string)}}, errors.New("Failed to add source subnet") + } + }) + a.addHandler("addRoute", []string{"subnet", "destPubKey"}, func(in admin_info) (admin_info, error) { + var err error + a.core.router.doAdmin(func() { + err = a.core.router.cryptokey.addRoute(in["subnet"].(string), in["destPubKey"].(string)) + }) + if err == nil { + return admin_info{"added": []string{fmt.Sprintf("%s via %s", in["subnet"].(string), in["destPubKey"].(string))}}, nil + } else { + return admin_info{"not_added": []string{fmt.Sprintf("%s via %s", in["subnet"].(string), in["destPubKey"].(string))}}, errors.New("Failed to add route") + } + }) + a.addHandler("getSourceSubnets", []string{}, func(in admin_info) (admin_info, error) { + var subnets []string + a.core.router.doAdmin(func() { + getSourceSubnets := func(snets []net.IPNet) { + for _, subnet := range snets { + subnets = append(subnets, subnet.String()) + } + } + getSourceSubnets(a.core.router.cryptokey.ipv4sources) + getSourceSubnets(a.core.router.cryptokey.ipv6sources) + }) + return admin_info{"source_subnets": subnets}, nil + }) + a.addHandler("getRoutes", []string{}, func(in admin_info) (admin_info, error) { + var routes []string + a.core.router.doAdmin(func() { + getRoutes := func(ckrs []cryptokey_route) { + for _, ckr := range ckrs { + routes = append(routes, fmt.Sprintf("%s via %s", ckr.subnet.String(), hex.EncodeToString(ckr.destination[:]))) + } + } + getRoutes(a.core.router.cryptokey.ipv4routes) + getRoutes(a.core.router.cryptokey.ipv6routes) + }) + return admin_info{"routes": routes}, nil + }) } // start runs the admin API socket to listen for / respond to admin API calls. diff --git a/src/yggdrasil/ckr.go b/src/yggdrasil/ckr.go index 2a054711..f440b3d8 100644 --- a/src/yggdrasil/ckr.go +++ b/src/yggdrasil/ckr.go @@ -25,7 +25,7 @@ type cryptokey struct { type cryptokey_route struct { subnet net.IPNet - destination []byte + destination boxPubKey } // Initialise crypto-key routing. This must be done before any other CKR calls. @@ -171,13 +171,15 @@ func (c *cryptokey) addRoute(cidr string, dest string) error { } } // Decode the public key - if boxPubKey, err := hex.DecodeString(dest); err != nil { + if bpk, err := hex.DecodeString(dest); err != nil && len(bpk) == boxPubKeyLen { return err } else { // Add the new crypto-key route + var key boxPubKey + copy(key[:], bpk) *routingtable = append(*routingtable, cryptokey_route{ subnet: *ipnet, - destination: boxPubKey, + destination: key, }) // Sort so most specific routes are first @@ -227,9 +229,7 @@ func (c *cryptokey) getPublicKeyForAddress(addr address, addrlen int) (boxPubKey // Check if there's a cache entry for this addr if route, ok := (*routingcache)[addr]; ok { - var box boxPubKey - copy(box[:boxPubKeyLen], route.destination) - return box, nil + return route.destination, nil } // No cache was found - start by converting the address into a net.IP @@ -245,9 +245,7 @@ func (c *cryptokey) getPublicKeyForAddress(addr address, addrlen int) (boxPubKey (*routingcache)[addr] = route // Return the boxPubKey - var box boxPubKey - copy(box[:boxPubKeyLen], route.destination) - return box, nil + return route.destination, nil } } diff --git a/yggdrasilctl.go b/yggdrasilctl.go index d98386b7..13a0c234 100644 --- a/yggdrasilctl.go +++ b/yggdrasilctl.go @@ -231,7 +231,7 @@ func main() { uint(k), uint(v), uint(queuesizepercent), uint(portqueuepackets[k])) } } - case "addpeer", "removepeer", "addallowedencryptionpublickey", "removeallowedencryptionpublickey": + case "addpeer", "removepeer", "addallowedencryptionpublickey", "removeallowedencryptionpublickey", "addsourcesubnet", "addroute": if _, ok := res["added"]; ok { for _, v := range res["added"].([]interface{}) { fmt.Println("Added:", fmt.Sprint(v))