5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-11-22 21:10:29 +00:00

Merge pull request #101 from neilalexander/wire

Export fields of wire structs
This commit is contained in:
Arceliar 2018-06-02 16:24:06 -05:00 committed by GitHub
commit b3b729804c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 273 additions and 273 deletions

View File

@ -583,9 +583,9 @@ func (a *admin) getResponse_dot() []byte {
infos[info.key] = info infos[info.key] = info
} }
} }
addInfo(dht, "fillcolor=\"#ffffff\" style=filled fontname=\"sans serif\"", "Known in DHT") // white addInfo(dht, "fillcolor=\"#ffffff\" style=filled fontname=\"sans serif\"", "Known in DHT") // white
addInfo(sessions, "fillcolor=\"#acf3fd\" style=filled fontname=\"sans serif\"", "Open session") // blue addInfo(sessions, "fillcolor=\"#acf3fd\" style=filled fontname=\"sans serif\"", "Open session") // blue
addInfo(peers, "fillcolor=\"#ffffb5\" style=filled fontname=\"sans serif\"", "Connected peer") // yellow addInfo(peers, "fillcolor=\"#ffffb5\" style=filled fontname=\"sans serif\"", "Connected peer") // yellow
addInfo(append([]admin_nodeInfo(nil), *self), "fillcolor=\"#a5ff8a\" style=filled fontname=\"sans serif\"", "This node") // green addInfo(append([]admin_nodeInfo(nil), *self), "fillcolor=\"#a5ff8a\" style=filled fontname=\"sans serif\"", "This node") // green
// Get coords as a slice of strings, FIXME? this looks very fragile // Get coords as a slice of strings, FIXME? this looks very fragile
coordSlice := func(coords string) []string { coordSlice := func(coords string) []string {

View File

@ -172,7 +172,7 @@ func (c *Core) GetAddress() *net.IP {
func (c *Core) GetSubnet() *net.IPNet { func (c *Core) GetSubnet() *net.IPNet {
subnet := address_subnetForNodeID(c.GetNodeID())[:] subnet := address_subnetForNodeID(c.GetNodeID())[:]
subnet = append(subnet, 0, 0, 0, 0, 0, 0, 0, 0) subnet = append(subnet, 0, 0, 0, 0, 0, 0, 0, 0)
return &net.IPNet{ IP: subnet, Mask: net.CIDRMask(64, 128) } return &net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)}
} }
// Sets the output logger of the Yggdrasil node after startup. This may be // Sets the output logger of the Yggdrasil node after startup. This may be

View File

@ -51,16 +51,16 @@ type bucket struct {
} }
type dhtReq struct { type dhtReq struct {
key boxPubKey // Key of whoever asked Key boxPubKey // Key of whoever asked
coords []byte // Coords of whoever asked Coords []byte // Coords of whoever asked
dest NodeID // NodeID they're asking about Dest NodeID // NodeID they're asking about
} }
type dhtRes struct { type dhtRes struct {
key boxPubKey // key to respond to Key boxPubKey // key to respond to
coords []byte // coords to respond to Coords []byte // coords to respond to
dest NodeID Dest NodeID
infos []*dhtInfo // response Infos []*dhtInfo // response
} }
type dht_rumor struct { type dht_rumor struct {
@ -90,33 +90,33 @@ func (t *dht) handleReq(req *dhtReq) {
loc := t.core.switchTable.getLocator() loc := t.core.switchTable.getLocator()
coords := loc.getCoords() coords := loc.getCoords()
res := dhtRes{ res := dhtRes{
key: t.core.boxPub, Key: t.core.boxPub,
coords: coords, Coords: coords,
dest: req.dest, Dest: req.Dest,
infos: t.lookup(&req.dest, false), Infos: t.lookup(&req.Dest, false),
} }
t.sendRes(&res, req) t.sendRes(&res, req)
// Also (possibly) add them to our DHT // Also (possibly) add them to our DHT
info := dhtInfo{ info := dhtInfo{
key: req.key, key: req.Key,
coords: req.coords, coords: req.Coords,
} }
t.insertIfNew(&info, false) // This seems DoSable (we just trust their coords...) t.insertIfNew(&info, false) // This seems DoSable (we just trust their coords...)
//if req.dest != t.nodeID { t.ping(&info, info.getNodeID()) } // Or spam... //if req.dest != t.nodeID { t.ping(&info, info.getNodeID()) } // Or spam...
} }
func (t *dht) handleRes(res *dhtRes) { func (t *dht) handleRes(res *dhtRes) {
reqs, isIn := t.reqs[res.key] reqs, isIn := t.reqs[res.Key]
if !isIn { if !isIn {
return return
} }
_, isIn = reqs[res.dest] _, isIn = reqs[res.Dest]
if !isIn { if !isIn {
return return
} }
rinfo := dhtInfo{ rinfo := dhtInfo{
key: res.key, key: res.Key,
coords: res.coords, coords: res.Coords,
send: time.Now(), // Technically wrong but should be OK... send: time.Now(), // Technically wrong but should be OK...
recv: time.Now(), recv: time.Now(),
} }
@ -138,15 +138,15 @@ func (t *dht) handleRes(res *dhtRes) {
} }
// Insert into table // Insert into table
t.insert(&rinfo, false) t.insert(&rinfo, false)
if res.dest == *rinfo.getNodeID() { if res.Dest == *rinfo.getNodeID() {
return return
} // No infinite recursions } // No infinite recursions
if len(res.infos) > dht_lookup_size { if len(res.Infos) > dht_lookup_size {
// Ignore any "extra" lookup results // Ignore any "extra" lookup results
res.infos = res.infos[:dht_lookup_size] res.Infos = res.Infos[:dht_lookup_size]
} }
for _, info := range res.infos { for _, info := range res.Infos {
if dht_firstCloserThanThird(info.getNodeID(), &res.dest, rinfo.getNodeID()) { if dht_firstCloserThanThird(info.getNodeID(), &res.Dest, rinfo.getNodeID()) {
t.addToMill(info, info.getNodeID()) t.addToMill(info, info.getNodeID())
} }
} }
@ -318,12 +318,12 @@ func (t *dht) sendReq(req *dhtReq, dest *dhtInfo) {
shared := t.core.sessions.getSharedKey(&t.core.boxPriv, &dest.key) shared := t.core.sessions.getSharedKey(&t.core.boxPriv, &dest.key)
payload, nonce := boxSeal(shared, bs, nil) payload, nonce := boxSeal(shared, bs, nil)
p := wire_protoTrafficPacket{ p := wire_protoTrafficPacket{
ttl: ^uint64(0), TTL: ^uint64(0),
coords: dest.coords, Coords: dest.coords,
toKey: dest.key, ToKey: dest.key,
fromKey: t.core.boxPub, FromKey: t.core.boxPub,
nonce: *nonce, Nonce: *nonce,
payload: payload, Payload: payload,
} }
packet := p.encode() packet := p.encode()
t.core.router.out(packet) t.core.router.out(packet)
@ -335,21 +335,21 @@ func (t *dht) sendReq(req *dhtReq, dest *dhtInfo) {
panic("This should never happen") panic("This should never happen")
} }
} }
reqsToDest[req.dest] = time.Now() reqsToDest[req.Dest] = time.Now()
} }
func (t *dht) sendRes(res *dhtRes, req *dhtReq) { func (t *dht) sendRes(res *dhtRes, req *dhtReq) {
// Send a reply for a dhtReq // Send a reply for a dhtReq
bs := res.encode() bs := res.encode()
shared := t.core.sessions.getSharedKey(&t.core.boxPriv, &req.key) shared := t.core.sessions.getSharedKey(&t.core.boxPriv, &req.Key)
payload, nonce := boxSeal(shared, bs, nil) payload, nonce := boxSeal(shared, bs, nil)
p := wire_protoTrafficPacket{ p := wire_protoTrafficPacket{
ttl: ^uint64(0), TTL: ^uint64(0),
coords: req.coords, Coords: req.Coords,
toKey: req.key, ToKey: req.Key,
fromKey: t.core.boxPub, FromKey: t.core.boxPub,
nonce: *nonce, Nonce: *nonce,
payload: payload, Payload: payload,
} }
packet := p.encode() packet := p.encode()
t.core.router.out(packet) t.core.router.out(packet)
@ -403,9 +403,9 @@ func (t *dht) ping(info *dhtInfo, target *NodeID) {
loc := t.core.switchTable.getLocator() loc := t.core.switchTable.getLocator()
coords := loc.getCoords() coords := loc.getCoords()
req := dhtReq{ req := dhtReq{
key: t.core.boxPub, Key: t.core.boxPub,
coords: coords, Coords: coords,
dest: *target, Dest: *target,
} }
info.pings++ info.pings++
info.send = time.Now() info.send = time.Now()

View File

@ -207,16 +207,16 @@ func (p *peer) linkLoop(in <-chan []byte) {
switch { switch {
case p.msgAnc == nil: case p.msgAnc == nil:
update = true update = true
case lastRSeq != p.msgAnc.seq: case lastRSeq != p.msgAnc.Seq:
update = true update = true
case p.msgAnc.rseq != p.myMsg.seq: case p.msgAnc.Rseq != p.myMsg.seq:
update = true update = true
case counter%4 == 0: case counter%4 == 0:
update = true update = true
} }
if update { if update {
if p.msgAnc != nil { if p.msgAnc != nil {
lastRSeq = p.msgAnc.seq lastRSeq = p.msgAnc.Seq
} }
p.sendSwitchAnnounce() p.sendSwitchAnnounce()
} }
@ -291,8 +291,8 @@ func (p *peer) sendPacket(packet []byte) {
func (p *peer) sendLinkPacket(packet []byte) { func (p *peer) sendLinkPacket(packet []byte) {
bs, nonce := boxSeal(&p.shared, packet, nil) bs, nonce := boxSeal(&p.shared, packet, nil)
linkPacket := wire_linkProtoTrafficPacket{ linkPacket := wire_linkProtoTrafficPacket{
nonce: *nonce, Nonce: *nonce,
payload: bs, Payload: bs,
} }
packet = linkPacket.encode() packet = linkPacket.encode()
p.sendPacket(packet) p.sendPacket(packet)
@ -303,7 +303,7 @@ func (p *peer) handleLinkTraffic(bs []byte) {
if !packet.decode(bs) { if !packet.decode(bs) {
return return
} }
payload, isOK := boxOpen(&p.shared, packet.payload, &packet.nonce) payload, isOK := boxOpen(&p.shared, packet.Payload, &packet.Nonce)
if !isOK { if !isOK {
return return
} }
@ -331,9 +331,9 @@ func (p *peer) handleSwitchAnnounce(packet []byte) {
} }
//if p.msgAnc != nil && anc.Seq != p.msgAnc.Seq { p.msgHops = nil } //if p.msgAnc != nil && anc.Seq != p.msgAnc.Seq { p.msgHops = nil }
if p.msgAnc == nil || if p.msgAnc == nil ||
anc.root != p.msgAnc.root || anc.Root != p.msgAnc.Root ||
anc.tstamp != p.msgAnc.tstamp || anc.Tstamp != p.msgAnc.Tstamp ||
anc.seq != p.msgAnc.seq { anc.Seq != p.msgAnc.Seq {
p.msgHops = nil p.msgHops = nil
} }
p.msgAnc = &anc p.msgAnc = &anc
@ -344,10 +344,10 @@ func (p *peer) handleSwitchAnnounce(packet []byte) {
func (p *peer) requestHop(hop uint64) { func (p *peer) requestHop(hop uint64) {
//p.core.log.Println("DEBUG requestHop") //p.core.log.Println("DEBUG requestHop")
req := msgHopReq{} req := msgHopReq{}
req.root = p.msgAnc.root req.Root = p.msgAnc.Root
req.tstamp = p.msgAnc.tstamp req.Tstamp = p.msgAnc.Tstamp
req.seq = p.msgAnc.seq req.Seq = p.msgAnc.Seq
req.hop = hop req.Hop = hop
packet := req.encode() packet := req.encode()
p.sendLinkPacket(packet) p.sendLinkPacket(packet)
} }
@ -364,28 +364,28 @@ func (p *peer) handleSwitchHopRequest(packet []byte) {
if !req.decode(packet) { if !req.decode(packet) {
return return
} }
if req.root != p.myMsg.locator.root { if req.Root != p.myMsg.locator.root {
return return
} }
if req.tstamp != p.myMsg.locator.tstamp { if req.Tstamp != p.myMsg.locator.tstamp {
return return
} }
if req.seq != p.myMsg.seq { if req.Seq != p.myMsg.seq {
return return
} }
if uint64(len(p.myMsg.locator.coords)) <= req.hop { if uint64(len(p.myMsg.locator.coords)) <= req.Hop {
return return
} }
res := msgHop{} res := msgHop{}
res.root = p.myMsg.locator.root res.Root = p.myMsg.locator.root
res.tstamp = p.myMsg.locator.tstamp res.Tstamp = p.myMsg.locator.tstamp
res.seq = p.myMsg.seq res.Seq = p.myMsg.seq
res.hop = req.hop res.Hop = req.Hop
res.port = p.myMsg.locator.coords[res.hop] res.Port = p.myMsg.locator.coords[res.Hop]
sinfo := p.getSig(res.hop) sinfo := p.getSig(res.Hop)
//p.core.log.Println("DEBUG sig:", sinfo) //p.core.log.Println("DEBUG sig:", sinfo)
res.next = sinfo.next res.Next = sinfo.next
res.sig = sinfo.sig res.Sig = sinfo.sig
packet = res.encode() packet = res.encode()
p.sendLinkPacket(packet) p.sendLinkPacket(packet)
} }
@ -402,31 +402,31 @@ func (p *peer) handleSwitchHop(packet []byte) {
if !res.decode(packet) { if !res.decode(packet) {
return return
} }
if res.root != p.msgAnc.root { if res.Root != p.msgAnc.Root {
return return
} }
if res.tstamp != p.msgAnc.tstamp { if res.Tstamp != p.msgAnc.Tstamp {
return return
} }
if res.seq != p.msgAnc.seq { if res.Seq != p.msgAnc.Seq {
return return
} }
if res.hop != uint64(len(p.msgHops)) { if res.Hop != uint64(len(p.msgHops)) {
return return
} // always process in order } // always process in order
loc := switchLocator{coords: make([]switchPort, 0, len(p.msgHops)+1)} loc := switchLocator{coords: make([]switchPort, 0, len(p.msgHops)+1)}
loc.root = res.root loc.root = res.Root
loc.tstamp = res.tstamp loc.tstamp = res.Tstamp
for _, hop := range p.msgHops { for _, hop := range p.msgHops {
loc.coords = append(loc.coords, hop.port) loc.coords = append(loc.coords, hop.Port)
} }
loc.coords = append(loc.coords, res.port) loc.coords = append(loc.coords, res.Port)
thisHopKey := &res.root thisHopKey := &res.Root
if res.hop != 0 { if res.Hop != 0 {
thisHopKey = &p.msgHops[res.hop-1].next thisHopKey = &p.msgHops[res.Hop-1].Next
} }
bs := getBytesForSig(&res.next, &loc) bs := getBytesForSig(&res.Next, &loc)
if p.core.sigs.check(thisHopKey, &res.sig, bs) { if p.core.sigs.check(thisHopKey, &res.Sig, bs) {
p.msgHops = append(p.msgHops, &res) p.msgHops = append(p.msgHops, &res)
p.processSwitchMessage() p.processSwitchMessage()
} else { } else {
@ -442,12 +442,12 @@ func (p *peer) processSwitchMessage() {
if p.msgAnc == nil { if p.msgAnc == nil {
return return
} }
if uint64(len(p.msgHops)) < p.msgAnc.len { if uint64(len(p.msgHops)) < p.msgAnc.Len {
p.requestHop(uint64(len(p.msgHops))) p.requestHop(uint64(len(p.msgHops)))
return return
} }
p.throttle++ p.throttle++
if p.msgAnc.len != uint64(len(p.msgHops)) { if p.msgAnc.Len != uint64(len(p.msgHops)) {
return return
} }
msg := switchMessage{} msg := switchMessage{}
@ -455,26 +455,26 @@ func (p *peer) processSwitchMessage() {
sigs := make([]sigInfo, 0, len(p.msgHops)) sigs := make([]sigInfo, 0, len(p.msgHops))
for idx, hop := range p.msgHops { for idx, hop := range p.msgHops {
// Consistency checks, should be redundant (already checked these...) // Consistency checks, should be redundant (already checked these...)
if hop.root != p.msgAnc.root { if hop.Root != p.msgAnc.Root {
return return
} }
if hop.tstamp != p.msgAnc.tstamp { if hop.Tstamp != p.msgAnc.Tstamp {
return return
} }
if hop.seq != p.msgAnc.seq { if hop.Seq != p.msgAnc.Seq {
return return
} }
if hop.hop != uint64(idx) { if hop.Hop != uint64(idx) {
return return
} }
coords = append(coords, hop.port) coords = append(coords, hop.Port)
sigs = append(sigs, sigInfo{next: hop.next, sig: hop.sig}) sigs = append(sigs, sigInfo{next: hop.Next, sig: hop.Sig})
} }
msg.from = p.sig msg.from = p.sig
msg.locator.root = p.msgAnc.root msg.locator.root = p.msgAnc.Root
msg.locator.tstamp = p.msgAnc.tstamp msg.locator.tstamp = p.msgAnc.Tstamp
msg.locator.coords = coords msg.locator.coords = coords
msg.seq = p.msgAnc.seq msg.seq = p.msgAnc.Seq
//msg.RSeq = p.msgAnc.RSeq //msg.RSeq = p.msgAnc.RSeq
//msg.Degree = p.msgAnc.Deg //msg.Degree = p.msgAnc.Deg
p.core.switchTable.handleMessage(&msg, p.port, sigs) p.core.switchTable.handleMessage(&msg, p.port, sigs)
@ -493,13 +493,13 @@ func (p *peer) processSwitchMessage() {
func (p *peer) sendSwitchAnnounce() { func (p *peer) sendSwitchAnnounce() {
anc := msgAnnounce{} anc := msgAnnounce{}
anc.root = p.myMsg.locator.root anc.Root = p.myMsg.locator.root
anc.tstamp = p.myMsg.locator.tstamp anc.Tstamp = p.myMsg.locator.tstamp
anc.seq = p.myMsg.seq anc.Seq = p.myMsg.seq
anc.len = uint64(len(p.myMsg.locator.coords)) anc.Len = uint64(len(p.myMsg.locator.coords))
//anc.Deg = p.myMsg.Degree //anc.Deg = p.myMsg.Degree
if p.msgAnc != nil { if p.msgAnc != nil {
anc.rseq = p.msgAnc.seq anc.Rseq = p.msgAnc.Seq
} }
packet := anc.encode() packet := anc.encode()
p.sendLinkPacket(packet) p.sendLinkPacket(packet)

View File

@ -8,5 +8,5 @@ import "log"
// Starts the function profiler. This is only supported when built with // Starts the function profiler. This is only supported when built with
// '-tags build'. // '-tags build'.
func StartProfiler(_ *log.Logger) error { func StartProfiler(_ *log.Logger) error {
return errors.New("Release builds do not support -pprof, build using '-tags debug'") return errors.New("Release builds do not support -pprof, build using '-tags debug'")
} }

View File

@ -266,7 +266,7 @@ func (r *router) handleTraffic(packet []byte) {
if !p.decode(packet) { if !p.decode(packet) {
return return
} }
sinfo, isIn := r.core.sessions.getSessionForHandle(&p.handle) sinfo, isIn := r.core.sessions.getSessionForHandle(&p.Handle)
if !isIn { if !isIn {
return return
} }
@ -283,13 +283,13 @@ func (r *router) handleProto(packet []byte) {
// Now try to open the payload // Now try to open the payload
var sharedKey *boxSharedKey var sharedKey *boxSharedKey
//var theirPermPub *boxPubKey //var theirPermPub *boxPubKey
if p.toKey == r.core.boxPub { if p.ToKey == r.core.boxPub {
// Try to open using our permanent key // Try to open using our permanent key
sharedKey = r.core.sessions.getSharedKey(&r.core.boxPriv, &p.fromKey) sharedKey = r.core.sessions.getSharedKey(&r.core.boxPriv, &p.FromKey)
} else { } else {
return return
} }
bs, isOK := boxOpen(sharedKey, p.payload, &p.nonce) bs, isOK := boxOpen(sharedKey, p.Payload, &p.Nonce)
if !isOK { if !isOK {
return return
} }
@ -303,13 +303,13 @@ func (r *router) handleProto(packet []byte) {
//fmt.Println("RECV bytes:", bs) //fmt.Println("RECV bytes:", bs)
switch bsType { switch bsType {
case wire_SessionPing: case wire_SessionPing:
r.handlePing(bs, &p.fromKey) r.handlePing(bs, &p.FromKey)
case wire_SessionPong: case wire_SessionPong:
r.handlePong(bs, &p.fromKey) r.handlePong(bs, &p.FromKey)
case wire_DHTLookupRequest: case wire_DHTLookupRequest:
r.handleDHTReq(bs, &p.fromKey) r.handleDHTReq(bs, &p.FromKey)
case wire_DHTLookupResponse: case wire_DHTLookupResponse:
r.handleDHTRes(bs, &p.fromKey) r.handleDHTRes(bs, &p.FromKey)
case wire_SearchRequest: case wire_SearchRequest:
r.handleSearchReq(bs) r.handleSearchReq(bs)
case wire_SearchResponse: case wire_SearchResponse:
@ -324,7 +324,7 @@ func (r *router) handlePing(bs []byte, fromKey *boxPubKey) {
if !ping.decode(bs) { if !ping.decode(bs) {
return return
} }
ping.sendPermPub = *fromKey ping.SendPermPub = *fromKey
r.core.sessions.handlePing(&ping) r.core.sessions.handlePing(&ping)
} }
@ -337,7 +337,7 @@ func (r *router) handleDHTReq(bs []byte, fromKey *boxPubKey) {
if !req.decode(bs) { if !req.decode(bs) {
return return
} }
req.key = *fromKey req.Key = *fromKey
r.core.dht.handleReq(&req) r.core.dht.handleReq(&req)
} }
@ -346,7 +346,7 @@ func (r *router) handleDHTRes(bs []byte, fromKey *boxPubKey) {
if !res.decode(bs) { if !res.decode(bs) {
return return
} }
res.key = *fromKey res.Key = *fromKey
r.core.dht.handleRes(&res) r.core.dht.handleRes(&res)
} }

View File

@ -108,12 +108,12 @@ func (s *searches) forwardSearch(req *searchReq, next *dhtInfo) {
shared := s.core.sessions.getSharedKey(&s.core.boxPriv, &next.key) shared := s.core.sessions.getSharedKey(&s.core.boxPriv, &next.key)
payload, nonce := boxSeal(shared, bs, nil) payload, nonce := boxSeal(shared, bs, nil)
p := wire_protoTrafficPacket{ p := wire_protoTrafficPacket{
ttl: ^uint64(0), TTL: ^uint64(0),
coords: next.coords, Coords: next.coords,
toKey: next.key, ToKey: next.key,
fromKey: s.core.boxPub, FromKey: s.core.boxPub,
nonce: *nonce, Nonce: *nonce,
payload: payload, Payload: payload,
} }
packet := p.encode() packet := p.encode()
s.core.router.out(packet) s.core.router.out(packet)
@ -132,12 +132,12 @@ func (s *searches) sendSearchRes(req *searchReq) {
shared := s.core.sessions.getSharedKey(&s.core.boxPriv, &req.key) shared := s.core.sessions.getSharedKey(&s.core.boxPriv, &req.key)
payload, nonce := boxSeal(shared, bs, nil) payload, nonce := boxSeal(shared, bs, nil)
p := wire_protoTrafficPacket{ p := wire_protoTrafficPacket{
ttl: ^uint64(0), TTL: ^uint64(0),
coords: req.coords, Coords: req.coords,
toKey: req.key, ToKey: req.key,
fromKey: s.core.boxPub, FromKey: s.core.boxPub,
nonce: *nonce, Nonce: *nonce,
payload: payload, Payload: payload,
} }
packet := p.encode() packet := p.encode()
s.core.router.out(packet) s.core.router.out(packet)

View File

@ -38,40 +38,40 @@ type sessionInfo struct {
} }
type sessionPing struct { type sessionPing struct {
sendPermPub boxPubKey // Sender's permanent key SendPermPub boxPubKey // Sender's permanent key
handle handle // Random number to ID session Handle handle // Random number to ID session
sendSesPub boxPubKey // Session key to use SendSesPub boxPubKey // Session key to use
coords []byte Coords []byte
tstamp int64 // unix time, but the only real requirement is that it increases Tstamp int64 // unix time, but the only real requirement is that it increases
isPong bool IsPong bool
mtu uint16 MTU uint16
} }
// Returns true if the session was updated, false otherwise // Returns true if the session was updated, false otherwise
func (s *sessionInfo) update(p *sessionPing) bool { func (s *sessionInfo) update(p *sessionPing) bool {
if !(p.tstamp > s.tstamp) { if !(p.Tstamp > s.tstamp) {
// To protect against replay attacks // To protect against replay attacks
return false return false
} }
if p.sendPermPub != s.theirPermPub { if p.SendPermPub != s.theirPermPub {
// Should only happen if two sessions got the same handle // Should only happen if two sessions got the same handle
// That shouldn't be allowed anyway, but if it happens then let one time out // That shouldn't be allowed anyway, but if it happens then let one time out
return false return false
} }
if p.sendSesPub != s.theirSesPub { if p.SendSesPub != s.theirSesPub {
s.theirSesPub = p.sendSesPub s.theirSesPub = p.SendSesPub
s.theirHandle = p.handle s.theirHandle = p.Handle
s.sharedSesKey = *getSharedKey(&s.mySesPriv, &s.theirSesPub) s.sharedSesKey = *getSharedKey(&s.mySesPriv, &s.theirSesPub)
s.theirNonce = boxNonce{} s.theirNonce = boxNonce{}
s.nonceMask = 0 s.nonceMask = 0
} }
if p.mtu >= 1280 || p.mtu == 0 { if p.MTU >= 1280 || p.MTU == 0 {
s.theirMTU = p.mtu s.theirMTU = p.MTU
} }
s.coords = append([]byte{}, p.coords...) s.coords = append([]byte{}, p.Coords...)
now := time.Now() now := time.Now()
s.time = now s.time = now
s.tstamp = p.tstamp s.tstamp = p.Tstamp
s.init = true s.init = true
return true return true
} }
@ -215,12 +215,12 @@ func (ss *sessions) getPing(sinfo *sessionInfo) sessionPing {
loc := ss.core.switchTable.getLocator() loc := ss.core.switchTable.getLocator()
coords := loc.getCoords() coords := loc.getCoords()
ref := sessionPing{ ref := sessionPing{
sendPermPub: ss.core.boxPub, SendPermPub: ss.core.boxPub,
handle: sinfo.myHandle, Handle: sinfo.myHandle,
sendSesPub: sinfo.mySesPub, SendSesPub: sinfo.mySesPub,
tstamp: time.Now().Unix(), Tstamp: time.Now().Unix(),
coords: coords, Coords: coords,
mtu: sinfo.myMTU, MTU: sinfo.myMTU,
} }
sinfo.myNonce.update() sinfo.myNonce.update()
return ref return ref
@ -250,17 +250,17 @@ func (ss *sessions) ping(sinfo *sessionInfo) {
func (ss *sessions) sendPingPong(sinfo *sessionInfo, isPong bool) { func (ss *sessions) sendPingPong(sinfo *sessionInfo, isPong bool) {
ping := ss.getPing(sinfo) ping := ss.getPing(sinfo)
ping.isPong = isPong ping.IsPong = isPong
bs := ping.encode() bs := ping.encode()
shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub) shared := ss.getSharedKey(&ss.core.boxPriv, &sinfo.theirPermPub)
payload, nonce := boxSeal(shared, bs, nil) payload, nonce := boxSeal(shared, bs, nil)
p := wire_protoTrafficPacket{ p := wire_protoTrafficPacket{
ttl: ^uint64(0), TTL: ^uint64(0),
coords: sinfo.coords, Coords: sinfo.coords,
toKey: sinfo.theirPermPub, ToKey: sinfo.theirPermPub,
fromKey: ss.core.boxPub, FromKey: ss.core.boxPub,
nonce: *nonce, Nonce: *nonce,
payload: payload, Payload: payload,
} }
packet := p.encode() packet := p.encode()
ss.core.router.out(packet) ss.core.router.out(packet)
@ -271,13 +271,13 @@ func (ss *sessions) sendPingPong(sinfo *sessionInfo, isPong bool) {
func (ss *sessions) handlePing(ping *sessionPing) { func (ss *sessions) handlePing(ping *sessionPing) {
// Get the corresponding session (or create a new session) // Get the corresponding session (or create a new session)
sinfo, isIn := ss.getByTheirPerm(&ping.sendPermPub) sinfo, isIn := ss.getByTheirPerm(&ping.SendPermPub)
if !isIn || sinfo.timedout() { if !isIn || sinfo.timedout() {
if isIn { if isIn {
sinfo.close() sinfo.close()
} }
ss.createSession(&ping.sendPermPub) ss.createSession(&ping.SendPermPub)
sinfo, isIn = ss.getByTheirPerm(&ping.sendPermPub) sinfo, isIn = ss.getByTheirPerm(&ping.SendPermPub)
if !isIn { if !isIn {
panic("This should not happen") panic("This should not happen")
} }
@ -286,7 +286,7 @@ func (ss *sessions) handlePing(ping *sessionPing) {
if !sinfo.update(ping) { /*panic("Should not happen in testing")*/ if !sinfo.update(ping) { /*panic("Should not happen in testing")*/
return return
} }
if !ping.isPong { if !ping.IsPong {
ss.sendPingPong(sinfo, true) ss.sendPingPong(sinfo, true)
} }
if sinfo.packet != nil { if sinfo.packet != nil {
@ -383,11 +383,11 @@ func (sinfo *sessionInfo) doSend(bs []byte) {
payload, nonce := boxSeal(&sinfo.sharedSesKey, bs, &sinfo.myNonce) payload, nonce := boxSeal(&sinfo.sharedSesKey, bs, &sinfo.myNonce)
defer util_putBytes(payload) defer util_putBytes(payload)
p := wire_trafficPacket{ p := wire_trafficPacket{
ttl: ^uint64(0), TTL: ^uint64(0),
coords: sinfo.coords, Coords: sinfo.coords,
handle: sinfo.theirHandle, Handle: sinfo.theirHandle,
nonce: *nonce, Nonce: *nonce,
payload: payload, Payload: payload,
} }
packet := p.encode() packet := p.encode()
sinfo.bytesSent += uint64(len(bs)) sinfo.bytesSent += uint64(len(bs))
@ -395,12 +395,12 @@ func (sinfo *sessionInfo) doSend(bs []byte) {
} }
func (sinfo *sessionInfo) doRecv(p *wire_trafficPacket) { func (sinfo *sessionInfo) doRecv(p *wire_trafficPacket) {
defer util_putBytes(p.payload) defer util_putBytes(p.Payload)
payloadSize := uint16(len(p.payload)) payloadSize := uint16(len(p.Payload))
if !sinfo.nonceIsOK(&p.nonce) { if !sinfo.nonceIsOK(&p.Nonce) {
return return
} }
bs, isOK := boxOpen(&sinfo.sharedSesKey, p.payload, &p.nonce) bs, isOK := boxOpen(&sinfo.sharedSesKey, p.Payload, &p.Nonce)
if !isOK { if !isOK {
// We're going to guess that the session MTU is too large // We're going to guess that the session MTU is too large
// Set myMTU to the largest value we think we can receive // Set myMTU to the largest value we think we can receive
@ -433,7 +433,7 @@ func (sinfo *sessionInfo) doRecv(p *wire_trafficPacket) {
} }
} }
go func() { sinfo.core.router.admin <- fixSessionMTU }() go func() { sinfo.core.router.admin <- fixSessionMTU }()
sinfo.updateNonce(&p.nonce) sinfo.updateNonce(&p.Nonce)
sinfo.time = time.Now() sinfo.time = time.Now()
sinfo.bytesRecvd += uint64(len(bs)) sinfo.bytesRecvd += uint64(len(bs))
sinfo.core.router.recvPacket(bs, &sinfo.theirAddr, &sinfo.theirSubnet) sinfo.core.router.recvPacket(bs, &sinfo.theirAddr, &sinfo.theirSubnet)

View File

@ -121,21 +121,21 @@ func wire_decode_coords(packet []byte) ([]byte, int) {
// Announces that we can send parts of a Message with a particular seq // Announces that we can send parts of a Message with a particular seq
type msgAnnounce struct { type msgAnnounce struct {
root sigPubKey Root sigPubKey
tstamp int64 Tstamp int64
seq uint64 Seq uint64
len uint64 Len uint64
//Deg uint64 //Deg uint64
rseq uint64 Rseq uint64
} }
func (m *msgAnnounce) encode() []byte { func (m *msgAnnounce) encode() []byte {
bs := wire_encode_uint64(wire_SwitchAnnounce) bs := wire_encode_uint64(wire_SwitchAnnounce)
bs = append(bs, m.root[:]...) bs = append(bs, m.Root[:]...)
bs = append(bs, wire_encode_uint64(wire_intToUint(m.tstamp))...) bs = append(bs, wire_encode_uint64(wire_intToUint(m.Tstamp))...)
bs = append(bs, wire_encode_uint64(m.seq)...) bs = append(bs, wire_encode_uint64(m.Seq)...)
bs = append(bs, wire_encode_uint64(m.len)...) bs = append(bs, wire_encode_uint64(m.Len)...)
bs = append(bs, wire_encode_uint64(m.rseq)...) bs = append(bs, wire_encode_uint64(m.Rseq)...)
return bs return bs
} }
@ -147,34 +147,34 @@ func (m *msgAnnounce) decode(bs []byte) bool {
return false return false
case pType != wire_SwitchAnnounce: case pType != wire_SwitchAnnounce:
return false return false
case !wire_chop_slice(m.root[:], &bs): case !wire_chop_slice(m.Root[:], &bs):
return false return false
case !wire_chop_uint64(&tstamp, &bs): case !wire_chop_uint64(&tstamp, &bs):
return false return false
case !wire_chop_uint64(&m.seq, &bs): case !wire_chop_uint64(&m.Seq, &bs):
return false return false
case !wire_chop_uint64(&m.len, &bs): case !wire_chop_uint64(&m.Len, &bs):
return false return false
case !wire_chop_uint64(&m.rseq, &bs): case !wire_chop_uint64(&m.Rseq, &bs):
return false return false
} }
m.tstamp = wire_intFromUint(tstamp) m.Tstamp = wire_intFromUint(tstamp)
return true return true
} }
type msgHopReq struct { type msgHopReq struct {
root sigPubKey Root sigPubKey
tstamp int64 Tstamp int64
seq uint64 Seq uint64
hop uint64 Hop uint64
} }
func (m *msgHopReq) encode() []byte { func (m *msgHopReq) encode() []byte {
bs := wire_encode_uint64(wire_SwitchHopRequest) bs := wire_encode_uint64(wire_SwitchHopRequest)
bs = append(bs, m.root[:]...) bs = append(bs, m.Root[:]...)
bs = append(bs, wire_encode_uint64(wire_intToUint(m.tstamp))...) bs = append(bs, wire_encode_uint64(wire_intToUint(m.Tstamp))...)
bs = append(bs, wire_encode_uint64(m.seq)...) bs = append(bs, wire_encode_uint64(m.Seq)...)
bs = append(bs, wire_encode_uint64(m.hop)...) bs = append(bs, wire_encode_uint64(m.Hop)...)
return bs return bs
} }
@ -186,38 +186,38 @@ func (m *msgHopReq) decode(bs []byte) bool {
return false return false
case pType != wire_SwitchHopRequest: case pType != wire_SwitchHopRequest:
return false return false
case !wire_chop_slice(m.root[:], &bs): case !wire_chop_slice(m.Root[:], &bs):
return false return false
case !wire_chop_uint64(&tstamp, &bs): case !wire_chop_uint64(&tstamp, &bs):
return false return false
case !wire_chop_uint64(&m.seq, &bs): case !wire_chop_uint64(&m.Seq, &bs):
return false return false
case !wire_chop_uint64(&m.hop, &bs): case !wire_chop_uint64(&m.Hop, &bs):
return false return false
} }
m.tstamp = wire_intFromUint(tstamp) m.Tstamp = wire_intFromUint(tstamp)
return true return true
} }
type msgHop struct { type msgHop struct {
root sigPubKey Root sigPubKey
tstamp int64 Tstamp int64
seq uint64 Seq uint64
hop uint64 Hop uint64
port switchPort Port switchPort
next sigPubKey Next sigPubKey
sig sigBytes Sig sigBytes
} }
func (m *msgHop) encode() []byte { func (m *msgHop) encode() []byte {
bs := wire_encode_uint64(wire_SwitchHop) bs := wire_encode_uint64(wire_SwitchHop)
bs = append(bs, m.root[:]...) bs = append(bs, m.Root[:]...)
bs = append(bs, wire_encode_uint64(wire_intToUint(m.tstamp))...) bs = append(bs, wire_encode_uint64(wire_intToUint(m.Tstamp))...)
bs = append(bs, wire_encode_uint64(m.seq)...) bs = append(bs, wire_encode_uint64(m.Seq)...)
bs = append(bs, wire_encode_uint64(m.hop)...) bs = append(bs, wire_encode_uint64(m.Hop)...)
bs = append(bs, wire_encode_uint64(uint64(m.port))...) bs = append(bs, wire_encode_uint64(uint64(m.Port))...)
bs = append(bs, m.next[:]...) bs = append(bs, m.Next[:]...)
bs = append(bs, m.sig[:]...) bs = append(bs, m.Sig[:]...)
return bs return bs
} }
@ -229,22 +229,22 @@ func (m *msgHop) decode(bs []byte) bool {
return false return false
case pType != wire_SwitchHop: case pType != wire_SwitchHop:
return false return false
case !wire_chop_slice(m.root[:], &bs): case !wire_chop_slice(m.Root[:], &bs):
return false return false
case !wire_chop_uint64(&tstamp, &bs): case !wire_chop_uint64(&tstamp, &bs):
return false return false
case !wire_chop_uint64(&m.seq, &bs): case !wire_chop_uint64(&m.Seq, &bs):
return false return false
case !wire_chop_uint64(&m.hop, &bs): case !wire_chop_uint64(&m.Hop, &bs):
return false return false
case !wire_chop_uint64((*uint64)(&m.port), &bs): case !wire_chop_uint64((*uint64)(&m.Port), &bs):
return false return false
case !wire_chop_slice(m.next[:], &bs): case !wire_chop_slice(m.Next[:], &bs):
return false return false
case !wire_chop_slice(m.sig[:], &bs): case !wire_chop_slice(m.Sig[:], &bs):
return false return false
} }
m.tstamp = wire_intFromUint(tstamp) m.Tstamp = wire_intFromUint(tstamp)
return true return true
} }
@ -292,22 +292,22 @@ func wire_chop_uint64(toUInt64 *uint64, fromSlice *[]byte) bool {
// Wire traffic packets // Wire traffic packets
type wire_trafficPacket struct { type wire_trafficPacket struct {
ttl uint64 TTL uint64
coords []byte Coords []byte
handle handle Handle handle
nonce boxNonce Nonce boxNonce
payload []byte Payload []byte
} }
// This is basically MarshalBinary, but decode doesn't allow that... // This is basically MarshalBinary, but decode doesn't allow that...
func (p *wire_trafficPacket) encode() []byte { func (p *wire_trafficPacket) encode() []byte {
bs := util_getBytes() bs := util_getBytes()
bs = wire_put_uint64(wire_Traffic, bs) bs = wire_put_uint64(wire_Traffic, bs)
bs = wire_put_uint64(p.ttl, bs) bs = wire_put_uint64(p.TTL, bs)
bs = wire_put_coords(p.coords, bs) bs = wire_put_coords(p.Coords, bs)
bs = append(bs, p.handle[:]...) bs = append(bs, p.Handle[:]...)
bs = append(bs, p.nonce[:]...) bs = append(bs, p.Nonce[:]...)
bs = append(bs, p.payload...) bs = append(bs, p.Payload...)
return bs return bs
} }
@ -319,37 +319,37 @@ func (p *wire_trafficPacket) decode(bs []byte) bool {
return false return false
case pType != wire_Traffic: case pType != wire_Traffic:
return false return false
case !wire_chop_uint64(&p.ttl, &bs): case !wire_chop_uint64(&p.TTL, &bs):
return false return false
case !wire_chop_coords(&p.coords, &bs): case !wire_chop_coords(&p.Coords, &bs):
return false return false
case !wire_chop_slice(p.handle[:], &bs): case !wire_chop_slice(p.Handle[:], &bs):
return false return false
case !wire_chop_slice(p.nonce[:], &bs): case !wire_chop_slice(p.Nonce[:], &bs):
return false return false
} }
p.payload = append(util_getBytes(), bs...) p.Payload = append(util_getBytes(), bs...)
return true return true
} }
type wire_protoTrafficPacket struct { type wire_protoTrafficPacket struct {
ttl uint64 TTL uint64
coords []byte Coords []byte
toKey boxPubKey ToKey boxPubKey
fromKey boxPubKey FromKey boxPubKey
nonce boxNonce Nonce boxNonce
payload []byte Payload []byte
} }
func (p *wire_protoTrafficPacket) encode() []byte { func (p *wire_protoTrafficPacket) encode() []byte {
coords := wire_encode_coords(p.coords) coords := wire_encode_coords(p.Coords)
bs := wire_encode_uint64(wire_ProtocolTraffic) bs := wire_encode_uint64(wire_ProtocolTraffic)
bs = append(bs, wire_encode_uint64(p.ttl)...) bs = append(bs, wire_encode_uint64(p.TTL)...)
bs = append(bs, coords...) bs = append(bs, coords...)
bs = append(bs, p.toKey[:]...) bs = append(bs, p.ToKey[:]...)
bs = append(bs, p.fromKey[:]...) bs = append(bs, p.FromKey[:]...)
bs = append(bs, p.nonce[:]...) bs = append(bs, p.Nonce[:]...)
bs = append(bs, p.payload...) bs = append(bs, p.Payload...)
return bs return bs
} }
@ -360,30 +360,30 @@ func (p *wire_protoTrafficPacket) decode(bs []byte) bool {
return false return false
case pType != wire_ProtocolTraffic: case pType != wire_ProtocolTraffic:
return false return false
case !wire_chop_uint64(&p.ttl, &bs): case !wire_chop_uint64(&p.TTL, &bs):
return false return false
case !wire_chop_coords(&p.coords, &bs): case !wire_chop_coords(&p.Coords, &bs):
return false return false
case !wire_chop_slice(p.toKey[:], &bs): case !wire_chop_slice(p.ToKey[:], &bs):
return false return false
case !wire_chop_slice(p.fromKey[:], &bs): case !wire_chop_slice(p.FromKey[:], &bs):
return false return false
case !wire_chop_slice(p.nonce[:], &bs): case !wire_chop_slice(p.Nonce[:], &bs):
return false return false
} }
p.payload = bs p.Payload = bs
return true return true
} }
type wire_linkProtoTrafficPacket struct { type wire_linkProtoTrafficPacket struct {
nonce boxNonce Nonce boxNonce
payload []byte Payload []byte
} }
func (p *wire_linkProtoTrafficPacket) encode() []byte { func (p *wire_linkProtoTrafficPacket) encode() []byte {
bs := wire_encode_uint64(wire_LinkProtocolTraffic) bs := wire_encode_uint64(wire_LinkProtocolTraffic)
bs = append(bs, p.nonce[:]...) bs = append(bs, p.Nonce[:]...)
bs = append(bs, p.payload...) bs = append(bs, p.Payload...)
return bs return bs
} }
@ -394,10 +394,10 @@ func (p *wire_linkProtoTrafficPacket) decode(bs []byte) bool {
return false return false
case pType != wire_LinkProtocolTraffic: case pType != wire_LinkProtocolTraffic:
return false return false
case !wire_chop_slice(p.nonce[:], &bs): case !wire_chop_slice(p.Nonce[:], &bs):
return false return false
} }
p.payload = bs p.Payload = bs
return true return true
} }
@ -405,19 +405,19 @@ func (p *wire_linkProtoTrafficPacket) decode(bs []byte) bool {
func (p *sessionPing) encode() []byte { func (p *sessionPing) encode() []byte {
var pTypeVal uint64 var pTypeVal uint64
if p.isPong { if p.IsPong {
pTypeVal = wire_SessionPong pTypeVal = wire_SessionPong
} else { } else {
pTypeVal = wire_SessionPing pTypeVal = wire_SessionPing
} }
bs := wire_encode_uint64(pTypeVal) bs := wire_encode_uint64(pTypeVal)
//p.sendPermPub used in top level (crypto), so skipped here //p.sendPermPub used in top level (crypto), so skipped here
bs = append(bs, p.handle[:]...) bs = append(bs, p.Handle[:]...)
bs = append(bs, p.sendSesPub[:]...) bs = append(bs, p.SendSesPub[:]...)
bs = append(bs, wire_encode_uint64(wire_intToUint(p.tstamp))...) bs = append(bs, wire_encode_uint64(wire_intToUint(p.Tstamp))...)
coords := wire_encode_coords(p.coords) coords := wire_encode_coords(p.Coords)
bs = append(bs, coords...) bs = append(bs, coords...)
bs = append(bs, wire_encode_uint64(uint64(p.mtu))...) bs = append(bs, wire_encode_uint64(uint64(p.MTU))...)
return bs return bs
} }
@ -431,32 +431,32 @@ func (p *sessionPing) decode(bs []byte) bool {
case pType != wire_SessionPing && pType != wire_SessionPong: case pType != wire_SessionPing && pType != wire_SessionPong:
return false return false
//p.sendPermPub used in top level (crypto), so skipped here //p.sendPermPub used in top level (crypto), so skipped here
case !wire_chop_slice(p.handle[:], &bs): case !wire_chop_slice(p.Handle[:], &bs):
return false return false
case !wire_chop_slice(p.sendSesPub[:], &bs): case !wire_chop_slice(p.SendSesPub[:], &bs):
return false return false
case !wire_chop_uint64(&tstamp, &bs): case !wire_chop_uint64(&tstamp, &bs):
return false return false
case !wire_chop_coords(&p.coords, &bs): case !wire_chop_coords(&p.Coords, &bs):
return false return false
case !wire_chop_uint64(&mtu, &bs): case !wire_chop_uint64(&mtu, &bs):
mtu = 1280 mtu = 1280
} }
p.tstamp = wire_intFromUint(tstamp) p.Tstamp = wire_intFromUint(tstamp)
if pType == wire_SessionPong { if pType == wire_SessionPong {
p.isPong = true p.IsPong = true
} }
p.mtu = uint16(mtu) p.MTU = uint16(mtu)
return true return true
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
func (r *dhtReq) encode() []byte { func (r *dhtReq) encode() []byte {
coords := wire_encode_coords(r.coords) coords := wire_encode_coords(r.Coords)
bs := wire_encode_uint64(wire_DHTLookupRequest) bs := wire_encode_uint64(wire_DHTLookupRequest)
bs = append(bs, coords...) bs = append(bs, coords...)
bs = append(bs, r.dest[:]...) bs = append(bs, r.Dest[:]...)
return bs return bs
} }
@ -467,9 +467,9 @@ func (r *dhtReq) decode(bs []byte) bool {
return false return false
case pType != wire_DHTLookupRequest: case pType != wire_DHTLookupRequest:
return false return false
case !wire_chop_coords(&r.coords, &bs): case !wire_chop_coords(&r.Coords, &bs):
return false return false
case !wire_chop_slice(r.dest[:], &bs): case !wire_chop_slice(r.Dest[:], &bs):
return false return false
default: default:
return true return true
@ -477,11 +477,11 @@ func (r *dhtReq) decode(bs []byte) bool {
} }
func (r *dhtRes) encode() []byte { func (r *dhtRes) encode() []byte {
coords := wire_encode_coords(r.coords) coords := wire_encode_coords(r.Coords)
bs := wire_encode_uint64(wire_DHTLookupResponse) bs := wire_encode_uint64(wire_DHTLookupResponse)
bs = append(bs, coords...) bs = append(bs, coords...)
bs = append(bs, r.dest[:]...) bs = append(bs, r.Dest[:]...)
for _, info := range r.infos { for _, info := range r.Infos {
coords = wire_encode_coords(info.coords) coords = wire_encode_coords(info.coords)
bs = append(bs, info.key[:]...) bs = append(bs, info.key[:]...)
bs = append(bs, coords...) bs = append(bs, coords...)
@ -496,9 +496,9 @@ func (r *dhtRes) decode(bs []byte) bool {
return false return false
case pType != wire_DHTLookupResponse: case pType != wire_DHTLookupResponse:
return false return false
case !wire_chop_coords(&r.coords, &bs): case !wire_chop_coords(&r.Coords, &bs):
return false return false
case !wire_chop_slice(r.dest[:], &bs): case !wire_chop_slice(r.Dest[:], &bs):
return false return false
} }
for len(bs) > 0 { for len(bs) > 0 {
@ -509,7 +509,7 @@ func (r *dhtRes) decode(bs []byte) bool {
case !wire_chop_coords(&info.coords, &bs): case !wire_chop_coords(&info.coords, &bs):
return false return false
} }
r.infos = append(r.infos, &info) r.Infos = append(r.Infos, &info)
} }
return true return true
} }