aboutsummaryrefslogtreecommitdiff
path: root/plugin/torrent
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/torrent')
-rw-r--r--plugin/torrent/README.md48
-rw-r--r--plugin/torrent/session.go25
-rw-r--r--plugin/torrent/setup.go58
-rw-r--r--plugin/torrent/setup_test.go53
-rw-r--r--plugin/torrent/torrent.go9
5 files changed, 193 insertions, 0 deletions
diff --git a/plugin/torrent/README.md b/plugin/torrent/README.md
new file mode 100644
index 000000000..890bb8e3b
--- /dev/null
+++ b/plugin/torrent/README.md
@@ -0,0 +1,48 @@
+# torrent
+
+## Name
+
+*torrent* - use BitTorrent to disseminate zone data.
+
+## Description
+
+The *torrent* plugin uses the BitTorrent protocol to disseminate zone data. Multiple peers can
+connect and down- and upload the data. A couple of nodes can be `seed` only meaning they will update
+the torrent when their zone data changes. Non-`seed` peers will write received data back into the
+zonefile - once the torrent is fully downloaded.
+
+## Syntax
+
+The simplest syntax is for a peer wanting to receive the zone data:
+
+~~~ txt
+torrent DBFILE
+~~~
+
+* **DBFILE** the zone database file to torrent. If the path is relative, the path from the
+ *root* plugin will be prepended to it.
+
+For peers seeding the torrent use this, slightly expanded, syntax
+
+~~~ txt
+torrent DBFILE {
+ seed
+}
+~~~
+
+* `seed` tells *torrent* to seed content from **DBFILE** to the peers, it will _never_ write to
+ **DBFILE**. When `seed` is _not_ specified **DBFILE** will be written to once the entire torrent
+ is downloaded.
+
+## Examples
+
+~~~ txt
+example.org {
+ file db.example.org
+ torrent db.example.org
+}
+~~~
+
+## Also See
+
+## Bugs
diff --git a/plugin/torrent/session.go b/plugin/torrent/session.go
new file mode 100644
index 000000000..3b3a35a41
--- /dev/null
+++ b/plugin/torrent/session.go
@@ -0,0 +1,25 @@
+package torrent
+
+import (
+ "log"
+ "time"
+
+ rtorrent "github.com/cenkalti/rain/torrent"
+)
+
+func (t *Torrent) StartSession() error {
+ s, err := rtorrent.NewSession(torrent.DefaultConfig)
+ if err != nil {
+ return err
+ }
+
+ // Add magnet link
+ tor, _ := ses.AddURI(magnetLink, nil)
+
+ // Watch the progress
+ for range time.Tick(time.Second) {
+ s := tor.Stats()
+ log.Printf("Status: %s, Downloaded: %d, Peers: %d", s.Status.String(), s.Bytes.Completed, s.Peers.Total)
+ }
+
+}
diff --git a/plugin/torrent/setup.go b/plugin/torrent/setup.go
new file mode 100644
index 000000000..ac69f0e96
--- /dev/null
+++ b/plugin/torrent/setup.go
@@ -0,0 +1,58 @@
+package torrent
+
+import (
+ "path/filepath"
+
+ "github.com/coredns/coredns/core/dnsserver"
+ "github.com/coredns/coredns/plugin"
+
+ "github.com/caddyserver/caddy"
+)
+
+func init() { plugin.Register("torrent", setup) }
+
+func setup(c *caddy.Controller) error {
+ tor, err := parse(c)
+ if err != nil {
+ return plugin.Error("sign", err)
+ }
+
+ c.OnStartup(func() error {
+ // go tor.do()
+ return nil
+ })
+ c.OnShutdown(func() error {
+ close(tor.stop)
+ return nil
+ })
+
+ // Don't call AddPlugin, *sign* is not a plugin.
+ return nil
+}
+
+func parse(c *caddy.Controller) (*Torrent, error) {
+ t := &Torrent{}
+ config := dnsserver.GetConfig(c)
+
+ for c.Next() {
+ if !c.NextArg() {
+ return nil, c.ArgErr()
+ }
+ dbfile := c.Val()
+ if !filepath.IsAbs(dbfile) && config.Root != "" {
+ dbfile = filepath.Join(config.Root, dbfile)
+ }
+ t.dbfile = dbfile
+
+ for c.NextBlock() {
+ switch c.Val() {
+ case "seed":
+ t.seed = true
+ default:
+ return nil, c.Errf("unknown property '%s'", c.Val())
+ }
+ }
+ }
+
+ return t, nil
+}
diff --git a/plugin/torrent/setup_test.go b/plugin/torrent/setup_test.go
new file mode 100644
index 000000000..3faa336fd
--- /dev/null
+++ b/plugin/torrent/setup_test.go
@@ -0,0 +1,53 @@
+package torrent
+
+import (
+ "testing"
+
+ "github.com/caddyserver/caddy"
+)
+
+func TestParse(t *testing.T) {
+ tests := []struct {
+ input string
+ shouldErr bool
+ exp *Torrent
+ }{
+ {`torrent testdata/db.miek.nl {
+ seed
+ }`,
+ false,
+ &Torrent{dbfile: "testdata/db.miek.nl", seed: true},
+ },
+ {`torrent testdata/db.miek.nl`,
+ false,
+ &Torrent{dbfile: "testdata/db.miek.nl"},
+ },
+ // errors
+ {`torrent db.example.org {
+ bla
+ }`,
+ true,
+ nil,
+ },
+ }
+ for i, tc := range tests {
+ c := caddy.NewTestController("dns", tc.input)
+ tor, err := parse(c)
+
+ if err == nil && tc.shouldErr {
+ t.Fatalf("Test %d expected errors, but got no error", i)
+ }
+ if err != nil && !tc.shouldErr {
+ t.Fatalf("Test %d expected no errors, but got '%v'", i, err)
+ }
+ if tc.shouldErr {
+ continue
+ }
+ if x := tor.dbfile; x != tc.exp.dbfile {
+ t.Errorf("Test %d expected %s as dbfile, got %s", i, tc.exp.dbfile, x)
+ }
+ if x := tor.seed; x != tc.exp.seed {
+ t.Errorf("Test %d expected %T as seed, got %T", i, tc.exp.seed, x)
+ }
+ }
+}
diff --git a/plugin/torrent/torrent.go b/plugin/torrent/torrent.go
new file mode 100644
index 000000000..91453ce22
--- /dev/null
+++ b/plugin/torrent/torrent.go
@@ -0,0 +1,9 @@
+package torrent
+
+// Torrent contains the file data that needs to be torrented.
+type Torrent struct {
+ dbfile string
+ seed bool
+
+ stop chan struct{}
+}