Пример #1
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())
}
Пример #2
0
func (ns *NodeState) do_NEIGH_LIST(sok io.ReadWriteCloser, req textprot.TextReq) (err error) {
	var response textprot.TextReq
	defer func() {
		err = response.WriteTo(sok)
	}()
	ns.RLock()
	defer ns.RUnlock()

	if ns.sigNeighs.Signat == nil {
		response = textprot.TextReq{Verb: "NOPE"}
		return
	}
	// signeighs is fine now, let's do the magic!
	response = textprot.TextReq{
		Verb: "OKAY",
		Blob: ns.sigNeighs.ToString(),
	}
	return
}
Пример #3
0
func (clnt *Client) execCmd(req textprot.TextReq) (resp textprot.TextReq, err error) {
	err = req.WriteTo(clnt.sok)
	if err != nil {
		clnt.sok.Close()
		err = ErrBadSocket
		return
	}
	err = resp.ReadFrom(clnt.sok)
	if err != nil {
		clnt.sok.Close()
		err = ErrBadSocket
		return
	}
	fmt.Println(resp)
	if resp.Verb != "OKAY" {
		err = ErrRejectedReq
		return
	}
	return
}
Пример #4
0
func (ns *NodeState) do_NEIGH_CONNECT(sok io.ReadWriteCloser, req textprot.TextReq) (err error) {
	// decode the hex
	if len(req.Args) == 0 {
		err = errors.New("core2core: server got truncated NEIGH_CONNECT")
		return
	}
	hexstr := req.Args[0]
	bts, err := hex.DecodeString(hexstr)
	if err != nil {
		return
	}

	kilog.Debug("core2core: NEIGH_CONNECT received to %x", bts)

	// read-lock the state; release when done searching
	ns.RLock()
	// linear search for the next hop
	found := false
	var nxtneigh directory.Neighbor
	for _, val := range ns.fulNeighs {
		if subtle.ConstantTimeCompare(val.PubKey, bts) == 1 {
			nxtneigh = val
			found = found || true
			// don't break, precaution against side channels
		} else {
			found = found || false
		}
	}
	ns.RUnlock()
	if !found {
		response := textprot.TextReq{
			Verb: "NOPE",
		}
		err = response.WriteTo(sok)
		kilog.Debug("core2core: NEIGH_CONNECT to %x failed due to not found", bts)
		return
	}

	// easydial to the next hop
	hostport := fmt.Sprintf("%v:%v", nxtneigh.Address, nxtneigh.Port)
	nxtsok, err := kiricom.EasyDial(hostport, nil, nxtneigh.Secret)
	if err != nil {
		return
	}
	defer nxtsok.Close()

	// reply OKAY
	response := textprot.TextReq{
		Verb: "OKAY",
	}
	err = response.WriteTo(sok)
	if err != nil {
		return
	}

	kilog.Debug("core2core: NEIGH_CONNECT success to %x", bts)

	// begin tunneling
	go func() {
		defer nxtsok.Close()
		defer sok.Close()
		io.Copy(nxtsok, sok)
	}()
	defer sok.Close()
	io.Copy(sok, nxtsok)
	return nil
}