diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/admin/admin.go b/src/admin/admin.go index db4b64b..59d0f95 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -282,7 +282,7 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log. if in["nocache"] != nil { nocache = in["nocache"].(string) == "true" } - var box_pub_key string + var boxPubKey crypto.BoxPubKey var coords []uint64 if in["box_pub_key"] == nil && in["coords"] == nil { nodeinfo := a.core.MyNodeInfo() @@ -295,10 +295,14 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log. } else if in["box_pub_key"] == nil || in["coords"] == nil { return Info{}, errors.New("Expecting both box_pub_key and coords") } else { - box_pub_key = in["box_pub_key"].(string) + if b, err := hex.DecodeString(in["box_pub_key"].(string)); err == nil { + copy(boxPubKey[:], b[:]) + } else { + return Info{}, err + } coords = util.DecodeCoordString(in["coords"].(string)) } - result, err := a.core.GetNodeInfo(box_pub_key, coords, nocache) + result, err := a.core.GetNodeInfo(boxPubKey, coords, nocache) if err == nil { var m map[string]interface{} if err = json.Unmarshal(result, &m); err == nil { diff --git a/src/util/util.go b/src/util/util.go index 5be9760..6fb515c 100644 --- a/src/util/util.go +++ b/src/util/util.go @@ -97,7 +97,7 @@ func Difference(a, b []string) []string { } // DecodeCoordString decodes a string representing coordinates in [1 2 3] format -// and returns a []byte. +// and returns a []uint64. func DecodeCoordString(in string) (out []uint64) { s := strings.Trim(in, "[]") t := strings.Split(s, " ") diff --git a/src/yggdrasil/api.go b/src/yggdrasil/api.go index f1cfc18..98f9013 100644 --- a/src/yggdrasil/api.go +++ b/src/yggdrasil/api.go @@ -32,7 +32,7 @@ type Peer struct { // to a given node. type SwitchPeer struct { PublicKey crypto.BoxPubKey - Coords []byte + Coords []uint64 BytesSent uint64 BytesRecvd uint64 Port uint64 @@ -83,7 +83,7 @@ type SwitchQueue struct { // Session represents an open session with another node. type Session struct { PublicKey crypto.BoxPubKey - Coords []byte + Coords []uint64 BytesSent uint64 BytesRecvd uint64 MTU uint16 @@ -136,7 +136,7 @@ func (c *Core) GetSwitchPeers() []SwitchPeer { } coords := elem.locator.getCoords() info := SwitchPeer{ - Coords: append([]byte{}, coords...), + Coords: append([]uint64{}, wire_coordsBytestoUint64s(coords)...), BytesSent: atomic.LoadUint64(&peer.bytesSent), BytesRecvd: atomic.LoadUint64(&peer.bytesRecvd), Port: uint64(elem.port), @@ -164,7 +164,7 @@ func (c *Core) GetDHT() []DHTEntry { }) for _, v := range dhtentry { info := DHTEntry{ - Coords: append([]uint64{}, coordsBytestoUint64s(v.coords)...), + Coords: append([]uint64{}, wire_coordsBytestoUint64s(v.coords)...), LastSeen: now.Sub(v.recv), } copy(info.PublicKey[:], v.key[:]) @@ -212,7 +212,7 @@ func (c *Core) GetSessions() []Session { var session Session workerFunc := func() { session = Session{ - Coords: append([]byte{}, sinfo.coords...), + Coords: append([]uint64{}, wire_coordsBytestoUint64s(sinfo.coords)...), MTU: sinfo.getMTU(), BytesSent: sinfo.bytesSent, BytesRecvd: sinfo.bytesRecvd, @@ -309,9 +309,9 @@ func (c *Core) EncryptionPublicKey() string { } // Coords returns the current coordinates of the node. -func (c *Core) Coords() []byte { +func (c *Core) Coords() []uint64 { table := c.switchTable.table.Load().(lookupTable) - return table.self.getCoords() + return wire_coordsBytestoUint64s(table.self.getCoords()) } // Address gets the IPv6 address of the Yggdrasil node. This is always a /128 @@ -334,8 +334,8 @@ func (c *Core) MyNodeInfo() NodeInfoPayload { return c.router.nodeinfo.getNodeInfo() } -// SetNodeInfo the lcal nodeinfo. Note that nodeinfo can be any value or struct, -// it will be serialised into JSON automatically. +// SetNodeInfo sets the local nodeinfo. Note that nodeinfo can be any value or +// struct, it will be serialised into JSON automatically. func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) { c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy) } @@ -344,7 +344,7 @@ func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) { // key and coordinates specified. The third parameter specifies whether a cached // result is acceptable - this results in less traffic being generated than is // necessary when, e.g. crawling the network. -func (c *Core) GetNodeInfo(key crypto.BoxPubKey, coords []byte, nocache bool) (NodeInfoPayload, error) { +func (c *Core) GetNodeInfo(key crypto.BoxPubKey, coords []uint64, nocache bool) (NodeInfoPayload, error) { response := make(chan *NodeInfoPayload, 1) sendNodeInfoRequest := func() { c.router.nodeinfo.addCallback(key, func(nodeinfo *NodeInfoPayload) { @@ -354,7 +354,7 @@ func (c *Core) GetNodeInfo(key crypto.BoxPubKey, coords []byte, nocache bool) (N default: } }) - c.router.nodeinfo.sendNodeInfo(key, coords, false) + c.router.nodeinfo.sendNodeInfo(key, wire_coordsUint64stoBytes(coords), false) } c.router.doAdmin(sendNodeInfoRequest) go func() { @@ -456,7 +456,7 @@ func (c *Core) DHTPing(key crypto.BoxPubKey, coords []uint64, target *crypto.Nod resCh := make(chan *dhtRes, 1) info := dhtInfo{ key: key, - coords: coordsUint64stoBytes(coords), + coords: wire_coordsUint64stoBytes(coords), } if target == nil { target = info.getNodeID() @@ -473,12 +473,12 @@ func (c *Core) DHTPing(key crypto.BoxPubKey, coords []uint64, target *crypto.Nod res := <-resCh if res != nil { r := DHTRes{ - Coords: append([]uint64{}, coordsBytestoUint64s(res.Coords)...), + Coords: append([]uint64{}, wire_coordsBytestoUint64s(res.Coords)...), } copy(r.PublicKey[:], res.Key[:]) for _, i := range res.Infos { e := DHTEntry{ - Coords: append([]uint64{}, coordsBytestoUint64s(i.coords)...), + Coords: append([]uint64{}, wire_coordsBytestoUint64s(i.coords)...), } copy(e.PublicKey[:], i.key[:]) r.Infos = append(r.Infos, e) diff --git a/src/yggdrasil/switch.go b/src/yggdrasil/switch.go index 34b57aa..1bc4050 100644 --- a/src/yggdrasil/switch.go +++ b/src/yggdrasil/switch.go @@ -137,27 +137,6 @@ type peerInfo struct { // This is just a uint64 with a named type for clarity reasons. type switchPort uint64 -func coordsUint64stoBytes(in []uint64) (out []byte) { - for _, coord := range in { - c := wire_encode_uint64(coord) - out = append(out, c...) - } - return out -} - -func coordsBytestoUint64s(in []byte) (out []uint64) { - offset := 0 - for { - coord, length := wire_decode_uint64(in[offset:]) - if length == 0 { - break - } - out = append(out, coord) - offset += length - } - return out -} - // This is the subset of the information about a peer needed to make routing decisions, and it stored separately in an atomically accessed table, which gets hammered in the "hot loop" of the routing logic (see: peer.handleTraffic in peers.go). type tableElem struct { port switchPort diff --git a/src/yggdrasil/wire.go b/src/yggdrasil/wire.go index 5aa354d..4ff19e2 100644 --- a/src/yggdrasil/wire.go +++ b/src/yggdrasil/wire.go @@ -115,6 +115,29 @@ func wire_decode_coords(packet []byte) ([]byte, int) { return packet[coordBegin:coordEnd], coordEnd } +// Converts a []uint64 set of coords to a []byte set of coords. +func wire_coordsUint64stoBytes(in []uint64) (out []byte) { + for _, coord := range in { + c := wire_encode_uint64(coord) + out = append(out, c...) + } + return out +} + +// Converts a []byte set of coords to a []uint64 set of coords. +func wire_coordsBytestoUint64s(in []byte) (out []uint64) { + offset := 0 + for { + coord, length := wire_decode_uint64(in[offset:]) + if length == 0 { + break + } + out = append(out, coord) + offset += length + } + return out +} + //////////////////////////////////////////////////////////////////////////////// // Encodes a swtichMsg into its wire format.