misc.go 1.37 KB
Newer Older
Matt Joiner's avatar
Matt Joiner committed
1 2
package dht

3
import (
4
	"fmt"
5
	"hash/fnv"
6
	"net"
7

8
	"github.com/anacrolix/missinggo/v2"
Matt Joiner's avatar
Matt Joiner committed
9 10
	"github.com/lukechampine/stm/stmutil"

11
	"github.com/anacrolix/dht/v2/krpc"
12
)
Matt Joiner's avatar
Matt Joiner committed
13 14 15 16 17 18 19 20 21

func mustListen(addr string) net.PacketConn {
	ret, err := net.ListenPacket("udp", addr)
	if err != nil {
		panic(err)
	}
	return ret
}

22 23 24 25
func addrResolver(addr string) func() ([]Addr, error) {
	return func() ([]Addr, error) {
		ua, err := net.ResolveUDPAddr("udp", addr)
		return []Addr{NewAddr(ua)}, err
Matt Joiner's avatar
Matt Joiner committed
26 27
	}
}
28

29 30 31 32 33 34 35 36 37 38 39 40 41
type addrMaybeId struct {
	Addr krpc.NodeAddr
	Id   *int160
}

func (me addrMaybeId) String() string {
	if me.Id == nil {
		return fmt.Sprintf("unknown id at %s", me.Addr)
	} else {
		return fmt.Sprintf("%x at %v", *me.Id, me.Addr)
	}
}

Matt Joiner's avatar
Matt Joiner committed
42 43
func nodesByDistance(target int160) stmutil.Settish {
	return stmutil.NewSortedSet(func(_l, _r interface{}) bool {
44
		var ml missinggo.MultiLess
Matt Joiner's avatar
Matt Joiner committed
45 46
		l := _l.(addrMaybeId)
		r := _r.(addrMaybeId)
47 48 49 50 51 52 53 54 55
		ml.NextBool(r.Id == nil, l.Id == nil)
		if l.Id != nil && r.Id != nil {
			d := distance(*l.Id, target).Cmp(distance(*r.Id, target))
			ml.StrictNext(d == 0, d < 0)
		}
		hashString := func(s string) uint64 {
			h := fnv.New64a()
			h.Write([]byte(s))
			return h.Sum64()
Matt Joiner's avatar
Matt Joiner committed
56
		}
57 58 59 60 61
		lh := hashString(l.Addr.String())
		rh := hashString(r.Addr.String())
		ml.StrictNext(lh == rh, lh < rh)
		//ml.StrictNext(l.Addr.String() == r.Addr.String(), l.Addr.String() < r.Addr.String())
		return ml.Less()
Matt Joiner's avatar
Matt Joiner committed
62
	})
63
}