diff --git a/src/yggdrasil/peer.go b/src/yggdrasil/peer.go index 0113470e..1656d392 100644 --- a/src/yggdrasil/peer.go +++ b/src/yggdrasil/peer.go @@ -205,11 +205,13 @@ func (p *peer) linkLoop() { case counter%4 == 0: update = true } - if update { + if true || update { + // TODO change update logic, the new switchMsg works differently if p.msgAnc != nil { lastRSeq = p.msgAnc.Seq } - p.sendSwitchAnnounce() + p.sendSwitchMsg() + //p.sendSwitchAnnounce() } counter = (counter + 1) % 4 } @@ -236,10 +238,11 @@ func (p *peer) handlePacket(packet []byte) { } func (p *peer) handleTraffic(packet []byte, pTypeLen int) { - if p.port != 0 && p.msgAnc == nil { - // Drop traffic until the peer manages to send us at least one anc - return - } + //if p.port != 0 && p.msgAnc == nil { + // // Drop traffic until the peer manages to send us at least one anc + // // TODO? equivalent for new switch format? + // return + //} ttl, ttlLen := wire_decode_uint64(packet[pTypeLen:]) ttlBegin := pTypeLen ttlEnd := pTypeLen + ttlLen @@ -298,6 +301,8 @@ func (p *peer) handleLinkTraffic(bs []byte) { return } switch pType { + case wire_SwitchMsg: + p.handleSwitchMsg(payload) case wire_SwitchAnnounce: p.handleSwitchAnnounce(payload) case wire_SwitchHopRequest: @@ -467,12 +472,79 @@ func (p *peer) processSwitchMessage() { if len(coords) == 0 { return } - // Reuse locator, set the coords to the peer's coords, to use in dht - msg.locator.coords = coords[:len(coords)-1] // Pass a mesage to the dht informing it that this peer (still) exists + l := msg.locator + l.coords = l.coords[:len(l.coords)-1] dinfo := dhtInfo{ key: p.box, - coords: msg.locator.getCoords(), + coords: l.getCoords(), + } + p.core.dht.peers <- &dinfo + p.core.log.Println("DEBUG: peers<-&dhtInfo", dinfo, p.box, msg) +} + +func (p *peer) sendSwitchMsg() { + info, sigs := p.core.switchTable.createMessage(p.port) + var msg switchMsg + msg.Root, msg.TStamp = info.locator.root, info.locator.tstamp + for idx, sig := range sigs { + hop := switchMsgHop{ + Port: info.locator.coords[idx], + Next: sig.next, + Sig: sig.sig, + } + msg.Hops = append(msg.Hops, hop) + } + msg.Hops = append(msg.Hops, switchMsgHop{ + Port: p.port, + Next: p.sig, + Sig: *sign(&p.core.sigPriv, getBytesForSig(&p.sig, &info.locator)), + }) + packet := msg.encode() + var test switchMsg + test.decode(packet) + //p.core.log.Println("Encoded msg:", msg, "; bytes:", packet) + p.sendLinkPacket(packet) +} + +func (p *peer) handleSwitchMsg(packet []byte) { + var msg switchMsg + msg.decode(packet) + //p.core.log.Println("Decoded msg:", msg, "; bytes:", packet) + if len(msg.Hops) < 1 { + p.throttle++ + panic("FIXME testing") + return + } + var info switchMessage + var sigs []sigInfo + info.locator.root = msg.Root + info.locator.tstamp = msg.TStamp + thisHopKey := &msg.Root + for _, hop := range msg.Hops { + var sig sigInfo + sig.next = hop.Next + sig.sig = hop.Sig + sigs = append(sigs, sig) + info.locator.coords = append(info.locator.coords, hop.Port) + // TODO check signatures + bs := getBytesForSig(&hop.Next, &info.locator) + if !p.core.sigs.check(thisHopKey, &hop.Sig, bs) { + //p.throttle++ + //panic("FIXME testing") + //return + } + thisHopKey = &hop.Next + } + info.from = p.sig + info.seq = uint64(time.Now().Unix()) + p.core.switchTable.handleMessage(&info, p.port, sigs) + // Pass a mesage to the dht informing it that this peer (still) exists + l := info.locator + l.coords = l.coords[:len(l.coords)-1] + dinfo := dhtInfo{ + key: p.box, + coords: l.getCoords(), } p.core.dht.peers <- &dinfo } diff --git a/src/yggdrasil/wire.go b/src/yggdrasil/wire.go index 6b592e5b..bd298de9 100644 --- a/src/yggdrasil/wire.go +++ b/src/yggdrasil/wire.go @@ -12,6 +12,7 @@ const ( wire_Traffic = iota // data being routed somewhere, handle for crypto wire_ProtocolTraffic // protocol traffic, pub keys for crypto wire_LinkProtocolTraffic // link proto traffic, pub keys for crypto + wire_SwitchMsg // inside link protocol traffic header wire_SwitchAnnounce // inside protocol traffic header wire_SwitchHopRequest // inside protocol traffic header wire_SwitchHop // inside protocol traffic header @@ -117,6 +118,61 @@ func wire_decode_coords(packet []byte) ([]byte, int) { //////////////////////////////////////////////////////////////////////////////// +type switchMsg struct { + Root sigPubKey + TStamp int64 + Hops []switchMsgHop +} + +type switchMsgHop struct { + Port switchPort + Next sigPubKey + Sig sigBytes +} + +func (m *switchMsg) encode() []byte { + bs := wire_encode_uint64(wire_SwitchMsg) + bs = append(bs, m.Root[:]...) + bs = append(bs, wire_encode_uint64(wire_intToUint(m.TStamp))...) + for _, hop := range m.Hops { + bs = append(bs, wire_encode_uint64(uint64(hop.Port))...) + bs = append(bs, hop.Next[:]...) + bs = append(bs, hop.Sig[:]...) + } + return bs +} + +func (m *switchMsg) decode(bs []byte) bool { + var pType uint64 + var tstamp uint64 + switch { + case !wire_chop_uint64(&pType, &bs): + return false + case pType != wire_SwitchMsg: + return false + case !wire_chop_slice(m.Root[:], &bs): + return false + case !wire_chop_uint64(&tstamp, &bs): + return false + } + m.TStamp = wire_intFromUint(tstamp) + for len(bs) > 0 { + var hop switchMsgHop + switch { + case !wire_chop_uint64((*uint64)(&hop.Port), &bs): + return false + case !wire_chop_slice(hop.Next[:], &bs): + return false + case !wire_chop_slice(hop.Sig[:], &bs): + return false + } + m.Hops = append(m.Hops, hop) + } + return true +} + +//////////////////////////////////////////////////////////////////////////////// + // Announces that we can send parts of a Message with a particular seq type msgAnnounce struct { Root sigPubKey