diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 656df8c..3c191c8 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -189,41 +189,40 @@ func run() int { } table.Render() - case "getdht": - var resp admin.GetDHTResponse + case "gettree": + var resp admin.GetTreeResponse if err := json.Unmarshal(recv.Response, &resp); err != nil { panic(err) } //table.SetHeader([]string{"Public Key", "IP Address", "Port", "Rest"}) table.SetHeader([]string{"Public Key", "IP Address", "Parent", "Sequence"}) - for _, dht := range resp.DHT { + for _, tree := range resp.Tree { table.Append([]string{ - dht.PublicKey, - dht.IPAddress, - dht.Parent, - fmt.Sprintf("%d", dht.Sequence), + tree.PublicKey, + tree.IPAddress, + tree.Parent, + fmt.Sprintf("%d", tree.Sequence), //fmt.Sprintf("%d", dht.Port), //fmt.Sprintf("%d", dht.Rest), }) } table.Render() - /* - case "getpaths": - var resp admin.GetPathsResponse - if err := json.Unmarshal(recv.Response, &resp); err != nil { - panic(err) - } - table.SetHeader([]string{"Public Key", "IP Address", "Seq"}) - for _, p := range resp.Paths { - table.Append([]string{ - p.PublicKey, - p.IPAddress, - fmt.Sprintf("%d", p.Sequence), - }) - } - table.Render() - */ + case "getpaths": + var resp admin.GetPathsResponse + if err := json.Unmarshal(recv.Response, &resp); err != nil { + panic(err) + } + table.SetHeader([]string{"Public Key", "IP Address", "Path", "Seq"}) + for _, p := range resp.Paths { + table.Append([]string{ + p.PublicKey, + p.IPAddress, + fmt.Sprintf("%v", p.Path), + fmt.Sprintf("%d", p.Sequence), + }) + } + table.Render() case "getsessions": var resp admin.GetSessionsResponse diff --git a/contrib/ansible/genkeys.go b/contrib/ansible/genkeys.go index 4a02b9b..c1aed7e 100644 --- a/contrib/ansible/genkeys.go +++ b/contrib/ansible/genkeys.go @@ -1,7 +1,5 @@ /* - This file generates crypto keys for [ansible-yggdrasil](https://github.com/jcgruenhage/ansible-yggdrasil/) - */ package main diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index 7993799..dcf5eb2 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -190,10 +190,9 @@ func (m *Yggdrasil) GetPublicKeyString() string { return hex.EncodeToString(m.core.GetSelf().Key) } -// GetCoordsString gets the node's coordinates -func (m *Yggdrasil) GetCoordsString() string { - return "N/A" - // return fmt.Sprintf("%v", m.core.GetSelf().Coords) +// GetRoutingEntries gets the number of entries in the routing table +func (m *Yggdrasil) GetRoutingEntries() int { + return int(m.core.GetSelf().RoutingEntries) } func (m *Yggdrasil) GetPeersJSON() (result string) { @@ -219,8 +218,16 @@ func (m *Yggdrasil) GetPeersJSON() (result string) { } } -func (m *Yggdrasil) GetDHTJSON() (result string) { - if res, err := json.Marshal(m.core.GetDHT()); err == nil { +func (m *Yggdrasil) GetPathsJSON() (result string) { + if res, err := json.Marshal(m.core.GetPaths()); err == nil { + return string(res) + } else { + return "{}" + } +} + +func (m *Yggdrasil) GetTreeJSON() (result string) { + if res, err := json.Marshal(m.core.GetTree()); err == nil { return string(res) } else { return "{}" diff --git a/contrib/mobile/mobile_test.go b/contrib/mobile/mobile_test.go index 1991640..880e5fc 100644 --- a/contrib/mobile/mobile_test.go +++ b/contrib/mobile/mobile_test.go @@ -9,7 +9,7 @@ func TestStartYggdrasil(t *testing.T) { } t.Log("Address:", ygg.GetAddressString()) t.Log("Subnet:", ygg.GetSubnetString()) - t.Log("Coords:", ygg.GetCoordsString()) + t.Log("Routing entries:", ygg.GetRoutingEntries()) if err := ygg.Stop(); err != nil { t.Fatalf("Failed to stop Yggdrasil: %s", err) } diff --git a/go.mod b/go.mod index 970e0f9..dd6dfb4 100644 --- a/go.mod +++ b/go.mod @@ -2,10 +2,8 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.19 -replace github.com/Arceliar/ironwood => github.com/Arceliar/ironwood v0.0.0-20230326213941-b977dd93b701 - require ( - github.com/Arceliar/ironwood v0.0.0-20230506230631-14d951aa1d45 + github.com/Arceliar/ironwood v0.0.0-20230515022317-31b976732ebe github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d github.com/cheggaaa/pb/v3 v3.0.8 github.com/gologme/log v1.2.0 @@ -15,19 +13,21 @@ require ( github.com/mitchellh/mapstructure v1.4.1 github.com/vishvananda/netlink v1.1.0 golang.org/x/mobile v0.0.0-20221110043201-43a038452099 - golang.org/x/net v0.7.0 - golang.org/x/sys v0.5.0 - golang.org/x/text v0.7.0 + golang.org/x/net v0.9.0 + golang.org/x/sys v0.7.0 + golang.org/x/text v0.9.0 golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a golang.zx2c4.com/wireguard/windows v0.4.12 ) require ( + github.com/bits-and-blooms/bitset v1.5.0 // indirect + github.com/bits-and-blooms/bloom/v3 v3.3.1 // indirect github.com/mattn/go-colorable v0.1.8 // indirect github.com/rivo/uniseg v0.2.0 // indirect - golang.org/x/crypto v0.0.0-20221012134737-56aed061732a // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/tools v0.1.12 // indirect + golang.org/x/crypto v0.8.0 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/tools v0.6.0 // indirect ) require ( diff --git a/go.sum b/go.sum index 7fe478a..0a0e6b8 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,15 @@ -github.com/Arceliar/ironwood v0.0.0-20230326213941-b977dd93b701 h1:Cce66vRcL0hjO/wVqBU22d2r/J5+61N/aMzfPizMS5E= -github.com/Arceliar/ironwood v0.0.0-20230326213941-b977dd93b701/go.mod h1:PhT70gxs32jSoxpi5gLlvCguWTzbpaqnNRTY6GgFPBY= +github.com/Arceliar/ironwood v0.0.0-20230515022317-31b976732ebe h1:u69sr6Y9jqu6sk43Yyt+izLnLGgqCw3OYh2HU+jYUBw= +github.com/Arceliar/ironwood v0.0.0-20230515022317-31b976732ebe/go.mod h1:MIfrhR4b+U6gurd5pln622Zwaf2kzpIvXcnvRZMvlRI= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM= github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q= github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/bits-and-blooms/bitset v1.3.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bloom/v3 v3.3.1 h1:K2+A19bXT8gJR5mU7y+1yW6hsKfNCjcP2uNfLFKncjQ= +github.com/bits-and-blooms/bloom/v3 v3.3.1/go.mod h1:bhUUknWd5khVbTe4UgMCSiOOVJzr3tMoijSK3WwvW90= github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA= github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= @@ -34,36 +39,62 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6 github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= +github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg= -golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/mobile v0.0.0-20221110043201-43a038452099 h1:aIu0lKmfdgtn2uTj7JI2oN4TUrQvgB+wzTPO23bCKt8= golang.org/x/mobile v0.0.0-20221110043201-43a038452099/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a h1:tTbyylK9/D3u/wEP26Vx7L700UpY48nhioJWZM1vhZw= golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= golang.zx2c4.com/wireguard/windows v0.4.12 h1:CUmbdWKVNzTSsVb4yUAiEwL3KsabdJkEPdDjCHxBlhA= diff --git a/src/admin/admin.go b/src/admin/admin.go index be4482f..d0d444b 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -132,35 +132,33 @@ func (a *AdminSocket) SetupAdminHandlers() { }, ) _ = a.AddHandler( - "getDHT", "Show known DHT entries", []string{}, + "getTree", "Show known Tree entries", []string{}, func(in json.RawMessage) (interface{}, error) { - req := &GetDHTRequest{} - res := &GetDHTResponse{} + req := &GetTreeRequest{} + res := &GetTreeResponse{} if err := json.Unmarshal(in, &req); err != nil { return nil, err } - if err := a.getDHTHandler(req, res); err != nil { + if err := a.getTreeHandler(req, res); err != nil { + return nil, err + } + return res, nil + }, + ) + _ = a.AddHandler( + "getPaths", "Show established paths through this node", []string{}, + func(in json.RawMessage) (interface{}, error) { + req := &GetPathsRequest{} + res := &GetPathsResponse{} + if err := json.Unmarshal(in, &req); err != nil { + return nil, err + } + if err := a.getPathsHandler(req, res); err != nil { return nil, err } return res, nil }, ) - /* - _ = a.AddHandler( - "getPaths", "Show established paths through this node", []string{}, - func(in json.RawMessage) (interface{}, error) { - req := &GetPathsRequest{} - res := &GetPathsResponse{} - if err := json.Unmarshal(in, &req); err != nil { - return nil, err - } - if err := a.getPathsHandler(req, res); err != nil { - return nil, err - } - return res, nil - }, - ) - */ _ = a.AddHandler( "getSessions", "Show established traffic sessions with remote nodes", []string{}, func(in json.RawMessage) (interface{}, error) { diff --git a/src/admin/getpaths.go b/src/admin/getpaths.go index 94a9945..66e11bd 100644 --- a/src/admin/getpaths.go +++ b/src/admin/getpaths.go @@ -1,7 +1,5 @@ package admin -/* - import ( "encoding/hex" "net" @@ -19,9 +17,10 @@ type GetPathsResponse struct { } type PathEntry struct { - IPAddress string `json:"address"` - PublicKey string `json:"key"` - Sequence uint64 `json:"sequence"` + IPAddress string `json:"address"` + PublicKey string `json:"key"` + Path []uint64 `json:"path"` + Sequence uint64 `json:"sequence"` } func (a *AdminSocket) getPathsHandler(req *GetPathsRequest, res *GetPathsResponse) error { @@ -32,6 +31,7 @@ func (a *AdminSocket) getPathsHandler(req *GetPathsRequest, res *GetPathsRespons res.Paths = append(res.Paths, PathEntry{ IPAddress: net.IP(addr[:]).String(), PublicKey: hex.EncodeToString(p.Key), + Path: p.Path, Sequence: p.Sequence, }) } @@ -40,5 +40,3 @@ func (a *AdminSocket) getPathsHandler(req *GetPathsRequest, res *GetPathsRespons }) return nil } - -*/ diff --git a/src/admin/getdht.go b/src/admin/gettree.go similarity index 56% rename from src/admin/getdht.go rename to src/admin/gettree.go index acddad7..06cf8e7 100644 --- a/src/admin/getdht.go +++ b/src/admin/gettree.go @@ -9,13 +9,13 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/address" ) -type GetDHTRequest struct{} +type GetTreeRequest struct{} -type GetDHTResponse struct { - DHT []DHTEntry `json:"dht"` +type GetTreeResponse struct { + Tree []TreeEntry `json:"tree"` } -type DHTEntry struct { +type TreeEntry struct { IPAddress string `json:"address"` PublicKey string `json:"key"` Parent string `json:"parent"` @@ -24,12 +24,12 @@ type DHTEntry struct { //Rest uint64 `json:"rest"` } -func (a *AdminSocket) getDHTHandler(req *GetDHTRequest, res *GetDHTResponse) error { - dht := a.core.GetDHT() - res.DHT = make([]DHTEntry, 0, len(dht)) - for _, d := range dht { +func (a *AdminSocket) getTreeHandler(req *GetTreeRequest, res *GetTreeResponse) error { + tree := a.core.GetTree() + res.Tree = make([]TreeEntry, 0, len(tree)) + for _, d := range tree { addr := address.AddrForKey(d.Key) - res.DHT = append(res.DHT, DHTEntry{ + res.Tree = append(res.Tree, TreeEntry{ IPAddress: net.IP(addr[:]).String(), PublicKey: hex.EncodeToString(d.Key[:]), Parent: hex.EncodeToString(d.Parent[:]), @@ -38,8 +38,8 @@ func (a *AdminSocket) getDHTHandler(req *GetDHTRequest, res *GetDHTResponse) err //Rest: d.Rest, }) } - sort.SliceStable(res.DHT, func(i, j int) bool { - return strings.Compare(res.DHT[i].PublicKey, res.DHT[j].PublicKey) < 0 + sort.SliceStable(res.Tree, func(i, j int) bool { + return strings.Compare(res.Tree[i].PublicKey, res.Tree[j].PublicKey) < 0 }) return nil } diff --git a/src/core/api.go b/src/core/api.go index da4ead5..feece23 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -30,7 +30,7 @@ type PeerInfo struct { Uptime time.Duration } -type DHTEntryInfo struct { +type TreeEntryInfo struct { Key ed25519.PublicKey Parent ed25519.PublicKey Sequence uint64 @@ -38,12 +38,11 @@ type DHTEntryInfo struct { //Rest uint64 } -/* type PathEntryInfo struct { Key ed25519.PublicKey + Path []uint64 Sequence uint64 } -*/ type SessionInfo struct { Key ed25519.PublicKey @@ -94,22 +93,21 @@ func (c *Core) GetPeers() []PeerInfo { return peers } -func (c *Core) GetDHT() []DHTEntryInfo { - var dhts []DHTEntryInfo - ds := c.PacketConn.PacketConn.Debug.GetDHT() - for _, d := range ds { - var info DHTEntryInfo - info.Key = d.Key - info.Parent = d.Parent - info.Sequence = d.Sequence +func (c *Core) GetTree() []TreeEntryInfo { + var trees []TreeEntryInfo + ts := c.PacketConn.PacketConn.Debug.GetTree() + for _, t := range ts { + var info TreeEntryInfo + info.Key = t.Key + info.Parent = t.Parent + info.Sequence = t.Sequence //info.Port = d.Port //info.Rest = d.Rest - dhts = append(dhts, info) + trees = append(trees, info) } - return dhts + return trees } -/* func (c *Core) GetPaths() []PathEntryInfo { var paths []PathEntryInfo ps := c.PacketConn.PacketConn.Debug.GetPaths() @@ -117,12 +115,11 @@ func (c *Core) GetPaths() []PathEntryInfo { var info PathEntryInfo info.Key = p.Key info.Sequence = p.Sequence - //info.Path = p.Path + info.Path = p.Path paths = append(paths, info) } return paths } -*/ func (c *Core) GetSessions() []SessionInfo { var sessions []SessionInfo @@ -282,8 +279,8 @@ func (c *Core) SetAdmin(a AddHandler) error { return err } if err := a.AddHandler( - "debug_remoteGetDHT", "Debug use only", []string{"key"}, - c.proto.getDHTHandler, + "debug_remoteGetTree", "Debug use only", []string{"key"}, + c.proto.getTreeHandler, ); err != nil { return err } diff --git a/src/core/core.go b/src/core/core.go index bbf5b63..9243be0 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -10,10 +10,12 @@ import ( "time" iwe "github.com/Arceliar/ironwood/encrypted" + iwn "github.com/Arceliar/ironwood/network" iwt "github.com/Arceliar/ironwood/types" "github.com/Arceliar/phony" "github.com/gologme/log" + "github.com/yggdrasil-network/yggdrasil-go/src/address" "github.com/yggdrasil-network/yggdrasil-go/src/version" ) @@ -40,6 +42,7 @@ type Core struct { nodeinfoPrivacy NodeInfoPrivacy // immutable after startup _allowedPublicKeys map[[32]byte]struct{} // configurable after startup } + pathNotify func(ed25519.PublicKey) } func New(secret ed25519.PrivateKey, logger Logger, opts ...SetupOption) (*Core, error) { @@ -61,7 +64,14 @@ func New(secret ed25519.PrivateKey, logger Logger, opts ...SetupOption) (*Core, copy(c.secret, secret) c.public = secret.Public().(ed25519.PublicKey) var err error - if c.PacketConn, err = iwe.NewPacketConn(c.secret); err != nil { + keyXform := func(key ed25519.PublicKey) ed25519.PublicKey { + return address.SubnetForKey(key).GetKey() + } + if c.PacketConn, err = iwe.NewPacketConn(c.secret, + iwn.WithBloomTransform(keyXform), + iwn.WithPeerMaxMessageSize(65535*2), + iwn.WithPathNotify(c.doPathNotify), + ); err != nil { return nil, fmt.Errorf("error creating encryption: %w", err) } c.config._peers = map[Peer]*linkInfo{} @@ -151,11 +161,15 @@ func (c *Core) _close() error { func (c *Core) MTU() uint64 { const sessionTypeOverhead = 1 - return c.PacketConn.MTU() - sessionTypeOverhead + MTU := c.PacketConn.MTU() - sessionTypeOverhead + if MTU > 65535 { + MTU = 65535 + } + return MTU } func (c *Core) ReadFrom(p []byte) (n int, from net.Addr, err error) { - buf := make([]byte, c.PacketConn.MTU(), 65535) + buf := make([]byte, c.PacketConn.MTU()) for { bs := buf n, from, err = c.PacketConn.ReadFrom(bs) @@ -199,6 +213,20 @@ func (c *Core) WriteTo(p []byte, addr net.Addr) (n int, err error) { return } +func (c *Core) doPathNotify(key ed25519.PublicKey) { + c.Act(nil, func() { + if c.pathNotify != nil { + c.pathNotify(key) + } + }) +} + +func (c *Core) SetPathNotify(notify func(ed25519.PublicKey)) { + c.Act(nil, func() { + c.pathNotify = notify + }) +} + type Logger interface { Printf(string, ...interface{}) Println(...interface{}) diff --git a/src/core/core_test.go b/src/core/core_test.go index f917030..ce28f4e 100644 --- a/src/core/core_test.go +++ b/src/core/core_test.go @@ -75,7 +75,8 @@ func WaitConnected(nodeA, nodeB *Core) bool { return true } */ - if len(nodeA.GetDHT()) > 1 && len(nodeB.GetDHT()) > 1 { + if len(nodeA.GetTree()) > 1 && len(nodeB.GetTree()) > 1 { + time.Sleep(3*time.Second) // FIXME hack, there's still stuff happening internally return true } } diff --git a/src/core/proto.go b/src/core/proto.go index 186e9b8..d8cae73 100644 --- a/src/core/proto.go +++ b/src/core/proto.go @@ -21,8 +21,8 @@ const ( typeDebugGetSelfResponse typeDebugGetPeersRequest typeDebugGetPeersResponse - typeDebugGetDHTRequest - typeDebugGetDHTResponse + typeDebugGetTreeRequest + typeDebugGetTreeResponse ) type reqInfo struct { @@ -40,7 +40,7 @@ type protoHandler struct { selfRequests map[keyArray]*reqInfo peersRequests map[keyArray]*reqInfo - dhtRequests map[keyArray]*reqInfo + treeRequests map[keyArray]*reqInfo } func (p *protoHandler) init(core *Core) { @@ -49,7 +49,7 @@ func (p *protoHandler) init(core *Core) { p.selfRequests = make(map[keyArray]*reqInfo) p.peersRequests = make(map[keyArray]*reqInfo) - p.dhtRequests = make(map[keyArray]*reqInfo) + p.treeRequests = make(map[keyArray]*reqInfo) } // Common functions @@ -89,10 +89,10 @@ func (p *protoHandler) _handleDebug(key keyArray, bs []byte) { p._handleGetPeersRequest(key) case typeDebugGetPeersResponse: p._handleGetPeersResponse(key, bs[1:]) - case typeDebugGetDHTRequest: - p._handleGetDHTRequest(key) - case typeDebugGetDHTResponse: - p._handleGetDHTResponse(key, bs[1:]) + case typeDebugGetTreeRequest: + p._handleGetTreeRequest(key) + case typeDebugGetTreeResponse: + p._handleGetTreeResponse(key, bs[1:]) } } @@ -188,47 +188,47 @@ func (p *protoHandler) _handleGetPeersResponse(key keyArray, bs []byte) { } } -// Get DHT +// Get Tree -func (p *protoHandler) sendGetDHTRequest(key keyArray, callback func([]byte)) { +func (p *protoHandler) sendGetTreeRequest(key keyArray, callback func([]byte)) { p.Act(nil, func() { - if info := p.dhtRequests[key]; info != nil { + if info := p.treeRequests[key]; info != nil { info.timer.Stop() - delete(p.dhtRequests, key) + delete(p.treeRequests, key) } info := new(reqInfo) info.callback = callback info.timer = time.AfterFunc(time.Minute, func() { p.Act(nil, func() { - if p.dhtRequests[key] == info { - delete(p.dhtRequests, key) + if p.treeRequests[key] == info { + delete(p.treeRequests, key) } }) }) - p.dhtRequests[key] = info - p._sendDebug(key, typeDebugGetDHTRequest, nil) + p.treeRequests[key] = info + p._sendDebug(key, typeDebugGetTreeRequest, nil) }) } -func (p *protoHandler) _handleGetDHTRequest(key keyArray) { - dinfos := p.core.GetDHT() +func (p *protoHandler) _handleGetTreeRequest(key keyArray) { + dinfos := p.core.GetTree() var bs []byte for _, dinfo := range dinfos { tmp := append(bs, dinfo.Key[:]...) - const responseOverhead = 2 // 1 debug type, 1 getdht type + const responseOverhead = 2 // 1 debug type, 1 gettree type if uint64(len(tmp))+responseOverhead > p.core.MTU() { break } bs = tmp } - p._sendDebug(key, typeDebugGetDHTResponse, bs) + p._sendDebug(key, typeDebugGetTreeResponse, bs) } -func (p *protoHandler) _handleGetDHTResponse(key keyArray, bs []byte) { - if info := p.dhtRequests[key]; info != nil { +func (p *protoHandler) _handleGetTreeResponse(key keyArray, bs []byte) { + if info := p.treeRequests[key]; info != nil { info.timer.Stop() info.callback(bs) - delete(p.dhtRequests, key) + delete(p.treeRequests, key) } } @@ -322,16 +322,16 @@ func (p *protoHandler) getPeersHandler(in json.RawMessage) (interface{}, error) } } -// Admin socket stuff for "Get DHT" +// Admin socket stuff for "Get Tree" -type DebugGetDHTRequest struct { +type DebugGetTreeRequest struct { Key string `json:"key"` } -type DebugGetDHTResponse map[string]interface{} +type DebugGetTreeResponse map[string]interface{} -func (p *protoHandler) getDHTHandler(in json.RawMessage) (interface{}, error) { - var req DebugGetDHTRequest +func (p *protoHandler) getTreeHandler(in json.RawMessage) (interface{}, error) { + var req DebugGetTreeRequest if err := json.Unmarshal(in, &req); err != nil { return nil, err } @@ -343,7 +343,7 @@ func (p *protoHandler) getDHTHandler(in json.RawMessage) (interface{}, error) { } copy(key[:], kbs) ch := make(chan []byte, 1) - p.sendGetDHTRequest(key, func(info []byte) { + p.sendGetTreeRequest(key, func(info []byte) { ch <- info }) timer := time.NewTimer(6 * time.Second) @@ -367,7 +367,7 @@ func (p *protoHandler) getDHTHandler(in json.RawMessage) (interface{}, error) { return nil, err } ip := net.IP(address.AddrForKey(kbs)[:]) - res := DebugGetDHTResponse{ip.String(): msg} + res := DebugGetTreeResponse{ip.String(): msg} return res, nil } } diff --git a/src/ipv6rwc/ipv6rwc.go b/src/ipv6rwc/ipv6rwc.go index 22213c5..59f4f02 100644 --- a/src/ipv6rwc/ipv6rwc.go +++ b/src/ipv6rwc/ipv6rwc.go @@ -31,16 +31,16 @@ const ( type keyArray [ed25519.PublicKeySize]byte type keyStore struct { - core *core.Core - address address.Address - subnet address.Subnet - mutex sync.Mutex - keyToInfo map[keyArray]*keyInfo - addrToInfo map[address.Address]*keyInfo - //addrBuffer map[address.Address]*buffer + core *core.Core + address address.Address + subnet address.Subnet + mutex sync.Mutex + keyToInfo map[keyArray]*keyInfo + addrToInfo map[address.Address]*keyInfo + addrBuffer map[address.Address]*buffer subnetToInfo map[address.Subnet]*keyInfo - //subnetBuffer map[address.Subnet]*buffer - mtu uint64 + subnetBuffer map[address.Subnet]*buffer + mtu uint64 } type keyInfo struct { @@ -50,12 +50,10 @@ type keyInfo struct { timeout *time.Timer // From calling a time.AfterFunc to do cleanup } -/* type buffer struct { packet []byte timeout *time.Timer } -*/ func (k *keyStore) init(c *core.Core) { k.core = c @@ -65,11 +63,14 @@ func (k *keyStore) init(c *core.Core) { err = fmt.Errorf("tun.core.SetOutOfBandHander: %w", err) panic(err) }*/ + k.core.SetPathNotify(func(key ed25519.PublicKey) { + k.update(key) + }) k.keyToInfo = make(map[keyArray]*keyInfo) k.addrToInfo = make(map[address.Address]*keyInfo) - //k.addrBuffer = make(map[address.Address]*buffer) + k.addrBuffer = make(map[address.Address]*buffer) k.subnetToInfo = make(map[address.Subnet]*keyInfo) - //k.subnetBuffer = make(map[address.Subnet]*buffer) + k.subnetBuffer = make(map[address.Subnet]*buffer) k.mtu = 1280 // Default to something safe, expect user to set this } @@ -80,33 +81,25 @@ func (k *keyStore) sendToAddress(addr address.Address, bs []byte) { k.mutex.Unlock() _, _ = k.core.WriteTo(bs, iwt.Addr(info.key[:])) } else { - /* - var buf *buffer - if buf = k.addrBuffer[addr]; buf == nil { - buf = new(buffer) - k.addrBuffer[addr] = buf - } - msg := append([]byte(nil), bs...) - buf.packet = msg - if buf.timeout != nil { - buf.timeout.Stop() - } - buf.timeout = time.AfterFunc(keyStoreTimeout, func() { - k.mutex.Lock() - defer k.mutex.Unlock() - if nbuf := k.addrBuffer[addr]; nbuf == buf { - delete(k.addrBuffer, addr) - } - }) - k.mutex.Unlock() - k.sendKeyLookup(addr.GetKey()) - */ - k.mutex.Unlock() - key := k.core.GetKeyFor(addr.GetKey()) - info := k.update(key) - if info.address == addr { - _, _ = k.core.WriteTo(bs, iwt.Addr(info.key[:])) + var buf *buffer + if buf = k.addrBuffer[addr]; buf == nil { + buf = new(buffer) + k.addrBuffer[addr] = buf } + msg := append([]byte(nil), bs...) + buf.packet = msg + if buf.timeout != nil { + buf.timeout.Stop() + } + buf.timeout = time.AfterFunc(keyStoreTimeout, func() { + k.mutex.Lock() + defer k.mutex.Unlock() + if nbuf := k.addrBuffer[addr]; nbuf == buf { + delete(k.addrBuffer, addr) + } + }) + k.mutex.Unlock() + k.sendKeyLookup(addr.GetKey()) } } @@ -117,33 +110,25 @@ func (k *keyStore) sendToSubnet(subnet address.Subnet, bs []byte) { k.mutex.Unlock() _, _ = k.core.WriteTo(bs, iwt.Addr(info.key[:])) } else { - /* - var buf *buffer - if buf = k.subnetBuffer[subnet]; buf == nil { - buf = new(buffer) - k.subnetBuffer[subnet] = buf - } - msg := append([]byte(nil), bs...) - buf.packet = msg - if buf.timeout != nil { - buf.timeout.Stop() - } - buf.timeout = time.AfterFunc(keyStoreTimeout, func() { - k.mutex.Lock() - defer k.mutex.Unlock() - if nbuf := k.subnetBuffer[subnet]; nbuf == buf { - delete(k.subnetBuffer, subnet) - } - }) - k.mutex.Unlock() - k.sendKeyLookup(subnet.GetKey()) - */ - k.mutex.Unlock() - key := k.core.GetKeyFor(subnet.GetKey()) - info := k.update(key) - if info.subnet == subnet { - _, _ = k.core.WriteTo(bs, iwt.Addr(info.key[:])) + var buf *buffer + if buf = k.subnetBuffer[subnet]; buf == nil { + buf = new(buffer) + k.subnetBuffer[subnet] = buf } + msg := append([]byte(nil), bs...) + buf.packet = msg + if buf.timeout != nil { + buf.timeout.Stop() + } + buf.timeout = time.AfterFunc(keyStoreTimeout, func() { + k.mutex.Lock() + defer k.mutex.Unlock() + if nbuf := k.subnetBuffer[subnet]; nbuf == buf { + delete(k.subnetBuffer, subnet) + } + }) + k.mutex.Unlock() + k.sendKeyLookup(subnet.GetKey()) } } @@ -161,16 +146,14 @@ func (k *keyStore) update(key ed25519.PublicKey) *keyInfo { k.keyToInfo[info.key] = info k.addrToInfo[info.address] = info k.subnetToInfo[info.subnet] = info - /* - if buf := k.addrBuffer[info.address]; buf != nil { - packets = append(packets, buf.packet) - delete(k.addrBuffer, info.address) - } - if buf := k.subnetBuffer[info.subnet]; buf != nil { - packets = append(packets, buf.packet) - delete(k.subnetBuffer, info.subnet) - } - */ + if buf := k.addrBuffer[info.address]; buf != nil { + packets = append(packets, buf.packet) + delete(k.addrBuffer, info.address) + } + if buf := k.subnetBuffer[info.subnet]; buf != nil { + packets = append(packets, buf.packet) + delete(k.subnetBuffer, info.subnet) + } } k.resetTimeout(info) k.mutex.Unlock() @@ -223,14 +206,17 @@ func (k *keyStore) oobHandler(fromKey, toKey ed25519.PublicKey, data []byte) { / } */ -/* func (k *keyStore) sendKeyLookup(partial ed25519.PublicKey) { - sig := ed25519.Sign(k.core.PrivateKey(), partial[:]) - bs := append([]byte{typeKeyLookup}, sig...) - //_ = k.core.SendOutOfBand(partial, bs) - _ = bs + /* + sig := ed25519.Sign(k.core.PrivateKey(), partial[:]) + bs := append([]byte{typeKeyLookup}, sig...) + //_ = k.core.SendOutOfBand(partial, bs) + _ = bs + */ + k.core.SendLookup(partial) } +/* func (k *keyStore) sendKeyResponse(dest ed25519.PublicKey) { // nolint:unused sig := ed25519.Sign(k.core.PrivateKey(), dest[:]) bs := append([]byte{typeKeyResponse}, sig...)