예제 #1
0
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
}
예제 #2
0
// 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
}
예제 #3
0
// 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())
}