// Sets up the DHT node for peer bootstrapping func (self *DHT) Init() error { //sum := sha1.Sum([]byte(self.Config.Info)) // Create a hex encoded sha1 sum of a string to be used for DH //infoHash, err := dht.DecodeInfoHash(hex.EncodeToString(sum[:])) cfg := dht.NewConfig() cfg.Port = self.Config.Port cfg.NumTargetPeers = self.Config.DesiredPeers d, err := dht.New(cfg) if err != nil { return err } //self.InfoHash = infoHash self.DHT = d //add the bootstrap nodes for _, addr := range self.Config.BootstrapNodes { self.DHT.AddNode(addr) } if self.Config.Disabled { // We have to initialize the DHT anyway because daemon loop needs // to read from its initialized chans. As long as Start() is prevented, // the DHT will not run. logger.Info("DHT is disabled") } else { logger.Info("Init DHT on port %d", self.Config.Port) } return nil }
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) go d.Run() go drainresults(d) for { d.PeersRequest(string(ih), false) time.Sleep(5 * time.Second) } }
func DiscoverPeers(cm *network.ConnectionManager, address string) { // Hex encoded string: "The Distributed Bay!" ih, err := dht.DecodeInfoHash("5468652044697374726962757465642042617921") if err != nil { log.Fatalf("DHT DecodeInfoHash error: %v\n", err) } _, portStr, err := net.SplitHostPort(address) if err != nil { log.Fatal("Bind address error!", err) } port, err := strconv.Atoi(portStr) if err != nil { log.Fatal(err) } config := dht.NewConfig() config.Port = port config.NumTargetPeers = 10 node, err := dht.New(config) if err != nil { log.Fatal("Error creating DHT node!") } go node.Run() go checkPeers(node, cm) log.Println("Requesting peers from the DHT!") for { node.PeersRequest(string(ih), true) time.Sleep(15 * time.Second) } }
func NewControlSession(shareid id.Id, listenPort int, session *sharesession.Session, trackers []string) (*ControlSession, error) { sid := "-tt" + strconv.Itoa(os.Getpid()) + "_" + strconv.FormatInt(rand.Int63(), 10) // TODO: UPnP UDP port mapping. cfg := dht.NewConfig() cfg.Port = listenPort cfg.NumTargetPeers = TARGET_NUM_PEERS dhtNode, err := dht.New(cfg) if err != nil { log.Fatal("DHT node creation error", err) } current := session.GetCurrentIHMessage() var currentIhMessage IHMessage err = bencode.NewDecoder(strings.NewReader(current)).Decode(¤tIhMessage) if err != nil { log.Printf("Couldn't decode current message, starting from scratch: %s\n", err) } rev := "0-" if currentIhMessage.Info.Rev != "" { parts := strings.Split(currentIhMessage.Info.Rev, "-") if len(parts) == 2 { if _, err := strconv.Atoi(parts[0]); err == nil { rev = currentIhMessage.Info.Rev } } } cs := &ControlSession{ Port: listenPort, PeerID: sid[:20], ID: shareid, Torrents: make(chan Announce), NewPeers: make(chan string), dht: dhtNode, peerMessageChan: make(chan peerMessage), quit: make(chan struct{}), ourExtensions: map[int]string{ 1: "ut_pex", 2: "bs_metadata", }, peers: newPeers(), currentIH: currentIhMessage.Info.InfoHash, rev: rev, trackers: trackers, session: session, } go cs.dht.Run() cs.dht.PeersRequest(string(cs.ID.Infohash), true) go cs.Run() return cs, nil }
func startDHT(listenPort int) *dht.DHT { // TODO: UPnP UDP port mapping. cfg := dht.NewConfig() cfg.Port = listenPort cfg.NumTargetPeers = TARGET_NUM_PEERS dhtnode, err := dht.New(cfg) if err != nil { log.Println("DHT node creation error:", err) return nil } go dhtnode.Run() return dhtnode }
func NewNode(conf *Config) (node *Node, err error) { // setup the DHT dhtConf := dht.DefaultConfig dhtConf.Port = conf.dhtPort dhtClient, err := dht.New(dhtConf) if err != nil { return } dht := newDHT(dhtClient) go dht.Run() node.dht = dht return node, nil }
func NewTorrentSession(fileDir string, torrent string, listenPort uint16, seedRatio float64) (ts *TorrentSession, err error) { t := &TorrentSession{ fileDir: fileDir, seedRatio: seedRatio, peers: make(map[string]*peerState), peerMessageChan: make(chan peerMessage), activePieces: make(map[int]*ActivePiece), quit: make(chan bool), torrentFile: torrent, chokePolicy: &ClassicChokePolicy{}, chokePolicyHeartbeat: time.Tick(10 * time.Second), } fromMagnet := strings.HasPrefix(torrent, "magnet:") t.M, err = GetMetaInfo(torrent) if err != nil { return } dhtAllowed := useDHT && t.M.Info.Private == 0 if dhtAllowed { // TODO: UPnP UDP port mapping. cfg := dht.NewConfig() cfg.Port = int(listenPort) cfg.NumTargetPeers = TARGET_NUM_PEERS if t.dht, err = dht.New(cfg); err != nil { log.Println("DHT node creation error", err) return } go t.dht.Run() } t.si = &SessionInfo{ PeerId: peerId(), Port: listenPort, UseDHT: dhtAllowed, FromMagnet: fromMagnet, HaveTorrent: false, ME: &MetaDataExchange{}, OurExtensions: map[int]string{1: "ut_metadata"}, } t.setHeader() if !t.si.FromMagnet { t.load() } return t, err }
func NewDhtNode(port, numTargetPeers int, c *PeerCache) (*DhtNode, error) { conf := dht.NewConfig() conf.Port = port conf.NumTargetPeers = numTargetPeers node, err := dht.New(conf) if err != nil { return nil, err } d := &DhtNode{node: node} go d.node.Run() go d.drainResults(c) return d, nil }
// StartNewDownloadManager starts a new goroutine and returns 2 channels: // The first is used to pass torrent infohashes to the downloader; // The second is used by the downloader to signal when all the requested torrents // have been downloaded or have timed out. func StartNewDownloadManager() (chan<- string, <-chan bool) { // Starts a DHT node with the default options, picks a random UDP port. d, err := dht.New(nil) if err != nil { log.Errorf("WINSTON: New DHT error: %v\n", err) os.Exit(1) } go d.Run() time.Sleep(7 * time.Second) //TODO: this seems to be necessary; remove after investigating the DHT lib filesToDownload := make(chan string) finished := make(chan bool) go downloadManager(d, filesToDownload, finished) return filesToDownload, finished }
func NewTorrentSession(torrent string, listenPort int) (ts *TorrentSession, err error) { t := &TorrentSession{ peers: make(map[string]*peerState), peerMessageChan: make(chan peerMessage), activePieces: make(map[int]*ActivePiece), quit: make(chan bool), } if useDHT { // TODO: UPnP UDP port mapping. cfg := dht.NewConfig() cfg.Port = listenPort cfg.NumTargetPeers = TARGET_NUM_PEERS if t.dht, err = dht.New(cfg); err != nil { log.Println("DHT node creation error", err) return } go t.dht.Run() } fromMagnet := strings.HasPrefix(torrent, "magnet:") t.m, err = getMetaInfo(torrent) if err != nil { return } t.si = &SessionInfo{ PeerId: peerId(), Port: listenPort, UseDHT: useDHT, FromMagnet: fromMagnet, HaveTorrent: false, ME: &MetaDataExchange{}, OurExtensions: map[int]string{1: "ut_metadat"}, } if !t.si.FromMagnet { t.load() } return t, err }
func main() { // randomly generated hash: AE6D4306F4AE6D4306F4AE6D4306F4AE6D4306F4 // ubuntu-12.04.4-desktop-amd64.iso: deca7a89a1dbdc4b213de1c0d5351e92582f31fb ih, err := dht.DecodeInfoHash("AE6D4306F4AE6D4306F4AE6D4306F4AE6D4306F4") 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) } go d.Run() go drain(d) for { d.PeersRequest(string(ih), false) time.Sleep(5 * time.Second) } }
func (d *DiscoveryDHT) Run() error { var err error d.ih, err = dht.DecodeInfoHash(d.localNode.Config().NetworkID) if err != nil { return fmt.Errorf("decode infohash err: %s", err) } config := dht.NewConfig() config.Port = d.localNode.State().ListenPort d.node, err = dht.New(config) if err != nil { return fmt.Errorf("new dht init err: %s", err) } if err = d.node.Start(); err != nil { return fmt.Errorf("dht start err: %s", err) } d.waitGroup.Add(2) go d.process() go d.awaitPeers() d.waitGroup.Wait() return nil }
func main() { ipv6Address := flag.String("v6", "", "Address to bind to IPv6 interface") 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) } conf4 := dht.NewConfig() conf4.UDPProto = "udp4" conf4.Port = 8445 // standard IPv4 bootstrap nodes = dht.transmissionbt.com // router.utorrent.com router.bittorrent.com conf6 := dht.NewConfig() conf6.UDPProto = "udp6" conf6.Port = 8445 conf6.Address = *ipv6Address // Starts a DHT node with the default options. It picks a random UDP port. To change this, see dht.NewConfig. d4, err := dht.New(conf4) if err != nil { fmt.Fprintf(os.Stderr, "New DHT error: %v", err) os.Exit(1) } var d6 *dht.DHT if len(*ipv6Address) > 1 { fmt.Printf("Tring to bind to IPv6=%s\n", *ipv6Address) d6, err = dht.New(conf6) if err != nil { fmt.Fprintf(os.Stderr, "New DHT error: %v", err) os.Exit(1) } if err = d6.Start(); err != nil { fmt.Fprintf(os.Stderr, "DHT start error: %v", err) os.Exit(1) } go drainresults(d6) } else { fmt.Fprintf(os.Stderr, "Not binding to IPv6 interface. If desired pass -v6=[address] for the\n") fmt.Fprintf(os.Stderr, "address you want the DHT to bind to. Privacy addresses are not recommended\n") fmt.Fprintf(os.Stderr, "Since they can expire and connections will fail\n\n") } // For debugging. go http.ListenAndServe(fmt.Sprintf(":%d", httpPortTCP), nil) if err = d4.Start(); err != nil { fmt.Fprintf(os.Stderr, "DHT start error: %v", err) os.Exit(1) } go drainresults(d4) for { d4.PeersRequest(string(ih), true) if len(*ipv6Address) > 1 { d6.PeersRequest(string(ih), true) } time.Sleep(5 * time.Second) } }