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 }