Esempio n. 1
0
// 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
}
Esempio n. 2
0
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)
	}

}
Esempio n. 3
0
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(&currentIhMessage)
	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
}
Esempio n. 4
0
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
}
Esempio n. 5
0
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
}
Esempio n. 6
0
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
}
Esempio n. 7
0
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
}
Esempio n. 8
0
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
}
Esempio n. 9
0
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)
	}
}