Exemple #1
0
func findAuthenticatedPeers(port, appPort, minPeers int, passphrase []byte, c chan Peer) {
	defer close(c)
	ih, err := infoHash(passphrase)
	if err != nil {
		log.Println("Could not calculate infohash for the provided passphrase", err)
		return
	}
	announce := false
	if appPort > 0 {
		announce = true
		if _, err = listenAuth(port, appPort, passphrase); err != nil {
			log.Println("Could not open listener:", err)
			return
		}
	}
	// Connect to the DHT network.
	d, err := dht.NewDHTNode(port, minPeers, announce)
	if err != nil {
		log.Println("Could not create the DHT node:", err)
		return
	}
	d.AddNode("213.239.195.138:40000")
	go d.DoDHT()
	// Sends authenticated peers to channel c.
	go obtainPeers(d, passphrase, c)

	for {
		// Keeps requesting for the infohash. This is a no-op if the
		// DHT is satisfied with the number of peers it has found.
		d.PeersRequest(string(ih), true)

		time.Sleep(5 * time.Second)
	}
}
Exemple #2
0
func main() {
	flag.Parse()
	// Change to l4g.DEBUG to see *lots* of debugging information.
	l4g.AddFilter("stdout", l4g.WARNING, l4g.NewConsoleLogWriter())
	if len(flag.Args()) != 1 {
		fmt.Fprintf(os.Stderr, "Usage: %v <infohash>\n\n", os.Args[0])
		fmt.Fprintf(os.Stderr, "Example infohash: d1c5676ae7ac98e8b19f63565905105e3c4c37a2\n")
		flag.PrintDefaults()
		os.Exit(1)
	}
	ih, err := dht.DecodeInfoHash(flag.Args()[0])
	if err != nil {
		l4g.Critical("DecodeInfoHash error: %v\n", err)
		os.Exit(1)
	}

	// This is a hint to the DHT of the minimum number of peers it will try to
	// find for the given node. This is not a reliable limit. In the future this
	// might be moved to "PeersRequest()", so the controlling client can have
	// different targets at different moments or for different infohashes.
	targetNumPeers := 5
	d, err := dht.NewDHTNode(dhtPortUDP, targetNumPeers, false)
	if err != nil {
		l4g.Critical("NewDHTNode error: %v", err)
		os.Exit(1)

	}
	// For debugging.
	go http.ListenAndServe(fmt.Sprintf(":%d", httpPortTCP), nil)

	go d.DoDHT()
	go drainresults(d)

	for {
		// Give the DHT some time to "warm-up" its routing table.
		time.Sleep(5 * time.Second)

		d.PeersRequest(string(ih), false)
	}
}
Exemple #3
0
func NewTorrentSession(torrent string) (ts *TorrentSession, err error) {

	var listenPort int
	if listenPort, err = chooseListenPort(); err != nil {
		log.Println("Could not choose listen port.")
		log.Println("Peer connectivity will be affected.")
	}
	t := &TorrentSession{peers: make(map[string]*peerState),
		peerMessageChan: make(chan peerMessage),
		activePieces:    make(map[int]*ActivePiece)}
	t.m, err = getMetaInfo(torrent)
	if err != nil {
		return
	}
	log.Printf("Tracker: %v, Comment: %v, InfoHash: %x, Encoding: %v, Private: %v",
		t.m.Announce, t.m.Comment, t.m.InfoHash, t.m.Encoding, t.m.Info.Private)
	if e := t.m.Encoding; e != "" && e != "UTF-8" {
		return nil, errors.New(fmt.Sprintf("Unknown encoding %s", e))
	}
	ext := ".torrent"
	dir := fileDir
	if len(t.m.Info.Files) != 0 {
		dir += "/" + filepath.Base(torrent)
		if dir[len(dir)-len(ext):] == ext {
			dir = dir[:len(dir)-len(ext)]
		}
	}

	t.fileStore, t.totalSize, err = NewFileStore(&t.m.Info, dir)
	if err != nil {
		return
	}
	t.lastPieceLength = int(t.totalSize % t.m.Info.PieceLength)

	start := time.Now()
	good, bad, pieceSet, err := checkPieces(t.fileStore, t.totalSize, t.m)
	end := time.Now()
	log.Printf("Computed missing pieces (%.2f seconds)", end.Sub(start).Seconds())
	if err != nil {
		return
	}
	t.pieceSet = pieceSet
	t.totalPieces = good + bad
	t.goodPieces = good
	log.Println("Good pieces:", good, "Bad pieces:", bad)

	left := int64(bad) * int64(t.m.Info.PieceLength)
	if !t.pieceSet.IsSet(t.totalPieces - 1) {
		left = left - t.m.Info.PieceLength + int64(t.lastPieceLength)
	}
	t.si = &SessionInfo{PeerId: peerId(), Port: listenPort, Left: left}
	if useDHT {
		// TODO: UPnP UDP port mapping.
		if t.dht, err = dht.NewDHTNode(listenPort, TARGET_NUM_PEERS, true); err != nil {
			log.Println("DHT node creation error", err)
			return
		}
		go t.dht.DoDHT()
	}
	return t, err
}
Exemple #4
0
func NewTorrentSession(torrent string) (ts *TorrentSession, err error) {

	var listenPort int
	if listenPort, err = chooseListenPort(); err != nil {
		log.Println("Could not choose listen port.")
		log.Println("Peer connectivity will be affected.")
	}

	t := &TorrentSession{peers: make(map[string]*peerState),
		peerMessageChan: make(chan peerMessage, 100),
		activePieces:    make(map[int]*ActivePiece),
		history:		make(map[string]*DownloadUpload),
		ioRequestChan:	make(chan *IoArgs, 100),
		ioResponceChan: make(chan interface{}, 100),
		}

	t.cache = cache.NewLRUCache(10 * 1024 *1024)	

	t.m, err = getMetaInfo(torrent)
	if err != nil {
		return
	}
	log.Printf("Tracker: %v, Comment: %v, InfoHash: %x, Encoding: %v, Private: %v",
		t.m.Announce, t.m.Comment, t.m.InfoHash, t.m.Encoding, t.m.Info.Private)
	if e := t.m.Encoding; e != "" && e != "UTF-8" {
		return nil, errors.New(fmt.Sprintf("Unknown encoding %s", e))
	}
	ext := ".torrent"
	dir := cfg.fileDir
	if len(t.m.Info.Files) != 0 {
		dir += "/" + filepath.Base(torrent)
		if dir[len(dir)-len(ext):] == ext {
			dir = dir[:len(dir)-len(ext)]
		}
	}

	t.fileStore, t.totalSize, err = NewFileStore(&t.m.Info, dir)
	if err != nil {
		return
	}

	t.lastPieceLength = int(t.totalSize % t.m.Info.PieceLength)

	start := time.Now()

	var good, bad int
	var pieceSet *Bitset
	if cfg.noCheckSum{
		//todo: refactor to function
		t.fastResumeFile = torrent + ".fastResume"
		if f, err := os.OpenFile(t.fastResumeFile, os.O_CREATE | os.O_RDWR | O_BINARY, 0); err != nil {
			panic("can not open fast resume file")
		}else{
			defer f.Close()
			set, _ := ioutil.ReadAll(f)
			totalPieceCount := int((t.totalSize + int64(t.m.Info.PieceLength) - 1) / int64(t.m.Info.PieceLength))
			if len(set) != totalPieceCount {
				log.Println("warning, invalid fast resume file")
				good, bad, pieceSet, err = checkPieces(t.fileStore, t.totalSize, t.m)
			}else{
				pieceSet = NewBitset(totalPieceCount)
				for i := 0; i < totalPieceCount; i++ {
					if set[i] == 1 {
						pieceSet.Set(i)
						good++
					}else{
						bad++
					}
				}
			}
		}
	}else{
		good, bad, pieceSet, err = checkPieces(t.fileStore, t.totalSize, t.m)
	}
	
	end := time.Now()
	log.Printf("Computed missing pieces (%.2f seconds)", end.Sub(start).Seconds())
	if err != nil {
		return
	}
	t.pieceSet = pieceSet
	t.totalPieces = good + bad
	t.goodPieces = good
	log.Println("Good pieces:", good, "Bad pieces:", bad)

	left := int64(bad) * int64(t.m.Info.PieceLength)
	if !t.pieceSet.IsSet(t.totalPieces - 1) {
		left = left - t.m.Info.PieceLength + int64(t.lastPieceLength)
	}
	t.si = &SessionInfo{PeerId: peerId(), Port: listenPort, Left: left}
	if cfg.useDHT {
		// TODO: UPnP UDP port mapping.
		if t.dht, err = dht.NewDHTNode(listenPort, cfg.TARGET_NUM_PEERS, true); err != nil {
			log.Println("DHT node creation error", err)
			return
		}
		go t.dht.DoDHT()
	}

	go IoRoutine(t.ioRequestChan, t.ioResponceChan)

	return t, err
}
Exemple #5
0
func main() {
	var numTargetPeers int
	var sendAnnouncements bool
	var file *os.File
	var num int
	var shalist [64]string
	var err error
	var part []byte

	l4g.AddFilter("stdout", l4g.DEBUG, l4g.NewConsoleLogWriter())

	if file, err = os.Open("hops.log"); err != nil {
		return
	}
	reader := bufio.NewReader(file)
	num = 0
	for {
		if part, _, err = reader.ReadLine(); err != nil {
			break
		}
		if err == io.EOF {
			err = nil
		}
		hasher := sha1.New()
		hasher.Write(part)
		shalist[num] = string(hasher.Sum(nil))
		num = num + 1
	}

	sendAnnouncements = true
	numTargetPeers = 64

	port := 42345
	l4g.Error("used port %d", port)
	dht, err := dht.NewDHTNode(port, numTargetPeers, false)
	if err != nil {
		l4g.Error("DHT node creation error", err)
		return
	}

	go dht.DoDHT()
	go drainresults(dht)

	queryTick := time.Tick(20 * time.Second)

	go http.ListenAndServe(fmt.Sprintf(":%d", httpPort), nil)
	for {
		select {
		case <-queryTick:
			// trying the manual method from dht_test in case I have the format
			// wrong
			fmt.Printf("TICK ************************************\n")
			fmt.Printf("TICK ************************************\n")
			fmt.Printf("TICK ************************************\n")
			fmt.Printf("TICK ************************************\n")
			fmt.Printf("TICK ************************************\n")
			fmt.Printf("TICK ************************************\n")
			for i := 0; i < num; i++ {
				l4g.Info("querying for infoHash: %x", shalist[i])
				dht.PeersRequest(shalist[i], sendAnnouncements)
				time.Sleep(10 * time.Second)
			}
		}
	}
}