func (ns *NodeState) do_NEIGH_PUSH(sok io.ReadWriteCloser, req textprot.TextReq) (err error) { var info textprot.NeighInfo err = info.FromString(req.Blob) if err != nil { return } // validate info sanctum := directory.DefaultProvider("").PublicKey() err = sanctum.Verify(info.Json.HashValue(), info.Signat) if err != nil { return } if subtle.ConstantTimeCompare(info.Json.IssuedTo, ns.client.GetPrivate().PublicKey()) != 1 { return errors.New("core2core: somebody pushed me a NEIGH_PUSH to the wrong person") } // pull more info from the directory neiz, err := ns.provider.JoinEdge(ns.client) if err != nil { return } // return okay err = (&textprot.TextReq{Verb: "OKAY"}).WriteTo(sok) if err != nil { return } // commit into data structure ns.Lock() defer ns.Unlock() ns.fulNeighs = neiz ns.sigNeighs = info return }
// ListNeighs lists the public keys of the neighbors of the node func (clnt *Client) ListNeighs() ([]natrium.EdDSAPublic, error) { req := textprot.TextReq{ Verb: "NEIGH_LIST", } resp, err := clnt.execCmd(req) var ninf textprot.NeighInfo err = ninf.FromString(resp.Blob) if err != nil { clnt.sok.Close() return nil, ErrBadSocket } // do the checks pubkey := directory.DefaultProvider("").PublicKey() err = pubkey.Verify(ninf.Json.HashValue(), ninf.Signat) if err != nil { clnt.sok.Close() // this server is really bad, go away now return nil, ErrBadCrypto } if ninf.Json.Expires < int(time.Now().Unix()) || subtle.ConstantTimeCompare(clnt.CurrentPublic(), ninf.Json.IssuedTo) != 1 { clnt.sok.Close() return nil, ErrBadCrypto } // return the val var toret []natrium.EdDSAPublic for _, v := range ninf.Json.NeighList { toret = append(toret, natrium.EdDSAPublic(v)) } return toret, nil }
// applyDeltaOnce pushes one piece of info into the network func (srv *Server) applyDeltaOnce(key ChordKey, meta Neighbor) { kilog.Debug("directory: beginning push to %x", key.ToBytes()) rawsok, err := kiricom.EasyDial(fmt.Sprintf("%v:%v", meta.Address, meta.Port), nil, meta.Secret) if err != nil { kilog.Debug("directory: push to %x failed due to %v", key.ToBytes(), err.Error()) return } defer rawsok.Close() sok, err := kiss.KiSSAnonHandshake(kiss.NewDirectVerifier(meta.PubKey), rawsok) if err != nil { kilog.Debug("directory: push to %x failed in KiSS due to %v", key.ToBytes(), err.Error()) return } defer sok.Close() srv.Lock() neighs, err := srv.crd.Neighs(key) if err != nil { panic("WTF is going on here") } srv.Unlock() var msg textprot.NeighInfo // expires 1hr from now msg.Json.Expires = int(time.Now().Add(time.Hour).Unix()) msg.Json.IssuedTo = meta.PubKey for _, nay := range neighs { msg.Json.NeighList = append(msg.Json.NeighList, nay.ToBytes()) } msg.Signat = srv.prv.Sign(msg.Json.HashValue()) // send the message req := textprot.TextReq{ Verb: "NEIGH_PUSH", Blob: msg.ToString(), } err = req.WriteTo(sok) if err != nil { kilog.Debug("directory: push to %x failed while pushing due to %v", key.ToBytes(), err.Error()) return } //fmt.Println(msg.ToString()) // get msg back err = req.ReadFrom(sok) if err != nil { kilog.Debug("directory: push to %x failed at the final stage", key.ToBytes()) return } kilog.Debug("directory: push to %x succeeded", key.ToBytes()) }