CircleCI's localhost hostname doesn't resolve for IPv6.
}
}
- cl.conns, err = listenAll(cl.enabledPeerNetworks(), cl.config.ListenAddr)
+ cl.conns, err = listenAll(cl.enabledPeerNetworks(), cl.config.ListenHost, cl.config.ListenPort)
if err != nil {
return
}
"net"
"os"
"path/filepath"
+ "strings"
"sync"
"testing"
"time"
func TestingConfig() *Config {
return &Config{
- ListenAddr: "localhost:0",
+ ListenHost: func(network string) string {
+ if strings.Contains(network, "4") {
+ return "127.0.0.1"
+ } else {
+ return "::1"
+ }
+ },
NoDHT: true,
DataDir: tempDir(),
DisableTrackers: true,
cfg := TestingConfig()
cfg.DisableTCP = true
cfg.DisableUTP = true
- cfg.ListenAddr = "redonk"
+ cfg.ListenHost = func(string) string { return "redonk" }
cl, err := NewClient(cfg)
require.NoError(b, err)
defer cl.Close()
func TestAddMetainfoWithNodes(t *testing.T) {
cfg := TestingConfig()
- cfg.ListenAddr = ":0"
+ cfg.ListenHost = func(string) string { return "" }
cfg.NoDHT = false
cfg.DhtStartingNodes = func() ([]dht.Addr, error) { return nil, nil }
// For now, we want to just jam the nodes into the table, without
if s != nil {
defer s.Close()
}
- cfg := TestingConfig()
- cfg.ListenAddr = ":50007"
+ cfg := TestingConfig().SetListenAddr(":50007")
cl, err := NewClient(cfg)
require.Error(t, err)
require.Nil(t, cl)
clientConfig.DefaultStorage = storage.NewMMap("")
}
if flags.Addr != nil {
- clientConfig.ListenAddr = flags.Addr.String()
+ clientConfig.SetListenAddr(flags.Addr.String())
}
if flags.UploadRate != -1 {
clientConfig.UploadRateLimiter = rate.NewLimiter(rate.Limit(flags.UploadRate), 256<<10)
defer fuse.Unmount(args.MountDir)
// TODO: Think about the ramifications of exiting not due to a signal.
defer conn.Close()
- client, err := torrent.NewClient(&torrent.Config{
+ cfg := torrent.Config{
DataDir: args.DownloadDir,
DisableTrackers: args.DisableTrackers,
- ListenAddr: args.ListenAddr.String(),
NoUpload: true, // Ensure that downloads are responsive.
- })
+ }
+ cfg.SetListenAddr(args.ListenAddr.String())
+ client, err := torrent.NewClient(&cfg)
if err != nil {
log.Print(err)
return 1
"golang.org/x/time/rate"
"github.com/anacrolix/dht"
+ "github.com/anacrolix/missinggo"
+ "github.com/anacrolix/missinggo/expect"
"github.com/anacrolix/torrent/iplist"
"github.com/anacrolix/torrent/storage"
)
// The address to listen for new uTP and TCP bittorrent protocol
// connections. DHT shares a UDP socket with uTP unless configured
// otherwise.
- ListenAddr string `long:"listen-addr" value-name:"HOST:PORT"`
+ ListenHost func(network string) string
+ ListenPort int
NoDefaultPortForwarding bool
// Don't announce to trackers. This only leaves DHT to discover peers.
DisableTrackers bool `long:"disable-trackers"`
PublicIp6 net.IP
}
+func (cfg *Config) SetListenAddr(addr string) *Config {
+ host, port, err := missinggo.ParseHostPort(addr)
+ expect.Nil(err)
+ cfg.ListenHost = func(string) string { return host }
+ cfg.ListenPort = port
+ return cfg
+}
+
func (cfg *Config) setDefaults() {
if cfg.HTTP == nil {
cfg.HTTP = DefaultHTTPClient
layout, err := newGreetingLayout()
require.NoError(t, err)
defer layout.Destroy()
- seeder, err := torrent.NewClient(&torrent.Config{
+ seeder, err := torrent.NewClient((&torrent.Config{
DataDir: layout.Completed,
DisableTrackers: true,
NoDHT: true,
- ListenAddr: "localhost:0",
Seed: true,
- })
+ }).SetListenAddr("localhost:0"))
require.NoError(t, err)
defer seeder.Close()
testutil.ExportStatusWriter(seeder, "s")
<-seederTorrent.GotInfo()
seederTorrent.VerifyData()
}()
- leecher, err := torrent.NewClient(&torrent.Config{
+ leecher, err := torrent.NewClient((&torrent.Config{
DisableTrackers: true,
NoDHT: true,
- ListenAddr: "localhost:0",
DisableTCP: true,
DefaultStorage: storage.NewMMap(filepath.Join(layout.BaseDir, "download")),
// This can be used to check if clients can connect to other clients
// with the same ID.
// PeerID: seeder.PeerID(),
- })
+ }).SetListenAddr("localhost:0"))
require.NoError(t, err)
testutil.ExportStatusWriter(leecher, "l")
defer leecher.Close()
return net.JoinHostPort(host, strconv.FormatInt(int64(port), 10))
}
-func listenAll(networks []string, addr string) ([]socket, error) {
+func listenAll(networks []string, getHost func(string) string, port int) ([]socket, error) {
if len(networks) == 0 {
return nil, nil
}
+ var nahs []networkAndHost
+ for _, n := range networks {
+ nahs = append(nahs, networkAndHost{n, getHost(n)})
+ }
for {
- ss, retry, err := listenAllRetry(networks, addr)
+ ss, retry, err := listenAllRetry(nahs, port)
if !retry {
return ss, err
}
}
}
-func listenAllRetry(networks []string, addr string) (ss []socket, retry bool, err error) {
- _, port, err := missinggo.ParseHostPort(addr)
- if err != nil {
- err = fmt.Errorf("error parsing addr: %s", err)
- return
- }
- ss = make([]socket, 1, len(networks))
- ss[0], err = listen(networks[0], addr)
+type networkAndHost struct {
+ Network string
+ Host string
+}
+
+func listenAllRetry(nahs []networkAndHost, port int) (ss []socket, retry bool, err error) {
+ ss = make([]socket, 1, len(nahs))
+ portStr := strconv.FormatInt(int64(port), 10)
+ ss[0], err = listen(nahs[0].Network, net.JoinHostPort(nahs[0].Host, portStr))
if err != nil {
return nil, false, fmt.Errorf("first listen: %s", err)
}
ss = nil
}
}()
- restAddr := setPort(addr, missinggo.AddrPort(ss[0].Addr()))
- for _, n := range networks[1:] {
- s, err := listen(n, restAddr)
+ portStr = strconv.FormatInt(int64(missinggo.AddrPort(ss[0].Addr())), 10)
+ for _, nah := range nahs[1:] {
+ s, err := listen(nah.Network, net.JoinHostPort(nah.Host, portStr))
if err != nil {
return ss,
missinggo.IsAddrInUse(err) && port == 0,