Rename Config->ClientConfig and change how defaults work

This is a very breaking change.
This commit is contained in:
Matt Joiner 2018-06-16 16:30:04 +10:00
parent ad5e44eaf5
commit e97f487d2e
5 changed files with 71 additions and 96 deletions

View File

@ -27,7 +27,6 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/dustin/go-humanize"
"github.com/google/btree"
"golang.org/x/time/rate"
"github.com/anacrolix/torrent/bencode"
"github.com/anacrolix/torrent/iplist"
@ -44,7 +43,7 @@ type Client struct {
event sync.Cond
closed missinggo.Event
config Config
config *ClientConfig
logger *log.Logger
halfOpenLimit int
@ -56,8 +55,6 @@ type Client struct {
ipBlockList iplist.Ranger
// Our BitTorrent protocol extension bytes, sent in our BT handshakes.
extensionBytes peerExtensionBytes
uploadLimit *rate.Limiter
downloadLimit *rate.Limiter
// Set of addresses that have our client ID. This intentionally will
// include ourselves if we end up trying to connect to our own address
@ -173,12 +170,10 @@ func (cl *Client) announceKey() int32 {
return int32(binary.BigEndian.Uint32(cl.peerID[16:20]))
}
func NewClient(cfg *Config) (cl *Client, err error) {
func NewClient(cfg *ClientConfig) (cl *Client, err error) {
if cfg == nil {
cfg = &Config{}
cfg = NewDefaultClientConfig()
}
cfg.setDefaults()
defer func() {
if err != nil {
cl = nil
@ -186,7 +181,7 @@ func NewClient(cfg *Config) (cl *Client, err error) {
}()
cl = &Client{
halfOpenLimit: cfg.HalfOpenConnsPerTorrent,
config: *cfg,
config: cfg,
dopplegangerAddrs: make(map[string]struct{}),
torrents: make(map[metainfo.Hash]*Torrent),
}
@ -198,16 +193,6 @@ func NewClient(cfg *Config) (cl *Client, err error) {
}
cl.Close()
}()
if cfg.UploadRateLimiter == nil {
cl.uploadLimit = unlimited
} else {
cl.uploadLimit = cfg.UploadRateLimiter
}
if cfg.DownloadRateLimiter == nil {
cl.downloadLimit = unlimited
} else {
cl.downloadLimit = cfg.DownloadRateLimiter
}
cl.extensionBytes = defaultPeerExtensionBytes()
cl.event.L = &cl.mu
storageImpl := cfg.DefaultStorage
@ -492,7 +477,7 @@ func dialUTP(ctx context.Context, addr string, sock utpSocket) (c net.Conn, err
var allPeerNetworks = []string{"tcp4", "tcp6", "udp4", "udp6"}
func peerNetworkEnabled(network string, cfg Config) bool {
func peerNetworkEnabled(network string, cfg *ClientConfig) bool {
c := func(s string) bool {
return strings.Contains(network, s)
}
@ -1178,7 +1163,7 @@ func (cl *Client) newConnection(nc net.Conn, outgoing bool) (c *connection) {
c.writerCond.L = &cl.mu
c.setRW(connStatsReadWriter{nc, c})
c.r = &rateLimitedReader{
l: cl.downloadLimit,
l: cl.config.DownloadRateLimiter,
r: c.r,
}
return

View File

@ -30,15 +30,14 @@ import (
"github.com/anacrolix/torrent/storage"
)
func TestingConfig() *Config {
return &Config{
ListenHost: LoopbackListenHost,
NoDHT: true,
DataDir: tempDir(),
DisableTrackers: true,
NoDefaultPortForwarding: true,
// Debug: true,
}
func TestingConfig() *ClientConfig {
cfg := NewDefaultClientConfig()
cfg.ListenHost = LoopbackListenHost
cfg.NoDHT = true
cfg.DataDir = tempDir()
cfg.DisableTrackers = true
cfg.NoDefaultPortForwarding = true
return cfg
}
func TestClientDefault(t *testing.T) {
@ -105,7 +104,9 @@ func TestPieceHashSize(t *testing.T) {
func TestTorrentInitialState(t *testing.T) {
dir, mi := testutil.GreetingTestTorrent()
defer os.RemoveAll(dir)
cl := &Client{}
cl := &Client{
config: &ClientConfig{},
}
cl.initLogger()
tor := cl.newTorrent(
mi.HashInfoBytes(),
@ -138,8 +139,7 @@ func TestUnmarshalPEXMsg(t *testing.T) {
}
func TestReducedDialTimeout(t *testing.T) {
cfg := &Config{}
cfg.setDefaults()
cfg := NewDefaultClientConfig()
for _, _case := range []struct {
Max time.Duration
HalfOpenLimit int
@ -357,7 +357,9 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) {
// Create seeder and a Torrent.
cfg := TestingConfig()
cfg.Seed = true
cfg.UploadRateLimiter = ps.SeederUploadRateLimiter
if ps.SeederUploadRateLimiter != nil {
cfg.UploadRateLimiter = ps.SeederUploadRateLimiter
}
// cfg.ListenAddr = "localhost:4000"
if ps.SeederStorage != nil {
cfg.DefaultStorage = ps.SeederStorage(greetingTempDir)
@ -380,12 +382,15 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) {
leecherDataDir, err := ioutil.TempDir("", "")
require.NoError(t, err)
defer os.RemoveAll(leecherDataDir)
cfg = TestingConfig()
if ps.LeecherStorage == nil {
cfg.DataDir = leecherDataDir
} else {
cfg.DefaultStorage = ps.LeecherStorage(leecherDataDir)
}
cfg.DownloadRateLimiter = ps.LeecherDownloadRateLimiter
if ps.LeecherDownloadRateLimiter != nil {
cfg.DownloadRateLimiter = ps.LeecherDownloadRateLimiter
}
cfg.Seed = false
leecher, err := NewClient(cfg)
require.NoError(t, err)
@ -443,6 +448,7 @@ func assertReadAllGreeting(t *testing.T, r io.ReadSeeker) {
func TestSeedAfterDownloading(t *testing.T) {
greetingTempDir, mi := testutil.GreetingTestTorrent()
defer os.RemoveAll(greetingTempDir)
cfg := TestingConfig()
cfg.Seed = true
cfg.DataDir = greetingTempDir
@ -454,6 +460,9 @@ func TestSeedAfterDownloading(t *testing.T) {
require.NoError(t, err)
assert.True(t, ok)
seederTorrent.VerifyData()
cfg = TestingConfig()
cfg.Seed = true
cfg.DataDir, err = ioutil.TempDir("", "")
require.NoError(t, err)
defer os.RemoveAll(cfg.DataDir)
@ -461,6 +470,8 @@ func TestSeedAfterDownloading(t *testing.T) {
require.NoError(t, err)
defer leecher.Close()
testutil.ExportStatusWriter(leecher, "l")
cfg = TestingConfig()
cfg.Seed = false
cfg.DataDir, err = ioutil.TempDir("", "")
require.NoError(t, err)
@ -982,8 +993,11 @@ func TestSetMaxEstablishedConn(t *testing.T) {
defer ss.Close()
var tts []*Torrent
ih := testutil.GreetingMetaInfo().HashInfoBytes()
cfg := TestingConfig()
cfg.DisableAcceptRateLimiting = true
cfg.dropDuplicatePeerIds = true
for i := range iter.N(3) {
cl, err := NewClient(TestingConfig())
cl, err := NewClient(cfg)
require.NoError(t, err)
defer cl.Close()
tt, _ := cl.AddTorrentInfoHash(ih)

View File

@ -16,20 +16,10 @@ import (
"github.com/anacrolix/torrent/storage"
)
var DefaultHTTPClient = &http.Client{
Timeout: time.Second * 15,
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 15 * time.Second,
}).Dial,
TLSHandshakeTimeout: 15 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
var DefaultHTTPUserAgent = "Go-Torrent/1.0"
// Override Client defaults.
type Config struct {
// Probably not safe to modify this after it's given to a Client.
type ClientConfig struct {
// Store torrent file data in this directory unless .DefaultStorage is
// specified.
DataDir string `long:"data-dir" description:"directory to store downloaded torrent data"`
@ -120,7 +110,7 @@ type Config struct {
PublicIp6 net.IP
}
func (cfg *Config) SetListenAddr(addr string) *Config {
func (cfg *ClientConfig) SetListenAddr(addr string) *ClientConfig {
host, port, err := missinggo.ParseHostPort(addr)
expect.Nil(err)
cfg.ListenHost = func(string) string { return host }
@ -128,53 +118,35 @@ func (cfg *Config) SetListenAddr(addr string) *Config {
return cfg
}
func (cfg *Config) setDefaults() {
if cfg.HTTP == nil {
cfg.HTTP = DefaultHTTPClient
if cfg.ProxyURL != "" {
cfg.setProxyURL()
}
}
if cfg.HTTPUserAgent == "" {
cfg.HTTPUserAgent = DefaultHTTPUserAgent
}
if cfg.ExtendedHandshakeClientVersion == "" {
cfg.ExtendedHandshakeClientVersion = "go.torrent dev 20150624"
}
if cfg.Bep20 == "" {
cfg.Bep20 = "-GT0001-"
}
if cfg.NominalDialTimeout == 0 {
cfg.NominalDialTimeout = 30 * time.Second
}
if cfg.MinDialTimeout == 0 {
cfg.MinDialTimeout = 5 * time.Second
}
if cfg.EstablishedConnsPerTorrent == 0 {
cfg.EstablishedConnsPerTorrent = 50
}
if cfg.HalfOpenConnsPerTorrent == 0 {
cfg.HalfOpenConnsPerTorrent = (cfg.EstablishedConnsPerTorrent + 1) / 2
}
if cfg.TorrentPeersHighWater == 0 {
// Memory and freshness are the concern here.
cfg.TorrentPeersHighWater = 500
}
if cfg.TorrentPeersLowWater == 0 {
cfg.TorrentPeersLowWater = 2 * cfg.HalfOpenConnsPerTorrent
}
if cfg.HandshakesTimeout == 0 {
cfg.HandshakesTimeout = 20 * time.Second
}
if cfg.DhtStartingNodes == nil {
cfg.DhtStartingNodes = dht.GlobalBootstrapAddrs
}
if cfg.ListenHost == nil {
cfg.ListenHost = func(string) string { return "" }
func NewDefaultClientConfig() *ClientConfig {
return &ClientConfig{
HTTP: &http.Client{
Timeout: time.Second * 15,
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 15 * time.Second,
}).Dial,
TLSHandshakeTimeout: 15 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}},
HTTPUserAgent: DefaultHTTPUserAgent,
ExtendedHandshakeClientVersion: "go.torrent dev 20150624",
Bep20: "-GT0001-",
NominalDialTimeout: 30 * time.Second,
MinDialTimeout: 5 * time.Second,
EstablishedConnsPerTorrent: 50,
HalfOpenConnsPerTorrent: 25,
TorrentPeersHighWater: 500,
TorrentPeersLowWater: 50,
HandshakesTimeout: 20 * time.Second,
DhtStartingNodes: dht.GlobalBootstrapAddrs,
ListenHost: func(string) string { return "" },
UploadRateLimiter: unlimited,
DownloadRateLimiter: unlimited,
}
}
func (cfg *Config) setProxyURL() {
func (cfg *ClientConfig) setProxyURL() {
fixedURL, err := url.Parse(cfg.ProxyURL)
if err != nil {
return

View File

@ -1308,7 +1308,7 @@ another:
return false
}
for r := range c.PeerRequests {
res := c.t.cl.uploadLimit.ReserveN(time.Now(), int(r.Length))
res := c.t.cl.config.UploadRateLimiter.ReserveN(time.Now(), int(r.Length))
if !res.OK() {
panic(fmt.Sprintf("upload rate limiter burst size < %d", r.Length))
}

View File

@ -21,7 +21,9 @@ import (
// Have that would potentially alter it.
func TestSendBitfieldThenHave(t *testing.T) {
r, w := io.Pipe()
var cl Client
cl := Client{
config: &ClientConfig{DownloadRateLimiter: unlimited},
}
cl.initLogger()
c := cl.newConnection(nil, false)
c.setTorrent(cl.newTorrent(metainfo.Hash{}, nil))
@ -87,7 +89,9 @@ func (me *torrentStorage) WriteAt(b []byte, _ int64) (int, error) {
func BenchmarkConnectionMainReadLoop(b *testing.B) {
cl := &Client{
downloadLimit: unlimited,
config: &ClientConfig{
DownloadRateLimiter: unlimited,
},
}
ts := &torrentStorage{}
t := &Torrent{