revert to _9 and add save info bytes

This commit is contained in:
YouROK
2020-04-18 15:19:39 +03:00
parent 0bc5ea3084
commit 45b2bfdd05
12 changed files with 93 additions and 72 deletions

View File

@@ -37,13 +37,12 @@ type Settings struct {
DisableUPNP bool DisableUPNP bool
DisableDHT bool DisableDHT bool
DisableUpload bool DisableUpload bool
//Encryption int // 0 - Enable, 1 - disable, 2 - force Encryption int // 0 - Enable, 1 - disable, 2 - force
DownloadRateLimit int // in kb, 0 - inf DownloadRateLimit int // in kb, 0 - inf
UploadRateLimit int // in kb, 0 - inf UploadRateLimit int // in kb, 0 - inf
ConnectionsLimit int ConnectionsLimit int
DhtConnectionLimit int // 0 - inf DhtConnectionLimit int // 0 - inf
PeersListenPort int PeersListenPort int
PeerStrategy int // 0 - Timeout, 1 - Fastest, 2 - Fuzzing
TorrentDisconnectTimeout int // in seconds TorrentDisconnectTimeout int // in seconds
} }

View File

@@ -10,6 +10,7 @@ import (
type Torrent struct { type Torrent struct {
Name string Name string
Magnet string Magnet string
InfoBytes []byte
Hash string Hash string
Size int64 Size int64
Timestamp int64 Timestamp int64
@@ -83,6 +84,10 @@ func SaveTorrentDB(torrent *Torrent) error {
if err != nil { if err != nil {
return fmt.Errorf("error save torrent: %v", err) return fmt.Errorf("error save torrent: %v", err)
} }
err = hdb.Put([]byte("InfoBytes"), torrent.InfoBytes)
if err != nil {
return fmt.Errorf("error save torrent: %v", err)
}
err = hdb.Put([]byte("Size"), i2b(torrent.Size)) err = hdb.Put([]byte("Size"), i2b(torrent.Size))
if err != nil { if err != nil {
return fmt.Errorf("error save torrent: %v", err) return fmt.Errorf("error save torrent: %v", err)
@@ -172,6 +177,13 @@ func LoadTorrentDB(hash string) (*Torrent, error) {
} }
torr.Magnet = string(tmp) torr.Magnet = string(tmp)
tmp = hdb.Get([]byte("InfoBytes"))
if len(tmp) > 0 {
torr.InfoBytes = tmp
} else {
torr.InfoBytes = nil
}
tmp = hdb.Get([]byte("Size")) tmp = hdb.Get([]byte("Size"))
if tmp == nil { if tmp == nil {
return fmt.Errorf("error load torrent") return fmt.Errorf("error load torrent")

View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"io" "io"
"sync" "sync"
"time"
"server/settings" "server/settings"
"server/torr/storage/memcache" "server/torr/storage/memcache"
@@ -80,10 +79,10 @@ func (bt *BTServer) configure() {
bt.config.NoDefaultPortForwarding = settings.Get().DisableUPNP bt.config.NoDefaultPortForwarding = settings.Get().DisableUPNP
bt.config.NoDHT = settings.Get().DisableDHT bt.config.NoDHT = settings.Get().DisableDHT
bt.config.NoUpload = settings.Get().DisableUpload bt.config.NoUpload = settings.Get().DisableUpload
//bt.config.EncryptionPolicy = torrent.EncryptionPolicy{ bt.config.EncryptionPolicy = torrent.EncryptionPolicy{
// DisableEncryption: settings.Get().Encryption == 1, DisableEncryption: settings.Get().Encryption == 1,
// ForceEncryption: settings.Get().Encryption == 2, ForceEncryption: settings.Get().Encryption == 2,
//} }
bt.config.IPBlocklist = blocklist bt.config.IPBlocklist = blocklist
bt.config.DefaultStorage = bt.storage bt.config.DefaultStorage = bt.storage
bt.config.Bep20 = peerID bt.config.Bep20 = peerID
@@ -91,13 +90,6 @@ func (bt *BTServer) configure() {
bt.config.HTTPUserAgent = userAgent bt.config.HTTPUserAgent = userAgent
bt.config.ExtendedHandshakeClientVersion = cliVers bt.config.ExtendedHandshakeClientVersion = cliVers
bt.config.EstablishedConnsPerTorrent = settings.Get().ConnectionsLimit bt.config.EstablishedConnsPerTorrent = settings.Get().ConnectionsLimit
if settings.Get().PeerStrategy == 1 { //Fastest
bt.config.DefaultRequestStrategy = torrent.RequestStrategyFastest()
} else if settings.Get().PeerStrategy == 2 { //Fuzzing
bt.config.DefaultRequestStrategy = torrent.RequestStrategyFuzzing()
} else {
bt.config.DefaultRequestStrategy = torrent.RequestStrategyDuplicateRequestTimeout(time.Second * 5)
}
if settings.Get().DhtConnectionLimit > 0 { if settings.Get().DhtConnectionLimit > 0 {
bt.config.ConnTracker.SetMaxEntries(settings.Get().DhtConnectionLimit) bt.config.ConnTracker.SetMaxEntries(settings.Get().DhtConnectionLimit)
} }
@@ -115,8 +107,8 @@ func (bt *BTServer) configure() {
log.Println("Configure client:", settings.Get()) log.Println("Configure client:", settings.Get())
} }
func (bt *BTServer) AddTorrent(magnet metainfo.Magnet, onAdd func(*Torrent)) (*Torrent, error) { func (bt *BTServer) AddTorrent(magnet metainfo.Magnet, infobytes []byte, onAdd func(*Torrent)) (*Torrent, error) {
torr, err := NewTorrent(magnet, bt) torr, err := NewTorrent(magnet, infobytes, bt)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -169,7 +161,6 @@ func (bt *BTServer) BTState() *BTState {
btState.LocalPort = bt.client.LocalPort() btState.LocalPort = bt.client.LocalPort()
btState.PeerID = fmt.Sprintf("%x", bt.client.PeerID()) btState.PeerID = fmt.Sprintf("%x", bt.client.PeerID())
btState.BannedIPs = len(bt.client.BadPeerIPs()) btState.BannedIPs = len(bt.client.BadPeerIPs())
for _, dht := range bt.client.DhtServers() { for _, dht := range bt.client.DhtServers() {
btState.DHTs = append(btState.DHTs, dht) btState.DHTs = append(btState.DHTs, dht)
} }

View File

@@ -8,10 +8,11 @@ import (
"server/settings" "server/settings"
"server/utils" "server/utils"
"log"
"github.com/anacrolix/missinggo/httptoo" "github.com/anacrolix/missinggo/httptoo"
"github.com/anacrolix/torrent" "github.com/anacrolix/torrent"
"github.com/labstack/echo" "github.com/labstack/echo"
"log"
) )
func (bt *BTServer) View(torr *Torrent, file *torrent.File, c echo.Context) error { func (bt *BTServer) View(torr *Torrent, file *torrent.File, c echo.Context) error {

View File

@@ -1,14 +1,14 @@
package torr package torr
import ( import (
"github.com/anacrolix/torrent" "github.com/anacrolix/dht"
) )
type BTState struct { type BTState struct {
LocalPort int LocalPort int
PeerID string PeerID string
BannedIPs int BannedIPs int
DHTs []torrent.DhtServer DHTs []*dht.Server
Torrents []*Torrent Torrents []*Torrent
} }

View File

@@ -74,7 +74,7 @@ type Torrent struct {
progressTicker *time.Ticker progressTicker *time.Ticker
} }
func NewTorrent(magnet metainfo.Magnet, bt *BTServer) (*Torrent, error) { func NewTorrent(magnet metainfo.Magnet, infobytes []byte, bt *BTServer) (*Torrent, error) {
switch settings.Get().RetrackersMode { switch settings.Get().RetrackersMode {
case 1: case 1:
magnet.Trackers = append(magnet.Trackers, utils.GetDefTrackers()...) magnet.Trackers = append(magnet.Trackers, utils.GetDefTrackers()...)
@@ -84,6 +84,7 @@ func NewTorrent(magnet metainfo.Magnet, bt *BTServer) (*Torrent, error) {
magnet.Trackers = utils.GetDefTrackers() magnet.Trackers = utils.GetDefTrackers()
} }
goTorrent, _, err := bt.client.AddTorrentSpec(&torrent.TorrentSpec{ goTorrent, _, err := bt.client.AddTorrentSpec(&torrent.TorrentSpec{
InfoBytes: infobytes,
Trackers: [][]string{magnet.Trackers}, Trackers: [][]string{magnet.Trackers},
DisplayName: magnet.DisplayName, DisplayName: magnet.DisplayName,
InfoHash: magnet.InfoHash, InfoHash: magnet.InfoHash,

View File

@@ -1,4 +1,4 @@
package version package version
const Version = "1.1.76_12" const Version = "1.1.76_20"
const VerInt = 76 const VerInt = 76

View File

@@ -7,8 +7,6 @@ import (
"server/utils" "server/utils"
dht2 "github.com/anacrolix/dht"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
"github.com/labstack/echo" "github.com/labstack/echo"
"github.com/labstack/gommon/bytes" "github.com/labstack/gommon/bytes"
@@ -41,12 +39,10 @@ func statePage(c echo.Context) error {
for _, dht := range state.DHTs { for _, dht := range state.DHTs {
msg += fmt.Sprintf("%s DHT server at %s:<br>\n", dht.Addr().Network(), dht.Addr().String()) msg += fmt.Sprintf("%s DHT server at %s:<br>\n", dht.Addr().Network(), dht.Addr().String())
dhtStats := dht.Stats() dhtStats := dht.Stats()
if ds, ok := dhtStats.(dht2.ServerStats); ok { msg += fmt.Sprintf("\t&emsp;# Nodes: %d (%d good, %d banned)<br>\n", dhtStats.Nodes, dhtStats.GoodNodes, dhtStats.BadNodes)
msg += fmt.Sprintf("\t&emsp;# Nodes: %d (%d good, %d banned)<br>\n", ds.Nodes, ds.GoodNodes, ds.BadNodes)
msg += fmt.Sprintf("\t&emsp;Server ID: %x<br>\n", dht.ID()) msg += fmt.Sprintf("\t&emsp;Server ID: %x<br>\n", dht.ID())
msg += fmt.Sprintf("\t&emsp;Announces: %d<br>\n", ds.SuccessfulOutboundAnnouncePeerQueries) msg += fmt.Sprintf("\t&emsp;Announces: %d<br>\n", dhtStats.SuccessfulOutboundAnnouncePeerQueries)
msg += fmt.Sprintf("\t&emsp;Outstanding transactions: %d<br>\n", ds.OutstandingTransactions) msg += fmt.Sprintf("\t&emsp;Outstanding transactions: %d<br>\n", dhtStats.OutstandingTransactions)
}
} }
sort.Slice(state.Torrents, func(i, j int) bool { sort.Slice(state.Torrents, func(i, j int) bool {

View File

@@ -84,7 +84,7 @@ func torrentAdd(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Link must be non-empty") return echo.NewHTTPError(http.StatusBadRequest, "Link must be non-empty")
} }
magnet, err := helpers.GetMagnet(jreq.Link) magnet, infoBytes, err := helpers.GetMagnet(jreq.Link)
if err != nil { if err != nil {
fmt.Println("Error get magnet:", jreq.Hash, err) fmt.Println("Error get magnet:", jreq.Hash, err)
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
@@ -94,7 +94,17 @@ func torrentAdd(c echo.Context) error {
magnet.DisplayName = jreq.Title magnet.DisplayName = jreq.Title
} }
err = helpers.Add(bts, *magnet, !jreq.DontSave) tor := bts.GetTorrent(magnet.InfoHash)
if tor != nil {
return c.String(http.StatusOK, magnet.InfoHash.HexString())
}
torDb, err := settings.LoadTorrentDB(magnet.InfoHash.HexString())
if err == nil && torDb != nil {
infoBytes = torDb.InfoBytes
}
err = helpers.Add(bts, *magnet, infoBytes, !jreq.DontSave)
if err != nil { if err != nil {
fmt.Println("Error add torrent:", jreq.Hash, err) fmt.Println("Error add torrent:", jreq.Hash, err)
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
@@ -117,7 +127,7 @@ func torrentUpload(c echo.Context) error {
defer form.RemoveAll() defer form.RemoveAll()
_, dontSave := form.Value["DontSave"] _, dontSave := form.Value["DontSave"]
var magnets []metainfo.Magnet magnets := map[*metainfo.Magnet][]byte{}
for _, file := range form.File { for _, file := range form.File {
torrFile, err := file[0].Open() torrFile, err := file[0].Open()
@@ -138,12 +148,12 @@ func torrentUpload(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }
magnet := mi.Magnet(info.Name, mi.HashInfoBytes()) magnet := mi.Magnet(info.Name, mi.HashInfoBytes())
magnets = append(magnets, magnet) magnets[&magnet] = mi.InfoBytes
} }
ret := make([]string, 0) ret := make([]string, 0)
for _, magnet := range magnets { for magnet, infobytes := range magnets {
er := helpers.Add(bts, magnet, !dontSave) er := helpers.Add(bts, *magnet, infobytes, !dontSave)
if er != nil { if er != nil {
err = er err = er
fmt.Println("Error add torrent:", magnet.String(), er) fmt.Println("Error add torrent:", magnet.String(), er)
@@ -334,7 +344,7 @@ func preload(hashHex, fileLink string, size int64) *echo.HTTPError {
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "Error parser magnet in db: "+hashHex) return echo.NewHTTPError(http.StatusBadRequest, "Error parser magnet in db: "+hashHex)
} }
tor, err = bts.AddTorrent(m, nil) tor, err = bts.AddTorrent(m, torrDb.InfoBytes, nil)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }
@@ -476,7 +486,7 @@ func torrentPlay(c echo.Context) error {
} }
} }
magnet, err := helpers.GetMagnet(link) magnet, infoBytes, err := helpers.GetMagnet(link)
if err != nil { if err != nil {
fmt.Println("Error get magnet:", link, err) fmt.Println("Error get magnet:", link, err)
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
@@ -484,7 +494,7 @@ func torrentPlay(c echo.Context) error {
tor := bts.GetTorrent(magnet.InfoHash) tor := bts.GetTorrent(magnet.InfoHash)
if tor == nil { if tor == nil {
tor, err = bts.AddTorrent(*magnet, nil) tor, err = bts.AddTorrent(*magnet, infoBytes, nil)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
} }
@@ -502,6 +512,7 @@ func torrentPlay(c echo.Context) error {
if t, err := settings.LoadTorrentDB(magnet.InfoHash.HexString()); t == nil && err == nil { if t, err := settings.LoadTorrentDB(magnet.InfoHash.HexString()); t == nil && err == nil {
torrDb := toTorrentDB(tor) torrDb := toTorrentDB(tor)
if torrDb != nil { if torrDb != nil {
torrDb.InfoBytes = infoBytes
settings.SaveTorrentDB(torrDb) settings.SaveTorrentDB(torrDb)
} }
} }
@@ -565,7 +576,7 @@ func torrentView(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest, "Error parser magnet in db: "+hashHex) return echo.NewHTTPError(http.StatusBadRequest, "Error parser magnet in db: "+hashHex)
} }
tor, err = bts.AddTorrent(m, nil) tor, err = bts.AddTorrent(m, torrDb.InfoBytes, nil)
if err != nil { if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }

View File

@@ -9,33 +9,42 @@ import (
"strings" "strings"
"time" "time"
"server/settings"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
) )
func GetMagnet(link string) (*metainfo.Magnet, error) { func GetMagnet(link string) (*metainfo.Magnet, []byte, error) {
url, err := url.Parse(link) url, err := url.Parse(link)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
var mag *metainfo.Magnet var mag *metainfo.Magnet
var infoBytes []byte
switch strings.ToLower(url.Scheme) { switch strings.ToLower(url.Scheme) {
case "magnet": case "magnet":
mag, err = getMag(url.String()) mag, err = getMag(url.String())
if err == nil {
torDb, err := settings.LoadTorrentDB(mag.InfoHash.HexString())
if err == nil && torDb != nil {
infoBytes = torDb.InfoBytes
}
}
case "http", "https": case "http", "https":
mag, err = getMagFromHttp(url.String()) mag, infoBytes, err = getMagFromHttp(url.String())
case "": case "":
mag, err = getMag("magnet:?xt=urn:btih:" + url.Path) mag, err = getMag("magnet:?xt=urn:btih:" + url.Path)
case "file": case "file":
mag, err = getMagFromFile(url.Path) mag, infoBytes, err = getMagFromFile(url.Path)
default: default:
err = fmt.Errorf("unknown scheme:", url, url.Scheme) err = fmt.Errorf("unknown scheme:", url, url.Scheme)
} }
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return mag, nil return mag, infoBytes, nil
} }
func getMag(link string) (*metainfo.Magnet, error) { func getMag(link string) (*metainfo.Magnet, error) {
@@ -43,10 +52,10 @@ func getMag(link string) (*metainfo.Magnet, error) {
return &mag, err return &mag, err
} }
func getMagFromHttp(url string) (*metainfo.Magnet, error) { func getMagFromHttp(url string) (*metainfo.Magnet, []byte, error) {
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
client := new(http.Client) client := new(http.Client)
@@ -55,38 +64,38 @@ func getMagFromHttp(url string) (*metainfo.Magnet, error) {
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != 200 { if resp.StatusCode != 200 {
return nil, errors.New(resp.Status) return nil, nil, errors.New(resp.Status)
} }
minfo, err := metainfo.Load(resp.Body) minfo, err := metainfo.Load(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
info, err := minfo.UnmarshalInfo() info, err := minfo.UnmarshalInfo()
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
mag := minfo.Magnet(info.Name, minfo.HashInfoBytes()) mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
return &mag, nil return &mag, minfo.InfoBytes, nil
} }
func getMagFromFile(path string) (*metainfo.Magnet, error) { func getMagFromFile(path string) (*metainfo.Magnet, []byte, error) {
if runtime.GOOS == "windows" && strings.HasPrefix(path, "/") { if runtime.GOOS == "windows" && strings.HasPrefix(path, "/") {
path = strings.TrimPrefix(path, "/") path = strings.TrimPrefix(path, "/")
} }
minfo, err := metainfo.LoadFromFile(path) minfo, err := metainfo.LoadFromFile(path)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
info, err := minfo.UnmarshalInfo() info, err := minfo.UnmarshalInfo()
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
mag := minfo.Magnet(info.Name, minfo.HashInfoBytes()) mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
return &mag, nil return &mag, minfo.InfoBytes, nil
} }

View File

@@ -13,9 +13,9 @@ import (
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
) )
func Add(bts *torr.BTServer, magnet metainfo.Magnet, save bool) error { func Add(bts *torr.BTServer, magnet metainfo.Magnet, infobytes []byte, save bool) error {
fmt.Println("Adding torrent", magnet.String()) fmt.Println("Adding torrent", magnet.String())
_, err := bts.AddTorrent(magnet, func(torr *torr.Torrent) { _, err := bts.AddTorrent(magnet, infobytes, func(torr *torr.Torrent) {
if torr, _ := settings.LoadTorrentDB(magnet.InfoHash.HexString()); torr != nil { if torr, _ := settings.LoadTorrentDB(magnet.InfoHash.HexString()); torr != nil {
return return
} }
@@ -24,6 +24,7 @@ func Add(bts *torr.BTServer, magnet metainfo.Magnet, save bool) error {
torDb.Hash = torr.Hash().HexString() torDb.Hash = torr.Hash().HexString()
torDb.Size = torr.Length() torDb.Size = torr.Length()
torDb.Magnet = magnet.String() torDb.Magnet = magnet.String()
torDb.InfoBytes = infobytes
torDb.Timestamp = time.Now().Unix() torDb.Timestamp = time.Now().Unix()
files := torr.Stats().FileStats files := torr.Stats().FileStats
sort.Slice(files, func(i, j int) bool { sort.Slice(files, func(i, j int) bool {

View File

@@ -89,12 +89,12 @@ var settingsPage = `
<br> <br>
<div class="input-group"> <div class="input-group">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text">Peer strategy</div> <div class="input-group-text">Шифрование</div>
</div> </div>
<select id="PeerStrategy" class="form-control"> <select id="Encryption" class="form-control">
<option value="0">Duplicate Request Timeout</option> <option value="0">По умолчанию</option>
<option value="1">Fastest</option> <option value="1">Отключить</option>
<option value="2">Fuzzing</option> <option value="2">Принудительно</option>
</select> </select>
</div> </div>
<br> <br>
@@ -171,7 +171,7 @@ var settingsPage = `
data.DisableUPNP = $('#DisableUPNP').prop('checked'); data.DisableUPNP = $('#DisableUPNP').prop('checked');
data.DisableDHT = $('#DisableDHT').prop('checked'); data.DisableDHT = $('#DisableDHT').prop('checked');
data.DisableUpload = $('#DisableUpload').prop('checked'); data.DisableUpload = $('#DisableUpload').prop('checked');
data.PeerStrategy = Number($('#PeerStrategy').val()); data.Encryption = Number($('#Encryption').val());
data.ConnectionsLimit = Number($('#ConnectionsLimit').val()); data.ConnectionsLimit = Number($('#ConnectionsLimit').val());
data.DhtConnectionLimit = Number($('#DhtConnectionLimit').val()); data.DhtConnectionLimit = Number($('#DhtConnectionLimit').val());
@@ -205,7 +205,7 @@ var settingsPage = `
$('#DisableUPNP').prop('checked', data.DisableUPNP); $('#DisableUPNP').prop('checked', data.DisableUPNP);
$('#DisableDHT').prop('checked', data.DisableDHT); $('#DisableDHT').prop('checked', data.DisableDHT);
$('#DisableUpload').prop('checked', data.DisableUpload); $('#DisableUpload').prop('checked', data.DisableUpload);
$('#PeerStrategy').val(data.PeerStrategy); $('#Encryption').val(data.Encryption);
$('#ConnectionsLimit').val(data.ConnectionsLimit); $('#ConnectionsLimit').val(data.ConnectionsLimit);
$('#DhtConnectionLimit').val(data.DhtConnectionLimit); $('#DhtConnectionLimit').val(data.DhtConnectionLimit);