mirror of
https://github.com/yann-shi/dht.git
synced 2026-10-16 20:21:06 +08:00
add license && golint
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Dean Karn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,6 +1,5 @@
|
||||
// Package dht implements the bittorrent dht protocol. For more information
|
||||
// see http://www.bittorrent.org/beps/bep_0005.html.
|
||||
|
||||
package dht
|
||||
|
||||
import (
|
||||
@@ -18,7 +17,9 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
// StandardMode follows the standard protocol
|
||||
StandardMode = iota
|
||||
// CrawlMode for crawling the dht network.
|
||||
CrawlMode
|
||||
)
|
||||
|
||||
@@ -132,7 +133,7 @@ func (dht *DHT) IsStandardMode() bool {
|
||||
return dht.Mode == StandardMode
|
||||
}
|
||||
|
||||
// IsStandardMode returns whether mode is CrawlMode.
|
||||
// IsCrawlMode returns whether mode is CrawlMode.
|
||||
func (dht *DHT) IsCrawlMode() bool {
|
||||
return dht.Mode == CrawlMode
|
||||
}
|
||||
@@ -196,7 +197,7 @@ func (dht *DHT) id(target string) string {
|
||||
}
|
||||
|
||||
// GetPeers returns peers who have announced having infoHash.
|
||||
func (dht *DHT) GetPeers(infoHash string) ([]*peer, error) {
|
||||
func (dht *DHT) GetPeers(infoHash string) ([]*Peer, error) {
|
||||
if !dht.Ready {
|
||||
return nil, errors.New("dht not ready")
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ func (tm *tokenManager) token(addr *net.UDPAddr) string {
|
||||
}
|
||||
|
||||
// check returns whether the token is valid.
|
||||
func (tm *tokenManager) check(addr *net.UDPAddr, token_ string) bool {
|
||||
func (tm *tokenManager) check(addr *net.UDPAddr, tokenString string) bool {
|
||||
v, ok := tm.Get(addr.IP.String())
|
||||
tk, _ := v.(token)
|
||||
|
||||
return ok && token_ == tk.data
|
||||
return ok && tokenString == tk.data
|
||||
}
|
||||
|
||||
// makeQuery returns a query-formed data.
|
||||
@@ -148,8 +148,8 @@ func newTransactionManager(maxCursor uint64, dht *DHT) *transactionManager {
|
||||
}
|
||||
}
|
||||
|
||||
// genTransId generates a transaction id and returns it.
|
||||
func (tm *transactionManager) genTransId() string {
|
||||
// genTransID generates a transaction id and returns it.
|
||||
func (tm *transactionManager) genTransID() string {
|
||||
tm.Lock()
|
||||
defer tm.Unlock()
|
||||
|
||||
@@ -187,8 +187,8 @@ func (tm *transactionManager) insert(trans *transaction) {
|
||||
}
|
||||
|
||||
// delete removes a transaction from transactionManager.
|
||||
func (tm *transactionManager) delete(transId string) {
|
||||
v, ok := tm.transactions.Get(transId)
|
||||
func (tm *transactionManager) delete(transID string) {
|
||||
v, ok := tm.transactions.Get(transID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -224,9 +224,9 @@ func (tm *transactionManager) transaction(
|
||||
return v.(*transaction)
|
||||
}
|
||||
|
||||
// getByTransId returns a transaction by transId.
|
||||
func (tm *transactionManager) getByTransId(transId string) *transaction {
|
||||
return tm.transaction(transId, 0)
|
||||
// getByTransID returns a transaction by transID.
|
||||
func (tm *transactionManager) getByTransID(transID string) *transaction {
|
||||
return tm.transaction(transID, 0)
|
||||
}
|
||||
|
||||
// getByIndex returns a transaction by indexed key.
|
||||
@@ -237,9 +237,9 @@ func (tm *transactionManager) getByIndex(index string) *transaction {
|
||||
// transaction gets the proper transaction with whose id is transId and
|
||||
// address is addr.
|
||||
func (tm *transactionManager) filterOne(
|
||||
transId string, addr *net.UDPAddr) *transaction {
|
||||
transID string, addr *net.UDPAddr) *transaction {
|
||||
|
||||
trans := tm.getByTransId(transId)
|
||||
trans := tm.getByTransID(transID)
|
||||
if trans == nil || trans.node.addr.String() != addr.String() {
|
||||
return nil
|
||||
}
|
||||
@@ -251,8 +251,8 @@ func (tm *transactionManager) filterOne(
|
||||
// When timeout, it will retry `try - 1` times, which means it will query
|
||||
// `try` times totally.
|
||||
func (tm *transactionManager) query(q *query, try int) {
|
||||
transId := q.data["t"].(string)
|
||||
trans := tm.newTransaction(transId, q)
|
||||
transID := q.data["t"].(string)
|
||||
trans := tm.newTransaction(transID, q)
|
||||
|
||||
tm.insert(trans)
|
||||
defer tm.delete(trans.id)
|
||||
@@ -300,7 +300,7 @@ func (tm *transactionManager) sendQuery(
|
||||
return
|
||||
}
|
||||
|
||||
data := makeQuery(tm.genTransId(), queryType, a)
|
||||
data := makeQuery(tm.genTransID(), queryType, a)
|
||||
tm.queryChan <- &query{
|
||||
node: no,
|
||||
data: data,
|
||||
@@ -465,14 +465,14 @@ func handleRequest(dht *DHT, addr *net.UDPAddr,
|
||||
var nodes string
|
||||
|
||||
if dht.IsStandardMode() {
|
||||
targetId := newBitmapFromString(target)
|
||||
targetID := newBitmapFromString(target)
|
||||
|
||||
no, _ := dht.routingTable.GetNodeKBucktById(targetId)
|
||||
no, _ := dht.routingTable.GetNodeKBucktByID(targetID)
|
||||
if no != nil {
|
||||
nodes = no.CompactNodeInfo()
|
||||
} else {
|
||||
nodes = strings.Join(
|
||||
dht.routingTable.GetNeighborCompactInfos(targetId, dht.K),
|
||||
dht.routingTable.GetNeighborCompactInfos(targetID, dht.K),
|
||||
"",
|
||||
)
|
||||
}
|
||||
@@ -546,8 +546,8 @@ func handleRequest(dht *DHT, addr *net.UDPAddr,
|
||||
return
|
||||
}
|
||||
|
||||
if implied_port, ok := a["implied_port"]; ok &&
|
||||
implied_port.(int) != 0 {
|
||||
if impliedPort, ok := a["implied_port"]; ok &&
|
||||
impliedPort.(int) != 0 {
|
||||
|
||||
port = addr.Port
|
||||
}
|
||||
@@ -603,13 +603,13 @@ func findOn(dht *DHT, r map[string]interface{}, target *bitmap,
|
||||
return nil
|
||||
}
|
||||
|
||||
targetId := target.RawString()
|
||||
targetID := target.RawString()
|
||||
for _, no := range dht.routingTable.GetNeighbors(target, dht.K) {
|
||||
switch queryType {
|
||||
case findNodeType:
|
||||
dht.transactionManager.findNode(no, targetId)
|
||||
dht.transactionManager.findNode(no, targetID)
|
||||
case getPeersType:
|
||||
dht.transactionManager.getPeers(no, targetId)
|
||||
dht.transactionManager.getPeers(no, targetID)
|
||||
default:
|
||||
panic("invalid find type")
|
||||
}
|
||||
|
||||
+15
-8
@@ -13,15 +13,22 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// REQUEST represents request message type
|
||||
REQUEST = iota
|
||||
// DATA represents data message type
|
||||
DATA
|
||||
// REJECT represents reject message type
|
||||
REJECT
|
||||
)
|
||||
|
||||
const (
|
||||
BLOCK = 16384 // 2 ^ 14
|
||||
MAX_METADATA_SIZE = BLOCK * 1000
|
||||
// BLOCK is 2 ^ 14
|
||||
BLOCK = 16384
|
||||
// MaxMetadataSize represents the max medata it can accept
|
||||
MaxMetadataSize = BLOCK * 1000
|
||||
// EXTENDED represents it is a extended message
|
||||
EXTENDED = 20
|
||||
// HANDSHAKE represents handshake bit
|
||||
HANDSHAKE = 0
|
||||
)
|
||||
|
||||
@@ -65,7 +72,7 @@ func readMessage(conn *net.TCPConn, data *bytes.Buffer) (
|
||||
|
||||
// sendMessage sends data to the connection.
|
||||
func sendMessage(conn *net.TCPConn, data []byte) error {
|
||||
var length int32 = int32(len(data))
|
||||
length := int32(len(data))
|
||||
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
binary.Write(buffer, binary.BigEndian, length)
|
||||
@@ -75,11 +82,11 @@ func sendMessage(conn *net.TCPConn, data []byte) error {
|
||||
}
|
||||
|
||||
// sendHandshake sends handshake message to conn.
|
||||
func sendHandshake(conn *net.TCPConn, infoHash, peerId []byte) error {
|
||||
func sendHandshake(conn *net.TCPConn, infoHash, peerID []byte) error {
|
||||
data := make([]byte, 68)
|
||||
copy(data[:28], handshakePrefix)
|
||||
copy(data[28:48], infoHash)
|
||||
copy(data[48:], peerId)
|
||||
copy(data[48:], peerID)
|
||||
|
||||
_, err := conn.Write(data)
|
||||
return err
|
||||
@@ -133,7 +140,7 @@ func getUTMetaSize(data []byte) (
|
||||
utMetadata = m["ut_metadata"].(int)
|
||||
metadataSize = dict["metadata_size"].(int)
|
||||
|
||||
if metadataSize > MAX_METADATA_SIZE {
|
||||
if metadataSize > MaxMetadataSize {
|
||||
err = errors.New("metadata_size too long")
|
||||
}
|
||||
return
|
||||
@@ -264,7 +271,7 @@ func (wire *Wire) fetchMetadata(r Request) {
|
||||
|
||||
switch msgType {
|
||||
case EXTENDED:
|
||||
extendedId, err := data.ReadByte()
|
||||
extendedID, err := data.ReadByte()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -274,7 +281,7 @@ func (wire *Wire) fetchMetadata(r Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if extendedId == 0 {
|
||||
if extendedID == 0 {
|
||||
if pieces != nil {
|
||||
return
|
||||
}
|
||||
|
||||
+92
-92
@@ -62,24 +62,24 @@ func (node *node) CompactNodeInfo() string {
|
||||
}, "")
|
||||
}
|
||||
|
||||
// peer represents a peer contact.
|
||||
type peer struct {
|
||||
ip net.IP
|
||||
port int
|
||||
// Peer represents a peer contact.
|
||||
type Peer struct {
|
||||
IP net.IP
|
||||
Port int
|
||||
token string
|
||||
}
|
||||
|
||||
// newPeer returns a new peer pointer.
|
||||
func newPeer(ip net.IP, port int, token string) *peer {
|
||||
return &peer{
|
||||
ip: ip,
|
||||
port: port,
|
||||
func newPeer(ip net.IP, port int, token string) *Peer {
|
||||
return &Peer{
|
||||
IP: ip,
|
||||
Port: port,
|
||||
token: token,
|
||||
}
|
||||
}
|
||||
|
||||
// newPeerFromCompactIPPortInfo create a peer pointer by compact ip/port info.
|
||||
func newPeerFromCompactIPPortInfo(compactInfo, token string) (*peer, error) {
|
||||
func newPeerFromCompactIPPortInfo(compactInfo, token string) (*Peer, error) {
|
||||
ip, port, err := decodeCompactIPPortInfo(compactInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -88,10 +88,10 @@ func newPeerFromCompactIPPortInfo(compactInfo, token string) (*peer, error) {
|
||||
return newPeer(ip, port, token), nil
|
||||
}
|
||||
|
||||
// CompactNodeInfo returns "Compact node info".
|
||||
// CompactIPPortInfo returns "Compact node info".
|
||||
// See http://www.bittorrent.org/beps/bep_0005.html.
|
||||
func (p *peer) CompactIPPortInfo() string {
|
||||
info, _ := encodeCompactIPPortInfo(p.ip, p.port)
|
||||
func (p *Peer) CompactIPPortInfo() string {
|
||||
info, _ := encodeCompactIPPortInfo(p.IP, p.Port)
|
||||
return info
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func newPeersManager(dht *DHT) *peersManager {
|
||||
}
|
||||
|
||||
// Insert adds a peer into peersManager.
|
||||
func (pm *peersManager) Insert(infoHash string, peer *peer) {
|
||||
func (pm *peersManager) Insert(infoHash string, peer *Peer) {
|
||||
pm.Lock()
|
||||
if _, ok := pm.table.Get(infoHash); !ok {
|
||||
pm.table.Set(infoHash, newKeyedDeque())
|
||||
@@ -123,8 +123,8 @@ func (pm *peersManager) Insert(infoHash string, peer *peer) {
|
||||
}
|
||||
|
||||
// GetPeers returns size-length peers who announces having infoHash.
|
||||
func (pm *peersManager) GetPeers(infoHash string, size int) []*peer {
|
||||
peers := make([]*peer, 0, size)
|
||||
func (pm *peersManager) GetPeers(infoHash string, size int) []*Peer {
|
||||
peers := make([]*Peer, 0, size)
|
||||
|
||||
v, ok := pm.table.Get(infoHash)
|
||||
if !ok {
|
||||
@@ -132,7 +132,7 @@ func (pm *peersManager) GetPeers(infoHash string, size int) []*peer {
|
||||
}
|
||||
|
||||
for e := range v.(*keyedDeque).Iter() {
|
||||
peers = append(peers, e.Value.(*peer))
|
||||
peers = append(peers, e.Value.(*Peer))
|
||||
}
|
||||
|
||||
if len(peers) > size {
|
||||
@@ -141,105 +141,105 @@ func (pm *peersManager) GetPeers(infoHash string, size int) []*peer {
|
||||
return peers
|
||||
}
|
||||
|
||||
// kBucket represents a k-size bucket.
|
||||
type kBucket struct {
|
||||
// kbucket represents a k-size bucket.
|
||||
type kbucket struct {
|
||||
sync.RWMutex
|
||||
nodes, candidates *keyedDeque
|
||||
lastChanged time.Time
|
||||
prefix *bitmap
|
||||
}
|
||||
|
||||
// newKBucket returns a new kBucket pointer.
|
||||
func newKBucket(prefix *bitmap) *kBucket {
|
||||
kbucket := &kBucket{
|
||||
// newKBucket returns a new kbucket pointer.
|
||||
func newKBucket(prefix *bitmap) *kbucket {
|
||||
bucket := &kbucket{
|
||||
nodes: newKeyedDeque(),
|
||||
candidates: newKeyedDeque(),
|
||||
lastChanged: time.Now(),
|
||||
prefix: prefix,
|
||||
}
|
||||
return kbucket
|
||||
return bucket
|
||||
}
|
||||
|
||||
// LastChanged return the last time when it changes.
|
||||
func (kbucket *kBucket) LastChanged() time.Time {
|
||||
kbucket.RLock()
|
||||
defer kbucket.RUnlock()
|
||||
func (bucket *kbucket) LastChanged() time.Time {
|
||||
bucket.RLock()
|
||||
defer bucket.RUnlock()
|
||||
|
||||
return kbucket.lastChanged
|
||||
return bucket.lastChanged
|
||||
}
|
||||
|
||||
// RandomChildID returns a random id that has the same prefix with kbucket.
|
||||
func (kbucket *kBucket) RandomChildID() string {
|
||||
prefixLen := kbucket.prefix.Size / 8
|
||||
// RandomChildID returns a random id that has the same prefix with bucket.
|
||||
func (bucket *kbucket) RandomChildID() string {
|
||||
prefixLen := bucket.prefix.Size / 8
|
||||
|
||||
return strings.Join([]string{
|
||||
kbucket.prefix.RawString()[:prefixLen],
|
||||
bucket.prefix.RawString()[:prefixLen],
|
||||
randomString(20 - prefixLen),
|
||||
}, "")
|
||||
}
|
||||
|
||||
// UpdateTimestamp update kbucket's last changed time..
|
||||
func (kbucket *kBucket) UpdateTimestamp() {
|
||||
kbucket.Lock()
|
||||
defer kbucket.Unlock()
|
||||
// UpdateTimestamp update bucket's last changed time..
|
||||
func (bucket *kbucket) UpdateTimestamp() {
|
||||
bucket.Lock()
|
||||
defer bucket.Unlock()
|
||||
|
||||
kbucket.lastChanged = time.Now()
|
||||
bucket.lastChanged = time.Now()
|
||||
}
|
||||
|
||||
// Insert inserts node to the kbucket. It returns whether the node is new in
|
||||
// the kbucket.
|
||||
func (kbucket *kBucket) Insert(no *node, rt *routingTable) bool {
|
||||
isNew := !kbucket.nodes.HasKey(no.id.RawString())
|
||||
// Insert inserts node to the bucket. It returns whether the node is new in
|
||||
// the bucket.
|
||||
func (bucket *kbucket) Insert(no *node, rt *routingTable) bool {
|
||||
isNew := !bucket.nodes.HasKey(no.id.RawString())
|
||||
|
||||
kbucket.nodes.Push(no.id.RawString(), no)
|
||||
bucket.nodes.Push(no.id.RawString(), no)
|
||||
rt.cachedNodes.Set(no.addr.String(), no)
|
||||
rt.Touch(kbucket)
|
||||
rt.Touch(bucket)
|
||||
|
||||
return isNew
|
||||
}
|
||||
|
||||
// Replace removes node, then put kbucket.candidates.Back() to the right
|
||||
// place of kbucket.nodes.
|
||||
func (kbucket *kBucket) Replace(no *node, rt *routingTable) {
|
||||
kbucket.nodes.Delete(no.id.RawString())
|
||||
// Replace removes node, then put bucket.candidates.Back() to the right
|
||||
// place of bucket.nodes.
|
||||
func (bucket *kbucket) Replace(no *node, rt *routingTable) {
|
||||
bucket.nodes.Delete(no.id.RawString())
|
||||
|
||||
rt.cachedNodes.Delete(no.addr.String())
|
||||
rt.Touch(kbucket)
|
||||
rt.Touch(bucket)
|
||||
|
||||
if kbucket.candidates.Len() == 0 {
|
||||
if bucket.candidates.Len() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
no = kbucket.candidates.Remove(kbucket.candidates.Back()).(*node)
|
||||
no = bucket.candidates.Remove(bucket.candidates.Back()).(*node)
|
||||
|
||||
inserted := false
|
||||
for e := range kbucket.nodes.Iter() {
|
||||
for e := range bucket.nodes.Iter() {
|
||||
if e.Value.(*node).lastActiveTime.After(
|
||||
no.lastActiveTime) && !inserted {
|
||||
|
||||
kbucket.nodes.InsertBefore(no, e)
|
||||
bucket.nodes.InsertBefore(no, e)
|
||||
inserted = true
|
||||
}
|
||||
}
|
||||
|
||||
if !inserted {
|
||||
kbucket.nodes.PushBack(no)
|
||||
bucket.nodes.PushBack(no)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear resets the kbucket.
|
||||
func (kbucket *kBucket) Clear() {
|
||||
kbucket.Lock()
|
||||
defer kbucket.Unlock()
|
||||
// Clear resets the bucket.
|
||||
func (bucket *kbucket) Clear() {
|
||||
bucket.Lock()
|
||||
defer bucket.Unlock()
|
||||
|
||||
kbucket.nodes.Clear()
|
||||
kbucket.candidates.Clear()
|
||||
kbucket.lastChanged = time.Now()
|
||||
bucket.nodes.Clear()
|
||||
bucket.candidates.Clear()
|
||||
bucket.lastChanged = time.Now()
|
||||
}
|
||||
|
||||
// Fresh pings the expired nodes in the kbucket.
|
||||
func (kbucket *kBucket) Fresh(dht *DHT) {
|
||||
for e := range kbucket.nodes.Iter() {
|
||||
// Fresh pings the expired nodes in the bucket.
|
||||
func (bucket *kbucket) Fresh(dht *DHT) {
|
||||
for e := range bucket.nodes.Iter() {
|
||||
no := e.Value.(*node)
|
||||
if time.Since(no.lastActiveTime) > dht.NodeExpriedAfter {
|
||||
dht.transactionManager.ping(no)
|
||||
@@ -251,14 +251,14 @@ func (kbucket *kBucket) Fresh(dht *DHT) {
|
||||
type routingTableNode struct {
|
||||
sync.RWMutex
|
||||
children []*routingTableNode
|
||||
kbucket *kBucket
|
||||
bucket *kbucket
|
||||
}
|
||||
|
||||
// newRoutingTableNode returns a new routingTableNode pointer.
|
||||
func newRoutingTableNode(prefix *bitmap) *routingTableNode {
|
||||
return &routingTableNode{
|
||||
children: make([]*routingTableNode, 2),
|
||||
kbucket: newKBucket(prefix),
|
||||
bucket: newKBucket(prefix),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,20 +283,20 @@ func (tableNode *routingTableNode) SetChild(index int, c *routingTableNode) {
|
||||
tableNode.children[index] = c
|
||||
}
|
||||
|
||||
// KBucket returns the kbucket routingTableNode holds.
|
||||
func (tableNode *routingTableNode) KBucket() *kBucket {
|
||||
// KBucket returns the bucket routingTableNode holds.
|
||||
func (tableNode *routingTableNode) KBucket() *kbucket {
|
||||
tableNode.RLock()
|
||||
defer tableNode.RUnlock()
|
||||
|
||||
return tableNode.kbucket
|
||||
return tableNode.bucket
|
||||
}
|
||||
|
||||
// SetKBucket sets the kbucket.
|
||||
func (tableNode *routingTableNode) SetKBucket(kbucket *kBucket) {
|
||||
// SetKBucket sets the bucket.
|
||||
func (tableNode *routingTableNode) SetKBucket(bucket *kbucket) {
|
||||
tableNode.Lock()
|
||||
defer tableNode.Unlock()
|
||||
|
||||
tableNode.kbucket = kbucket
|
||||
tableNode.bucket = bucket
|
||||
}
|
||||
|
||||
// Split splits current routingTableNode and sets it's two children.
|
||||
@@ -313,7 +313,7 @@ func (tableNode *routingTableNode) Split(rt *routingTable) {
|
||||
}
|
||||
|
||||
tableNode.Lock()
|
||||
tableNode.children[1].kbucket.prefix.Set(prefixLen)
|
||||
tableNode.children[1].bucket.prefix.Set(prefixLen)
|
||||
tableNode.Unlock()
|
||||
|
||||
for e := range tableNode.KBucket().nodes.Iter() {
|
||||
@@ -340,7 +340,7 @@ func (tableNode *routingTableNode) Clear() {
|
||||
defer tableNode.Unlock()
|
||||
|
||||
tableNode.children = make([]*routingTableNode, 2)
|
||||
tableNode.kbucket.Clear()
|
||||
tableNode.bucket.Clear()
|
||||
}
|
||||
|
||||
// routingTable implements the routing table in DHT protocol.
|
||||
@@ -366,15 +366,15 @@ func newRoutingTable(k int, dht *DHT) *routingTable {
|
||||
dht: dht,
|
||||
}
|
||||
|
||||
rt.cachedKBuckets.Push(root.kbucket.prefix.String(), root.kbucket)
|
||||
rt.cachedKBuckets.Push(root.bucket.prefix.String(), root.bucket)
|
||||
return rt
|
||||
}
|
||||
|
||||
// Touch updates the routing table. It will put the kbucket to the end of
|
||||
// kbucket list.
|
||||
func (rt *routingTable) Touch(kbucket *kBucket) {
|
||||
kbucket.UpdateTimestamp()
|
||||
rt.cachedKBuckets.Push(kbucket.prefix.String(), kbucket)
|
||||
// Touch updates the routing table. It will put the bucket to the end of
|
||||
// bucket list.
|
||||
func (rt *routingTable) Touch(bucket *kbucket) {
|
||||
bucket.UpdateTimestamp()
|
||||
rt.cachedKBuckets.Push(bucket.prefix.String(), bucket)
|
||||
}
|
||||
|
||||
// Insert adds a node to routing table. It returns whether the node is new
|
||||
@@ -402,12 +402,12 @@ func (rt *routingTable) Insert(nd *node) bool {
|
||||
|
||||
return root.KBucket().Insert(nd, rt)
|
||||
} else if root.KBucket().prefix.Compare(nd.id, prefixLen-1) == 0 {
|
||||
// If node has the same prefix with kbucket, split it.
|
||||
// If node has the same prefix with bucket, split it.
|
||||
|
||||
root.Split(rt)
|
||||
root = root.Child(nd.id.Bit(prefixLen - 1))
|
||||
} else {
|
||||
// Finally, store node as a candidate and fresh the kbucket.
|
||||
// Finally, store node as a candidate and fresh the bucket.
|
||||
root.KBucket().candidates.PushBack(nd)
|
||||
if root.KBucket().candidates.Len() > rt.k {
|
||||
root.KBucket().candidates.Remove(
|
||||
@@ -451,10 +451,10 @@ func (rt *routingTable) GetNeighborCompactInfos(id *bitmap, size int) []string {
|
||||
return infos
|
||||
}
|
||||
|
||||
// GetNodeKBucktById returns node whose id is `id` and the kbucket it
|
||||
// GetNodeKBucktById returns node whose id is `id` and the bucket it
|
||||
// belongs to.
|
||||
func (rt *routingTable) GetNodeKBucktById(id *bitmap) (
|
||||
nd *node, kbucket *kBucket) {
|
||||
func (rt *routingTable) GetNodeKBucktByID(id *bitmap) (
|
||||
nd *node, bucket *kbucket) {
|
||||
|
||||
rt.RLock()
|
||||
defer rt.RUnlock()
|
||||
@@ -469,7 +469,7 @@ func (rt *routingTable) GetNodeKBucktById(id *bitmap) (
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
nd, kbucket = v.Value.(*node), root.KBucket()
|
||||
nd, bucket = v.Value.(*node), root.KBucket()
|
||||
return
|
||||
}
|
||||
root = next
|
||||
@@ -491,9 +491,9 @@ func (rt *routingTable) GetNodeByAddress(address string) (no *node, ok bool) {
|
||||
|
||||
// Remove deletes the node whose id is `id`.
|
||||
func (rt *routingTable) Remove(id *bitmap) {
|
||||
if nd, kbucket := rt.GetNodeKBucktById(id); nd != nil {
|
||||
if nd, bucket := rt.GetNodeKBucktByID(id); nd != nil {
|
||||
rt.Lock()
|
||||
kbucket.Replace(nd, rt)
|
||||
bucket.Replace(nd, rt)
|
||||
rt.Unlock()
|
||||
}
|
||||
}
|
||||
@@ -514,7 +514,7 @@ func (rt *routingTable) Clear() {
|
||||
rt.root.Clear()
|
||||
rt.cachedNodes.Clear()
|
||||
rt.cachedKBuckets.Clear()
|
||||
rt.cachedKBuckets.Push(rt.root.kbucket.prefix.String(), rt.root.kbucket)
|
||||
rt.cachedKBuckets.Push(rt.root.bucket.prefix.String(), rt.root.bucket)
|
||||
}
|
||||
|
||||
// Fresh sends findNode to all nodes in the expired nodes.
|
||||
@@ -522,15 +522,15 @@ func (rt *routingTable) Fresh() {
|
||||
now := time.Now()
|
||||
|
||||
for e := range rt.cachedKBuckets.Iter() {
|
||||
kbucket := e.Value.(*kBucket)
|
||||
if now.Sub(kbucket.LastChanged()) < rt.dht.KBucketExpiredAfter ||
|
||||
kbucket.nodes.Len() == 0 {
|
||||
bucket := e.Value.(*kbucket)
|
||||
if now.Sub(bucket.LastChanged()) < rt.dht.KBucketExpiredAfter ||
|
||||
bucket.nodes.Len() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for e := range kbucket.nodes.Iter() {
|
||||
for e := range bucket.nodes.Iter() {
|
||||
no := e.Value.(*node)
|
||||
rt.dht.transactionManager.findNode(no, kbucket.RandomChildID())
|
||||
rt.dht.transactionManager.findNode(no, bucket.RandomChildID())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,7 +547,7 @@ func (rt *routingTable) Len() int {
|
||||
return rt.cachedNodes.Len()
|
||||
}
|
||||
|
||||
// Implemention of heap with heap.Interface.
|
||||
// Implementation of heap with heap.Interface.
|
||||
type heapItem struct {
|
||||
distance *bitmap
|
||||
value interface{}
|
||||
|
||||
@@ -7,15 +7,15 @@ import (
|
||||
"github.com/shiyanhui/dht"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
type file struct {
|
||||
Path []interface{} `json:"path"`
|
||||
Length int `json:"length"`
|
||||
}
|
||||
|
||||
type BitTorrent struct {
|
||||
type bitTorrent struct {
|
||||
InfoHash string `json:"infohash"`
|
||||
Name string `json:"name"`
|
||||
Files []File `json:"files,omitempty"`
|
||||
Files []file `json:"files,omitempty"`
|
||||
Length int `json:"length,omitempty"`
|
||||
}
|
||||
|
||||
@@ -33,20 +33,20 @@ func main() {
|
||||
continue
|
||||
}
|
||||
|
||||
bt := BitTorrent{
|
||||
bt := bitTorrent{
|
||||
InfoHash: hex.EncodeToString(resp.InfoHash),
|
||||
Name: info["name"].(string),
|
||||
}
|
||||
|
||||
if v, ok := info["files"]; ok {
|
||||
files := v.([]interface{})
|
||||
bt.Files = make([]File, len(files))
|
||||
bt.Files = make([]file, len(files))
|
||||
|
||||
for i, item := range files {
|
||||
file := item.(map[string]interface{})
|
||||
bt.Files[i] = File{
|
||||
Path: file["path"].([]interface{}),
|
||||
Length: file["length"].(int),
|
||||
f := item.(map[string]interface{})
|
||||
bt.Files[i] = file{
|
||||
Path: f["path"].([]interface{}),
|
||||
Length: f["length"].(int),
|
||||
}
|
||||
}
|
||||
} else if _, ok := info["length"]; ok {
|
||||
|
||||
Reference in New Issue
Block a user