Commit 37e60387 authored by Miek Gieben's avatar Miek Gieben

Play some more with torrenting

Signed-off-by: default avatarMiek Gieben <miek@miek.nl>
parent ef334254
...@@ -55,4 +55,5 @@ var Directives = []string{ ...@@ -55,4 +55,5 @@ var Directives = []string{
"whoami", "whoami",
"on", "on",
"sign", "sign",
"torrent",
} }
...@@ -46,6 +46,7 @@ import ( ...@@ -46,6 +46,7 @@ import (
_ "github.com/coredns/coredns/plugin/sign" _ "github.com/coredns/coredns/plugin/sign"
_ "github.com/coredns/coredns/plugin/template" _ "github.com/coredns/coredns/plugin/template"
_ "github.com/coredns/coredns/plugin/tls" _ "github.com/coredns/coredns/plugin/tls"
_ "github.com/coredns/coredns/plugin/torrent"
_ "github.com/coredns/coredns/plugin/trace" _ "github.com/coredns/coredns/plugin/trace"
_ "github.com/coredns/coredns/plugin/transfer" _ "github.com/coredns/coredns/plugin/transfer"
_ "github.com/coredns/coredns/plugin/whoami" _ "github.com/coredns/coredns/plugin/whoami"
......
...@@ -12,6 +12,7 @@ require ( ...@@ -12,6 +12,7 @@ require (
github.com/aws/aws-sdk-go v1.33.7 github.com/aws/aws-sdk-go v1.33.7
github.com/caddyserver/caddy v1.0.5 github.com/caddyserver/caddy v1.0.5
github.com/cenkalti/backoff/v4 v4.0.2 github.com/cenkalti/backoff/v4 v4.0.2
github.com/cenkalti/rain v1.4.4
github.com/dnstap/golang-dnstap v0.2.0 github.com/dnstap/golang-dnstap v0.2.0
github.com/farsightsec/golang-framestream v0.0.0-20190425193708-fa4b164d59b8 github.com/farsightsec/golang-framestream v0.0.0-20190425193708-fa4b164d59b8
github.com/golang/protobuf v1.4.2 github.com/golang/protobuf v1.4.2
...@@ -20,6 +21,7 @@ require ( ...@@ -20,6 +21,7 @@ require (
github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/imdario/mergo v0.3.9 // indirect github.com/imdario/mergo v0.3.9 // indirect
github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062 github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062
github.com/jackpal/bencode-go v0.0.0-20180813173944-227668e840fa
github.com/kr/pretty v0.2.0 // indirect github.com/kr/pretty v0.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/miekg/dns v1.1.30 github.com/miekg/dns v1.1.30
...@@ -31,6 +33,7 @@ require ( ...@@ -31,6 +33,7 @@ require (
github.com/prometheus/client_model v0.2.0 github.com/prometheus/client_model v0.2.0
github.com/prometheus/common v0.10.0 github.com/prometheus/common v0.10.0
github.com/prometheus/prometheus v2.5.0+incompatible github.com/prometheus/prometheus v2.5.0+incompatible
github.com/zeebo/bencode v1.0.0
go.etcd.io/etcd v0.5.0-alpha.5.0.20200306183522-221f0cc107cb go.etcd.io/etcd v0.5.0-alpha.5.0.20200306183522-221f0cc107cb
go.uber.org/zap v1.14.1 // indirect go.uber.org/zap v1.14.1 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
......
This diff is collapsed.
...@@ -64,3 +64,4 @@ erratic:erratic ...@@ -64,3 +64,4 @@ erratic:erratic
whoami:whoami whoami:whoami
on:github.com/caddyserver/caddy/onevent on:github.com/caddyserver/caddy/onevent
sign:sign sign:sign
torrent:torrent
...@@ -26,13 +26,13 @@ For peers seeding the torrent use this, slightly expanded, syntax ...@@ -26,13 +26,13 @@ For peers seeding the torrent use this, slightly expanded, syntax
~~~ txt ~~~ txt
torrent DBFILE { torrent DBFILE {
seed dht
// directory (temp storage)
// port for dth, etc.
} }
~~~ ~~~
* `seed` tells *torrent* to seed content from **DBFILE** to the peers, it will _never_ write to * `dth` starts a DTH server on address
**DBFILE**. When `seed` is _not_ specified **DBFILE** will be written to once the entire torrent
is downloaded.
## Examples ## Examples
......
package torrent
import (
"crypto/sha1"
"io"
"os"
"strings"
"github.com/zeebo/bencode"
)
const pieceLength = 2048 * 10
// pieces will hash the file in path on 256kb boundaries and return the (sha1) hashes.
func pieces(path string) (int, string, error) {
f, err := os.Open(path)
if err != nil {
return 0, "", err
}
hashes := "" // concatenated string of hash (strings)
buf := make([]byte, 2048)
h := sha1.New()
chunk := 0
length := 0
n, err := f.Read(buf)
for err != nil {
h.Write(buf[:n])
chunk++
length += n
if chunk > 10 {
chunk = 0
hashes += string(h.Sum(nil))
h = sha1.New()
}
n, err = f.Read(buf)
}
if n > 0 {
length += n
h.Write(buf[:n])
hashes += string(h.Sum(nil))
}
return length, hashes, nil
}
// Info is the torrent meta data for a single file.
type Info struct {
Pieces string `bencode:"pieces"`
PieceLength int `bencode:"piece length"`
Length int `bencode:"length"`
Name string `bencode:"name"`
}
// TorrentInfo contains the meta data for this torrent.
type TorrentInfo struct {
Nodes []string `bencode:"nodes"`
Info Info `bencode:"info"`
}
func NewTorrentInfo(path string) (*TorrentInfo, error) {
length, pieces, err := pieces(path)
if err != nil {
return nil, err
}
i := Info{Pieces: pieces, PieceLength: 2048 * 10, Length: length, Name: path}
return &TorrentInfo{Nodes: []string{}, Info: i}, nil
}
func (t *TorrentInfo) ToReader() io.Reader {
s, err := bencode.EncodeString(t)
if err != nil {
return nil
}
return strings.NewReader(s)
}
package torrent package torrent
import ( import (
"io/ioutil"
"log" "log"
"path/filepath"
"time" "time"
rtorrent "github.com/cenkalti/rain/torrent" rtorrent "github.com/cenkalti/rain/torrent"
) )
func (t *Torrent) StartSession() error { func (t *Torrent) Do() error {
s, err := rtorrent.NewSession(torrent.DefaultConfig) dc := rtorrent.DefaultConfig
dc.DHTEnabled = t.dht
dc.RPCEnabled = false
dc.DHTBootstrapNodes = []string{"127.0.0.1:7246"} // its a me
td, err := ioutil.TempDir("", "example")
if err != nil {
return err
}
dc.DataDir = td
dc.Database = filepath.Join(td, "session.db")
s, err := rtorrent.NewSession(dc)
if err != nil {
return err
}
ti, err := NewTorrentInfo("plugin/torrent/testdata/db.miek.nl")
if err != nil {
return err
}
tor, err := s.AddTorrent(ti.ToReader(), nil)
if err != nil { if err != nil {
return err return err
} }
// mag, _ := tor.Magnet()
// Add magnet link go s.StartAll()
tor, _ := ses.AddURI(magnetLink, nil)
// Watch the progress // Watch the progress
for range time.Tick(time.Second) { for range time.Tick(time.Second) {
s := tor.Stats() s := tor.Stats()
log.Printf("Status: %s, Downloaded: %d, Peers: %d", s.Status.String(), s.Bytes.Completed, s.Peers.Total) log.Printf("Status: %s, Downloaded: %d, Peers: %d", s.Status.String(), s.Bytes.Completed, s.Peers.Total)
} }
return nil
} }
...@@ -14,12 +14,12 @@ func init() { plugin.Register("torrent", setup) } ...@@ -14,12 +14,12 @@ func init() { plugin.Register("torrent", setup) }
func setup(c *caddy.Controller) error { func setup(c *caddy.Controller) error {
tor, err := parse(c) tor, err := parse(c)
if err != nil { if err != nil {
return plugin.Error("sign", err) return plugin.Error("torrent", err)
} }
c.OnStartup(func() error { c.OnStartup(func() error {
// go tor.do() err := tor.Do()
return nil return err
}) })
c.OnShutdown(func() error { c.OnShutdown(func() error {
close(tor.stop) close(tor.stop)
...@@ -31,7 +31,7 @@ func setup(c *caddy.Controller) error { ...@@ -31,7 +31,7 @@ func setup(c *caddy.Controller) error {
} }
func parse(c *caddy.Controller) (*Torrent, error) { func parse(c *caddy.Controller) (*Torrent, error) {
t := &Torrent{} t := &Torrent{stop: make(chan struct{})}
config := dnsserver.GetConfig(c) config := dnsserver.GetConfig(c)
for c.Next() { for c.Next() {
...@@ -46,8 +46,8 @@ func parse(c *caddy.Controller) (*Torrent, error) { ...@@ -46,8 +46,8 @@ func parse(c *caddy.Controller) (*Torrent, error) {
for c.NextBlock() { for c.NextBlock() {
switch c.Val() { switch c.Val() {
case "seed": case "dht":
t.seed = true t.dht = true
default: default:
return nil, c.Errf("unknown property '%s'", c.Val()) return nil, c.Errf("unknown property '%s'", c.Val())
} }
......
...@@ -13,10 +13,10 @@ func TestParse(t *testing.T) { ...@@ -13,10 +13,10 @@ func TestParse(t *testing.T) {
exp *Torrent exp *Torrent
}{ }{
{`torrent testdata/db.miek.nl { {`torrent testdata/db.miek.nl {
seed dht
}`, }`,
false, false,
&Torrent{dbfile: "testdata/db.miek.nl", seed: true}, &Torrent{dbfile: "testdata/db.miek.nl", dht: true},
}, },
{`torrent testdata/db.miek.nl`, {`torrent testdata/db.miek.nl`,
false, false,
...@@ -46,8 +46,8 @@ func TestParse(t *testing.T) { ...@@ -46,8 +46,8 @@ func TestParse(t *testing.T) {
if x := tor.dbfile; x != tc.exp.dbfile { if x := tor.dbfile; x != tc.exp.dbfile {
t.Errorf("Test %d expected %s as dbfile, got %s", i, tc.exp.dbfile, x) t.Errorf("Test %d expected %s as dbfile, got %s", i, tc.exp.dbfile, x)
} }
if x := tor.seed; x != tc.exp.seed { if x := tor.dth; x != tc.exp.dth {
t.Errorf("Test %d expected %T as seed, got %T", i, tc.exp.seed, x) t.Errorf("Test %d expected %T as seed, got %T", i, tc.exp.dth, x)
} }
} }
} }
$TTL 30M
$ORIGIN miek.nl.
@ IN SOA linode.atoom.net. miek.miek.nl. ( 1282630060 4H 1H 7D 4H )
IN NS linode.atoom.net.
IN MX 1 aspmx.l.google.com.
IN AAAA 2a01:7e00::f03c:91ff:fe79:234c
IN DNSKEY 257 3 13 sfzRg5nDVxbeUc51su4MzjgwpOpUwnuu81SlRHqJuXe3SOYOeypR69tZ52XLmE56TAmPHsiB8Rgk+NTpf0o1Cw==
a IN AAAA 2a01:7e00::f03c:91ff:fe79:234c
www IN CNAME a
bla IN NS ns1.bla.com.
ns3.blaaat.miek.nl. IN AAAA ::1 ; non-glue, should be signed.
; in baliwick nameserver that requires glue, should not be signed
bla IN NS ns2.bla.miek.nl.
ns2.bla.miek.nl. IN A 127.0.0.1
...@@ -3,7 +3,7 @@ package torrent ...@@ -3,7 +3,7 @@ package torrent
// Torrent contains the file data that needs to be torrented. // Torrent contains the file data that needs to be torrented.
type Torrent struct { type Torrent struct {
dbfile string dbfile string
seed bool dht bool
stop chan struct{} stop chan struct{}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment