// 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()) }
func (dpv dftProv) getSock(clnt Client) io.ReadWriteCloser { sock, err := net.Dial("tcp", dpv.url) if err != nil { kilog.Warning("directory: default provider failed: %v", err.Error()) return nil } /*obsok, err := kiss.LLObfsClientHandshake(dpv.PublicKey(), sock) if err != nil { kilog.Warning("directory: default provider failed: %v", err.Error()) sock.Close() return nil }*/ secsok, err := kiss.KiSSNamedHandshake(clnt.private, kiss.NewDirectVerifier(dpv.PublicKey()), sock) if err != nil { kilog.Warning("directory: default provider failed: %v", err.Error()) sock.Close() return nil } return secsok }
// NewClient creates a client from the given first-node information. func NewClient(first directory.Neighbor) (toret *Client, err error) { // kissless kiricom sok, err := kiricom.EasyDial( fmt.Sprintf("%v:%v", first.Address, first.Port), nil, first.Secret) if err != nil { return } // negotiate KiSS secsok, err := kiss.KiSSAnonHandshake(kiss.NewDirectVerifier(first.PubKey), sok) if err != nil { return } // return the client toret = &Client{ sok: secsok, pklst: []natrium.EdDSAPublic{first.PubKey}, } return }
// ConnectNext connects to the next hop, identified by public key func (clnt *Client) ConnectNext(nxpub natrium.EdDSAPublic) error { req := textprot.TextReq{ Verb: "NEIGH_CONNECT", Args: []string{hex.EncodeToString(nxpub)}, } _, err := clnt.execCmd(req) if err != nil { return err } // now negotiate KiSS newsok, err := kiss.KiSSAnonHandshake(kiss.NewDirectVerifier(nxpub), clnt.sok) if err != nil { clnt.sok.Close() return ErrBadSocket } clnt.sok = newsok clnt.pklst = append(clnt.pklst, nxpub) clnt.circlen++ return nil }
// connect to the service identified by the public key func dialPubKey(pub natrium.EdDSAPublic) (io.ReadWriteCloser, error) { kilog.Debug("circ: beginning to dial %v", pub) var key directory.ChordKey key.FromBytes(pub) circPool.Lock() if len(circPool.neighs) == 0 { circPool.Unlock() return nil, ErrNoRoute } once, ok := circPool.onceTab[key] if !ok { kilog.Debug("circ: %v is a new destination, will have to build a fresh one", pub) once = new(sync.Once) circPool.onceTab[key] = once } circPool.Unlock() once.Do(func() { kilog.Debug("circ: entered atomic action for %v", pub) defer kilog.Debug("circ: leaving atomic action for %v", pub) thing, err := newCircGroup(pub) if err != nil { kilog.Debug("circ: rolling back %v due to %v", pub, err.Error()) circPool.Lock() delete(circPool.onceTab, key) circPool.Unlock() return } circPool.Lock() circPool.dialTab[key] = thing circPool.Unlock() }) circPool.Lock() thing, ok := circPool.dialTab[key] circPool.Unlock() if !ok { return nil, ErrNoRoute } raah, err := thing.Dial() if err != nil { thing.Destroy() circPool.Lock() if circPool.onceTab[key] != nil { delete(circPool.onceTab, key) } if circPool.dialTab[key] != nil { delete(circPool.dialTab, key) } circPool.Unlock() return nil, err } toret, err := kiss.KiSSAnonHandshake(kiss.NewDirectVerifier(pub), raah) if err != nil { thing.Destroy() circPool.Lock() if circPool.onceTab[key] != nil { delete(circPool.onceTab, key) } if circPool.dialTab[key] != nil { delete(circPool.dialTab, key) } circPool.Unlock() return nil, err } return toret, nil }