2013-09-26 17:49:15 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2014-07-11 17:30:20 +08:00
|
|
|
"bitbucket.org/anacrolix/go.torrent/dht"
|
2014-07-22 23:54:58 +08:00
|
|
|
"bitbucket.org/anacrolix/go.torrent/util"
|
2013-09-26 17:49:15 +08:00
|
|
|
"flag"
|
2013-11-04 21:07:28 +08:00
|
|
|
"fmt"
|
2013-09-26 17:49:15 +08:00
|
|
|
"log"
|
2013-09-29 06:11:24 +08:00
|
|
|
"net"
|
2013-11-04 21:07:28 +08:00
|
|
|
"net/http"
|
|
|
|
_ "net/http/pprof"
|
|
|
|
"os"
|
2014-06-26 22:57:07 +08:00
|
|
|
"strings"
|
2014-03-20 13:58:09 +08:00
|
|
|
|
2014-06-28 17:38:31 +08:00
|
|
|
"github.com/anacrolix/libtorgo/metainfo"
|
2014-03-20 13:58:09 +08:00
|
|
|
|
|
|
|
"bitbucket.org/anacrolix/go.torrent"
|
2013-09-26 17:49:15 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
downloadDir = flag.String("downloadDir", "", "directory to store download torrent data")
|
2013-11-04 21:07:28 +08:00
|
|
|
testPeer = flag.String("testPeer", "", "bootstrap peer address")
|
2014-07-11 23:23:10 +08:00
|
|
|
httpAddr = flag.String("httpAddr", "localhost:0", "http serve address")
|
2014-03-20 21:13:32 +08:00
|
|
|
// TODO: Check the default torrent listen port.
|
2014-05-21 15:38:09 +08:00
|
|
|
listenAddr = flag.String("listenAddr", ":6882", "incoming connection address")
|
|
|
|
disableTrackers = flag.Bool("disableTrackers", false, "disable trackers")
|
|
|
|
seed = flag.Bool("seed", false, "seed after downloading")
|
2013-09-26 17:49:15 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2013-09-30 19:51:08 +08:00
|
|
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
2013-09-26 17:49:15 +08:00
|
|
|
flag.Parse()
|
|
|
|
}
|
|
|
|
|
2014-03-20 21:13:32 +08:00
|
|
|
func makeListener() net.Listener {
|
|
|
|
l, err := net.Listen("tcp", *listenAddr)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
return l
|
|
|
|
}
|
|
|
|
|
2013-09-26 17:49:15 +08:00
|
|
|
func main() {
|
2014-06-27 16:57:35 +08:00
|
|
|
if *httpAddr != "" {
|
2014-07-22 23:54:58 +08:00
|
|
|
util.LoggedHTTPServe(*httpAddr)
|
2013-11-04 21:07:28 +08:00
|
|
|
}
|
2014-07-11 17:30:20 +08:00
|
|
|
dhtServer := &dht.Server{
|
|
|
|
Socket: func() *net.UDPConn {
|
|
|
|
addr, err := net.ResolveUDPAddr("udp4", *listenAddr)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error resolving dht listen addr: %s", err)
|
|
|
|
}
|
|
|
|
s, err := net.ListenUDP("udp4", addr)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error creating dht socket: %s", err)
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}(),
|
|
|
|
}
|
|
|
|
err := dhtServer.Init()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error initing dht server: %s", err)
|
|
|
|
}
|
|
|
|
go func() {
|
|
|
|
err := dhtServer.Serve()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error serving dht: %s", err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
go func() {
|
|
|
|
err := dhtServer.Bootstrap()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("error bootstrapping dht server: %s", err)
|
|
|
|
}
|
|
|
|
}()
|
2013-11-04 21:07:28 +08:00
|
|
|
client := torrent.Client{
|
2014-05-21 15:38:09 +08:00
|
|
|
DataDir: *downloadDir,
|
|
|
|
Listener: makeListener(),
|
|
|
|
DisableTrackers: *disableTrackers,
|
2014-07-11 17:30:20 +08:00
|
|
|
DHT: dhtServer,
|
2013-11-04 21:07:28 +08:00
|
|
|
}
|
2014-06-27 16:57:35 +08:00
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
|
|
|
client.WriteStatus(w)
|
|
|
|
})
|
2013-11-04 21:07:28 +08:00
|
|
|
client.Start()
|
|
|
|
defer client.Stop()
|
|
|
|
if flag.NArg() == 0 {
|
|
|
|
fmt.Fprintln(os.Stderr, "no torrents specified")
|
|
|
|
return
|
|
|
|
}
|
2013-09-26 17:49:15 +08:00
|
|
|
for _, arg := range flag.Args() {
|
2014-06-26 22:57:07 +08:00
|
|
|
var ih torrent.InfoHash
|
|
|
|
if strings.HasPrefix(arg, "magnet:") {
|
|
|
|
m, err := torrent.ParseMagnetURI(arg)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error parsing magnet uri: %s", err)
|
|
|
|
}
|
|
|
|
ih = m.InfoHash
|
|
|
|
err = client.AddMagnet(arg)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("error adding magnet: %s", err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
metaInfo, err := metainfo.LoadFromFile(arg)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
err = client.AddTorrent(metaInfo)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2014-07-13 15:37:12 +08:00
|
|
|
ih = torrent.BytesInfoHash(metaInfo.Info.Hash)
|
2013-09-26 17:49:15 +08:00
|
|
|
}
|
2014-06-26 22:57:07 +08:00
|
|
|
client.PrioritizeDataRegion(ih, 0, 999999999)
|
|
|
|
err := client.AddPeers(ih, func() []torrent.Peer {
|
2013-11-04 21:07:28 +08:00
|
|
|
if *testPeer == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
addr, err := net.ResolveTCPAddr("tcp", *testPeer)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
return []torrent.Peer{{
|
2014-03-20 13:58:09 +08:00
|
|
|
IP: addr.IP,
|
|
|
|
Port: addr.Port,
|
|
|
|
}}
|
2013-11-04 21:07:28 +08:00
|
|
|
}())
|
2013-09-29 06:11:24 +08:00
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2013-09-26 17:49:15 +08:00
|
|
|
}
|
2014-05-21 15:38:09 +08:00
|
|
|
if *seed {
|
|
|
|
select {}
|
|
|
|
}
|
2014-04-09 00:36:05 +08:00
|
|
|
if client.WaitAll() {
|
|
|
|
log.Print("all torrents completed!")
|
|
|
|
} else {
|
|
|
|
log.Fatal("y u no complete torrents?!")
|
|
|
|
}
|
2013-09-26 17:49:15 +08:00
|
|
|
}
|