Esempio n. 1
0
func buildCirc(tgt directory.ChordKey) (*core2core.Client, error) {
	// find the closest neighbor to the destination
	circPool.Lock()
	nxt := circPool.neighs[0]
	for _, v := range circPool.neighs[1:] {
		var vkee directory.ChordKey
		var xkee directory.ChordKey
		vkee.FromBytes(v.PubKey)
		xkee.FromBytes(nxt.PubKey)
		if vkee.Distance(tgt).Cmp(xkee.Distance(tgt)) == -1 {
			nxt = v
		}
	}
	circPool.Unlock()
	kilog.Debug("circ: closest neighbor to %x is %v", tgt.ToBytes(), nxt.PubKey)

	// begin to route
	spider, err := core2core.NewClient(nxt)
	if err != nil {
		return nil, err
	}
	//defer spider.Destroy()

	// loop
	closest := false
	for !closest {
		neighs, err := spider.ListNeighs()
		if err != nil {
			spider.Destroy()
			return nil, err
		}
		if len(neighs) == 0 {
			kilog.Warning("circ: topology anomaly! node with no neighbors!")
			spider.Destroy()
			return nil, err
		}
		better := spider.CurrentPublic()
		closest = true
		// can we find a closer one?
		for _, cand := range neighs {
			var candkee directory.ChordKey
			var currkee directory.ChordKey
			candkee.FromBytes(cand)
			currkee.FromBytes(better)
			if candkee.Distance(tgt).Cmp(currkee.Distance(tgt)) == -1 {
				better = cand
				closest = false
			}
		}
		// connect to the next hop
		if !closest {
			kilog.Debug("circ: circuit to %x extending to %v", tgt.ToBytes(), better)
			err = spider.ConnectNext(better)
			if err != nil {
				spider.Destroy()
				return nil, err
			}
		}
	}
	return spider, nil
}