-
Notifications
You must be signed in to change notification settings - Fork 144
/
main.go
86 lines (78 loc) · 2.27 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Runs a node on a random UDP port that attempts to collect 10 peers for an
// infohash, then keeps running as a passive DHT node.
//
// IMPORTANT: if the UDP port is not reachable from the public internet, you
// may see very few results.
//
// To collect 10 peers, it usually has to contact some 1k nodes. It's much easier
// to find peers for popular infohashes. This process is not instant and should
// take a minute or two, depending on your network connection.
//
//
// There is a builtin web server that can be used to collect debugging stats
// from http://localhost:8711/debug/vars.
package main
import (
"flag"
"fmt"
"net/http"
"os"
"time"
"github.com/nictuku/dht"
)
const (
httpPortTCP = 8711
numTarget = 10
exampleIH = "deca7a89a1dbdc4b213de1c0d5351e92582f31fb" // ubuntu-12.04.4-desktop-amd64.iso
)
func main() {
flag.Parse()
// To see logs, use the -logtostderr flag and change the verbosity with
// -v 0 (less verbose) up to -v 5 (more verbose).
if len(flag.Args()) != 1 {
fmt.Fprintf(os.Stderr, "Usage: %v <infohash>\n\n", os.Args[0])
fmt.Fprintf(os.Stderr, "Example infohash: %v\n", exampleIH)
flag.PrintDefaults()
os.Exit(1)
}
ih, err := dht.DecodeInfoHash(flag.Args()[0])
if err != nil {
fmt.Fprintf(os.Stderr, "DecodeInfoHash error: %v\n", err)
os.Exit(1)
}
// Starts a DHT node with the default options. It picks a random UDP port. To change this, see dht.NewConfig.
d, err := dht.New(nil)
if err != nil {
fmt.Fprintf(os.Stderr, "New DHT error: %v", err)
os.Exit(1)
}
// For debugging.
go http.ListenAndServe(fmt.Sprintf(":%d", httpPortTCP), nil)
if err = d.Start(); err != nil {
fmt.Fprintf(os.Stderr, "DHT start error: %v", err)
os.Exit(1)
}
go drainresults(d)
for {
d.PeersRequest(string(ih), false)
time.Sleep(5 * time.Second)
}
}
// drainresults loops, printing the address of nodes it has found.
func drainresults(n *dht.DHT) {
count := 0
fmt.Println("=========================== DHT")
fmt.Println("Note that there are many bad nodes that reply to anything you ask.")
fmt.Println("Peers found:")
for r := range n.PeersRequestResults {
for _, peers := range r {
for _, x := range peers {
fmt.Printf("%d: %v\n", count, dht.DecodePeerAddress(x))
count++
if count >= numTarget {
os.Exit(0)
}
}
}
}
}