func (t *transport) handlePing(ch *e3x.Channel) { var ( err error pkt *lob.Packet id string alive bool ) defer ch.Close() pkt, err = ch.ReadPacket() if err != nil { // log error // tracef("error: %s", err) return } id, _ = pkt.Header().GetString("vn") rpc := t.lookupRPC(id) if rpc == nil { alive = false } else { alive = true } pkt = &lob.Packet{} pkt.Header().SetBool("alive", alive) err = ch.WritePacket(pkt) if err != nil { // log error // tracef("error: %s", err) return } }
func (t *transport) handleListVnodes(ch *e3x.Channel) { var ( err error res []*completeVnode ) defer ch.Close() _, err = ch.ReadPacket() if err != nil { // log error // tracef("error: %s", err) return } for _, rpc := range t.localVnodes { res = append(res, t.completeVnode(rpc.vn)) } err = json.NewEncoder(newStream(ch)).Encode(&res) if err != nil { // log error // tracef("error: %s", err) return } // tracef("handle.ListVnodes() => %s", res) }
func (mod *module) handle_peer(ch *e3x.Channel) { defer ch.Kill() log := mod.log.From(ch.RemoteHashname()).To(mod.e.LocalHashname()) // MUST allow router role if mod.config.DisableRouter { log.Println("drop: router disabled") return } pkt, err := ch.ReadPacket() if err != nil { log.Printf("drop: failed to read packet: %s", err) return } peerStr, ok := pkt.Header().GetString("peer") if !ok { log.Printf("drop: no peer in packet") return } peer := hashname.H(peerStr) // MUST have link to either endpoint if mod.e.GetExchange(ch.RemoteHashname()) == nil && mod.e.GetExchange(peer) == nil { log.Printf("drop: no link to either peer") return } // MUST pass firewall if mod.config.AllowPeer != nil && !mod.config.AllowPeer(ch.RemoteHashname(), peer) { log.Printf("drop: blocked by firewall") return } ex := mod.e.GetExchange(peer) if ex == nil { log.Printf("drop: no exchange to target") // resolve? return } token := cipherset.ExtractToken(pkt.Body(nil)) if token != cipherset.ZeroToken { // add bridge back to requester mod.RouteToken(token, ch.Exchange()) } mod.connect(ex, bufpool.New().Set(pkt.Body(nil))) }
func (t *transport) handleGetPredecessor(ch *e3x.Channel) { var ( err error pkt *lob.Packet id string vnode *chord.Vnode res *completeVnode ) defer ch.Close() pkt, err = ch.ReadPacket() if err != nil { // log error // tracef("error: %s", err) return } id, _ = pkt.Header().GetString("vn") rpc := t.lookupRPC(id) if rpc == nil { // log // tracef("error: %s", "no RPC") return } vnode, err = rpc.GetPredecessor() if err != nil { // log // tracef("error: %s", err) return } res = t.completeVnode(vnode) err = json.NewEncoder(newStream(ch)).Encode(&res) if err != nil { // log // tracef("error: %s", err) return } if res != nil { // tracef("handle.GetPredecessor(Vnode(%q)) => Vnode(%q)", id, res.Id) } }
// Ping a Vnode, check for liveness func (t *transport) Ping(vn *chord.Vnode) (bool, error) { var ( addr *e3x.Addr ch *e3x.Channel pkt *lob.Packet alive bool err error ) addr = t.lookupAddr(hashname.H(vn.Host)) if addr == nil { return false, e3x.ErrNoAddress } ch, err = t.e.Open(addr, "chord.ping", true) if err != nil { return false, err } defer ch.Close() // ch.SetReadDeadline(time.Now().Add(30*time.Second)) // ch.SetWriteDeadline(time.Now().Add(30*time.Second)) pkt = &lob.Packet{} pkt.Header().SetString("vn", vn.String()) err = ch.WritePacket(pkt) if err != nil { return false, err } pkt, err = ch.ReadPacket() if err != nil { return false, err } alive, _ = pkt.Header().GetBool("alive") // tracef("Ping(Vnode(%q)) => %v", vn.String(), alive) return alive, nil }
func (mod *module) handlePathRequest(c *e3x.Channel) { defer c.Kill() pkt, err := c.ReadPacket() if err != nil { return // ignore } // decode paths known by peer and add them as candidates if header, found := pkt.Header().Get("paths"); found { data, err := json.Marshal(header) if err != nil { return // ignore } var entries []json.RawMessage err = json.Unmarshal(data, &entries) if err != nil { return // ignore } for _, entry := range entries { addr, err := transports.DecodeAddr(entry) if err != nil { } if err == nil { c.Exchange().AddPathCandidate(addr) } } } var pipes = c.Exchange().KnownPipes() for _, pipe := range pipes { pkt := &lob.Packet{} pkt.Header().Set("path", pipe.RemoteAddr()) c.WritePacketTo(pkt, pipe) } }
func (d *dht) handle_see(c *e3x.Channel) { defer c.Close() pkt, err := c.ReadPacket() if err != nil { return } key, ok := pkt.Header().GetString("key") if !ok { return } h := d.localLookup(key) pkt = &lob.Packet{} pkt.Header().Set("see", h) pkt.Header().SetBool("end", true) err = c.WritePacket(pkt) if err != nil { return } }
func (mod *module) handle_connect(ch *e3x.Channel) { defer ch.Kill() var ( from hashname.H localIdent *e3x.Identity remoteIdent *e3x.Identity handshake cipherset.Handshake innerData = bufpool.New() err error ) localIdent, err = mod.e.LocalIdentity() if err != nil { return } pkt, err := ch.ReadPacket() if err != nil { return } pkt.Body(innerData.SetLen(pkt.BodyLen()).RawBytes()[:0]) inner, err := lob.Decode(innerData) if err != nil { return } innerHdr := inner.Header() if innerHdr.IsBinary() && len(innerHdr.Bytes) == 1 { // handshake var ( csid = innerHdr.Bytes[0] key = localIdent.Keys()[csid] ) if key == nil { return } handshake, err = cipherset.DecryptHandshake(csid, key, inner.Body(nil)) if err != nil { return } from, err = hashname.FromIntermediates(handshake.Parts()) if err != nil { return } remoteIdent, err = e3x.NewIdentity(cipherset.Keys{ handshake.CSID(): handshake.PublicKey(), }, handshake.Parts(), nil) if err != nil { return } } else { // key packet var parts = make(cipherset.Parts) var csid uint8 for key, value := range inner.Header().Extra { if len(key) != 2 { continue } keyData, err := hex.DecodeString(key) if err != nil { continue } partCSID := keyData[0] switch v := value.(type) { case bool: csid = partCSID case string: parts[partCSID] = v } } hn, err := hashname.FromKeyAndIntermediates(csid, inner.Body(nil), parts) if err != nil { return } from = hn pubKey, err := cipherset.DecodeKeyBytes(csid, inner.Body(nil), nil) if err != nil { return } remoteIdent, err = e3x.NewIdentity(cipherset.Keys{csid: pubKey}, parts, nil) if err != nil { return } } if from == "" { return } if mod.config.AllowConnect != nil && !mod.config.AllowConnect(from, ch.RemoteHashname()) { return } x, err := mod.e.CreateExchange(remoteIdent) if err != nil { return } // when the BODY contains a handshake if handshake != nil { routerExchange := ch.Exchange() routerAddr := &peerAddr{ router: routerExchange.RemoteHashname(), } conn := newConnection(x.RemoteHashname(), routerAddr, routerExchange, func() { mod.unregisterConnection(routerExchange, x.LocalToken()) }) pipe, added := x.AddPipeConnection(conn, nil) if added { mod.registerConnection(routerExchange, x.LocalToken(), conn) } resp, ok := x.ApplyHandshake(handshake, pipe) if !ok { return } if resp != nil { err = mod.peerVia(ch.Exchange(), from, resp) if err != nil { return } } } // when the BODY contains a key packet if handshake == nil { pkt, err := x.GenerateHandshake() if err != nil { return } err = mod.peerVia(ch.Exchange(), from, pkt) if err != nil { return } } // Notify on-exchange callbacks mod.getIntroduction(from).resolve(x, nil) }