@cryptotaxi247 / kubo / commits / e9b1fe4ce

clean up dependencies

License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>

Jeromy committed Mar 22, 2016 at 13:09 UTC e9b1fe4cef2a6685c5bd79393adc320bdafdc3d4
295 files changed +6465 -53125
Godeps/Godeps.json
-89
@@ -14,39 +14,10 @@
14 "Comment": "null-5",
15 "Rev": "75cd24fc2f2c2a2088577d12123ddee5f54e0675"
16 },
17 - {
18 - "ImportPath": "github.com/alecthomas/kingpin",
19 - "Comment": "v2.1.0-2-gaedd543",
20 - "Rev": "aedd5430ecd39ba1396fee0c00308b494c552b1e"
21 - },
22 - {
23 - "ImportPath": "github.com/alecthomas/template",
24 - "Rev": "b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0"
25 - },
26 - {
27 - "ImportPath": "github.com/alecthomas/units",
28 - "Rev": "6b4e7dc5e3143b85ea77909c72caf89416fc2915"
29 - },
30 - {
31 - "ImportPath": "github.com/anacrolix/jitter",
32 - "Rev": "2ea5c18645100745b24e9f5cfc9b3f6f7eac51ef"
33 - },
34 - {
35 - "ImportPath": "github.com/anacrolix/missinggo",
36 - "Rev": "4e1ca5963308863b56c31863f60c394a7365ec29"
37 - },
38 - {
39 - "ImportPath": "github.com/anacrolix/utp",
40 - "Rev": "0bb24de92c268452fb9106ca4fb9302442ca0dee"
41 - },
17 {
18 "ImportPath": "github.com/beorn7/perks/quantile",
19 "Rev": "b965b613227fddccbfffe13eae360ed3fa822f8d"
20 },
46 - {
47 - "ImportPath": "github.com/bradfitz/iter",
48 - "Rev": "454541ec3da2a73fc34fd049b19ee5777bf19345"
49 - },
21 {
22 "ImportPath": "github.com/bren2010/proquint",
23 "Rev": "5958552242606512f714d2e93513b380f43f9991"
@@ -75,18 +46,6 @@
46 "ImportPath": "github.com/codahale/metrics",
47 "Rev": "7c37910bc765e705301b159683480bdd44555c91"
48 },
78 - {
79 - "ImportPath": "github.com/coreos/go-semver/semver",
80 - "Rev": "568e959cd89871e61434c1143528d9162da89ef2"
81 - },
82 - {
83 - "ImportPath": "github.com/crowdmob/goamz/aws",
84 - "Rev": "82345796204222aa56be89cf930c316b1297f906"
85 - },
86 - {
87 - "ImportPath": "github.com/crowdmob/goamz/s3",
88 - "Rev": "82345796204222aa56be89cf930c316b1297f906"
89 - },
49 {
50 "ImportPath": "github.com/cryptix/mdns",
51 "Rev": "04ff72a32679d57d009c0ac0fc5c4cda10350bad"
@@ -107,10 +66,6 @@
66 "ImportPath": "github.com/facebookgo/atomicfile",
67 "Rev": "6f117f2e7f224fb03eb5e5fba370eade6e2b90c8"
68 },
110 - {
111 - "ImportPath": "github.com/fd/go-nat",
112 - "Rev": "50e7633d5f27d81490026a13e5b92d2e42d8c6bb"
113 - },
69 {
70 "ImportPath": "github.com/gogo/protobuf/io",
71 "Rev": "0ac967c269268f1af7d9bcc7927ccc9a589b2b36"
@@ -127,22 +82,10 @@
82 "ImportPath": "github.com/hashicorp/golang-lru",
83 "Rev": "253b2dc1ca8bae42c3b5b6e53dd2eab1a7551116"
84 },
130 - {
131 - "ImportPath": "github.com/hashicorp/yamux",
132 - "Rev": "9feabe6854fadca1abec9cd3bd2a613fe9a34000"
133 - },
134 - {
135 - "ImportPath": "github.com/huin/goupnp",
136 - "Rev": "223008361153d7d434c1f0ac990cd3fcae6931f5"
137 - },
85 {
86 "ImportPath": "github.com/ipfs/go-datastore",
87 "Rev": "e63957b6da369d986ef3e7a3f249779ba3f56c7e"
88 },
142 - {
143 - "ImportPath": "github.com/jackpal/go-nat-pmp",
144 - "Rev": "a45aa3d54aef73b504e15eb71bea0e5565b5e6e1"
145 - },
89 {
90 "ImportPath": "github.com/jbenet/go-base58",
91 "Rev": "6237cf65f3a6f7111cd8a42be3590df99a66bc7d"
@@ -201,34 +144,10 @@
144 "ImportPath": "github.com/jbenet/go-random-files",
145 "Rev": "737479700b40b4b50e914e963ce8d9d44603e3c8"
146 },
204 - {
205 - "ImportPath": "github.com/jbenet/go-reuseport",
206 - "Rev": "48959f1fad204b6cf2c0e8d086ef69f03f2de961"
207 - },
208 - {
209 - "ImportPath": "github.com/jbenet/go-sockaddr/net",
210 - "Rev": "da304f94eea1af8ba8d1faf184623e1f9d9777dc"
211 - },
212 - {
213 - "ImportPath": "github.com/jbenet/go-stream-muxer",
214 - "Rev": "e2e261765847234749629e0190fef193a4548303"
215 - },
216 - {
217 - "ImportPath": "github.com/jbenet/go-temp-err-catcher",
218 - "Rev": "aac704a3f4f27190b4ccc05f303a4931fd1241ff"
219 - },
220 - {
221 - "ImportPath": "github.com/jbenet/goprocess",
222 - "Rev": "64a8220330a485070813201cc05b0c6777f6a516"
223 - },
147 {
148 "ImportPath": "github.com/matttproud/golang_protobuf_extensions/pbutil",
149 "Rev": "fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a"
150 },
228 - {
229 - "ImportPath": "github.com/miekg/dns",
230 - "Rev": "82ffc45b1f84ff71bd1cebed8b210118ce3d181e"
231 - },
151 {
152 "ImportPath": "github.com/mitchellh/go-homedir",
153 "Rev": "1f6da4a72e57d4e7edd4a7295a585e0a3999a2d4"
@@ -302,14 +221,6 @@
221 "ImportPath": "github.com/whyrusleeping/go-metrics",
222 "Rev": "1cd8009604ec2238b5a71305a0ecd974066e0e16"
223 },
305 - {
306 - "ImportPath": "github.com/whyrusleeping/go-multiplex",
307 - "Rev": "474b9aebeb391746f304ddf7c764a5da12319857"
308 - },
309 - {
310 - "ImportPath": "github.com/whyrusleeping/go-multistream",
311 - "Rev": "31bb014803a6eba2261bda5593e42c016a5f33bb"
312 - },
224 {
225 "ImportPath": "github.com/whyrusleeping/go-sysinfo",
226 "Rev": "769b7c0b50e8030895abc74ba8107ac715e3162a"
Godeps/_workspace/src/github.com/anacrolix/jitter/jitter.go deleted
-12
@@ -1,12 +0,0 @@
1 -package jitter
2 -
3 -import (
4 - "math/rand"
5 - "time"
6 -)
7 -
8 -func Duration(average, plusMinus time.Duration) (ret time.Duration) {
9 - ret = average - plusMinus
10 - ret += time.Duration(rand.Int63n(2*int64(plusMinus) + 1))
11 - return
12 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/addr.go deleted
-72
@@ -1,72 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "net"
5 - "strconv"
6 - "strings"
7 -)
8 -
9 -type HostMaybePort struct {
10 - Host string
11 - Port int
12 - NoPort bool
13 -}
14 -
15 -func (me HostMaybePort) String() string {
16 - if me.NoPort {
17 - return me.Host
18 - }
19 - return net.JoinHostPort(me.Host, strconv.FormatInt(int64(me.Port), 10))
20 -}
21 -
22 -func SplitHostPort(hostport string) (ret HostMaybePort) {
23 - host, port, err := net.SplitHostPort(hostport)
24 - if err != nil {
25 - if strings.Contains(err.Error(), "missing port") {
26 - ret.Host = hostport
27 - ret.NoPort = true
28 - return
29 - }
30 - panic(err)
31 - }
32 - i64, err := strconv.ParseInt(port, 0, 0)
33 - ret.Host = host
34 - ret.Port = int(i64)
35 - if err != nil {
36 - ret.NoPort = true
37 - }
38 - return
39 -}
40 -
41 -// Extracts the port as an integer from an address string.
42 -func AddrPort(addr net.Addr) int {
43 - switch raw := addr.(type) {
44 - case *net.UDPAddr:
45 - return raw.Port
46 - default:
47 - _, port, err := net.SplitHostPort(addr.String())
48 - if err != nil {
49 - panic(err)
50 - }
51 - i64, err := strconv.ParseInt(port, 0, 0)
52 - if err != nil {
53 - panic(err)
54 - }
55 - return int(i64)
56 - }
57 -}
58 -
59 -func AddrIP(addr net.Addr) net.IP {
60 - switch raw := addr.(type) {
61 - case *net.UDPAddr:
62 - return raw.IP
63 - case *net.TCPAddr:
64 - return raw.IP
65 - default:
66 - host, _, err := net.SplitHostPort(addr.String())
67 - if err != nil {
68 - panic(err)
69 - }
70 - return net.ParseIP(host)
71 - }
72 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/addr_test.go deleted
-17
@@ -1,17 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "testing"
5 -
6 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/assert"
7 -)
8 -
9 -func TestSplitHostPort(t *testing.T) {
10 - assert.EqualValues(t, HostMaybePort{"a", 1, false}, SplitHostPort("a:1"))
11 - assert.EqualValues(t, HostMaybePort{"a", 0, true}, SplitHostPort("a"))
12 -}
13 -
14 -func TestHostMaybePortString(t *testing.T) {
15 - assert.EqualValues(t, "a:1", (HostMaybePort{"a", 1, false}).String())
16 - assert.EqualValues(t, "a", (HostMaybePort{"a", 0, true}).String())
17 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/args/args.go deleted
-15
@@ -1,15 +0,0 @@
1 -package args
2 -
3 -import (
4 - "flag"
5 - "fmt"
6 - "os"
7 -)
8 -
9 -func Parse() {
10 - flag.Parse()
11 - if flag.NArg() != 0 {
12 - fmt.Fprintf(os.Stderr, "unexpected positional arguments\n")
13 - os.Exit(2)
14 - }
15 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/atime.go deleted
-11
@@ -1,11 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "os"
5 - "time"
6 -)
7 -
8 -// Extracts the access time from the FileInfo internals.
9 -func FileInfoAccessTime(fi os.FileInfo) time.Time {
10 - return fileInfoAccessTime(fi)
11 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_darwin.go deleted
-12
@@ -1,12 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "os"
5 - "syscall"
6 - "time"
7 -)
8 -
9 -func fileInfoAccessTime(fi os.FileInfo) time.Time {
10 - ts := fi.Sys().(*syscall.Stat_t).Atimespec
11 - return time.Unix(int64(ts.Sec), int64(ts.Nsec))
12 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_freebsd.go deleted
-12
@@ -1,12 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "os"
5 - "syscall"
6 - "time"
7 -)
8 -
9 -func fileInfoAccessTime(fi os.FileInfo) time.Time {
10 - ts := fi.Sys().(*syscall.Stat_t).Atimespec
11 - return time.Unix(int64(ts.Sec), int64(ts.Nsec))
12 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_linux.go deleted
-12
@@ -1,12 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "os"
5 - "syscall"
6 - "time"
7 -)
8 -
9 -func fileInfoAccessTime(fi os.FileInfo) time.Time {
10 - ts := fi.Sys().(*syscall.Stat_t).Atim
11 - return time.Unix(int64(ts.Sec), int64(ts.Nsec))
12 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_windows.go deleted
-12
@@ -1,12 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "os"
5 - "syscall"
6 - "time"
7 -)
8 -
9 -func fileInfoAccessTime(fi os.FileInfo) time.Time {
10 - ts := fi.Sys().(syscall.Win32FileAttributeData).LastAccessTime
11 - return time.Unix(0, int64(ts.Nanoseconds()))
12 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/castslice.go deleted
-17
@@ -1,17 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "reflect"
5 -
6 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/bradfitz/iter"
7 -)
8 -
9 -func ConvertToSliceOfEmptyInterface(slice interface{}) (ret []interface{}) {
10 - v := reflect.ValueOf(slice)
11 - l := v.Len()
12 - ret = make([]interface{}, 0, l)
13 - for i := range iter.N(v.Len()) {
14 - ret = append(ret, v.Index(i).Interface())
15 - }
16 - return
17 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/go-env/main.go deleted
-12
@@ -1,12 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 - "os"
6 -)
7 -
8 -func main() {
9 - for _, v := range os.Environ() {
10 - fmt.Printf("%s\n", v)
11 - }
12 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/nop/main.go deleted
-3
@@ -1,3 +0,0 @@
1 -package main
2 -
3 -func main() {}
Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-escape/main.go deleted
-11
@@ -1,11 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 - "net/url"
6 - "os"
7 -)
8 -
9 -func main() {
10 - fmt.Println(url.QueryEscape(os.Args[1]))
11 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-unescape/main.go deleted
-11
@@ -1,11 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 - "net/url"
6 - "os"
7 -)
8 -
9 -func main() {
10 - fmt.Println(url.QueryUnescape(os.Args[1]))
11 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/copy.go deleted
-32
@@ -1,32 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "fmt"
5 - "reflect"
6 -)
7 -
8 -func CopyExact(dest interface{}, src interface{}) {
9 - dV := reflect.ValueOf(dest)
10 - sV := reflect.ValueOf(src)
11 - if dV.Kind() == reflect.Ptr {
12 - dV = dV.Elem()
13 - }
14 - if dV.Kind() == reflect.Array && !dV.CanAddr() {
15 - panic(fmt.Sprintf("dest not addressable: %T", dest))
16 - }
17 - if sV.Kind() == reflect.Ptr {
18 - sV = sV.Elem()
19 - }
20 - if sV.Kind() == reflect.String {
21 - sV = sV.Convert(reflect.SliceOf(dV.Type().Elem()))
22 - }
23 - if !sV.IsValid() {
24 - panic("invalid source, probably nil")
25 - }
26 - if dV.Len() != sV.Len() {
27 - panic(fmt.Sprintf("dest len (%d) != src len (%d)", dV.Len(), sV.Len()))
28 - }
29 - if dV.Len() != reflect.Copy(dV, sV) {
30 - panic("dammit")
31 - }
32 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/copy_test.go deleted
-89
@@ -1,89 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "bytes"
5 - "strings"
6 - "testing"
7 -)
8 -
9 -func TestCopyToArray(t *testing.T) {
10 - var arr [3]byte
11 - bb := []byte{1, 2, 3}
12 - CopyExact(&arr, bb)
13 - if !bytes.Equal(arr[:], bb) {
14 - t.FailNow()
15 - }
16 -}
17 -
18 -func TestCopyToSlicedArray(t *testing.T) {
19 - var arr [5]byte
20 - CopyExact(arr[:], "hello")
21 - if !bytes.Equal(arr[:], []byte("hello")) {
22 - t.FailNow()
23 - }
24 -}
25 -
26 -func TestCopyDestNotAddr(t *testing.T) {
27 - defer func() {
28 - r := recover()
29 - if r == nil {
30 - t.FailNow()
31 - }
32 - t.Log(r)
33 - }()
34 - var arr [3]byte
35 - CopyExact(arr, "nope")
36 -}
37 -
38 -func TestCopyLenMismatch(t *testing.T) {
39 - defer func() {
40 - r := recover()
41 - if r == nil {
42 - t.FailNow()
43 - }
44 - t.Log(r)
45 - }()
46 - CopyExact(make([]byte, 2), "abc")
47 -}
48 -
49 -func TestCopySrcString(t *testing.T) {
50 - dest := make([]byte, 3)
51 - CopyExact(dest, "lol")
52 - if string(dest) != "lol" {
53 - t.FailNow()
54 - }
55 - func() {
56 - defer func() {
57 - r := recover()
58 - if r == nil {
59 - t.FailNow()
60 - }
61 - }()
62 - CopyExact(dest, "rofl")
63 - }()
64 - var arr [5]byte
65 - CopyExact(&arr, interface{}("hello"))
66 - if string(arr[:]) != "hello" {
67 - t.FailNow()
68 - }
69 -}
70 -
71 -func TestCopySrcNilInterface(t *testing.T) {
72 - var arr [3]byte
73 - defer func() {
74 - r := recover().(string)
75 - if !strings.Contains(r, "invalid source") {
76 - t.FailNow()
77 - }
78 - }()
79 - CopyExact(&arr, nil)
80 -}
81 -
82 -func TestCopySrcPtr(t *testing.T) {
83 - var bigDst [1024]byte
84 - var bigSrc [1024]byte = [1024]byte{'h', 'i'}
85 - CopyExact(&bigDst, &bigSrc)
86 - if !bytes.Equal(bigDst[:], bigSrc[:]) {
87 - t.FailNow()
88 - }
89 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/croak.go deleted
-18
@@ -1,18 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "fmt"
5 - "os"
6 -)
7 -
8 -func Unchomp(s string) string {
9 - if len(s) > 0 && s[len(s)-1] == '\n' {
10 - return s
11 - }
12 - return s + "\n"
13 -}
14 -
15 -func Fatal(msg interface{}) {
16 - os.Stderr.WriteString(Unchomp(fmt.Sprint(msg)))
17 - os.Exit(1)
18 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/doc.go deleted
-3
@@ -1,3 +0,0 @@
1 -// Package missinggo contains miscellaneous helpers used in many of anacrolix'
2 -// projects.
3 -package missinggo
Godeps/_workspace/src/github.com/anacrolix/missinggo/expvarIndentMap.go deleted
-35
@@ -1,35 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "bytes"
5 - "expvar"
6 - "fmt"
7 -)
8 -
9 -type IndentMap struct {
10 - expvar.Map
11 -}
12 -
13 -var _ expvar.Var = &IndentMap{}
14 -
15 -func NewExpvarIndentMap(name string) *IndentMap {
16 - v := new(IndentMap)
17 - v.Init()
18 - expvar.Publish(name, v)
19 - return v
20 -}
21 -
22 -func (v *IndentMap) String() string {
23 - var b bytes.Buffer
24 - fmt.Fprintf(&b, "{")
25 - first := true
26 - v.Do(func(kv expvar.KeyValue) {
27 - if !first {
28 - fmt.Fprintf(&b, ",")
29 - }
30 - fmt.Fprintf(&b, "\n\t%q: %v", kv.Key, kv.Value)
31 - first = false
32 - })
33 - fmt.Fprintf(&b, "}")
34 - return b.String()
35 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache.go deleted
-269
@@ -1,269 +0,0 @@
1 -package filecache
2 -
3 -import (
4 - "errors"
5 - "log"
6 - "os"
7 - "path"
8 - "path/filepath"
9 - "sync"
10 - "time"
11 -
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
13 -)
14 -
15 -type Cache struct {
16 - mu sync.Mutex
17 - capacity int64
18 - filled int64
19 - items *lruItems
20 - paths map[string]ItemInfo
21 - root string
22 -}
23 -
24 -type CacheInfo struct {
25 - Capacity int64
26 - Filled int64
27 - NumItems int
28 -}
29 -
30 -type ItemInfo struct {
31 - Accessed time.Time
32 - Size int64
33 - Path string
34 -}
35 -
36 -// Calls the function for every item known to the cache. The ItemInfo should
37 -// not be modified.
38 -func (me *Cache) WalkItems(cb func(ItemInfo)) {
39 - me.mu.Lock()
40 - defer me.mu.Unlock()
41 - for e := me.items.Front(); e != nil; e = e.Next() {
42 - cb(e.Value().(ItemInfo))
43 - }
44 -}
45 -
46 -func (me *Cache) Info() (ret CacheInfo) {
47 - me.mu.Lock()
48 - defer me.mu.Unlock()
49 - ret.Capacity = me.capacity
50 - ret.Filled = me.filled
51 - ret.NumItems = len(me.paths)
52 - return
53 -}
54 -
55 -func (me *Cache) SetCapacity(capacity int64) {
56 - me.mu.Lock()
57 - defer me.mu.Unlock()
58 - me.capacity = capacity
59 -}
60 -
61 -func NewCache(root string) (ret *Cache, err error) {
62 - if !filepath.IsAbs(root) {
63 - err = errors.New("root is not an absolute filepath")
64 - return
65 - }
66 - ret = &Cache{
67 - root: root,
68 - capacity: -1, // unlimited
69 - }
70 - ret.mu.Lock()
71 - go func() {
72 - defer ret.mu.Unlock()
73 - ret.rescan()
74 - }()
75 - return
76 -}
77 -
78 -// An empty return path is an error.
79 -func sanitizePath(p string) (ret string) {
80 - if p == "" {
81 - return
82 - }
83 - ret = path.Clean("/" + p)
84 - if ret[0] == '/' {
85 - ret = ret[1:]
86 - }
87 - return
88 -}
89 -
90 -// Leaf is a descendent of root.
91 -func pruneEmptyDirs(root string, leaf string) (err error) {
92 - rootInfo, err := os.Stat(root)
93 - if err != nil {
94 - return
95 - }
96 - for {
97 - var leafInfo os.FileInfo
98 - leafInfo, err = os.Stat(leaf)
99 - if os.IsNotExist(err) {
100 - goto parent
101 - }
102 - if err != nil {
103 - return
104 - }
105 - if !leafInfo.IsDir() {
106 - return
107 - }
108 - if os.SameFile(rootInfo, leafInfo) {
109 - return
110 - }
111 - if os.Remove(leaf) != nil {
112 - return
113 - }
114 - parent:
115 - leaf = filepath.Dir(leaf)
116 - }
117 -}
118 -
119 -func (me *Cache) Remove(path string) (err error) {
120 - path = sanitizePath(path)
121 - me.mu.Lock()
122 - defer me.mu.Unlock()
123 - err = me.remove(path)
124 - return
125 -}
126 -
127 -var (
128 - ErrBadPath = errors.New("bad path")
129 - ErrIsDir = errors.New("is directory")
130 -)
131 -
132 -func (me *Cache) OpenFile(path string, flag int) (ret *File, err error) {
133 - path = sanitizePath(path)
134 - if path == "" {
135 - err = ErrIsDir
136 - return
137 - }
138 - f, err := os.OpenFile(me.realpath(path), flag, 0644)
139 - if flag&os.O_CREATE != 0 && os.IsNotExist(err) {
140 - os.MkdirAll(me.root, 0755)
141 - os.MkdirAll(filepath.Dir(me.realpath(path)), 0755)
142 - f, err = os.OpenFile(me.realpath(path), flag, 0644)
143 - if err != nil {
144 - me.pruneEmptyDirs(path)
145 - }
146 - }
147 - if err != nil {
148 - return
149 - }
150 - ret = &File{
151 - c: me,
152 - path: path,
153 - f: f,
154 - }
155 - me.mu.Lock()
156 - go func() {
157 - defer me.mu.Unlock()
158 - me.statItem(path, time.Now())
159 - }()
160 - return
161 -}
162 -
163 -func (me *Cache) rescan() {
164 - me.filled = 0
165 - me.items = newLRUItems()
166 - me.paths = make(map[string]ItemInfo)
167 - err := filepath.Walk(me.root, func(path string, info os.FileInfo, err error) error {
168 - if os.IsNotExist(err) {
169 - return nil
170 - }
171 - if err != nil {
172 - return err
173 - }
174 - if info.IsDir() {
175 - return nil
176 - }
177 - path, err = filepath.Rel(me.root, path)
178 - if err != nil {
179 - log.Print(err)
180 - return nil
181 - }
182 - me.statItem(path, time.Time{})
183 - return nil
184 - })
185 - if err != nil {
186 - panic(err)
187 - }
188 -}
189 -
190 -func (me *Cache) insertItem(i ItemInfo) {
191 - me.items.Insert(i)
192 -}
193 -
194 -func (me *Cache) removeInfo(path string) (ret ItemInfo, ok bool) {
195 - ret, ok = me.paths[path]
196 - if !ok {
197 - return
198 - }
199 - if !me.items.Remove(ret) {
200 - panic(ret)
201 - }
202 - me.filled -= ret.Size
203 - delete(me.paths, path)
204 - return
205 -}
206 -
207 -// Triggers the item for path to be updated. If access is non-zero, set the
208 -// item's access time to that value, otherwise deduce it appropriately.
209 -func (me *Cache) statItem(path string, access time.Time) {
210 - info, ok := me.removeInfo(path)
211 - fi, err := os.Stat(me.realpath(path))
212 - if os.IsNotExist(err) {
213 - return
214 - }
215 - if err != nil {
216 - panic(err)
217 - }
218 - if !ok {
219 - info.Path = path
220 - }
221 - if !access.IsZero() {
222 - info.Accessed = access
223 - }
224 - if info.Accessed.IsZero() {
225 - info.Accessed = missinggo.FileInfoAccessTime(fi)
226 - }
227 - info.Size = fi.Size()
228 - me.filled += info.Size
229 - me.insertItem(info)
230 - me.paths[path] = info
231 -}
232 -
233 -func (me *Cache) realpath(path string) string {
234 - return filepath.Join(me.root, filepath.FromSlash(path))
235 -}
236 -
237 -func (me *Cache) TrimToCapacity() {
238 - me.mu.Lock()
239 - defer me.mu.Unlock()
240 - me.trimToCapacity()
241 -}
242 -
243 -func (me *Cache) pruneEmptyDirs(path string) {
244 - pruneEmptyDirs(me.root, me.realpath(path))
245 -}
246 -
247 -func (me *Cache) remove(path string) (err error) {
248 - err = os.Remove(me.realpath(path))
249 - if os.IsNotExist(err) {
250 - err = nil
251 - }
252 - me.pruneEmptyDirs(path)
253 - me.removeInfo(path)
254 - return
255 -}
256 -
257 -func (me *Cache) trimToCapacity() {
258 - if me.capacity < 0 {
259 - return
260 - }
261 - for me.filled > me.capacity {
262 - item := me.items.LRU()
263 - me.remove(item.Path)
264 - }
265 -}
266 -
267 -func (me *Cache) pathInfo(p string) ItemInfo {
268 - return me.paths[p]
269 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache_test.go deleted
-84
@@ -1,84 +0,0 @@
1 -package filecache
2 -
3 -import (
4 - "io"
5 - "io/ioutil"
6 - "os"
7 - "path/filepath"
8 - "testing"
9 -
10 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/assert"
11 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/require"
12 -
13 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
14 -)
15 -
16 -func TestCache(t *testing.T) {
17 - td, err := ioutil.TempDir("", "gotest")
18 - if err != nil {
19 - t.Fatal(err)
20 - }
21 - defer os.RemoveAll(td)
22 - c, err := NewCache(filepath.Join(td, "cache"))
23 - if err != nil {
24 - t.Fatal(err)
25 - }
26 - assert.EqualValues(t, 0, c.Info().Filled)
27 - c.WalkItems(func(i ItemInfo) {})
28 - _, err = c.OpenFile("/", os.O_CREATE)
29 - assert.NotNil(t, err)
30 - _, err = c.OpenFile("", os.O_CREATE)
31 - assert.NotNil(t, err)
32 - c.WalkItems(func(i ItemInfo) {})
33 - require.Equal(t, 0, c.Info().NumItems)
34 - _, err = c.OpenFile("notexist", 0)
35 - assert.True(t, os.IsNotExist(err), err)
36 - _, err = c.OpenFile("/notexist", 0)
37 - assert.True(t, os.IsNotExist(err), err)
38 - _, err = c.OpenFile("/dir/notexist", 0)
39 - assert.True(t, os.IsNotExist(err), err)
40 - f, err := c.OpenFile("dir/blah", os.O_CREATE)
41 - require.NoError(t, err)
42 - defer f.Close()
43 - c.WalkItems(func(i ItemInfo) {})
44 - assert.True(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("cache/dir/blah"))))
45 - assert.True(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("cache/dir/"))))
46 - assert.Equal(t, 1, c.Info().NumItems)
47 - f.Remove()
48 - assert.False(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("dir/blah"))))
49 - assert.False(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("dir/"))))
50 - _, err = f.Read(nil)
51 - assert.NotEqual(t, io.EOF, err)
52 - a, err := c.OpenFile("/a", os.O_CREATE|os.O_WRONLY)
53 - defer a.Close()
54 - require.Nil(t, err)
55 - b, err := c.OpenFile("b", os.O_CREATE|os.O_WRONLY)
56 - defer b.Close()
57 - require.Nil(t, err)
58 - c.mu.Lock()
59 - assert.True(t, c.pathInfo("a").Accessed.Before(c.pathInfo("b").Accessed))
60 - c.mu.Unlock()
61 - n, err := a.Write([]byte("hello"))
62 - assert.Nil(t, err)
63 - assert.EqualValues(t, 5, n)
64 - assert.EqualValues(t, 5, c.Info().Filled)
65 - assert.True(t, c.pathInfo("b").Accessed.Before(c.pathInfo("a").Accessed))
66 - c.SetCapacity(5)
67 - n, err = a.Write([]byte(" world"))
68 - assert.NotNil(t, err)
69 - _, err = b.Write([]byte("boom!"))
70 - // "a" and "b" have been evicted.
71 - assert.NotNil(t, err)
72 - assert.EqualValues(t, 0, c.Info().Filled)
73 - assert.EqualValues(t, 0, c.Info().NumItems)
74 - _, err = a.Seek(0, os.SEEK_SET)
75 - assert.NotNil(t, err)
76 -}
77 -
78 -func TestSanitizePath(t *testing.T) {
79 - assert.Equal(t, "", sanitizePath("////"))
80 - assert.Equal(t, "", sanitizePath("/../.."))
81 - assert.Equal(t, "a", sanitizePath("/a//b/.."))
82 - assert.Equal(t, "a", sanitizePath("../a"))
83 - assert.Equal(t, "a", sanitizePath("./a"))
84 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/file.go deleted
-117
@@ -1,117 +0,0 @@
1 -package filecache
2 -
3 -import (
4 - "errors"
5 - "math"
6 - "os"
7 - "sync"
8 - "time"
9 -)
10 -
11 -type File struct {
12 - mu sync.Mutex
13 - c *Cache
14 - path string
15 - f *os.File
16 - gone bool
17 -}
18 -
19 -func (me *File) Remove() (err error) {
20 - return me.c.Remove(me.path)
21 -}
22 -
23 -func (me *File) Seek(offset int64, whence int) (ret int64, err error) {
24 - ret, err = me.f.Seek(offset, whence)
25 - return
26 -}
27 -
28 -func (me *File) maxWrite() (max int64, err error) {
29 - if me.c.capacity < 0 {
30 - max = math.MaxInt64
31 - return
32 - }
33 - pos, err := me.Seek(0, os.SEEK_CUR)
34 - if err != nil {
35 - return
36 - }
37 - max = me.c.capacity - pos
38 - if max < 0 {
39 - max = 0
40 - }
41 - return
42 -}
43 -
44 -var (
45 - ErrFileTooLarge = errors.New("file too large for cache")
46 - ErrFileDisappeared = errors.New("file disappeared")
47 -)
48 -
49 -func (me *File) checkGone() {
50 - if me.gone {
51 - return
52 - }
53 - ffi, _ := me.Stat()
54 - fsfi, _ := os.Stat(me.c.realpath(me.path))
55 - me.gone = !os.SameFile(ffi, fsfi)
56 -}
57 -
58 -func (me *File) goneErr() error {
59 - me.mu.Lock()
60 - defer me.mu.Unlock()
61 - me.checkGone()
62 - if me.gone {
63 - me.f.Close()
64 - return ErrFileDisappeared
65 - }
66 - return nil
67 -}
68 -
69 -func (me *File) Write(b []byte) (n int, err error) {
70 - err = me.goneErr()
71 - if err != nil {
72 - return
73 - }
74 - n, err = me.f.Write(b)
75 - me.c.mu.Lock()
76 - me.c.statItem(me.path, time.Now())
77 - me.c.trimToCapacity()
78 - me.c.mu.Unlock()
79 - if err == nil {
80 - err = me.goneErr()
81 - }
82 - return
83 -}
84 -
85 -func (me *File) Close() error {
86 - return me.f.Close()
87 -}
88 -
89 -func (me *File) Stat() (os.FileInfo, error) {
90 - return me.f.Stat()
91 -}
92 -
93 -func (me *File) Read(b []byte) (n int, err error) {
94 - err = me.goneErr()
95 - if err != nil {
96 - return
97 - }
98 - defer func() {
99 - me.c.mu.Lock()
100 - defer me.c.mu.Unlock()
101 - me.c.statItem(me.path, time.Now())
102 - }()
103 - return me.f.Read(b)
104 -}
105 -
106 -func (me *File) ReadAt(b []byte, off int64) (n int, err error) {
107 - err = me.goneErr()
108 - if err != nil {
109 - return
110 - }
111 - defer func() {
112 - me.c.mu.Lock()
113 - defer me.c.mu.Unlock()
114 - me.c.statItem(me.path, time.Now())
115 - }()
116 - return me.f.ReadAt(b, off)
117 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems.go deleted
-94
@@ -1,94 +0,0 @@
1 -package filecache
2 -
3 -import (
4 - "container/list"
5 - "io"
6 -
7 - "gx/ipfs/QmVgtwPh2NNoZTSyYkr4Y3epaYACBKf26r8hV6EFA7xS6c/b"
8 -)
9 -
10 -type Iterator interface {
11 - Next() Iterator
12 - Value() interface{}
13 -}
14 -
15 -type listElementIterator struct {
16 - le *list.Element
17 -}
18 -
19 -func (me listElementIterator) Next() Iterator {
20 - e := me.le.Next()
21 - if e == nil {
22 - return nil
23 - }
24 - return listElementIterator{e}
25 -}
26 -
27 -func (me listElementIterator) Value() interface{} {
28 - return me.le.Value
29 -}
30 -
31 -func newLRUItems() *lruItems {
32 - return &lruItems{b.TreeNew(func(_a, _b interface{}) int {
33 - a := _a.(ItemInfo)
34 - b := _b.(ItemInfo)
35 - if a.Accessed != b.Accessed {
36 - if a.Accessed.Before(b.Accessed) {
37 - return -1
38 - } else {
39 - return 1
40 - }
41 - }
42 - if a.Path == b.Path {
43 - return 0
44 - }
45 - if a.Path < b.Path {
46 - return -1
47 - }
48 - return 1
49 - })}
50 -}
51 -
52 -type lruItems struct {
53 - tree *b.Tree
54 -}
55 -
56 -type bEnumeratorIterator struct {
57 - e *b.Enumerator
58 - v ItemInfo
59 -}
60 -
61 -func (me bEnumeratorIterator) Next() Iterator {
62 - _, v, err := me.e.Next()
63 - if err == io.EOF {
64 - return nil
65 - }
66 - return bEnumeratorIterator{me.e, v.(ItemInfo)}
67 -}
68 -
69 -func (me bEnumeratorIterator) Value() interface{} {
70 - return me.v
71 -}
72 -
73 -func (me *lruItems) Front() Iterator {
74 - e, _ := me.tree.SeekFirst()
75 - if e == nil {
76 - return nil
77 - }
78 - return bEnumeratorIterator{
79 - e: e,
80 - }.Next()
81 -}
82 -
83 -func (me *lruItems) LRU() ItemInfo {
84 - _, v := me.tree.First()
85 - return v.(ItemInfo)
86 -}
87 -
88 -func (me *lruItems) Insert(ii ItemInfo) {
89 - me.tree.Set(ii, ii)
90 -}
91 -
92 -func (me *lruItems) Remove(ii ItemInfo) bool {
93 - return me.tree.Delete(ii)
94 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems_test.go deleted
-22
@@ -1,22 +0,0 @@
1 -package filecache
2 -
3 -import (
4 - "math/rand"
5 - "testing"
6 - "time"
7 -
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/bradfitz/iter"
9 -)
10 -
11 -func BenchmarkInsert(b *testing.B) {
12 - for range iter.N(b.N) {
13 - li := newLRUItems()
14 - for range iter.N(10000) {
15 - r := rand.Int63()
16 - t := time.Unix(r/1e9, r%1e9)
17 - li.Insert(ItemInfo{
18 - Accessed: t,
19 - })
20 - }
21 - }
22 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange.go deleted
-38
@@ -1,38 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "regexp"
5 - "strconv"
6 -)
7 -
8 -type HTTPBytesContentRange struct {
9 - First, Last, Length int64
10 -}
11 -
12 -var bytesContentRangeRegexp = regexp.MustCompile(`bytes[ =](\d+)-(\d+)/(\d+|\*)`)
13 -
14 -func ParseHTTPBytesContentRange(s string) (ret HTTPBytesContentRange, ok bool) {
15 - ss := bytesContentRangeRegexp.FindStringSubmatch(s)
16 - if ss == nil {
17 - return
18 - }
19 - var err error
20 - ret.First, err = strconv.ParseInt(ss[1], 10, 64)
21 - if err != nil {
22 - return
23 - }
24 - ret.Last, err = strconv.ParseInt(ss[2], 10, 64)
25 - if err != nil {
26 - return
27 - }
28 - if ss[3] == "*" {
29 - ret.Length = -1
30 - } else {
31 - ret.Length, err = strconv.ParseInt(ss[3], 10, 64)
32 - if err != nil {
33 - return
34 - }
35 - }
36 - ok = true
37 - return
38 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange_test.go deleted
-27
@@ -1,27 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "testing"
5 -
6 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/assert"
7 -)
8 -
9 -func TestParseHTTPContentRange(t *testing.T) {
10 - for _, _case := range []struct {
11 - h string
12 - cr *HTTPBytesContentRange
13 - }{
14 - {"", nil},
15 - {"1-2/*", nil},
16 - {"bytes=1-2/3", &HTTPBytesContentRange{1, 2, 3}},
17 - {"bytes=12-34/*", &HTTPBytesContentRange{12, 34, -1}},
18 - {" bytes=12-34/*", &HTTPBytesContentRange{12, 34, -1}},
19 - {" bytes 12-34/56", &HTTPBytesContentRange{12, 34, 56}},
20 - } {
21 - ret, ok := ParseHTTPBytesContentRange(_case.h)
22 - assert.Equal(t, _case.cr != nil, ok)
23 - if _case.cr != nil {
24 - assert.Equal(t, *_case.cr, ret)
25 - }
26 - }
27 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/httpfile/httpfile.go deleted
-222
@@ -1,222 +0,0 @@
1 -package httpfile
2 -
3 -import (
4 - "bytes"
5 - "errors"
6 - "fmt"
7 - "io"
8 - "net/http"
9 - "os"
10 - "strconv"
11 -
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
13 -)
14 -
15 -type File struct {
16 - off int64
17 - r io.ReadCloser
18 - rOff int64
19 - length int64
20 - url string
21 -}
22 -
23 -func OpenSectionReader(url string, off, n int64) (ret io.ReadCloser, err error) {
24 - req, err := http.NewRequest("GET", url, nil)
25 - if err != nil {
26 - return
27 - }
28 - req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", off, off+n-1))
29 - resp, err := http.DefaultClient.Do(req)
30 - if err != nil {
31 - return
32 - }
33 - if resp.StatusCode == http.StatusNotFound {
34 - err = ErrNotFound
35 - resp.Body.Close()
36 - return
37 - }
38 - if resp.StatusCode != http.StatusPartialContent {
39 - err = fmt.Errorf("bad response status: %s", resp.Status)
40 - resp.Body.Close()
41 - return
42 - }
43 - ret = resp.Body
44 - return
45 -}
46 -
47 -func Open(url string) *File {
48 - return &File{
49 - url: url,
50 - }
51 -}
52 -
53 -func (me *File) prepareReader() (err error) {
54 - if me.r != nil && me.off != me.rOff {
55 - me.r.Close()
56 - me.r = nil
57 - }
58 - if me.r != nil {
59 - return nil
60 - }
61 - req, err := http.NewRequest("GET", me.url, nil)
62 - if err != nil {
63 - return
64 - }
65 - if me.off != 0 {
66 - req.Header.Set("Range", fmt.Sprintf("bytes=%d-", me.off))
67 - }
68 - resp, err := http.DefaultClient.Do(req)
69 - if err != nil {
70 - return
71 - }
72 - switch resp.StatusCode {
73 - case http.StatusPartialContent:
74 - cr, ok := missinggo.ParseHTTPBytesContentRange(resp.Header.Get("Content-Range"))
75 - if !ok || cr.First != me.off {
76 - err = errors.New("bad response")
77 - resp.Body.Close()
78 - return
79 - }
80 - me.length = cr.Length
81 - case http.StatusOK:
82 - if me.off != 0 {
83 - err = errors.New("bad response")
84 - resp.Body.Close()
85 - return
86 - }
87 - if h := resp.Header.Get("Content-Length"); h != "" {
88 - var cl uint64
89 - cl, err = strconv.ParseUint(h, 10, 64)
90 - if err != nil {
91 - resp.Body.Close()
92 - return
93 - }
94 - me.length = int64(cl)
95 - }
96 - default:
97 - err = errors.New(resp.Status)
98 - resp.Body.Close()
99 - return
100 - }
101 - me.r = resp.Body
102 - me.rOff = me.off
103 - return
104 -}
105 -
106 -func (me *File) Read(b []byte) (n int, err error) {
107 - err = me.prepareReader()
108 - if err != nil {
109 - return
110 - }
111 - n, err = me.r.Read(b)
112 - me.off += int64(n)
113 - me.rOff += int64(n)
114 - return
115 -}
116 -
117 -func instanceLength(r *http.Response) (int64, error) {
118 - switch r.StatusCode {
119 - case http.StatusOK:
120 - if h := r.Header.Get("Content-Length"); h != "" {
121 - return strconv.ParseInt(h, 10, 64)
122 - } else {
123 - return -1, nil
124 - }
125 - case http.StatusPartialContent:
126 - cr, ok := missinggo.ParseHTTPBytesContentRange(r.Header.Get("Content-Range"))
127 - if !ok {
128 - return -1, errors.New("bad 206 response")
129 - }
130 - return cr.Length, nil
131 - default:
132 - return -1, errors.New(r.Status)
133 - }
134 -}
135 -
136 -func (me *File) Seek(offset int64, whence int) (ret int64, err error) {
137 - switch whence {
138 - case os.SEEK_SET:
139 - ret = offset
140 - case os.SEEK_CUR:
141 - ret = me.off + offset
142 - case os.SEEK_END:
143 - if me.length < 0 {
144 - err = errors.New("length unknown")
145 - return
146 - }
147 - ret = me.length + offset
148 - default:
149 - err = fmt.Errorf("unhandled whence: %d", whence)
150 - return
151 - }
152 - me.off = ret
153 - return
154 -}
155 -
156 -func (me *File) Write(b []byte) (n int, err error) {
157 - req, err := http.NewRequest("PATCH", me.url, bytes.NewReader(b))
158 - if err != nil {
159 - return
160 - }
161 - req.Header.Set("Content-Range", fmt.Sprintf("bytes=%d-", me.off))
162 - req.ContentLength = int64(len(b))
163 - resp, err := http.DefaultClient.Do(req)
164 - if err != nil {
165 - return
166 - }
167 - resp.Body.Close()
168 - if resp.StatusCode != http.StatusPartialContent {
169 - err = errors.New(resp.Status)
170 - return
171 - }
172 - n = len(b)
173 - me.off += int64(n)
174 - return
175 -}
176 -
177 -var (
178 - ErrNotFound = errors.New("not found")
179 -)
180 -
181 -// Returns the length of the resource in bytes.
182 -func GetLength(url string) (ret int64, err error) {
183 - resp, err := http.Head(url)
184 - if err != nil {
185 - return
186 - }
187 - resp.Body.Close()
188 - if resp.StatusCode == http.StatusNotFound {
189 - err = ErrNotFound
190 - return
191 - }
192 - return instanceLength(resp)
193 -}
194 -
195 -func (me *File) Close() error {
196 - me.url = ""
197 - if me.r != nil {
198 - me.r.Close()
199 - me.r = nil
200 - }
201 - return nil
202 -}
203 -
204 -func Delete(urlStr string) (err error) {
205 - req, err := http.NewRequest("DELETE", urlStr, nil)
206 - if err != nil {
207 - return
208 - }
209 - resp, err := http.DefaultClient.Do(req)
210 - if err != nil {
211 - return
212 - }
213 - resp.Body.Close()
214 - if resp.StatusCode == http.StatusNotFound {
215 - err = ErrNotFound
216 - return
217 - }
218 - if resp.StatusCode != 200 {
219 - err = fmt.Errorf("response: %s", resp.Status)
220 - }
221 - return
222 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/httpgzip.go deleted
-47
@@ -1,47 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "compress/gzip"
5 - "io"
6 - "net/http"
7 - "strings"
8 -)
9 -
10 -type gzipResponseWriter struct {
11 - io.Writer
12 - http.ResponseWriter
13 - haveWritten bool
14 -}
15 -
16 -func (w *gzipResponseWriter) Write(b []byte) (int, error) {
17 - if w.haveWritten {
18 - goto write
19 - }
20 - w.haveWritten = true
21 - if w.Header().Get("Content-Type") != "" {
22 - goto write
23 - }
24 - if type_ := http.DetectContentType(b); type_ != "application/octet-stream" {
25 - w.Header().Set("Content-Type", type_)
26 - }
27 -write:
28 - return w.Writer.Write(b)
29 -}
30 -
31 -// Gzips response body if the request says it'll allow it.
32 -func GzipHTTPHandler(h http.Handler) http.Handler {
33 - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
34 - if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") || w.Header().Get("Content-Encoding") != "" || w.Header().Get("Vary") != "" {
35 - h.ServeHTTP(w, r)
36 - return
37 - }
38 - w.Header().Set("Content-Encoding", "gzip")
39 - w.Header().Set("Vary", "Accept-Encoding")
40 - gz := gzip.NewWriter(w)
41 - defer gz.Close()
42 - h.ServeHTTP(&gzipResponseWriter{
43 - Writer: gz,
44 - ResponseWriter: w,
45 - }, r)
46 - })
47 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/httpresponsestatus.go deleted
-60
@@ -1,60 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "bufio"
5 - "io"
6 - "net"
7 - "net/http"
8 -)
9 -
10 -// A http.ResponseWriter that tracks the status of the response. The status
11 -// code, and number of bytes written for example.
12 -type StatusResponseWriter struct {
13 - RW http.ResponseWriter
14 - Code int
15 - BytesWritten int64
16 -}
17 -
18 -var _ http.ResponseWriter = &StatusResponseWriter{}
19 -
20 -func (me *StatusResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
21 - return me.RW.(http.Hijacker).Hijack()
22 -}
23 -
24 -func (me *StatusResponseWriter) CloseNotify() <-chan bool {
25 - return me.RW.(http.CloseNotifier).CloseNotify()
26 -}
27 -
28 -func (me *StatusResponseWriter) Flush() {
29 - me.RW.(http.Flusher).Flush()
30 -}
31 -
32 -func (me *StatusResponseWriter) Header() http.Header {
33 - return me.RW.Header()
34 -}
35 -
36 -func (me *StatusResponseWriter) Write(b []byte) (n int, err error) {
37 - if me.Code == 0 {
38 - me.Code = 200
39 - }
40 - n, err = me.RW.Write(b)
41 - me.BytesWritten += int64(n)
42 - return
43 -}
44 -
45 -func (me *StatusResponseWriter) WriteHeader(code int) {
46 - me.RW.WriteHeader(code)
47 - me.Code = code
48 -}
49 -
50 -type ReaderFromStatusResponseWriter struct {
51 - StatusResponseWriter
52 - io.ReaderFrom
53 -}
54 -
55 -func NewReaderFromStatusResponseWriter(w http.ResponseWriter) *ReaderFromStatusResponseWriter {
56 - return &ReaderFromStatusResponseWriter{
57 - StatusResponseWriter{RW: w},
58 - w.(io.ReaderFrom),
59 - }
60 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby.go deleted
-81
@@ -1,81 +0,0 @@
1 -package itertools
2 -
3 -type groupBy struct {
4 - curKey interface{}
5 - curKeyOk bool
6 - curValue interface{}
7 - keyFunc func(interface{}) interface{}
8 - input Iterator
9 - groupKey interface{}
10 - groupKeyOk bool
11 -}
12 -
13 -type Group interface {
14 - Iterator
15 - Key() interface{}
16 -}
17 -
18 -type group struct {
19 - gb *groupBy
20 - key interface{}
21 - first bool
22 -}
23 -
24 -func (me *group) Next() (ok bool) {
25 - if me.first {
26 - me.first = false
27 - return true
28 - }
29 - me.gb.advance()
30 - if !me.gb.curKeyOk || me.gb.curKey != me.key {
31 - return
32 - }
33 - ok = true
34 - return
35 -}
36 -
37 -func (me group) Value() (ret interface{}) {
38 - ret = me.gb.curValue
39 - return
40 -}
41 -
42 -func (me group) Key() interface{} {
43 - return me.key
44 -}
45 -
46 -func (me *groupBy) advance() {
47 - me.curKeyOk = me.input.Next()
48 - if me.curKeyOk {
49 - me.curValue = me.input.Value()
50 - me.curKey = me.keyFunc(me.curValue)
51 - }
52 -}
53 -
54 -func (me *groupBy) Next() (ok bool) {
55 - for me.curKey == me.groupKey {
56 - ok = me.input.Next()
57 - if !ok {
58 - return
59 - }
60 - me.curValue = me.input.Value()
61 - me.curKey = me.keyFunc(me.curValue)
62 - me.curKeyOk = true
63 - }
64 - me.groupKey = me.curKey
65 - me.groupKeyOk = true
66 - return true
67 -}
68 -
69 -func (me *groupBy) Value() (ret interface{}) {
70 - return &group{me, me.groupKey, true}
71 -}
72 -
73 -func GroupBy(input Iterator, keyFunc func(interface{}) interface{}) Iterator {
74 - if keyFunc == nil {
75 - keyFunc = func(a interface{}) interface{} { return a }
76 - }
77 - return &groupBy{
78 - input: input,
79 - keyFunc: keyFunc,
80 - }
81 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby_test.go deleted
-31
@@ -1,31 +0,0 @@
1 -package itertools
2 -
3 -import (
4 - "testing"
5 -
6 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/require"
7 -)
8 -
9 -func TestGroupByKey(t *testing.T) {
10 - var ks []byte
11 - gb := GroupBy(StringIterator("AAAABBBCCDAABBB"), nil)
12 - for gb.Next() {
13 - ks = append(ks, gb.Value().(Group).Key().(byte))
14 - }
15 - t.Log(ks)
16 - require.EqualValues(t, "ABCDAB", ks)
17 -}
18 -
19 -func TestGroupByList(t *testing.T) {
20 - var gs []string
21 - gb := GroupBy(StringIterator("AAAABBBCCD"), nil)
22 - for gb.Next() {
23 - i := gb.Value().(Iterator)
24 - var g string
25 - for i.Next() {
26 - g += string(i.Value().(byte))
27 - }
28 - gs = append(gs, g)
29 - }
30 - t.Log(gs)
31 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator.go deleted
-41
@@ -1,41 +0,0 @@
1 -package itertools
2 -
3 -import "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
4 -
5 -type Iterator interface {
6 - Next() bool
7 - Value() interface{}
8 -}
9 -
10 -type sliceIterator struct {
11 - slice []interface{}
12 - value interface{}
13 - ok bool
14 -}
15 -
16 -func (me *sliceIterator) Next() bool {
17 - if len(me.slice) == 0 {
18 - return false
19 - }
20 - me.value = me.slice[0]
21 - me.slice = me.slice[1:]
22 - me.ok = true
23 - return true
24 -}
25 -
26 -func (me *sliceIterator) Value() interface{} {
27 - if !me.ok {
28 - panic("no value; call Next")
29 - }
30 - return me.value
31 -}
32 -
33 -func SliceIterator(a []interface{}) Iterator {
34 - return &sliceIterator{
35 - slice: a,
36 - }
37 -}
38 -
39 -func StringIterator(a string) Iterator {
40 - return SliceIterator(missinggo.ConvertToSliceOfEmptyInterface(a))
41 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator_test.go deleted
-17
@@ -1,17 +0,0 @@
1 -package itertools
2 -
3 -import (
4 - "testing"
5 -
6 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/require"
7 -)
8 -
9 -func TestIterator(t *testing.T) {
10 - const s = "AAAABBBCCDAABBB"
11 - si := StringIterator(s)
12 - for i := range s {
13 - require.True(t, si.Next())
14 - require.Equal(t, s[i], si.Value().(byte))
15 - }
16 - require.False(t, si.Next())
17 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/net.go deleted
-26
@@ -1,26 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "net"
5 -)
6 -
7 -type HostPort struct {
8 - Host string // Just the host, with no port.
9 - Port string // May be empty if no port was given.
10 - Err error // The error returned from net.SplitHostPort.
11 -}
12 -
13 -// Parse a "hostport" string, a concept that floats around the stdlib a lot
14 -// and is painful to work with. If no port is present, what's usually present
15 -// is just the host.
16 -func ParseHostPort(hostPort string) (ret HostPort) {
17 - ret.Host, ret.Port, ret.Err = net.SplitHostPort(hostPort)
18 - if ret.Err != nil {
19 - ret.Host = hostPort
20 - }
21 - return
22 -}
23 -
24 -func (me *HostPort) Join() string {
25 - return net.JoinHostPort(me.Host, me.Port)
26 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/path.go deleted
-20
@@ -1,20 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "os"
5 - "path"
6 -)
7 -
8 -// Splits the pathname p into Root and Ext, such that Root+Ext==p.
9 -func PathSplitExt(p string) (ret struct {
10 - Root, Ext string
11 -}) {
12 - ret.Ext = path.Ext(p)
13 - ret.Root = p[:len(p)-len(ret.Ext)]
14 - return
15 -}
16 -
17 -func FilePathExists(p string) bool {
18 - _, err := os.Stat(p)
19 - return err == nil
20 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/path_test.go deleted
-17
@@ -1,17 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "fmt"
5 -)
6 -
7 -func ExamplePathSplitExt() {
8 - fmt.Printf("%q\n", PathSplitExt(".cshrc"))
9 - fmt.Printf("%q\n", PathSplitExt("dir/a.ext"))
10 - fmt.Printf("%q\n", PathSplitExt("dir/.rc"))
11 - fmt.Printf("%q\n", PathSplitExt("home/.secret/file"))
12 - // Output:
13 - // {"" ".cshrc"}
14 - // {"dir/a" ".ext"}
15 - // {"dir/" ".rc"}
16 - // {"home/.secret/file" ""}
17 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/mutex.go deleted
-48
@@ -1,48 +0,0 @@
1 -package perf
2 -
3 -import (
4 - "sync"
5 -
6 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
7 -)
8 -
9 -type TimedLocker struct {
10 - L sync.Locker
11 - Desc string
12 -}
13 -
14 -func (me *TimedLocker) Lock() {
15 - tr := NewTimer()
16 - me.L.Lock()
17 - tr.Stop(me.Desc)
18 -}
19 -
20 -func (me *TimedLocker) Unlock() {
21 - me.L.Unlock()
22 -}
23 -
24 -type TimedRWLocker struct {
25 - RWL missinggo.RWLocker
26 - WriteDesc string
27 - ReadDesc string
28 -}
29 -
30 -func (me *TimedRWLocker) Lock() {
31 - tr := NewTimer()
32 - me.RWL.Lock()
33 - tr.Stop(me.WriteDesc)
34 -}
35 -
36 -func (me *TimedRWLocker) Unlock() {
37 - me.RWL.Unlock()
38 -}
39 -
40 -func (me *TimedRWLocker) RLock() {
41 - tr := NewTimer()
42 - me.RWL.RLock()
43 - tr.Stop(me.ReadDesc)
44 -}
45 -
46 -func (me *TimedRWLocker) RUnlock() {
47 - me.RWL.RUnlock()
48 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf.go deleted
-92
@@ -1,92 +0,0 @@
1 -package perf
2 -
3 -import (
4 - "bytes"
5 - "expvar"
6 - "fmt"
7 - "strconv"
8 - "sync"
9 - "time"
10 -
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
12 -)
13 -
14 -var (
15 - em = missinggo.NewExpvarIndentMap("perfBuckets")
16 - mu sync.RWMutex
17 -)
18 -
19 -type Timer struct {
20 - started time.Time
21 -}
22 -
23 -func NewTimer() Timer {
24 - return Timer{time.Now()}
25 -}
26 -
27 -func bucketExponent(d time.Duration) int {
28 - e := -9
29 - for d != 0 {
30 - d /= 10
31 - e++
32 - }
33 - return e
34 -}
35 -
36 -type buckets struct {
37 - mu sync.Mutex
38 - buckets []int64
39 -}
40 -
41 -func (me *buckets) Add(t time.Duration) {
42 - e := bucketExponent(t)
43 - me.mu.Lock()
44 - for e+9 >= len(me.buckets) {
45 - me.buckets = append(me.buckets, 0)
46 - }
47 - me.buckets[e+9]++
48 - me.mu.Unlock()
49 -}
50 -
51 -func (me *buckets) String() string {
52 - var b bytes.Buffer
53 - fmt.Fprintf(&b, "{")
54 - first := true
55 - me.mu.Lock()
56 - for i, count := range me.buckets {
57 - if first {
58 - if count == 0 {
59 - continue
60 - }
61 - first = false
62 - } else {
63 - fmt.Fprintf(&b, ", ")
64 - }
65 - key := strconv.Itoa(i - 9)
66 - fmt.Fprintf(&b, "%q: %d", key, count)
67 - }
68 - me.mu.Unlock()
69 - fmt.Fprintf(&b, "}")
70 - return b.String()
71 -}
72 -
73 -var _ expvar.Var = &buckets{}
74 -
75 -func (t *Timer) Stop(desc string) time.Duration {
76 - d := time.Since(t.started)
77 - mu.RLock()
78 - _m := em.Get(desc)
79 - mu.RUnlock()
80 - if _m == nil {
81 - mu.Lock()
82 - _m = em.Get(desc)
83 - if _m == nil {
84 - _m = new(buckets)
85 - em.Set(desc, _m)
86 - }
87 - mu.Unlock()
88 - }
89 - m := _m.(*buckets)
90 - m.Add(d)
91 - return d
92 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf_test.go deleted
-52
@@ -1,52 +0,0 @@
1 -package perf
2 -
3 -import (
4 - "fmt"
5 - "strconv"
6 - "testing"
7 - "time"
8 -
9 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/bradfitz/iter"
10 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/assert"
11 -)
12 -
13 -func TestTimer(t *testing.T) {
14 - tr := NewTimer()
15 - tr.Stop("hiyo")
16 - tr.Stop("hiyo")
17 - t.Log(em.Get("hiyo").(*buckets))
18 -}
19 -
20 -func BenchmarkStopWarm(b *testing.B) {
21 - tr := NewTimer()
22 - for range iter.N(b.N) {
23 - tr.Stop("a")
24 - }
25 -}
26 -
27 -func BenchmarkStopCold(b *testing.B) {
28 - tr := NewTimer()
29 - for i := range iter.N(b.N) {
30 - tr.Stop(strconv.FormatInt(int64(i), 10))
31 - }
32 -}
33 -
34 -func TestExponent(t *testing.T) {
35 - for _, c := range []struct {
36 - e int
37 - d time.Duration
38 - }{
39 - {-1, 10 * time.Millisecond},
40 - {-2, 5 * time.Millisecond},
41 - {-2, time.Millisecond},
42 - {-3, 500 * time.Microsecond},
43 - {-3, 100 * time.Microsecond},
44 - } {
45 - tr := NewTimer()
46 - time.Sleep(c.d)
47 - assert.Equal(t, c.e, bucketExponent(tr.Stop(fmt.Sprintf("%d", c.e))), "%s", c.d)
48 - }
49 - assert.Equal(t, `{"-1": 1}`, em.Get("-1").String())
50 - assert.Equal(t, `{"-2": 2}`, em.Get("-2").String())
51 - assert.Equal(t, `{"-3": 2}`, em.Get("-3").String())
52 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub.go deleted
-92
@@ -1,92 +0,0 @@
1 -package pubsub
2 -
3 -import (
4 - "sync"
5 -)
6 -
7 -type PubSub struct {
8 - mu sync.Mutex
9 - next chan item
10 - closed bool
11 -}
12 -
13 -type item struct {
14 - value interface{}
15 - next chan item
16 -}
17 -
18 -type Subscription struct {
19 - next chan item
20 - Values chan interface{}
21 - mu sync.Mutex
22 - closed chan struct{}
23 -}
24 -
25 -func NewPubSub() (ret *PubSub) {
26 - return &PubSub{
27 - next: make(chan item, 1),
28 - }
29 -}
30 -
31 -func (me *PubSub) Publish(v interface{}) {
32 - next := make(chan item, 1)
33 - i := item{v, next}
34 - me.mu.Lock()
35 - me.next <- i
36 - me.next = next
37 - me.mu.Unlock()
38 -}
39 -
40 -func (me *Subscription) Close() {
41 - me.mu.Lock()
42 - defer me.mu.Unlock()
43 - select {
44 - case <-me.closed:
45 - default:
46 - close(me.closed)
47 - }
48 -}
49 -
50 -func (me *Subscription) runner() {
51 - defer close(me.Values)
52 - for {
53 - select {
54 - case i, ok := <-me.next:
55 - if !ok {
56 - me.Close()
57 - return
58 - }
59 - me.next <- i
60 - me.next = i.next
61 - select {
62 - case me.Values <- i.value:
63 - case <-me.closed:
64 - return
65 - }
66 - case <-me.closed:
67 - return
68 - }
69 - }
70 -}
71 -
72 -func (me *PubSub) Subscribe() (ret *Subscription) {
73 - ret = &Subscription{
74 - closed: make(chan struct{}),
75 - Values: make(chan interface{}),
76 - }
77 - me.mu.Lock()
78 - ret.next = me.next
79 - me.mu.Unlock()
80 - go ret.runner()
81 - return
82 -}
83 -
84 -func (me *PubSub) Close() {
85 - me.mu.Lock()
86 - defer me.mu.Unlock()
87 - if me.closed {
88 - return
89 - }
90 - close(me.next)
91 - me.closed = true
92 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub_test.go deleted
-74
@@ -1,74 +0,0 @@
1 -package pubsub
2 -
3 -import (
4 - "sync"
5 - "testing"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/bradfitz/iter"
8 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/assert"
9 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/require"
10 -)
11 -
12 -func TestDoubleClose(t *testing.T) {
13 - ps := NewPubSub()
14 - ps.Close()
15 - ps.Close()
16 -}
17 -
18 -func testBroadcast(t testing.TB, subs, vals int) {
19 - ps := NewPubSub()
20 - var wg sync.WaitGroup
21 - for range iter.N(subs) {
22 - wg.Add(1)
23 - s := ps.Subscribe()
24 - go func() {
25 - defer wg.Done()
26 - var e int
27 - for i := range s.Values {
28 - assert.Equal(t, e, i.(int))
29 - e++
30 - }
31 - assert.Equal(t, vals, e)
32 - }()
33 - }
34 - for i := range iter.N(vals) {
35 - ps.Publish(i)
36 - }
37 - ps.Close()
38 - wg.Wait()
39 -}
40 -
41 -func TestBroadcast(t *testing.T) {
42 - testBroadcast(t, 100, 10)
43 -}
44 -
45 -func BenchmarkBroadcast(b *testing.B) {
46 - for range iter.N(b.N) {
47 - testBroadcast(b, 10, 1000)
48 - }
49 -}
50 -
51 -func TestCloseSubscription(t *testing.T) {
52 - ps := NewPubSub()
53 - ps.Publish(1)
54 - s := ps.Subscribe()
55 - select {
56 - case <-s.Values:
57 - t.FailNow()
58 - default:
59 - }
60 - ps.Publish(2)
61 - s2 := ps.Subscribe()
62 - ps.Publish(3)
63 - require.Equal(t, 2, <-s.Values)
64 - require.EqualValues(t, 3, <-s.Values)
65 - s.Close()
66 - _, ok := <-s.Values
67 - require.False(t, ok)
68 - ps.Publish(4)
69 - ps.Close()
70 - require.Equal(t, 3, <-s2.Values)
71 - require.Equal(t, 4, <-s2.Values)
72 - require.Nil(t, <-s2.Values)
73 - s2.Close()
74 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/rle.go deleted
-46
@@ -1,46 +0,0 @@
1 -package missinggo
2 -
3 -// A RunLengthEncoder counts successive duplicate elements and emits the
4 -// element and the run length when the element changes or the encoder is
5 -// flushed.
6 -type RunLengthEncoder interface {
7 - // Add a series of identical elements to the stream.
8 - Append(element interface{}, count uint64)
9 - // Emit the current element and its count if non-zero without waiting for
10 - // the element to change.
11 - Flush()
12 -}
13 -
14 -type runLengthEncoder struct {
15 - eachRun func(element interface{}, count uint64)
16 - element interface{}
17 - count uint64
18 -}
19 -
20 -// Creates a new RunLengthEncoder. eachRun is called when an element and its
21 -// count is emitted, per the RunLengthEncoder interface.
22 -func NewRunLengthEncoder(eachRun func(element interface{}, count uint64)) RunLengthEncoder {
23 - return &runLengthEncoder{
24 - eachRun: eachRun,
25 - }
26 -}
27 -
28 -func (me *runLengthEncoder) Append(element interface{}, count uint64) {
29 - if element == me.element {
30 - me.count += count
31 - return
32 - }
33 - if me.count != 0 {
34 - me.eachRun(me.element, me.count)
35 - }
36 - me.count = count
37 - me.element = element
38 -}
39 -
40 -func (me *runLengthEncoder) Flush() {
41 - if me.count == 0 {
42 - return
43 - }
44 - me.eachRun(me.element, me.count)
45 - me.count = 0
46 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/rle_test.go deleted
-20
@@ -1,20 +0,0 @@
1 -package missinggo_test
2 -
3 -import (
4 - "fmt"
5 -
6 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
7 -)
8 -
9 -func ExampleNewRunLengthEncoder() {
10 - var s string
11 - rle := missinggo.NewRunLengthEncoder(func(e interface{}, count uint64) {
12 - s += fmt.Sprintf("%d%c", count, e)
13 - })
14 - for _, e := range "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" {
15 - rle.Append(e, 1)
16 - }
17 - rle.Flush()
18 - fmt.Println(s)
19 - // Output: 12W1B12W3B24W1B14W
20 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/singleflight.go deleted
-39
@@ -1,39 +0,0 @@
1 -package missinggo
2 -
3 -import "sync"
4 -
5 -type ongoing struct {
6 - do sync.Mutex
7 - users int
8 -}
9 -
10 -type SingleFlight struct {
11 - mu sync.Mutex
12 - ongoing map[string]*ongoing
13 -}
14 -
15 -func (me *SingleFlight) Lock(id string) {
16 - me.mu.Lock()
17 - on, ok := me.ongoing[id]
18 - if !ok {
19 - on = new(ongoing)
20 - if me.ongoing == nil {
21 - me.ongoing = make(map[string]*ongoing)
22 - }
23 - me.ongoing[id] = on
24 - }
25 - on.users++
26 - me.mu.Unlock()
27 - on.do.Lock()
28 -}
29 -
30 -func (me *SingleFlight) Unlock(id string) {
31 - me.mu.Lock()
32 - on := me.ongoing[id]
33 - on.do.Unlock()
34 - on.users--
35 - if on.users == 0 {
36 - delete(me.ongoing, id)
37 - }
38 - me.mu.Unlock()
39 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/sync.go deleted
-11
@@ -1,11 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "sync"
5 -)
6 -
7 -type RWLocker interface {
8 - sync.Locker
9 - RLock()
10 - RUnlock()
11 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/url.go deleted
-30
@@ -1,30 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "net/http"
5 - "net/url"
6 -)
7 -
8 -// Deep copies a URL.
9 -func CopyURL(u *url.URL) (ret *url.URL) {
10 - ret = new(url.URL)
11 - *ret = *u
12 - if u.User != nil {
13 - ret.User = new(url.Userinfo)
14 - *ret.User = *u.User
15 - }
16 - return
17 -}
18 -
19 -// Reconstructs the URL that would have produced the given Request.
20 -// Request.URLs are not fully populated in http.Server handlers.
21 -func RequestedURL(r *http.Request) (ret *url.URL) {
22 - ret = CopyURL(r.URL)
23 - ret.Host = r.Host
24 - if r.TLS != nil {
25 - ret.Scheme = "https"
26 - } else {
27 - ret.Scheme = "http"
28 - }
29 - return
30 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf.go deleted
-51
@@ -1,51 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "log"
5 - "runtime"
6 - "sync"
7 - "sync/atomic"
8 -)
9 -
10 -const debug = false
11 -
12 -// A Wolf represents some event that becomes less and less interesting as it
13 -// occurs. Call CryHeard to see if we should pay attention this time.
14 -type Wolf struct {
15 - cries uint64
16 -}
17 -
18 -// Returns true less and less often. Convenient for exponentially decreasing
19 -// the amount of noise due to errors.
20 -func (me *Wolf) CryHeard() bool {
21 - n := atomic.AddUint64(&me.cries, 1)
22 - return n&(n-1) == 0
23 -}
24 -
25 -var (
26 - mu sync.Mutex
27 - wolves map[uintptr]*Wolf
28 -)
29 -
30 -// Calls CryHeard() on a Wolf that is unique to the callers program counter.
31 -// i.e. every CryHeard() expression has its own Wolf.
32 -func CryHeard() bool {
33 - pc, file, line, ok := runtime.Caller(1)
34 - if debug {
35 - log.Println(pc, file, line, ok)
36 - }
37 - if !ok {
38 - return true
39 - }
40 - mu.Lock()
41 - if wolves == nil {
42 - wolves = make(map[uintptr]*Wolf)
43 - }
44 - w, ok := wolves[pc]
45 - if !ok {
46 - w = new(Wolf)
47 - wolves[pc] = w
48 - }
49 - mu.Unlock()
50 - return w.CryHeard()
51 -}
Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf_test.go deleted
-30
@@ -1,30 +0,0 @@
1 -package missinggo
2 -
3 -import (
4 - "testing"
5 -
6 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/require"
7 -)
8 -
9 -func cryHeard() bool {
10 - return CryHeard()
11 -}
12 -
13 -func TestCrySameLocation(t *testing.T) {
14 - require.True(t, cryHeard())
15 - require.True(t, cryHeard())
16 - require.False(t, cryHeard())
17 - require.True(t, cryHeard())
18 - require.False(t, cryHeard())
19 - require.False(t, cryHeard())
20 - require.False(t, cryHeard())
21 - require.True(t, cryHeard())
22 -}
23 -
24 -func TestCryDifferentLocations(t *testing.T) {
25 - require.True(t, CryHeard())
26 - require.True(t, CryHeard())
27 - require.True(t, CryHeard())
28 - require.True(t, CryHeard())
29 - require.True(t, CryHeard())
30 -}
Godeps/_workspace/src/github.com/anacrolix/utp/LICENSE deleted
-362
@@ -1,362 +0,0 @@
1 -Mozilla Public License, version 2.0
2 -
3 -1. Definitions
4 -
5 -1.1. "Contributor"
6 -
7 - means each individual or legal entity that creates, contributes to the
8 - creation of, or owns Covered Software.
9 -
10 -1.2. "Contributor Version"
11 -
12 - means the combination of the Contributions of others (if any) used by a
13 - Contributor and that particular Contributor's Contribution.
14 -
15 -1.3. "Contribution"
16 -
17 - means Covered Software of a particular Contributor.
18 -
19 -1.4. "Covered Software"
20 -
21 - means Source Code Form to which the initial Contributor has attached the
22 - notice in Exhibit A, the Executable Form of such Source Code Form, and
23 - Modifications of such Source Code Form, in each case including portions
24 - thereof.
25 -
26 -1.5. "Incompatible With Secondary Licenses"
27 - means
28 -
29 - a. that the initial Contributor has attached the notice described in
30 - Exhibit B to the Covered Software; or
31 -
32 - b. that the Covered Software was made available under the terms of
33 - version 1.1 or earlier of the License, but not also under the terms of
34 - a Secondary License.
35 -
36 -1.6. "Executable Form"
37 -
38 - means any form of the work other than Source Code Form.
39 -
40 -1.7. "Larger Work"
41 -
42 - means a work that combines Covered Software with other material, in a
43 - separate file or files, that is not Covered Software.
44 -
45 -1.8. "License"
46 -
47 - means this document.
48 -
49 -1.9. "Licensable"
50 -
51 - means having the right to grant, to the maximum extent possible, whether
52 - at the time of the initial grant or subsequently, any and all of the
53 - rights conveyed by this License.
54 -
55 -1.10. "Modifications"
56 -
57 - means any of the following:
58 -
59 - a. any file in Source Code Form that results from an addition to,
60 - deletion from, or modification of the contents of Covered Software; or
61 -
62 - b. any new file in Source Code Form that contains any Covered Software.
63 -
64 -1.11. "Patent Claims" of a Contributor
65 -
66 - means any patent claim(s), including without limitation, method,
67 - process, and apparatus claims, in any patent Licensable by such
68 - Contributor that would be infringed, but for the grant of the License,
69 - by the making, using, selling, offering for sale, having made, import,
70 - or transfer of either its Contributions or its Contributor Version.
71 -
72 -1.12. "Secondary License"
73 -
74 - means either the GNU General Public License, Version 2.0, the GNU Lesser
75 - General Public License, Version 2.1, the GNU Affero General Public
76 - License, Version 3.0, or any later versions of those licenses.
77 -
78 -1.13. "Source Code Form"
79 -
80 - means the form of the work preferred for making modifications.
81 -
82 -1.14. "You" (or "Your")
83 -
84 - means an individual or a legal entity exercising rights under this
85 - License. For legal entities, "You" includes any entity that controls, is
86 - controlled by, or is under common control with You. For purposes of this
87 - definition, "control" means (a) the power, direct or indirect, to cause
88 - the direction or management of such entity, whether by contract or
89 - otherwise, or (b) ownership of more than fifty percent (50%) of the
90 - outstanding shares or beneficial ownership of such entity.
91 -
92 -
93 -2. License Grants and Conditions
94 -
95 -2.1. Grants
96 -
97 - Each Contributor hereby grants You a world-wide, royalty-free,
98 - non-exclusive license:
99 -
100 - a. under intellectual property rights (other than patent or trademark)
101 - Licensable by such Contributor to use, reproduce, make available,
102 - modify, display, perform, distribute, and otherwise exploit its
103 - Contributions, either on an unmodified basis, with Modifications, or
104 - as part of a Larger Work; and
105 -
106 - b. under Patent Claims of such Contributor to make, use, sell, offer for
107 - sale, have made, import, and otherwise transfer either its
108 - Contributions or its Contributor Version.
109 -
110 -2.2. Effective Date
111 -
112 - The licenses granted in Section 2.1 with respect to any Contribution
113 - become effective for each Contribution on the date the Contributor first
114 - distributes such Contribution.
115 -
116 -2.3. Limitations on Grant Scope
117 -
118 - The licenses granted in this Section 2 are the only rights granted under
119 - this License. No additional rights or licenses will be implied from the
120 - distribution or licensing of Covered Software under this License.
121 - Notwithstanding Section 2.1(b) above, no patent license is granted by a
122 - Contributor:
123 -
124 - a. for any code that a Contributor has removed from Covered Software; or
125 -
126 - b. for infringements caused by: (i) Your and any other third party's
127 - modifications of Covered Software, or (ii) the combination of its
128 - Contributions with other software (except as part of its Contributor
129 - Version); or
130 -
131 - c. under Patent Claims infringed by Covered Software in the absence of
132 - its Contributions.
133 -
134 - This License does not grant any rights in the trademarks, service marks,
135 - or logos of any Contributor (except as may be necessary to comply with
136 - the notice requirements in Section 3.4).
137 -
138 -2.4. Subsequent Licenses
139 -
140 - No Contributor makes additional grants as a result of Your choice to
141 - distribute the Covered Software under a subsequent version of this
142 - License (see Section 10.2) or under the terms of a Secondary License (if
143 - permitted under the terms of Section 3.3).
144 -
145 -2.5. Representation
146 -
147 - Each Contributor represents that the Contributor believes its
148 - Contributions are its original creation(s) or it has sufficient rights to
149 - grant the rights to its Contributions conveyed by this License.
150 -
151 -2.6. Fair Use
152 -
153 - This License is not intended to limit any rights You have under
154 - applicable copyright doctrines of fair use, fair dealing, or other
155 - equivalents.
156 -
157 -2.7. Conditions
158 -
159 - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
160 - Section 2.1.
161 -
162 -
163 -3. Responsibilities
164 -
165 -3.1. Distribution of Source Form
166 -
167 - All distribution of Covered Software in Source Code Form, including any
168 - Modifications that You create or to which You contribute, must be under
169 - the terms of this License. You must inform recipients that the Source
170 - Code Form of the Covered Software is governed by the terms of this
171 - License, and how they can obtain a copy of this License. You may not
172 - attempt to alter or restrict the recipients' rights in the Source Code
173 - Form.
174 -
175 -3.2. Distribution of Executable Form
176 -
177 - If You distribute Covered Software in Executable Form then:
178 -
179 - a. such Covered Software must also be made available in Source Code Form,
180 - as described in Section 3.1, and You must inform recipients of the
181 - Executable Form how they can obtain a copy of such Source Code Form by
182 - reasonable means in a timely manner, at a charge no more than the cost
183 - of distribution to the recipient; and
184 -
185 - b. You may distribute such Executable Form under the terms of this
186 - License, or sublicense it under different terms, provided that the
187 - license for the Executable Form does not attempt to limit or alter the
188 - recipients' rights in the Source Code Form under this License.
189 -
190 -3.3. Distribution of a Larger Work
191 -
192 - You may create and distribute a Larger Work under terms of Your choice,
193 - provided that You also comply with the requirements of this License for
194 - the Covered Software. If the Larger Work is a combination of Covered
195 - Software with a work governed by one or more Secondary Licenses, and the
196 - Covered Software is not Incompatible With Secondary Licenses, this
197 - License permits You to additionally distribute such Covered Software
198 - under the terms of such Secondary License(s), so that the recipient of
199 - the Larger Work may, at their option, further distribute the Covered
200 - Software under the terms of either this License or such Secondary
201 - License(s).
202 -
203 -3.4. Notices
204 -
205 - You may not remove or alter the substance of any license notices
206 - (including copyright notices, patent notices, disclaimers of warranty, or
207 - limitations of liability) contained within the Source Code Form of the
208 - Covered Software, except that You may alter any license notices to the
209 - extent required to remedy known factual inaccuracies.
210 -
211 -3.5. Application of Additional Terms
212 -
213 - You may choose to offer, and to charge a fee for, warranty, support,
214 - indemnity or liability obligations to one or more recipients of Covered
215 - Software. However, You may do so only on Your own behalf, and not on
216 - behalf of any Contributor. You must make it absolutely clear that any
217 - such warranty, support, indemnity, or liability obligation is offered by
218 - You alone, and You hereby agree to indemnify every Contributor for any
219 - liability incurred by such Contributor as a result of warranty, support,
220 - indemnity or liability terms You offer. You may include additional
221 - disclaimers of warranty and limitations of liability specific to any
222 - jurisdiction.
223 -
224 -4. Inability to Comply Due to Statute or Regulation
225 -
226 - If it is impossible for You to comply with any of the terms of this License
227 - with respect to some or all of the Covered Software due to statute,
228 - judicial order, or regulation then You must: (a) comply with the terms of
229 - this License to the maximum extent possible; and (b) describe the
230 - limitations and the code they affect. Such description must be placed in a
231 - text file included with all distributions of the Covered Software under
232 - this License. Except to the extent prohibited by statute or regulation,
233 - such description must be sufficiently detailed for a recipient of ordinary
234 - skill to be able to understand it.
235 -
236 -5. Termination
237 -
238 -5.1. The rights granted under this License will terminate automatically if You
239 - fail to comply with any of its terms. However, if You become compliant,
240 - then the rights granted under this License from a particular Contributor
241 - are reinstated (a) provisionally, unless and until such Contributor
242 - explicitly and finally terminates Your grants, and (b) on an ongoing
243 - basis, if such Contributor fails to notify You of the non-compliance by
244 - some reasonable means prior to 60 days after You have come back into
245 - compliance. Moreover, Your grants from a particular Contributor are
246 - reinstated on an ongoing basis if such Contributor notifies You of the
247 - non-compliance by some reasonable means, this is the first time You have
248 - received notice of non-compliance with this License from such
249 - Contributor, and You become compliant prior to 30 days after Your receipt
250 - of the notice.
251 -
252 -5.2. If You initiate litigation against any entity by asserting a patent
253 - infringement claim (excluding declaratory judgment actions,
254 - counter-claims, and cross-claims) alleging that a Contributor Version
255 - directly or indirectly infringes any patent, then the rights granted to
256 - You by any and all Contributors for the Covered Software under Section
257 - 2.1 of this License shall terminate.
258 -
259 -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
260 - license agreements (excluding distributors and resellers) which have been
261 - validly granted by You or Your distributors under this License prior to
262 - termination shall survive termination.
263 -
264 -6. Disclaimer of Warranty
265 -
266 - Covered Software is provided under this License on an "as is" basis,
267 - without warranty of any kind, either expressed, implied, or statutory,
268 - including, without limitation, warranties that the Covered Software is free
269 - of defects, merchantable, fit for a particular purpose or non-infringing.
270 - The entire risk as to the quality and performance of the Covered Software
271 - is with You. Should any Covered Software prove defective in any respect,
272 - You (not any Contributor) assume the cost of any necessary servicing,
273 - repair, or correction. This disclaimer of warranty constitutes an essential
274 - part of this License. No use of any Covered Software is authorized under
275 - this License except under this disclaimer.
276 -
277 -7. Limitation of Liability
278 -
279 - Under no circumstances and under no legal theory, whether tort (including
280 - negligence), contract, or otherwise, shall any Contributor, or anyone who
281 - distributes Covered Software as permitted above, be liable to You for any
282 - direct, indirect, special, incidental, or consequential damages of any
283 - character including, without limitation, damages for lost profits, loss of
284 - goodwill, work stoppage, computer failure or malfunction, or any and all
285 - other commercial damages or losses, even if such party shall have been
286 - informed of the possibility of such damages. This limitation of liability
287 - shall not apply to liability for death or personal injury resulting from
288 - such party's negligence to the extent applicable law prohibits such
289 - limitation. Some jurisdictions do not allow the exclusion or limitation of
290 - incidental or consequential damages, so this exclusion and limitation may
291 - not apply to You.
292 -
293 -8. Litigation
294 -
295 - Any litigation relating to this License may be brought only in the courts
296 - of a jurisdiction where the defendant maintains its principal place of
297 - business and such litigation shall be governed by laws of that
298 - jurisdiction, without reference to its conflict-of-law provisions. Nothing
299 - in this Section shall prevent a party's ability to bring cross-claims or
300 - counter-claims.
301 -
302 -9. Miscellaneous
303 -
304 - This License represents the complete agreement concerning the subject
305 - matter hereof. If any provision of this License is held to be
306 - unenforceable, such provision shall be reformed only to the extent
307 - necessary to make it enforceable. Any law or regulation which provides that
308 - the language of a contract shall be construed against the drafter shall not
309 - be used to construe this License against a Contributor.
310 -
311 -
312 -10. Versions of the License
313 -
314 -10.1. New Versions
315 -
316 - Mozilla Foundation is the license steward. Except as provided in Section
317 - 10.3, no one other than the license steward has the right to modify or
318 - publish new versions of this License. Each version will be given a
319 - distinguishing version number.
320 -
321 -10.2. Effect of New Versions
322 -
323 - You may distribute the Covered Software under the terms of the version
324 - of the License under which You originally received the Covered Software,
325 - or under the terms of any subsequent version published by the license
326 - steward.
327 -
328 -10.3. Modified Versions
329 -
330 - If you create software not governed by this License, and you want to
331 - create a new license for such software, you may create and use a
332 - modified version of this License if you rename the license and remove
333 - any references to the name of the license steward (except to note that
334 - such modified license differs from this License).
335 -
336 -10.4. Distributing Source Code Form that is Incompatible With Secondary
337 - Licenses If You choose to distribute Source Code Form that is
338 - Incompatible With Secondary Licenses under the terms of this version of
339 - the License, the notice described in Exhibit B of this License must be
340 - attached.
341 -
342 -Exhibit A - Source Code Form License Notice
343 -
344 - This Source Code Form is subject to the
345 - terms of the Mozilla Public License, v.
346 - 2.0. If a copy of the MPL was not
347 - distributed with this file, You can
348 - obtain one at
349 - http://mozilla.org/MPL/2.0/.
350 -
351 -If it is not possible or desirable to put the notice in a particular file,
352 -then You may include the notice in a location (such as a LICENSE file in a
353 -relevant directory) where a recipient would be likely to look for such a
354 -notice.
355 -
356 -You may add additional accurate notices of copyright ownership.
357 -
358 -Exhibit B - "Incompatible With Secondary Licenses" Notice
359 -
360 - This Source Code Form is "Incompatible
361 - With Secondary Licenses", as defined by
362 - the Mozilla Public License, v. 2.0.
Godeps/_workspace/src/github.com/anacrolix/utp/README.md deleted
-19
@@ -1,19 +0,0 @@
1 -# utp
2 -[![GoDoc](https://godoc.org/github.com/anacrolix/utp?status.svg)](https://godoc.org/github.com/anacrolix/utp)
3 -[![Build Status](https://drone.io/github.com/anacrolix/utp/status.png)](https://drone.io/github.com/anacrolix/utp/latest)
4 -
5 -Package utp implements uTP, the micro transport protocol as used with Bittorrent. It opts for simplicity and reliability over strict adherence to the (poor) spec.
6 -
7 -## Supported
8 -
9 - * Multiple uTP connections switched on a single PacketConn, including those initiated locally.
10 - * Raw access to the PacketConn for non-uTP purposes, like sharing the PacketConn with a DHT implementation.
11 -
12 -## Implementation characteristics
13 -
14 - * Receive window size is used to limit out of order packets received.
15 - * There is no MTU path discovery. The minimum size is always used.
16 - * A fixed 64 slot selective ack window is used in both sending and receiving.
17 - * All received non-ACK packets are ACKed in response.
18 -
19 -Patches welcomed.
Godeps/_workspace/src/github.com/anacrolix/utp/cmd/ucat/ucat.go deleted
-66
@@ -1,66 +0,0 @@
1 -package main
2 -
3 -import (
4 - "flag"
5 - "fmt"
6 - "io"
7 - "log"
8 - "net"
9 - "os"
10 - "os/signal"
11 -
12 - "gx/ipfs/QmazECKVXFsA3J6cHAqf8HeTDUB8zARjfo75nxE6o63AAp/envpprof"
13 -
14 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/utp"
15 -)
16 -
17 -func main() {
18 - defer envpprof.Stop()
19 - listen := flag.Bool("l", false, "listen")
20 - port := flag.Int("p", 0, "port to listen on")
21 - flag.Parse()
22 - var (
23 - conn net.Conn
24 - err error
25 - )
26 - if *listen {
27 - s, err := utp.NewSocket("udp", fmt.Sprintf(":%d", *port))
28 - if err != nil {
29 - log.Fatal(err)
30 - }
31 - defer s.Close()
32 - conn, err = s.Accept()
33 - if err != nil {
34 - log.Fatal(err)
35 - }
36 - } else {
37 - conn, err = utp.Dial(net.JoinHostPort(flag.Arg(0), flag.Arg(1)))
38 - if err != nil {
39 - log.Fatal(err)
40 - }
41 - }
42 - defer conn.Close()
43 - go func() {
44 - sig := make(chan os.Signal, 1)
45 - signal.Notify(sig, os.Interrupt)
46 - <-sig
47 - conn.Close()
48 - }()
49 - writerDone := make(chan struct{})
50 - go func() {
51 - defer close(writerDone)
52 - written, err := io.Copy(conn, os.Stdin)
53 - if err != nil {
54 - conn.Close()
55 - log.Fatalf("error after writing %d bytes: %s", written, err)
56 - }
57 - log.Printf("wrote %d bytes", written)
58 - conn.Close()
59 - }()
60 - n, err := io.Copy(os.Stdout, conn)
61 - if err != nil {
62 - log.Fatal(err)
63 - }
64 - log.Printf("received %d bytes", n)
65 - // <-writerDone
66 -}
Godeps/_workspace/src/github.com/anacrolix/utp/pingpong deleted
-61
@@ -1,61 +0,0 @@
1 -# This shell script uses nc-like executables to send and receive the file at
2 -# $1, and prints the checksums. 3 such executables are
3 -# github.com/h2so5/utp/ucat, invoked as h2so5-ucat, libutp-ucat, which is the
4 -# ucat or ucat-static generated by the C++ libutp, and lastly, ./cmd/ucat from
5 -# this repository. A good file in my experiments is no more than a few 100MB,
6 -# or you'll be waiting a while.
7 -
8 -set -eu
9 -# set -x
10 -
11 -# Passed to invocations of godo for package ./cmd/ucat.
12 -#GODOFLAGS=-race
13 -
14 -#export GO_UTP_PACKET_DROP=0.1
15 -export GOPPROF=
16 -
17 -# Invokes the implementation to test against. If there's an arg, then it's
18 -# expected to listen.
19 -function other_ucat() {
20 - if [[ $# != 0 ]]; then
21 - libutp-ucat -l -p 4000
22 - # h2so5-ucat -l :4000
23 - else
24 - libutp-ucat localhost 4000
25 - # h2so5-ucat localhost:4000
26 - fi
27 -}
28 -
29 -# Check what the correct result is.
30 -md5 "$1"
31 -
32 -rate() {
33 - pv -a -W -b
34 -}
35 -
36 -echo 'utp->other_ucat'
37 -# Send from this uTP implementation to another client.
38 -other_ucat -l | rate | md5 &
39 -# sleep 1
40 -godo ${GODOFLAGS-} ./cmd/ucat localhost 4000 < "$1"
41 -wait
42 -
43 -echo 'other_ucat->utp'
44 -# Send from the other implementation, to this one.
45 -GO_UTP_LOGGING=0 GOPPROF= godo ${GODOFLAGS-} ./cmd/ucat -l -p 4000 | rate | md5 &
46 -# Never receive from h2so5's ucat without a small sleep first. Don't know why.
47 -# sleep 1
48 -other_ucat < "$1"
49 -wait
50 -
51 -echo 'libutp->libutp'
52 -libutp-ucat -l -p 4000 | rate | md5 &
53 -libutp-ucat localhost 4000 < "$1"
54 -wait
55 -
56 -echo 'utp->utp'
57 -godo ./cmd/ucat -l -p 4000 | rate | md5 &
58 -godo ./cmd/ucat localhost 4000 < "$1"
59 -wait
60 -
61 -# Now check the hashes match (yes you).
Godeps/_workspace/src/github.com/anacrolix/utp/utp.go deleted
-1461
@@ -1,1461 +0,0 @@
1 -// Package utp implements uTP, the micro transport protocol as used with
2 -// Bittorrent. It opts for simplicity and reliability over strict adherence to
3 -// the (poor) spec. It allows using the underlying OS-level transport despite
4 -// dispatching uTP on top to allow for example, shared socket use with DHT.
5 -// Additionally, multiple uTP connections can share the same OS socket, to
6 -// truly realize uTP's claim to be light on system and network switching
7 -// resources.
8 -//
9 -// Socket is a wrapper of net.UDPConn, and performs dispatching of uTP packets
10 -// to attached uTP Conns. Dial and Accept is done via Socket. Conn implements
11 -// net.Conn over uTP, via aforementioned Socket.
12 -package utp
13 -
14 -import (
15 - "encoding/binary"
16 - "errors"
17 - "expvar"
18 - "fmt"
19 - "io"
20 - "log"
21 - "math/rand"
22 - "net"
23 - "os"
24 - "strconv"
25 - "sync"
26 - "time"
27 -
28 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/jitter"
29 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
30 -)
31 -
32 -const (
33 - // Maximum received SYNs that haven't been accepted. If more SYNs are
34 - // received, a pseudo randomly selected SYN is replied to with a reset to
35 - // make room.
36 - backlog = 50
37 -
38 - // IPv6 min MTU is 1280, -40 for IPv6 header, and ~8 for fragment header?
39 - minMTU = 1232
40 - recvWindow = 0x8000 // 32KiB
41 - // uTP header of 20, +2 for the next extension, and 8 bytes of selective
42 - // ACK.
43 - maxHeaderSize = 30
44 - maxPayloadSize = minMTU - maxHeaderSize
45 - maxRecvSize = 0x2000
46 -
47 - // Maximum out-of-order packets to buffer.
48 - maxUnackedInbound = 64
49 -
50 - // If an send isn't acknowledged after this period, its connection is
51 - // destroyed. There are resends during this period.
52 - sendTimeout = 15 * time.Second
53 -)
54 -
55 -var (
56 - ackSkippedResends = expvar.NewInt("utpAckSkippedResends")
57 - // Inbound packets processed by a Conn.
58 - deliveriesProcessed = expvar.NewInt("utpDeliveriesProcessed")
59 - sentStatePackets = expvar.NewInt("utpSentStatePackets")
60 - unusedReads = expvar.NewInt("utpUnusedReads")
61 - sendBufferPool = sync.Pool{
62 - New: func() interface{} { return make([]byte, minMTU) },
63 - }
64 -)
65 -
66 -type deadlineCallback struct {
67 - deadline time.Time
68 - timer *time.Timer
69 - callback func()
70 - inited bool
71 -}
72 -
73 -func (me *deadlineCallback) deadlineExceeded() bool {
74 - return !me.deadline.IsZero() && !time.Now().Before(me.deadline)
75 -}
76 -
77 -func (me *deadlineCallback) updateTimer() {
78 - if me.timer != nil {
79 - me.timer.Stop()
80 - }
81 - if me.deadline.IsZero() {
82 - return
83 - }
84 - if me.callback == nil {
85 - panic("deadline callback is nil")
86 - }
87 - me.timer = time.AfterFunc(me.deadline.Sub(time.Now()), me.callback)
88 -}
89 -
90 -func (me *deadlineCallback) setDeadline(t time.Time) {
91 - me.deadline = t
92 - me.updateTimer()
93 -}
94 -
95 -func (me *deadlineCallback) setCallback(f func()) {
96 - me.callback = f
97 - me.updateTimer()
98 -}
99 -
100 -type connDeadlines struct {
101 - // mu sync.Mutex
102 - read, write deadlineCallback
103 -}
104 -
105 -func (c *connDeadlines) SetDeadline(t time.Time) error {
106 - c.read.setDeadline(t)
107 - c.write.setDeadline(t)
108 - return nil
109 -}
110 -
111 -func (c *connDeadlines) SetReadDeadline(t time.Time) error {
112 - c.read.setDeadline(t)
113 - return nil
114 -}
115 -
116 -func (c *connDeadlines) SetWriteDeadline(t time.Time) error {
117 - c.write.setDeadline(t)
118 - return nil
119 -}
120 -
121 -// Strongly-type guarantee of resolved network address.
122 -type resolvedAddrStr string
123 -
124 -// Uniquely identifies any uTP connection on top of the underlying packet
125 -// stream.
126 -type connKey struct {
127 - remoteAddr resolvedAddrStr
128 - connID uint16
129 -}
130 -
131 -// A Socket wraps a net.PacketConn, diverting uTP packets to its child uTP
132 -// Conns.
133 -type Socket struct {
134 - mu sync.RWMutex
135 - event sync.Cond
136 - pc net.PacketConn
137 - conns map[connKey]*Conn
138 - backlog map[syn]struct{}
139 - reads chan read
140 - closing chan struct{}
141 -
142 - unusedReads chan read
143 - connDeadlines
144 - // If a read error occurs on the underlying net.PacketConn, it is put
145 - // here. This is because reading is done in its own goroutine to dispatch
146 - // to uTP Conns.
147 - ReadErr error
148 -}
149 -
150 -type read struct {
151 - data []byte
152 - from net.Addr
153 -}
154 -
155 -type syn struct {
156 - seq_nr, conn_id uint16
157 - addr string
158 -}
159 -
160 -const (
161 - extensionTypeSelectiveAck = 1
162 -)
163 -
164 -type extensionField struct {
165 - Type byte
166 - Bytes []byte
167 -}
168 -
169 -type header struct {
170 - Type st
171 - Version int
172 - ConnID uint16
173 - Timestamp uint32
174 - TimestampDiff uint32
175 - WndSize uint32
176 - SeqNr uint16
177 - AckNr uint16
178 - Extensions []extensionField
179 -}
180 -
181 -var (
182 - mu sync.RWMutex
183 - logLevel = 0
184 - artificialPacketDropChance = 0.0
185 -)
186 -
187 -func init() {
188 - logLevel, _ = strconv.Atoi(os.Getenv("GO_UTP_LOGGING"))
189 - fmt.Sscanf(os.Getenv("GO_UTP_PACKET_DROP"), "%f", &artificialPacketDropChance)
190 -}
191 -
192 -var (
193 - errClosed = errors.New("closed")
194 - errNotImplemented = errors.New("not implemented")
195 - errTimeout net.Error = timeoutError{"i/o timeout"}
196 - errAckTimeout = timeoutError{"timed out waiting for ack"}
197 -)
198 -
199 -type timeoutError struct {
200 - msg string
201 -}
202 -
203 -func (me timeoutError) Timeout() bool { return true }
204 -func (me timeoutError) Error() string { return me.msg }
205 -func (me timeoutError) Temporary() bool { return false }
206 -
207 -func unmarshalExtensions(_type byte, b []byte) (n int, ef []extensionField, err error) {
208 - for _type != 0 {
209 - if _type != extensionTypeSelectiveAck {
210 - // An extension type that is not known to us. Generally we're
211 - // unmarshalling an packet that isn't actually uTP but we don't
212 - // yet know for sure until we try to deliver it.
213 -
214 - // logonce.Stderr.Printf("utp extension %d", _type)
215 - }
216 - if len(b) < 2 || len(b) < int(b[1])+2 {
217 - err = fmt.Errorf("buffer ends prematurely: %x", b)
218 - return
219 - }
220 - ef = append(ef, extensionField{
221 - Type: _type,
222 - Bytes: append([]byte{}, b[2:int(b[1])+2]...),
223 - })
224 - _type = b[0]
225 - n += 2 + int(b[1])
226 - b = b[2+int(b[1]):]
227 - }
228 - return
229 -}
230 -
231 -var errInvalidHeader = errors.New("invalid header")
232 -
233 -func (h *header) Unmarshal(b []byte) (n int, err error) {
234 - h.Type = st(b[0] >> 4)
235 - h.Version = int(b[0] & 0xf)
236 - if h.Type > stMax || h.Version != 1 {
237 - err = errInvalidHeader
238 - return
239 - }
240 - n, h.Extensions, err = unmarshalExtensions(b[1], b[20:])
241 - if err != nil {
242 - return
243 - }
244 - h.ConnID = binary.BigEndian.Uint16(b[2:4])
245 - h.Timestamp = binary.BigEndian.Uint32(b[4:8])
246 - h.TimestampDiff = binary.BigEndian.Uint32(b[8:12])
247 - h.WndSize = binary.BigEndian.Uint32(b[12:16])
248 - h.SeqNr = binary.BigEndian.Uint16(b[16:18])
249 - h.AckNr = binary.BigEndian.Uint16(b[18:20])
250 - n += 20
251 - return
252 -}
253 -
254 -func (h *header) Marshal() (ret []byte) {
255 - hLen := 20 + func() (ret int) {
256 - for _, ext := range h.Extensions {
257 - ret += 2 + len(ext.Bytes)
258 - }
259 - return
260 - }()
261 - ret = sendBufferPool.Get().([]byte)[:hLen:minMTU]
262 - // ret = make([]byte, hLen, minMTU)
263 - p := ret // Used for manipulating ret.
264 - p[0] = byte(h.Type<<4 | 1)
265 - binary.BigEndian.PutUint16(p[2:4], h.ConnID)
266 - binary.BigEndian.PutUint32(p[4:8], h.Timestamp)
267 - binary.BigEndian.PutUint32(p[8:12], h.TimestampDiff)
268 - binary.BigEndian.PutUint32(p[12:16], h.WndSize)
269 - binary.BigEndian.PutUint16(p[16:18], h.SeqNr)
270 - binary.BigEndian.PutUint16(p[18:20], h.AckNr)
271 - // Pointer to the last type field so the next extension can set it.
272 - _type := &p[1]
273 - // We're done with the basic header.
274 - p = p[20:]
275 - for _, ext := range h.Extensions {
276 - *_type = ext.Type
277 - // The next extension's type will go here.
278 - _type = &p[0]
279 - p[1] = uint8(len(ext.Bytes))
280 - if int(p[1]) != copy(p[2:], ext.Bytes) {
281 - panic("unexpected extension length")
282 - }
283 - p = p[2+len(ext.Bytes):]
284 - }
285 - if len(p) != 0 {
286 - panic("header length changed")
287 - }
288 - return
289 -}
290 -
291 -var (
292 - _ net.Listener = &Socket{}
293 - _ net.PacketConn = &Socket{}
294 -)
295 -
296 -const (
297 - csInvalid = iota
298 - csSynSent
299 - csConnected
300 - csDestroy
301 -)
302 -
303 -type st int
304 -
305 -func (me st) String() string {
306 - switch me {
307 - case stData:
308 - return "stData"
309 - case stFin:
310 - return "stFin"
311 - case stState:
312 - return "stState"
313 - case stReset:
314 - return "stReset"
315 - case stSyn:
316 - return "stSyn"
317 - default:
318 - panic(fmt.Sprintf("%d", me))
319 - }
320 -}
321 -
322 -const (
323 - stData st = 0
324 - stFin = 1
325 - stState = 2
326 - stReset = 3
327 - stSyn = 4
328 -
329 - // Used for validating packet headers.
330 - stMax = stSyn
331 -)
332 -
333 -// Conn is a uTP stream and implements net.Conn. It owned by a Socket, which
334 -// handles dispatching packets to and from Conns.
335 -type Conn struct {
336 - mu sync.Mutex
337 - event sync.Cond
338 -
339 - recv_id, send_id uint16
340 - seq_nr, ack_nr uint16
341 - lastAck uint16
342 - lastTimeDiff uint32
343 - peerWndSize uint32
344 -
345 - readBuf []byte
346 -
347 - socket *Socket
348 - remoteAddr net.Addr
349 - // The uTP timestamp.
350 - startTimestamp uint32
351 - // When the conn was allocated.
352 - created time.Time
353 - // Callback to unregister Conn from a parent Socket. Should be called when
354 - // no more packets will be handled.
355 - detach func()
356 -
357 - cs int
358 - gotFin bool
359 - sentFin bool
360 - err error
361 -
362 - unackedSends []*send
363 - // Inbound payloads, the first is ack_nr+1.
364 - inbound []recv
365 - packetsIn chan packet
366 - connDeadlines
367 - latencies []time.Duration
368 - pendingSendState bool
369 - destroyed chan struct{}
370 -}
371 -
372 -type send struct {
373 - acked chan struct{} // Closed with Conn lock.
374 - payloadSize uint32
375 - started time.Time
376 - // This send was skipped in a selective ack.
377 - resend func()
378 - timedOut func()
379 - conn *Conn
380 -
381 - mu sync.Mutex
382 - acksSkipped int
383 - resendTimer *time.Timer
384 - numResends int
385 -}
386 -
387 -func (s *send) Ack() (latency time.Duration) {
388 - s.mu.Lock()
389 - defer s.mu.Unlock()
390 - s.resendTimer.Stop()
391 - select {
392 - case <-s.acked:
393 - return
394 - default:
395 - close(s.acked)
396 - }
397 - latency = time.Since(s.started)
398 - return
399 -}
400 -
401 -type recv struct {
402 - seen bool
403 - data []byte
404 - Type st
405 -}
406 -
407 -var (
408 - _ net.Conn = &Conn{}
409 -)
410 -
411 -func (c *Conn) age() time.Duration {
412 - return time.Since(c.created)
413 -}
414 -
415 -func (c *Conn) timestamp() uint32 {
416 - return nowTimestamp() - c.startTimestamp
417 -}
418 -
419 -func (c *Conn) connected() bool {
420 - return c.cs == csConnected
421 -}
422 -
423 -// addr is used to create a listening UDP conn which becomes the underlying
424 -// net.PacketConn for the Socket.
425 -func NewSocket(network, addr string) (s *Socket, err error) {
426 - s = &Socket{
427 - backlog: make(map[syn]struct{}, backlog),
428 - reads: make(chan read, 100),
429 - closing: make(chan struct{}),
430 -
431 - unusedReads: make(chan read, 100),
432 - }
433 - s.event.L = &s.mu
434 - s.pc, err = net.ListenPacket(network, addr)
435 - if err != nil {
436 - return
437 - }
438 - go s.reader()
439 - go s.dispatcher()
440 - return
441 -}
442 -
443 -func packetDebugString(h *header, payload []byte) string {
444 - return fmt.Sprintf("%s->%d: %q", h.Type, h.ConnID, payload)
445 -}
446 -
447 -func (s *Socket) reader() {
448 - defer close(s.reads)
449 - var b [maxRecvSize]byte
450 - for {
451 - if s.pc == nil {
452 - break
453 - }
454 - n, addr, err := s.pc.ReadFrom(b[:])
455 - if err != nil {
456 - select {
457 - case <-s.closing:
458 - default:
459 - s.ReadErr = err
460 - }
461 - return
462 - }
463 - var nilB []byte
464 - s.reads <- read{append(nilB, b[:n:n]...), addr}
465 - }
466 -}
467 -
468 -func (s *Socket) unusedRead(read read) {
469 - unusedReads.Add(1)
470 - select {
471 - case s.unusedReads <- read:
472 - default:
473 - // Drop the packet.
474 - }
475 -}
476 -
477 -func stringAddr(s string) net.Addr {
478 - addr, err := net.ResolveUDPAddr("udp", s)
479 - if err != nil {
480 - panic(err)
481 - }
482 - return addr
483 -}
484 -
485 -func (s *Socket) pushBacklog(syn syn) {
486 - if _, ok := s.backlog[syn]; ok {
487 - return
488 - }
489 - for k := range s.backlog {
490 - if len(s.backlog) < backlog {
491 - break
492 - }
493 - delete(s.backlog, k)
494 - // A syn is sent on the remote's recv_id, so this is where we can send
495 - // the reset.
496 - s.reset(stringAddr(k.addr), k.seq_nr, k.conn_id)
497 - }
498 - s.backlog[syn] = struct{}{}
499 - s.event.Broadcast()
500 -}
501 -
502 -func (s *Socket) dispatcher() {
503 - for {
504 - select {
505 - case read, ok := <-s.reads:
506 - if !ok {
507 - return
508 - }
509 - if len(read.data) < 20 {
510 - s.unusedRead(read)
511 - continue
512 - }
513 - s.dispatch(read)
514 - }
515 - }
516 -}
517 -
518 -func (s *Socket) dispatch(read read) {
519 - b := read.data
520 - addr := read.from
521 - var h header
522 - hEnd, err := h.Unmarshal(b)
523 - if logLevel >= 1 {
524 - log.Printf("recvd utp msg: %s", packetDebugString(&h, b[hEnd:]))
525 - }
526 - if err != nil || h.Type > stMax || h.Version != 1 {
527 - s.unusedRead(read)
528 - return
529 - }
530 - s.mu.RLock()
531 - c, ok := s.conns[connKey{resolvedAddrStr(addr.String()), func() (recvID uint16) {
532 - recvID = h.ConnID
533 - // If a SYN is resent, its connection ID field will be one lower
534 - // than we expect.
535 - if h.Type == stSyn {
536 - recvID++
537 - }
538 - return
539 - }()}]
540 - s.mu.RUnlock()
541 - if ok {
542 - if h.Type == stSyn {
543 - if h.ConnID == c.send_id-2 {
544 - // This is a SYN for connection that cannot exist locally. The
545 - // connection the remote wants to establish here with the proposed
546 - // recv_id, already has an existing connection that was dialled
547 - // *out* from this socket, which is why the send_id is 1 higher,
548 - // rather than 1 lower than the recv_id.
549 - log.Print("resetting conflicting syn")
550 - s.reset(addr, h.SeqNr, h.ConnID)
551 - return
552 - } else if h.ConnID != c.send_id {
553 - panic("bad assumption")
554 - }
555 - }
556 - c.deliver(h, b[hEnd:])
557 - return
558 - }
559 - if h.Type == stSyn {
560 - if logLevel >= 1 {
561 - log.Printf("adding SYN to backlog")
562 - }
563 - syn := syn{
564 - seq_nr: h.SeqNr,
565 - conn_id: h.ConnID,
566 - addr: addr.String(),
567 - }
568 - s.mu.Lock()
569 - s.pushBacklog(syn)
570 - s.mu.Unlock()
571 - return
572 - } else if h.Type != stReset {
573 - // This is an unexpected packet. We'll send a reset, but also pass
574 - // it on.
575 - // log.Print("resetting unexpected packet")
576 - // I don't think you can reset on the received packets ConnID if it isn't a SYN, as the send_id will differ in this case.
577 - s.reset(addr, h.SeqNr, h.ConnID)
578 - s.reset(addr, h.SeqNr, h.ConnID-1)
579 - s.reset(addr, h.SeqNr, h.ConnID+1)
580 - }
581 - s.unusedRead(read)
582 -}
583 -
584 -// Send a reset in response to a packet with the given header.
585 -func (s *Socket) reset(addr net.Addr, ackNr, connId uint16) {
586 - go s.writeTo((&header{
587 - Type: stReset,
588 - Version: 1,
589 - ConnID: connId,
590 - AckNr: ackNr,
591 - }).Marshal(), addr)
592 -}
593 -
594 -// Attempt to connect to a remote uTP listener, creating a Socket just for
595 -// this connection.
596 -func Dial(addr string) (net.Conn, error) {
597 - return DialTimeout(addr, 0)
598 -}
599 -
600 -// Same as Dial with a timeout parameter.
601 -func DialTimeout(addr string, timeout time.Duration) (nc net.Conn, err error) {
602 - s, err := NewSocket("udp", ":0")
603 - if err != nil {
604 - return
605 - }
606 - return s.DialTimeout(addr, timeout)
607 -
608 -}
609 -
610 -// Return a recv_id that should be free. Handling the case where it isn't is
611 -// deferred to a more appropriate function.
612 -func (s *Socket) newConnID(remoteAddr resolvedAddrStr) (id uint16) {
613 - // Rather than use math.Rand, which requires generating all the IDs up
614 - // front and allocating a slice, we do it on the stack, generating the IDs
615 - // only as required. To do this, we use the fact that the array is
616 - // default-initialized. IDs that are 0, are actually their index in the
617 - // array. IDs that are non-zero, are +1 from their intended ID.
618 - var idsBack [0x10000]int
619 - ids := idsBack[:]
620 - for len(ids) != 0 {
621 - // Pick the next ID from the untried ids.
622 - i := rand.Intn(len(ids))
623 - id = uint16(ids[i])
624 - // If it's zero, then treat it as though the index i was the ID.
625 - // Otherwise the value we get is the ID+1.
626 - if id == 0 {
627 - id = uint16(i)
628 - } else {
629 - id--
630 - }
631 - // Check there's no connection using this ID for its recv_id...
632 - _, ok1 := s.conns[connKey{remoteAddr, id}]
633 - // and if we're connecting to our own Socket, that there isn't a Conn
634 - // already receiving on what will correspond to our send_id. Note that
635 - // we just assume that we could be connecting to our own Socket. This
636 - // will halve the available connection IDs to each distinct remote
637 - // address. Presumably that's ~0x8000, down from ~0x10000.
638 - _, ok2 := s.conns[connKey{remoteAddr, id + 1}]
639 - _, ok4 := s.conns[connKey{remoteAddr, id - 1}]
640 - if !ok1 && !ok2 && !ok4 {
641 - return
642 - }
643 - // The set of possible IDs is shrinking. The highest one will be lost, so
644 - // it's moved to the location of the one we just tried.
645 - ids[i] = len(ids) // Conveniently already +1.
646 - // And shrink.
647 - ids = ids[:len(ids)-1]
648 - }
649 - return
650 -}
651 -
652 -func (c *Conn) sendPendingState() {
653 - if !c.pendingSendState {
654 - return
655 - }
656 - c.sendState()
657 -}
658 -
659 -func (s *Socket) newConn(addr net.Addr) (c *Conn) {
660 - c = &Conn{
661 - socket: s,
662 - remoteAddr: addr,
663 - startTimestamp: nowTimestamp(),
664 - created: time.Now(),
665 - packetsIn: make(chan packet, 100),
666 - destroyed: make(chan struct{}),
667 - }
668 - c.event.L = &c.mu
669 - c.mu.Lock()
670 - c.connDeadlines.read.setCallback(func() {
671 - c.mu.Lock()
672 - c.event.Broadcast()
673 - c.mu.Unlock()
674 - })
675 - c.connDeadlines.write.setCallback(func() {
676 - c.mu.Lock()
677 - c.event.Broadcast()
678 - c.mu.Unlock()
679 - })
680 - c.mu.Unlock()
681 - go c.deliveryProcessor()
682 - return
683 -}
684 -
685 -func (s *Socket) Dial(addr string) (net.Conn, error) {
686 - return s.DialTimeout(addr, 0)
687 -}
688 -
689 -func (s *Socket) DialTimeout(addr string, timeout time.Duration) (nc net.Conn, err error) {
690 - netAddr, err := net.ResolveUDPAddr("udp", addr)
691 - if err != nil {
692 - return
693 - }
694 -
695 - s.mu.Lock()
696 - c := s.newConn(netAddr)
697 - c.recv_id = s.newConnID(resolvedAddrStr(netAddr.String()))
698 - c.send_id = c.recv_id + 1
699 - if logLevel >= 1 {
700 - log.Printf("dial registering addr: %s", netAddr.String())
701 - }
702 - if !s.registerConn(c.recv_id, resolvedAddrStr(netAddr.String()), c) {
703 - err = errors.New("couldn't register new connection")
704 - log.Println(c.recv_id, netAddr.String())
705 - for k, c := range s.conns {
706 - log.Println(k, c, c.age())
707 - }
708 - log.Printf("that's %d connections", len(s.conns))
709 - }
710 - s.mu.Unlock()
711 - if err != nil {
712 - return
713 - }
714 -
715 - connErr := make(chan error, 1)
716 - go func() {
717 - connErr <- c.connect()
718 - }()
719 - var timeoutCh <-chan time.Time
720 - if timeout != 0 {
721 - timeoutCh = time.After(timeout)
722 - }
723 - select {
724 - case err = <-connErr:
725 - case <-timeoutCh:
726 - c.Close()
727 - err = errTimeout
728 - }
729 - if err == nil {
730 - nc = c
731 - }
732 - return
733 -}
734 -
735 -func (c *Conn) wndSize() uint32 {
736 - if len(c.inbound) > maxUnackedInbound/2 {
737 - return 0
738 - }
739 - var buffered int
740 - for _, r := range c.inbound {
741 - buffered += len(r.data)
742 - }
743 - buffered += len(c.readBuf)
744 - if buffered >= recvWindow {
745 - return 0
746 - }
747 - return recvWindow - uint32(buffered)
748 -}
749 -
750 -func nowTimestamp() uint32 {
751 - return uint32(time.Now().UnixNano() / int64(time.Microsecond))
752 -}
753 -
754 -// Send the given payload with an up to date header.
755 -func (c *Conn) send(_type st, connID uint16, payload []byte, seqNr uint16) (err error) {
756 - // Always selectively ack the first 64 packets. Don't bother with rest for
757 - // now.
758 - selAck := selectiveAckBitmask(make([]byte, 8))
759 - for i := 1; i < 65; i++ {
760 - if len(c.inbound) <= i {
761 - break
762 - }
763 - if c.inbound[i].seen {
764 - selAck.SetBit(i - 1)
765 - }
766 - }
767 - h := header{
768 - Type: _type,
769 - Version: 1,
770 - ConnID: connID,
771 - SeqNr: seqNr,
772 - AckNr: c.ack_nr,
773 - WndSize: c.wndSize(),
774 - Timestamp: c.timestamp(),
775 - TimestampDiff: c.lastTimeDiff,
776 - // Currently always send an 8 byte selective ack.
777 - Extensions: []extensionField{{
778 - Type: extensionTypeSelectiveAck,
779 - Bytes: selAck,
780 - }},
781 - }
782 - p := h.Marshal()
783 - // Extension headers are currently fixed in size.
784 - if len(p) != maxHeaderSize {
785 - panic("header has unexpected size")
786 - }
787 - p = append(p, payload...)
788 - if logLevel >= 1 {
789 - log.Printf("writing utp msg to %s: %s", c.remoteAddr, packetDebugString(&h, payload))
790 - }
791 - n1, err := c.socket.writeTo(p, c.remoteAddr)
792 - if err != nil {
793 - return
794 - }
795 - if n1 != len(p) {
796 - panic(n1)
797 - }
798 - c.unpendSendState()
799 - return
800 -}
801 -
802 -func (me *Conn) unpendSendState() {
803 - me.pendingSendState = false
804 -}
805 -
806 -func (c *Conn) pendSendState() {
807 - c.pendingSendState = true
808 -}
809 -
810 -func (me *Socket) writeTo(b []byte, addr net.Addr) (n int, err error) {
811 - mu.RLock()
812 - apdc := artificialPacketDropChance
813 - mu.RUnlock()
814 - if apdc != 0 {
815 - if rand.Float64() < apdc {
816 - n = len(b)
817 - return
818 - }
819 - }
820 - n, err = me.pc.WriteTo(b, addr)
821 - return
822 -}
823 -
824 -func (s *send) timeoutResend() {
825 - select {
826 - case <-s.acked:
827 - return
828 - default:
829 - }
830 - if time.Since(s.started) >= sendTimeout {
831 - s.timedOut()
832 - return
833 - }
834 - s.conn.mu.Lock()
835 - rt := s.conn.resendTimeout()
836 - s.conn.mu.Unlock()
837 - go s.resend()
838 - s.mu.Lock()
839 - s.numResends++
840 - s.resendTimer.Reset(rt)
841 - s.mu.Unlock()
842 -}
843 -
844 -func (me *Conn) writeSyn() (err error) {
845 - if me.cs != csInvalid {
846 - panic(me.cs)
847 - }
848 - _, err = me.write(stSyn, me.recv_id, nil, me.seq_nr)
849 - return
850 -}
851 -
852 -func (c *Conn) write(_type st, connID uint16, payload []byte, seqNr uint16) (n int, err error) {
853 - switch _type {
854 - case stSyn, stFin, stData:
855 - default:
856 - panic(_type)
857 - }
858 - switch c.cs {
859 - case csConnected, csSynSent, csInvalid:
860 - default:
861 - panic(c.cs)
862 - }
863 - if c.sentFin {
864 - panic(c)
865 - }
866 - if len(payload) > maxPayloadSize {
867 - payload = payload[:maxPayloadSize]
868 - }
869 - err = c.send(_type, connID, payload, seqNr)
870 - if err != nil {
871 - return
872 - }
873 - n = len(payload)
874 - // Copy payload so caller to write can continue to use the buffer.
875 - if payload != nil {
876 - payload = append(sendBufferPool.Get().([]byte)[:0:minMTU], payload...)
877 - }
878 - send := &send{
879 - acked: make(chan struct{}),
880 - payloadSize: uint32(len(payload)),
881 - started: time.Now(),
882 - resend: func() {
883 - c.mu.Lock()
884 - err := c.send(_type, connID, payload, seqNr)
885 - if err != nil {
886 - log.Printf("error resending packet: %s", err)
887 - }
888 - c.mu.Unlock()
889 - },
890 - timedOut: func() {
891 - c.mu.Lock()
892 - c.destroy(errAckTimeout)
893 - c.mu.Unlock()
894 - },
895 - conn: c,
896 - }
897 - send.mu.Lock()
898 - send.resendTimer = time.AfterFunc(c.resendTimeout(), send.timeoutResend)
899 - send.mu.Unlock()
900 - c.unackedSends = append(c.unackedSends, send)
901 - c.seq_nr++
902 - return
903 -}
904 -
905 -func (c *Conn) latency() (ret time.Duration) {
906 - if len(c.latencies) == 0 {
907 - // Sort of the p95 of latencies?
908 - return 200 * time.Millisecond
909 - }
910 - for _, l := range c.latencies {
911 - ret += l
912 - }
913 - ret = (ret + time.Duration(len(c.latencies)) - 1) / time.Duration(len(c.latencies))
914 - return
915 -}
916 -
917 -func (c *Conn) numUnackedSends() (num int) {
918 - for _, s := range c.unackedSends {
919 - select {
920 - case <-s.acked:
921 - default:
922 - num++
923 - }
924 - }
925 - return
926 -}
927 -
928 -func (c *Conn) cur_window() (window uint32) {
929 - for _, s := range c.unackedSends {
930 - select {
931 - case <-s.acked:
932 - default:
933 - window += s.payloadSize
934 - }
935 - }
936 - return
937 -}
938 -
939 -func (c *Conn) sendState() {
940 - c.send(stState, c.send_id, nil, c.seq_nr)
941 - sentStatePackets.Add(1)
942 -}
943 -
944 -func seqLess(a, b uint16) bool {
945 - if b < 0x8000 {
946 - return a < b || a >= b-0x8000
947 - } else {
948 - return a < b && a >= b-0x8000
949 - }
950 -}
951 -
952 -// Ack our send with the given sequence number.
953 -func (c *Conn) ack(nr uint16) {
954 - if !seqLess(c.lastAck, nr) {
955 - // Already acked.
956 - return
957 - }
958 - i := nr - c.lastAck - 1
959 - if int(i) >= len(c.unackedSends) {
960 - log.Printf("got ack ahead of syn (%x > %x)", nr, c.seq_nr-1)
961 - return
962 - }
963 - latency := c.unackedSends[i].Ack()
964 - if latency != 0 {
965 - c.latencies = append(c.latencies, latency)
966 - if len(c.latencies) > 10 {
967 - c.latencies = c.latencies[len(c.latencies)-10:]
968 - }
969 - }
970 - for {
971 - if len(c.unackedSends) == 0 {
972 - break
973 - }
974 - select {
975 - case <-c.unackedSends[0].acked:
976 - default:
977 - // Can't trim unacked sends any further.
978 - return
979 - }
980 - // Trim the front of the unacked sends.
981 - c.unackedSends = c.unackedSends[1:]
982 - c.lastAck++
983 - }
984 - c.event.Broadcast()
985 -}
986 -
987 -func (c *Conn) ackTo(nr uint16) {
988 - if !seqLess(nr, c.seq_nr) {
989 - return
990 - }
991 - for seqLess(c.lastAck, nr) {
992 - c.ack(c.lastAck + 1)
993 - }
994 -}
995 -
996 -type selectiveAckBitmask []byte
997 -
998 -func (me selectiveAckBitmask) NumBits() int {
999 - return len(me) * 8
1000 -}
1001 -
1002 -func (me selectiveAckBitmask) SetBit(index int) {
1003 - me[index/8] |= 1 << uint(index%8)
1004 -}
1005 -
1006 -func (me selectiveAckBitmask) BitIsSet(index int) bool {
1007 - return me[index/8]>>uint(index%8)&1 == 1
1008 -}
1009 -
1010 -// Return the send state for the sequence number. Returns nil if there's no
1011 -// outstanding send for that sequence number.
1012 -func (c *Conn) seqSend(seqNr uint16) *send {
1013 - if !seqLess(c.lastAck, seqNr) {
1014 - // Presumably already acked.
1015 - return nil
1016 - }
1017 - i := int(seqNr - c.lastAck - 1)
1018 - if i >= len(c.unackedSends) {
1019 - // No such send.
1020 - return nil
1021 - }
1022 - return c.unackedSends[i]
1023 -}
1024 -
1025 -func (c *Conn) resendTimeout() time.Duration {
1026 - l := c.latency()
1027 - if l < 10*time.Millisecond {
1028 - l = 10 * time.Millisecond
1029 - }
1030 - ret := jitter.Duration(3*l, l)
1031 - // log.Print(ret)
1032 - return ret
1033 -}
1034 -
1035 -func (c *Conn) ackSkipped(seqNr uint16) {
1036 - send := c.seqSend(seqNr)
1037 - if send == nil {
1038 - return
1039 - }
1040 - send.mu.Lock()
1041 - defer send.mu.Unlock()
1042 - send.acksSkipped++
1043 - switch send.acksSkipped {
1044 - case 3, 60:
1045 - ackSkippedResends.Add(1)
1046 - go send.resend()
1047 - send.resendTimer.Reset(c.resendTimeout())
1048 - default:
1049 - }
1050 -}
1051 -
1052 -type packet struct {
1053 - h header
1054 - payload []byte
1055 -}
1056 -
1057 -func (c *Conn) deliver(h header, payload []byte) {
1058 - c.packetsIn <- packet{h, payload}
1059 -}
1060 -
1061 -func (c *Conn) deliveryProcessor() {
1062 - for {
1063 - select {
1064 - case p := <-c.packetsIn:
1065 - c.processDelivery(p.h, p.payload)
1066 - timeout := time.After(500 * time.Microsecond)
1067 - batched:
1068 - for {
1069 - select {
1070 - case p := <-c.packetsIn:
1071 - c.processDelivery(p.h, p.payload)
1072 - case <-timeout:
1073 - break batched
1074 - }
1075 - }
1076 - c.mu.Lock()
1077 - c.sendPendingState()
1078 - c.mu.Unlock()
1079 - case <-c.destroyed:
1080 - return
1081 - }
1082 - }
1083 -}
1084 -
1085 -func (c *Conn) processDelivery(h header, payload []byte) {
1086 - deliveriesProcessed.Add(1)
1087 - c.mu.Lock()
1088 - defer c.mu.Unlock()
1089 - defer c.event.Broadcast()
1090 - c.assertHeader(h)
1091 - c.peerWndSize = h.WndSize
1092 - c.applyAcks(h)
1093 - if h.Timestamp == 0 {
1094 - c.lastTimeDiff = 0
1095 - } else {
1096 - c.lastTimeDiff = c.timestamp() - h.Timestamp
1097 - }
1098 -
1099 - // We want this connection destroyed, and our peer has acked everything.
1100 - if c.sentFin && len(c.unackedSends) == 0 {
1101 - // log.Print("gracefully completed")
1102 - c.destroy(nil)
1103 - return
1104 - }
1105 - if h.Type == stReset {
1106 - c.destroy(errors.New("peer reset"))
1107 - return
1108 - }
1109 - if c.cs == csSynSent {
1110 - if h.Type != stState {
1111 - return
1112 - }
1113 - c.changeState(csConnected)
1114 - c.ack_nr = h.SeqNr - 1
1115 - return
1116 - }
1117 - if h.Type == stState {
1118 - return
1119 - }
1120 - c.pendSendState()
1121 - if !seqLess(c.ack_nr, h.SeqNr) {
1122 - // Already received this packet.
1123 - return
1124 - }
1125 - inboundIndex := int(h.SeqNr - c.ack_nr - 1)
1126 - if inboundIndex < len(c.inbound) && c.inbound[inboundIndex].seen {
1127 - // Already received this packet.
1128 - return
1129 - }
1130 - // Derived from running in production:
1131 - // grep -oP '(?<=packet out of order, index=)\d+' log | sort -n | uniq -c
1132 - // 64 should correspond to 8 bytes of selective ack.
1133 - if inboundIndex >= maxUnackedInbound {
1134 - // Discard packet too far ahead.
1135 - if missinggo.CryHeard() {
1136 - // I can't tell if this occurs due to bad peers, or something
1137 - // missing in the implementation.
1138 - log.Printf("received packet from %s %d ahead of next seqnr (%x > %x)", c.remoteAddr, inboundIndex, h.SeqNr, c.ack_nr+1)
1139 - }
1140 - return
1141 - }
1142 - // Extend inbound so the new packet has a place.
1143 - for inboundIndex >= len(c.inbound) {
1144 - c.inbound = append(c.inbound, recv{})
1145 - }
1146 - c.inbound[inboundIndex] = recv{true, payload, h.Type}
1147 - c.processInbound()
1148 -}
1149 -
1150 -func (c *Conn) applyAcks(h header) {
1151 - c.ackTo(h.AckNr)
1152 - for _, ext := range h.Extensions {
1153 - switch ext.Type {
1154 - case extensionTypeSelectiveAck:
1155 - c.ackSkipped(h.AckNr + 1)
1156 - bitmask := selectiveAckBitmask(ext.Bytes)
1157 - for i := 0; i < bitmask.NumBits(); i++ {
1158 - if bitmask.BitIsSet(i) {
1159 - nr := h.AckNr + 2 + uint16(i)
1160 - // log.Printf("selectively acked %d", nr)
1161 - c.ack(nr)
1162 - } else {
1163 - c.ackSkipped(h.AckNr + 2 + uint16(i))
1164 - }
1165 - }
1166 - }
1167 - }
1168 -}
1169 -
1170 -func (c *Conn) assertHeader(h header) {
1171 - if h.Type == stSyn {
1172 - if h.ConnID != c.send_id {
1173 - panic(fmt.Sprintf("%d != %d", h.ConnID, c.send_id))
1174 - }
1175 - } else {
1176 - if h.ConnID != c.recv_id {
1177 - panic("erroneous delivery")
1178 - }
1179 - }
1180 -}
1181 -
1182 -func (c *Conn) processInbound() {
1183 - // Consume consecutive next packets.
1184 - for !c.gotFin && len(c.inbound) > 0 && c.inbound[0].seen {
1185 - c.ack_nr++
1186 - p := c.inbound[0]
1187 - c.inbound = c.inbound[1:]
1188 - c.readBuf = append(c.readBuf, p.data...)
1189 - if p.Type == stFin {
1190 - c.gotFin = true
1191 - }
1192 - }
1193 -}
1194 -
1195 -func (c *Conn) waitAck(seq uint16) {
1196 - send := c.seqSend(seq)
1197 - if send == nil {
1198 - return
1199 - }
1200 - c.mu.Unlock()
1201 - defer c.mu.Lock()
1202 - <-send.acked
1203 - return
1204 -}
1205 -
1206 -func (c *Conn) changeState(cs int) {
1207 - // log.Println(c, "goes", c.cs, "->", cs)
1208 - c.cs = cs
1209 -}
1210 -
1211 -func (c *Conn) connect() error {
1212 - c.mu.Lock()
1213 - defer c.mu.Unlock()
1214 - c.seq_nr = 1
1215 - err := c.writeSyn()
1216 - if err != nil {
1217 - return err
1218 - }
1219 - c.changeState(csSynSent)
1220 - if logLevel >= 2 {
1221 - log.Printf("sent syn")
1222 - }
1223 - // c.seq_nr++
1224 - c.waitAck(1)
1225 - if c.err != nil {
1226 - err = c.err
1227 - }
1228 - c.event.Broadcast()
1229 - return err
1230 -}
1231 -
1232 -// Returns true if the connection was newly registered, false otherwise.
1233 -func (s *Socket) registerConn(recvID uint16, remoteAddr resolvedAddrStr, c *Conn) bool {
1234 - if s.conns == nil {
1235 - s.conns = make(map[connKey]*Conn)
1236 - }
1237 - key := connKey{remoteAddr, recvID}
1238 - if _, ok := s.conns[key]; ok {
1239 - return false
1240 - }
1241 - s.conns[key] = c
1242 - c.detach = func() {
1243 - s.mu.Lock()
1244 - defer s.mu.Unlock()
1245 - defer s.event.Broadcast()
1246 - if s.conns[key] != c {
1247 - panic("conn changed")
1248 - }
1249 - // log.Println("detached", key)
1250 - delete(s.conns, key)
1251 - if len(s.conns) == 0 {
1252 - s.pc.Close()
1253 - }
1254 - }
1255 - return true
1256 -}
1257 -
1258 -func (s *Socket) nextSyn() (syn syn, ok bool) {
1259 - s.mu.Lock()
1260 - defer s.mu.Unlock()
1261 - for {
1262 - for k := range s.backlog {
1263 - syn = k
1264 - delete(s.backlog, k)
1265 - ok = true
1266 - return
1267 - }
1268 - select {
1269 - case <-s.closing:
1270 - return
1271 - default:
1272 - }
1273 - s.event.Wait()
1274 - }
1275 -}
1276 -
1277 -// Accept and return a new uTP connection.
1278 -func (s *Socket) Accept() (c net.Conn, err error) {
1279 - for {
1280 - syn, ok := s.nextSyn()
1281 - if !ok {
1282 - err = errClosed
1283 - return
1284 - }
1285 - s.mu.Lock()
1286 - _c := s.newConn(stringAddr(syn.addr))
1287 - _c.send_id = syn.conn_id
1288 - _c.recv_id = _c.send_id + 1
1289 - _c.seq_nr = uint16(rand.Int())
1290 - _c.lastAck = _c.seq_nr - 1
1291 - _c.ack_nr = syn.seq_nr
1292 - _c.cs = csConnected
1293 - if !s.registerConn(_c.recv_id, resolvedAddrStr(syn.addr), _c) {
1294 - // SYN that triggered this accept duplicates existing connection.
1295 - // Ack again in case the SYN was a resend.
1296 - _c = s.conns[connKey{resolvedAddrStr(syn.addr), _c.recv_id}]
1297 - if _c.send_id != syn.conn_id {
1298 - panic(":|")
1299 - }
1300 - _c.sendState()
1301 - s.mu.Unlock()
1302 - continue
1303 - }
1304 - _c.sendState()
1305 - // _c.seq_nr++
1306 - c = _c
1307 - s.mu.Unlock()
1308 - return
1309 - }
1310 -}
1311 -
1312 -// The address we're listening on for new uTP connections.
1313 -func (s *Socket) Addr() net.Addr {
1314 - return s.pc.LocalAddr()
1315 -}
1316 -
1317 -// Marks the Socket for close. Currently this just axes the underlying OS
1318 -// socket.
1319 -func (s *Socket) Close() (err error) {
1320 - s.mu.Lock()
1321 - defer s.mu.Unlock()
1322 - select {
1323 - case <-s.closing:
1324 - return
1325 - default:
1326 - }
1327 - s.event.Broadcast()
1328 - close(s.closing)
1329 - if len(s.conns) == 0 {
1330 - err = s.pc.Close()
1331 - }
1332 - return
1333 -}
1334 -
1335 -func (s *Socket) LocalAddr() net.Addr {
1336 - return s.pc.LocalAddr()
1337 -}
1338 -
1339 -func (s *Socket) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
1340 - read, ok := <-s.unusedReads
1341 - if !ok {
1342 - err = io.EOF
1343 - }
1344 - n = copy(p, read.data)
1345 - addr = read.from
1346 - return
1347 -}
1348 -
1349 -func (s *Socket) WriteTo(b []byte, addr net.Addr) (int, error) {
1350 - return s.pc.WriteTo(b, addr)
1351 -}
1352 -
1353 -func (c *Conn) writeFin() (err error) {
1354 - if c.sentFin {
1355 - return
1356 - }
1357 - _, err = c.write(stFin, c.send_id, nil, c.seq_nr)
1358 - if err != nil {
1359 - return
1360 - }
1361 - c.sentFin = true
1362 - c.event.Broadcast()
1363 - return
1364 -}
1365 -
1366 -func (c *Conn) destroy(reason error) {
1367 - if c.err != nil && reason != nil {
1368 - log.Printf("duplicate destroy call: %s", reason)
1369 - }
1370 - if c.cs == csDestroy {
1371 - return
1372 - }
1373 - close(c.destroyed)
1374 - c.writeFin()
1375 - c.changeState(csDestroy)
1376 - c.err = reason
1377 - c.event.Broadcast()
1378 - c.detach()
1379 - for _, s := range c.unackedSends {
1380 - s.Ack()
1381 - }
1382 -}
1383 -
1384 -func (c *Conn) Close() error {
1385 - c.mu.Lock()
1386 - defer c.mu.Unlock()
1387 - return c.writeFin()
1388 -}
1389 -
1390 -func (c *Conn) LocalAddr() net.Addr {
1391 - return c.socket.Addr()
1392 -}
1393 -
1394 -func (c *Conn) Read(b []byte) (n int, err error) {
1395 - c.mu.Lock()
1396 - defer c.mu.Unlock()
1397 - for {
1398 - if len(c.readBuf) != 0 {
1399 - break
1400 - }
1401 - if c.cs == csDestroy || c.gotFin || c.sentFin {
1402 - err = c.err
1403 - if err == nil {
1404 - err = io.EOF
1405 - }
1406 - return
1407 - }
1408 - if c.connDeadlines.read.deadlineExceeded() {
1409 - err = errTimeout
1410 - return
1411 - }
1412 - if logLevel >= 2 {
1413 - log.Printf("nothing to read, state=%d", c.cs)
1414 - }
1415 - c.event.Wait()
1416 - }
1417 - n = copy(b, c.readBuf)
1418 - c.readBuf = c.readBuf[n:]
1419 -
1420 - return
1421 -}
1422 -
1423 -func (c *Conn) RemoteAddr() net.Addr {
1424 - return c.remoteAddr
1425 -}
1426 -
1427 -func (c *Conn) String() string {
1428 - return fmt.Sprintf("<UTPConn %s-%s (%d)>", c.LocalAddr(), c.RemoteAddr(), c.recv_id)
1429 -}
1430 -
1431 -func (c *Conn) Write(p []byte) (n int, err error) {
1432 - c.mu.Lock()
1433 - defer c.mu.Unlock()
1434 - for len(p) != 0 {
1435 - for {
1436 - if c.sentFin {
1437 - err = io.ErrClosedPipe
1438 - return
1439 - }
1440 - // If peerWndSize is 0, we still want to send something, so don't
1441 - // block until we exceed it.
1442 - if c.cur_window() <= c.peerWndSize && len(c.unackedSends) < 64 && c.cs == csConnected {
1443 - break
1444 - }
1445 - if c.connDeadlines.write.deadlineExceeded() {
1446 - err = errTimeout
1447 - return
1448 - }
1449 - c.event.Wait()
1450 - }
1451 - var n1 int
1452 - n1, err = c.write(stData, c.send_id, p, c.seq_nr)
1453 - if err != nil {
1454 - return
1455 - }
1456 - // c.seq_nr++
1457 - n += n1
1458 - p = p[n1:]
1459 - }
1460 - return
1461 -}
Godeps/_workspace/src/github.com/anacrolix/utp/utp_test.go deleted
-411
@@ -1,411 +0,0 @@
1 -package utp
2 -
3 -import (
4 - "fmt"
5 - "io"
6 - "io/ioutil"
7 - "log"
8 - "net"
9 - "runtime"
10 - "sync"
11 - "testing"
12 - "time"
13 -
14 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/anacrolix/missinggo"
15 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/bradfitz/iter"
16 - "gx/ipfs/QmZwjfAKWe7vWZ8f48u7AGA1xYfzR1iCD9A2XSCYFRBWot/testify/require"
17 - _ "gx/ipfs/QmazECKVXFsA3J6cHAqf8HeTDUB8zARjfo75nxE6o63AAp/envpprof"
18 -)
19 -
20 -func init() {
21 - log.SetFlags(log.Flags() | log.Lshortfile)
22 -}
23 -
24 -func TestUTPPingPong(t *testing.T) {
25 - defer goroutineLeakCheck(t)()
26 - s, err := NewSocket("udp", "localhost:0")
27 - require.NoError(t, err)
28 - defer s.Close()
29 - pingerClosed := make(chan struct{})
30 - go func() {
31 - defer close(pingerClosed)
32 - b, err := Dial(s.Addr().String())
33 - require.NoError(t, err)
34 - defer b.Close()
35 - n, err := b.Write([]byte("ping"))
36 - require.NoError(t, err)
37 - require.EqualValues(t, 4, n)
38 - buf := make([]byte, 4)
39 - b.Read(buf)
40 - require.EqualValues(t, "pong", buf)
41 - log.Printf("got pong")
42 - }()
43 - a, err := s.Accept()
44 - require.NoError(t, err)
45 - defer a.Close()
46 - log.Printf("accepted %s", a)
47 - buf := make([]byte, 42)
48 - n, err := a.Read(buf)
49 - require.NoError(t, err)
50 - require.EqualValues(t, "ping", buf[:n])
51 - log.Print("got ping")
52 - n, err = a.Write([]byte("pong"))
53 - require.NoError(t, err)
54 - require.Equal(t, 4, n)
55 - log.Print("waiting for pinger to close")
56 - <-pingerClosed
57 -}
58 -
59 -func goroutineLeakCheck(t testing.TB) func() {
60 - if !testing.Verbose() {
61 - return func() {}
62 - }
63 - numStart := runtime.NumGoroutine()
64 - return func() {
65 - var numNow int
66 - for range iter.N(1) {
67 - numNow = runtime.NumGoroutine()
68 - if numNow == numStart {
69 - return
70 - }
71 - time.Sleep(10 * time.Millisecond)
72 - }
73 - // I'd print stacks, or treat this as fatal, but I think
74 - // runtime.NumGoroutine is including system routines for which we are
75 - // not provided the stacks, and are spawned unpredictably.
76 - t.Logf("have %d goroutines, started with %d", numNow, numStart)
77 - }
78 -}
79 -
80 -func TestDialTimeout(t *testing.T) {
81 - defer goroutineLeakCheck(t)()
82 - s, _ := NewSocket("udp", "localhost:0")
83 - defer s.Close()
84 - conn, err := DialTimeout(s.Addr().String(), 10*time.Millisecond)
85 - if err == nil {
86 - conn.Close()
87 - t.Fatal("expected timeout")
88 - }
89 - t.Log(err)
90 -}
91 -
92 -func TestMinMaxHeaderType(t *testing.T) {
93 - require.Equal(t, stSyn, stMax)
94 -}
95 -
96 -func TestUTPRawConn(t *testing.T) {
97 - l, err := NewSocket("udp", "")
98 - require.NoError(t, err)
99 - defer l.Close()
100 - go func() {
101 - for {
102 - _, err := l.Accept()
103 - if err != nil {
104 - break
105 - }
106 - }
107 - }()
108 - // Connect a UTP peer to see if the RawConn will still work.
109 - log.Print("dialing")
110 - utpPeer := func() net.Conn {
111 - s, _ := NewSocket("udp", "")
112 - defer s.Close()
113 - ret, err := s.Dial(fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr())))
114 - require.NoError(t, err)
115 - return ret
116 - }()
117 - log.Print("dial returned")
118 - if err != nil {
119 - t.Fatalf("error dialing utp listener: %s", err)
120 - }
121 - defer utpPeer.Close()
122 - peer, err := net.ListenPacket("udp", ":0")
123 - if err != nil {
124 - t.Fatal(err)
125 - }
126 - defer peer.Close()
127 -
128 - msgsReceived := 0
129 - const N = 5000 // How many messages to send.
130 - readerStopped := make(chan struct{})
131 - // The reader goroutine.
132 - go func() {
133 - defer close(readerStopped)
134 - b := make([]byte, 500)
135 - for i := 0; i < N; i++ {
136 - n, _, err := l.ReadFrom(b)
137 - if err != nil {
138 - t.Fatalf("error reading from raw conn: %s", err)
139 - }
140 - msgsReceived++
141 - var d int
142 - fmt.Sscan(string(b[:n]), &d)
143 - if d != i {
144 - log.Printf("got wrong number: expected %d, got %d", i, d)
145 - }
146 - }
147 - }()
148 - udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr())))
149 - if err != nil {
150 - t.Fatal(err)
151 - }
152 - for i := 0; i < N; i++ {
153 - _, err := peer.WriteTo([]byte(fmt.Sprintf("%d", i)), udpAddr)
154 - if err != nil {
155 - t.Fatal(err)
156 - }
157 - time.Sleep(time.Microsecond)
158 - }
159 - select {
160 - case <-readerStopped:
161 - case <-time.After(time.Second):
162 - t.Fatal("reader timed out")
163 - }
164 - if msgsReceived != N {
165 - t.Fatalf("messages received: %d", msgsReceived)
166 - }
167 -}
168 -
169 -func TestConnReadDeadline(t *testing.T) {
170 - ls, _ := NewSocket("udp", "localhost:0")
171 - ds, _ := NewSocket("udp", "localhost:0")
172 - dcReadErr := make(chan error)
173 - go func() {
174 - c, _ := ds.Dial(ls.Addr().String())
175 - defer c.Close()
176 - _, err := c.Read(nil)
177 - dcReadErr <- err
178 - }()
179 - c, _ := ls.Accept()
180 - dl := time.Now().Add(time.Millisecond)
181 - c.SetReadDeadline(dl)
182 - _, err := c.Read(nil)
183 - require.Equal(t, errTimeout, err)
184 - // The deadline has passed.
185 - if !time.Now().After(dl) {
186 - t.FailNow()
187 - }
188 - // Returns timeout on subsequent read.
189 - _, err = c.Read(nil)
190 - require.Equal(t, errTimeout, err)
191 - // Disable the deadline.
192 - c.SetReadDeadline(time.Time{})
193 - readReturned := make(chan struct{})
194 - go func() {
195 - c.Read(nil)
196 - close(readReturned)
197 - }()
198 - select {
199 - case <-readReturned:
200 - // Read returned but shouldn't have.
201 - t.FailNow()
202 - case <-time.After(time.Millisecond):
203 - }
204 - c.Close()
205 - select {
206 - case <-readReturned:
207 - case <-time.After(time.Millisecond):
208 - t.Fatal("read should return after Conn is closed")
209 - }
210 - if err := <-dcReadErr; err != io.EOF {
211 - t.Fatalf("dial conn read returned %s", err)
212 - }
213 -}
214 -
215 -func connectSelfLots(n int, t testing.TB) {
216 - defer goroutineLeakCheck(t)()
217 - s, err := NewSocket("udp", "localhost:0")
218 - if err != nil {
219 - t.Fatal(err)
220 - }
221 - go func() {
222 - for range iter.N(n) {
223 - c, err := s.Accept()
224 - if err != nil {
225 - log.Fatal(err)
226 - }
227 - defer c.Close()
228 - }
229 - }()
230 - dialErr := make(chan error)
231 - connCh := make(chan net.Conn)
232 - dialSema := make(chan struct{}, backlog)
233 - for range iter.N(n) {
234 - go func() {
235 - dialSema <- struct{}{}
236 - c, err := s.Dial(s.Addr().String())
237 - <-dialSema
238 - if err != nil {
239 - dialErr <- err
240 - return
241 - }
242 - connCh <- c
243 - }()
244 - }
245 - conns := make([]net.Conn, 0, n)
246 - for range iter.N(n) {
247 - select {
248 - case c := <-connCh:
249 - conns = append(conns, c)
250 - case err := <-dialErr:
251 - t.Fatal(err)
252 - }
253 - }
254 - for _, c := range conns {
255 - if c != nil {
256 - c.Close()
257 - }
258 - }
259 - s.mu.Lock()
260 - for len(s.conns) != 0 {
261 - // log.Print(len(s.conns))
262 - s.event.Wait()
263 - }
264 - s.mu.Unlock()
265 - s.Close()
266 -}
267 -
268 -// Connect to ourself heaps.
269 -func TestConnectSelf(t *testing.T) {
270 - // A rough guess says that at worst, I can only have 0x10000/3 connections
271 - // to the same socket, due to fragmentation in the assigned connection
272 - // IDs.
273 - connectSelfLots(0x1000, t)
274 -}
275 -
276 -func BenchmarkConnectSelf(b *testing.B) {
277 - for range iter.N(b.N) {
278 - connectSelfLots(2, b)
279 - }
280 -}
281 -
282 -func BenchmarkNewCloseSocket(b *testing.B) {
283 - for range iter.N(b.N) {
284 - s, err := NewSocket("udp", "localhost:0")
285 - if err != nil {
286 - b.Fatal(err)
287 - }
288 - err = s.Close()
289 - if err != nil {
290 - b.Fatal(err)
291 - }
292 - }
293 -}
294 -
295 -func TestRejectDialBacklogFilled(t *testing.T) {
296 - s, err := NewSocket("udp", "localhost:0")
297 - if err != nil {
298 - t.Fatal(err)
299 - }
300 - errChan := make(chan error, 1)
301 - dial := func() {
302 - _, err := s.Dial(s.Addr().String())
303 - if err != nil {
304 - errChan <- err
305 - }
306 - }
307 - // Fill the backlog.
308 - for range iter.N(backlog + 1) {
309 - go dial()
310 - }
311 - s.mu.Lock()
312 - for len(s.backlog) < backlog {
313 - s.event.Wait()
314 - }
315 - s.mu.Unlock()
316 - select {
317 - case <-errChan:
318 - t.FailNow()
319 - default:
320 - }
321 - // One more connection should cause a dial attempt to get reset.
322 - go dial()
323 - err = <-errChan
324 - if err.Error() != "peer reset" {
325 - t.FailNow()
326 - }
327 - s.Close()
328 -}
329 -
330 -// Make sure that we can reset AfterFunc timers, so we don't have to create
331 -// brand new ones everytime they fire. Specifically for the Conn resend timer.
332 -func TestResetAfterFuncTimer(t *testing.T) {
333 - fired := make(chan struct{})
334 - timer := time.AfterFunc(time.Millisecond, func() {
335 - fired <- struct{}{}
336 - })
337 - <-fired
338 - if timer.Reset(time.Millisecond) {
339 - // The timer should have expired
340 - t.FailNow()
341 - }
342 - <-fired
343 -}
344 -
345 -func connPair() (initer, accepted net.Conn) {
346 - s, err := NewSocket("udp", "localhost:0")
347 - if err != nil {
348 - panic(err)
349 - }
350 - defer s.Close()
351 - var wg sync.WaitGroup
352 - wg.Add(1)
353 - go func() {
354 - defer wg.Done()
355 - var err error
356 - initer, err = Dial(s.Addr().String())
357 - if err != nil {
358 - panic(err)
359 - }
360 - }()
361 - accepted, err = s.Accept()
362 - if err != nil {
363 - panic(err)
364 - }
365 - wg.Wait()
366 - return
367 -}
368 -
369 -// Check that peer sending FIN doesn't cause unread data to be dropped in a
370 -// receiver.
371 -func TestReadFinishedConn(t *testing.T) {
372 - a, b := connPair()
373 - defer a.Close()
374 - defer b.Close()
375 - mu.Lock()
376 - originalAPDC := artificialPacketDropChance
377 - artificialPacketDropChance = 1
378 - mu.Unlock()
379 - n, err := a.Write([]byte("hello"))
380 - require.Equal(t, 5, n)
381 - require.NoError(t, err)
382 - n, err = a.Write([]byte("world"))
383 - require.Equal(t, 5, n)
384 - require.NoError(t, err)
385 - mu.Lock()
386 - artificialPacketDropChance = originalAPDC
387 - mu.Unlock()
388 - a.Close()
389 - all, err := ioutil.ReadAll(b)
390 - require.NoError(t, err)
391 - require.EqualValues(t, "helloworld", all)
392 -}
393 -
394 -func TestCloseDetachesQuickly(t *testing.T) {
395 - s, _ := NewSocket("udp", "localhost:0")
396 - defer s.Close()
397 - go func() {
398 - a, _ := s.Dial(s.Addr().String())
399 - log.Print("close a")
400 - a.Close()
401 - log.Print("closed a")
402 - }()
403 - b, _ := s.Accept()
404 - b.Close()
405 - s.mu.Lock()
406 - for len(s.conns) != 0 {
407 - log.Print(len(s.conns))
408 - s.event.Wait()
409 - }
410 - s.mu.Unlock()
411 -}
Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml new
+18
@@ -0,0 +1,18 @@
1 +language: go
2 +sudo: false
3 +
4 +go:
5 +- 1.1.2
6 +- 1.2.2
7 +- 1.3.3
8 +- 1.4.2
9 +- 1.5.1
10 +- tip
11 +
12 +matrix:
13 + allow_failures:
14 + - go: tip
15 +
16 +script:
17 +- go vet ./...
18 +- go test -v ./...
Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE new
+21
@@ -0,0 +1,21 @@
1 +Copyright (C) 2013 Jeremy Saenz
2 +All Rights Reserved.
3 +
4 +MIT LICENSE
5 +
6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
7 +this software and associated documentation files (the "Software"), to deal in
8 +the Software without restriction, including without limitation the rights to
9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 +the Software, and to permit persons to whom the Software is furnished to do so,
11 +subject to the following conditions:
12 +
13 +The above copyright notice and this permission notice shall be included in all
14 +copies or substantial portions of the Software.
15 +
16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Godeps/_workspace/src/github.com/codegangsta/cli/README.md new
+394
@@ -0,0 +1,394 @@
1 +[![Coverage](http://gocover.io/_badge/github.com/codegangsta/cli?0)](http://gocover.io/github.com/codegangsta/cli)
2 +[![Build Status](https://travis-ci.org/codegangsta/cli.svg?branch=master)](https://travis-ci.org/codegangsta/cli)
3 +[![GoDoc](https://godoc.org/github.com/codegangsta/cli?status.svg)](https://godoc.org/github.com/codegangsta/cli)
4 +
5 +# cli.go
6 +
7 +`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way.
8 +
9 +## Overview
10 +
11 +Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app.
12 +
13 +**This is where `cli.go` comes into play.** `cli.go` makes command line programming fun, organized, and expressive!
14 +
15 +## Installation
16 +
17 +Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html).
18 +
19 +To install `cli.go`, simply run:
20 +```
21 +$ go get github.com/codegangsta/cli
22 +```
23 +
24 +Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used:
25 +```
26 +export PATH=$PATH:$GOPATH/bin
27 +```
28 +
29 +## Getting Started
30 +
31 +One of the philosophies behind `cli.go` is that an API should be playful and full of discovery. So a `cli.go` app can be as little as one line of code in `main()`.
32 +
33 +``` go
34 +package main
35 +
36 +import (
37 + "os"
38 + "github.com/codegangsta/cli"
39 +)
40 +
41 +func main() {
42 + cli.NewApp().Run(os.Args)
43 +}
44 +```
45 +
46 +This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation:
47 +
48 +``` go
49 +package main
50 +
51 +import (
52 + "os"
53 + "github.com/codegangsta/cli"
54 +)
55 +
56 +func main() {
57 + app := cli.NewApp()
58 + app.Name = "boom"
59 + app.Usage = "make an explosive entrance"
60 + app.Action = func(c *cli.Context) {
61 + println("boom! I say!")
62 + }
63 +
64 + app.Run(os.Args)
65 +}
66 +```
67 +
68 +Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below.
69 +
70 +## Example
71 +
72 +Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness!
73 +
74 +Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it:
75 +
76 +``` go
77 +package main
78 +
79 +import (
80 + "os"
81 + "github.com/codegangsta/cli"
82 +)
83 +
84 +func main() {
85 + app := cli.NewApp()
86 + app.Name = "greet"
87 + app.Usage = "fight the loneliness!"
88 + app.Action = func(c *cli.Context) {
89 + println("Hello friend!")
90 + }
91 +
92 + app.Run(os.Args)
93 +}
94 +```
95 +
96 +Install our command to the `$GOPATH/bin` directory:
97 +
98 +```
99 +$ go install
100 +```
101 +
102 +Finally run our new command:
103 +
104 +```
105 +$ greet
106 +Hello friend!
107 +```
108 +
109 +`cli.go` also generates neat help text:
110 +
111 +```
112 +$ greet help
113 +NAME:
114 + greet - fight the loneliness!
115 +
116 +USAGE:
117 + greet [global options] command [command options] [arguments...]
118 +
119 +VERSION:
120 + 0.0.0
121 +
122 +COMMANDS:
123 + help, h Shows a list of commands or help for one command
124 +
125 +GLOBAL OPTIONS
126 + --version Shows version information
127 +```
128 +
129 +### Arguments
130 +
131 +You can lookup arguments by calling the `Args` function on `cli.Context`.
132 +
133 +``` go
134 +...
135 +app.Action = func(c *cli.Context) {
136 + println("Hello", c.Args()[0])
137 +}
138 +...
139 +```
140 +
141 +### Flags
142 +
143 +Setting and querying flags is simple.
144 +
145 +``` go
146 +...
147 +app.Flags = []cli.Flag {
148 + cli.StringFlag{
149 + Name: "lang",
150 + Value: "english",
151 + Usage: "language for the greeting",
152 + },
153 +}
154 +app.Action = func(c *cli.Context) {
155 + name := "someone"
156 + if c.NArg() > 0 {
157 + name = c.Args()[0]
158 + }
159 + if c.String("lang") == "spanish" {
160 + println("Hola", name)
161 + } else {
162 + println("Hello", name)
163 + }
164 +}
165 +...
166 +```
167 +
168 +You can also set a destination variable for a flag, to which the content will be scanned.
169 +
170 +``` go
171 +...
172 +var language string
173 +app.Flags = []cli.Flag {
174 + cli.StringFlag{
175 + Name: "lang",
176 + Value: "english",
177 + Usage: "language for the greeting",
178 + Destination: &language,
179 + },
180 +}
181 +app.Action = func(c *cli.Context) {
182 + name := "someone"
183 + if c.NArg() > 0 {
184 + name = c.Args()[0]
185 + }
186 + if language == "spanish" {
187 + println("Hola", name)
188 + } else {
189 + println("Hello", name)
190 + }
191 +}
192 +...
193 +```
194 +
195 +See full list of flags at http://godoc.org/github.com/codegangsta/cli
196 +
197 +#### Alternate Names
198 +
199 +You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g.
200 +
201 +``` go
202 +app.Flags = []cli.Flag {
203 + cli.StringFlag{
204 + Name: "lang, l",
205 + Value: "english",
206 + Usage: "language for the greeting",
207 + },
208 +}
209 +```
210 +
211 +That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error.
212 +
213 +#### Values from the Environment
214 +
215 +You can also have the default value set from the environment via `EnvVar`. e.g.
216 +
217 +``` go
218 +app.Flags = []cli.Flag {
219 + cli.StringFlag{
220 + Name: "lang, l",
221 + Value: "english",
222 + Usage: "language for the greeting",
223 + EnvVar: "APP_LANG",
224 + },
225 +}
226 +```
227 +
228 +The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default.
229 +
230 +``` go
231 +app.Flags = []cli.Flag {
232 + cli.StringFlag{
233 + Name: "lang, l",
234 + Value: "english",
235 + Usage: "language for the greeting",
236 + EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG",
237 + },
238 +}
239 +```
240 +
241 +#### Values from alternate input sources (YAML and others)
242 +
243 +There is a separate package altsrc that adds support for getting flag values from other input sources like YAML.
244 +
245 +In order to get values for a flag from an alternate input source the following code would be added to wrap an existing cli.Flag like below:
246 +
247 +``` go
248 + altsrc.NewIntFlag(cli.IntFlag{Name: "test"})
249 +```
250 +
251 +Initialization must also occur for these flags. Below is an example initializing getting data from a yaml file below.
252 +
253 +``` go
254 + command.Before = altsrc.InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load"))
255 +```
256 +
257 +The code above will use the "load" string as a flag name to get the file name of a yaml file from the cli.Context.
258 +It will then use that file name to initialize the yaml input source for any flags that are defined on that command.
259 +As a note the "load" flag used would also have to be defined on the command flags in order for this code snipped to work.
260 +
261 +Currently only YAML files are supported but developers can add support for other input sources by implementing the
262 +altsrc.InputSourceContext for their given sources.
263 +
264 +Here is a more complete sample of a command using YAML support:
265 +
266 +``` go
267 + command := &cli.Command{
268 + Name: "test-cmd",
269 + Aliases: []string{"tc"},
270 + Usage: "this is for testing",
271 + Description: "testing",
272 + Action: func(c *cli.Context) {
273 + // Action to run
274 + },
275 + Flags: []cli.Flag{
276 + NewIntFlag(cli.IntFlag{Name: "test"}),
277 + cli.StringFlag{Name: "load"}},
278 + }
279 + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load"))
280 + err := command.Run(c)
281 +```
282 +
283 +### Subcommands
284 +
285 +Subcommands can be defined for a more git-like command line app.
286 +
287 +```go
288 +...
289 +app.Commands = []cli.Command{
290 + {
291 + Name: "add",
292 + Aliases: []string{"a"},
293 + Usage: "add a task to the list",
294 + Action: func(c *cli.Context) {
295 + println("added task: ", c.Args().First())
296 + },
297 + },
298 + {
299 + Name: "complete",
300 + Aliases: []string{"c"},
301 + Usage: "complete a task on the list",
302 + Action: func(c *cli.Context) {
303 + println("completed task: ", c.Args().First())
304 + },
305 + },
306 + {
307 + Name: "template",
308 + Aliases: []string{"r"},
309 + Usage: "options for task templates",
310 + Subcommands: []cli.Command{
311 + {
312 + Name: "add",
313 + Usage: "add a new template",
314 + Action: func(c *cli.Context) {
315 + println("new task template: ", c.Args().First())
316 + },
317 + },
318 + {
319 + Name: "remove",
320 + Usage: "remove an existing template",
321 + Action: func(c *cli.Context) {
322 + println("removed task template: ", c.Args().First())
323 + },
324 + },
325 + },
326 + },
327 +}
328 +...
329 +```
330 +
331 +### Bash Completion
332 +
333 +You can enable completion commands by setting the `EnableBashCompletion`
334 +flag on the `App` object. By default, this setting will only auto-complete to
335 +show an app's subcommands, but you can write your own completion methods for
336 +the App or its subcommands.
337 +
338 +```go
339 +...
340 +var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"}
341 +app := cli.NewApp()
342 +app.EnableBashCompletion = true
343 +app.Commands = []cli.Command{
344 + {
345 + Name: "complete",
346 + Aliases: []string{"c"},
347 + Usage: "complete a task on the list",
348 + Action: func(c *cli.Context) {
349 + println("completed task: ", c.Args().First())
350 + },
351 + BashComplete: func(c *cli.Context) {
352 + // This will complete if no args are passed
353 + if c.NArg() > 0 {
354 + return
355 + }
356 + for _, t := range tasks {
357 + fmt.Println(t)
358 + }
359 + },
360 + }
361 +}
362 +...
363 +```
364 +
365 +#### To Enable
366 +
367 +Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while
368 +setting the `PROG` variable to the name of your program:
369 +
370 +`PROG=myprogram source /.../cli/autocomplete/bash_autocomplete`
371 +
372 +#### To Distribute
373 +
374 +Copy `autocomplete/bash_autocomplete` into `/etc/bash_completion.d/` and rename
375 +it to the name of the program you wish to add autocomplete support for (or
376 +automatically install it there if you are distributing a package). Don't forget
377 +to source the file to make it active in the current shell.
378 +
379 +```
380 +sudo cp src/bash_autocomplete /etc/bash_completion.d/<myprogram>
381 +source /etc/bash_completion.d/<myprogram>
382 +```
383 +
384 +Alternatively, you can just document that users should source the generic
385 +`autocomplete/bash_autocomplete` in their bash configuration with `$PROG` set
386 +to the name of their program (as above).
387 +
388 +## Contribution Guidelines
389 +
390 +Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch.
391 +
392 +If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together.
393 +
394 +If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out.
Godeps/_workspace/src/github.com/codegangsta/cli/altsrc/flag.go new
+439
@@ -0,0 +1,439 @@
1 +package altsrc
2 +
3 +import (
4 + "flag"
5 + "fmt"
6 + "os"
7 + "strconv"
8 + "strings"
9 +
10 + "github.com/codegangsta/cli"
11 +)
12 +
13 +// FlagInputSourceExtension is an extension interface of cli.Flag that
14 +// allows a value to be set on the existing parsed flags.
15 +type FlagInputSourceExtension interface {
16 + cli.Flag
17 + ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error
18 +}
19 +
20 +// ApplyInputSourceValues iterates over all provided flags and
21 +// executes ApplyInputSourceValue on flags implementing the
22 +// FlagInputSourceExtension interface to initialize these flags
23 +// to an alternate input source.
24 +func ApplyInputSourceValues(context *cli.Context, inputSourceContext InputSourceContext, flags []cli.Flag) error {
25 + for _, f := range flags {
26 + inputSourceExtendedFlag, isType := f.(FlagInputSourceExtension)
27 + if isType {
28 + err := inputSourceExtendedFlag.ApplyInputSourceValue(context, inputSourceContext)
29 + if err != nil {
30 + return err
31 + }
32 + }
33 + }
34 +
35 + return nil
36 +}
37 +
38 +// InitInputSource is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new
39 +// input source based on the func provided. If there is no error it will then apply the new input source to any flags
40 +// that are supported by the input source
41 +func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) func(context *cli.Context) error {
42 + return func(context *cli.Context) error {
43 + inputSource, err := createInputSource()
44 + if err != nil {
45 + return fmt.Errorf("Unable to create input source: inner error: \n'%v'", err.Error())
46 + }
47 +
48 + return ApplyInputSourceValues(context, inputSource, flags)
49 + }
50 +}
51 +
52 +// InitInputSourceWithContext is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new
53 +// input source based on the func provided with potentially using existing cli.Context values to initialize itself. If there is
54 +// no error it will then apply the new input source to any flags that are supported by the input source
55 +func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(context *cli.Context) (InputSourceContext, error)) func(context *cli.Context) error {
56 + return func(context *cli.Context) error {
57 + inputSource, err := createInputSource(context)
58 + if err != nil {
59 + return fmt.Errorf("Unable to create input source with context: inner error: \n'%v'", err.Error())
60 + }
61 +
62 + return ApplyInputSourceValues(context, inputSource, flags)
63 + }
64 +}
65 +
66 +// GenericFlag is the flag type that wraps cli.GenericFlag to allow
67 +// for other values to be specified
68 +type GenericFlag struct {
69 + cli.GenericFlag
70 + set *flag.FlagSet
71 +}
72 +
73 +// NewGenericFlag creates a new GenericFlag
74 +func NewGenericFlag(flag cli.GenericFlag) *GenericFlag {
75 + return &GenericFlag{GenericFlag: flag, set: nil}
76 +}
77 +
78 +// ApplyInputSourceValue applies a generic value to the flagSet if required
79 +func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
80 + if f.set != nil {
81 + if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
82 + value, err := isc.Generic(f.GenericFlag.Name)
83 + if err != nil {
84 + return err
85 + }
86 + if value != nil {
87 + eachName(f.Name, func(name string) {
88 + f.set.Set(f.Name, value.String())
89 + })
90 + }
91 + }
92 + }
93 +
94 + return nil
95 +}
96 +
97 +// Apply saves the flagSet for later usage then calls
98 +// the wrapped GenericFlag.Apply
99 +func (f *GenericFlag) Apply(set *flag.FlagSet) {
100 + f.set = set
101 + f.GenericFlag.Apply(set)
102 +}
103 +
104 +// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow
105 +// for other values to be specified
106 +type StringSliceFlag struct {
107 + cli.StringSliceFlag
108 + set *flag.FlagSet
109 +}
110 +
111 +// NewStringSliceFlag creates a new StringSliceFlag
112 +func NewStringSliceFlag(flag cli.StringSliceFlag) *StringSliceFlag {
113 + return &StringSliceFlag{StringSliceFlag: flag, set: nil}
114 +}
115 +
116 +// ApplyInputSourceValue applies a StringSlice value to the flagSet if required
117 +func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
118 + if f.set != nil {
119 + if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
120 + value, err := isc.StringSlice(f.StringSliceFlag.Name)
121 + if err != nil {
122 + return err
123 + }
124 + if value != nil {
125 + var sliceValue cli.StringSlice = value
126 + eachName(f.Name, func(name string) {
127 + underlyingFlag := f.set.Lookup(f.Name)
128 + if underlyingFlag != nil {
129 + underlyingFlag.Value = &sliceValue
130 + }
131 + })
132 + }
133 + }
134 + }
135 + return nil
136 +}
137 +
138 +// Apply saves the flagSet for later usage then calls
139 +// the wrapped StringSliceFlag.Apply
140 +func (f *StringSliceFlag) Apply(set *flag.FlagSet) {
141 + f.set = set
142 + f.StringSliceFlag.Apply(set)
143 +}
144 +
145 +// IntSliceFlag is the flag type that wraps cli.IntSliceFlag to allow
146 +// for other values to be specified
147 +type IntSliceFlag struct {
148 + cli.IntSliceFlag
149 + set *flag.FlagSet
150 +}
151 +
152 +// NewIntSliceFlag creates a new IntSliceFlag
153 +func NewIntSliceFlag(flag cli.IntSliceFlag) *IntSliceFlag {
154 + return &IntSliceFlag{IntSliceFlag: flag, set: nil}
155 +}
156 +
157 +// ApplyInputSourceValue applies a IntSlice value if required
158 +func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
159 + if f.set != nil {
160 + if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
161 + value, err := isc.IntSlice(f.IntSliceFlag.Name)
162 + if err != nil {
163 + return err
164 + }
165 + if value != nil {
166 + var sliceValue cli.IntSlice = value
167 + eachName(f.Name, func(name string) {
168 + underlyingFlag := f.set.Lookup(f.Name)
169 + if underlyingFlag != nil {
170 + underlyingFlag.Value = &sliceValue
171 + }
172 + })
173 + }
174 + }
175 + }
176 + return nil
177 +}
178 +
179 +// Apply saves the flagSet for later usage then calls
180 +// the wrapped IntSliceFlag.Apply
181 +func (f *IntSliceFlag) Apply(set *flag.FlagSet) {
182 + f.set = set
183 + f.IntSliceFlag.Apply(set)
184 +}
185 +
186 +// BoolFlag is the flag type that wraps cli.BoolFlag to allow
187 +// for other values to be specified
188 +type BoolFlag struct {
189 + cli.BoolFlag
190 + set *flag.FlagSet
191 +}
192 +
193 +// NewBoolFlag creates a new BoolFlag
194 +func NewBoolFlag(flag cli.BoolFlag) *BoolFlag {
195 + return &BoolFlag{BoolFlag: flag, set: nil}
196 +}
197 +
198 +// ApplyInputSourceValue applies a Bool value to the flagSet if required
199 +func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
200 + if f.set != nil {
201 + if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
202 + value, err := isc.Bool(f.BoolFlag.Name)
203 + if err != nil {
204 + return err
205 + }
206 + if value {
207 + eachName(f.Name, func(name string) {
208 + f.set.Set(f.Name, strconv.FormatBool(value))
209 + })
210 + }
211 + }
212 + }
213 + return nil
214 +}
215 +
216 +// Apply saves the flagSet for later usage then calls
217 +// the wrapped BoolFlag.Apply
218 +func (f *BoolFlag) Apply(set *flag.FlagSet) {
219 + f.set = set
220 + f.BoolFlag.Apply(set)
221 +}
222 +
223 +// BoolTFlag is the flag type that wraps cli.BoolTFlag to allow
224 +// for other values to be specified
225 +type BoolTFlag struct {
226 + cli.BoolTFlag
227 + set *flag.FlagSet
228 +}
229 +
230 +// NewBoolTFlag creates a new BoolTFlag
231 +func NewBoolTFlag(flag cli.BoolTFlag) *BoolTFlag {
232 + return &BoolTFlag{BoolTFlag: flag, set: nil}
233 +}
234 +
235 +// ApplyInputSourceValue applies a BoolT value to the flagSet if required
236 +func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
237 + if f.set != nil {
238 + if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
239 + value, err := isc.BoolT(f.BoolTFlag.Name)
240 + if err != nil {
241 + return err
242 + }
243 + if !value {
244 + eachName(f.Name, func(name string) {
245 + f.set.Set(f.Name, strconv.FormatBool(value))
246 + })
247 + }
248 + }
249 + }
250 + return nil
251 +}
252 +
253 +// Apply saves the flagSet for later usage then calls
254 +// the wrapped BoolTFlag.Apply
255 +func (f *BoolTFlag) Apply(set *flag.FlagSet) {
256 + f.set = set
257 +
258 + f.BoolTFlag.Apply(set)
259 +}
260 +
261 +// StringFlag is the flag type that wraps cli.StringFlag to allow
262 +// for other values to be specified
263 +type StringFlag struct {
264 + cli.StringFlag
265 + set *flag.FlagSet
266 +}
267 +
268 +// NewStringFlag creates a new StringFlag
269 +func NewStringFlag(flag cli.StringFlag) *StringFlag {
270 + return &StringFlag{StringFlag: flag, set: nil}
271 +}
272 +
273 +// ApplyInputSourceValue applies a String value to the flagSet if required
274 +func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
275 + if f.set != nil {
276 + if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
277 + value, err := isc.String(f.StringFlag.Name)
278 + if err != nil {
279 + return err
280 + }
281 + if value != "" {
282 + eachName(f.Name, func(name string) {
283 + f.set.Set(f.Name, value)
284 + })
285 + }
286 + }
287 + }
288 + return nil
289 +}
290 +
291 +// Apply saves the flagSet for later usage then calls
292 +// the wrapped StringFlag.Apply
293 +func (f *StringFlag) Apply(set *flag.FlagSet) {
294 + f.set = set
295 +
296 + f.StringFlag.Apply(set)
297 +}
298 +
299 +// IntFlag is the flag type that wraps cli.IntFlag to allow
300 +// for other values to be specified
301 +type IntFlag struct {
302 + cli.IntFlag
303 + set *flag.FlagSet
304 +}
305 +
306 +// NewIntFlag creates a new IntFlag
307 +func NewIntFlag(flag cli.IntFlag) *IntFlag {
308 + return &IntFlag{IntFlag: flag, set: nil}
309 +}
310 +
311 +// ApplyInputSourceValue applies a int value to the flagSet if required
312 +func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
313 + if f.set != nil {
314 + if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
315 + value, err := isc.Int(f.IntFlag.Name)
316 + if err != nil {
317 + return err
318 + }
319 + if value > 0 {
320 + eachName(f.Name, func(name string) {
321 + f.set.Set(f.Name, strconv.FormatInt(int64(value), 10))
322 + })
323 + }
324 + }
325 + }
326 + return nil
327 +}
328 +
329 +// Apply saves the flagSet for later usage then calls
330 +// the wrapped IntFlag.Apply
331 +func (f *IntFlag) Apply(set *flag.FlagSet) {
332 + f.set = set
333 + f.IntFlag.Apply(set)
334 +}
335 +
336 +// DurationFlag is the flag type that wraps cli.DurationFlag to allow
337 +// for other values to be specified
338 +type DurationFlag struct {
339 + cli.DurationFlag
340 + set *flag.FlagSet
341 +}
342 +
343 +// NewDurationFlag creates a new DurationFlag
344 +func NewDurationFlag(flag cli.DurationFlag) *DurationFlag {
345 + return &DurationFlag{DurationFlag: flag, set: nil}
346 +}
347 +
348 +// ApplyInputSourceValue applies a Duration value to the flagSet if required
349 +func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
350 + if f.set != nil {
351 + if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
352 + value, err := isc.Duration(f.DurationFlag.Name)
353 + if err != nil {
354 + return err
355 + }
356 + if value > 0 {
357 + eachName(f.Name, func(name string) {
358 + f.set.Set(f.Name, value.String())
359 + })
360 + }
361 + }
362 + }
363 + return nil
364 +}
365 +
366 +// Apply saves the flagSet for later usage then calls
367 +// the wrapped DurationFlag.Apply
368 +func (f *DurationFlag) Apply(set *flag.FlagSet) {
369 + f.set = set
370 +
371 + f.DurationFlag.Apply(set)
372 +}
373 +
374 +// Float64Flag is the flag type that wraps cli.Float64Flag to allow
375 +// for other values to be specified
376 +type Float64Flag struct {
377 + cli.Float64Flag
378 + set *flag.FlagSet
379 +}
380 +
381 +// NewFloat64Flag creates a new Float64Flag
382 +func NewFloat64Flag(flag cli.Float64Flag) *Float64Flag {
383 + return &Float64Flag{Float64Flag: flag, set: nil}
384 +}
385 +
386 +// ApplyInputSourceValue applies a Float64 value to the flagSet if required
387 +func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
388 + if f.set != nil {
389 + if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
390 + value, err := isc.Float64(f.Float64Flag.Name)
391 + if err != nil {
392 + return err
393 + }
394 + if value > 0 {
395 + floatStr := float64ToString(value)
396 + eachName(f.Name, func(name string) {
397 + f.set.Set(f.Name, floatStr)
398 + })
399 + }
400 + }
401 + }
402 + return nil
403 +}
404 +
405 +// Apply saves the flagSet for later usage then calls
406 +// the wrapped Float64Flag.Apply
407 +func (f *Float64Flag) Apply(set *flag.FlagSet) {
408 + f.set = set
409 +
410 + f.Float64Flag.Apply(set)
411 +}
412 +
413 +func isEnvVarSet(envVars string) bool {
414 + for _, envVar := range strings.Split(envVars, ",") {
415 + envVar = strings.TrimSpace(envVar)
416 + if envVal := os.Getenv(envVar); envVal != "" {
417 + // TODO: Can't use this for bools as
418 + // set means that it was true or false based on
419 + // Bool flag type, should work for other types
420 + if len(envVal) > 0 {
421 + return true
422 + }
423 + }
424 + }
425 +
426 + return false
427 +}
428 +
429 +func float64ToString(f float64) string {
430 + return fmt.Sprintf("%v", f)
431 +}
432 +
433 +func eachName(longName string, fn func(string)) {
434 + parts := strings.Split(longName, ",")
435 + for _, name := range parts {
436 + name = strings.Trim(name, " ")
437 + fn(name)
438 + }
439 +}
Godeps/_workspace/src/github.com/codegangsta/cli/altsrc/flag_test.go new
+336
@@ -0,0 +1,336 @@
1 +package altsrc
2 +
3 +import (
4 + "flag"
5 + "fmt"
6 + "os"
7 + "strings"
8 + "testing"
9 + "time"
10 +
11 + "github.com/codegangsta/cli"
12 +)
13 +
14 +type testApplyInputSource struct {
15 + Flag FlagInputSourceExtension
16 + FlagName string
17 + FlagSetName string
18 + Expected string
19 + ContextValueString string
20 + ContextValue flag.Value
21 + EnvVarValue string
22 + EnvVarName string
23 + MapValue interface{}
24 +}
25 +
26 +func TestGenericApplyInputSourceValue(t *testing.T) {
27 + v := &Parser{"abc", "def"}
28 + c := runTest(t, testApplyInputSource{
29 + Flag: NewGenericFlag(cli.GenericFlag{Name: "test", Value: &Parser{}}),
30 + FlagName: "test",
31 + MapValue: v,
32 + })
33 + expect(t, v, c.Generic("test"))
34 +}
35 +
36 +func TestGenericApplyInputSourceMethodContextSet(t *testing.T) {
37 + p := &Parser{"abc", "def"}
38 + c := runTest(t, testApplyInputSource{
39 + Flag: NewGenericFlag(cli.GenericFlag{Name: "test", Value: &Parser{}}),
40 + FlagName: "test",
41 + MapValue: &Parser{"efg", "hig"},
42 + ContextValueString: p.String(),
43 + })
44 + expect(t, p, c.Generic("test"))
45 +}
46 +
47 +func TestGenericApplyInputSourceMethodEnvVarSet(t *testing.T) {
48 + c := runTest(t, testApplyInputSource{
49 + Flag: NewGenericFlag(cli.GenericFlag{Name: "test", Value: &Parser{}, EnvVar: "TEST"}),
50 + FlagName: "test",
51 + MapValue: &Parser{"efg", "hij"},
52 + EnvVarName: "TEST",
53 + EnvVarValue: "abc,def",
54 + })
55 + expect(t, &Parser{"abc", "def"}, c.Generic("test"))
56 +}
57 +
58 +func TestStringSliceApplyInputSourceValue(t *testing.T) {
59 + c := runTest(t, testApplyInputSource{
60 + Flag: NewStringSliceFlag(cli.StringSliceFlag{Name: "test"}),
61 + FlagName: "test",
62 + MapValue: []string{"hello", "world"},
63 + })
64 + expect(t, c.StringSlice("test"), []string{"hello", "world"})
65 +}
66 +
67 +func TestStringSliceApplyInputSourceMethodContextSet(t *testing.T) {
68 + c := runTest(t, testApplyInputSource{
69 + Flag: NewStringSliceFlag(cli.StringSliceFlag{Name: "test"}),
70 + FlagName: "test",
71 + MapValue: []string{"hello", "world"},
72 + ContextValueString: "ohno",
73 + })
74 + expect(t, c.StringSlice("test"), []string{"ohno"})
75 +}
76 +
77 +func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
78 + c := runTest(t, testApplyInputSource{
79 + Flag: NewStringSliceFlag(cli.StringSliceFlag{Name: "test", EnvVar: "TEST"}),
80 + FlagName: "test",
81 + MapValue: []string{"hello", "world"},
82 + EnvVarName: "TEST",
83 + EnvVarValue: "oh,no",
84 + })
85 + expect(t, c.StringSlice("test"), []string{"oh", "no"})
86 +}
87 +
88 +func TestIntSliceApplyInputSourceValue(t *testing.T) {
89 + c := runTest(t, testApplyInputSource{
90 + Flag: NewIntSliceFlag(cli.IntSliceFlag{Name: "test"}),
91 + FlagName: "test",
92 + MapValue: []int{1, 2},
93 + })
94 + expect(t, c.IntSlice("test"), []int{1, 2})
95 +}
96 +
97 +func TestIntSliceApplyInputSourceMethodContextSet(t *testing.T) {
98 + c := runTest(t, testApplyInputSource{
99 + Flag: NewIntSliceFlag(cli.IntSliceFlag{Name: "test"}),
100 + FlagName: "test",
101 + MapValue: []int{1, 2},
102 + ContextValueString: "3",
103 + })
104 + expect(t, c.IntSlice("test"), []int{3})
105 +}
106 +
107 +func TestIntSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
108 + c := runTest(t, testApplyInputSource{
109 + Flag: NewIntSliceFlag(cli.IntSliceFlag{Name: "test", EnvVar: "TEST"}),
110 + FlagName: "test",
111 + MapValue: []int{1, 2},
112 + EnvVarName: "TEST",
113 + EnvVarValue: "3,4",
114 + })
115 + expect(t, c.IntSlice("test"), []int{3, 4})
116 +}
117 +
118 +func TestBoolApplyInputSourceMethodSet(t *testing.T) {
119 + c := runTest(t, testApplyInputSource{
120 + Flag: NewBoolFlag(cli.BoolFlag{Name: "test"}),
121 + FlagName: "test",
122 + MapValue: true,
123 + })
124 + expect(t, true, c.Bool("test"))
125 +}
126 +
127 +func TestBoolApplyInputSourceMethodContextSet(t *testing.T) {
128 + c := runTest(t, testApplyInputSource{
129 + Flag: NewBoolFlag(cli.BoolFlag{Name: "test"}),
130 + FlagName: "test",
131 + MapValue: false,
132 + ContextValueString: "true",
133 + })
134 + expect(t, true, c.Bool("test"))
135 +}
136 +
137 +func TestBoolApplyInputSourceMethodEnvVarSet(t *testing.T) {
138 + c := runTest(t, testApplyInputSource{
139 + Flag: NewBoolFlag(cli.BoolFlag{Name: "test", EnvVar: "TEST"}),
140 + FlagName: "test",
141 + MapValue: false,
142 + EnvVarName: "TEST",
143 + EnvVarValue: "true",
144 + })
145 + expect(t, true, c.Bool("test"))
146 +}
147 +
148 +func TestBoolTApplyInputSourceMethodSet(t *testing.T) {
149 + c := runTest(t, testApplyInputSource{
150 + Flag: NewBoolTFlag(cli.BoolTFlag{Name: "test"}),
151 + FlagName: "test",
152 + MapValue: false,
153 + })
154 + expect(t, false, c.BoolT("test"))
155 +}
156 +
157 +func TestBoolTApplyInputSourceMethodContextSet(t *testing.T) {
158 + c := runTest(t, testApplyInputSource{
159 + Flag: NewBoolTFlag(cli.BoolTFlag{Name: "test"}),
160 + FlagName: "test",
161 + MapValue: true,
162 + ContextValueString: "false",
163 + })
164 + expect(t, false, c.BoolT("test"))
165 +}
166 +
167 +func TestBoolTApplyInputSourceMethodEnvVarSet(t *testing.T) {
168 + c := runTest(t, testApplyInputSource{
169 + Flag: NewBoolTFlag(cli.BoolTFlag{Name: "test", EnvVar: "TEST"}),
170 + FlagName: "test",
171 + MapValue: true,
172 + EnvVarName: "TEST",
173 + EnvVarValue: "false",
174 + })
175 + expect(t, false, c.BoolT("test"))
176 +}
177 +
178 +func TestStringApplyInputSourceMethodSet(t *testing.T) {
179 + c := runTest(t, testApplyInputSource{
180 + Flag: NewStringFlag(cli.StringFlag{Name: "test"}),
181 + FlagName: "test",
182 + MapValue: "hello",
183 + })
184 + expect(t, "hello", c.String("test"))
185 +}
186 +
187 +func TestStringApplyInputSourceMethodContextSet(t *testing.T) {
188 + c := runTest(t, testApplyInputSource{
189 + Flag: NewStringFlag(cli.StringFlag{Name: "test"}),
190 + FlagName: "test",
191 + MapValue: "hello",
192 + ContextValueString: "goodbye",
193 + })
194 + expect(t, "goodbye", c.String("test"))
195 +}
196 +
197 +func TestStringApplyInputSourceMethodEnvVarSet(t *testing.T) {
198 + c := runTest(t, testApplyInputSource{
199 + Flag: NewStringFlag(cli.StringFlag{Name: "test", EnvVar: "TEST"}),
200 + FlagName: "test",
201 + MapValue: "hello",
202 + EnvVarName: "TEST",
203 + EnvVarValue: "goodbye",
204 + })
205 + expect(t, "goodbye", c.String("test"))
206 +}
207 +
208 +func TestIntApplyInputSourceMethodSet(t *testing.T) {
209 + c := runTest(t, testApplyInputSource{
210 + Flag: NewIntFlag(cli.IntFlag{Name: "test"}),
211 + FlagName: "test",
212 + MapValue: 15,
213 + })
214 + expect(t, 15, c.Int("test"))
215 +}
216 +
217 +func TestIntApplyInputSourceMethodContextSet(t *testing.T) {
218 + c := runTest(t, testApplyInputSource{
219 + Flag: NewIntFlag(cli.IntFlag{Name: "test"}),
220 + FlagName: "test",
221 + MapValue: 15,
222 + ContextValueString: "7",
223 + })
224 + expect(t, 7, c.Int("test"))
225 +}
226 +
227 +func TestIntApplyInputSourceMethodEnvVarSet(t *testing.T) {
228 + c := runTest(t, testApplyInputSource{
229 + Flag: NewIntFlag(cli.IntFlag{Name: "test", EnvVar: "TEST"}),
230 + FlagName: "test",
231 + MapValue: 15,
232 + EnvVarName: "TEST",
233 + EnvVarValue: "12",
234 + })
235 + expect(t, 12, c.Int("test"))
236 +}
237 +
238 +func TestDurationApplyInputSourceMethodSet(t *testing.T) {
239 + c := runTest(t, testApplyInputSource{
240 + Flag: NewDurationFlag(cli.DurationFlag{Name: "test"}),
241 + FlagName: "test",
242 + MapValue: time.Duration(30 * time.Second),
243 + })
244 + expect(t, time.Duration(30*time.Second), c.Duration("test"))
245 +}
246 +
247 +func TestDurationApplyInputSourceMethodContextSet(t *testing.T) {
248 + c := runTest(t, testApplyInputSource{
249 + Flag: NewDurationFlag(cli.DurationFlag{Name: "test"}),
250 + FlagName: "test",
251 + MapValue: time.Duration(30 * time.Second),
252 + ContextValueString: time.Duration(15 * time.Second).String(),
253 + })
254 + expect(t, time.Duration(15*time.Second), c.Duration("test"))
255 +}
256 +
257 +func TestDurationApplyInputSourceMethodEnvVarSet(t *testing.T) {
258 + c := runTest(t, testApplyInputSource{
259 + Flag: NewDurationFlag(cli.DurationFlag{Name: "test", EnvVar: "TEST"}),
260 + FlagName: "test",
261 + MapValue: time.Duration(30 * time.Second),
262 + EnvVarName: "TEST",
263 + EnvVarValue: time.Duration(15 * time.Second).String(),
264 + })
265 + expect(t, time.Duration(15*time.Second), c.Duration("test"))
266 +}
267 +
268 +func TestFloat64ApplyInputSourceMethodSet(t *testing.T) {
269 + c := runTest(t, testApplyInputSource{
270 + Flag: NewFloat64Flag(cli.Float64Flag{Name: "test"}),
271 + FlagName: "test",
272 + MapValue: 1.3,
273 + })
274 + expect(t, 1.3, c.Float64("test"))
275 +}
276 +
277 +func TestFloat64ApplyInputSourceMethodContextSet(t *testing.T) {
278 + c := runTest(t, testApplyInputSource{
279 + Flag: NewFloat64Flag(cli.Float64Flag{Name: "test"}),
280 + FlagName: "test",
281 + MapValue: 1.3,
282 + ContextValueString: fmt.Sprintf("%v", 1.4),
283 + })
284 + expect(t, 1.4, c.Float64("test"))
285 +}
286 +
287 +func TestFloat64ApplyInputSourceMethodEnvVarSet(t *testing.T) {
288 + c := runTest(t, testApplyInputSource{
289 + Flag: NewFloat64Flag(cli.Float64Flag{Name: "test", EnvVar: "TEST"}),
290 + FlagName: "test",
291 + MapValue: 1.3,
292 + EnvVarName: "TEST",
293 + EnvVarValue: fmt.Sprintf("%v", 1.4),
294 + })
295 + expect(t, 1.4, c.Float64("test"))
296 +}
297 +
298 +func runTest(t *testing.T, test testApplyInputSource) *cli.Context {
299 + inputSource := &MapInputSource{valueMap: map[string]interface{}{test.FlagName: test.MapValue}}
300 + set := flag.NewFlagSet(test.FlagSetName, flag.ContinueOnError)
301 + c := cli.NewContext(nil, set, nil)
302 + if test.EnvVarName != "" && test.EnvVarValue != "" {
303 + os.Setenv(test.EnvVarName, test.EnvVarValue)
304 + defer os.Setenv(test.EnvVarName, "")
305 + }
306 +
307 + test.Flag.Apply(set)
308 + if test.ContextValue != nil {
309 + flag := set.Lookup(test.FlagName)
310 + flag.Value = test.ContextValue
311 + }
312 + if test.ContextValueString != "" {
313 + set.Set(test.FlagName, test.ContextValueString)
314 + }
315 + test.Flag.ApplyInputSourceValue(c, inputSource)
316 +
317 + return c
318 +}
319 +
320 +type Parser [2]string
321 +
322 +func (p *Parser) Set(value string) error {
323 + parts := strings.Split(value, ",")
324 + if len(parts) != 2 {
325 + return fmt.Errorf("invalid format")
326 + }
327 +
328 + (*p)[0] = parts[0]
329 + (*p)[1] = parts[1]
330 +
331 + return nil
332 +}
333 +
334 +func (p *Parser) String() string {
335 + return fmt.Sprintf("%s,%s", p[0], p[1])
336 +}
Godeps/_workspace/src/github.com/codegangsta/cli/altsrc/helpers_test.go new
+18
@@ -0,0 +1,18 @@
1 +package altsrc
2 +
3 +import (
4 + "reflect"
5 + "testing"
6 +)
7 +
8 +func expect(t *testing.T, a interface{}, b interface{}) {
9 + if !reflect.DeepEqual(b, a) {
10 + t.Errorf("Expected %#v (type %v) - Got %#v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
11 + }
12 +}
13 +
14 +func refute(t *testing.T, a interface{}, b interface{}) {
15 + if a == b {
16 + t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
17 + }
18 +}
Godeps/_workspace/src/github.com/codegangsta/cli/altsrc/input_source_context.go new
+21
@@ -0,0 +1,21 @@
1 +package altsrc
2 +
3 +import (
4 + "time"
5 +
6 + "github.com/codegangsta/cli"
7 +)
8 +
9 +// InputSourceContext is an interface used to allow
10 +// other input sources to be implemented as needed.
11 +type InputSourceContext interface {
12 + Int(name string) (int, error)
13 + Duration(name string) (time.Duration, error)
14 + Float64(name string) (float64, error)
15 + String(name string) (string, error)
16 + StringSlice(name string) ([]string, error)
17 + IntSlice(name string) ([]int, error)
18 + Generic(name string) (cli.Generic, error)
19 + Bool(name string) (bool, error)
20 + BoolT(name string) (bool, error)
21 +}
Godeps/_workspace/src/github.com/codegangsta/cli/altsrc/map_input_source.go new
+152
@@ -0,0 +1,152 @@
1 +package altsrc
2 +
3 +import (
4 + "fmt"
5 + "reflect"
6 + "time"
7 +
8 + "github.com/codegangsta/cli"
9 +)
10 +
11 +// MapInputSource implements InputSourceContext to return
12 +// data from the map that is loaded.
13 +type MapInputSource struct {
14 + valueMap map[string]interface{}
15 +}
16 +
17 +// Int returns an int from the map if it exists otherwise returns 0
18 +func (fsm *MapInputSource) Int(name string) (int, error) {
19 + otherGenericValue, exists := fsm.valueMap[name]
20 + if exists {
21 + otherValue, isType := otherGenericValue.(int)
22 + if !isType {
23 + return 0, incorrectTypeForFlagError(name, "int", otherGenericValue)
24 + }
25 +
26 + return otherValue, nil
27 + }
28 +
29 + return 0, nil
30 +}
31 +
32 +// Duration returns a duration from the map if it exists otherwise returns 0
33 +func (fsm *MapInputSource) Duration(name string) (time.Duration, error) {
34 + otherGenericValue, exists := fsm.valueMap[name]
35 + if exists {
36 + otherValue, isType := otherGenericValue.(time.Duration)
37 + if !isType {
38 + return 0, incorrectTypeForFlagError(name, "duration", otherGenericValue)
39 + }
40 + return otherValue, nil
41 + }
42 +
43 + return 0, nil
44 +}
45 +
46 +// Float64 returns an float64 from the map if it exists otherwise returns 0
47 +func (fsm *MapInputSource) Float64(name string) (float64, error) {
48 + otherGenericValue, exists := fsm.valueMap[name]
49 + if exists {
50 + otherValue, isType := otherGenericValue.(float64)
51 + if !isType {
52 + return 0, incorrectTypeForFlagError(name, "float64", otherGenericValue)
53 + }
54 + return otherValue, nil
55 + }
56 +
57 + return 0, nil
58 +}
59 +
60 +// String returns a string from the map if it exists otherwise returns an empty string
61 +func (fsm *MapInputSource) String(name string) (string, error) {
62 + otherGenericValue, exists := fsm.valueMap[name]
63 + if exists {
64 + otherValue, isType := otherGenericValue.(string)
65 + if !isType {
66 + return "", incorrectTypeForFlagError(name, "string", otherGenericValue)
67 + }
68 + return otherValue, nil
69 + }
70 +
71 + return "", nil
72 +}
73 +
74 +// StringSlice returns an []string from the map if it exists otherwise returns nil
75 +func (fsm *MapInputSource) StringSlice(name string) ([]string, error) {
76 + otherGenericValue, exists := fsm.valueMap[name]
77 + if exists {
78 + otherValue, isType := otherGenericValue.([]string)
79 + if !isType {
80 + return nil, incorrectTypeForFlagError(name, "[]string", otherGenericValue)
81 + }
82 + return otherValue, nil
83 + }
84 +
85 + return nil, nil
86 +}
87 +
88 +// IntSlice returns an []int from the map if it exists otherwise returns nil
89 +func (fsm *MapInputSource) IntSlice(name string) ([]int, error) {
90 + otherGenericValue, exists := fsm.valueMap[name]
91 + if exists {
92 + otherValue, isType := otherGenericValue.([]int)
93 + if !isType {
94 + return nil, incorrectTypeForFlagError(name, "[]int", otherGenericValue)
95 + }
96 + return otherValue, nil
97 + }
98 +
99 + return nil, nil
100 +}
101 +
102 +// Generic returns an cli.Generic from the map if it exists otherwise returns nil
103 +func (fsm *MapInputSource) Generic(name string) (cli.Generic, error) {
104 + otherGenericValue, exists := fsm.valueMap[name]
105 + if exists {
106 + otherValue, isType := otherGenericValue.(cli.Generic)
107 + if !isType {
108 + return nil, incorrectTypeForFlagError(name, "cli.Generic", otherGenericValue)
109 + }
110 + return otherValue, nil
111 + }
112 +
113 + return nil, nil
114 +}
115 +
116 +// Bool returns an bool from the map otherwise returns false
117 +func (fsm *MapInputSource) Bool(name string) (bool, error) {
118 + otherGenericValue, exists := fsm.valueMap[name]
119 + if exists {
120 + otherValue, isType := otherGenericValue.(bool)
121 + if !isType {
122 + return false, incorrectTypeForFlagError(name, "bool", otherGenericValue)
123 + }
124 + return otherValue, nil
125 + }
126 +
127 + return false, nil
128 +}
129 +
130 +// BoolT returns an bool from the map otherwise returns true
131 +func (fsm *MapInputSource) BoolT(name string) (bool, error) {
132 + otherGenericValue, exists := fsm.valueMap[name]
133 + if exists {
134 + otherValue, isType := otherGenericValue.(bool)
135 + if !isType {
136 + return true, incorrectTypeForFlagError(name, "bool", otherGenericValue)
137 + }
138 + return otherValue, nil
139 + }
140 +
141 + return true, nil
142 +}
143 +
144 +func incorrectTypeForFlagError(name, expectedTypeName string, value interface{}) error {
145 + valueType := reflect.TypeOf(value)
146 + valueTypeName := ""
147 + if valueType != nil {
148 + valueTypeName = valueType.Name()
149 + }
150 +
151 + return fmt.Errorf("Mismatched type for flag '%s'. Expected '%s' but actual is '%s'", name, expectedTypeName, valueTypeName)
152 +}
Godeps/_workspace/src/github.com/codegangsta/cli/altsrc/yaml_command_test.go new
+172
@@ -0,0 +1,172 @@
1 +// Disabling building of yaml support in cases where golang is 1.0 or 1.1
2 +// as the encoding library is not implemented or supported.
3 +
4 +// +build !go1,!go1.1
5 +
6 +package altsrc
7 +
8 +import (
9 + "flag"
10 + "io/ioutil"
11 + "os"
12 + "testing"
13 +
14 + "github.com/codegangsta/cli"
15 +)
16 +
17 +func TestCommandYamlFileTest(t *testing.T) {
18 + app := cli.NewApp()
19 + set := flag.NewFlagSet("test", 0)
20 + ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666)
21 + defer os.Remove("current.yaml")
22 + test := []string{"test-cmd", "--load", "current.yaml"}
23 + set.Parse(test)
24 +
25 + c := cli.NewContext(app, set, nil)
26 +
27 + command := &cli.Command{
28 + Name: "test-cmd",
29 + Aliases: []string{"tc"},
30 + Usage: "this is for testing",
31 + Description: "testing",
32 + Action: func(c *cli.Context) {
33 + val := c.Int("test")
34 + expect(t, val, 15)
35 + },
36 + Flags: []cli.Flag{
37 + NewIntFlag(cli.IntFlag{Name: "test"}),
38 + cli.StringFlag{Name: "load"}},
39 + }
40 + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load"))
41 + err := command.Run(c)
42 +
43 + expect(t, err, nil)
44 +}
45 +
46 +func TestCommandYamlFileTestGlobalEnvVarWins(t *testing.T) {
47 + app := cli.NewApp()
48 + set := flag.NewFlagSet("test", 0)
49 + ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666)
50 + defer os.Remove("current.yaml")
51 +
52 + os.Setenv("THE_TEST", "10")
53 + defer os.Setenv("THE_TEST", "")
54 + test := []string{"test-cmd", "--load", "current.yaml"}
55 + set.Parse(test)
56 +
57 + c := cli.NewContext(app, set, nil)
58 +
59 + command := &cli.Command{
60 + Name: "test-cmd",
61 + Aliases: []string{"tc"},
62 + Usage: "this is for testing",
63 + Description: "testing",
64 + Action: func(c *cli.Context) {
65 + val := c.Int("test")
66 + expect(t, val, 10)
67 + },
68 + Flags: []cli.Flag{
69 + NewIntFlag(cli.IntFlag{Name: "test", EnvVar: "THE_TEST"}),
70 + cli.StringFlag{Name: "load"}},
71 + }
72 + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load"))
73 +
74 + err := command.Run(c)
75 +
76 + expect(t, err, nil)
77 +}
78 +
79 +func TestCommandYamlFileTestSpecifiedFlagWins(t *testing.T) {
80 + app := cli.NewApp()
81 + set := flag.NewFlagSet("test", 0)
82 + ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666)
83 + defer os.Remove("current.yaml")
84 +
85 + test := []string{"test-cmd", "--load", "current.yaml", "--test", "7"}
86 + set.Parse(test)
87 +
88 + c := cli.NewContext(app, set, nil)
89 +
90 + command := &cli.Command{
91 + Name: "test-cmd",
92 + Aliases: []string{"tc"},
93 + Usage: "this is for testing",
94 + Description: "testing",
95 + Action: func(c *cli.Context) {
96 + val := c.Int("test")
97 + expect(t, val, 7)
98 + },
99 + Flags: []cli.Flag{
100 + NewIntFlag(cli.IntFlag{Name: "test"}),
101 + cli.StringFlag{Name: "load"}},
102 + }
103 + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load"))
104 +
105 + err := command.Run(c)
106 +
107 + expect(t, err, nil)
108 +}
109 +
110 +func TestCommandYamlFileTestDefaultValueFileWins(t *testing.T) {
111 + app := cli.NewApp()
112 + set := flag.NewFlagSet("test", 0)
113 + ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666)
114 + defer os.Remove("current.yaml")
115 +
116 + test := []string{"test-cmd", "--load", "current.yaml"}
117 + set.Parse(test)
118 +
119 + c := cli.NewContext(app, set, nil)
120 +
121 + command := &cli.Command{
122 + Name: "test-cmd",
123 + Aliases: []string{"tc"},
124 + Usage: "this is for testing",
125 + Description: "testing",
126 + Action: func(c *cli.Context) {
127 + val := c.Int("test")
128 + expect(t, val, 15)
129 + },
130 + Flags: []cli.Flag{
131 + NewIntFlag(cli.IntFlag{Name: "test", Value: 7}),
132 + cli.StringFlag{Name: "load"}},
133 + }
134 + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load"))
135 +
136 + err := command.Run(c)
137 +
138 + expect(t, err, nil)
139 +}
140 +
141 +func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWins(t *testing.T) {
142 + app := cli.NewApp()
143 + set := flag.NewFlagSet("test", 0)
144 + ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666)
145 + defer os.Remove("current.yaml")
146 +
147 + os.Setenv("THE_TEST", "11")
148 + defer os.Setenv("THE_TEST", "")
149 +
150 + test := []string{"test-cmd", "--load", "current.yaml"}
151 + set.Parse(test)
152 +
153 + c := cli.NewContext(app, set, nil)
154 +
155 + command := &cli.Command{
156 + Name: "test-cmd",
157 + Aliases: []string{"tc"},
158 + Usage: "this is for testing",
159 + Description: "testing",
160 + Action: func(c *cli.Context) {
161 + val := c.Int("test")
162 + expect(t, val, 11)
163 + },
164 + Flags: []cli.Flag{
165 + NewIntFlag(cli.IntFlag{Name: "test", Value: 7, EnvVar: "THE_TEST"}),
166 + cli.StringFlag{Name: "load"}},
167 + }
168 + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load"))
169 + err := command.Run(c)
170 +
171 + expect(t, err, nil)
172 +}
Godeps/_workspace/src/github.com/codegangsta/cli/altsrc/yaml_file_loader.go new
+84
@@ -0,0 +1,84 @@
1 +// Disabling building of yaml support in cases where golang is 1.0 or 1.1
2 +// as the encoding library is not implemented or supported.
3 +
4 +// +build !go1,!go1.1
5 +
6 +package altsrc
7 +
8 +import (
9 + "fmt"
10 + "io/ioutil"
11 + "net/http"
12 + "net/url"
13 + "os"
14 +
15 + "github.com/codegangsta/cli"
16 +
17 + "gopkg.in/yaml.v2"
18 +)
19 +
20 +type yamlSourceContext struct {
21 + FilePath string
22 +}
23 +
24 +// NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath.
25 +func NewYamlSourceFromFile(file string) (InputSourceContext, error) {
26 + ymlLoader := &yamlSourceLoader{FilePath: file}
27 + var results map[string]interface{}
28 + err := readCommandYaml(ysl.FilePath, &results)
29 + if err != nil {
30 + return fmt.Errorf("Unable to load Yaml file '%s': inner error: \n'%v'", filePath, err.Error())
31 + }
32 +
33 + return &MapInputSource{valueMap: results}, nil
34 +}
35 +
36 +// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
37 +func NewYamlSourceFromFlagFunc(flagFileName string) func(InputSourceContext, error) {
38 + return func(context cli.Context) {
39 + filePath := context.String(flagFileName)
40 + return NewYamlSourceFromFile(filePath)
41 + }
42 +}
43 +
44 +func readCommandYaml(filePath string, container interface{}) (err error) {
45 + b, err := loadDataFrom(filePath)
46 + if err != nil {
47 + return err
48 + }
49 +
50 + err = yaml.Unmarshal(b, container)
51 + if err != nil {
52 + return err
53 + }
54 +
55 + err = nil
56 + return
57 +}
58 +
59 +func loadDataFrom(filePath string) ([]byte, error) {
60 + u, err := url.Parse(filePath)
61 + if err != nil {
62 + return nil, err
63 + }
64 +
65 + if u.Host != "" { // i have a host, now do i support the scheme?
66 + switch u.Scheme {
67 + case "http", "https":
68 + res, err := http.Get(filePath)
69 + if err != nil {
70 + return nil, err
71 + }
72 + return ioutil.ReadAll(res.Body)
73 + default:
74 + return nil, fmt.Errorf("scheme of %s is unsupported", filePath)
75 + }
76 + } else if u.Path != "" { // i dont have a host, but I have a path. I am a local file.
77 + if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil {
78 + return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath)
79 + }
80 + return ioutil.ReadFile(filePath)
81 + } else {
82 + return nil, fmt.Errorf("unable to determine how to load from path %s", filePath)
83 + }
84 +}
Godeps/_workspace/src/github.com/codegangsta/cli/app.go new
+349
@@ -0,0 +1,349 @@
1 +package cli
2 +
3 +import (
4 + "fmt"
5 + "io"
6 + "io/ioutil"
7 + "os"
8 + "path"
9 + "time"
10 +)
11 +
12 +// App is the main structure of a cli application. It is recommended that
13 +// an app be created with the cli.NewApp() function
14 +type App struct {
15 + // The name of the program. Defaults to path.Base(os.Args[0])
16 + Name string
17 + // Full name of command for help, defaults to Name
18 + HelpName string
19 + // Description of the program.
20 + Usage string
21 + // Text to override the USAGE section of help
22 + UsageText string
23 + // Description of the program argument format.
24 + ArgsUsage string
25 + // Version of the program
26 + Version string
27 + // List of commands to execute
28 + Commands []Command
29 + // List of flags to parse
30 + Flags []Flag
31 + // Boolean to enable bash completion commands
32 + EnableBashCompletion bool
33 + // Boolean to hide built-in help command
34 + HideHelp bool
35 + // Boolean to hide built-in version flag
36 + HideVersion bool
37 + // An action to execute when the bash-completion flag is set
38 + BashComplete func(context *Context)
39 + // An action to execute before any subcommands are run, but after the context is ready
40 + // If a non-nil error is returned, no subcommands are run
41 + Before func(context *Context) error
42 + // An action to execute after any subcommands are run, but after the subcommand has finished
43 + // It is run even if Action() panics
44 + After func(context *Context) error
45 + // The action to execute when no subcommands are specified
46 + Action func(context *Context)
47 + // Execute this function if the proper command cannot be found
48 + CommandNotFound func(context *Context, command string)
49 + // Execute this function, if an usage error occurs. This is useful for displaying customized usage error messages.
50 + // This function is able to replace the original error messages.
51 + // If this function is not set, the "Incorrect usage" is displayed and the execution is interrupted.
52 + OnUsageError func(context *Context, err error, isSubcommand bool) error
53 + // Compilation date
54 + Compiled time.Time
55 + // List of all authors who contributed
56 + Authors []Author
57 + // Copyright of the binary if any
58 + Copyright string
59 + // Name of Author (Note: Use App.Authors, this is deprecated)
60 + Author string
61 + // Email of Author (Note: Use App.Authors, this is deprecated)
62 + Email string
63 + // Writer writer to write output to
64 + Writer io.Writer
65 +}
66 +
67 +// Tries to find out when this binary was compiled.
68 +// Returns the current time if it fails to find it.
69 +func compileTime() time.Time {
70 + info, err := os.Stat(os.Args[0])
71 + if err != nil {
72 + return time.Now()
73 + }
74 + return info.ModTime()
75 +}
76 +
77 +// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action.
78 +func NewApp() *App {
79 + return &App{
80 + Name: path.Base(os.Args[0]),
81 + HelpName: path.Base(os.Args[0]),
82 + Usage: "A new cli application",
83 + UsageText: "",
84 + Version: "0.0.0",
85 + BashComplete: DefaultAppComplete,
86 + Action: helpCommand.Action,
87 + Compiled: compileTime(),
88 + Writer: os.Stdout,
89 + }
90 +}
91 +
92 +// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination
93 +func (a *App) Run(arguments []string) (err error) {
94 + if a.Author != "" || a.Email != "" {
95 + a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email})
96 + }
97 +
98 + newCmds := []Command{}
99 + for _, c := range a.Commands {
100 + if c.HelpName == "" {
101 + c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
102 + }
103 + newCmds = append(newCmds, c)
104 + }
105 + a.Commands = newCmds
106 +
107 + // append help to commands
108 + if a.Command(helpCommand.Name) == nil && !a.HideHelp {
109 + a.Commands = append(a.Commands, helpCommand)
110 + if (HelpFlag != BoolFlag{}) {
111 + a.appendFlag(HelpFlag)
112 + }
113 + }
114 +
115 + //append version/help flags
116 + if a.EnableBashCompletion {
117 + a.appendFlag(BashCompletionFlag)
118 + }
119 +
120 + if !a.HideVersion {
121 + a.appendFlag(VersionFlag)
122 + }
123 +
124 + // parse flags
125 + set := flagSet(a.Name, a.Flags)
126 + set.SetOutput(ioutil.Discard)
127 + err = set.Parse(arguments[1:])
128 + nerr := normalizeFlags(a.Flags, set)
129 + context := NewContext(a, set, nil)
130 + if nerr != nil {
131 + fmt.Fprintln(a.Writer, nerr)
132 + ShowAppHelp(context)
133 + return nerr
134 + }
135 +
136 + if checkCompletions(context) {
137 + return nil
138 + }
139 +
140 + if err != nil {
141 + if a.OnUsageError != nil {
142 + err := a.OnUsageError(context, err, false)
143 + return err
144 + } else {
145 + fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.")
146 + ShowAppHelp(context)
147 + return err
148 + }
149 + }
150 +
151 + if !a.HideHelp && checkHelp(context) {
152 + ShowAppHelp(context)
153 + return nil
154 + }
155 +
156 + if !a.HideVersion && checkVersion(context) {
157 + ShowVersion(context)
158 + return nil
159 + }
160 +
161 + if a.After != nil {
162 + defer func() {
163 + if afterErr := a.After(context); afterErr != nil {
164 + if err != nil {
165 + err = NewMultiError(err, afterErr)
166 + } else {
167 + err = afterErr
168 + }
169 + }
170 + }()
171 + }
172 +
173 + if a.Before != nil {
174 + err = a.Before(context)
175 + if err != nil {
176 + fmt.Fprintf(a.Writer, "%v\n\n", err)
177 + ShowAppHelp(context)
178 + return err
179 + }
180 + }
181 +
182 + args := context.Args()
183 + if args.Present() {
184 + name := args.First()
185 + c := a.Command(name)
186 + if c != nil {
187 + return c.Run(context)
188 + }
189 + }
190 +
191 + // Run default Action
192 + a.Action(context)
193 + return nil
194 +}
195 +
196 +// Another entry point to the cli app, takes care of passing arguments and error handling
197 +func (a *App) RunAndExitOnError() {
198 + if err := a.Run(os.Args); err != nil {
199 + fmt.Fprintln(os.Stderr, err)
200 + os.Exit(1)
201 + }
202 +}
203 +
204 +// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags
205 +func (a *App) RunAsSubcommand(ctx *Context) (err error) {
206 + // append help to commands
207 + if len(a.Commands) > 0 {
208 + if a.Command(helpCommand.Name) == nil && !a.HideHelp {
209 + a.Commands = append(a.Commands, helpCommand)
210 + if (HelpFlag != BoolFlag{}) {
211 + a.appendFlag(HelpFlag)
212 + }
213 + }
214 + }
215 +
216 + newCmds := []Command{}
217 + for _, c := range a.Commands {
218 + if c.HelpName == "" {
219 + c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
220 + }
221 + newCmds = append(newCmds, c)
222 + }
223 + a.Commands = newCmds
224 +
225 + // append flags
226 + if a.EnableBashCompletion {
227 + a.appendFlag(BashCompletionFlag)
228 + }
229 +
230 + // parse flags
231 + set := flagSet(a.Name, a.Flags)
232 + set.SetOutput(ioutil.Discard)
233 + err = set.Parse(ctx.Args().Tail())
234 + nerr := normalizeFlags(a.Flags, set)
235 + context := NewContext(a, set, ctx)
236 +
237 + if nerr != nil {
238 + fmt.Fprintln(a.Writer, nerr)
239 + fmt.Fprintln(a.Writer)
240 + if len(a.Commands) > 0 {
241 + ShowSubcommandHelp(context)
242 + } else {
243 + ShowCommandHelp(ctx, context.Args().First())
244 + }
245 + return nerr
246 + }
247 +
248 + if checkCompletions(context) {
249 + return nil
250 + }
251 +
252 + if err != nil {
253 + if a.OnUsageError != nil {
254 + err = a.OnUsageError(context, err, true)
255 + return err
256 + } else {
257 + fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.")
258 + ShowSubcommandHelp(context)
259 + return err
260 + }
261 + }
262 +
263 + if len(a.Commands) > 0 {
264 + if checkSubcommandHelp(context) {
265 + return nil
266 + }
267 + } else {
268 + if checkCommandHelp(ctx, context.Args().First()) {
269 + return nil
270 + }
271 + }
272 +
273 + if a.After != nil {
274 + defer func() {
275 + afterErr := a.After(context)
276 + if afterErr != nil {
277 + if err != nil {
278 + err = NewMultiError(err, afterErr)
279 + } else {
280 + err = afterErr
281 + }
282 + }
283 + }()
284 + }
285 +
286 + if a.Before != nil {
287 + err := a.Before(context)
288 + if err != nil {
289 + return err
290 + }
291 + }
292 +
293 + args := context.Args()
294 + if args.Present() {
295 + name := args.First()
296 + c := a.Command(name)
297 + if c != nil {
298 + return c.Run(context)
299 + }
300 + }
301 +
302 + // Run default Action
303 + a.Action(context)
304 +
305 + return nil
306 +}
307 +
308 +// Returns the named command on App. Returns nil if the command does not exist
309 +func (a *App) Command(name string) *Command {
310 + for _, c := range a.Commands {
311 + if c.HasName(name) {
312 + return &c
313 + }
314 + }
315 +
316 + return nil
317 +}
318 +
319 +func (a *App) hasFlag(flag Flag) bool {
320 + for _, f := range a.Flags {
321 + if flag == f {
322 + return true
323 + }
324 + }
325 +
326 + return false
327 +}
328 +
329 +func (a *App) appendFlag(flag Flag) {
330 + if !a.hasFlag(flag) {
331 + a.Flags = append(a.Flags, flag)
332 + }
333 +}
334 +
335 +// Author represents someone who has contributed to a cli project.
336 +type Author struct {
337 + Name string // The Authors name
338 + Email string // The Authors email
339 +}
340 +
341 +// String makes Author comply to the Stringer interface, to allow an easy print in the templating process
342 +func (a Author) String() string {
343 + e := ""
344 + if a.Email != "" {
345 + e = "<" + a.Email + "> "
346 + }
347 +
348 + return fmt.Sprintf("%v %v", a.Name, e)
349 +}
Godeps/_workspace/src/github.com/codegangsta/cli/app_test.go new
+1047
@@ -0,0 +1,1047 @@
1 +package cli
2 +
3 +import (
4 + "bytes"
5 + "errors"
6 + "flag"
7 + "fmt"
8 + "io"
9 + "io/ioutil"
10 + "os"
11 + "strings"
12 + "testing"
13 +)
14 +
15 +func ExampleApp_Run() {
16 + // set args for examples sake
17 + os.Args = []string{"greet", "--name", "Jeremy"}
18 +
19 + app := NewApp()
20 + app.Name = "greet"
21 + app.Flags = []Flag{
22 + StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
23 + }
24 + app.Action = func(c *Context) {
25 + fmt.Printf("Hello %v\n", c.String("name"))
26 + }
27 + app.UsageText = "app [first_arg] [second_arg]"
28 + app.Author = "Harrison"
29 + app.Email = "harrison@lolwut.com"
30 + app.Authors = []Author{Author{Name: "Oliver Allen", Email: "oliver@toyshop.com"}}
31 + app.Run(os.Args)
32 + // Output:
33 + // Hello Jeremy
34 +}
35 +
36 +func ExampleApp_Run_subcommand() {
37 + // set args for examples sake
38 + os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
39 + app := NewApp()
40 + app.Name = "say"
41 + app.Commands = []Command{
42 + {
43 + Name: "hello",
44 + Aliases: []string{"hi"},
45 + Usage: "use it to see a description",
46 + Description: "This is how we describe hello the function",
47 + Subcommands: []Command{
48 + {
49 + Name: "english",
50 + Aliases: []string{"en"},
51 + Usage: "sends a greeting in english",
52 + Description: "greets someone in english",
53 + Flags: []Flag{
54 + StringFlag{
55 + Name: "name",
56 + Value: "Bob",
57 + Usage: "Name of the person to greet",
58 + },
59 + },
60 + Action: func(c *Context) {
61 + fmt.Println("Hello,", c.String("name"))
62 + },
63 + },
64 + },
65 + },
66 + }
67 +
68 + app.Run(os.Args)
69 + // Output:
70 + // Hello, Jeremy
71 +}
72 +
73 +func ExampleApp_Run_help() {
74 + // set args for examples sake
75 + os.Args = []string{"greet", "h", "describeit"}
76 +
77 + app := NewApp()
78 + app.Name = "greet"
79 + app.Flags = []Flag{
80 + StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
81 + }
82 + app.Commands = []Command{
83 + {
84 + Name: "describeit",
85 + Aliases: []string{"d"},
86 + Usage: "use it to see a description",
87 + Description: "This is how we describe describeit the function",
88 + Action: func(c *Context) {
89 + fmt.Printf("i like to describe things")
90 + },
91 + },
92 + }
93 + app.Run(os.Args)
94 + // Output:
95 + // NAME:
96 + // greet describeit - use it to see a description
97 + //
98 + // USAGE:
99 + // greet describeit [arguments...]
100 + //
101 + // DESCRIPTION:
102 + // This is how we describe describeit the function
103 +}
104 +
105 +func ExampleApp_Run_bashComplete() {
106 + // set args for examples sake
107 + os.Args = []string{"greet", "--generate-bash-completion"}
108 +
109 + app := NewApp()
110 + app.Name = "greet"
111 + app.EnableBashCompletion = true
112 + app.Commands = []Command{
113 + {
114 + Name: "describeit",
115 + Aliases: []string{"d"},
116 + Usage: "use it to see a description",
117 + Description: "This is how we describe describeit the function",
118 + Action: func(c *Context) {
119 + fmt.Printf("i like to describe things")
120 + },
121 + }, {
122 + Name: "next",
123 + Usage: "next example",
124 + Description: "more stuff to see when generating bash completion",
125 + Action: func(c *Context) {
126 + fmt.Printf("the next example")
127 + },
128 + },
129 + }
130 +
131 + app.Run(os.Args)
132 + // Output:
133 + // describeit
134 + // d
135 + // next
136 + // help
137 + // h
138 +}
139 +
140 +func TestApp_Run(t *testing.T) {
141 + s := ""
142 +
143 + app := NewApp()
144 + app.Action = func(c *Context) {
145 + s = s + c.Args().First()
146 + }
147 +
148 + err := app.Run([]string{"command", "foo"})
149 + expect(t, err, nil)
150 + err = app.Run([]string{"command", "bar"})
151 + expect(t, err, nil)
152 + expect(t, s, "foobar")
153 +}
154 +
155 +var commandAppTests = []struct {
156 + name string
157 + expected bool
158 +}{
159 + {"foobar", true},
160 + {"batbaz", true},
161 + {"b", true},
162 + {"f", true},
163 + {"bat", false},
164 + {"nothing", false},
165 +}
166 +
167 +func TestApp_Command(t *testing.T) {
168 + app := NewApp()
169 + fooCommand := Command{Name: "foobar", Aliases: []string{"f"}}
170 + batCommand := Command{Name: "batbaz", Aliases: []string{"b"}}
171 + app.Commands = []Command{
172 + fooCommand,
173 + batCommand,
174 + }
175 +
176 + for _, test := range commandAppTests {
177 + expect(t, app.Command(test.name) != nil, test.expected)
178 + }
179 +}
180 +
181 +func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
182 + var parsedOption, firstArg string
183 +
184 + app := NewApp()
185 + command := Command{
186 + Name: "cmd",
187 + Flags: []Flag{
188 + StringFlag{Name: "option", Value: "", Usage: "some option"},
189 + },
190 + Action: func(c *Context) {
191 + parsedOption = c.String("option")
192 + firstArg = c.Args().First()
193 + },
194 + }
195 + app.Commands = []Command{command}
196 +
197 + app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})
198 +
199 + expect(t, parsedOption, "my-option")
200 + expect(t, firstArg, "my-arg")
201 +}
202 +
203 +func TestApp_RunAsSubcommandParseFlags(t *testing.T) {
204 + var context *Context
205 +
206 + a := NewApp()
207 + a.Commands = []Command{
208 + {
209 + Name: "foo",
210 + Action: func(c *Context) {
211 + context = c
212 + },
213 + Flags: []Flag{
214 + StringFlag{
215 + Name: "lang",
216 + Value: "english",
217 + Usage: "language for the greeting",
218 + },
219 + },
220 + Before: func(_ *Context) error { return nil },
221 + },
222 + }
223 + a.Run([]string{"", "foo", "--lang", "spanish", "abcd"})
224 +
225 + expect(t, context.Args().Get(0), "abcd")
226 + expect(t, context.String("lang"), "spanish")
227 +}
228 +
229 +func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) {
230 + var parsedOption string
231 + var args []string
232 +
233 + app := NewApp()
234 + command := Command{
235 + Name: "cmd",
236 + Flags: []Flag{
237 + StringFlag{Name: "option", Value: "", Usage: "some option"},
238 + },
239 + Action: func(c *Context) {
240 + parsedOption = c.String("option")
241 + args = c.Args()
242 + },
243 + }
244 + app.Commands = []Command{command}
245 +
246 + app.Run([]string{"", "cmd", "my-arg", "--option", "my-option", "--", "--notARealFlag"})
247 +
248 + expect(t, parsedOption, "my-option")
249 + expect(t, args[0], "my-arg")
250 + expect(t, args[1], "--")
251 + expect(t, args[2], "--notARealFlag")
252 +}
253 +
254 +func TestApp_CommandWithDash(t *testing.T) {
255 + var args []string
256 +
257 + app := NewApp()
258 + command := Command{
259 + Name: "cmd",
260 + Action: func(c *Context) {
261 + args = c.Args()
262 + },
263 + }
264 + app.Commands = []Command{command}
265 +
266 + app.Run([]string{"", "cmd", "my-arg", "-"})
267 +
268 + expect(t, args[0], "my-arg")
269 + expect(t, args[1], "-")
270 +}
271 +
272 +func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) {
273 + var args []string
274 +
275 + app := NewApp()
276 + command := Command{
277 + Name: "cmd",
278 + Action: func(c *Context) {
279 + args = c.Args()
280 + },
281 + }
282 + app.Commands = []Command{command}
283 +
284 + app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"})
285 +
286 + expect(t, args[0], "my-arg")
287 + expect(t, args[1], "--")
288 + expect(t, args[2], "notAFlagAtAll")
289 +}
290 +
291 +func TestApp_Float64Flag(t *testing.T) {
292 + var meters float64
293 +
294 + app := NewApp()
295 + app.Flags = []Flag{
296 + Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
297 + }
298 + app.Action = func(c *Context) {
299 + meters = c.Float64("height")
300 + }
301 +
302 + app.Run([]string{"", "--height", "1.93"})
303 + expect(t, meters, 1.93)
304 +}
305 +
306 +func TestApp_ParseSliceFlags(t *testing.T) {
307 + var parsedOption, firstArg string
308 + var parsedIntSlice []int
309 + var parsedStringSlice []string
310 +
311 + app := NewApp()
312 + command := Command{
313 + Name: "cmd",
314 + Flags: []Flag{
315 + IntSliceFlag{Name: "p", Value: &IntSlice{}, Usage: "set one or more ip addr"},
316 + StringSliceFlag{Name: "ip", Value: &StringSlice{}, Usage: "set one or more ports to open"},
317 + },
318 + Action: func(c *Context) {
319 + parsedIntSlice = c.IntSlice("p")
320 + parsedStringSlice = c.StringSlice("ip")
321 + parsedOption = c.String("option")
322 + firstArg = c.Args().First()
323 + },
324 + }
325 + app.Commands = []Command{command}
326 +
327 + app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
328 +
329 + IntsEquals := func(a, b []int) bool {
330 + if len(a) != len(b) {
331 + return false
332 + }
333 + for i, v := range a {
334 + if v != b[i] {
335 + return false
336 + }
337 + }
338 + return true
339 + }
340 +
341 + StrsEquals := func(a, b []string) bool {
342 + if len(a) != len(b) {
343 + return false
344 + }
345 + for i, v := range a {
346 + if v != b[i] {
347 + return false
348 + }
349 + }
350 + return true
351 + }
352 + var expectedIntSlice = []int{22, 80}
353 + var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}
354 +
355 + if !IntsEquals(parsedIntSlice, expectedIntSlice) {
356 + t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
357 + }
358 +
359 + if !StrsEquals(parsedStringSlice, expectedStringSlice) {
360 + t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
361 + }
362 +}
363 +
364 +func TestApp_ParseSliceFlagsWithMissingValue(t *testing.T) {
365 + var parsedIntSlice []int
366 + var parsedStringSlice []string
367 +
368 + app := NewApp()
369 + command := Command{
370 + Name: "cmd",
371 + Flags: []Flag{
372 + IntSliceFlag{Name: "a", Usage: "set numbers"},
373 + StringSliceFlag{Name: "str", Usage: "set strings"},
374 + },
375 + Action: func(c *Context) {
376 + parsedIntSlice = c.IntSlice("a")
377 + parsedStringSlice = c.StringSlice("str")
378 + },
379 + }
380 + app.Commands = []Command{command}
381 +
382 + app.Run([]string{"", "cmd", "my-arg", "-a", "2", "-str", "A"})
383 +
384 + var expectedIntSlice = []int{2}
385 + var expectedStringSlice = []string{"A"}
386 +
387 + if parsedIntSlice[0] != expectedIntSlice[0] {
388 + t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
389 + }
390 +
391 + if parsedStringSlice[0] != expectedStringSlice[0] {
392 + t.Errorf("%v does not match %v", parsedIntSlice[0], expectedIntSlice[0])
393 + }
394 +}
395 +
396 +func TestApp_DefaultStdout(t *testing.T) {
397 + app := NewApp()
398 +
399 + if app.Writer != os.Stdout {
400 + t.Error("Default output writer not set.")
401 + }
402 +}
403 +
404 +type mockWriter struct {
405 + written []byte
406 +}
407 +
408 +func (fw *mockWriter) Write(p []byte) (n int, err error) {
409 + if fw.written == nil {
410 + fw.written = p
411 + } else {
412 + fw.written = append(fw.written, p...)
413 + }
414 +
415 + return len(p), nil
416 +}
417 +
418 +func (fw *mockWriter) GetWritten() (b []byte) {
419 + return fw.written
420 +}
421 +
422 +func TestApp_SetStdout(t *testing.T) {
423 + w := &mockWriter{}
424 +
425 + app := NewApp()
426 + app.Name = "test"
427 + app.Writer = w
428 +
429 + err := app.Run([]string{"help"})
430 +
431 + if err != nil {
432 + t.Fatalf("Run error: %s", err)
433 + }
434 +
435 + if len(w.written) == 0 {
436 + t.Error("App did not write output to desired writer.")
437 + }
438 +}
439 +
440 +func TestApp_BeforeFunc(t *testing.T) {
441 + beforeRun, subcommandRun := false, false
442 + beforeError := fmt.Errorf("fail")
443 + var err error
444 +
445 + app := NewApp()
446 +
447 + app.Before = func(c *Context) error {
448 + beforeRun = true
449 + s := c.String("opt")
450 + if s == "fail" {
451 + return beforeError
452 + }
453 +
454 + return nil
455 + }
456 +
457 + app.Commands = []Command{
458 + Command{
459 + Name: "sub",
460 + Action: func(c *Context) {
461 + subcommandRun = true
462 + },
463 + },
464 + }
465 +
466 + app.Flags = []Flag{
467 + StringFlag{Name: "opt"},
468 + }
469 +
470 + // run with the Before() func succeeding
471 + err = app.Run([]string{"command", "--opt", "succeed", "sub"})
472 +
473 + if err != nil {
474 + t.Fatalf("Run error: %s", err)
475 + }
476 +
477 + if beforeRun == false {
478 + t.Errorf("Before() not executed when expected")
479 + }
480 +
481 + if subcommandRun == false {
482 + t.Errorf("Subcommand not executed when expected")
483 + }
484 +
485 + // reset
486 + beforeRun, subcommandRun = false, false
487 +
488 + // run with the Before() func failing
489 + err = app.Run([]string{"command", "--opt", "fail", "sub"})
490 +
491 + // should be the same error produced by the Before func
492 + if err != beforeError {
493 + t.Errorf("Run error expected, but not received")
494 + }
495 +
496 + if beforeRun == false {
497 + t.Errorf("Before() not executed when expected")
498 + }
499 +
500 + if subcommandRun == true {
501 + t.Errorf("Subcommand executed when NOT expected")
502 + }
503 +
504 +}
505 +
506 +func TestApp_AfterFunc(t *testing.T) {
507 + afterRun, subcommandRun := false, false
508 + afterError := fmt.Errorf("fail")
509 + var err error
510 +
511 + app := NewApp()
512 +
513 + app.After = func(c *Context) error {
514 + afterRun = true
515 + s := c.String("opt")
516 + if s == "fail" {
517 + return afterError
518 + }
519 +
520 + return nil
521 + }
522 +
523 + app.Commands = []Command{
524 + Command{
525 + Name: "sub",
526 + Action: func(c *Context) {
527 + subcommandRun = true
528 + },
529 + },
530 + }
531 +
532 + app.Flags = []Flag{
533 + StringFlag{Name: "opt"},
534 + }
535 +
536 + // run with the After() func succeeding
537 + err = app.Run([]string{"command", "--opt", "succeed", "sub"})
538 +
539 + if err != nil {
540 + t.Fatalf("Run error: %s", err)
541 + }
542 +
543 + if afterRun == false {
544 + t.Errorf("After() not executed when expected")
545 + }
546 +
547 + if subcommandRun == false {
548 + t.Errorf("Subcommand not executed when expected")
549 + }
550 +
551 + // reset
552 + afterRun, subcommandRun = false, false
553 +
554 + // run with the Before() func failing
555 + err = app.Run([]string{"command", "--opt", "fail", "sub"})
556 +
557 + // should be the same error produced by the Before func
558 + if err != afterError {
559 + t.Errorf("Run error expected, but not received")
560 + }
561 +
562 + if afterRun == false {
563 + t.Errorf("After() not executed when expected")
564 + }
565 +
566 + if subcommandRun == false {
567 + t.Errorf("Subcommand not executed when expected")
568 + }
569 +}
570 +
571 +func TestAppNoHelpFlag(t *testing.T) {
572 + oldFlag := HelpFlag
573 + defer func() {
574 + HelpFlag = oldFlag
575 + }()
576 +
577 + HelpFlag = BoolFlag{}
578 +
579 + app := NewApp()
580 + app.Writer = ioutil.Discard
581 + err := app.Run([]string{"test", "-h"})
582 +
583 + if err != flag.ErrHelp {
584 + t.Errorf("expected error about missing help flag, but got: %s (%T)", err, err)
585 + }
586 +}
587 +
588 +func TestAppHelpPrinter(t *testing.T) {
589 + oldPrinter := HelpPrinter
590 + defer func() {
591 + HelpPrinter = oldPrinter
592 + }()
593 +
594 + var wasCalled = false
595 + HelpPrinter = func(w io.Writer, template string, data interface{}) {
596 + wasCalled = true
597 + }
598 +
599 + app := NewApp()
600 + app.Run([]string{"-h"})
601 +
602 + if wasCalled == false {
603 + t.Errorf("Help printer expected to be called, but was not")
604 + }
605 +}
606 +
607 +func TestAppVersionPrinter(t *testing.T) {
608 + oldPrinter := VersionPrinter
609 + defer func() {
610 + VersionPrinter = oldPrinter
611 + }()
612 +
613 + var wasCalled = false
614 + VersionPrinter = func(c *Context) {
615 + wasCalled = true
616 + }
617 +
618 + app := NewApp()
619 + ctx := NewContext(app, nil, nil)
620 + ShowVersion(ctx)
621 +
622 + if wasCalled == false {
623 + t.Errorf("Version printer expected to be called, but was not")
624 + }
625 +}
626 +
627 +func TestAppCommandNotFound(t *testing.T) {
628 + beforeRun, subcommandRun := false, false
629 + app := NewApp()
630 +
631 + app.CommandNotFound = func(c *Context, command string) {
632 + beforeRun = true
633 + }
634 +
635 + app.Commands = []Command{
636 + Command{
637 + Name: "bar",
638 + Action: func(c *Context) {
639 + subcommandRun = true
640 + },
641 + },
642 + }
643 +
644 + app.Run([]string{"command", "foo"})
645 +
646 + expect(t, beforeRun, true)
647 + expect(t, subcommandRun, false)
648 +}
649 +
650 +func TestGlobalFlag(t *testing.T) {
651 + var globalFlag string
652 + var globalFlagSet bool
653 + app := NewApp()
654 + app.Flags = []Flag{
655 + StringFlag{Name: "global, g", Usage: "global"},
656 + }
657 + app.Action = func(c *Context) {
658 + globalFlag = c.GlobalString("global")
659 + globalFlagSet = c.GlobalIsSet("global")
660 + }
661 + app.Run([]string{"command", "-g", "foo"})
662 + expect(t, globalFlag, "foo")
663 + expect(t, globalFlagSet, true)
664 +
665 +}
666 +
667 +func TestGlobalFlagsInSubcommands(t *testing.T) {
668 + subcommandRun := false
669 + parentFlag := false
670 + app := NewApp()
671 +
672 + app.Flags = []Flag{
673 + BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
674 + }
675 +
676 + app.Commands = []Command{
677 + Command{
678 + Name: "foo",
679 + Flags: []Flag{
680 + BoolFlag{Name: "parent, p", Usage: "Parent flag"},
681 + },
682 + Subcommands: []Command{
683 + {
684 + Name: "bar",
685 + Action: func(c *Context) {
686 + if c.GlobalBool("debug") {
687 + subcommandRun = true
688 + }
689 + if c.GlobalBool("parent") {
690 + parentFlag = true
691 + }
692 + },
693 + },
694 + },
695 + },
696 + }
697 +
698 + app.Run([]string{"command", "-d", "foo", "-p", "bar"})
699 +
700 + expect(t, subcommandRun, true)
701 + expect(t, parentFlag, true)
702 +}
703 +
704 +func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) {
705 + var subcommandHelpTopics = [][]string{
706 + {"command", "foo", "--help"},
707 + {"command", "foo", "-h"},
708 + {"command", "foo", "help"},
709 + }
710 +
711 + for _, flagSet := range subcommandHelpTopics {
712 + t.Logf("==> checking with flags %v", flagSet)
713 +
714 + app := NewApp()
715 + buf := new(bytes.Buffer)
716 + app.Writer = buf
717 +
718 + subCmdBar := Command{
719 + Name: "bar",
720 + Usage: "does bar things",
721 + }
722 + subCmdBaz := Command{
723 + Name: "baz",
724 + Usage: "does baz things",
725 + }
726 + cmd := Command{
727 + Name: "foo",
728 + Description: "descriptive wall of text about how it does foo things",
729 + Subcommands: []Command{subCmdBar, subCmdBaz},
730 + }
731 +
732 + app.Commands = []Command{cmd}
733 + err := app.Run(flagSet)
734 +
735 + if err != nil {
736 + t.Error(err)
737 + }
738 +
739 + output := buf.String()
740 + t.Logf("output: %q\n", buf.Bytes())
741 +
742 + if strings.Contains(output, "No help topic for") {
743 + t.Errorf("expect a help topic, got none: \n%q", output)
744 + }
745 +
746 + for _, shouldContain := range []string{
747 + cmd.Name, cmd.Description,
748 + subCmdBar.Name, subCmdBar.Usage,
749 + subCmdBaz.Name, subCmdBaz.Usage,
750 + } {
751 + if !strings.Contains(output, shouldContain) {
752 + t.Errorf("want help to contain %q, did not: \n%q", shouldContain, output)
753 + }
754 + }
755 + }
756 +}
757 +
758 +func TestApp_Run_SubcommandFullPath(t *testing.T) {
759 + app := NewApp()
760 + buf := new(bytes.Buffer)
761 + app.Writer = buf
762 + app.Name = "command"
763 + subCmd := Command{
764 + Name: "bar",
765 + Usage: "does bar things",
766 + }
767 + cmd := Command{
768 + Name: "foo",
769 + Description: "foo commands",
770 + Subcommands: []Command{subCmd},
771 + }
772 + app.Commands = []Command{cmd}
773 +
774 + err := app.Run([]string{"command", "foo", "bar", "--help"})
775 + if err != nil {
776 + t.Error(err)
777 + }
778 +
779 + output := buf.String()
780 + if !strings.Contains(output, "command foo bar - does bar things") {
781 + t.Errorf("expected full path to subcommand: %s", output)
782 + }
783 + if !strings.Contains(output, "command foo bar [arguments...]") {
784 + t.Errorf("expected full path to subcommand: %s", output)
785 + }
786 +}
787 +
788 +func TestApp_Run_SubcommandHelpName(t *testing.T) {
789 + app := NewApp()
790 + buf := new(bytes.Buffer)
791 + app.Writer = buf
792 + app.Name = "command"
793 + subCmd := Command{
794 + Name: "bar",
795 + HelpName: "custom",
796 + Usage: "does bar things",
797 + }
798 + cmd := Command{
799 + Name: "foo",
800 + Description: "foo commands",
801 + Subcommands: []Command{subCmd},
802 + }
803 + app.Commands = []Command{cmd}
804 +
805 + err := app.Run([]string{"command", "foo", "bar", "--help"})
806 + if err != nil {
807 + t.Error(err)
808 + }
809 +
810 + output := buf.String()
811 + if !strings.Contains(output, "custom - does bar things") {
812 + t.Errorf("expected HelpName for subcommand: %s", output)
813 + }
814 + if !strings.Contains(output, "custom [arguments...]") {
815 + t.Errorf("expected HelpName to subcommand: %s", output)
816 + }
817 +}
818 +
819 +func TestApp_Run_CommandHelpName(t *testing.T) {
820 + app := NewApp()
821 + buf := new(bytes.Buffer)
822 + app.Writer = buf
823 + app.Name = "command"
824 + subCmd := Command{
825 + Name: "bar",
826 + Usage: "does bar things",
827 + }
828 + cmd := Command{
829 + Name: "foo",
830 + HelpName: "custom",
831 + Description: "foo commands",
832 + Subcommands: []Command{subCmd},
833 + }
834 + app.Commands = []Command{cmd}
835 +
836 + err := app.Run([]string{"command", "foo", "bar", "--help"})
837 + if err != nil {
838 + t.Error(err)
839 + }
840 +
841 + output := buf.String()
842 + if !strings.Contains(output, "command foo bar - does bar things") {
843 + t.Errorf("expected full path to subcommand: %s", output)
844 + }
845 + if !strings.Contains(output, "command foo bar [arguments...]") {
846 + t.Errorf("expected full path to subcommand: %s", output)
847 + }
848 +}
849 +
850 +func TestApp_Run_CommandSubcommandHelpName(t *testing.T) {
851 + app := NewApp()
852 + buf := new(bytes.Buffer)
853 + app.Writer = buf
854 + app.Name = "base"
855 + subCmd := Command{
856 + Name: "bar",
857 + HelpName: "custom",
858 + Usage: "does bar things",
859 + }
860 + cmd := Command{
861 + Name: "foo",
862 + Description: "foo commands",
863 + Subcommands: []Command{subCmd},
864 + }
865 + app.Commands = []Command{cmd}
866 +
867 + err := app.Run([]string{"command", "foo", "--help"})
868 + if err != nil {
869 + t.Error(err)
870 + }
871 +
872 + output := buf.String()
873 + if !strings.Contains(output, "base foo - foo commands") {
874 + t.Errorf("expected full path to subcommand: %s", output)
875 + }
876 + if !strings.Contains(output, "base foo command [command options] [arguments...]") {
877 + t.Errorf("expected full path to subcommand: %s", output)
878 + }
879 +}
880 +
881 +func TestApp_Run_Help(t *testing.T) {
882 + var helpArguments = [][]string{{"boom", "--help"}, {"boom", "-h"}, {"boom", "help"}}
883 +
884 + for _, args := range helpArguments {
885 + buf := new(bytes.Buffer)
886 +
887 + t.Logf("==> checking with arguments %v", args)
888 +
889 + app := NewApp()
890 + app.Name = "boom"
891 + app.Usage = "make an explosive entrance"
892 + app.Writer = buf
893 + app.Action = func(c *Context) {
894 + buf.WriteString("boom I say!")
895 + }
896 +
897 + err := app.Run(args)
898 + if err != nil {
899 + t.Error(err)
900 + }
901 +
902 + output := buf.String()
903 + t.Logf("output: %q\n", buf.Bytes())
904 +
905 + if !strings.Contains(output, "boom - make an explosive entrance") {
906 + t.Errorf("want help to contain %q, did not: \n%q", "boom - make an explosive entrance", output)
907 + }
908 + }
909 +}
910 +
911 +func TestApp_Run_Version(t *testing.T) {
912 + var versionArguments = [][]string{{"boom", "--version"}, {"boom", "-v"}}
913 +
914 + for _, args := range versionArguments {
915 + buf := new(bytes.Buffer)
916 +
917 + t.Logf("==> checking with arguments %v", args)
918 +
919 + app := NewApp()
920 + app.Name = "boom"
921 + app.Usage = "make an explosive entrance"
922 + app.Version = "0.1.0"
923 + app.Writer = buf
924 + app.Action = func(c *Context) {
925 + buf.WriteString("boom I say!")
926 + }
927 +
928 + err := app.Run(args)
929 + if err != nil {
930 + t.Error(err)
931 + }
932 +
933 + output := buf.String()
934 + t.Logf("output: %q\n", buf.Bytes())
935 +
936 + if !strings.Contains(output, "0.1.0") {
937 + t.Errorf("want version to contain %q, did not: \n%q", "0.1.0", output)
938 + }
939 + }
940 +}
941 +
942 +func TestApp_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) {
943 + app := NewApp()
944 + app.Action = func(c *Context) {}
945 + app.Before = func(c *Context) error { return fmt.Errorf("before error") }
946 + app.After = func(c *Context) error { return fmt.Errorf("after error") }
947 +
948 + err := app.Run([]string{"foo"})
949 + if err == nil {
950 + t.Fatalf("expected to receive error from Run, got none")
951 + }
952 +
953 + if !strings.Contains(err.Error(), "before error") {
954 + t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
955 + }
956 + if !strings.Contains(err.Error(), "after error") {
957 + t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
958 + }
959 +}
960 +
961 +func TestApp_Run_SubcommandDoesNotOverwriteErrorFromBefore(t *testing.T) {
962 + app := NewApp()
963 + app.Commands = []Command{
964 + Command{
965 + Subcommands: []Command{
966 + Command{
967 + Name: "sub",
968 + },
969 + },
970 + Name: "bar",
971 + Before: func(c *Context) error { return fmt.Errorf("before error") },
972 + After: func(c *Context) error { return fmt.Errorf("after error") },
973 + },
974 + }
975 +
976 + err := app.Run([]string{"foo", "bar"})
977 + if err == nil {
978 + t.Fatalf("expected to receive error from Run, got none")
979 + }
980 +
981 + if !strings.Contains(err.Error(), "before error") {
982 + t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
983 + }
984 + if !strings.Contains(err.Error(), "after error") {
985 + t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
986 + }
987 +}
988 +
989 +func TestApp_OnUsageError_WithWrongFlagValue(t *testing.T) {
990 + app := NewApp()
991 + app.Flags = []Flag{
992 + IntFlag{Name: "flag"},
993 + }
994 + app.OnUsageError = func(c *Context, err error, isSubcommand bool) error {
995 + if isSubcommand {
996 + t.Errorf("Expect no subcommand")
997 + }
998 + if !strings.HasPrefix(err.Error(), "invalid value \"wrong\"") {
999 + t.Errorf("Expect an invalid value error, but got \"%v\"", err)
1000 + }
1001 + return errors.New("intercepted: " + err.Error())
1002 + }
1003 + app.Commands = []Command{
1004 + Command{
1005 + Name: "bar",
1006 + },
1007 + }
1008 +
1009 + err := app.Run([]string{"foo", "--flag=wrong"})
1010 + if err == nil {
1011 + t.Fatalf("expected to receive error from Run, got none")
1012 + }
1013 +
1014 + if !strings.HasPrefix(err.Error(), "intercepted: invalid value") {
1015 + t.Errorf("Expect an intercepted error, but got \"%v\"", err)
1016 + }
1017 +}
1018 +
1019 +func TestApp_OnUsageError_WithWrongFlagValue_ForSubcommand(t *testing.T) {
1020 + app := NewApp()
1021 + app.Flags = []Flag{
1022 + IntFlag{Name: "flag"},
1023 + }
1024 + app.OnUsageError = func(c *Context, err error, isSubcommand bool) error {
1025 + if isSubcommand {
1026 + t.Errorf("Expect subcommand")
1027 + }
1028 + if !strings.HasPrefix(err.Error(), "invalid value \"wrong\"") {
1029 + t.Errorf("Expect an invalid value error, but got \"%v\"", err)
1030 + }
1031 + return errors.New("intercepted: " + err.Error())
1032 + }
1033 + app.Commands = []Command{
1034 + Command{
1035 + Name: "bar",
1036 + },
1037 + }
1038 +
1039 + err := app.Run([]string{"foo", "--flag=wrong", "bar"})
1040 + if err == nil {
1041 + t.Fatalf("expected to receive error from Run, got none")
1042 + }
1043 +
1044 + if !strings.HasPrefix(err.Error(), "intercepted: invalid value") {
1045 + t.Errorf("Expect an intercepted error, but got \"%v\"", err)
1046 + }
1047 +}
Godeps/_workspace/src/github.com/codegangsta/cli/appveyor.yml new
+16
@@ -0,0 +1,16 @@
1 +version: "{build}"
2 +
3 +os: Windows Server 2012 R2
4 +
5 +install:
6 + - go version
7 + - go env
8 +
9 +build_script:
10 + - cd %APPVEYOR_BUILD_FOLDER%
11 + - go vet ./...
12 + - go test -v ./...
13 +
14 +test: off
15 +
16 +deploy: off
Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete new
+14
@@ -0,0 +1,14 @@
1 +#! /bin/bash
2 +
3 +: ${PROG:=$(basename ${BASH_SOURCE})}
4 +
5 +_cli_bash_autocomplete() {
6 + local cur opts base
7 + COMPREPLY=()
8 + cur="${COMP_WORDS[COMP_CWORD]}"
9 + opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
10 + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
11 + return 0
12 + }
13 +
14 + complete -F _cli_bash_autocomplete $PROG
Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete new
+5
@@ -0,0 +1,5 @@
1 +autoload -U compinit && compinit
2 +autoload -U bashcompinit && bashcompinit
3 +
4 +script_dir=$(dirname $0)
5 +source ${script_dir}/bash_autocomplete
Godeps/_workspace/src/github.com/codegangsta/cli/cli.go new
+40
@@ -0,0 +1,40 @@
1 +// Package cli provides a minimal framework for creating and organizing command line
2 +// Go applications. cli is designed to be easy to understand and write, the most simple
3 +// cli application can be written as follows:
4 +// func main() {
5 +// cli.NewApp().Run(os.Args)
6 +// }
7 +//
8 +// Of course this application does not do much, so let's make this an actual application:
9 +// func main() {
10 +// app := cli.NewApp()
11 +// app.Name = "greet"
12 +// app.Usage = "say a greeting"
13 +// app.Action = func(c *cli.Context) {
14 +// println("Greetings")
15 +// }
16 +//
17 +// app.Run(os.Args)
18 +// }
19 +package cli
20 +
21 +import (
22 + "strings"
23 +)
24 +
25 +type MultiError struct {
26 + Errors []error
27 +}
28 +
29 +func NewMultiError(err ...error) MultiError {
30 + return MultiError{Errors: err}
31 +}
32 +
33 +func (m MultiError) Error() string {
34 + errs := make([]string, len(m.Errors))
35 + for i, err := range m.Errors {
36 + errs[i] = err.Error()
37 + }
38 +
39 + return strings.Join(errs, "\n")
40 +}
Godeps/_workspace/src/github.com/codegangsta/cli/command.go new
+250
@@ -0,0 +1,250 @@
1 +package cli
2 +
3 +import (
4 + "fmt"
5 + "io/ioutil"
6 + "strings"
7 +)
8 +
9 +// Command is a subcommand for a cli.App.
10 +type Command struct {
11 + // The name of the command
12 + Name string
13 + // short name of the command. Typically one character (deprecated, use `Aliases`)
14 + ShortName string
15 + // A list of aliases for the command
16 + Aliases []string
17 + // A short description of the usage of this command
18 + Usage string
19 + // Custom text to show on USAGE section of help
20 + UsageText string
21 + // A longer explanation of how the command works
22 + Description string
23 + // A short description of the arguments of this command
24 + ArgsUsage string
25 + // The function to call when checking for bash command completions
26 + BashComplete func(context *Context)
27 + // An action to execute before any sub-subcommands are run, but after the context is ready
28 + // If a non-nil error is returned, no sub-subcommands are run
29 + Before func(context *Context) error
30 + // An action to execute after any subcommands are run, but before the subcommand has finished
31 + // It is run even if Action() panics
32 + After func(context *Context) error
33 + // The function to call when this command is invoked
34 + Action func(context *Context)
35 + // Execute this function, if an usage error occurs. This is useful for displaying customized usage error messages.
36 + // This function is able to replace the original error messages.
37 + // If this function is not set, the "Incorrect usage" is displayed and the execution is interrupted.
38 + OnUsageError func(context *Context, err error) error
39 + // List of child commands
40 + Subcommands []Command
41 + // List of flags to parse
42 + Flags []Flag
43 + // Treat all flags as normal arguments if true
44 + SkipFlagParsing bool
45 + // Boolean to hide built-in help command
46 + HideHelp bool
47 +
48 + // Full name of command for help, defaults to full command name, including parent commands.
49 + HelpName string
50 + commandNamePath []string
51 +}
52 +
53 +// Returns the full name of the command.
54 +// For subcommands this ensures that parent commands are part of the command path
55 +func (c Command) FullName() string {
56 + if c.commandNamePath == nil {
57 + return c.Name
58 + }
59 + return strings.Join(c.commandNamePath, " ")
60 +}
61 +
62 +// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
63 +func (c Command) Run(ctx *Context) (err error) {
64 + if len(c.Subcommands) > 0 {
65 + return c.startApp(ctx)
66 + }
67 +
68 + if !c.HideHelp && (HelpFlag != BoolFlag{}) {
69 + // append help to flags
70 + c.Flags = append(
71 + c.Flags,
72 + HelpFlag,
73 + )
74 + }
75 +
76 + if ctx.App.EnableBashCompletion {
77 + c.Flags = append(c.Flags, BashCompletionFlag)
78 + }
79 +
80 + set := flagSet(c.Name, c.Flags)
81 + set.SetOutput(ioutil.Discard)
82 +
83 + if !c.SkipFlagParsing {
84 + firstFlagIndex := -1
85 + terminatorIndex := -1
86 + for index, arg := range ctx.Args() {
87 + if arg == "--" {
88 + terminatorIndex = index
89 + break
90 + } else if arg == "-" {
91 + // Do nothing. A dash alone is not really a flag.
92 + continue
93 + } else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 {
94 + firstFlagIndex = index
95 + }
96 + }
97 +
98 + if firstFlagIndex > -1 {
99 + args := ctx.Args()
100 + regularArgs := make([]string, len(args[1:firstFlagIndex]))
101 + copy(regularArgs, args[1:firstFlagIndex])
102 +
103 + var flagArgs []string
104 + if terminatorIndex > -1 {
105 + flagArgs = args[firstFlagIndex:terminatorIndex]
106 + regularArgs = append(regularArgs, args[terminatorIndex:]...)
107 + } else {
108 + flagArgs = args[firstFlagIndex:]
109 + }
110 +
111 + err = set.Parse(append(flagArgs, regularArgs...))
112 + } else {
113 + err = set.Parse(ctx.Args().Tail())
114 + }
115 + } else {
116 + if c.SkipFlagParsing {
117 + err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...))
118 + }
119 + }
120 +
121 + if err != nil {
122 + if c.OnUsageError != nil {
123 + err := c.OnUsageError(ctx, err)
124 + return err
125 + } else {
126 + fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.")
127 + fmt.Fprintln(ctx.App.Writer)
128 + ShowCommandHelp(ctx, c.Name)
129 + return err
130 + }
131 + }
132 +
133 + nerr := normalizeFlags(c.Flags, set)
134 + if nerr != nil {
135 + fmt.Fprintln(ctx.App.Writer, nerr)
136 + fmt.Fprintln(ctx.App.Writer)
137 + ShowCommandHelp(ctx, c.Name)
138 + return nerr
139 + }
140 + context := NewContext(ctx.App, set, ctx)
141 +
142 + if checkCommandCompletions(context, c.Name) {
143 + return nil
144 + }
145 +
146 + if checkCommandHelp(context, c.Name) {
147 + return nil
148 + }
149 +
150 + if c.After != nil {
151 + defer func() {
152 + afterErr := c.After(context)
153 + if afterErr != nil {
154 + if err != nil {
155 + err = NewMultiError(err, afterErr)
156 + } else {
157 + err = afterErr
158 + }
159 + }
160 + }()
161 + }
162 +
163 + if c.Before != nil {
164 + err := c.Before(context)
165 + if err != nil {
166 + fmt.Fprintln(ctx.App.Writer, err)
167 + fmt.Fprintln(ctx.App.Writer)
168 + ShowCommandHelp(ctx, c.Name)
169 + return err
170 + }
171 + }
172 +
173 + context.Command = c
174 + c.Action(context)
175 + return nil
176 +}
177 +
178 +func (c Command) Names() []string {
179 + names := []string{c.Name}
180 +
181 + if c.ShortName != "" {
182 + names = append(names, c.ShortName)
183 + }
184 +
185 + return append(names, c.Aliases...)
186 +}
187 +
188 +// Returns true if Command.Name or Command.ShortName matches given name
189 +func (c Command) HasName(name string) bool {
190 + for _, n := range c.Names() {
191 + if n == name {
192 + return true
193 + }
194 + }
195 + return false
196 +}
197 +
198 +func (c Command) startApp(ctx *Context) error {
199 + app := NewApp()
200 +
201 + // set the name and usage
202 + app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name)
203 + if c.HelpName == "" {
204 + app.HelpName = c.HelpName
205 + } else {
206 + app.HelpName = app.Name
207 + }
208 +
209 + if c.Description != "" {
210 + app.Usage = c.Description
211 + } else {
212 + app.Usage = c.Usage
213 + }
214 +
215 + // set CommandNotFound
216 + app.CommandNotFound = ctx.App.CommandNotFound
217 +
218 + // set the flags and commands
219 + app.Commands = c.Subcommands
220 + app.Flags = c.Flags
221 + app.HideHelp = c.HideHelp
222 +
223 + app.Version = ctx.App.Version
224 + app.HideVersion = ctx.App.HideVersion
225 + app.Compiled = ctx.App.Compiled
226 + app.Author = ctx.App.Author
227 + app.Email = ctx.App.Email
228 + app.Writer = ctx.App.Writer
229 +
230 + // bash completion
231 + app.EnableBashCompletion = ctx.App.EnableBashCompletion
232 + if c.BashComplete != nil {
233 + app.BashComplete = c.BashComplete
234 + }
235 +
236 + // set the actions
237 + app.Before = c.Before
238 + app.After = c.After
239 + if c.Action != nil {
240 + app.Action = c.Action
241 + } else {
242 + app.Action = helpSubcommand.Action
243 + }
244 +
245 + for index, cc := range app.Commands {
246 + app.Commands[index].commandNamePath = []string{c.Name, cc.Name}
247 + }
248 +
249 + return app.RunAsSubcommand(ctx)
250 +}
Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go new
+97
@@ -0,0 +1,97 @@
1 +package cli
2 +
3 +import (
4 + "errors"
5 + "flag"
6 + "fmt"
7 + "io/ioutil"
8 + "strings"
9 + "testing"
10 +)
11 +
12 +func TestCommandFlagParsing(t *testing.T) {
13 + cases := []struct {
14 + testArgs []string
15 + skipFlagParsing bool
16 + expectedErr error
17 + }{
18 + {[]string{"blah", "blah", "-break"}, false, errors.New("flag provided but not defined: -break")}, // Test normal "not ignoring flags" flow
19 + {[]string{"blah", "blah"}, true, nil}, // Test SkipFlagParsing without any args that look like flags
20 + {[]string{"blah", "-break"}, true, nil}, // Test SkipFlagParsing with random flag arg
21 + {[]string{"blah", "-help"}, true, nil}, // Test SkipFlagParsing with "special" help flag arg
22 + }
23 +
24 + for _, c := range cases {
25 + app := NewApp()
26 + app.Writer = ioutil.Discard
27 + set := flag.NewFlagSet("test", 0)
28 + set.Parse(c.testArgs)
29 +
30 + context := NewContext(app, set, nil)
31 +
32 + command := Command{
33 + Name: "test-cmd",
34 + Aliases: []string{"tc"},
35 + Usage: "this is for testing",
36 + Description: "testing",
37 + Action: func(_ *Context) {},
38 + }
39 +
40 + command.SkipFlagParsing = c.skipFlagParsing
41 +
42 + err := command.Run(context)
43 +
44 + expect(t, err, c.expectedErr)
45 + expect(t, []string(context.Args()), c.testArgs)
46 + }
47 +}
48 +
49 +func TestCommand_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) {
50 + app := NewApp()
51 + app.Commands = []Command{
52 + Command{
53 + Name: "bar",
54 + Before: func(c *Context) error { return fmt.Errorf("before error") },
55 + After: func(c *Context) error { return fmt.Errorf("after error") },
56 + },
57 + }
58 +
59 + err := app.Run([]string{"foo", "bar"})
60 + if err == nil {
61 + t.Fatalf("expected to receive error from Run, got none")
62 + }
63 +
64 + if !strings.Contains(err.Error(), "before error") {
65 + t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
66 + }
67 + if !strings.Contains(err.Error(), "after error") {
68 + t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
69 + }
70 +}
71 +
72 +func TestCommand_OnUsageError_WithWrongFlagValue(t *testing.T) {
73 + app := NewApp()
74 + app.Commands = []Command{
75 + Command{
76 + Name: "bar",
77 + Flags: []Flag{
78 + IntFlag{Name: "flag"},
79 + },
80 + OnUsageError: func(c *Context, err error) error {
81 + if !strings.HasPrefix(err.Error(), "invalid value \"wrong\"") {
82 + t.Errorf("Expect an invalid value error, but got \"%v\"", err)
83 + }
84 + return errors.New("intercepted: " + err.Error())
85 + },
86 + },
87 + }
88 +
89 + err := app.Run([]string{"foo", "bar", "--flag=wrong"})
90 + if err == nil {
91 + t.Fatalf("expected to receive error from Run, got none")
92 + }
93 +
94 + if !strings.HasPrefix(err.Error(), "intercepted: invalid value") {
95 + t.Errorf("Expect an intercepted error, but got \"%v\"", err)
96 + }
97 +}
Godeps/_workspace/src/github.com/codegangsta/cli/context.go new
+393
@@ -0,0 +1,393 @@
1 +package cli
2 +
3 +import (
4 + "errors"
5 + "flag"
6 + "strconv"
7 + "strings"
8 + "time"
9 +)
10 +
11 +// Context is a type that is passed through to
12 +// each Handler action in a cli application. Context
13 +// can be used to retrieve context-specific Args and
14 +// parsed command-line options.
15 +type Context struct {
16 + App *App
17 + Command Command
18 + flagSet *flag.FlagSet
19 + setFlags map[string]bool
20 + globalSetFlags map[string]bool
21 + parentContext *Context
22 +}
23 +
24 +// Creates a new context. For use in when invoking an App or Command action.
25 +func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
26 + return &Context{App: app, flagSet: set, parentContext: parentCtx}
27 +}
28 +
29 +// Looks up the value of a local int flag, returns 0 if no int flag exists
30 +func (c *Context) Int(name string) int {
31 + return lookupInt(name, c.flagSet)
32 +}
33 +
34 +// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists
35 +func (c *Context) Duration(name string) time.Duration {
36 + return lookupDuration(name, c.flagSet)
37 +}
38 +
39 +// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists
40 +func (c *Context) Float64(name string) float64 {
41 + return lookupFloat64(name, c.flagSet)
42 +}
43 +
44 +// Looks up the value of a local bool flag, returns false if no bool flag exists
45 +func (c *Context) Bool(name string) bool {
46 + return lookupBool(name, c.flagSet)
47 +}
48 +
49 +// Looks up the value of a local boolT flag, returns false if no bool flag exists
50 +func (c *Context) BoolT(name string) bool {
51 + return lookupBoolT(name, c.flagSet)
52 +}
53 +
54 +// Looks up the value of a local string flag, returns "" if no string flag exists
55 +func (c *Context) String(name string) string {
56 + return lookupString(name, c.flagSet)
57 +}
58 +
59 +// Looks up the value of a local string slice flag, returns nil if no string slice flag exists
60 +func (c *Context) StringSlice(name string) []string {
61 + return lookupStringSlice(name, c.flagSet)
62 +}
63 +
64 +// Looks up the value of a local int slice flag, returns nil if no int slice flag exists
65 +func (c *Context) IntSlice(name string) []int {
66 + return lookupIntSlice(name, c.flagSet)
67 +}
68 +
69 +// Looks up the value of a local generic flag, returns nil if no generic flag exists
70 +func (c *Context) Generic(name string) interface{} {
71 + return lookupGeneric(name, c.flagSet)
72 +}
73 +
74 +// Looks up the value of a global int flag, returns 0 if no int flag exists
75 +func (c *Context) GlobalInt(name string) int {
76 + if fs := lookupGlobalFlagSet(name, c); fs != nil {
77 + return lookupInt(name, fs)
78 + }
79 + return 0
80 +}
81 +
82 +// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists
83 +func (c *Context) GlobalDuration(name string) time.Duration {
84 + if fs := lookupGlobalFlagSet(name, c); fs != nil {
85 + return lookupDuration(name, fs)
86 + }
87 + return 0
88 +}
89 +
90 +// Looks up the value of a global bool flag, returns false if no bool flag exists
91 +func (c *Context) GlobalBool(name string) bool {
92 + if fs := lookupGlobalFlagSet(name, c); fs != nil {
93 + return lookupBool(name, fs)
94 + }
95 + return false
96 +}
97 +
98 +// Looks up the value of a global string flag, returns "" if no string flag exists
99 +func (c *Context) GlobalString(name string) string {
100 + if fs := lookupGlobalFlagSet(name, c); fs != nil {
101 + return lookupString(name, fs)
102 + }
103 + return ""
104 +}
105 +
106 +// Looks up the value of a global string slice flag, returns nil if no string slice flag exists
107 +func (c *Context) GlobalStringSlice(name string) []string {
108 + if fs := lookupGlobalFlagSet(name, c); fs != nil {
109 + return lookupStringSlice(name, fs)
110 + }
111 + return nil
112 +}
113 +
114 +// Looks up the value of a global int slice flag, returns nil if no int slice flag exists
115 +func (c *Context) GlobalIntSlice(name string) []int {
116 + if fs := lookupGlobalFlagSet(name, c); fs != nil {
117 + return lookupIntSlice(name, fs)
118 + }
119 + return nil
120 +}
121 +
122 +// Looks up the value of a global generic flag, returns nil if no generic flag exists
123 +func (c *Context) GlobalGeneric(name string) interface{} {
124 + if fs := lookupGlobalFlagSet(name, c); fs != nil {
125 + return lookupGeneric(name, fs)
126 + }
127 + return nil
128 +}
129 +
130 +// Returns the number of flags set
131 +func (c *Context) NumFlags() int {
132 + return c.flagSet.NFlag()
133 +}
134 +
135 +// Determines if the flag was actually set
136 +func (c *Context) IsSet(name string) bool {
137 + if c.setFlags == nil {
138 + c.setFlags = make(map[string]bool)
139 + c.flagSet.Visit(func(f *flag.Flag) {
140 + c.setFlags[f.Name] = true
141 + })
142 + }
143 + return c.setFlags[name] == true
144 +}
145 +
146 +// Determines if the global flag was actually set
147 +func (c *Context) GlobalIsSet(name string) bool {
148 + if c.globalSetFlags == nil {
149 + c.globalSetFlags = make(map[string]bool)
150 + ctx := c
151 + if ctx.parentContext != nil {
152 + ctx = ctx.parentContext
153 + }
154 + for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
155 + ctx.flagSet.Visit(func(f *flag.Flag) {
156 + c.globalSetFlags[f.Name] = true
157 + })
158 + }
159 + }
160 + return c.globalSetFlags[name]
161 +}
162 +
163 +// Returns a slice of flag names used in this context.
164 +func (c *Context) FlagNames() (names []string) {
165 + for _, flag := range c.Command.Flags {
166 + name := strings.Split(flag.GetName(), ",")[0]
167 + if name == "help" {
168 + continue
169 + }
170 + names = append(names, name)
171 + }
172 + return
173 +}
174 +
175 +// Returns a slice of global flag names used by the app.
176 +func (c *Context) GlobalFlagNames() (names []string) {
177 + for _, flag := range c.App.Flags {
178 + name := strings.Split(flag.GetName(), ",")[0]
179 + if name == "help" || name == "version" {
180 + continue
181 + }
182 + names = append(names, name)
183 + }
184 + return
185 +}
186 +
187 +// Returns the parent context, if any
188 +func (c *Context) Parent() *Context {
189 + return c.parentContext
190 +}
191 +
192 +type Args []string
193 +
194 +// Returns the command line arguments associated with the context.
195 +func (c *Context) Args() Args {
196 + args := Args(c.flagSet.Args())
197 + return args
198 +}
199 +
200 +// Returns the number of the command line arguments.
201 +func (c *Context) NArg() int {
202 + return len(c.Args())
203 +}
204 +
205 +// Returns the nth argument, or else a blank string
206 +func (a Args) Get(n int) string {
207 + if len(a) > n {
208 + return a[n]
209 + }
210 + return ""
211 +}
212 +
213 +// Returns the first argument, or else a blank string
214 +func (a Args) First() string {
215 + return a.Get(0)
216 +}
217 +
218 +// Return the rest of the arguments (not the first one)
219 +// or else an empty string slice
220 +func (a Args) Tail() []string {
221 + if len(a) >= 2 {
222 + return []string(a)[1:]
223 + }
224 + return []string{}
225 +}
226 +
227 +// Checks if there are any arguments present
228 +func (a Args) Present() bool {
229 + return len(a) != 0
230 +}
231 +
232 +// Swaps arguments at the given indexes
233 +func (a Args) Swap(from, to int) error {
234 + if from >= len(a) || to >= len(a) {
235 + return errors.New("index out of range")
236 + }
237 + a[from], a[to] = a[to], a[from]
238 + return nil
239 +}
240 +
241 +func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
242 + if ctx.parentContext != nil {
243 + ctx = ctx.parentContext
244 + }
245 + for ; ctx != nil; ctx = ctx.parentContext {
246 + if f := ctx.flagSet.Lookup(name); f != nil {
247 + return ctx.flagSet
248 + }
249 + }
250 + return nil
251 +}
252 +
253 +func lookupInt(name string, set *flag.FlagSet) int {
254 + f := set.Lookup(name)
255 + if f != nil {
256 + val, err := strconv.Atoi(f.Value.String())
257 + if err != nil {
258 + return 0
259 + }
260 + return val
261 + }
262 +
263 + return 0
264 +}
265 +
266 +func lookupDuration(name string, set *flag.FlagSet) time.Duration {
267 + f := set.Lookup(name)
268 + if f != nil {
269 + val, err := time.ParseDuration(f.Value.String())
270 + if err == nil {
271 + return val
272 + }
273 + }
274 +
275 + return 0
276 +}
277 +
278 +func lookupFloat64(name string, set *flag.FlagSet) float64 {
279 + f := set.Lookup(name)
280 + if f != nil {
281 + val, err := strconv.ParseFloat(f.Value.String(), 64)
282 + if err != nil {
283 + return 0
284 + }
285 + return val
286 + }
287 +
288 + return 0
289 +}
290 +
291 +func lookupString(name string, set *flag.FlagSet) string {
292 + f := set.Lookup(name)
293 + if f != nil {
294 + return f.Value.String()
295 + }
296 +
297 + return ""
298 +}
299 +
300 +func lookupStringSlice(name string, set *flag.FlagSet) []string {
301 + f := set.Lookup(name)
302 + if f != nil {
303 + return (f.Value.(*StringSlice)).Value()
304 +
305 + }
306 +
307 + return nil
308 +}
309 +
310 +func lookupIntSlice(name string, set *flag.FlagSet) []int {
311 + f := set.Lookup(name)
312 + if f != nil {
313 + return (f.Value.(*IntSlice)).Value()
314 +
315 + }
316 +
317 + return nil
318 +}
319 +
320 +func lookupGeneric(name string, set *flag.FlagSet) interface{} {
321 + f := set.Lookup(name)
322 + if f != nil {
323 + return f.Value
324 + }
325 + return nil
326 +}
327 +
328 +func lookupBool(name string, set *flag.FlagSet) bool {
329 + f := set.Lookup(name)
330 + if f != nil {
331 + val, err := strconv.ParseBool(f.Value.String())
332 + if err != nil {
333 + return false
334 + }
335 + return val
336 + }
337 +
338 + return false
339 +}
340 +
341 +func lookupBoolT(name string, set *flag.FlagSet) bool {
342 + f := set.Lookup(name)
343 + if f != nil {
344 + val, err := strconv.ParseBool(f.Value.String())
345 + if err != nil {
346 + return true
347 + }
348 + return val
349 + }
350 +
351 + return false
352 +}
353 +
354 +func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
355 + switch ff.Value.(type) {
356 + case *StringSlice:
357 + default:
358 + set.Set(name, ff.Value.String())
359 + }
360 +}
361 +
362 +func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
363 + visited := make(map[string]bool)
364 + set.Visit(func(f *flag.Flag) {
365 + visited[f.Name] = true
366 + })
367 + for _, f := range flags {
368 + parts := strings.Split(f.GetName(), ",")
369 + if len(parts) == 1 {
370 + continue
371 + }
372 + var ff *flag.Flag
373 + for _, name := range parts {
374 + name = strings.Trim(name, " ")
375 + if visited[name] {
376 + if ff != nil {
377 + return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
378 + }
379 + ff = set.Lookup(name)
380 + }
381 + }
382 + if ff == nil {
383 + continue
384 + }
385 + for _, name := range parts {
386 + name = strings.Trim(name, " ")
387 + if !visited[name] {
388 + copyFlag(name, ff, set)
389 + }
390 + }
391 + }
392 + return nil
393 +}
Godeps/_workspace/src/github.com/codegangsta/cli/context_test.go new
+121
@@ -0,0 +1,121 @@
1 +package cli
2 +
3 +import (
4 + "flag"
5 + "testing"
6 + "time"
7 +)
8 +
9 +func TestNewContext(t *testing.T) {
10 + set := flag.NewFlagSet("test", 0)
11 + set.Int("myflag", 12, "doc")
12 + globalSet := flag.NewFlagSet("test", 0)
13 + globalSet.Int("myflag", 42, "doc")
14 + globalCtx := NewContext(nil, globalSet, nil)
15 + command := Command{Name: "mycommand"}
16 + c := NewContext(nil, set, globalCtx)
17 + c.Command = command
18 + expect(t, c.Int("myflag"), 12)
19 + expect(t, c.GlobalInt("myflag"), 42)
20 + expect(t, c.Command.Name, "mycommand")
21 +}
22 +
23 +func TestContext_Int(t *testing.T) {
24 + set := flag.NewFlagSet("test", 0)
25 + set.Int("myflag", 12, "doc")
26 + c := NewContext(nil, set, nil)
27 + expect(t, c.Int("myflag"), 12)
28 +}
29 +
30 +func TestContext_Duration(t *testing.T) {
31 + set := flag.NewFlagSet("test", 0)
32 + set.Duration("myflag", time.Duration(12*time.Second), "doc")
33 + c := NewContext(nil, set, nil)
34 + expect(t, c.Duration("myflag"), time.Duration(12*time.Second))
35 +}
36 +
37 +func TestContext_String(t *testing.T) {
38 + set := flag.NewFlagSet("test", 0)
39 + set.String("myflag", "hello world", "doc")
40 + c := NewContext(nil, set, nil)
41 + expect(t, c.String("myflag"), "hello world")
42 +}
43 +
44 +func TestContext_Bool(t *testing.T) {
45 + set := flag.NewFlagSet("test", 0)
46 + set.Bool("myflag", false, "doc")
47 + c := NewContext(nil, set, nil)
48 + expect(t, c.Bool("myflag"), false)
49 +}
50 +
51 +func TestContext_BoolT(t *testing.T) {
52 + set := flag.NewFlagSet("test", 0)
53 + set.Bool("myflag", true, "doc")
54 + c := NewContext(nil, set, nil)
55 + expect(t, c.BoolT("myflag"), true)
56 +}
57 +
58 +func TestContext_Args(t *testing.T) {
59 + set := flag.NewFlagSet("test", 0)
60 + set.Bool("myflag", false, "doc")
61 + c := NewContext(nil, set, nil)
62 + set.Parse([]string{"--myflag", "bat", "baz"})
63 + expect(t, len(c.Args()), 2)
64 + expect(t, c.Bool("myflag"), true)
65 +}
66 +
67 +func TestContext_NArg(t *testing.T) {
68 + set := flag.NewFlagSet("test", 0)
69 + set.Bool("myflag", false, "doc")
70 + c := NewContext(nil, set, nil)
71 + set.Parse([]string{"--myflag", "bat", "baz"})
72 + expect(t, c.NArg(), 2)
73 +}
74 +
75 +func TestContext_IsSet(t *testing.T) {
76 + set := flag.NewFlagSet("test", 0)
77 + set.Bool("myflag", false, "doc")
78 + set.String("otherflag", "hello world", "doc")
79 + globalSet := flag.NewFlagSet("test", 0)
80 + globalSet.Bool("myflagGlobal", true, "doc")
81 + globalCtx := NewContext(nil, globalSet, nil)
82 + c := NewContext(nil, set, globalCtx)
83 + set.Parse([]string{"--myflag", "bat", "baz"})
84 + globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
85 + expect(t, c.IsSet("myflag"), true)
86 + expect(t, c.IsSet("otherflag"), false)
87 + expect(t, c.IsSet("bogusflag"), false)
88 + expect(t, c.IsSet("myflagGlobal"), false)
89 +}
90 +
91 +func TestContext_GlobalIsSet(t *testing.T) {
92 + set := flag.NewFlagSet("test", 0)
93 + set.Bool("myflag", false, "doc")
94 + set.String("otherflag", "hello world", "doc")
95 + globalSet := flag.NewFlagSet("test", 0)
96 + globalSet.Bool("myflagGlobal", true, "doc")
97 + globalSet.Bool("myflagGlobalUnset", true, "doc")
98 + globalCtx := NewContext(nil, globalSet, nil)
99 + c := NewContext(nil, set, globalCtx)
100 + set.Parse([]string{"--myflag", "bat", "baz"})
101 + globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
102 + expect(t, c.GlobalIsSet("myflag"), false)
103 + expect(t, c.GlobalIsSet("otherflag"), false)
104 + expect(t, c.GlobalIsSet("bogusflag"), false)
105 + expect(t, c.GlobalIsSet("myflagGlobal"), true)
106 + expect(t, c.GlobalIsSet("myflagGlobalUnset"), false)
107 + expect(t, c.GlobalIsSet("bogusGlobal"), false)
108 +}
109 +
110 +func TestContext_NumFlags(t *testing.T) {
111 + set := flag.NewFlagSet("test", 0)
112 + set.Bool("myflag", false, "doc")
113 + set.String("otherflag", "hello world", "doc")
114 + globalSet := flag.NewFlagSet("test", 0)
115 + globalSet.Bool("myflagGlobal", true, "doc")
116 + globalCtx := NewContext(nil, globalSet, nil)
117 + c := NewContext(nil, set, globalCtx)
118 + set.Parse([]string{"--myflag", "--otherflag=foo"})
119 + globalSet.Parse([]string{"--myflagGlobal"})
120 + expect(t, c.NumFlags(), 2)
121 +}
Godeps/_workspace/src/github.com/codegangsta/cli/flag.go new
+546
@@ -0,0 +1,546 @@
1 +package cli
2 +
3 +import (
4 + "flag"
5 + "fmt"
6 + "os"
7 + "runtime"
8 + "strconv"
9 + "strings"
10 + "time"
11 +)
12 +
13 +// This flag enables bash-completion for all commands and subcommands
14 +var BashCompletionFlag = BoolFlag{
15 + Name: "generate-bash-completion",
16 +}
17 +
18 +// This flag prints the version for the application
19 +var VersionFlag = BoolFlag{
20 + Name: "version, v",
21 + Usage: "print the version",
22 +}
23 +
24 +// This flag prints the help for all commands and subcommands
25 +// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
26 +// unless HideHelp is set to true)
27 +var HelpFlag = BoolFlag{
28 + Name: "help, h",
29 + Usage: "show help",
30 +}
31 +
32 +// Flag is a common interface related to parsing flags in cli.
33 +// For more advanced flag parsing techniques, it is recommended that
34 +// this interface be implemented.
35 +type Flag interface {
36 + fmt.Stringer
37 + // Apply Flag settings to the given flag set
38 + Apply(*flag.FlagSet)
39 + GetName() string
40 +}
41 +
42 +func flagSet(name string, flags []Flag) *flag.FlagSet {
43 + set := flag.NewFlagSet(name, flag.ContinueOnError)
44 +
45 + for _, f := range flags {
46 + f.Apply(set)
47 + }
48 + return set
49 +}
50 +
51 +func eachName(longName string, fn func(string)) {
52 + parts := strings.Split(longName, ",")
53 + for _, name := range parts {
54 + name = strings.Trim(name, " ")
55 + fn(name)
56 + }
57 +}
58 +
59 +// Generic is a generic parseable type identified by a specific flag
60 +type Generic interface {
61 + Set(value string) error
62 + String() string
63 +}
64 +
65 +// GenericFlag is the flag type for types implementing Generic
66 +type GenericFlag struct {
67 + Name string
68 + Value Generic
69 + Usage string
70 + EnvVar string
71 +}
72 +
73 +// String returns the string representation of the generic flag to display the
74 +// help text to the user (uses the String() method of the generic flag to show
75 +// the value)
76 +func (f GenericFlag) String() string {
77 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
78 +}
79 +
80 +func (f GenericFlag) FormatValueHelp() string {
81 + if f.Value == nil {
82 + return ""
83 + }
84 + s := f.Value.String()
85 + if len(s) == 0 {
86 + return ""
87 + }
88 + return fmt.Sprintf("\"%s\"", s)
89 +}
90 +
91 +// Apply takes the flagset and calls Set on the generic flag with the value
92 +// provided by the user for parsing by the flag
93 +func (f GenericFlag) Apply(set *flag.FlagSet) {
94 + val := f.Value
95 + if f.EnvVar != "" {
96 + for _, envVar := range strings.Split(f.EnvVar, ",") {
97 + envVar = strings.TrimSpace(envVar)
98 + if envVal := os.Getenv(envVar); envVal != "" {
99 + val.Set(envVal)
100 + break
101 + }
102 + }
103 + }
104 +
105 + eachName(f.Name, func(name string) {
106 + set.Var(f.Value, name, f.Usage)
107 + })
108 +}
109 +
110 +func (f GenericFlag) GetName() string {
111 + return f.Name
112 +}
113 +
114 +// StringSlice is an opaque type for []string to satisfy flag.Value
115 +type StringSlice []string
116 +
117 +// Set appends the string value to the list of values
118 +func (f *StringSlice) Set(value string) error {
119 + *f = append(*f, value)
120 + return nil
121 +}
122 +
123 +// String returns a readable representation of this value (for usage defaults)
124 +func (f *StringSlice) String() string {
125 + return fmt.Sprintf("%s", *f)
126 +}
127 +
128 +// Value returns the slice of strings set by this flag
129 +func (f *StringSlice) Value() []string {
130 + return *f
131 +}
132 +
133 +// StringSlice is a string flag that can be specified multiple times on the
134 +// command-line
135 +type StringSliceFlag struct {
136 + Name string
137 + Value *StringSlice
138 + Usage string
139 + EnvVar string
140 +}
141 +
142 +// String returns the usage
143 +func (f StringSliceFlag) String() string {
144 + firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
145 + pref := prefixFor(firstName)
146 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
147 +}
148 +
149 +// Apply populates the flag given the flag set and environment
150 +func (f StringSliceFlag) Apply(set *flag.FlagSet) {
151 + if f.EnvVar != "" {
152 + for _, envVar := range strings.Split(f.EnvVar, ",") {
153 + envVar = strings.TrimSpace(envVar)
154 + if envVal := os.Getenv(envVar); envVal != "" {
155 + newVal := &StringSlice{}
156 + for _, s := range strings.Split(envVal, ",") {
157 + s = strings.TrimSpace(s)
158 + newVal.Set(s)
159 + }
160 + f.Value = newVal
161 + break
162 + }
163 + }
164 + }
165 +
166 + eachName(f.Name, func(name string) {
167 + if f.Value == nil {
168 + f.Value = &StringSlice{}
169 + }
170 + set.Var(f.Value, name, f.Usage)
171 + })
172 +}
173 +
174 +func (f StringSliceFlag) GetName() string {
175 + return f.Name
176 +}
177 +
178 +// StringSlice is an opaque type for []int to satisfy flag.Value
179 +type IntSlice []int
180 +
181 +// Set parses the value into an integer and appends it to the list of values
182 +func (f *IntSlice) Set(value string) error {
183 + tmp, err := strconv.Atoi(value)
184 + if err != nil {
185 + return err
186 + } else {
187 + *f = append(*f, tmp)
188 + }
189 + return nil
190 +}
191 +
192 +// String returns a readable representation of this value (for usage defaults)
193 +func (f *IntSlice) String() string {
194 + return fmt.Sprintf("%d", *f)
195 +}
196 +
197 +// Value returns the slice of ints set by this flag
198 +func (f *IntSlice) Value() []int {
199 + return *f
200 +}
201 +
202 +// IntSliceFlag is an int flag that can be specified multiple times on the
203 +// command-line
204 +type IntSliceFlag struct {
205 + Name string
206 + Value *IntSlice
207 + Usage string
208 + EnvVar string
209 +}
210 +
211 +// String returns the usage
212 +func (f IntSliceFlag) String() string {
213 + firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
214 + pref := prefixFor(firstName)
215 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
216 +}
217 +
218 +// Apply populates the flag given the flag set and environment
219 +func (f IntSliceFlag) Apply(set *flag.FlagSet) {
220 + if f.EnvVar != "" {
221 + for _, envVar := range strings.Split(f.EnvVar, ",") {
222 + envVar = strings.TrimSpace(envVar)
223 + if envVal := os.Getenv(envVar); envVal != "" {
224 + newVal := &IntSlice{}
225 + for _, s := range strings.Split(envVal, ",") {
226 + s = strings.TrimSpace(s)
227 + err := newVal.Set(s)
228 + if err != nil {
229 + fmt.Fprintf(os.Stderr, err.Error())
230 + }
231 + }
232 + f.Value = newVal
233 + break
234 + }
235 + }
236 + }
237 +
238 + eachName(f.Name, func(name string) {
239 + if f.Value == nil {
240 + f.Value = &IntSlice{}
241 + }
242 + set.Var(f.Value, name, f.Usage)
243 + })
244 +}
245 +
246 +func (f IntSliceFlag) GetName() string {
247 + return f.Name
248 +}
249 +
250 +// BoolFlag is a switch that defaults to false
251 +type BoolFlag struct {
252 + Name string
253 + Usage string
254 + EnvVar string
255 + Destination *bool
256 +}
257 +
258 +// String returns a readable representation of this value (for usage defaults)
259 +func (f BoolFlag) String() string {
260 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
261 +}
262 +
263 +// Apply populates the flag given the flag set and environment
264 +func (f BoolFlag) Apply(set *flag.FlagSet) {
265 + val := false
266 + if f.EnvVar != "" {
267 + for _, envVar := range strings.Split(f.EnvVar, ",") {
268 + envVar = strings.TrimSpace(envVar)
269 + if envVal := os.Getenv(envVar); envVal != "" {
270 + envValBool, err := strconv.ParseBool(envVal)
271 + if err == nil {
272 + val = envValBool
273 + }
274 + break
275 + }
276 + }
277 + }
278 +
279 + eachName(f.Name, func(name string) {
280 + if f.Destination != nil {
281 + set.BoolVar(f.Destination, name, val, f.Usage)
282 + return
283 + }
284 + set.Bool(name, val, f.Usage)
285 + })
286 +}
287 +
288 +func (f BoolFlag) GetName() string {
289 + return f.Name
290 +}
291 +
292 +// BoolTFlag this represents a boolean flag that is true by default, but can
293 +// still be set to false by --some-flag=false
294 +type BoolTFlag struct {
295 + Name string
296 + Usage string
297 + EnvVar string
298 + Destination *bool
299 +}
300 +
301 +// String returns a readable representation of this value (for usage defaults)
302 +func (f BoolTFlag) String() string {
303 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
304 +}
305 +
306 +// Apply populates the flag given the flag set and environment
307 +func (f BoolTFlag) Apply(set *flag.FlagSet) {
308 + val := true
309 + if f.EnvVar != "" {
310 + for _, envVar := range strings.Split(f.EnvVar, ",") {
311 + envVar = strings.TrimSpace(envVar)
312 + if envVal := os.Getenv(envVar); envVal != "" {
313 + envValBool, err := strconv.ParseBool(envVal)
314 + if err == nil {
315 + val = envValBool
316 + break
317 + }
318 + }
319 + }
320 + }
321 +
322 + eachName(f.Name, func(name string) {
323 + if f.Destination != nil {
324 + set.BoolVar(f.Destination, name, val, f.Usage)
325 + return
326 + }
327 + set.Bool(name, val, f.Usage)
328 + })
329 +}
330 +
331 +func (f BoolTFlag) GetName() string {
332 + return f.Name
333 +}
334 +
335 +// StringFlag represents a flag that takes as string value
336 +type StringFlag struct {
337 + Name string
338 + Value string
339 + Usage string
340 + EnvVar string
341 + Destination *string
342 +}
343 +
344 +// String returns the usage
345 +func (f StringFlag) String() string {
346 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
347 +}
348 +
349 +func (f StringFlag) FormatValueHelp() string {
350 + s := f.Value
351 + if len(s) == 0 {
352 + return ""
353 + }
354 + return fmt.Sprintf("\"%s\"", s)
355 +}
356 +
357 +// Apply populates the flag given the flag set and environment
358 +func (f StringFlag) Apply(set *flag.FlagSet) {
359 + if f.EnvVar != "" {
360 + for _, envVar := range strings.Split(f.EnvVar, ",") {
361 + envVar = strings.TrimSpace(envVar)
362 + if envVal := os.Getenv(envVar); envVal != "" {
363 + f.Value = envVal
364 + break
365 + }
366 + }
367 + }
368 +
369 + eachName(f.Name, func(name string) {
370 + if f.Destination != nil {
371 + set.StringVar(f.Destination, name, f.Value, f.Usage)
372 + return
373 + }
374 + set.String(name, f.Value, f.Usage)
375 + })
376 +}
377 +
378 +func (f StringFlag) GetName() string {
379 + return f.Name
380 +}
381 +
382 +// IntFlag is a flag that takes an integer
383 +// Errors if the value provided cannot be parsed
384 +type IntFlag struct {
385 + Name string
386 + Value int
387 + Usage string
388 + EnvVar string
389 + Destination *int
390 +}
391 +
392 +// String returns the usage
393 +func (f IntFlag) String() string {
394 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
395 +}
396 +
397 +// Apply populates the flag given the flag set and environment
398 +func (f IntFlag) Apply(set *flag.FlagSet) {
399 + if f.EnvVar != "" {
400 + for _, envVar := range strings.Split(f.EnvVar, ",") {
401 + envVar = strings.TrimSpace(envVar)
402 + if envVal := os.Getenv(envVar); envVal != "" {
403 + envValInt, err := strconv.ParseInt(envVal, 0, 64)
404 + if err == nil {
405 + f.Value = int(envValInt)
406 + break
407 + }
408 + }
409 + }
410 + }
411 +
412 + eachName(f.Name, func(name string) {
413 + if f.Destination != nil {
414 + set.IntVar(f.Destination, name, f.Value, f.Usage)
415 + return
416 + }
417 + set.Int(name, f.Value, f.Usage)
418 + })
419 +}
420 +
421 +func (f IntFlag) GetName() string {
422 + return f.Name
423 +}
424 +
425 +// DurationFlag is a flag that takes a duration specified in Go's duration
426 +// format: https://golang.org/pkg/time/#ParseDuration
427 +type DurationFlag struct {
428 + Name string
429 + Value time.Duration
430 + Usage string
431 + EnvVar string
432 + Destination *time.Duration
433 +}
434 +
435 +// String returns a readable representation of this value (for usage defaults)
436 +func (f DurationFlag) String() string {
437 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
438 +}
439 +
440 +// Apply populates the flag given the flag set and environment
441 +func (f DurationFlag) Apply(set *flag.FlagSet) {
442 + if f.EnvVar != "" {
443 + for _, envVar := range strings.Split(f.EnvVar, ",") {
444 + envVar = strings.TrimSpace(envVar)
445 + if envVal := os.Getenv(envVar); envVal != "" {
446 + envValDuration, err := time.ParseDuration(envVal)
447 + if err == nil {
448 + f.Value = envValDuration
449 + break
450 + }
451 + }
452 + }
453 + }
454 +
455 + eachName(f.Name, func(name string) {
456 + if f.Destination != nil {
457 + set.DurationVar(f.Destination, name, f.Value, f.Usage)
458 + return
459 + }
460 + set.Duration(name, f.Value, f.Usage)
461 + })
462 +}
463 +
464 +func (f DurationFlag) GetName() string {
465 + return f.Name
466 +}
467 +
468 +// Float64Flag is a flag that takes an float value
469 +// Errors if the value provided cannot be parsed
470 +type Float64Flag struct {
471 + Name string
472 + Value float64
473 + Usage string
474 + EnvVar string
475 + Destination *float64
476 +}
477 +
478 +// String returns the usage
479 +func (f Float64Flag) String() string {
480 + return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
481 +}
482 +
483 +// Apply populates the flag given the flag set and environment
484 +func (f Float64Flag) Apply(set *flag.FlagSet) {
485 + if f.EnvVar != "" {
486 + for _, envVar := range strings.Split(f.EnvVar, ",") {
487 + envVar = strings.TrimSpace(envVar)
488 + if envVal := os.Getenv(envVar); envVal != "" {
489 + envValFloat, err := strconv.ParseFloat(envVal, 10)
490 + if err == nil {
491 + f.Value = float64(envValFloat)
492 + }
493 + }
494 + }
495 + }
496 +
497 + eachName(f.Name, func(name string) {
498 + if f.Destination != nil {
499 + set.Float64Var(f.Destination, name, f.Value, f.Usage)
500 + return
501 + }
502 + set.Float64(name, f.Value, f.Usage)
503 + })
504 +}
505 +
506 +func (f Float64Flag) GetName() string {
507 + return f.Name
508 +}
509 +
510 +func prefixFor(name string) (prefix string) {
511 + if len(name) == 1 {
512 + prefix = "-"
513 + } else {
514 + prefix = "--"
515 + }
516 +
517 + return
518 +}
519 +
520 +func prefixedNames(fullName string) (prefixed string) {
521 + parts := strings.Split(fullName, ",")
522 + for i, name := range parts {
523 + name = strings.Trim(name, " ")
524 + prefixed += prefixFor(name) + name
525 + if i < len(parts)-1 {
526 + prefixed += ", "
527 + }
528 + }
529 + return
530 +}
531 +
532 +func withEnvHint(envVar, str string) string {
533 + envText := ""
534 + if envVar != "" {
535 + prefix := "$"
536 + suffix := ""
537 + sep := ", $"
538 + if runtime.GOOS == "windows" {
539 + prefix = "%"
540 + suffix = "%"
541 + sep = "%, %"
542 + }
543 + envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(strings.Split(envVar, ","), sep), suffix)
544 + }
545 + return str + envText
546 +}
Godeps/_workspace/src/github.com/codegangsta/cli/flag_test.go new
+859
@@ -0,0 +1,859 @@
1 +package cli
2 +
3 +import (
4 + "fmt"
5 + "os"
6 + "reflect"
7 + "strings"
8 + "testing"
9 + "runtime"
10 +)
11 +
12 +var boolFlagTests = []struct {
13 + name string
14 + expected string
15 +}{
16 + {"help", "--help\t"},
17 + {"h", "-h\t"},
18 +}
19 +
20 +func TestBoolFlagHelpOutput(t *testing.T) {
21 +
22 + for _, test := range boolFlagTests {
23 + flag := BoolFlag{Name: test.name}
24 + output := flag.String()
25 +
26 + if output != test.expected {
27 + t.Errorf("%s does not match %s", output, test.expected)
28 + }
29 + }
30 +}
31 +
32 +var stringFlagTests = []struct {
33 + name string
34 + value string
35 + expected string
36 +}{
37 + {"help", "", "--help \t"},
38 + {"h", "", "-h \t"},
39 + {"h", "", "-h \t"},
40 + {"test", "Something", "--test \"Something\"\t"},
41 +}
42 +
43 +func TestStringFlagHelpOutput(t *testing.T) {
44 +
45 + for _, test := range stringFlagTests {
46 + flag := StringFlag{Name: test.name, Value: test.value}
47 + output := flag.String()
48 +
49 + if output != test.expected {
50 + t.Errorf("%s does not match %s", output, test.expected)
51 + }
52 + }
53 +}
54 +
55 +func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
56 + os.Clearenv()
57 + os.Setenv("APP_FOO", "derp")
58 + for _, test := range stringFlagTests {
59 + flag := StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"}
60 + output := flag.String()
61 +
62 + expectedSuffix := " [$APP_FOO]"
63 + if runtime.GOOS == "windows" {
64 + expectedSuffix = " [%APP_FOO%]"
65 + }
66 + if !strings.HasSuffix(output, expectedSuffix) {
67 + t.Errorf("%s does not end with" + expectedSuffix, output)
68 + }
69 + }
70 +}
71 +
72 +var stringSliceFlagTests = []struct {
73 + name string
74 + value *StringSlice
75 + expected string
76 +}{
77 + {"help", func() *StringSlice {
78 + s := &StringSlice{}
79 + s.Set("")
80 + return s
81 + }(), "--help [--help option --help option]\t"},
82 + {"h", func() *StringSlice {
83 + s := &StringSlice{}
84 + s.Set("")
85 + return s
86 + }(), "-h [-h option -h option]\t"},
87 + {"h", func() *StringSlice {
88 + s := &StringSlice{}
89 + s.Set("")
90 + return s
91 + }(), "-h [-h option -h option]\t"},
92 + {"test", func() *StringSlice {
93 + s := &StringSlice{}
94 + s.Set("Something")
95 + return s
96 + }(), "--test [--test option --test option]\t"},
97 +}
98 +
99 +func TestStringSliceFlagHelpOutput(t *testing.T) {
100 +
101 + for _, test := range stringSliceFlagTests {
102 + flag := StringSliceFlag{Name: test.name, Value: test.value}
103 + output := flag.String()
104 +
105 + if output != test.expected {
106 + t.Errorf("%q does not match %q", output, test.expected)
107 + }
108 + }
109 +}
110 +
111 +func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) {
112 + os.Clearenv()
113 + os.Setenv("APP_QWWX", "11,4")
114 + for _, test := range stringSliceFlagTests {
115 + flag := StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"}
116 + output := flag.String()
117 +
118 + expectedSuffix := " [$APP_QWWX]"
119 + if runtime.GOOS == "windows" {
120 + expectedSuffix = " [%APP_QWWX%]"
121 + }
122 + if !strings.HasSuffix(output, expectedSuffix) {
123 + t.Errorf("%q does not end with" + expectedSuffix, output)
124 + }
125 + }
126 +}
127 +
128 +var intFlagTests = []struct {
129 + name string
130 + expected string
131 +}{
132 + {"help", "--help \"0\"\t"},
133 + {"h", "-h \"0\"\t"},
134 +}
135 +
136 +func TestIntFlagHelpOutput(t *testing.T) {
137 +
138 + for _, test := range intFlagTests {
139 + flag := IntFlag{Name: test.name}
140 + output := flag.String()
141 +
142 + if output != test.expected {
143 + t.Errorf("%s does not match %s", output, test.expected)
144 + }
145 + }
146 +}
147 +
148 +func TestIntFlagWithEnvVarHelpOutput(t *testing.T) {
149 + os.Clearenv()
150 + os.Setenv("APP_BAR", "2")
151 + for _, test := range intFlagTests {
152 + flag := IntFlag{Name: test.name, EnvVar: "APP_BAR"}
153 + output := flag.String()
154 +
155 + expectedSuffix := " [$APP_BAR]"
156 + if runtime.GOOS == "windows" {
157 + expectedSuffix = " [%APP_BAR%]"
158 + }
159 + if !strings.HasSuffix(output, expectedSuffix) {
160 + t.Errorf("%s does not end with" + expectedSuffix, output)
161 + }
162 + }
163 +}
164 +
165 +var durationFlagTests = []struct {
166 + name string
167 + expected string
168 +}{
169 + {"help", "--help \"0\"\t"},
170 + {"h", "-h \"0\"\t"},
171 +}
172 +
173 +func TestDurationFlagHelpOutput(t *testing.T) {
174 +
175 + for _, test := range durationFlagTests {
176 + flag := DurationFlag{Name: test.name}
177 + output := flag.String()
178 +
179 + if output != test.expected {
180 + t.Errorf("%s does not match %s", output, test.expected)
181 + }
182 + }
183 +}
184 +
185 +func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) {
186 + os.Clearenv()
187 + os.Setenv("APP_BAR", "2h3m6s")
188 + for _, test := range durationFlagTests {
189 + flag := DurationFlag{Name: test.name, EnvVar: "APP_BAR"}
190 + output := flag.String()
191 +
192 + expectedSuffix := " [$APP_BAR]"
193 + if runtime.GOOS == "windows" {
194 + expectedSuffix = " [%APP_BAR%]"
195 + }
196 + if !strings.HasSuffix(output, expectedSuffix) {
197 + t.Errorf("%s does not end with" + expectedSuffix, output)
198 + }
199 + }
200 +}
201 +
202 +var intSliceFlagTests = []struct {
203 + name string
204 + value *IntSlice
205 + expected string
206 +}{
207 + {"help", &IntSlice{}, "--help [--help option --help option]\t"},
208 + {"h", &IntSlice{}, "-h [-h option -h option]\t"},
209 + {"h", &IntSlice{}, "-h [-h option -h option]\t"},
210 + {"test", func() *IntSlice {
211 + i := &IntSlice{}
212 + i.Set("9")
213 + return i
214 + }(), "--test [--test option --test option]\t"},
215 +}
216 +
217 +func TestIntSliceFlagHelpOutput(t *testing.T) {
218 +
219 + for _, test := range intSliceFlagTests {
220 + flag := IntSliceFlag{Name: test.name, Value: test.value}
221 + output := flag.String()
222 +
223 + if output != test.expected {
224 + t.Errorf("%q does not match %q", output, test.expected)
225 + }
226 + }
227 +}
228 +
229 +func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) {
230 + os.Clearenv()
231 + os.Setenv("APP_SMURF", "42,3")
232 + for _, test := range intSliceFlagTests {
233 + flag := IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"}
234 + output := flag.String()
235 +
236 + expectedSuffix := " [$APP_SMURF]"
237 + if runtime.GOOS == "windows" {
238 + expectedSuffix = " [%APP_SMURF%]"
239 + }
240 + if !strings.HasSuffix(output, expectedSuffix) {
241 + t.Errorf("%q does not end with" + expectedSuffix, output)
242 + }
243 + }
244 +}
245 +
246 +var float64FlagTests = []struct {
247 + name string
248 + expected string
249 +}{
250 + {"help", "--help \"0\"\t"},
251 + {"h", "-h \"0\"\t"},
252 +}
253 +
254 +func TestFloat64FlagHelpOutput(t *testing.T) {
255 +
256 + for _, test := range float64FlagTests {
257 + flag := Float64Flag{Name: test.name}
258 + output := flag.String()
259 +
260 + if output != test.expected {
261 + t.Errorf("%s does not match %s", output, test.expected)
262 + }
263 + }
264 +}
265 +
266 +func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) {
267 + os.Clearenv()
268 + os.Setenv("APP_BAZ", "99.4")
269 + for _, test := range float64FlagTests {
270 + flag := Float64Flag{Name: test.name, EnvVar: "APP_BAZ"}
271 + output := flag.String()
272 +
273 + expectedSuffix := " [$APP_BAZ]"
274 + if runtime.GOOS == "windows" {
275 + expectedSuffix = " [%APP_BAZ%]"
276 + }
277 + if !strings.HasSuffix(output, expectedSuffix) {
278 + t.Errorf("%s does not end with" + expectedSuffix, output)
279 + }
280 + }
281 +}
282 +
283 +var genericFlagTests = []struct {
284 + name string
285 + value Generic
286 + expected string
287 +}{
288 + {"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"},
289 + {"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"},
290 +}
291 +
292 +func TestGenericFlagHelpOutput(t *testing.T) {
293 +
294 + for _, test := range genericFlagTests {
295 + flag := GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"}
296 + output := flag.String()
297 +
298 + if output != test.expected {
299 + t.Errorf("%q does not match %q", output, test.expected)
300 + }
301 + }
302 +}
303 +
304 +func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) {
305 + os.Clearenv()
306 + os.Setenv("APP_ZAP", "3")
307 + for _, test := range genericFlagTests {
308 + flag := GenericFlag{Name: test.name, EnvVar: "APP_ZAP"}
309 + output := flag.String()
310 +
311 + expectedSuffix := " [$APP_ZAP]"
312 + if runtime.GOOS == "windows" {
313 + expectedSuffix = " [%APP_ZAP%]"
314 + }
315 + if !strings.HasSuffix(output, expectedSuffix) {
316 + t.Errorf("%s does not end with" + expectedSuffix, output)
317 + }
318 + }
319 +}
320 +
321 +func TestParseMultiString(t *testing.T) {
322 + (&App{
323 + Flags: []Flag{
324 + StringFlag{Name: "serve, s"},
325 + },
326 + Action: func(ctx *Context) {
327 + if ctx.String("serve") != "10" {
328 + t.Errorf("main name not set")
329 + }
330 + if ctx.String("s") != "10" {
331 + t.Errorf("short name not set")
332 + }
333 + },
334 + }).Run([]string{"run", "-s", "10"})
335 +}
336 +
337 +func TestParseDestinationString(t *testing.T) {
338 + var dest string
339 + a := App{
340 + Flags: []Flag{
341 + StringFlag{
342 + Name: "dest",
343 + Destination: &dest,
344 + },
345 + },
346 + Action: func(ctx *Context) {
347 + if dest != "10" {
348 + t.Errorf("expected destination String 10")
349 + }
350 + },
351 + }
352 + a.Run([]string{"run", "--dest", "10"})
353 +}
354 +
355 +func TestParseMultiStringFromEnv(t *testing.T) {
356 + os.Clearenv()
357 + os.Setenv("APP_COUNT", "20")
358 + (&App{
359 + Flags: []Flag{
360 + StringFlag{Name: "count, c", EnvVar: "APP_COUNT"},
361 + },
362 + Action: func(ctx *Context) {
363 + if ctx.String("count") != "20" {
364 + t.Errorf("main name not set")
365 + }
366 + if ctx.String("c") != "20" {
367 + t.Errorf("short name not set")
368 + }
369 + },
370 + }).Run([]string{"run"})
371 +}
372 +
373 +func TestParseMultiStringFromEnvCascade(t *testing.T) {
374 + os.Clearenv()
375 + os.Setenv("APP_COUNT", "20")
376 + (&App{
377 + Flags: []Flag{
378 + StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"},
379 + },
380 + Action: func(ctx *Context) {
381 + if ctx.String("count") != "20" {
382 + t.Errorf("main name not set")
383 + }
384 + if ctx.String("c") != "20" {
385 + t.Errorf("short name not set")
386 + }
387 + },
388 + }).Run([]string{"run"})
389 +}
390 +
391 +func TestParseMultiStringSlice(t *testing.T) {
392 + (&App{
393 + Flags: []Flag{
394 + StringSliceFlag{Name: "serve, s", Value: &StringSlice{}},
395 + },
396 + Action: func(ctx *Context) {
397 + if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
398 + t.Errorf("main name not set")
399 + }
400 + if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
401 + t.Errorf("short name not set")
402 + }
403 + },
404 + }).Run([]string{"run", "-s", "10", "-s", "20"})
405 +}
406 +
407 +func TestParseMultiStringSliceFromEnv(t *testing.T) {
408 + os.Clearenv()
409 + os.Setenv("APP_INTERVALS", "20,30,40")
410 +
411 + (&App{
412 + Flags: []Flag{
413 + StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "APP_INTERVALS"},
414 + },
415 + Action: func(ctx *Context) {
416 + if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
417 + t.Errorf("main name not set from env")
418 + }
419 + if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
420 + t.Errorf("short name not set from env")
421 + }
422 + },
423 + }).Run([]string{"run"})
424 +}
425 +
426 +func TestParseMultiStringSliceFromEnvCascade(t *testing.T) {
427 + os.Clearenv()
428 + os.Setenv("APP_INTERVALS", "20,30,40")
429 +
430 + (&App{
431 + Flags: []Flag{
432 + StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
433 + },
434 + Action: func(ctx *Context) {
435 + if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
436 + t.Errorf("main name not set from env")
437 + }
438 + if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
439 + t.Errorf("short name not set from env")
440 + }
441 + },
442 + }).Run([]string{"run"})
443 +}
444 +
445 +func TestParseMultiInt(t *testing.T) {
446 + a := App{
447 + Flags: []Flag{
448 + IntFlag{Name: "serve, s"},
449 + },
450 + Action: func(ctx *Context) {
451 + if ctx.Int("serve") != 10 {
452 + t.Errorf("main name not set")
453 + }
454 + if ctx.Int("s") != 10 {
455 + t.Errorf("short name not set")
456 + }
457 + },
458 + }
459 + a.Run([]string{"run", "-s", "10"})
460 +}
461 +
462 +func TestParseDestinationInt(t *testing.T) {
463 + var dest int
464 + a := App{
465 + Flags: []Flag{
466 + IntFlag{
467 + Name: "dest",
468 + Destination: &dest,
469 + },
470 + },
471 + Action: func(ctx *Context) {
472 + if dest != 10 {
473 + t.Errorf("expected destination Int 10")
474 + }
475 + },
476 + }
477 + a.Run([]string{"run", "--dest", "10"})
478 +}
479 +
480 +func TestParseMultiIntFromEnv(t *testing.T) {
481 + os.Clearenv()
482 + os.Setenv("APP_TIMEOUT_SECONDS", "10")
483 + a := App{
484 + Flags: []Flag{
485 + IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
486 + },
487 + Action: func(ctx *Context) {
488 + if ctx.Int("timeout") != 10 {
489 + t.Errorf("main name not set")
490 + }
491 + if ctx.Int("t") != 10 {
492 + t.Errorf("short name not set")
493 + }
494 + },
495 + }
496 + a.Run([]string{"run"})
497 +}
498 +
499 +func TestParseMultiIntFromEnvCascade(t *testing.T) {
500 + os.Clearenv()
501 + os.Setenv("APP_TIMEOUT_SECONDS", "10")
502 + a := App{
503 + Flags: []Flag{
504 + IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
505 + },
506 + Action: func(ctx *Context) {
507 + if ctx.Int("timeout") != 10 {
508 + t.Errorf("main name not set")
509 + }
510 + if ctx.Int("t") != 10 {
511 + t.Errorf("short name not set")
512 + }
513 + },
514 + }
515 + a.Run([]string{"run"})
516 +}
517 +
518 +func TestParseMultiIntSlice(t *testing.T) {
519 + (&App{
520 + Flags: []Flag{
521 + IntSliceFlag{Name: "serve, s", Value: &IntSlice{}},
522 + },
523 + Action: func(ctx *Context) {
524 + if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) {
525 + t.Errorf("main name not set")
526 + }
527 + if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) {
528 + t.Errorf("short name not set")
529 + }
530 + },
531 + }).Run([]string{"run", "-s", "10", "-s", "20"})
532 +}
533 +
534 +func TestParseMultiIntSliceFromEnv(t *testing.T) {
535 + os.Clearenv()
536 + os.Setenv("APP_INTERVALS", "20,30,40")
537 +
538 + (&App{
539 + Flags: []Flag{
540 + IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "APP_INTERVALS"},
541 + },
542 + Action: func(ctx *Context) {
543 + if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
544 + t.Errorf("main name not set from env")
545 + }
546 + if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
547 + t.Errorf("short name not set from env")
548 + }
549 + },
550 + }).Run([]string{"run"})
551 +}
552 +
553 +func TestParseMultiIntSliceFromEnvCascade(t *testing.T) {
554 + os.Clearenv()
555 + os.Setenv("APP_INTERVALS", "20,30,40")
556 +
557 + (&App{
558 + Flags: []Flag{
559 + IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
560 + },
561 + Action: func(ctx *Context) {
562 + if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
563 + t.Errorf("main name not set from env")
564 + }
565 + if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
566 + t.Errorf("short name not set from env")
567 + }
568 + },
569 + }).Run([]string{"run"})
570 +}
571 +
572 +func TestParseMultiFloat64(t *testing.T) {
573 + a := App{
574 + Flags: []Flag{
575 + Float64Flag{Name: "serve, s"},
576 + },
577 + Action: func(ctx *Context) {
578 + if ctx.Float64("serve") != 10.2 {
579 + t.Errorf("main name not set")
580 + }
581 + if ctx.Float64("s") != 10.2 {
582 + t.Errorf("short name not set")
583 + }
584 + },
585 + }
586 + a.Run([]string{"run", "-s", "10.2"})
587 +}
588 +
589 +func TestParseDestinationFloat64(t *testing.T) {
590 + var dest float64
591 + a := App{
592 + Flags: []Flag{
593 + Float64Flag{
594 + Name: "dest",
595 + Destination: &dest,
596 + },
597 + },
598 + Action: func(ctx *Context) {
599 + if dest != 10.2 {
600 + t.Errorf("expected destination Float64 10.2")
601 + }
602 + },
603 + }
604 + a.Run([]string{"run", "--dest", "10.2"})
605 +}
606 +
607 +func TestParseMultiFloat64FromEnv(t *testing.T) {
608 + os.Clearenv()
609 + os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
610 + a := App{
611 + Flags: []Flag{
612 + Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
613 + },
614 + Action: func(ctx *Context) {
615 + if ctx.Float64("timeout") != 15.5 {
616 + t.Errorf("main name not set")
617 + }
618 + if ctx.Float64("t") != 15.5 {
619 + t.Errorf("short name not set")
620 + }
621 + },
622 + }
623 + a.Run([]string{"run"})
624 +}
625 +
626 +func TestParseMultiFloat64FromEnvCascade(t *testing.T) {
627 + os.Clearenv()
628 + os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
629 + a := App{
630 + Flags: []Flag{
631 + Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
632 + },
633 + Action: func(ctx *Context) {
634 + if ctx.Float64("timeout") != 15.5 {
635 + t.Errorf("main name not set")
636 + }
637 + if ctx.Float64("t") != 15.5 {
638 + t.Errorf("short name not set")
639 + }
640 + },
641 + }
642 + a.Run([]string{"run"})
643 +}
644 +
645 +func TestParseMultiBool(t *testing.T) {
646 + a := App{
647 + Flags: []Flag{
648 + BoolFlag{Name: "serve, s"},
649 + },
650 + Action: func(ctx *Context) {
651 + if ctx.Bool("serve") != true {
652 + t.Errorf("main name not set")
653 + }
654 + if ctx.Bool("s") != true {
655 + t.Errorf("short name not set")
656 + }
657 + },
658 + }
659 + a.Run([]string{"run", "--serve"})
660 +}
661 +
662 +func TestParseDestinationBool(t *testing.T) {
663 + var dest bool
664 + a := App{
665 + Flags: []Flag{
666 + BoolFlag{
667 + Name: "dest",
668 + Destination: &dest,
669 + },
670 + },
671 + Action: func(ctx *Context) {
672 + if dest != true {
673 + t.Errorf("expected destination Bool true")
674 + }
675 + },
676 + }
677 + a.Run([]string{"run", "--dest"})
678 +}
679 +
680 +func TestParseMultiBoolFromEnv(t *testing.T) {
681 + os.Clearenv()
682 + os.Setenv("APP_DEBUG", "1")
683 + a := App{
684 + Flags: []Flag{
685 + BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
686 + },
687 + Action: func(ctx *Context) {
688 + if ctx.Bool("debug") != true {
689 + t.Errorf("main name not set from env")
690 + }
691 + if ctx.Bool("d") != true {
692 + t.Errorf("short name not set from env")
693 + }
694 + },
695 + }
696 + a.Run([]string{"run"})
697 +}
698 +
699 +func TestParseMultiBoolFromEnvCascade(t *testing.T) {
700 + os.Clearenv()
701 + os.Setenv("APP_DEBUG", "1")
702 + a := App{
703 + Flags: []Flag{
704 + BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
705 + },
706 + Action: func(ctx *Context) {
707 + if ctx.Bool("debug") != true {
708 + t.Errorf("main name not set from env")
709 + }
710 + if ctx.Bool("d") != true {
711 + t.Errorf("short name not set from env")
712 + }
713 + },
714 + }
715 + a.Run([]string{"run"})
716 +}
717 +
718 +func TestParseMultiBoolT(t *testing.T) {
719 + a := App{
720 + Flags: []Flag{
721 + BoolTFlag{Name: "serve, s"},
722 + },
723 + Action: func(ctx *Context) {
724 + if ctx.BoolT("serve") != true {
725 + t.Errorf("main name not set")
726 + }
727 + if ctx.BoolT("s") != true {
728 + t.Errorf("short name not set")
729 + }
730 + },
731 + }
732 + a.Run([]string{"run", "--serve"})
733 +}
734 +
735 +func TestParseDestinationBoolT(t *testing.T) {
736 + var dest bool
737 + a := App{
738 + Flags: []Flag{
739 + BoolTFlag{
740 + Name: "dest",
741 + Destination: &dest,
742 + },
743 + },
744 + Action: func(ctx *Context) {
745 + if dest != true {
746 + t.Errorf("expected destination BoolT true")
747 + }
748 + },
749 + }
750 + a.Run([]string{"run", "--dest"})
751 +}
752 +
753 +func TestParseMultiBoolTFromEnv(t *testing.T) {
754 + os.Clearenv()
755 + os.Setenv("APP_DEBUG", "0")
756 + a := App{
757 + Flags: []Flag{
758 + BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
759 + },
760 + Action: func(ctx *Context) {
761 + if ctx.BoolT("debug") != false {
762 + t.Errorf("main name not set from env")
763 + }
764 + if ctx.BoolT("d") != false {
765 + t.Errorf("short name not set from env")
766 + }
767 + },
768 + }
769 + a.Run([]string{"run"})
770 +}
771 +
772 +func TestParseMultiBoolTFromEnvCascade(t *testing.T) {
773 + os.Clearenv()
774 + os.Setenv("APP_DEBUG", "0")
775 + a := App{
776 + Flags: []Flag{
777 + BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
778 + },
779 + Action: func(ctx *Context) {
780 + if ctx.BoolT("debug") != false {
781 + t.Errorf("main name not set from env")
782 + }
783 + if ctx.BoolT("d") != false {
784 + t.Errorf("short name not set from env")
785 + }
786 + },
787 + }
788 + a.Run([]string{"run"})
789 +}
790 +
791 +type Parser [2]string
792 +
793 +func (p *Parser) Set(value string) error {
794 + parts := strings.Split(value, ",")
795 + if len(parts) != 2 {
796 + return fmt.Errorf("invalid format")
797 + }
798 +
799 + (*p)[0] = parts[0]
800 + (*p)[1] = parts[1]
801 +
802 + return nil
803 +}
804 +
805 +func (p *Parser) String() string {
806 + return fmt.Sprintf("%s,%s", p[0], p[1])
807 +}
808 +
809 +func TestParseGeneric(t *testing.T) {
810 + a := App{
811 + Flags: []Flag{
812 + GenericFlag{Name: "serve, s", Value: &Parser{}},
813 + },
814 + Action: func(ctx *Context) {
815 + if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
816 + t.Errorf("main name not set")
817 + }
818 + if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
819 + t.Errorf("short name not set")
820 + }
821 + },
822 + }
823 + a.Run([]string{"run", "-s", "10,20"})
824 +}
825 +
826 +func TestParseGenericFromEnv(t *testing.T) {
827 + os.Clearenv()
828 + os.Setenv("APP_SERVE", "20,30")
829 + a := App{
830 + Flags: []Flag{
831 + GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"},
832 + },
833 + Action: func(ctx *Context) {
834 + if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) {
835 + t.Errorf("main name not set from env")
836 + }
837 + if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) {
838 + t.Errorf("short name not set from env")
839 + }
840 + },
841 + }
842 + a.Run([]string{"run"})
843 +}
844 +
845 +func TestParseGenericFromEnvCascade(t *testing.T) {
846 + os.Clearenv()
847 + os.Setenv("APP_FOO", "99,2000")
848 + a := App{
849 + Flags: []Flag{
850 + GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"},
851 + },
852 + Action: func(ctx *Context) {
853 + if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) {
854 + t.Errorf("value not set from env")
855 + }
856 + },
857 + }
858 + a.Run([]string{"run"})
859 +}
Godeps/_workspace/src/github.com/codegangsta/cli/help.go new
+248
@@ -0,0 +1,248 @@
1 +package cli
2 +
3 +import (
4 + "fmt"
5 + "io"
6 + "strings"
7 + "text/tabwriter"
8 + "text/template"
9 +)
10 +
11 +// The text template for the Default help topic.
12 +// cli.go uses text/template to render templates. You can
13 +// render custom help text by setting this variable.
14 +var AppHelpTemplate = `NAME:
15 + {{.Name}} - {{.Usage}}
16 +
17 +USAGE:
18 + {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
19 + {{if .Version}}
20 +VERSION:
21 + {{.Version}}
22 + {{end}}{{if len .Authors}}
23 +AUTHOR(S):
24 + {{range .Authors}}{{ . }}{{end}}
25 + {{end}}{{if .Commands}}
26 +COMMANDS:
27 + {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
28 + {{end}}{{end}}{{if .Flags}}
29 +GLOBAL OPTIONS:
30 + {{range .Flags}}{{.}}
31 + {{end}}{{end}}{{if .Copyright }}
32 +COPYRIGHT:
33 + {{.Copyright}}
34 + {{end}}
35 +`
36 +
37 +// The text template for the command help topic.
38 +// cli.go uses text/template to render templates. You can
39 +// render custom help text by setting this variable.
40 +var CommandHelpTemplate = `NAME:
41 + {{.HelpName}} - {{.Usage}}
42 +
43 +USAGE:
44 + {{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Description}}
45 +
46 +DESCRIPTION:
47 + {{.Description}}{{end}}{{if .Flags}}
48 +
49 +OPTIONS:
50 + {{range .Flags}}{{.}}
51 + {{end}}{{ end }}
52 +`
53 +
54 +// The text template for the subcommand help topic.
55 +// cli.go uses text/template to render templates. You can
56 +// render custom help text by setting this variable.
57 +var SubcommandHelpTemplate = `NAME:
58 + {{.HelpName}} - {{.Usage}}
59 +
60 +USAGE:
61 + {{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
62 +
63 +COMMANDS:
64 + {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
65 + {{end}}{{if .Flags}}
66 +OPTIONS:
67 + {{range .Flags}}{{.}}
68 + {{end}}{{end}}
69 +`
70 +
71 +var helpCommand = Command{
72 + Name: "help",
73 + Aliases: []string{"h"},
74 + Usage: "Shows a list of commands or help for one command",
75 + ArgsUsage: "[command]",
76 + Action: func(c *Context) {
77 + args := c.Args()
78 + if args.Present() {
79 + ShowCommandHelp(c, args.First())
80 + } else {
81 + ShowAppHelp(c)
82 + }
83 + },
84 +}
85 +
86 +var helpSubcommand = Command{
87 + Name: "help",
88 + Aliases: []string{"h"},
89 + Usage: "Shows a list of commands or help for one command",
90 + ArgsUsage: "[command]",
91 + Action: func(c *Context) {
92 + args := c.Args()
93 + if args.Present() {
94 + ShowCommandHelp(c, args.First())
95 + } else {
96 + ShowSubcommandHelp(c)
97 + }
98 + },
99 +}
100 +
101 +// Prints help for the App or Command
102 +type helpPrinter func(w io.Writer, templ string, data interface{})
103 +
104 +var HelpPrinter helpPrinter = printHelp
105 +
106 +// Prints version for the App
107 +var VersionPrinter = printVersion
108 +
109 +func ShowAppHelp(c *Context) {
110 + HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
111 +}
112 +
113 +// Prints the list of subcommands as the default app completion method
114 +func DefaultAppComplete(c *Context) {
115 + for _, command := range c.App.Commands {
116 + for _, name := range command.Names() {
117 + fmt.Fprintln(c.App.Writer, name)
118 + }
119 + }
120 +}
121 +
122 +// Prints help for the given command
123 +func ShowCommandHelp(ctx *Context, command string) {
124 + // show the subcommand help for a command with subcommands
125 + if command == "" {
126 + HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App)
127 + return
128 + }
129 +
130 + for _, c := range ctx.App.Commands {
131 + if c.HasName(command) {
132 + HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
133 + return
134 + }
135 + }
136 +
137 + if ctx.App.CommandNotFound != nil {
138 + ctx.App.CommandNotFound(ctx, command)
139 + } else {
140 + fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command)
141 + }
142 +}
143 +
144 +// Prints help for the given subcommand
145 +func ShowSubcommandHelp(c *Context) {
146 + ShowCommandHelp(c, c.Command.Name)
147 +}
148 +
149 +// Prints the version number of the App
150 +func ShowVersion(c *Context) {
151 + VersionPrinter(c)
152 +}
153 +
154 +func printVersion(c *Context) {
155 + fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
156 +}
157 +
158 +// Prints the lists of commands within a given context
159 +func ShowCompletions(c *Context) {
160 + a := c.App
161 + if a != nil && a.BashComplete != nil {
162 + a.BashComplete(c)
163 + }
164 +}
165 +
166 +// Prints the custom completions for a given command
167 +func ShowCommandCompletions(ctx *Context, command string) {
168 + c := ctx.App.Command(command)
169 + if c != nil && c.BashComplete != nil {
170 + c.BashComplete(ctx)
171 + }
172 +}
173 +
174 +func printHelp(out io.Writer, templ string, data interface{}) {
175 + funcMap := template.FuncMap{
176 + "join": strings.Join,
177 + }
178 +
179 + w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0)
180 + t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
181 + err := t.Execute(w, data)
182 + if err != nil {
183 + // If the writer is closed, t.Execute will fail, and there's nothing
184 + // we can do to recover. We could send this to os.Stderr if we need.
185 + return
186 + }
187 + w.Flush()
188 +}
189 +
190 +func checkVersion(c *Context) bool {
191 + found := false
192 + if VersionFlag.Name != "" {
193 + eachName(VersionFlag.Name, func(name string) {
194 + if c.GlobalBool(name) || c.Bool(name) {
195 + found = true
196 + }
197 + })
198 + }
199 + return found
200 +}
201 +
202 +func checkHelp(c *Context) bool {
203 + found := false
204 + if HelpFlag.Name != "" {
205 + eachName(HelpFlag.Name, func(name string) {
206 + if c.GlobalBool(name) || c.Bool(name) {
207 + found = true
208 + }
209 + })
210 + }
211 + return found
212 +}
213 +
214 +func checkCommandHelp(c *Context, name string) bool {
215 + if c.Bool("h") || c.Bool("help") {
216 + ShowCommandHelp(c, name)
217 + return true
218 + }
219 +
220 + return false
221 +}
222 +
223 +func checkSubcommandHelp(c *Context) bool {
224 + if c.GlobalBool("h") || c.GlobalBool("help") {
225 + ShowSubcommandHelp(c)
226 + return true
227 + }
228 +
229 + return false
230 +}
231 +
232 +func checkCompletions(c *Context) bool {
233 + if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion {
234 + ShowCompletions(c)
235 + return true
236 + }
237 +
238 + return false
239 +}
240 +
241 +func checkCommandCompletions(c *Context, name string) bool {
242 + if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
243 + ShowCommandCompletions(c, name)
244 + return true
245 + }
246 +
247 + return false
248 +}
Godeps/_workspace/src/github.com/codegangsta/cli/help_test.go new
+94
@@ -0,0 +1,94 @@
1 +package cli
2 +
3 +import (
4 + "bytes"
5 + "testing"
6 +)
7 +
8 +func Test_ShowAppHelp_NoAuthor(t *testing.T) {
9 + output := new(bytes.Buffer)
10 + app := NewApp()
11 + app.Writer = output
12 +
13 + c := NewContext(app, nil, nil)
14 +
15 + ShowAppHelp(c)
16 +
17 + if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
18 + t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
19 + }
20 +}
21 +
22 +func Test_ShowAppHelp_NoVersion(t *testing.T) {
23 + output := new(bytes.Buffer)
24 + app := NewApp()
25 + app.Writer = output
26 +
27 + app.Version = ""
28 +
29 + c := NewContext(app, nil, nil)
30 +
31 + ShowAppHelp(c)
32 +
33 + if bytes.Index(output.Bytes(), []byte("VERSION:")) != -1 {
34 + t.Errorf("expected\n%snot to include %s", output.String(), "VERSION:")
35 + }
36 +}
37 +
38 +func Test_Help_Custom_Flags(t *testing.T) {
39 + oldFlag := HelpFlag
40 + defer func() {
41 + HelpFlag = oldFlag
42 + }()
43 +
44 + HelpFlag = BoolFlag{
45 + Name: "help, x",
46 + Usage: "show help",
47 + }
48 +
49 + app := App{
50 + Flags: []Flag{
51 + BoolFlag{Name: "foo, h"},
52 + },
53 + Action: func(ctx *Context) {
54 + if ctx.Bool("h") != true {
55 + t.Errorf("custom help flag not set")
56 + }
57 + },
58 + }
59 + output := new(bytes.Buffer)
60 + app.Writer = output
61 + app.Run([]string{"test", "-h"})
62 + if output.Len() > 0 {
63 + t.Errorf("unexpected output: %s", output.String())
64 + }
65 +}
66 +
67 +func Test_Version_Custom_Flags(t *testing.T) {
68 + oldFlag := VersionFlag
69 + defer func() {
70 + VersionFlag = oldFlag
71 + }()
72 +
73 + VersionFlag = BoolFlag{
74 + Name: "version, V",
75 + Usage: "show version",
76 + }
77 +
78 + app := App{
79 + Flags: []Flag{
80 + BoolFlag{Name: "foo, v"},
81 + },
82 + Action: func(ctx *Context) {
83 + if ctx.Bool("v") != true {
84 + t.Errorf("custom version flag not set")
85 + }
86 + },
87 + }
88 + output := new(bytes.Buffer)
89 + app.Writer = output
90 + app.Run([]string{"test", "-v"})
91 + if output.Len() > 0 {
92 + t.Errorf("unexpected output: %s", output.String())
93 + }
94 +}
Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go new
+19
@@ -0,0 +1,19 @@
1 +package cli
2 +
3 +import (
4 + "reflect"
5 + "testing"
6 +)
7 +
8 +/* Test Helpers */
9 +func expect(t *testing.T, a interface{}, b interface{}) {
10 + if !reflect.DeepEqual(a, b) {
11 + t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
12 + }
13 +}
14 +
15 +func refute(t *testing.T, a interface{}, b interface{}) {
16 + if reflect.DeepEqual(a, b) {
17 + t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
18 + }
19 +}
Godeps/_workspace/src/github.com/coreos/go-semver/semver/semver.go deleted
-209
@@ -1,209 +0,0 @@
1 -package semver
2 -
3 -import (
4 - "bytes"
5 - "errors"
6 - "fmt"
7 - "strconv"
8 - "strings"
9 -)
10 -
11 -type Version struct {
12 - Major int64
13 - Minor int64
14 - Patch int64
15 - PreRelease PreRelease
16 - Metadata string
17 -}
18 -
19 -type PreRelease string
20 -
21 -func splitOff(input *string, delim string) (val string) {
22 - parts := strings.SplitN(*input, delim, 2)
23 -
24 - if len(parts) == 2 {
25 - *input = parts[0]
26 - val = parts[1]
27 - }
28 -
29 - return val
30 -}
31 -
32 -func NewVersion(version string) (*Version, error) {
33 - v := Version{}
34 -
35 - dotParts := strings.SplitN(version, ".", 3)
36 -
37 - if len(dotParts) != 3 {
38 - return nil, errors.New(fmt.Sprintf("%s is not in dotted-tri format", version))
39 - }
40 -
41 - v.Metadata = splitOff(&dotParts[2], "+")
42 - v.PreRelease = PreRelease(splitOff(&dotParts[2], "-"))
43 -
44 - parsed := make([]int64, 3, 3)
45 -
46 - for i, v := range dotParts[:3] {
47 - val, err := strconv.ParseInt(v, 10, 64)
48 - parsed[i] = val
49 - if err != nil {
50 - return nil, err
51 - }
52 - }
53 -
54 - v.Major = parsed[0]
55 - v.Minor = parsed[1]
56 - v.Patch = parsed[2]
57 -
58 - return &v, nil
59 -}
60 -
61 -func Must(v *Version, err error) *Version {
62 - if err != nil {
63 - panic(err)
64 - }
65 - return v
66 -}
67 -
68 -func (v *Version) String() string {
69 - var buffer bytes.Buffer
70 -
71 - base := fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
72 - buffer.WriteString(base)
73 -
74 - if v.PreRelease != "" {
75 - buffer.WriteString(fmt.Sprintf("-%s", v.PreRelease))
76 - }
77 -
78 - if v.Metadata != "" {
79 - buffer.WriteString(fmt.Sprintf("+%s", v.Metadata))
80 - }
81 -
82 - return buffer.String()
83 -}
84 -
85 -func (v *Version) LessThan(versionB Version) bool {
86 - versionA := *v
87 - cmp := recursiveCompare(versionA.Slice(), versionB.Slice())
88 -
89 - if cmp == 0 {
90 - cmp = preReleaseCompare(versionA, versionB)
91 - }
92 -
93 - if cmp == -1 {
94 - return true
95 - }
96 -
97 - return false
98 -}
99 -
100 -/* Slice converts the comparable parts of the semver into a slice of strings */
101 -func (v *Version) Slice() []int64 {
102 - return []int64{v.Major, v.Minor, v.Patch}
103 -}
104 -
105 -func (p *PreRelease) Slice() []string {
106 - preRelease := string(*p)
107 - return strings.Split(preRelease, ".")
108 -}
109 -
110 -func preReleaseCompare(versionA Version, versionB Version) int {
111 - a := versionA.PreRelease
112 - b := versionB.PreRelease
113 -
114 - /* Handle the case where if two versions are otherwise equal it is the
115 - * one without a PreRelease that is greater */
116 - if len(a) == 0 && (len(b) > 0) {
117 - return 1
118 - } else if len(b) == 0 && (len(a) > 0) {
119 - return -1
120 - }
121 -
122 - // If there is a prelease, check and compare each part.
123 - return recursivePreReleaseCompare(a.Slice(), b.Slice())
124 -}
125 -
126 -func recursiveCompare(versionA []int64, versionB []int64) int {
127 - if len(versionA) == 0 {
128 - return 0
129 - }
130 -
131 - a := versionA[0]
132 - b := versionB[0]
133 -
134 - if a > b {
135 - return 1
136 - } else if a < b {
137 - return -1
138 - }
139 -
140 - return recursiveCompare(versionA[1:], versionB[1:])
141 -}
142 -
143 -func recursivePreReleaseCompare(versionA []string, versionB []string) int {
144 - // Handle slice length disparity.
145 - if len(versionA) == 0 {
146 - // Nothing to compare too, so we return 0
147 - return 0
148 - } else if len(versionB) == 0 {
149 - // We're longer than versionB so return 1.
150 - return 1
151 - }
152 -
153 - a := versionA[0]
154 - b := versionB[0]
155 -
156 - aInt := false; bInt := false
157 -
158 - aI, err := strconv.Atoi(versionA[0])
159 - if err == nil {
160 - aInt = true
161 - }
162 -
163 - bI, err := strconv.Atoi(versionB[0])
164 - if err == nil {
165 - bInt = true
166 - }
167 -
168 - // Handle Integer Comparison
169 - if aInt && bInt {
170 - if aI > bI {
171 - return 1
172 - } else if aI < bI {
173 - return -1
174 - }
175 - }
176 -
177 - // Handle String Comparison
178 - if a > b {
179 - return 1
180 - } else if a < b {
181 - return -1
182 - }
183 -
184 - return recursivePreReleaseCompare(versionA[1:], versionB[1:])
185 -}
186 -
187 -// BumpMajor increments the Major field by 1 and resets all other fields to their default values
188 -func (v *Version) BumpMajor() {
189 - v.Major += 1
190 - v.Minor = 0
191 - v.Patch = 0
192 - v.PreRelease = PreRelease("")
193 - v.Metadata = ""
194 -}
195 -
196 -// BumpMinor increments the Minor field by 1 and resets all other fields to their default values
197 -func (v *Version) BumpMinor() {
198 - v.Minor += 1
199 - v.Patch = 0
200 - v.PreRelease = PreRelease("")
201 - v.Metadata = ""
202 -}
203 -
204 -// BumpPatch increments the Patch field by 1 and resets all other fields to their default values
205 -func (v *Version) BumpPatch() {
206 - v.Patch += 1
207 - v.PreRelease = PreRelease("")
208 - v.Metadata = ""
209 -}
Godeps/_workspace/src/github.com/coreos/go-semver/semver/semver_test.go deleted
-223
@@ -1,223 +0,0 @@
1 -package semver
2 -
3 -import (
4 - "errors"
5 - "math/rand"
6 - "reflect"
7 - "testing"
8 - "time"
9 -)
10 -
11 -type fixture struct {
12 - greaterVersion string
13 - lesserVersion string
14 -}
15 -
16 -var fixtures = []fixture{
17 - fixture{"0.0.0", "0.0.0-foo"},
18 - fixture{"0.0.1", "0.0.0"},
19 - fixture{"1.0.0", "0.9.9"},
20 - fixture{"0.10.0", "0.9.0"},
21 - fixture{"0.99.0", "0.10.0"},
22 - fixture{"2.0.0", "1.2.3"},
23 - fixture{"0.0.0", "0.0.0-foo"},
24 - fixture{"0.0.1", "0.0.0"},
25 - fixture{"1.0.0", "0.9.9"},
26 - fixture{"0.10.0", "0.9.0"},
27 - fixture{"0.99.0", "0.10.0"},
28 - fixture{"2.0.0", "1.2.3"},
29 - fixture{"0.0.0", "0.0.0-foo"},
30 - fixture{"0.0.1", "0.0.0"},
31 - fixture{"1.0.0", "0.9.9"},
32 - fixture{"0.10.0", "0.9.0"},
33 - fixture{"0.99.0", "0.10.0"},
34 - fixture{"2.0.0", "1.2.3"},
35 - fixture{"1.2.3", "1.2.3-asdf"},
36 - fixture{"1.2.3", "1.2.3-4"},
37 - fixture{"1.2.3", "1.2.3-4-foo"},
38 - fixture{"1.2.3-5-foo", "1.2.3-5"},
39 - fixture{"1.2.3-5", "1.2.3-4"},
40 - fixture{"1.2.3-5-foo", "1.2.3-5-Foo"},
41 - fixture{"3.0.0", "2.7.2+asdf"},
42 - fixture{"3.0.0+foobar", "2.7.2"},
43 - fixture{"1.2.3-a.10", "1.2.3-a.5"},
44 - fixture{"1.2.3-a.b", "1.2.3-a.5"},
45 - fixture{"1.2.3-a.b", "1.2.3-a"},
46 - fixture{"1.2.3-a.b.c.10.d.5", "1.2.3-a.b.c.5.d.100"},
47 - fixture{"1.0.0", "1.0.0-rc.1"},
48 - fixture{"1.0.0-rc.2", "1.0.0-rc.1"},
49 - fixture{"1.0.0-rc.1", "1.0.0-beta.11"},
50 - fixture{"1.0.0-beta.11", "1.0.0-beta.2"},
51 - fixture{"1.0.0-beta.2", "1.0.0-beta"},
52 - fixture{"1.0.0-beta", "1.0.0-alpha.beta"},
53 - fixture{"1.0.0-alpha.beta", "1.0.0-alpha.1"},
54 - fixture{"1.0.0-alpha.1", "1.0.0-alpha"},
55 -}
56 -
57 -func TestCompare(t *testing.T) {
58 - for _, v := range fixtures {
59 - gt, err := NewVersion(v.greaterVersion)
60 - if err != nil {
61 - t.Error(err)
62 - }
63 -
64 - lt, err := NewVersion(v.lesserVersion)
65 - if err != nil {
66 - t.Error(err)
67 - }
68 -
69 - if gt.LessThan(*lt) == true {
70 - t.Errorf("%s should not be less than %s", gt, lt)
71 - }
72 - }
73 -}
74 -
75 -func testString(t *testing.T, orig string, version *Version) {
76 - if orig != version.String() {
77 - t.Errorf("%s != %s", orig, version)
78 - }
79 -}
80 -
81 -func TestString(t *testing.T) {
82 - for _, v := range fixtures {
83 - gt, err := NewVersion(v.greaterVersion)
84 - if err != nil {
85 - t.Error(err)
86 - }
87 - testString(t, v.greaterVersion, gt)
88 -
89 - lt, err := NewVersion(v.lesserVersion)
90 - if err != nil {
91 - t.Error(err)
92 - }
93 - testString(t, v.lesserVersion, lt)
94 - }
95 -}
96 -
97 -func shuffleStringSlice(src []string) []string {
98 - dest := make([]string, len(src))
99 - rand.Seed(time.Now().Unix())
100 - perm := rand.Perm(len(src))
101 - for i, v := range perm {
102 - dest[v] = src[i]
103 - }
104 - return dest
105 -}
106 -
107 -func TestSort(t *testing.T) {
108 - sortedVersions := []string{"1.0.0", "1.0.2", "1.2.0", "3.1.1"}
109 - unsortedVersions := shuffleStringSlice(sortedVersions)
110 -
111 - semvers := []*Version{}
112 - for _, v := range unsortedVersions {
113 - sv, err := NewVersion(v)
114 - if err != nil {
115 - t.Fatal(err)
116 - }
117 - semvers = append(semvers, sv)
118 - }
119 -
120 - Sort(semvers)
121 -
122 - for idx, sv := range semvers {
123 - if sv.String() != sortedVersions[idx] {
124 - t.Fatalf("incorrect sort at index %v", idx)
125 - }
126 - }
127 -}
128 -
129 -func TestBumpMajor(t *testing.T) {
130 - version, _ := NewVersion("1.0.0")
131 - version.BumpMajor()
132 - if version.Major != 2 {
133 - t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
134 - }
135 -
136 - version, _ = NewVersion("1.5.2")
137 - version.BumpMajor()
138 - if version.Minor != 0 && version.Patch != 0 {
139 - t.Fatalf("bumping major on 1.5.2 resulted in %v", version)
140 - }
141 -
142 - version, _ = NewVersion("1.0.0+build.1-alpha.1")
143 - version.BumpMajor()
144 - if version.PreRelease != "" && version.PreRelease != "" {
145 - t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
146 - }
147 -}
148 -
149 -func TestBumpMinor(t *testing.T) {
150 - version, _ := NewVersion("1.0.0")
151 - version.BumpMinor()
152 -
153 - if version.Major != 1 {
154 - t.Fatalf("bumping minor on 1.0.0 resulted in %v", version)
155 - }
156 -
157 - if version.Minor != 1 {
158 - t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
159 - }
160 -
161 - version, _ = NewVersion("1.0.0+build.1-alpha.1")
162 - version.BumpMinor()
163 - if version.PreRelease != "" && version.PreRelease != "" {
164 - t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
165 - }
166 -}
167 -
168 -func TestBumpPatch(t *testing.T) {
169 - version, _ := NewVersion("1.0.0")
170 - version.BumpPatch()
171 -
172 - if version.Major != 1 {
173 - t.Fatalf("bumping minor on 1.0.0 resulted in %v", version)
174 - }
175 -
176 - if version.Minor != 0 {
177 - t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
178 - }
179 -
180 - if version.Patch != 1 {
181 - t.Fatalf("bumping major on 1.0.0 resulted in %v", version)
182 - }
183 -
184 - version, _ = NewVersion("1.0.0+build.1-alpha.1")
185 - version.BumpPatch()
186 - if version.PreRelease != "" && version.PreRelease != "" {
187 - t.Fatalf("bumping major on 1.0.0+build.1-alpha.1 resulted in %v", version)
188 - }
189 -}
190 -
191 -func TestMust(t *testing.T) {
192 - tests := []struct {
193 - versionStr string
194 -
195 - version *Version
196 - recov interface{}
197 - }{
198 - {
199 - versionStr: "1.0.0",
200 - version: &Version{Major: 1},
201 - },
202 - {
203 - versionStr: "version number",
204 - recov: errors.New("version number is not in dotted-tri format"),
205 - },
206 - }
207 -
208 - for _, tt := range tests {
209 - func() {
210 - defer func() {
211 - recov := recover()
212 - if !reflect.DeepEqual(tt.recov, recov) {
213 - t.Fatalf("incorrect panic for %q: want %v, got %v", tt.versionStr, tt.recov, recov)
214 - }
215 - }()
216 -
217 - version := Must(NewVersion(tt.versionStr))
218 - if !reflect.DeepEqual(tt.version, version) {
219 - t.Fatalf("incorrect version for %q: want %+v, got %+v", tt.versionStr, tt.version, version)
220 - }
221 - }()
222 - }
223 -}
Godeps/_workspace/src/github.com/coreos/go-semver/semver/sort.go deleted
-24
@@ -1,24 +0,0 @@
1 -package semver
2 -
3 -import (
4 - "sort"
5 -)
6 -
7 -type Versions []*Version
8 -
9 -func (s Versions) Len() int {
10 - return len(s)
11 -}
12 -
13 -func (s Versions) Swap(i, j int) {
14 - s[i], s[j] = s[j], s[i]
15 -}
16 -
17 -func (s Versions) Less(i, j int) bool {
18 - return s[i].LessThan(*s[j])
19 -}
20 -
21 -// Sort sorts the given slice of Version
22 -func Sort(versions []*Version) {
23 - sort.Sort(Versions(versions))
24 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/attempt.go deleted
-74
@@ -1,74 +0,0 @@
1 -package aws
2 -
3 -import (
4 - "time"
5 -)
6 -
7 -// AttemptStrategy represents a strategy for waiting for an action
8 -// to complete successfully. This is an internal type used by the
9 -// implementation of other goamz packages.
10 -type AttemptStrategy struct {
11 - Total time.Duration // total duration of attempt.
12 - Delay time.Duration // interval between each try in the burst.
13 - Min int // minimum number of retries; overrides Total
14 -}
15 -
16 -type Attempt struct {
17 - strategy AttemptStrategy
18 - last time.Time
19 - end time.Time
20 - force bool
21 - count int
22 -}
23 -
24 -// Start begins a new sequence of attempts for the given strategy.
25 -func (s AttemptStrategy) Start() *Attempt {
26 - now := time.Now()
27 - return &Attempt{
28 - strategy: s,
29 - last: now,
30 - end: now.Add(s.Total),
31 - force: true,
32 - }
33 -}
34 -
35 -// Next waits until it is time to perform the next attempt or returns
36 -// false if it is time to stop trying.
37 -func (a *Attempt) Next() bool {
38 - now := time.Now()
39 - sleep := a.nextSleep(now)
40 - if !a.force && !now.Add(sleep).Before(a.end) && a.strategy.Min <= a.count {
41 - return false
42 - }
43 - a.force = false
44 - if sleep > 0 && a.count > 0 {
45 - time.Sleep(sleep)
46 - now = time.Now()
47 - }
48 - a.count++
49 - a.last = now
50 - return true
51 -}
52 -
53 -func (a *Attempt) nextSleep(now time.Time) time.Duration {
54 - sleep := a.strategy.Delay - now.Sub(a.last)
55 - if sleep < 0 {
56 - return 0
57 - }
58 - return sleep
59 -}
60 -
61 -// HasNext returns whether another attempt will be made if the current
62 -// one fails. If it returns true, the following call to Next is
63 -// guaranteed to return true.
64 -func (a *Attempt) HasNext() bool {
65 - if a.force || a.strategy.Min > a.count {
66 - return true
67 - }
68 - now := time.Now()
69 - if now.Add(a.nextSleep(now)).Before(a.end) {
70 - a.force = true
71 - return true
72 - }
73 - return false
74 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/attempt_test.go deleted
-57
@@ -1,57 +0,0 @@
1 -package aws_test
2 -
3 -import (
4 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
5 - "gopkg.in/check.v1"
6 - "time"
7 -)
8 -
9 -func (S) TestAttemptTiming(c *check.C) {
10 - testAttempt := aws.AttemptStrategy{
11 - Total: 0.25e9,
12 - Delay: 0.1e9,
13 - }
14 - want := []time.Duration{0, 0.1e9, 0.2e9, 0.2e9}
15 - got := make([]time.Duration, 0, len(want)) // avoid allocation when testing timing
16 - t0 := time.Now()
17 - for a := testAttempt.Start(); a.Next(); {
18 - got = append(got, time.Now().Sub(t0))
19 - }
20 - got = append(got, time.Now().Sub(t0))
21 - c.Assert(got, check.HasLen, len(want))
22 - const margin = 0.01e9
23 - for i, got := range want {
24 - lo := want[i] - margin
25 - hi := want[i] + margin
26 - if got < lo || got > hi {
27 - c.Errorf("attempt %d want %g got %g", i, want[i].Seconds(), got.Seconds())
28 - }
29 - }
30 -}
31 -
32 -func (S) TestAttemptNextHasNext(c *check.C) {
33 - a := aws.AttemptStrategy{}.Start()
34 - c.Assert(a.Next(), check.Equals, true)
35 - c.Assert(a.Next(), check.Equals, false)
36 -
37 - a = aws.AttemptStrategy{}.Start()
38 - c.Assert(a.Next(), check.Equals, true)
39 - c.Assert(a.HasNext(), check.Equals, false)
40 - c.Assert(a.Next(), check.Equals, false)
41 -
42 - a = aws.AttemptStrategy{Total: 2e8}.Start()
43 - c.Assert(a.Next(), check.Equals, true)
44 - c.Assert(a.HasNext(), check.Equals, true)
45 - time.Sleep(2e8)
46 - c.Assert(a.HasNext(), check.Equals, true)
47 - c.Assert(a.Next(), check.Equals, true)
48 - c.Assert(a.Next(), check.Equals, false)
49 -
50 - a = aws.AttemptStrategy{Total: 1e8, Min: 2}.Start()
51 - time.Sleep(1e8)
52 - c.Assert(a.Next(), check.Equals, true)
53 - c.Assert(a.HasNext(), check.Equals, true)
54 - c.Assert(a.Next(), check.Equals, true)
55 - c.Assert(a.HasNext(), check.Equals, false)
56 - c.Assert(a.Next(), check.Equals, false)
57 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/aws.go deleted
-624
@@ -1,624 +0,0 @@
1 -//
2 -// goamz - Go packages to interact with the Amazon Web Services.
3 -//
4 -// https://wiki.ubuntu.com/goamz
5 -//
6 -// Copyright (c) 2011 Canonical Ltd.
7 -//
8 -// Written by Gustavo Niemeyer <gustavo.niemeyer@canonical.com>
9 -//
10 -package aws
11 -
12 -import (
13 - "encoding/json"
14 - "encoding/xml"
15 - "errors"
16 - "fmt"
17 - "io/ioutil"
18 - "net"
19 - "net/http"
20 - "net/url"
21 - "os"
22 - "os/user"
23 - "path"
24 - "regexp"
25 - "strings"
26 - "time"
27 -)
28 -
29 -// Regular expressions for INI files
30 -var (
31 - iniSectionRegexp = regexp.MustCompile(`^\s*\[([^\[\]]+)\]\s*$`)
32 - iniSettingRegexp = regexp.MustCompile(`^\s*(.+?)\s*=\s*(.*\S)\s*$`)
33 -)
34 -
35 -// Defines the valid signers
36 -const (
37 - V2Signature = iota
38 - V4Signature = iota
39 - Route53Signature = iota
40 -)
41 -
42 -// Defines the service endpoint and correct Signer implementation to use
43 -// to sign requests for this endpoint
44 -type ServiceInfo struct {
45 - Endpoint string
46 - Signer uint
47 -}
48 -
49 -// Region defines the URLs where AWS services may be accessed.
50 -//
51 -// See http://goo.gl/d8BP1 for more details.
52 -type Region struct {
53 - Name string // the canonical name of this region.
54 - EC2Endpoint string
55 - S3Endpoint string
56 - S3BucketEndpoint string // Not needed by AWS S3. Use ${bucket} for bucket name.
57 - S3LocationConstraint bool // true if this region requires a LocationConstraint declaration.
58 - S3LowercaseBucket bool // true if the region requires bucket names to be lower case.
59 - SDBEndpoint string
60 - SNSEndpoint string
61 - SQSEndpoint string
62 - SESEndpoint string
63 - IAMEndpoint string
64 - ELBEndpoint string
65 - DynamoDBEndpoint string
66 - CloudWatchServicepoint ServiceInfo
67 - AutoScalingEndpoint string
68 - RDSEndpoint ServiceInfo
69 - KinesisEndpoint string
70 - STSEndpoint string
71 - CloudFormationEndpoint string
72 - ElastiCacheEndpoint string
73 -}
74 -
75 -var Regions = map[string]Region{
76 - APNortheast.Name: APNortheast,
77 - APSoutheast.Name: APSoutheast,
78 - APSoutheast2.Name: APSoutheast2,
79 - EUCentral.Name: EUCentral,
80 - EUWest.Name: EUWest,
81 - USEast.Name: USEast,
82 - USWest.Name: USWest,
83 - USWest2.Name: USWest2,
84 - USGovWest.Name: USGovWest,
85 - SAEast.Name: SAEast,
86 -}
87 -
88 -// Designates a signer interface suitable for signing AWS requests, params
89 -// should be appropriately encoded for the request before signing.
90 -//
91 -// A signer should be initialized with Auth and the appropriate endpoint.
92 -type Signer interface {
93 - Sign(method, path string, params map[string]string)
94 -}
95 -
96 -// An AWS Service interface with the API to query the AWS service
97 -//
98 -// Supplied as an easy way to mock out service calls during testing.
99 -type AWSService interface {
100 - // Queries the AWS service at a given method/path with the params and
101 - // returns an http.Response and error
102 - Query(method, path string, params map[string]string) (*http.Response, error)
103 - // Builds an error given an XML payload in the http.Response, can be used
104 - // to process an error if the status code is not 200 for example.
105 - BuildError(r *http.Response) error
106 -}
107 -
108 -// Implements a Server Query/Post API to easily query AWS services and build
109 -// errors when desired
110 -type Service struct {
111 - service ServiceInfo
112 - signer Signer
113 -}
114 -
115 -// Create a base set of params for an action
116 -func MakeParams(action string) map[string]string {
117 - params := make(map[string]string)
118 - params["Action"] = action
119 - return params
120 -}
121 -
122 -// Create a new AWS server to handle making requests
123 -func NewService(auth Auth, service ServiceInfo) (s *Service, err error) {
124 - var signer Signer
125 - switch service.Signer {
126 - case V2Signature:
127 - signer, err = NewV2Signer(auth, service)
128 - // case V4Signature:
129 - // signer, err = NewV4Signer(auth, service, Regions["eu-west-1"])
130 - default:
131 - err = fmt.Errorf("Unsupported signer for service")
132 - }
133 - if err != nil {
134 - return
135 - }
136 - s = &Service{service: service, signer: signer}
137 - return
138 -}
139 -
140 -func (s *Service) Query(method, path string, params map[string]string) (resp *http.Response, err error) {
141 - params["Timestamp"] = time.Now().UTC().Format(time.RFC3339)
142 - u, err := url.Parse(s.service.Endpoint)
143 - if err != nil {
144 - return nil, err
145 - }
146 - u.Path = path
147 -
148 - s.signer.Sign(method, path, params)
149 - if method == "GET" {
150 - u.RawQuery = multimap(params).Encode()
151 - resp, err = http.Get(u.String())
152 - } else if method == "POST" {
153 - resp, err = http.PostForm(u.String(), multimap(params))
154 - }
155 -
156 - return
157 -}
158 -
159 -func (s *Service) BuildError(r *http.Response) error {
160 - errors := ErrorResponse{}
161 - xml.NewDecoder(r.Body).Decode(&errors)
162 - var err Error
163 - err = errors.Errors
164 - err.RequestId = errors.RequestId
165 - err.StatusCode = r.StatusCode
166 - if err.Message == "" {
167 - err.Message = r.Status
168 - }
169 - return &err
170 -}
171 -
172 -type ServiceError interface {
173 - error
174 - ErrorCode() string
175 -}
176 -
177 -type ErrorResponse struct {
178 - Errors Error `xml:"Error"`
179 - RequestId string // A unique ID for tracking the request
180 -}
181 -
182 -type Error struct {
183 - StatusCode int
184 - Type string
185 - Code string
186 - Message string
187 - RequestId string
188 -}
189 -
190 -func (err *Error) Error() string {
191 - return fmt.Sprintf("Type: %s, Code: %s, Message: %s",
192 - err.Type, err.Code, err.Message,
193 - )
194 -}
195 -
196 -func (err *Error) ErrorCode() string {
197 - return err.Code
198 -}
199 -
200 -type Auth struct {
201 - AccessKey, SecretKey string
202 - token string
203 - expiration time.Time
204 -}
205 -
206 -func (a *Auth) Token() string {
207 - if a.token == "" {
208 - return ""
209 - }
210 - if time.Since(a.expiration) >= -30*time.Second { //in an ideal world this should be zero assuming the instance is synching it's clock
211 - *a, _ = GetAuth("", "", "", time.Time{})
212 - }
213 - return a.token
214 -}
215 -
216 -func (a *Auth) Expiration() time.Time {
217 - return a.expiration
218 -}
219 -
220 -// To be used with other APIs that return auth credentials such as STS
221 -func NewAuth(accessKey, secretKey, token string, expiration time.Time) *Auth {
222 - return &Auth{
223 - AccessKey: accessKey,
224 - SecretKey: secretKey,
225 - token: token,
226 - expiration: expiration,
227 - }
228 -}
229 -
230 -// ResponseMetadata
231 -type ResponseMetadata struct {
232 - RequestId string // A unique ID for tracking the request
233 -}
234 -
235 -type BaseResponse struct {
236 - ResponseMetadata ResponseMetadata
237 -}
238 -
239 -var unreserved = make([]bool, 128)
240 -var hex = "0123456789ABCDEF"
241 -
242 -func init() {
243 - // RFC3986
244 - u := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890-_.~"
245 - for _, c := range u {
246 - unreserved[c] = true
247 - }
248 -}
249 -
250 -func multimap(p map[string]string) url.Values {
251 - q := make(url.Values, len(p))
252 - for k, v := range p {
253 - q[k] = []string{v}
254 - }
255 - return q
256 -}
257 -
258 -type credentials struct {
259 - Code string
260 - LastUpdated string
261 - Type string
262 - AccessKeyId string
263 - SecretAccessKey string
264 - Token string
265 - Expiration string
266 -}
267 -
268 -// GetMetaData retrieves instance metadata about the current machine.
269 -//
270 -// See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html for more details.
271 -func GetMetaData(path string) (contents []byte, err error) {
272 - c := http.Client{
273 - Transport: &http.Transport{
274 - Dial: func(netw, addr string) (net.Conn, error) {
275 - deadline := time.Now().Add(5 * time.Second)
276 - c, err := net.DialTimeout(netw, addr, time.Second*2)
277 - if err != nil {
278 - return nil, err
279 - }
280 - c.SetDeadline(deadline)
281 - return c, nil
282 - },
283 - },
284 - }
285 -
286 - url := "http://169.254.169.254/latest/meta-data/" + path
287 -
288 - resp, err := c.Get(url)
289 - if err != nil {
290 - return
291 - }
292 - defer resp.Body.Close()
293 -
294 - if resp.StatusCode != 200 {
295 - err = fmt.Errorf("Code %d returned for url %s", resp.StatusCode, url)
296 - return
297 - }
298 -
299 - body, err := ioutil.ReadAll(resp.Body)
300 - if err != nil {
301 - return
302 - }
303 - return []byte(body), err
304 -}
305 -
306 -func GetRegion(regionName string) (region Region) {
307 - region = Regions[regionName]
308 - return
309 -}
310 -
311 -// GetInstanceCredentials creates an Auth based on the instance's role credentials.
312 -// If the running instance is not in EC2 or does not have a valid IAM role, an error will be returned.
313 -// For more info about setting up IAM roles, see http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
314 -func GetInstanceCredentials() (cred credentials, err error) {
315 - credentialPath := "iam/security-credentials/"
316 -
317 - // Get the instance role
318 - role, err := GetMetaData(credentialPath)
319 - if err != nil {
320 - return
321 - }
322 -
323 - // Get the instance role credentials
324 - credentialJSON, err := GetMetaData(credentialPath + string(role))
325 - if err != nil {
326 - return
327 - }
328 -
329 - err = json.Unmarshal([]byte(credentialJSON), &cred)
330 - return
331 -}
332 -
333 -// GetAuth creates an Auth based on either passed in credentials,
334 -// environment information or instance based role credentials.
335 -func GetAuth(accessKey string, secretKey, token string, expiration time.Time) (auth Auth, err error) {
336 - // First try passed in credentials
337 - if accessKey != "" && secretKey != "" {
338 - return Auth{accessKey, secretKey, token, expiration}, nil
339 - }
340 -
341 - // Next try to get auth from the environment
342 - auth, err = EnvAuth()
343 - if err == nil {
344 - // Found auth, return
345 - return
346 - }
347 -
348 - // Next try getting auth from the instance role
349 - cred, err := GetInstanceCredentials()
350 - if err == nil {
351 - // Found auth, return
352 - auth.AccessKey = cred.AccessKeyId
353 - auth.SecretKey = cred.SecretAccessKey
354 - auth.token = cred.Token
355 - exptdate, err := time.Parse("2006-01-02T15:04:05Z", cred.Expiration)
356 - if err != nil {
357 - err = fmt.Errorf("Error Parsing expiration date: cred.Expiration :%s , error: %s \n", cred.Expiration, err)
358 - }
359 - auth.expiration = exptdate
360 - return auth, err
361 - }
362 -
363 - // Next try getting auth from the credentials file
364 - auth, err = CredentialFileAuth("", "", time.Minute*5)
365 - if err == nil {
366 - return
367 - }
368 -
369 - //err = errors.New("No valid AWS authentication found")
370 - err = fmt.Errorf("No valid AWS authentication found: %s", err)
371 - return auth, err
372 -}
373 -
374 -// EnvAuth creates an Auth based on environment information.
375 -// The AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment
376 -// variables are used.
377 -func EnvAuth() (auth Auth, err error) {
378 - auth.AccessKey = os.Getenv("AWS_ACCESS_KEY_ID")
379 - if auth.AccessKey == "" {
380 - auth.AccessKey = os.Getenv("AWS_ACCESS_KEY")
381 - }
382 -
383 - auth.SecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY")
384 - if auth.SecretKey == "" {
385 - auth.SecretKey = os.Getenv("AWS_SECRET_KEY")
386 - }
387 - if auth.AccessKey == "" {
388 - err = errors.New("AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment")
389 - }
390 - if auth.SecretKey == "" {
391 - err = errors.New("AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment")
392 - }
393 - return
394 -}
395 -
396 -// CredentialFileAuth creates and Auth based on a credentials file. The file
397 -// contains various authentication profiles for use with AWS.
398 -//
399 -// The credentials file, which is used by other AWS SDKs, is documented at
400 -// http://blogs.aws.amazon.com/security/post/Tx3D6U6WSFGOK2H/A-New-and-Standardized-Way-to-Manage-Credentials-in-the-AWS-SDKs
401 -func CredentialFileAuth(filePath string, profile string, expiration time.Duration) (auth Auth, err error) {
402 - if profile == "" {
403 - profile = "default"
404 - }
405 -
406 - if filePath == "" {
407 - u, err := user.Current()
408 - if err != nil {
409 - return auth, err
410 - }
411 -
412 - filePath = path.Join(u.HomeDir, ".aws", "credentials")
413 - }
414 -
415 - // read the file, then parse the INI
416 - contents, err := ioutil.ReadFile(filePath)
417 - if err != nil {
418 - return
419 - }
420 -
421 - profiles := parseINI(string(contents))
422 - profileData, ok := profiles[profile]
423 -
424 - if !ok {
425 - err = errors.New("The credentials file did not contain the profile")
426 - return
427 - }
428 -
429 - keyId, ok := profileData["aws_access_key_id"]
430 - if !ok {
431 - err = errors.New("The credentials file did not contain required attribute aws_access_key_id")
432 - return
433 - }
434 -
435 - secretKey, ok := profileData["aws_secret_access_key"]
436 - if !ok {
437 - err = errors.New("The credentials file did not contain required attribute aws_secret_access_key")
438 - return
439 - }
440 -
441 - auth.AccessKey = keyId
442 - auth.SecretKey = secretKey
443 -
444 - if token, ok := profileData["aws_session_token"]; ok {
445 - auth.token = token
446 - }
447 -
448 - auth.expiration = time.Now().Add(expiration)
449 -
450 - return
451 -}
452 -
453 -// parseINI takes the contents of a credentials file and returns a map, whose keys
454 -// are the various profiles, and whose values are maps of the settings for the
455 -// profiles
456 -func parseINI(fileContents string) map[string]map[string]string {
457 - profiles := make(map[string]map[string]string)
458 -
459 - lines := strings.Split(fileContents, "\n")
460 -
461 - var currentSection map[string]string
462 - for _, line := range lines {
463 - // remove comments, which start with a semi-colon
464 - if split := strings.Split(line, ";"); len(split) > 1 {
465 - line = split[0]
466 - }
467 -
468 - // check if the line is the start of a profile.
469 - //
470 - // for example:
471 - // [default]
472 - //
473 - // otherwise, check for the proper setting
474 - // property=value
475 - if sectMatch := iniSectionRegexp.FindStringSubmatch(line); len(sectMatch) == 2 {
476 - currentSection = make(map[string]string)
477 - profiles[sectMatch[1]] = currentSection
478 - } else if setMatch := iniSettingRegexp.FindStringSubmatch(line); len(setMatch) == 3 && currentSection != nil {
479 - currentSection[setMatch[1]] = setMatch[2]
480 - }
481 - }
482 -
483 - return profiles
484 -}
485 -
486 -// Encode takes a string and URI-encodes it in a way suitable
487 -// to be used in AWS signatures.
488 -func Encode(s string) string {
489 - encode := false
490 - for i := 0; i != len(s); i++ {
491 - c := s[i]
492 - if c > 127 || !unreserved[c] {
493 - encode = true
494 - break
495 - }
496 - }
497 - if !encode {
498 - return s
499 - }
500 - e := make([]byte, len(s)*3)
501 - ei := 0
502 - for i := 0; i != len(s); i++ {
503 - c := s[i]
504 - if c > 127 || !unreserved[c] {
505 - e[ei] = '%'
506 - e[ei+1] = hex[c>>4]
507 - e[ei+2] = hex[c&0xF]
508 - ei += 3
509 - } else {
510 - e[ei] = c
511 - ei += 1
512 - }
513 - }
514 - return string(e[:ei])
515 -}
516 -
517 -func dialTimeout(network, addr string) (net.Conn, error) {
518 - return net.DialTimeout(network, addr, time.Duration(2*time.Second))
519 -}
520 -
521 -func AvailabilityZone() string {
522 - transport := http.Transport{Dial: dialTimeout}
523 - client := http.Client{
524 - Transport: &transport,
525 - }
526 - resp, err := client.Get("http://169.254.169.254/latest/meta-data/placement/availability-zone")
527 - if err != nil {
528 - return "unknown"
529 - } else {
530 - defer resp.Body.Close()
531 - body, err := ioutil.ReadAll(resp.Body)
532 - if err != nil {
533 - return "unknown"
534 - } else {
535 - return string(body)
536 - }
537 - }
538 -}
539 -
540 -func InstanceRegion() string {
541 - az := AvailabilityZone()
542 - if az == "unknown" {
543 - return az
544 - } else {
545 - region := az[:len(az)-1]
546 - return region
547 - }
548 -}
549 -
550 -func InstanceId() string {
551 - transport := http.Transport{Dial: dialTimeout}
552 - client := http.Client{
553 - Transport: &transport,
554 - }
555 - resp, err := client.Get("http://169.254.169.254/latest/meta-data/instance-id")
556 - if err != nil {
557 - return "unknown"
558 - } else {
559 - defer resp.Body.Close()
560 - body, err := ioutil.ReadAll(resp.Body)
561 - if err != nil {
562 - return "unknown"
563 - } else {
564 - return string(body)
565 - }
566 - }
567 -}
568 -
569 -func InstanceType() string {
570 - transport := http.Transport{Dial: dialTimeout}
571 - client := http.Client{
572 - Transport: &transport,
573 - }
574 - resp, err := client.Get("http://169.254.169.254/latest/meta-data/instance-type")
575 - if err != nil {
576 - return "unknown"
577 - } else {
578 - defer resp.Body.Close()
579 - body, err := ioutil.ReadAll(resp.Body)
580 - if err != nil {
581 - return "unknown"
582 - } else {
583 - return string(body)
584 - }
585 - }
586 -}
587 -
588 -func ServerLocalIp() string {
589 - transport := http.Transport{Dial: dialTimeout}
590 - client := http.Client{
591 - Transport: &transport,
592 - }
593 - resp, err := client.Get("http://169.254.169.254/latest/meta-data/local-ipv4")
594 - if err != nil {
595 - return "127.0.0.1"
596 - } else {
597 - defer resp.Body.Close()
598 - body, err := ioutil.ReadAll(resp.Body)
599 - if err != nil {
600 - return "127.0.0.1"
601 - } else {
602 - return string(body)
603 - }
604 - }
605 -}
606 -
607 -func ServerPublicIp() string {
608 - transport := http.Transport{Dial: dialTimeout}
609 - client := http.Client{
610 - Transport: &transport,
611 - }
612 - resp, err := client.Get("http://169.254.169.254/latest/meta-data/public-ipv4")
613 - if err != nil {
614 - return "127.0.0.1"
615 - } else {
616 - defer resp.Body.Close()
617 - body, err := ioutil.ReadAll(resp.Body)
618 - if err != nil {
619 - return "127.0.0.1"
620 - } else {
621 - return string(body)
622 - }
623 - }
624 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/aws_test.go deleted
-140
@@ -1,140 +0,0 @@
1 -package aws_test
2 -
3 -import (
4 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
5 - "gopkg.in/check.v1"
6 - "io/ioutil"
7 - "os"
8 - "strings"
9 - "testing"
10 - "time"
11 -)
12 -
13 -func Test(t *testing.T) {
14 - check.TestingT(t)
15 -}
16 -
17 -var _ = check.Suite(&S{})
18 -
19 -type S struct {
20 - environ []string
21 -}
22 -
23 -func (s *S) SetUpSuite(c *check.C) {
24 - s.environ = os.Environ()
25 -}
26 -
27 -func (s *S) TearDownTest(c *check.C) {
28 - os.Clearenv()
29 - for _, kv := range s.environ {
30 - l := strings.SplitN(kv, "=", 2)
31 - os.Setenv(l[0], l[1])
32 - }
33 -}
34 -
35 -func (s *S) TestEnvAuthNoSecret(c *check.C) {
36 - os.Clearenv()
37 - _, err := aws.EnvAuth()
38 - c.Assert(err, check.ErrorMatches, "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment")
39 -}
40 -
41 -func (s *S) TestEnvAuthNoAccess(c *check.C) {
42 - os.Clearenv()
43 - os.Setenv("AWS_SECRET_ACCESS_KEY", "foo")
44 - _, err := aws.EnvAuth()
45 - c.Assert(err, check.ErrorMatches, "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment")
46 -}
47 -
48 -func (s *S) TestEnvAuth(c *check.C) {
49 - os.Clearenv()
50 - os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
51 - os.Setenv("AWS_ACCESS_KEY_ID", "access")
52 - auth, err := aws.EnvAuth()
53 - c.Assert(err, check.IsNil)
54 - c.Assert(auth, check.Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"})
55 -}
56 -
57 -func (s *S) TestEnvAuthAlt(c *check.C) {
58 - os.Clearenv()
59 - os.Setenv("AWS_SECRET_KEY", "secret")
60 - os.Setenv("AWS_ACCESS_KEY", "access")
61 - auth, err := aws.EnvAuth()
62 - c.Assert(err, check.IsNil)
63 - c.Assert(auth, check.Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"})
64 -}
65 -
66 -func (s *S) TestGetAuthStatic(c *check.C) {
67 - exptdate := time.Now().Add(time.Hour)
68 - auth, err := aws.GetAuth("access", "secret", "token", exptdate)
69 - c.Assert(err, check.IsNil)
70 - c.Assert(auth.AccessKey, check.Equals, "access")
71 - c.Assert(auth.SecretKey, check.Equals, "secret")
72 - c.Assert(auth.Token(), check.Equals, "token")
73 - c.Assert(auth.Expiration(), check.Equals, exptdate)
74 -}
75 -
76 -func (s *S) TestGetAuthEnv(c *check.C) {
77 - os.Clearenv()
78 - os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
79 - os.Setenv("AWS_ACCESS_KEY_ID", "access")
80 - auth, err := aws.GetAuth("", "", "", time.Time{})
81 - c.Assert(err, check.IsNil)
82 - c.Assert(auth, check.Equals, aws.Auth{SecretKey: "secret", AccessKey: "access"})
83 -}
84 -
85 -func (s *S) TestEncode(c *check.C) {
86 - c.Assert(aws.Encode("foo"), check.Equals, "foo")
87 - c.Assert(aws.Encode("/"), check.Equals, "%2F")
88 -}
89 -
90 -func (s *S) TestRegionsAreNamed(c *check.C) {
91 - for n, r := range aws.Regions {
92 - c.Assert(n, check.Equals, r.Name)
93 - }
94 -}
95 -
96 -func (s *S) TestCredentialsFileAuth(c *check.C) {
97 - file, err := ioutil.TempFile("", "creds")
98 -
99 - if err != nil {
100 - c.Fatal(err)
101 - }
102 -
103 - iniFile := `
104 -
105 -[default] ; comment 123
106 -aws_access_key_id = keyid1 ;comment
107 -aws_secret_access_key=key1
108 -
109 - [profile2]
110 - aws_access_key_id = keyid2 ;comment
111 - aws_secret_access_key=key2
112 - aws_session_token=token1
113 -
114 -`
115 - _, err = file.WriteString(iniFile)
116 - if err != nil {
117 - c.Fatal(err)
118 - }
119 -
120 - err = file.Close()
121 - if err != nil {
122 - c.Fatal(err)
123 - }
124 -
125 - // check non-existant profile
126 - _, err = aws.CredentialFileAuth(file.Name(), "no profile", 30*time.Minute)
127 - c.Assert(err, check.Not(check.Equals), nil)
128 -
129 - defaultProfile, err := aws.CredentialFileAuth(file.Name(), "default", 30*time.Minute)
130 - c.Assert(err, check.Equals, nil)
131 - c.Assert(defaultProfile.AccessKey, check.Equals, "keyid1")
132 - c.Assert(defaultProfile.SecretKey, check.Equals, "key1")
133 - c.Assert(defaultProfile.Token(), check.Equals, "")
134 -
135 - profile2, err := aws.CredentialFileAuth(file.Name(), "profile2", 30*time.Minute)
136 - c.Assert(err, check.Equals, nil)
137 - c.Assert(profile2.AccessKey, check.Equals, "keyid2")
138 - c.Assert(profile2.SecretKey, check.Equals, "key2")
139 - c.Assert(profile2.Token(), check.Equals, "token1")
140 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/client.go deleted
-124
@@ -1,124 +0,0 @@
1 -package aws
2 -
3 -import (
4 - "math"
5 - "net"
6 - "net/http"
7 - "time"
8 -)
9 -
10 -type RetryableFunc func(*http.Request, *http.Response, error) bool
11 -type WaitFunc func(try int)
12 -type DeadlineFunc func() time.Time
13 -
14 -type ResilientTransport struct {
15 - // Timeout is the maximum amount of time a dial will wait for
16 - // a connect to complete.
17 - //
18 - // The default is no timeout.
19 - //
20 - // With or without a timeout, the operating system may impose
21 - // its own earlier timeout. For instance, TCP timeouts are
22 - // often around 3 minutes.
23 - DialTimeout time.Duration
24 -
25 - // MaxTries, if non-zero, specifies the number of times we will retry on
26 - // failure. Retries are only attempted for temporary network errors or known
27 - // safe failures.
28 - MaxTries int
29 - Deadline DeadlineFunc
30 - ShouldRetry RetryableFunc
31 - Wait WaitFunc
32 - transport *http.Transport
33 -}
34 -
35 -// Convenience method for creating an http client
36 -func NewClient(rt *ResilientTransport) *http.Client {
37 - rt.transport = &http.Transport{
38 - Dial: func(netw, addr string) (net.Conn, error) {
39 - c, err := net.DialTimeout(netw, addr, rt.DialTimeout)
40 - if err != nil {
41 - return nil, err
42 - }
43 - c.SetDeadline(rt.Deadline())
44 - return c, nil
45 - },
46 - Proxy: http.ProxyFromEnvironment,
47 - }
48 - // TODO: Would be nice is ResilientTransport allowed clients to initialize
49 - // with http.Transport attributes.
50 - return &http.Client{
51 - Transport: rt,
52 - }
53 -}
54 -
55 -var retryingTransport = &ResilientTransport{
56 - Deadline: func() time.Time {
57 - return time.Now().Add(5 * time.Second)
58 - },
59 - DialTimeout: 10 * time.Second,
60 - MaxTries: 3,
61 - ShouldRetry: awsRetry,
62 - Wait: ExpBackoff,
63 -}
64 -
65 -// Exported default client
66 -var RetryingClient = NewClient(retryingTransport)
67 -
68 -func (t *ResilientTransport) RoundTrip(req *http.Request) (*http.Response, error) {
69 - return t.tries(req)
70 -}
71 -
72 -// Retry a request a maximum of t.MaxTries times.
73 -// We'll only retry if the proper criteria are met.
74 -// If a wait function is specified, wait that amount of time
75 -// In between requests.
76 -func (t *ResilientTransport) tries(req *http.Request) (res *http.Response, err error) {
77 - for try := 0; try < t.MaxTries; try += 1 {
78 - res, err = t.transport.RoundTrip(req)
79 -
80 - if !t.ShouldRetry(req, res, err) {
81 - break
82 - }
83 - if res != nil {
84 - res.Body.Close()
85 - }
86 - if t.Wait != nil {
87 - t.Wait(try)
88 - }
89 - }
90 -
91 - return
92 -}
93 -
94 -func ExpBackoff(try int) {
95 - time.Sleep(100 * time.Millisecond *
96 - time.Duration(math.Exp2(float64(try))))
97 -}
98 -
99 -func LinearBackoff(try int) {
100 - time.Sleep(time.Duration(try*100) * time.Millisecond)
101 -}
102 -
103 -// Decide if we should retry a request.
104 -// In general, the criteria for retrying a request is described here
105 -// http://docs.aws.amazon.com/general/latest/gr/api-retries.html
106 -func awsRetry(req *http.Request, res *http.Response, err error) bool {
107 - retry := false
108 -
109 - // Retry if there's a temporary network error.
110 - if neterr, ok := err.(net.Error); ok {
111 - if neterr.Temporary() {
112 - retry = true
113 - }
114 - }
115 -
116 - // Retry if we get a 5xx series error.
117 - if res != nil {
118 - if res.StatusCode >= 500 && res.StatusCode < 600 {
119 - retry = true
120 - }
121 - }
122 -
123 - return retry
124 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/export_test.go deleted
-29
@@ -1,29 +0,0 @@
1 -package aws
2 -
3 -import (
4 - "net/http"
5 - "time"
6 -)
7 -
8 -// V4Signer:
9 -// Exporting methods for testing
10 -
11 -func (s *V4Signer) RequestTime(req *http.Request) time.Time {
12 - return s.requestTime(req)
13 -}
14 -
15 -func (s *V4Signer) CanonicalRequest(req *http.Request) string {
16 - return s.canonicalRequest(req, "")
17 -}
18 -
19 -func (s *V4Signer) StringToSign(t time.Time, creq string) string {
20 - return s.stringToSign(t, creq)
21 -}
22 -
23 -func (s *V4Signer) Signature(t time.Time, sts string) string {
24 - return s.signature(t, sts)
25 -}
26 -
27 -func (s *V4Signer) Authorization(header http.Header, t time.Time, signature string) string {
28 - return s.authorization(header, t, signature)
29 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/regions.go deleted
-231
@@ -1,231 +0,0 @@
1 -package aws
2 -
3 -var USGovWest = Region{
4 - "us-gov-west-1",
5 - "https://ec2.us-gov-west-1.amazonaws.com",
6 - "https://s3-fips-us-gov-west-1.amazonaws.com",
7 - "",
8 - true,
9 - true,
10 - "",
11 - "https://sns.us-gov-west-1.amazonaws.com",
12 - "https://sqs.us-gov-west-1.amazonaws.com",
13 - "",
14 - "https://iam.us-gov.amazonaws.com",
15 - "https://elasticloadbalancing.us-gov-west-1.amazonaws.com",
16 - "https://dynamodb.us-gov-west-1.amazonaws.com",
17 - ServiceInfo{"https://monitoring.us-gov-west-1.amazonaws.com", V2Signature},
18 - "https://autoscaling.us-gov-west-1.amazonaws.com",
19 - ServiceInfo{"https://rds.us-gov-west-1.amazonaws.com", V2Signature},
20 - "",
21 - "https://sts.amazonaws.com",
22 - "https://cloudformation.us-gov-west-1.amazonaws.com",
23 - "",
24 -}
25 -
26 -var USEast = Region{
27 - "us-east-1",
28 - "https://ec2.us-east-1.amazonaws.com",
29 - "https://s3.amazonaws.com",
30 - "",
31 - false,
32 - false,
33 - "https://sdb.amazonaws.com",
34 - "https://sns.us-east-1.amazonaws.com",
35 - "https://sqs.us-east-1.amazonaws.com",
36 - "https://email.us-east-1.amazonaws.com",
37 - "https://iam.amazonaws.com",
38 - "https://elasticloadbalancing.us-east-1.amazonaws.com",
39 - "https://dynamodb.us-east-1.amazonaws.com",
40 - ServiceInfo{"https://monitoring.us-east-1.amazonaws.com", V2Signature},
41 - "https://autoscaling.us-east-1.amazonaws.com",
42 - ServiceInfo{"https://rds.us-east-1.amazonaws.com", V2Signature},
43 - "https://kinesis.us-east-1.amazonaws.com",
44 - "https://sts.amazonaws.com",
45 - "https://cloudformation.us-east-1.amazonaws.com",
46 - "https://elasticache.us-east-1.amazonaws.com",
47 -}
48 -
49 -var USWest = Region{
50 - "us-west-1",
51 - "https://ec2.us-west-1.amazonaws.com",
52 - "https://s3-us-west-1.amazonaws.com",
53 - "",
54 - true,
55 - true,
56 - "https://sdb.us-west-1.amazonaws.com",
57 - "https://sns.us-west-1.amazonaws.com",
58 - "https://sqs.us-west-1.amazonaws.com",
59 - "",
60 - "https://iam.amazonaws.com",
61 - "https://elasticloadbalancing.us-west-1.amazonaws.com",
62 - "https://dynamodb.us-west-1.amazonaws.com",
63 - ServiceInfo{"https://monitoring.us-west-1.amazonaws.com", V2Signature},
64 - "https://autoscaling.us-west-1.amazonaws.com",
65 - ServiceInfo{"https://rds.us-west-1.amazonaws.com", V2Signature},
66 - "",
67 - "https://sts.amazonaws.com",
68 - "https://cloudformation.us-west-1.amazonaws.com",
69 - "https://elasticache.us-west-1.amazonaws.com",
70 -}
71 -
72 -var USWest2 = Region{
73 - "us-west-2",
74 - "https://ec2.us-west-2.amazonaws.com",
75 - "https://s3-us-west-2.amazonaws.com",
76 - "",
77 - true,
78 - true,
79 - "https://sdb.us-west-2.amazonaws.com",
80 - "https://sns.us-west-2.amazonaws.com",
81 - "https://sqs.us-west-2.amazonaws.com",
82 - "https://email.us-west-2.amazonaws.com",
83 - "https://iam.amazonaws.com",
84 - "https://elasticloadbalancing.us-west-2.amazonaws.com",
85 - "https://dynamodb.us-west-2.amazonaws.com",
86 - ServiceInfo{"https://monitoring.us-west-2.amazonaws.com", V2Signature},
87 - "https://autoscaling.us-west-2.amazonaws.com",
88 - ServiceInfo{"https://rds.us-west-2.amazonaws.com", V2Signature},
89 - "https://kinesis.us-west-2.amazonaws.com",
90 - "https://sts.amazonaws.com",
91 - "https://cloudformation.us-west-2.amazonaws.com",
92 - "https://elasticache.us-west-2.amazonaws.com",
93 -}
94 -
95 -var EUWest = Region{
96 - "eu-west-1",
97 - "https://ec2.eu-west-1.amazonaws.com",
98 - "https://s3-eu-west-1.amazonaws.com",
99 - "",
100 - true,
101 - true,
102 - "https://sdb.eu-west-1.amazonaws.com",
103 - "https://sns.eu-west-1.amazonaws.com",
104 - "https://sqs.eu-west-1.amazonaws.com",
105 - "https://email.eu-west-1.amazonaws.com",
106 - "https://iam.amazonaws.com",
107 - "https://elasticloadbalancing.eu-west-1.amazonaws.com",
108 - "https://dynamodb.eu-west-1.amazonaws.com",
109 - ServiceInfo{"https://monitoring.eu-west-1.amazonaws.com", V2Signature},
110 - "https://autoscaling.eu-west-1.amazonaws.com",
111 - ServiceInfo{"https://rds.eu-west-1.amazonaws.com", V2Signature},
112 - "https://kinesis.eu-west-1.amazonaws.com",
113 - "https://sts.amazonaws.com",
114 - "https://cloudformation.eu-west-1.amazonaws.com",
115 - "https://elasticache.eu-west-1.amazonaws.com",
116 -}
117 -
118 -var EUCentral = Region{
119 - "eu-central-1",
120 - "https://ec2.eu-central-1.amazonaws.com",
121 - "https://s3-eu-central-1.amazonaws.com",
122 - "",
123 - true,
124 - true,
125 - "https://sdb.eu-central-1.amazonaws.com",
126 - "https://sns.eu-central-1.amazonaws.com",
127 - "https://sqs.eu-central-1.amazonaws.com",
128 - "",
129 - "https://iam.amazonaws.com",
130 - "https://elasticloadbalancing.eu-central-1.amazonaws.com",
131 - "https://dynamodb.eu-central-1.amazonaws.com",
132 - ServiceInfo{"https://monitoring.eu-central-1.amazonaws.com", V2Signature},
133 - "https://autoscaling.eu-central-1.amazonaws.com",
134 - ServiceInfo{"https://rds.eu-central-1.amazonaws.com", V2Signature},
135 - "https://kinesis.eu-central-1.amazonaws.com",
136 - "https://sts.amazonaws.com",
137 - "https://cloudformation.eu-central-1.amazonaws.com",
138 - "",
139 -}
140 -
141 -var APSoutheast = Region{
142 - "ap-southeast-1",
143 - "https://ec2.ap-southeast-1.amazonaws.com",
144 - "https://s3-ap-southeast-1.amazonaws.com",
145 - "",
146 - true,
147 - true,
148 - "https://sdb.ap-southeast-1.amazonaws.com",
149 - "https://sns.ap-southeast-1.amazonaws.com",
150 - "https://sqs.ap-southeast-1.amazonaws.com",
151 - "",
152 - "https://iam.amazonaws.com",
153 - "https://elasticloadbalancing.ap-southeast-1.amazonaws.com",
154 - "https://dynamodb.ap-southeast-1.amazonaws.com",
155 - ServiceInfo{"https://monitoring.ap-southeast-1.amazonaws.com", V2Signature},
156 - "https://autoscaling.ap-southeast-1.amazonaws.com",
157 - ServiceInfo{"https://rds.ap-southeast-1.amazonaws.com", V2Signature},
158 - "https://kinesis.ap-southeast-1.amazonaws.com",
159 - "https://sts.amazonaws.com",
160 - "https://cloudformation.ap-southeast-1.amazonaws.com",
161 - "https://elasticache.ap-southeast-1.amazonaws.com",
162 -}
163 -
164 -var APSoutheast2 = Region{
165 - "ap-southeast-2",
166 - "https://ec2.ap-southeast-2.amazonaws.com",
167 - "https://s3-ap-southeast-2.amazonaws.com",
168 - "",
169 - true,
170 - true,
171 - "https://sdb.ap-southeast-2.amazonaws.com",
172 - "https://sns.ap-southeast-2.amazonaws.com",
173 - "https://sqs.ap-southeast-2.amazonaws.com",
174 - "",
175 - "https://iam.amazonaws.com",
176 - "https://elasticloadbalancing.ap-southeast-2.amazonaws.com",
177 - "https://dynamodb.ap-southeast-2.amazonaws.com",
178 - ServiceInfo{"https://monitoring.ap-southeast-2.amazonaws.com", V2Signature},
179 - "https://autoscaling.ap-southeast-2.amazonaws.com",
180 - ServiceInfo{"https://rds.ap-southeast-2.amazonaws.com", V2Signature},
181 - "https://kinesis.ap-southeast-2.amazonaws.com",
182 - "https://sts.amazonaws.com",
183 - "https://cloudformation.ap-southeast-2.amazonaws.com",
184 - "https://elasticache.ap-southeast-2.amazonaws.com",
185 -}
186 -
187 -var APNortheast = Region{
188 - "ap-northeast-1",
189 - "https://ec2.ap-northeast-1.amazonaws.com",
190 - "https://s3-ap-northeast-1.amazonaws.com",
191 - "",
192 - true,
193 - true,
194 - "https://sdb.ap-northeast-1.amazonaws.com",
195 - "https://sns.ap-northeast-1.amazonaws.com",
196 - "https://sqs.ap-northeast-1.amazonaws.com",
197 - "",
198 - "https://iam.amazonaws.com",
199 - "https://elasticloadbalancing.ap-northeast-1.amazonaws.com",
200 - "https://dynamodb.ap-northeast-1.amazonaws.com",
201 - ServiceInfo{"https://monitoring.ap-northeast-1.amazonaws.com", V2Signature},
202 - "https://autoscaling.ap-northeast-1.amazonaws.com",
203 - ServiceInfo{"https://rds.ap-northeast-1.amazonaws.com", V2Signature},
204 - "https://kinesis.ap-northeast-1.amazonaws.com",
205 - "https://sts.amazonaws.com",
206 - "https://cloudformation.ap-northeast-1.amazonaws.com",
207 - "https://elasticache.ap-northeast-1.amazonaws.com",
208 -}
209 -
210 -var SAEast = Region{
211 - "sa-east-1",
212 - "https://ec2.sa-east-1.amazonaws.com",
213 - "https://s3-sa-east-1.amazonaws.com",
214 - "",
215 - true,
216 - true,
217 - "https://sdb.sa-east-1.amazonaws.com",
218 - "https://sns.sa-east-1.amazonaws.com",
219 - "https://sqs.sa-east-1.amazonaws.com",
220 - "",
221 - "https://iam.amazonaws.com",
222 - "https://elasticloadbalancing.sa-east-1.amazonaws.com",
223 - "https://dynamodb.sa-east-1.amazonaws.com",
224 - ServiceInfo{"https://monitoring.sa-east-1.amazonaws.com", V2Signature},
225 - "https://autoscaling.sa-east-1.amazonaws.com",
226 - ServiceInfo{"https://rds.sa-east-1.amazonaws.com", V2Signature},
227 - "",
228 - "https://sts.amazonaws.com",
229 - "https://cloudformation.sa-east-1.amazonaws.com",
230 - "https://elasticache.sa-east-1.amazonaws.com",
231 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/retry.go deleted
-136
@@ -1,136 +0,0 @@
1 -package aws
2 -
3 -import (
4 - "math/rand"
5 - "net"
6 - "net/http"
7 - "time"
8 -)
9 -
10 -const (
11 - maxDelay = 20 * time.Second
12 - defaultScale = 300 * time.Millisecond
13 - throttlingScale = 500 * time.Millisecond
14 - throttlingScaleRange = throttlingScale / 4
15 - defaultMaxRetries = 3
16 - dynamoDBScale = 25 * time.Millisecond
17 - dynamoDBMaxRetries = 10
18 -)
19 -
20 -// A RetryPolicy encapsulates a strategy for implementing client retries.
21 -//
22 -// Default implementations are provided which match the AWS SDKs.
23 -type RetryPolicy interface {
24 - // ShouldRetry returns whether a client should retry a failed request.
25 - ShouldRetry(target string, r *http.Response, err error, numRetries int) bool
26 -
27 - // Delay returns the time a client should wait before issuing a retry.
28 - Delay(target string, r *http.Response, err error, numRetries int) time.Duration
29 -}
30 -
31 -// DefaultRetryPolicy implements the AWS SDK default retry policy.
32 -//
33 -// It will retry up to 3 times, and uses an exponential backoff with a scale
34 -// factor of 300ms (300ms, 600ms, 1200ms). If the retry is because of
35 -// throttling, the delay will also include some randomness.
36 -//
37 -// See https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/retry/PredefinedRetryPolicies.java#L90.
38 -type DefaultRetryPolicy struct {
39 -}
40 -
41 -// ShouldRetry implements the RetryPolicy ShouldRetry method.
42 -func (policy DefaultRetryPolicy) ShouldRetry(target string, r *http.Response, err error, numRetries int) bool {
43 - return shouldRetry(r, err, numRetries, defaultMaxRetries)
44 -}
45 -
46 -// Delay implements the RetryPolicy Delay method.
47 -func (policy DefaultRetryPolicy) Delay(target string, r *http.Response, err error, numRetries int) time.Duration {
48 - scale := defaultScale
49 - if err, ok := err.(*Error); ok && isThrottlingException(err) {
50 - scale = throttlingScale + time.Duration(rand.Int63n(int64(throttlingScaleRange)))
51 - }
52 - return exponentialBackoff(numRetries, scale)
53 -}
54 -
55 -// DynamoDBRetryPolicy implements the AWS SDK DynamoDB retry policy.
56 -//
57 -// It will retry up to 10 times, and uses an exponential backoff with a scale
58 -// factor of 25ms (25ms, 50ms, 100ms, ...).
59 -//
60 -// See https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/retry/PredefinedRetryPolicies.java#L103.
61 -type DynamoDBRetryPolicy struct {
62 -}
63 -
64 -// ShouldRetry implements the RetryPolicy ShouldRetry method.
65 -func (policy DynamoDBRetryPolicy) ShouldRetry(target string, r *http.Response, err error, numRetries int) bool {
66 - return shouldRetry(r, err, numRetries, dynamoDBMaxRetries)
67 -}
68 -
69 -// Delay implements the RetryPolicy Delay method.
70 -func (policy DynamoDBRetryPolicy) Delay(target string, r *http.Response, err error, numRetries int) time.Duration {
71 - return exponentialBackoff(numRetries, dynamoDBScale)
72 -}
73 -
74 -// NeverRetryPolicy never retries requests and returns immediately on failure.
75 -type NeverRetryPolicy struct {
76 -}
77 -
78 -// ShouldRetry implements the RetryPolicy ShouldRetry method.
79 -func (policy NeverRetryPolicy) ShouldRetry(target string, r *http.Response, err error, numRetries int) bool {
80 - return false
81 -}
82 -
83 -// Delay implements the RetryPolicy Delay method.
84 -func (policy NeverRetryPolicy) Delay(target string, r *http.Response, err error, numRetries int) time.Duration {
85 - return time.Duration(0)
86 -}
87 -
88 -// shouldRetry determines if we should retry the request.
89 -//
90 -// See http://docs.aws.amazon.com/general/latest/gr/api-retries.html.
91 -func shouldRetry(r *http.Response, err error, numRetries int, maxRetries int) bool {
92 - // Once we've exceeded the max retry attempts, game over.
93 - if numRetries >= maxRetries {
94 - return false
95 - }
96 -
97 - // Always retry temporary network errors.
98 - if err, ok := err.(net.Error); ok && err.Temporary() {
99 - return true
100 - }
101 -
102 - // Always retry 5xx responses.
103 - if r != nil && r.StatusCode >= 500 {
104 - return true
105 - }
106 -
107 - // Always retry throttling exceptions.
108 - if err, ok := err.(ServiceError); ok && isThrottlingException(err) {
109 - return true
110 - }
111 -
112 - // Other classes of failures indicate a problem with the request. Retrying
113 - // won't help.
114 - return false
115 -}
116 -
117 -func exponentialBackoff(numRetries int, scale time.Duration) time.Duration {
118 - if numRetries < 0 {
119 - return time.Duration(0)
120 - }
121 -
122 - delay := (1 << uint(numRetries)) * scale
123 - if delay > maxDelay {
124 - return maxDelay
125 - }
126 - return delay
127 -}
128 -
129 -func isThrottlingException(err ServiceError) bool {
130 - switch err.ErrorCode() {
131 - case "Throttling", "ThrottlingException", "ProvisionedThroughputExceededException":
132 - return true
133 - default:
134 - return false
135 - }
136 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/retry_test.go deleted
-303
@@ -1,303 +0,0 @@
1 -package aws
2 -
3 -import (
4 - "math/rand"
5 - "net"
6 - "net/http"
7 - "testing"
8 - "time"
9 -)
10 -
11 -type testInput struct {
12 - res *http.Response
13 - err error
14 - numRetries int
15 -}
16 -
17 -type testResult struct {
18 - shouldRetry bool
19 - delay time.Duration
20 -}
21 -
22 -type testCase struct {
23 - input testInput
24 - defaultResult testResult
25 - dynamoDBResult testResult
26 -}
27 -
28 -var testCases = []testCase{
29 - // Test nil fields
30 - testCase{
31 - input: testInput{
32 - err: nil,
33 - res: nil,
34 - numRetries: 0,
35 - },
36 - defaultResult: testResult{
37 - shouldRetry: false,
38 - delay: 300 * time.Millisecond,
39 - },
40 - dynamoDBResult: testResult{
41 - shouldRetry: false,
42 - delay: 25 * time.Millisecond,
43 - },
44 - },
45 - // Test 3 different throttling exceptions
46 - testCase{
47 - input: testInput{
48 - err: &Error{
49 - Code: "Throttling",
50 - },
51 - numRetries: 0,
52 - },
53 - defaultResult: testResult{
54 - shouldRetry: true,
55 - delay: 617165505 * time.Nanosecond, // account for randomness with known seed
56 - },
57 - dynamoDBResult: testResult{
58 - shouldRetry: true,
59 - delay: 25 * time.Millisecond,
60 - },
61 - },
62 - testCase{
63 - input: testInput{
64 - err: &Error{
65 - Code: "ThrottlingException",
66 - },
67 - numRetries: 0,
68 - },
69 - defaultResult: testResult{
70 - shouldRetry: true,
71 - delay: 579393152 * time.Nanosecond, // account for randomness with known seed
72 - },
73 - dynamoDBResult: testResult{
74 - shouldRetry: true,
75 - delay: 25 * time.Millisecond,
76 - },
77 - },
78 - testCase{
79 - input: testInput{
80 - err: &Error{
81 - Code: "ProvisionedThroughputExceededException",
82 - },
83 - numRetries: 1,
84 - },
85 - defaultResult: testResult{
86 - shouldRetry: true,
87 - delay: 1105991654 * time.Nanosecond, // account for randomness with known seed
88 - },
89 - dynamoDBResult: testResult{
90 - shouldRetry: true,
91 - delay: 50 * time.Millisecond,
92 - },
93 - },
94 - // Test a fake throttling exception
95 - testCase{
96 - input: testInput{
97 - err: &Error{
98 - Code: "MyMadeUpThrottlingCode",
99 - },
100 - numRetries: 0,
101 - },
102 - defaultResult: testResult{
103 - shouldRetry: false,
104 - delay: 300 * time.Millisecond,
105 - },
106 - dynamoDBResult: testResult{
107 - shouldRetry: false,
108 - delay: 25 * time.Millisecond,
109 - },
110 - },
111 - // Test 5xx errors
112 - testCase{
113 - input: testInput{
114 - res: &http.Response{
115 - StatusCode: http.StatusInternalServerError,
116 - },
117 - numRetries: 1,
118 - },
119 - defaultResult: testResult{
120 - shouldRetry: true,
121 - delay: 600 * time.Millisecond,
122 - },
123 - dynamoDBResult: testResult{
124 - shouldRetry: true,
125 - delay: 50 * time.Millisecond,
126 - },
127 - },
128 - testCase{
129 - input: testInput{
130 - res: &http.Response{
131 - StatusCode: http.StatusServiceUnavailable,
132 - },
133 - numRetries: 1,
134 - },
135 - defaultResult: testResult{
136 - shouldRetry: true,
137 - delay: 600 * time.Millisecond,
138 - },
139 - dynamoDBResult: testResult{
140 - shouldRetry: true,
141 - delay: 50 * time.Millisecond,
142 - },
143 - },
144 - // Test a random 400 error
145 - testCase{
146 - input: testInput{
147 - res: &http.Response{
148 - StatusCode: http.StatusNotFound,
149 - },
150 - numRetries: 1,
151 - },
152 - defaultResult: testResult{
153 - shouldRetry: false,
154 - delay: 600 * time.Millisecond,
155 - },
156 - dynamoDBResult: testResult{
157 - shouldRetry: false,
158 - delay: 50 * time.Millisecond,
159 - },
160 - },
161 - // Test a temporary net.Error
162 - testCase{
163 - input: testInput{
164 - res: &http.Response{},
165 - err: &net.DNSError{
166 - IsTimeout: true,
167 - },
168 - numRetries: 2,
169 - },
170 - defaultResult: testResult{
171 - shouldRetry: true,
172 - delay: 1200 * time.Millisecond,
173 - },
174 - dynamoDBResult: testResult{
175 - shouldRetry: true,
176 - delay: 100 * time.Millisecond,
177 - },
178 - },
179 - // Test a non-temporary net.Error
180 - testCase{
181 - input: testInput{
182 - res: &http.Response{},
183 - err: &net.DNSError{
184 - IsTimeout: false,
185 - },
186 - numRetries: 3,
187 - },
188 - defaultResult: testResult{
189 - shouldRetry: false,
190 - delay: 2400 * time.Millisecond,
191 - },
192 - dynamoDBResult: testResult{
193 - shouldRetry: false,
194 - delay: 200 * time.Millisecond,
195 - },
196 - },
197 - // Assert failure after hitting max default retries
198 - testCase{
199 - input: testInput{
200 - err: &Error{
201 - Code: "ProvisionedThroughputExceededException",
202 - },
203 - numRetries: defaultMaxRetries,
204 - },
205 - defaultResult: testResult{
206 - shouldRetry: false,
207 - delay: 4313582352 * time.Nanosecond, // account for randomness with known seed
208 - },
209 - dynamoDBResult: testResult{
210 - shouldRetry: true,
211 - delay: 200 * time.Millisecond,
212 - },
213 - },
214 - // Assert failure after hitting max DynamoDB retries
215 - testCase{
216 - input: testInput{
217 - err: &Error{
218 - Code: "ProvisionedThroughputExceededException",
219 - },
220 - numRetries: dynamoDBMaxRetries,
221 - },
222 - defaultResult: testResult{
223 - shouldRetry: false,
224 - delay: maxDelay,
225 - },
226 - dynamoDBResult: testResult{
227 - shouldRetry: false,
228 - delay: maxDelay,
229 - },
230 - },
231 - // Assert we never go over the maxDelay value
232 - testCase{
233 - input: testInput{
234 - numRetries: 25,
235 - },
236 - defaultResult: testResult{
237 - shouldRetry: false,
238 - delay: maxDelay,
239 - },
240 - dynamoDBResult: testResult{
241 - shouldRetry: false,
242 - delay: maxDelay,
243 - },
244 - },
245 -}
246 -
247 -func TestDefaultRetryPolicy(t *testing.T) {
248 - rand.Seed(0)
249 - var policy RetryPolicy
250 - policy = &DefaultRetryPolicy{}
251 - for _, test := range testCases {
252 - res := test.input.res
253 - err := test.input.err
254 - numRetries := test.input.numRetries
255 -
256 - shouldRetry := policy.ShouldRetry("", res, err, numRetries)
257 - if shouldRetry != test.defaultResult.shouldRetry {
258 - t.Errorf("ShouldRetry returned %v, expected %v res=%#v err=%#v numRetries=%d", shouldRetry, test.defaultResult.shouldRetry, res, err, numRetries)
259 - }
260 - delay := policy.Delay("", res, err, numRetries)
261 - if delay != test.defaultResult.delay {
262 - t.Errorf("Delay returned %v, expected %v res=%#v err=%#v numRetries=%d", delay, test.defaultResult.delay, res, err, numRetries)
263 - }
264 - }
265 -}
266 -
267 -func TestDynamoDBRetryPolicy(t *testing.T) {
268 - var policy RetryPolicy
269 - policy = &DynamoDBRetryPolicy{}
270 - for _, test := range testCases {
271 - res := test.input.res
272 - err := test.input.err
273 - numRetries := test.input.numRetries
274 -
275 - shouldRetry := policy.ShouldRetry("", res, err, numRetries)
276 - if shouldRetry != test.dynamoDBResult.shouldRetry {
277 - t.Errorf("ShouldRetry returned %v, expected %v res=%#v err=%#v numRetries=%d", shouldRetry, test.dynamoDBResult.shouldRetry, res, err, numRetries)
278 - }
279 - delay := policy.Delay("", res, err, numRetries)
280 - if delay != test.dynamoDBResult.delay {
281 - t.Errorf("Delay returned %v, expected %v res=%#v err=%#v numRetries=%d", delay, test.dynamoDBResult.delay, res, err, numRetries)
282 - }
283 - }
284 -}
285 -
286 -func TestNeverRetryPolicy(t *testing.T) {
287 - var policy RetryPolicy
288 - policy = &NeverRetryPolicy{}
289 - for _, test := range testCases {
290 - res := test.input.res
291 - err := test.input.err
292 - numRetries := test.input.numRetries
293 -
294 - shouldRetry := policy.ShouldRetry("", res, err, numRetries)
295 - if shouldRetry {
296 - t.Errorf("ShouldRetry returned %v, expected %v res=%#v err=%#v numRetries=%d", shouldRetry, false, res, err, numRetries)
297 - }
298 - delay := policy.Delay("", res, err, numRetries)
299 - if delay != time.Duration(0) {
300 - t.Errorf("Delay returned %v, expected %v res=%#v err=%#v numRetries=%d", delay, time.Duration(0), res, err, numRetries)
301 - }
302 - }
303 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/sign.go deleted
-413
@@ -1,413 +0,0 @@
1 -package aws
2 -
3 -import (
4 - "bytes"
5 - "crypto/hmac"
6 - "crypto/sha256"
7 - "encoding/base64"
8 - "fmt"
9 - "io/ioutil"
10 - "net/http"
11 - "net/url"
12 - "path"
13 - "sort"
14 - "strings"
15 - "time"
16 -)
17 -
18 -type V2Signer struct {
19 - auth Auth
20 - service ServiceInfo
21 - host string
22 -}
23 -
24 -var b64 = base64.StdEncoding
25 -
26 -func NewV2Signer(auth Auth, service ServiceInfo) (*V2Signer, error) {
27 - u, err := url.Parse(service.Endpoint)
28 - if err != nil {
29 - return nil, err
30 - }
31 - return &V2Signer{auth: auth, service: service, host: u.Host}, nil
32 -}
33 -
34 -func (s *V2Signer) Sign(method, path string, params map[string]string) {
35 - params["AWSAccessKeyId"] = s.auth.AccessKey
36 - params["SignatureVersion"] = "2"
37 - params["SignatureMethod"] = "HmacSHA256"
38 - if s.auth.Token() != "" {
39 - params["SecurityToken"] = s.auth.Token()
40 - }
41 -
42 - // AWS specifies that the parameters in a signed request must
43 - // be provided in the natural order of the keys. This is distinct
44 - // from the natural order of the encoded value of key=value.
45 - // Percent and gocheck.Equals affect the sorting order.
46 - var keys, sarray []string
47 - for k, _ := range params {
48 - keys = append(keys, k)
49 - }
50 - sort.Strings(keys)
51 - for _, k := range keys {
52 - sarray = append(sarray, Encode(k)+"="+Encode(params[k]))
53 - }
54 - joined := strings.Join(sarray, "&")
55 - payload := method + "\n" + s.host + "\n" + path + "\n" + joined
56 - hash := hmac.New(sha256.New, []byte(s.auth.SecretKey))
57 - hash.Write([]byte(payload))
58 - signature := make([]byte, b64.EncodedLen(hash.Size()))
59 - b64.Encode(signature, hash.Sum(nil))
60 -
61 - params["Signature"] = string(signature)
62 -}
63 -
64 -// Common date formats for signing requests
65 -const (
66 - ISO8601BasicFormat = "20060102T150405Z"
67 - ISO8601BasicFormatShort = "20060102"
68 -)
69 -
70 -type Route53Signer struct {
71 - auth Auth
72 -}
73 -
74 -func NewRoute53Signer(auth Auth) *Route53Signer {
75 - return &Route53Signer{auth: auth}
76 -}
77 -
78 -// getCurrentDate fetches the date stamp from the aws servers to
79 -// ensure the auth headers are within 5 minutes of the server time
80 -func (s *Route53Signer) getCurrentDate() string {
81 - response, err := http.Get("https://route53.amazonaws.com/date")
82 - if err != nil {
83 - fmt.Print("Unable to get date from amazon: ", err)
84 - return ""
85 - }
86 -
87 - response.Body.Close()
88 - return response.Header.Get("Date")
89 -}
90 -
91 -// Creates the authorize signature based on the date stamp and secret key
92 -func (s *Route53Signer) getHeaderAuthorize(message string) string {
93 - hmacSha256 := hmac.New(sha256.New, []byte(s.auth.SecretKey))
94 - hmacSha256.Write([]byte(message))
95 - cryptedString := hmacSha256.Sum(nil)
96 -
97 - return base64.StdEncoding.EncodeToString(cryptedString)
98 -}
99 -
100 -// Adds all the required headers for AWS Route53 API to the request
101 -// including the authorization
102 -func (s *Route53Signer) Sign(req *http.Request) {
103 - date := s.getCurrentDate()
104 - authHeader := fmt.Sprintf("AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=%s,Signature=%s",
105 - s.auth.AccessKey, "HmacSHA256", s.getHeaderAuthorize(date))
106 -
107 - req.Header.Set("Host", req.Host)
108 - req.Header.Set("X-Amzn-Authorization", authHeader)
109 - req.Header.Set("X-Amz-Date", date)
110 - req.Header.Set("Content-Type", "application/xml")
111 - if s.auth.Token() != "" {
112 - req.Header.Set("X-Amzn-Security-Token", s.auth.Token())
113 - }
114 -}
115 -
116 -/*
117 -The V4Signer encapsulates all of the functionality to sign a request with the AWS
118 -Signature Version 4 Signing Process. (http://goo.gl/u1OWZz)
119 -*/
120 -type V4Signer struct {
121 - auth Auth
122 - serviceName string
123 - region Region
124 - // Add the x-amz-content-sha256 header
125 - IncludeXAmzContentSha256 bool
126 -}
127 -
128 -/*
129 -Return a new instance of a V4Signer capable of signing AWS requests.
130 -*/
131 -func NewV4Signer(auth Auth, serviceName string, region Region) *V4Signer {
132 - return &V4Signer{
133 - auth: auth,
134 - serviceName: serviceName,
135 - region: region,
136 - IncludeXAmzContentSha256: false,
137 - }
138 -}
139 -
140 -/*
141 -Sign a request according to the AWS Signature Version 4 Signing Process. (http://goo.gl/u1OWZz)
142 -
143 -The signed request will include an "x-amz-date" header with a current timestamp if a valid "x-amz-date"
144 -or "date" header was not available in the original request. In addition, AWS Signature Version 4 requires
145 -the "host" header to be a signed header, therefor the Sign method will manually set a "host" header from
146 -the request.Host.
147 -
148 -The signed request will include a new "Authorization" header indicating that the request has been signed.
149 -
150 -Any changes to the request after signing the request will invalidate the signature.
151 -*/
152 -func (s *V4Signer) Sign(req *http.Request) {
153 - req.Header.Set("host", req.Host) // host header must be included as a signed header
154 - t := s.requestTime(req) // Get request time
155 -
156 - payloadHash := ""
157 -
158 - if _, ok := req.Form["X-Amz-Expires"]; ok {
159 - // We are authenticating the the request by using query params
160 - // (also known as pre-signing a url, http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)
161 - payloadHash = "UNSIGNED-PAYLOAD"
162 - req.Header.Del("x-amz-date")
163 -
164 - req.Form["X-Amz-SignedHeaders"] = []string{s.signedHeaders(req.Header)}
165 - req.Form["X-Amz-Algorithm"] = []string{"AWS4-HMAC-SHA256"}
166 - req.Form["X-Amz-Credential"] = []string{s.auth.AccessKey + "/" + s.credentialScope(t)}
167 - req.Form["X-Amz-Date"] = []string{t.Format(ISO8601BasicFormat)}
168 - req.URL.RawQuery = req.Form.Encode()
169 - } else {
170 - payloadHash = s.payloadHash(req)
171 - if s.IncludeXAmzContentSha256 {
172 - req.Header.Set("x-amz-content-sha256", payloadHash) // x-amz-content-sha256 contains the payload hash
173 - }
174 - }
175 - creq := s.canonicalRequest(req, payloadHash) // Build canonical request
176 - sts := s.stringToSign(t, creq) // Build string to sign
177 - signature := s.signature(t, sts) // Calculate the AWS Signature Version 4
178 - auth := s.authorization(req.Header, t, signature) // Create Authorization header value
179 -
180 - if _, ok := req.Form["X-Amz-Expires"]; ok {
181 - req.Form["X-Amz-Signature"] = []string{signature}
182 - } else {
183 - req.Header.Set("Authorization", auth) // Add Authorization header to request
184 - }
185 - return
186 -}
187 -
188 -/*
189 -requestTime method will parse the time from the request "x-amz-date" or "date" headers.
190 -If the "x-amz-date" header is present, that will take priority over the "date" header.
191 -If neither header is defined or we are unable to parse either header as a valid date
192 -then we will create a new "x-amz-date" header with the current time.
193 -*/
194 -func (s *V4Signer) requestTime(req *http.Request) time.Time {
195 -
196 - // Get "x-amz-date" header
197 - date := req.Header.Get("x-amz-date")
198 -
199 - // Attempt to parse as ISO8601BasicFormat
200 - t, err := time.Parse(ISO8601BasicFormat, date)
201 - if err == nil {
202 - return t
203 - }
204 -
205 - // Attempt to parse as http.TimeFormat
206 - t, err = time.Parse(http.TimeFormat, date)
207 - if err == nil {
208 - req.Header.Set("x-amz-date", t.Format(ISO8601BasicFormat))
209 - return t
210 - }
211 -
212 - // Get "date" header
213 - date = req.Header.Get("date")
214 -
215 - // Attempt to parse as http.TimeFormat
216 - t, err = time.Parse(http.TimeFormat, date)
217 - if err == nil {
218 - return t
219 - }
220 -
221 - // Create a current time header to be used
222 - t = time.Now().UTC()
223 - req.Header.Set("x-amz-date", t.Format(ISO8601BasicFormat))
224 - return t
225 -}
226 -
227 -/*
228 -canonicalRequest method creates the canonical request according to Task 1 of the AWS Signature Version 4 Signing Process. (http://goo.gl/eUUZ3S)
229 -
230 - CanonicalRequest =
231 - HTTPRequestMethod + '\n' +
232 - CanonicalURI + '\n' +
233 - CanonicalQueryString + '\n' +
234 - CanonicalHeaders + '\n' +
235 - SignedHeaders + '\n' +
236 - HexEncode(Hash(Payload))
237 -
238 -payloadHash is optional; use the empty string and it will be calculated from the request
239 -*/
240 -func (s *V4Signer) canonicalRequest(req *http.Request, payloadHash string) string {
241 - if payloadHash == "" {
242 - payloadHash = s.payloadHash(req)
243 - }
244 - c := new(bytes.Buffer)
245 - fmt.Fprintf(c, "%s\n", req.Method)
246 - fmt.Fprintf(c, "%s\n", s.canonicalURI(req.URL))
247 - fmt.Fprintf(c, "%s\n", s.canonicalQueryString(req.URL))
248 - fmt.Fprintf(c, "%s\n\n", s.canonicalHeaders(req.Header))
249 - fmt.Fprintf(c, "%s\n", s.signedHeaders(req.Header))
250 - fmt.Fprintf(c, "%s", payloadHash)
251 - return c.String()
252 -}
253 -
254 -func (s *V4Signer) canonicalURI(u *url.URL) string {
255 - u = &url.URL{Path: u.Path}
256 - canonicalPath := u.String()
257 -
258 - slash := strings.HasSuffix(canonicalPath, "/")
259 - canonicalPath = path.Clean(canonicalPath)
260 -
261 - if canonicalPath == "" || canonicalPath == "." {
262 - canonicalPath = "/"
263 - }
264 -
265 - if canonicalPath != "/" && slash {
266 - canonicalPath += "/"
267 - }
268 -
269 - return canonicalPath
270 -}
271 -
272 -func (s *V4Signer) canonicalQueryString(u *url.URL) string {
273 - var a []string
274 - for k, vs := range u.Query() {
275 - k = url.QueryEscape(k)
276 - for _, v := range vs {
277 - if v == "" {
278 - a = append(a, k+"=")
279 - } else {
280 - v = url.QueryEscape(v)
281 - a = append(a, k+"="+v)
282 - }
283 - }
284 - }
285 - sort.Strings(a)
286 - return strings.Join(a, "&")
287 -}
288 -
289 -func (s *V4Signer) canonicalHeaders(h http.Header) string {
290 - i, a, lowerCase := 0, make([]string, len(h)), make(map[string][]string)
291 -
292 - for k, v := range h {
293 - lowerCase[strings.ToLower(k)] = v
294 - }
295 -
296 - var keys []string
297 - for k := range lowerCase {
298 - keys = append(keys, k)
299 - }
300 - sort.Strings(keys)
301 -
302 - for _, k := range keys {
303 - v := lowerCase[k]
304 - for j, w := range v {
305 - v[j] = strings.Trim(w, " ")
306 - }
307 - sort.Strings(v)
308 - a[i] = strings.ToLower(k) + ":" + strings.Join(v, ",")
309 - i++
310 - }
311 - return strings.Join(a, "\n")
312 -}
313 -
314 -func (s *V4Signer) signedHeaders(h http.Header) string {
315 - i, a := 0, make([]string, len(h))
316 - for k, _ := range h {
317 - a[i] = strings.ToLower(k)
318 - i++
319 - }
320 - sort.Strings(a)
321 - return strings.Join(a, ";")
322 -}
323 -
324 -func (s *V4Signer) payloadHash(req *http.Request) string {
325 - var b []byte
326 - if req.Body == nil {
327 - b = []byte("")
328 - } else {
329 - var err error
330 - b, err = ioutil.ReadAll(req.Body)
331 - if err != nil {
332 - // TODO: I REALLY DON'T LIKE THIS PANIC!!!!
333 - panic(err)
334 - }
335 - }
336 - req.Body = ioutil.NopCloser(bytes.NewBuffer(b))
337 - return s.hash(string(b))
338 -}
339 -
340 -/*
341 -stringToSign method creates the string to sign accorting to Task 2 of the AWS Signature Version 4 Signing Process. (http://goo.gl/es1PAu)
342 -
343 - StringToSign =
344 - Algorithm + '\n' +
345 - RequestDate + '\n' +
346 - CredentialScope + '\n' +
347 - HexEncode(Hash(CanonicalRequest))
348 -*/
349 -func (s *V4Signer) stringToSign(t time.Time, creq string) string {
350 - w := new(bytes.Buffer)
351 - fmt.Fprint(w, "AWS4-HMAC-SHA256\n")
352 - fmt.Fprintf(w, "%s\n", t.Format(ISO8601BasicFormat))
353 - fmt.Fprintf(w, "%s\n", s.credentialScope(t))
354 - fmt.Fprintf(w, "%s", s.hash(creq))
355 - return w.String()
356 -}
357 -
358 -func (s *V4Signer) credentialScope(t time.Time) string {
359 - return fmt.Sprintf("%s/%s/%s/aws4_request", t.Format(ISO8601BasicFormatShort), s.region.Name, s.serviceName)
360 -}
361 -
362 -/*
363 -signature method calculates the AWS Signature Version 4 according to Task 3 of the AWS Signature Version 4 Signing Process. (http://goo.gl/j0Yqe1)
364 -
365 - signature = HexEncode(HMAC(derived-signing-key, string-to-sign))
366 -*/
367 -func (s *V4Signer) signature(t time.Time, sts string) string {
368 - h := s.hmac(s.derivedKey(t), []byte(sts))
369 - return fmt.Sprintf("%x", h)
370 -}
371 -
372 -/*
373 -derivedKey method derives a signing key to be used for signing a request.
374 -
375 - kSecret = Your AWS Secret Access Key
376 - kDate = HMAC("AWS4" + kSecret, Date)
377 - kRegion = HMAC(kDate, Region)
378 - kService = HMAC(kRegion, Service)
379 - kSigning = HMAC(kService, "aws4_request")
380 -*/
381 -func (s *V4Signer) derivedKey(t time.Time) []byte {
382 - h := s.hmac([]byte("AWS4"+s.auth.SecretKey), []byte(t.Format(ISO8601BasicFormatShort)))
383 - h = s.hmac(h, []byte(s.region.Name))
384 - h = s.hmac(h, []byte(s.serviceName))
385 - h = s.hmac(h, []byte("aws4_request"))
386 - return h
387 -}
388 -
389 -/*
390 -authorization method generates the authorization header value.
391 -*/
392 -func (s *V4Signer) authorization(header http.Header, t time.Time, signature string) string {
393 - w := new(bytes.Buffer)
394 - fmt.Fprint(w, "AWS4-HMAC-SHA256 ")
395 - fmt.Fprintf(w, "Credential=%s/%s, ", s.auth.AccessKey, s.credentialScope(t))
396 - fmt.Fprintf(w, "SignedHeaders=%s, ", s.signedHeaders(header))
397 - fmt.Fprintf(w, "Signature=%s", signature)
398 - return w.String()
399 -}
400 -
401 -// hash method calculates the sha256 hash for a given string
402 -func (s *V4Signer) hash(in string) string {
403 - h := sha256.New()
404 - fmt.Fprintf(h, "%s", in)
405 - return fmt.Sprintf("%x", h.Sum(nil))
406 -}
407 -
408 -// hmac method calculates the sha256 hmac for a given slice of bytes
409 -func (s *V4Signer) hmac(key, data []byte) []byte {
410 - h := hmac.New(sha256.New, key)
411 - h.Write(data)
412 - return h.Sum(nil)
413 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/aws/sign_test.go deleted
-569
@@ -1,569 +0,0 @@
1 -package aws_test
2 -
3 -import (
4 - "fmt"
5 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
6 - "gopkg.in/check.v1"
7 - "net/http"
8 - "strings"
9 - "time"
10 -)
11 -
12 -var _ = check.Suite(&V4SignerSuite{})
13 -
14 -type V4SignerSuite struct {
15 - auth aws.Auth
16 - region aws.Region
17 - cases []V4SignerSuiteCase
18 -}
19 -
20 -type V4SignerSuiteCase struct {
21 - label string
22 - request V4SignerSuiteCaseRequest
23 - canonicalRequest string
24 - stringToSign string
25 - signature string
26 - authorization string
27 -}
28 -
29 -type V4SignerSuiteCaseRequest struct {
30 - method string
31 - host string
32 - url string
33 - headers []string
34 - body string
35 -}
36 -
37 -func (s *V4SignerSuite) SetUpSuite(c *check.C) {
38 - s.auth = aws.Auth{AccessKey: "AKIDEXAMPLE", SecretKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY"}
39 - s.region = aws.USEast
40 -
41 - // Test cases from the Signature Version 4 Test Suite (http://goo.gl/nguvs0)
42 - s.cases = append(s.cases,
43 -
44 - // get-header-key-duplicate
45 - V4SignerSuiteCase{
46 - label: "get-header-key-duplicate",
47 - request: V4SignerSuiteCaseRequest{
48 - method: "POST",
49 - host: "host.foo.com",
50 - url: "/",
51 - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "ZOO:zoobar", "zoo:foobar", "zoo:zoobar"},
52 - },
53 - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:foobar,zoobar,zoobar\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
54 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n3c52f0eaae2b61329c0a332e3fa15842a37bc5812cf4d80eb64784308850e313",
55 - signature: "54afcaaf45b331f81cd2edb974f7b824ff4dd594cbbaa945ed636b48477368ed",
56 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=54afcaaf45b331f81cd2edb974f7b824ff4dd594cbbaa945ed636b48477368ed",
57 - },
58 -
59 - // get-header-value-order
60 - V4SignerSuiteCase{
61 - label: "get-header-value-order",
62 - request: V4SignerSuiteCaseRequest{
63 - method: "POST",
64 - host: "host.foo.com",
65 - url: "/",
66 - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "p:z", "p:a", "p:p", "p:a"},
67 - },
68 - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\np:a,a,p,z\n\ndate;host;p\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
69 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n94c0389fefe0988cbbedc8606f0ca0b485b48da010d09fc844b45b697c8924fe",
70 - signature: "d2973954263943b11624a11d1c963ca81fb274169c7868b2858c04f083199e3d",
71 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;p, Signature=d2973954263943b11624a11d1c963ca81fb274169c7868b2858c04f083199e3d",
72 - },
73 -
74 - // get-header-value-trim
75 - V4SignerSuiteCase{
76 - label: "get-header-value-trim",
77 - request: V4SignerSuiteCaseRequest{
78 - method: "POST",
79 - host: "host.foo.com",
80 - url: "/",
81 - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "p: phfft "},
82 - },
83 - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\np:phfft\n\ndate;host;p\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
84 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ndddd1902add08da1ac94782b05f9278c08dc7468db178a84f8950d93b30b1f35",
85 - signature: "debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592",
86 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;p, Signature=debf546796015d6f6ded8626f5ce98597c33b47b9164cf6b17b4642036fcb592",
87 - },
88 -
89 - // get-empty
90 - V4SignerSuiteCase{
91 - label: "get-relative-relative",
92 - request: V4SignerSuiteCaseRequest{
93 - method: "GET",
94 - host: "host.foo.com",
95 - url: "",
96 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
97 - },
98 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
99 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
100 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
101 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
102 - },
103 -
104 - // get-single-relative
105 - V4SignerSuiteCase{
106 - label: "get-relative-relative",
107 - request: V4SignerSuiteCaseRequest{
108 - method: "GET",
109 - host: "host.foo.com",
110 - url: "/.",
111 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
112 - },
113 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
114 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
115 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
116 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
117 - },
118 -
119 - // get-multiple-relative
120 - V4SignerSuiteCase{
121 - label: "get-relative-relative",
122 - request: V4SignerSuiteCaseRequest{
123 - method: "GET",
124 - host: "host.foo.com",
125 - url: "/./././",
126 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
127 - },
128 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
129 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
130 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
131 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
132 - },
133 -
134 - // get-relative-relative
135 - V4SignerSuiteCase{
136 - label: "get-relative-relative",
137 - request: V4SignerSuiteCaseRequest{
138 - method: "GET",
139 - host: "host.foo.com",
140 - url: "/foo/bar/../..",
141 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
142 - },
143 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
144 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
145 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
146 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
147 - },
148 -
149 - // get-relative
150 - V4SignerSuiteCase{
151 - label: "get-relative",
152 - request: V4SignerSuiteCaseRequest{
153 - method: "GET",
154 - host: "host.foo.com",
155 - url: "/foo/..",
156 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
157 - },
158 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
159 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
160 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
161 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
162 - },
163 -
164 - // get-slash-dot-slash
165 - V4SignerSuiteCase{
166 - label: "get-slash-dot-slash",
167 - request: V4SignerSuiteCaseRequest{
168 - method: "GET",
169 - host: "host.foo.com",
170 - url: "/./",
171 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
172 - },
173 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
174 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
175 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
176 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
177 - },
178 -
179 - // get-slash-pointless-dot
180 - V4SignerSuiteCase{
181 - label: "get-slash-pointless-dot",
182 - request: V4SignerSuiteCaseRequest{
183 - method: "GET",
184 - host: "host.foo.com",
185 - url: "/./foo",
186 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
187 - },
188 - canonicalRequest: "GET\n/foo\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
189 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n8021a97572ee460f87ca67f4e8c0db763216d84715f5424a843a5312a3321e2d",
190 - signature: "910e4d6c9abafaf87898e1eb4c929135782ea25bb0279703146455745391e63a",
191 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=910e4d6c9abafaf87898e1eb4c929135782ea25bb0279703146455745391e63a",
192 - },
193 -
194 - // get-slash
195 - V4SignerSuiteCase{
196 - label: "get-slash",
197 - request: V4SignerSuiteCaseRequest{
198 - method: "GET",
199 - host: "host.foo.com",
200 - url: "//",
201 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
202 - },
203 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
204 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
205 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
206 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
207 - },
208 -
209 - // get-slashes
210 - V4SignerSuiteCase{
211 - label: "get-slashes",
212 - request: V4SignerSuiteCaseRequest{
213 - method: "GET",
214 - host: "host.foo.com",
215 - url: "//foo//",
216 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
217 - },
218 - canonicalRequest: "GET\n/foo/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
219 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n6bb4476ee8745730c9cb79f33a0c70baa6d8af29c0077fa12e4e8f1dd17e7098",
220 - signature: "b00392262853cfe3201e47ccf945601079e9b8a7f51ee4c3d9ee4f187aa9bf19",
221 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b00392262853cfe3201e47ccf945601079e9b8a7f51ee4c3d9ee4f187aa9bf19",
222 - },
223 -
224 - // get-space
225 - V4SignerSuiteCase{
226 - label: "get-space",
227 - request: V4SignerSuiteCaseRequest{
228 - method: "GET",
229 - host: "host.foo.com",
230 - url: "/%20/foo",
231 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
232 - },
233 - canonicalRequest: "GET\n/%20/foo\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
234 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n69c45fb9fe3fd76442b5086e50b2e9fec8298358da957b293ef26e506fdfb54b",
235 - signature: "f309cfbd10197a230c42dd17dbf5cca8a0722564cb40a872d25623cfa758e374",
236 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=f309cfbd10197a230c42dd17dbf5cca8a0722564cb40a872d25623cfa758e374",
237 - },
238 -
239 - // get-unreserved
240 - V4SignerSuiteCase{
241 - label: "get-unreserved",
242 - request: V4SignerSuiteCaseRequest{
243 - method: "GET",
244 - host: "host.foo.com",
245 - url: "/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
246 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
247 - },
248 - canonicalRequest: "GET\n/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
249 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ndf63ee3247c0356c696a3b21f8d8490b01fa9cd5bc6550ef5ef5f4636b7b8901",
250 - signature: "830cc36d03f0f84e6ee4953fbe701c1c8b71a0372c63af9255aa364dd183281e",
251 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=830cc36d03f0f84e6ee4953fbe701c1c8b71a0372c63af9255aa364dd183281e",
252 - },
253 -
254 - // get-utf8
255 - V4SignerSuiteCase{
256 - label: "get-utf8",
257 - request: V4SignerSuiteCaseRequest{
258 - method: "GET",
259 - host: "host.foo.com",
260 - url: "/%E1%88%B4",
261 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
262 - },
263 - canonicalRequest: "GET\n/%E1%88%B4\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
264 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n27ba31df5dbc6e063d8f87d62eb07143f7f271c5330a917840586ac1c85b6f6b",
265 - signature: "8d6634c189aa8c75c2e51e106b6b5121bed103fdb351f7d7d4381c738823af74",
266 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=8d6634c189aa8c75c2e51e106b6b5121bed103fdb351f7d7d4381c738823af74",
267 - },
268 -
269 - // get-vanilla-empty-query-key
270 - V4SignerSuiteCase{
271 - label: "get-vanilla-empty-query-key",
272 - request: V4SignerSuiteCaseRequest{
273 - method: "GET",
274 - host: "host.foo.com",
275 - url: "/?foo=bar",
276 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
277 - },
278 - canonicalRequest: "GET\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
279 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n0846c2945b0832deb7a463c66af5c4f8bd54ec28c438e67a214445b157c9ddf8",
280 - signature: "56c054473fd260c13e4e7393eb203662195f5d4a1fada5314b8b52b23f985e9f",
281 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=56c054473fd260c13e4e7393eb203662195f5d4a1fada5314b8b52b23f985e9f",
282 - },
283 -
284 - // get-vanilla-query-order-key-case
285 - V4SignerSuiteCase{
286 - label: "get-vanilla-query-order-key-case",
287 - request: V4SignerSuiteCaseRequest{
288 - method: "GET",
289 - host: "host.foo.com",
290 - url: "/?foo=Zoo&foo=aha",
291 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
292 - },
293 - canonicalRequest: "GET\n/\nfoo=Zoo&foo=aha\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
294 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ne25f777ba161a0f1baf778a87faf057187cf5987f17953320e3ca399feb5f00d",
295 - signature: "be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09",
296 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=be7148d34ebccdc6423b19085378aa0bee970bdc61d144bd1a8c48c33079ab09",
297 - },
298 -
299 - // get-vanilla-query-order-key
300 - V4SignerSuiteCase{
301 - label: "get-vanilla-query-order-key",
302 - request: V4SignerSuiteCaseRequest{
303 - method: "GET",
304 - host: "host.foo.com",
305 - url: "/?a=foo&b=foo",
306 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
307 - },
308 - canonicalRequest: "GET\n/\na=foo&b=foo\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
309 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n2f23d14fe13caebf6dfda346285c6d9c14f49eaca8f5ec55c627dd7404f7a727",
310 - signature: "0dc122f3b28b831ab48ba65cb47300de53fbe91b577fe113edac383730254a3b",
311 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=0dc122f3b28b831ab48ba65cb47300de53fbe91b577fe113edac383730254a3b",
312 - },
313 -
314 - // get-vanilla-query-order-value
315 - V4SignerSuiteCase{
316 - label: "get-vanilla-query-order-value",
317 - request: V4SignerSuiteCaseRequest{
318 - method: "GET",
319 - host: "host.foo.com",
320 - url: "/?foo=b&foo=a",
321 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
322 - },
323 - canonicalRequest: "GET\n/\nfoo=a&foo=b\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
324 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n33dffc220e89131f8f6157a35c40903daa658608d9129ff9489e5cf5bbd9b11b",
325 - signature: "feb926e49e382bec75c9d7dcb2a1b6dc8aa50ca43c25d2bc51143768c0875acc",
326 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=feb926e49e382bec75c9d7dcb2a1b6dc8aa50ca43c25d2bc51143768c0875acc",
327 - },
328 -
329 - // get-vanilla-query-unreserved
330 - V4SignerSuiteCase{
331 - label: "get-vanilla-query-unreserved",
332 - request: V4SignerSuiteCaseRequest{
333 - method: "GET",
334 - host: "host.foo.com",
335 - url: "/?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
336 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
337 - },
338 - canonicalRequest: "GET\n/\n-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
339 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nd2578f3156d4c9d180713d1ff20601d8a3eed0dd35447d24603d7d67414bd6b5",
340 - signature: "f1498ddb4d6dae767d97c466fb92f1b59a2c71ca29ac954692663f9db03426fb",
341 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=f1498ddb4d6dae767d97c466fb92f1b59a2c71ca29ac954692663f9db03426fb",
342 - },
343 -
344 - // get-vanilla-query
345 - V4SignerSuiteCase{
346 - label: "get-vanilla-query",
347 - request: V4SignerSuiteCaseRequest{
348 - method: "GET",
349 - host: "host.foo.com",
350 - url: "/",
351 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
352 - },
353 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
354 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
355 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
356 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
357 - },
358 -
359 - // get-vanilla-ut8-query
360 - V4SignerSuiteCase{
361 - label: "get-vanilla-ut8-query",
362 - request: V4SignerSuiteCaseRequest{
363 - method: "GET",
364 - host: "host.foo.com",
365 - url: "/?ሴ=bar",
366 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
367 - },
368 - canonicalRequest: "GET\n/\n%E1%88%B4=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
369 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nde5065ff39c131e6c2e2bd19cd9345a794bf3b561eab20b8d97b2093fc2a979e",
370 - signature: "6fb359e9a05394cc7074e0feb42573a2601abc0c869a953e8c5c12e4e01f1a8c",
371 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=6fb359e9a05394cc7074e0feb42573a2601abc0c869a953e8c5c12e4e01f1a8c",
372 - },
373 -
374 - // get-vanilla
375 - V4SignerSuiteCase{
376 - label: "get-vanilla",
377 - request: V4SignerSuiteCaseRequest{
378 - method: "GET",
379 - host: "host.foo.com",
380 - url: "/",
381 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
382 - },
383 - canonicalRequest: "GET\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
384 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n366b91fb121d72a00f46bbe8d395f53a102b06dfb7e79636515208ed3fa606b1",
385 - signature: "b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
386 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470",
387 - },
388 -
389 - // post-header-key-case
390 - V4SignerSuiteCase{
391 - label: "post-header-key-case",
392 - request: V4SignerSuiteCaseRequest{
393 - method: "POST",
394 - host: "host.foo.com",
395 - url: "/",
396 - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT"},
397 - },
398 - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
399 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n05da62cee468d24ae84faff3c39f1b85540de60243c1bcaace39c0a2acc7b2c4",
400 - signature: "22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
401 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
402 - },
403 -
404 - // post-header-key-sort
405 - V4SignerSuiteCase{
406 - label: "post-header-key-sort",
407 - request: V4SignerSuiteCaseRequest{
408 - method: "POST",
409 - host: "host.foo.com",
410 - url: "/",
411 - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "ZOO:zoobar"},
412 - },
413 - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:zoobar\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
414 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n34e1bddeb99e76ee01d63b5e28656111e210529efeec6cdfd46a48e4c734545d",
415 - signature: "b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a",
416 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=b7a95a52518abbca0964a999a880429ab734f35ebbf1235bd79a5de87756dc4a",
417 - },
418 -
419 - // post-header-value-case
420 - V4SignerSuiteCase{
421 - label: "post-header-value-case",
422 - request: V4SignerSuiteCaseRequest{
423 - method: "POST",
424 - host: "host.foo.com",
425 - url: "/",
426 - headers: []string{"DATE:Mon, 09 Sep 2011 23:36:00 GMT", "zoo:ZOOBAR"},
427 - },
428 - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\nzoo:ZOOBAR\n\ndate;host;zoo\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
429 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n3aae6d8274b8c03e2cc96fc7d6bda4b9bd7a0a184309344470b2c96953e124aa",
430 - signature: "273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7",
431 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host;zoo, Signature=273313af9d0c265c531e11db70bbd653f3ba074c1009239e8559d3987039cad7",
432 - },
433 -
434 - // post-vanilla-empty-query-value
435 - V4SignerSuiteCase{
436 - label: "post-vanilla-empty-query-value",
437 - request: V4SignerSuiteCaseRequest{
438 - method: "POST",
439 - host: "host.foo.com",
440 - url: "/?foo=bar",
441 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
442 - },
443 - canonicalRequest: "POST\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
444 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ncd4f39132d8e60bb388831d734230460872b564871c47f5de62e62d1a68dbe1e",
445 - signature: "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
446 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
447 - },
448 -
449 - // post-vanilla-query
450 - V4SignerSuiteCase{
451 - label: "post-vanilla-query",
452 - request: V4SignerSuiteCaseRequest{
453 - method: "POST",
454 - host: "host.foo.com",
455 - url: "/?foo=bar",
456 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
457 - },
458 - canonicalRequest: "POST\n/\nfoo=bar\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
459 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\ncd4f39132d8e60bb388831d734230460872b564871c47f5de62e62d1a68dbe1e",
460 - signature: "b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
461 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b6e3b79003ce0743a491606ba1035a804593b0efb1e20a11cba83f8c25a57a92",
462 - },
463 -
464 - // post-vanilla
465 - V4SignerSuiteCase{
466 - label: "post-vanilla",
467 - request: V4SignerSuiteCaseRequest{
468 - method: "POST",
469 - host: "host.foo.com",
470 - url: "/",
471 - headers: []string{"Date:Mon, 09 Sep 2011 23:36:00 GMT"},
472 - },
473 - canonicalRequest: "POST\n/\n\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ndate;host\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
474 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n05da62cee468d24ae84faff3c39f1b85540de60243c1bcaace39c0a2acc7b2c4",
475 - signature: "22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
476 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=22902d79e148b64e7571c3565769328423fe276eae4b26f83afceda9e767f726",
477 - },
478 -
479 - // post-x-www-form-urlencoded-parameters
480 - V4SignerSuiteCase{
481 - label: "post-x-www-form-urlencoded-parameters",
482 - request: V4SignerSuiteCaseRequest{
483 - method: "POST",
484 - host: "host.foo.com",
485 - url: "/",
486 - headers: []string{"Content-Type:application/x-www-form-urlencoded; charset=utf8", "Date:Mon, 09 Sep 2011 23:36:00 GMT"},
487 - body: "foo=bar",
488 - },
489 - canonicalRequest: "POST\n/\n\ncontent-type:application/x-www-form-urlencoded; charset=utf8\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ncontent-type;date;host\n3ba8907e7a252327488df390ed517c45b96dead033600219bdca7107d1d3f88a",
490 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\nc4115f9e54b5cecf192b1eaa23b8e88ed8dc5391bd4fde7b3fff3d9c9fe0af1f",
491 - signature: "b105eb10c6d318d2294de9d49dd8b031b55e3c3fe139f2e637da70511e9e7b71",
492 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=content-type;date;host, Signature=b105eb10c6d318d2294de9d49dd8b031b55e3c3fe139f2e637da70511e9e7b71",
493 - },
494 -
495 - // post-x-www-form-urlencoded
496 - V4SignerSuiteCase{
497 - label: "post-x-www-form-urlencoded",
498 - request: V4SignerSuiteCaseRequest{
499 - method: "POST",
500 - host: "host.foo.com",
501 - url: "/",
502 - headers: []string{"Content-Type:application/x-www-form-urlencoded", "Date:Mon, 09 Sep 2011 23:36:00 GMT"},
503 - body: "foo=bar",
504 - },
505 - canonicalRequest: "POST\n/\n\ncontent-type:application/x-www-form-urlencoded\ndate:Mon, 09 Sep 2011 23:36:00 GMT\nhost:host.foo.com\n\ncontent-type;date;host\n3ba8907e7a252327488df390ed517c45b96dead033600219bdca7107d1d3f88a",
506 - stringToSign: "AWS4-HMAC-SHA256\n20110909T233600Z\n20110909/us-east-1/host/aws4_request\n4c5c6e4b52fb5fb947a8733982a8a5a61b14f04345cbfe6e739236c76dd48f74",
507 - signature: "5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc",
508 - authorization: "AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=content-type;date;host, Signature=5a15b22cf462f047318703b92e6f4f38884e4a7ab7b1d6426ca46a8bd1c26cbc",
509 - },
510 - )
511 -}
512 -
513 -func (s *V4SignerSuite) TestCases(c *check.C) {
514 - signer := aws.NewV4Signer(s.auth, "host", s.region)
515 -
516 - for _, testCase := range s.cases {
517 -
518 - req, err := http.NewRequest(testCase.request.method, "http://"+testCase.request.host+testCase.request.url, strings.NewReader(testCase.request.body))
519 - c.Assert(err, check.IsNil, check.Commentf("Testcase: %s", testCase.label))
520 - for _, v := range testCase.request.headers {
521 - h := strings.SplitN(v, ":", 2)
522 - req.Header.Add(h[0], h[1])
523 - }
524 - req.Header.Set("host", req.Host)
525 -
526 - t := signer.RequestTime(req)
527 -
528 - canonicalRequest := signer.CanonicalRequest(req)
529 - c.Check(canonicalRequest, check.Equals, testCase.canonicalRequest, check.Commentf("Testcase: %s", testCase.label))
530 -
531 - stringToSign := signer.StringToSign(t, canonicalRequest)
532 - c.Check(stringToSign, check.Equals, testCase.stringToSign, check.Commentf("Testcase: %s", testCase.label))
533 -
534 - signature := signer.Signature(t, stringToSign)
535 - c.Check(signature, check.Equals, testCase.signature, check.Commentf("Testcase: %s", testCase.label))
536 -
537 - authorization := signer.Authorization(req.Header, t, signature)
538 - c.Check(authorization, check.Equals, testCase.authorization, check.Commentf("Testcase: %s", testCase.label))
539 -
540 - signer.Sign(req)
541 - c.Check(req.Header.Get("Authorization"), check.Equals, testCase.authorization, check.Commentf("Testcase: %s", testCase.label))
542 - }
543 -}
544 -
545 -func ExampleV4Signer() {
546 - // Get auth from env vars
547 - auth, err := aws.EnvAuth()
548 - if err != nil {
549 - fmt.Println(err)
550 - }
551 -
552 - // Create a signer with the auth, name of the service, and aws region
553 - signer := aws.NewV4Signer(auth, "dynamodb", aws.USEast)
554 -
555 - // Create a request
556 - req, err := http.NewRequest("POST", aws.USEast.DynamoDBEndpoint, strings.NewReader("sample_request"))
557 - if err != nil {
558 - fmt.Println(err)
559 - }
560 -
561 - // Date or x-amz-date header is required to sign a request
562 - req.Header.Add("Date", time.Now().UTC().Format(http.TimeFormat))
563 -
564 - // Sign the request
565 - signer.Sign(req)
566 -
567 - // Issue signed request
568 - http.DefaultClient.Do(req)
569 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/export_test.go deleted
-27
@@ -1,27 +0,0 @@
1 -package s3
2 -
3 -import (
4 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
5 -)
6 -
7 -var originalStrategy = attempts
8 -
9 -func SetAttemptStrategy(s *aws.AttemptStrategy) {
10 - if s == nil {
11 - attempts = originalStrategy
12 - } else {
13 - attempts = *s
14 - }
15 -}
16 -
17 -func Sign(auth aws.Auth, method, path string, params, headers map[string][]string) {
18 - sign(auth, method, path, params, headers)
19 -}
20 -
21 -func SetListPartsMax(n int) {
22 - listPartsMax = n
23 -}
24 -
25 -func SetListMultiMax(n int) {
26 - listMultiMax = n
27 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/lifecycle.go deleted
-202
@@ -1,202 +0,0 @@
1 -package s3
2 -
3 -import (
4 - "crypto/md5"
5 - "encoding/base64"
6 - "encoding/xml"
7 - "net/url"
8 - "strconv"
9 - "time"
10 -)
11 -
12 -// Implements an interface for s3 bucket lifecycle configuration
13 -// See goo.gl/d0bbDf for details.
14 -
15 -const (
16 - LifecycleRuleStatusEnabled = "Enabled"
17 - LifecycleRuleStatusDisabled = "Disabled"
18 - LifecycleRuleDateFormat = "2006-01-02"
19 - StorageClassGlacier = "GLACIER"
20 -)
21 -
22 -type Expiration struct {
23 - Days *uint `xml:"Days,omitempty"`
24 - Date string `xml:"Date,omitempty"`
25 -}
26 -
27 -// Returns Date as a time.Time.
28 -func (r *Expiration) ParseDate() (time.Time, error) {
29 - return time.Parse(LifecycleRuleDateFormat, r.Date)
30 -}
31 -
32 -type Transition struct {
33 - Days *uint `xml:"Days,omitempty"`
34 - Date string `xml:"Date,omitempty"`
35 - StorageClass string `xml:"StorageClass"`
36 -}
37 -
38 -// Returns Date as a time.Time.
39 -func (r *Transition) ParseDate() (time.Time, error) {
40 - return time.Parse(LifecycleRuleDateFormat, r.Date)
41 -}
42 -
43 -type NoncurrentVersionExpiration struct {
44 - Days *uint `xml:"NoncurrentDays,omitempty"`
45 -}
46 -
47 -type NoncurrentVersionTransition struct {
48 - Days *uint `xml:"NoncurrentDays,omitempty"`
49 - StorageClass string `xml:"StorageClass"`
50 -}
51 -
52 -type LifecycleRule struct {
53 - ID string `xml:"ID"`
54 - Prefix string `xml:"Prefix"`
55 - Status string `xml:"Status"`
56 - NoncurrentVersionTransition *NoncurrentVersionTransition `xml:"NoncurrentVersionTransition,omitempty"`
57 - NoncurrentVersionExpiration *NoncurrentVersionExpiration `xml:"NoncurrentVersionExpiration,omitempty"`
58 - Transition *Transition `xml:"Transition,omitempty"`
59 - Expiration *Expiration `xml:"Expiration,omitempty"`
60 -}
61 -
62 -// Create a lifecycle rule with arbitrary identifier id and object name prefix
63 -// for which the rules should apply.
64 -func NewLifecycleRule(id, prefix string) *LifecycleRule {
65 - rule := &LifecycleRule{
66 - ID: id,
67 - Prefix: prefix,
68 - Status: LifecycleRuleStatusEnabled,
69 - }
70 - return rule
71 -}
72 -
73 -// Adds a transition rule in days. Overwrites any previous transition rule.
74 -func (r *LifecycleRule) SetTransitionDays(days uint) {
75 - r.Transition = &Transition{
76 - Days: &days,
77 - StorageClass: StorageClassGlacier,
78 - }
79 -}
80 -
81 -// Adds a transition rule as a date. Overwrites any previous transition rule.
82 -func (r *LifecycleRule) SetTransitionDate(date time.Time) {
83 - r.Transition = &Transition{
84 - Date: date.Format(LifecycleRuleDateFormat),
85 - StorageClass: StorageClassGlacier,
86 - }
87 -}
88 -
89 -// Adds an expiration rule in days. Overwrites any previous expiration rule.
90 -// Days must be > 0.
91 -func (r *LifecycleRule) SetExpirationDays(days uint) {
92 - r.Expiration = &Expiration{
93 - Days: &days,
94 - }
95 -}
96 -
97 -// Adds an expiration rule as a date. Overwrites any previous expiration rule.
98 -func (r *LifecycleRule) SetExpirationDate(date time.Time) {
99 - r.Expiration = &Expiration{
100 - Date: date.Format(LifecycleRuleDateFormat),
101 - }
102 -}
103 -
104 -// Adds a noncurrent version transition rule. Overwrites any previous
105 -// noncurrent version transition rule.
106 -func (r *LifecycleRule) SetNoncurrentVersionTransitionDays(days uint) {
107 - r.NoncurrentVersionTransition = &NoncurrentVersionTransition{
108 - Days: &days,
109 - StorageClass: StorageClassGlacier,
110 - }
111 -}
112 -
113 -// Adds a noncurrent version expiration rule. Days must be > 0. Overwrites
114 -// any previous noncurrent version expiration rule.
115 -func (r *LifecycleRule) SetNoncurrentVersionExpirationDays(days uint) {
116 - r.NoncurrentVersionExpiration = &NoncurrentVersionExpiration{
117 - Days: &days,
118 - }
119 -}
120 -
121 -// Marks the rule as disabled.
122 -func (r *LifecycleRule) Disable() {
123 - r.Status = LifecycleRuleStatusDisabled
124 -}
125 -
126 -// Marks the rule as enabled (default).
127 -func (r *LifecycleRule) Enable() {
128 - r.Status = LifecycleRuleStatusEnabled
129 -}
130 -
131 -type LifecycleConfiguration struct {
132 - XMLName xml.Name `xml:"LifecycleConfiguration"`
133 - Rules *[]*LifecycleRule `xml:"Rule,omitempty"`
134 -}
135 -
136 -// Adds a LifecycleRule to the configuration.
137 -func (c *LifecycleConfiguration) AddRule(r *LifecycleRule) {
138 - var rules []*LifecycleRule
139 - if c.Rules != nil {
140 - rules = *c.Rules
141 - }
142 - rules = append(rules, r)
143 - c.Rules = &rules
144 -}
145 -
146 -// Sets the bucket's lifecycle configuration.
147 -func (b *Bucket) PutLifecycleConfiguration(c *LifecycleConfiguration) error {
148 - doc, err := xml.Marshal(c)
149 - if err != nil {
150 - return err
151 - }
152 -
153 - buf := makeXmlBuffer(doc)
154 - digest := md5.New()
155 - size, err := digest.Write(buf.Bytes())
156 - if err != nil {
157 - return err
158 - }
159 -
160 - headers := map[string][]string{
161 - "Content-Length": {strconv.FormatInt(int64(size), 10)},
162 - "Content-MD5": {base64.StdEncoding.EncodeToString(digest.Sum(nil))},
163 - }
164 -
165 - req := &request{
166 - path: "/",
167 - method: "PUT",
168 - bucket: b.Name,
169 - headers: headers,
170 - payload: buf,
171 - params: url.Values{"lifecycle": {""}},
172 - }
173 -
174 - return b.S3.queryV4Sign(req, nil)
175 -}
176 -
177 -// Retrieves the lifecycle configuration for the bucket. AWS returns an error
178 -// if no lifecycle found.
179 -func (b *Bucket) GetLifecycleConfiguration() (*LifecycleConfiguration, error) {
180 - req := &request{
181 - method: "GET",
182 - bucket: b.Name,
183 - path: "/",
184 - params: url.Values{"lifecycle": {""}},
185 - }
186 -
187 - conf := &LifecycleConfiguration{}
188 - err := b.S3.queryV4Sign(req, conf)
189 - return conf, err
190 -}
191 -
192 -// Delete the bucket's lifecycle configuration.
193 -func (b *Bucket) DeleteLifecycleConfiguration() error {
194 - req := &request{
195 - method: "DELETE",
196 - bucket: b.Name,
197 - path: "/",
198 - params: url.Values{"lifecycle": {""}},
199 - }
200 -
201 - return b.S3.queryV4Sign(req, nil)
202 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/lifecycle_test.go deleted
-205
@@ -1,205 +0,0 @@
1 -package s3_test
2 -
3 -import (
4 - "encoding/xml"
5 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
6 - "gopkg.in/check.v1"
7 - "io/ioutil"
8 - "net/http"
9 - "strings"
10 - "time"
11 -)
12 -
13 -func (s *S) TestLifecycleConfiguration(c *check.C) {
14 - date, err := time.Parse(s3.LifecycleRuleDateFormat, "2014-09-10")
15 - c.Check(err, check.IsNil)
16 -
17 - conf := &s3.LifecycleConfiguration{}
18 -
19 - rule := s3.NewLifecycleRule("transition-days", "/")
20 - rule.SetTransitionDays(7)
21 - conf.AddRule(rule)
22 -
23 - rule = s3.NewLifecycleRule("transition-date", "/")
24 - rule.SetTransitionDate(date)
25 - conf.AddRule(rule)
26 -
27 - rule = s3.NewLifecycleRule("expiration-days", "")
28 - rule.SetExpirationDays(1)
29 - conf.AddRule(rule)
30 -
31 - rule = s3.NewLifecycleRule("expiration-date", "")
32 - rule.SetExpirationDate(date)
33 - conf.AddRule(rule)
34 -
35 - rule = s3.NewLifecycleRule("noncurrent-transition", "")
36 - rule.SetNoncurrentVersionTransitionDays(11)
37 - conf.AddRule(rule)
38 -
39 - rule = s3.NewLifecycleRule("noncurrent-expiration", "")
40 - rule.SetNoncurrentVersionExpirationDays(1011)
41 -
42 - // Test Disable() and Enable() toggling
43 - c.Check(rule.Status, check.Equals, s3.LifecycleRuleStatusEnabled)
44 - rule.Disable()
45 - c.Check(rule.Status, check.Equals, s3.LifecycleRuleStatusDisabled)
46 - rule.Enable()
47 - c.Check(rule.Status, check.Equals, s3.LifecycleRuleStatusEnabled)
48 - rule.Disable()
49 - c.Check(rule.Status, check.Equals, s3.LifecycleRuleStatusDisabled)
50 -
51 - conf.AddRule(rule)
52 -
53 - doc, err := xml.MarshalIndent(conf, "", " ")
54 - c.Check(err, check.IsNil)
55 -
56 - expectedDoc := `<LifecycleConfiguration>
57 - <Rule>
58 - <ID>transition-days</ID>
59 - <Prefix>/</Prefix>
60 - <Status>Enabled</Status>
61 - <Transition>
62 - <Days>7</Days>
63 - <StorageClass>GLACIER</StorageClass>
64 - </Transition>
65 - </Rule>
66 - <Rule>
67 - <ID>transition-date</ID>
68 - <Prefix>/</Prefix>
69 - <Status>Enabled</Status>
70 - <Transition>
71 - <Date>2014-09-10</Date>
72 - <StorageClass>GLACIER</StorageClass>
73 - </Transition>
74 - </Rule>
75 - <Rule>
76 - <ID>expiration-days</ID>
77 - <Prefix></Prefix>
78 - <Status>Enabled</Status>
79 - <Expiration>
80 - <Days>1</Days>
81 - </Expiration>
82 - </Rule>
83 - <Rule>
84 - <ID>expiration-date</ID>
85 - <Prefix></Prefix>
86 - <Status>Enabled</Status>
87 - <Expiration>
88 - <Date>2014-09-10</Date>
89 - </Expiration>
90 - </Rule>
91 - <Rule>
92 - <ID>noncurrent-transition</ID>
93 - <Prefix></Prefix>
94 - <Status>Enabled</Status>
95 - <NoncurrentVersionTransition>
96 - <NoncurrentDays>11</NoncurrentDays>
97 - <StorageClass>GLACIER</StorageClass>
98 - </NoncurrentVersionTransition>
99 - </Rule>
100 - <Rule>
101 - <ID>noncurrent-expiration</ID>
102 - <Prefix></Prefix>
103 - <Status>Disabled</Status>
104 - <NoncurrentVersionExpiration>
105 - <NoncurrentDays>1011</NoncurrentDays>
106 - </NoncurrentVersionExpiration>
107 - </Rule>
108 -</LifecycleConfiguration>`
109 -
110 - c.Check(string(doc), check.Equals, expectedDoc)
111 -
112 - // Unmarshalling test
113 - conf2 := &s3.LifecycleConfiguration{}
114 - err = xml.Unmarshal(doc, conf2)
115 - c.Check(err, check.IsNil)
116 - s.checkLifecycleConfigurationEqual(c, conf, conf2)
117 -}
118 -
119 -func (s *S) checkLifecycleConfigurationEqual(c *check.C, conf, conf2 *s3.LifecycleConfiguration) {
120 - c.Check(len(*conf2.Rules), check.Equals, len(*conf.Rules))
121 - for i, rule := range *conf2.Rules {
122 - confRules := *conf.Rules
123 - c.Check(rule, check.DeepEquals, confRules[i])
124 - }
125 -}
126 -
127 -func (s *S) checkLifecycleRequest(c *check.C, req *http.Request) {
128 - // ?lifecycle= is the only query param
129 - v, ok := req.Form["lifecycle"]
130 - c.Assert(ok, check.Equals, true)
131 - c.Assert(v, check.HasLen, 1)
132 - c.Assert(v[0], check.Equals, "")
133 -
134 - c.Assert(req.Header["X-Amz-Date"], check.HasLen, 1)
135 - c.Assert(req.Header["X-Amz-Date"][0], check.Not(check.Equals), "")
136 -
137 - // Lifecycle methods require V4 auth
138 - usesV4 := strings.HasPrefix(req.Header["Authorization"][0], "AWS4-HMAC-SHA256")
139 - c.Assert(usesV4, check.Equals, true)
140 -}
141 -
142 -func (s *S) TestPutLifecycleConfiguration(c *check.C) {
143 - testServer.Response(200, nil, "")
144 -
145 - conf := &s3.LifecycleConfiguration{}
146 - rule := s3.NewLifecycleRule("id", "")
147 - rule.SetTransitionDays(7)
148 - conf.AddRule(rule)
149 -
150 - doc, err := xml.Marshal(conf)
151 - c.Check(err, check.IsNil)
152 -
153 - b := s.s3.Bucket("bucket")
154 - err = b.PutLifecycleConfiguration(conf)
155 - c.Assert(err, check.IsNil)
156 -
157 - req := testServer.WaitRequest()
158 - c.Assert(req.Method, check.Equals, "PUT")
159 - c.Assert(req.URL.Path, check.Equals, "/bucket/")
160 - c.Assert(req.Header["Content-Md5"], check.HasLen, 1)
161 - c.Assert(req.Header["Content-Md5"][0], check.Not(check.Equals), "")
162 - s.checkLifecycleRequest(c, req)
163 -
164 - // Check we sent the correct xml serialization
165 - data, err := ioutil.ReadAll(req.Body)
166 - req.Body.Close()
167 - c.Assert(err, check.IsNil)
168 - header := "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
169 - c.Assert(string(data), check.Equals, header+string(doc))
170 -}
171 -
172 -func (s *S) TestGetLifecycleConfiguration(c *check.C) {
173 - conf := &s3.LifecycleConfiguration{}
174 - rule := s3.NewLifecycleRule("id", "")
175 - rule.SetTransitionDays(7)
176 - conf.AddRule(rule)
177 -
178 - doc, err := xml.Marshal(conf)
179 - c.Check(err, check.IsNil)
180 -
181 - testServer.Response(200, nil, string(doc))
182 -
183 - b := s.s3.Bucket("bucket")
184 - conf2, err := b.GetLifecycleConfiguration()
185 - c.Check(err, check.IsNil)
186 -
187 - req := testServer.WaitRequest()
188 - c.Assert(req.Method, check.Equals, "GET")
189 - c.Assert(req.URL.Path, check.Equals, "/bucket/")
190 - s.checkLifecycleRequest(c, req)
191 - s.checkLifecycleConfigurationEqual(c, conf, conf2)
192 -}
193 -
194 -func (s *S) TestDeleteLifecycleConfiguration(c *check.C) {
195 - testServer.Response(200, nil, "")
196 -
197 - b := s.s3.Bucket("bucket")
198 - err := b.DeleteLifecycleConfiguration()
199 - c.Check(err, check.IsNil)
200 -
201 - req := testServer.WaitRequest()
202 - c.Assert(req.Method, check.Equals, "DELETE")
203 - c.Assert(req.URL.Path, check.Equals, "/bucket/")
204 - s.checkLifecycleRequest(c, req)
205 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/multi.go deleted
-464
@@ -1,464 +0,0 @@
1 -package s3
2 -
3 -import (
4 - "bytes"
5 - "crypto/md5"
6 - "encoding/base64"
7 - "encoding/hex"
8 - "encoding/xml"
9 - "errors"
10 - "io"
11 - "net/url"
12 - "sort"
13 - "strconv"
14 - "strings"
15 -)
16 -
17 -// Multi represents an unfinished multipart upload.
18 -//
19 -// Multipart uploads allow sending big objects in smaller chunks.
20 -// After all parts have been sent, the upload must be explicitly
21 -// completed by calling Complete with the list of parts.
22 -//
23 -// See http://goo.gl/vJfTG for an overview of multipart uploads.
24 -type Multi struct {
25 - Bucket *Bucket
26 - Key string
27 - UploadId string
28 -}
29 -
30 -// That's the default. Here just for testing.
31 -var listMultiMax = 1000
32 -
33 -type listMultiResp struct {
34 - NextKeyMarker string
35 - NextUploadIdMarker string
36 - IsTruncated bool
37 - Upload []Multi
38 - CommonPrefixes []string `xml:"CommonPrefixes>Prefix"`
39 -}
40 -
41 -// ListMulti returns the list of unfinished multipart uploads in b.
42 -//
43 -// The prefix parameter limits the response to keys that begin with the
44 -// specified prefix. You can use prefixes to separate a bucket into different
45 -// groupings of keys (to get the feeling of folders, for example).
46 -//
47 -// The delim parameter causes the response to group all of the keys that
48 -// share a common prefix up to the next delimiter in a single entry within
49 -// the CommonPrefixes field. You can use delimiters to separate a bucket
50 -// into different groupings of keys, similar to how folders would work.
51 -//
52 -// See http://goo.gl/ePioY for details.
53 -func (b *Bucket) ListMulti(prefix, delim string) (multis []*Multi, prefixes []string, err error) {
54 - params := map[string][]string{
55 - "uploads": {""},
56 - "max-uploads": {strconv.FormatInt(int64(listMultiMax), 10)},
57 - "prefix": {prefix},
58 - "delimiter": {delim},
59 - }
60 - for attempt := attempts.Start(); attempt.Next(); {
61 - req := &request{
62 - method: "GET",
63 - bucket: b.Name,
64 - params: params,
65 - }
66 - var resp listMultiResp
67 - err := b.S3.query(req, &resp)
68 - if shouldRetry(err) && attempt.HasNext() {
69 - continue
70 - }
71 - if err != nil {
72 - return nil, nil, err
73 - }
74 - for i := range resp.Upload {
75 - multi := &resp.Upload[i]
76 - multi.Bucket = b
77 - multis = append(multis, multi)
78 - }
79 - prefixes = append(prefixes, resp.CommonPrefixes...)
80 - if !resp.IsTruncated {
81 - return multis, prefixes, nil
82 - }
83 - params["key-marker"] = []string{resp.NextKeyMarker}
84 - params["upload-id-marker"] = []string{resp.NextUploadIdMarker}
85 - attempt = attempts.Start() // Last request worked.
86 - }
87 - panic("unreachable")
88 -}
89 -
90 -// Multi returns a multipart upload handler for the provided key
91 -// inside b. If a multipart upload exists for key, it is returned,
92 -// otherwise a new multipart upload is initiated with contType and perm.
93 -func (b *Bucket) Multi(key, contType string, perm ACL, options Options) (*Multi, error) {
94 - multis, _, err := b.ListMulti(key, "")
95 - if err != nil && !hasCode(err, "NoSuchUpload") {
96 - return nil, err
97 - }
98 - for _, m := range multis {
99 - if m.Key == key {
100 - return m, nil
101 - }
102 - }
103 - return b.InitMulti(key, contType, perm, options)
104 -}
105 -
106 -// InitMulti initializes a new multipart upload at the provided
107 -// key inside b and returns a value for manipulating it.
108 -//
109 -// See http://goo.gl/XP8kL for details.
110 -func (b *Bucket) InitMulti(key string, contType string, perm ACL, options Options) (*Multi, error) {
111 - headers := map[string][]string{
112 - "Content-Type": {contType},
113 - "Content-Length": {"0"},
114 - "x-amz-acl": {string(perm)},
115 - }
116 - options.addHeaders(headers)
117 - params := map[string][]string{
118 - "uploads": {""},
119 - }
120 - req := &request{
121 - method: "POST",
122 - bucket: b.Name,
123 - path: key,
124 - headers: headers,
125 - params: params,
126 - }
127 - var err error
128 - var resp struct {
129 - UploadId string `xml:"UploadId"`
130 - }
131 - for attempt := attempts.Start(); attempt.Next(); {
132 - err = b.S3.query(req, &resp)
133 - if !shouldRetry(err) {
134 - break
135 - }
136 - }
137 - if err != nil {
138 - return nil, err
139 - }
140 - return &Multi{Bucket: b, Key: key, UploadId: resp.UploadId}, nil
141 -}
142 -
143 -func (m *Multi) PutPartCopy(n int, options CopyOptions, source string) (*CopyObjectResult, Part, error) {
144 - headers := map[string][]string{
145 - "x-amz-copy-source": {url.QueryEscape(source)},
146 - }
147 - options.addHeaders(headers)
148 - params := map[string][]string{
149 - "uploadId": {m.UploadId},
150 - "partNumber": {strconv.FormatInt(int64(n), 10)},
151 - }
152 -
153 - sourceBucket := m.Bucket.S3.Bucket(strings.TrimRight(strings.SplitAfterN(source, "/", 2)[0], "/"))
154 - sourceMeta, err := sourceBucket.Head(strings.SplitAfterN(source, "/", 2)[1], nil)
155 - if err != nil {
156 - return nil, Part{}, err
157 - }
158 -
159 - for attempt := attempts.Start(); attempt.Next(); {
160 - req := &request{
161 - method: "PUT",
162 - bucket: m.Bucket.Name,
163 - path: m.Key,
164 - headers: headers,
165 - params: params,
166 - }
167 - resp := &CopyObjectResult{}
168 - err = m.Bucket.S3.query(req, resp)
169 - if shouldRetry(err) && attempt.HasNext() {
170 - continue
171 - }
172 - if err != nil {
173 - return nil, Part{}, err
174 - }
175 - if resp.ETag == "" {
176 - return nil, Part{}, errors.New("part upload succeeded with no ETag")
177 - }
178 - return resp, Part{n, resp.ETag, sourceMeta.ContentLength}, nil
179 - }
180 - panic("unreachable")
181 -}
182 -
183 -// PutPart sends part n of the multipart upload, reading all the content from r.
184 -// Each part, except for the last one, must be at least 5MB in size.
185 -//
186 -// See http://goo.gl/pqZer for details.
187 -func (m *Multi) PutPart(n int, r io.ReadSeeker) (Part, error) {
188 - partSize, _, md5b64, err := seekerInfo(r)
189 - if err != nil {
190 - return Part{}, err
191 - }
192 - return m.putPart(n, r, partSize, md5b64)
193 -}
194 -
195 -func (m *Multi) putPart(n int, r io.ReadSeeker, partSize int64, md5b64 string) (Part, error) {
196 - headers := map[string][]string{
197 - "Content-Length": {strconv.FormatInt(partSize, 10)},
198 - "Content-MD5": {md5b64},
199 - }
200 - params := map[string][]string{
201 - "uploadId": {m.UploadId},
202 - "partNumber": {strconv.FormatInt(int64(n), 10)},
203 - }
204 - for attempt := attempts.Start(); attempt.Next(); {
205 - _, err := r.Seek(0, 0)
206 - if err != nil {
207 - return Part{}, err
208 - }
209 - req := &request{
210 - method: "PUT",
211 - bucket: m.Bucket.Name,
212 - path: m.Key,
213 - headers: headers,
214 - params: params,
215 - payload: r,
216 - }
217 - err = m.Bucket.S3.prepare(req)
218 - if err != nil {
219 - return Part{}, err
220 - }
221 - resp, err := m.Bucket.S3.run(req, nil)
222 - if shouldRetry(err) && attempt.HasNext() {
223 - continue
224 - }
225 - if err != nil {
226 - return Part{}, err
227 - }
228 - etag := resp.Header.Get("ETag")
229 - if etag == "" {
230 - return Part{}, errors.New("part upload succeeded with no ETag")
231 - }
232 - return Part{n, etag, partSize}, nil
233 - }
234 - panic("unreachable")
235 -}
236 -
237 -func seekerInfo(r io.ReadSeeker) (size int64, md5hex string, md5b64 string, err error) {
238 - _, err = r.Seek(0, 0)
239 - if err != nil {
240 - return 0, "", "", err
241 - }
242 - digest := md5.New()
243 - size, err = io.Copy(digest, r)
244 - if err != nil {
245 - return 0, "", "", err
246 - }
247 - sum := digest.Sum(nil)
248 - md5hex = hex.EncodeToString(sum)
249 - md5b64 = base64.StdEncoding.EncodeToString(sum)
250 - return size, md5hex, md5b64, nil
251 -}
252 -
253 -type Part struct {
254 - N int `xml:"PartNumber"`
255 - ETag string
256 - Size int64
257 -}
258 -
259 -type partSlice []Part
260 -
261 -func (s partSlice) Len() int { return len(s) }
262 -func (s partSlice) Less(i, j int) bool { return s[i].N < s[j].N }
263 -func (s partSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
264 -
265 -type listPartsResp struct {
266 - NextPartNumberMarker string
267 - IsTruncated bool
268 - Part []Part
269 -}
270 -
271 -// That's the default. Here just for testing.
272 -var listPartsMax = 1000
273 -
274 -// Kept for backcompatability. See the documentation for ListPartsFull
275 -func (m *Multi) ListParts() ([]Part, error) {
276 - return m.ListPartsFull(0, listPartsMax)
277 -}
278 -
279 -// ListParts returns the list of previously uploaded parts in m,
280 -// ordered by part number (Only parts with higher part numbers than
281 -// partNumberMarker will be listed). Only up to maxParts parts will be
282 -// returned.
283 -//
284 -// See http://goo.gl/ePioY for details.
285 -func (m *Multi) ListPartsFull(partNumberMarker int, maxParts int) ([]Part, error) {
286 - if maxParts > listPartsMax {
287 - maxParts = listPartsMax
288 - }
289 -
290 - params := map[string][]string{
291 - "uploadId": {m.UploadId},
292 - "max-parts": {strconv.FormatInt(int64(maxParts), 10)},
293 - "part-number-marker": {strconv.FormatInt(int64(partNumberMarker), 10)},
294 - }
295 - var parts partSlice
296 - for attempt := attempts.Start(); attempt.Next(); {
297 - req := &request{
298 - method: "GET",
299 - bucket: m.Bucket.Name,
300 - path: m.Key,
301 - params: params,
302 - }
303 - var resp listPartsResp
304 - err := m.Bucket.S3.query(req, &resp)
305 - if shouldRetry(err) && attempt.HasNext() {
306 - continue
307 - }
308 - if err != nil {
309 - return nil, err
310 - }
311 - parts = append(parts, resp.Part...)
312 - if !resp.IsTruncated {
313 - sort.Sort(parts)
314 - return parts, nil
315 - }
316 - params["part-number-marker"] = []string{resp.NextPartNumberMarker}
317 - attempt = attempts.Start() // Last request worked.
318 - }
319 - panic("unreachable")
320 -}
321 -
322 -type ReaderAtSeeker interface {
323 - io.ReaderAt
324 - io.ReadSeeker
325 -}
326 -
327 -// PutAll sends all of r via a multipart upload with parts no larger
328 -// than partSize bytes, which must be set to at least 5MB.
329 -// Parts previously uploaded are either reused if their checksum
330 -// and size match the new part, or otherwise overwritten with the
331 -// new content.
332 -// PutAll returns all the parts of m (reused or not).
333 -func (m *Multi) PutAll(r ReaderAtSeeker, partSize int64) ([]Part, error) {
334 - old, err := m.ListParts()
335 - if err != nil && !hasCode(err, "NoSuchUpload") {
336 - return nil, err
337 - }
338 - reuse := 0 // Index of next old part to consider reusing.
339 - current := 1 // Part number of latest good part handled.
340 - totalSize, err := r.Seek(0, 2)
341 - if err != nil {
342 - return nil, err
343 - }
344 - first := true // Must send at least one empty part if the file is empty.
345 - var result []Part
346 -NextSection:
347 - for offset := int64(0); offset < totalSize || first; offset += partSize {
348 - first = false
349 - if offset+partSize > totalSize {
350 - partSize = totalSize - offset
351 - }
352 - section := io.NewSectionReader(r, offset, partSize)
353 - _, md5hex, md5b64, err := seekerInfo(section)
354 - if err != nil {
355 - return nil, err
356 - }
357 - for reuse < len(old) && old[reuse].N <= current {
358 - // Looks like this part was already sent.
359 - part := &old[reuse]
360 - etag := `"` + md5hex + `"`
361 - if part.N == current && part.Size == partSize && part.ETag == etag {
362 - // Checksum matches. Reuse the old part.
363 - result = append(result, *part)
364 - current++
365 - continue NextSection
366 - }
367 - reuse++
368 - }
369 -
370 - // Part wasn't found or doesn't match. Send it.
371 - part, err := m.putPart(current, section, partSize, md5b64)
372 - if err != nil {
373 - return nil, err
374 - }
375 - result = append(result, part)
376 - current++
377 - }
378 - return result, nil
379 -}
380 -
381 -type completeUpload struct {
382 - XMLName xml.Name `xml:"CompleteMultipartUpload"`
383 - Parts completeParts `xml:"Part"`
384 -}
385 -
386 -type completePart struct {
387 - PartNumber int
388 - ETag string
389 -}
390 -
391 -type completeParts []completePart
392 -
393 -func (p completeParts) Len() int { return len(p) }
394 -func (p completeParts) Less(i, j int) bool { return p[i].PartNumber < p[j].PartNumber }
395 -func (p completeParts) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
396 -
397 -// Complete assembles the given previously uploaded parts into the
398 -// final object. This operation may take several minutes.
399 -//
400 -// See http://goo.gl/2Z7Tw for details.
401 -func (m *Multi) Complete(parts []Part) error {
402 - params := map[string][]string{
403 - "uploadId": {m.UploadId},
404 - }
405 - c := completeUpload{}
406 - for _, p := range parts {
407 - c.Parts = append(c.Parts, completePart{p.N, p.ETag})
408 - }
409 - sort.Sort(c.Parts)
410 - data, err := xml.Marshal(&c)
411 - if err != nil {
412 - return err
413 - }
414 - for attempt := attempts.Start(); attempt.Next(); {
415 - req := &request{
416 - method: "POST",
417 - bucket: m.Bucket.Name,
418 - path: m.Key,
419 - params: params,
420 - payload: bytes.NewReader(data),
421 - }
422 - err := m.Bucket.S3.query(req, nil)
423 - if shouldRetry(err) && attempt.HasNext() {
424 - continue
425 - }
426 - return err
427 - }
428 - panic("unreachable")
429 -}
430 -
431 -// Abort deletes an unifinished multipart upload and any previously
432 -// uploaded parts for it.
433 -//
434 -// After a multipart upload is aborted, no additional parts can be
435 -// uploaded using it. However, if any part uploads are currently in
436 -// progress, those part uploads might or might not succeed. As a result,
437 -// it might be necessary to abort a given multipart upload multiple
438 -// times in order to completely free all storage consumed by all parts.
439 -//
440 -// NOTE: If the described scenario happens to you, please report back to
441 -// the goamz authors with details. In the future such retrying should be
442 -// handled internally, but it's not clear what happens precisely (Is an
443 -// error returned? Is the issue completely undetectable?).
444 -//
445 -// See http://goo.gl/dnyJw for details.
446 -func (m *Multi) Abort() error {
447 - params := map[string][]string{
448 - "uploadId": {m.UploadId},
449 - }
450 - for attempt := attempts.Start(); attempt.Next(); {
451 - req := &request{
452 - method: "DELETE",
453 - bucket: m.Bucket.Name,
454 - path: m.Key,
455 - params: params,
456 - }
457 - err := m.Bucket.S3.query(req, nil)
458 - if shouldRetry(err) && attempt.HasNext() {
459 - continue
460 - }
461 - return err
462 - }
463 - panic("unreachable")
464 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/multi_test.go deleted
-425
@@ -1,425 +0,0 @@
1 -package s3_test
2 -
3 -import (
4 - "encoding/xml"
5 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
6 - "gopkg.in/check.v1"
7 - "io"
8 - "io/ioutil"
9 - "strings"
10 -)
11 -
12 -func (s *S) TestInitMulti(c *check.C) {
13 - testServer.Response(200, nil, InitMultiResultDump)
14 - b := s.s3.Bucket("sample")
15 -
16 - metadata := make(map[string][]string)
17 - metadata["key1"] = []string{"value1"}
18 - metadata["key2"] = []string{"value2"}
19 - options := s3.Options{
20 - SSE: true,
21 - Meta: metadata,
22 - ContentEncoding: "text/utf8",
23 - CacheControl: "no-cache",
24 - RedirectLocation: "http://github.com/crowdmob/goamz",
25 - ContentMD5: "0000000000000000",
26 - }
27 -
28 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, options)
29 - c.Assert(err, check.IsNil)
30 -
31 - req := testServer.WaitRequest()
32 - c.Assert(req.Method, check.Equals, "POST")
33 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
34 - c.Assert(req.Header["Content-Type"], check.DeepEquals, []string{"text/plain"})
35 - c.Assert(req.Header["X-Amz-Acl"], check.DeepEquals, []string{"private"})
36 - c.Assert(req.Form["uploads"], check.DeepEquals, []string{""})
37 -
38 - c.Assert(req.Header["X-Amz-Server-Side-Encryption"], check.DeepEquals, []string{"AES256"})
39 - c.Assert(req.Header["Content-Encoding"], check.DeepEquals, []string{"text/utf8"})
40 - c.Assert(req.Header["Cache-Control"], check.DeepEquals, []string{"no-cache"})
41 - c.Assert(req.Header["Content-Md5"], check.DeepEquals, []string{"0000000000000000"})
42 - c.Assert(req.Header["X-Amz-Website-Redirect-Location"], check.DeepEquals, []string{"http://github.com/crowdmob/goamz"})
43 - c.Assert(req.Header["X-Amz-Meta-Key1"], check.DeepEquals, []string{"value1"})
44 - c.Assert(req.Header["X-Amz-Meta-Key2"], check.DeepEquals, []string{"value2"})
45 -
46 - c.Assert(multi.UploadId, check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
47 -}
48 -
49 -func (s *S) TestMultiNoPreviousUpload(c *check.C) {
50 - // Don't retry the NoSuchUpload error.
51 - s.DisableRetries()
52 -
53 - testServer.Response(404, nil, NoSuchUploadErrorDump)
54 - testServer.Response(200, nil, InitMultiResultDump)
55 -
56 - b := s.s3.Bucket("sample")
57 -
58 - multi, err := b.Multi("multi", "text/plain", s3.Private, s3.Options{})
59 - c.Assert(err, check.IsNil)
60 -
61 - req := testServer.WaitRequest()
62 - c.Assert(req.Method, check.Equals, "GET")
63 - c.Assert(req.URL.Path, check.Equals, "/sample/")
64 - c.Assert(req.Form["uploads"], check.DeepEquals, []string{""})
65 - c.Assert(req.Form["prefix"], check.DeepEquals, []string{"multi"})
66 -
67 - req = testServer.WaitRequest()
68 - c.Assert(req.Method, check.Equals, "POST")
69 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
70 - c.Assert(req.Form["uploads"], check.DeepEquals, []string{""})
71 -
72 - c.Assert(multi.UploadId, check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
73 -}
74 -
75 -func (s *S) TestMultiReturnOld(c *check.C) {
76 - testServer.Response(200, nil, ListMultiResultDump)
77 -
78 - b := s.s3.Bucket("sample")
79 -
80 - multi, err := b.Multi("multi1", "text/plain", s3.Private, s3.Options{})
81 - c.Assert(err, check.IsNil)
82 - c.Assert(multi.Key, check.Equals, "multi1")
83 - c.Assert(multi.UploadId, check.Equals, "iUVug89pPvSswrikD")
84 -
85 - req := testServer.WaitRequest()
86 - c.Assert(req.Method, check.Equals, "GET")
87 - c.Assert(req.URL.Path, check.Equals, "/sample/")
88 - c.Assert(req.Form["uploads"], check.DeepEquals, []string{""})
89 - c.Assert(req.Form["prefix"], check.DeepEquals, []string{"multi1"})
90 -}
91 -
92 -func (s *S) TestListParts(c *check.C) {
93 - testServer.Response(200, nil, InitMultiResultDump)
94 - testServer.Response(200, nil, ListPartsResultDump1)
95 - testServer.Response(404, nil, NoSuchUploadErrorDump) // :-(
96 - testServer.Response(200, nil, ListPartsResultDump2)
97 -
98 - b := s.s3.Bucket("sample")
99 -
100 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
101 - c.Assert(err, check.IsNil)
102 -
103 - parts, err := multi.ListParts()
104 - c.Assert(err, check.IsNil)
105 - c.Assert(parts, check.HasLen, 3)
106 - c.Assert(parts[0].N, check.Equals, 1)
107 - c.Assert(parts[0].Size, check.Equals, int64(5))
108 - c.Assert(parts[0].ETag, check.Equals, `"ffc88b4ca90a355f8ddba6b2c3b2af5c"`)
109 - c.Assert(parts[1].N, check.Equals, 2)
110 - c.Assert(parts[1].Size, check.Equals, int64(5))
111 - c.Assert(parts[1].ETag, check.Equals, `"d067a0fa9dc61a6e7195ca99696b5a89"`)
112 - c.Assert(parts[2].N, check.Equals, 3)
113 - c.Assert(parts[2].Size, check.Equals, int64(5))
114 - c.Assert(parts[2].ETag, check.Equals, `"49dcd91231f801159e893fb5c6674985"`)
115 - testServer.WaitRequest()
116 - req := testServer.WaitRequest()
117 - c.Assert(req.Method, check.Equals, "GET")
118 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
119 - c.Assert(req.Form.Get("uploadId"), check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
120 - c.Assert(req.Form["max-parts"], check.DeepEquals, []string{"1000"})
121 -
122 - testServer.WaitRequest() // The internal error.
123 - req = testServer.WaitRequest()
124 - c.Assert(req.Method, check.Equals, "GET")
125 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
126 - c.Assert(req.Form.Get("uploadId"), check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
127 - c.Assert(req.Form["max-parts"], check.DeepEquals, []string{"1000"})
128 - c.Assert(req.Form["part-number-marker"], check.DeepEquals, []string{"2"})
129 -}
130 -
131 -func (s *S) TestPutPart(c *check.C) {
132 - headers := map[string]string{
133 - "ETag": `"26f90efd10d614f100252ff56d88dad8"`,
134 - }
135 - testServer.Response(200, nil, InitMultiResultDump)
136 - testServer.Response(200, headers, "")
137 -
138 - b := s.s3.Bucket("sample")
139 -
140 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
141 - c.Assert(err, check.IsNil)
142 -
143 - part, err := multi.PutPart(1, strings.NewReader("<part 1>"))
144 - c.Assert(err, check.IsNil)
145 - c.Assert(part.N, check.Equals, 1)
146 - c.Assert(part.Size, check.Equals, int64(8))
147 - c.Assert(part.ETag, check.Equals, headers["ETag"])
148 -
149 - testServer.WaitRequest()
150 - req := testServer.WaitRequest()
151 - c.Assert(req.Method, check.Equals, "PUT")
152 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
153 - c.Assert(req.Form.Get("uploadId"), check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
154 - c.Assert(req.Form["partNumber"], check.DeepEquals, []string{"1"})
155 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"8"})
156 - c.Assert(req.Header["Content-Md5"], check.DeepEquals, []string{"JvkO/RDWFPEAJS/1bYja2A=="})
157 -}
158 -
159 -func (s *S) TestPutPartCopy(c *check.C) {
160 - testServer.Response(200, nil, InitMultiResultDump)
161 - // PutPartCopy makes a Head request internally to verify access to the source object
162 - // and obtain its size
163 - testServer.Response(200, nil, "content")
164 - testServer.Response(200, nil, PutCopyResultDump)
165 -
166 - b := s.s3.Bucket("sample")
167 -
168 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
169 - c.Assert(err, check.IsNil)
170 -
171 - res, part, err := multi.PutPartCopy(1, s3.CopyOptions{}, "source-bucket/\u00FCber-fil\u00E9.jpg")
172 - c.Assert(err, check.IsNil)
173 - c.Assert(part.N, check.Equals, 1)
174 - c.Assert(part.Size, check.Equals, int64(7))
175 - c.Assert(res, check.DeepEquals, &s3.CopyObjectResult{
176 - ETag: `"9b2cf535f27731c974343645a3985328"`,
177 - LastModified: `2009-10-28T22:32:00`})
178 -
179 - // Verify the Head request
180 - req := testServer.WaitRequest()
181 - c.Assert(req.Method, check.Equals, "POST")
182 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
183 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
184 - c.Assert(err, check.IsNil)
185 -
186 - testServer.WaitRequest()
187 - req = testServer.WaitRequest()
188 - c.Assert(req.Method, check.Equals, "PUT")
189 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
190 - c.Assert(req.Form.Get("uploadId"), check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
191 - c.Assert(req.Form["partNumber"], check.DeepEquals, []string{"1"})
192 - c.Assert(req.Header["X-Amz-Copy-Source"], check.DeepEquals, []string{`source-bucket%2F%C3%BCber-fil%C3%A9.jpg`})
193 -}
194 -
195 -func readAll(r io.Reader) string {
196 - data, err := ioutil.ReadAll(r)
197 - if err != nil {
198 - panic(err)
199 - }
200 - return string(data)
201 -}
202 -
203 -func (s *S) TestPutAllNoPreviousUpload(c *check.C) {
204 - // Don't retry the NoSuchUpload error.
205 - s.DisableRetries()
206 -
207 - etag1 := map[string]string{"ETag": `"etag1"`}
208 - etag2 := map[string]string{"ETag": `"etag2"`}
209 - etag3 := map[string]string{"ETag": `"etag3"`}
210 - testServer.Response(200, nil, InitMultiResultDump)
211 - testServer.Response(404, nil, NoSuchUploadErrorDump)
212 - testServer.Response(200, etag1, "")
213 - testServer.Response(200, etag2, "")
214 - testServer.Response(200, etag3, "")
215 -
216 - b := s.s3.Bucket("sample")
217 -
218 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
219 - c.Assert(err, check.IsNil)
220 -
221 - parts, err := multi.PutAll(strings.NewReader("part1part2last"), 5)
222 - c.Assert(parts, check.HasLen, 3)
223 - c.Assert(parts[0].ETag, check.Equals, `"etag1"`)
224 - c.Assert(parts[1].ETag, check.Equals, `"etag2"`)
225 - c.Assert(parts[2].ETag, check.Equals, `"etag3"`)
226 - c.Assert(err, check.IsNil)
227 -
228 - // Init
229 - testServer.WaitRequest()
230 -
231 - // List old parts. Won't find anything.
232 - req := testServer.WaitRequest()
233 - c.Assert(req.Method, check.Equals, "GET")
234 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
235 -
236 - // Send part 1.
237 - req = testServer.WaitRequest()
238 - c.Assert(req.Method, check.Equals, "PUT")
239 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
240 - c.Assert(req.Form["partNumber"], check.DeepEquals, []string{"1"})
241 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"5"})
242 - c.Assert(readAll(req.Body), check.Equals, "part1")
243 -
244 - // Send part 2.
245 - req = testServer.WaitRequest()
246 - c.Assert(req.Method, check.Equals, "PUT")
247 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
248 - c.Assert(req.Form["partNumber"], check.DeepEquals, []string{"2"})
249 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"5"})
250 - c.Assert(readAll(req.Body), check.Equals, "part2")
251 -
252 - // Send part 3 with shorter body.
253 - req = testServer.WaitRequest()
254 - c.Assert(req.Method, check.Equals, "PUT")
255 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
256 - c.Assert(req.Form["partNumber"], check.DeepEquals, []string{"3"})
257 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"4"})
258 - c.Assert(readAll(req.Body), check.Equals, "last")
259 -}
260 -
261 -func (s *S) TestPutAllZeroSizeFile(c *check.C) {
262 - // Don't retry the NoSuchUpload error.
263 - s.DisableRetries()
264 -
265 - etag1 := map[string]string{"ETag": `"etag1"`}
266 - testServer.Response(200, nil, InitMultiResultDump)
267 - testServer.Response(404, nil, NoSuchUploadErrorDump)
268 - testServer.Response(200, etag1, "")
269 -
270 - b := s.s3.Bucket("sample")
271 -
272 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
273 - c.Assert(err, check.IsNil)
274 -
275 - // Must send at least one part, so that completing it will work.
276 - parts, err := multi.PutAll(strings.NewReader(""), 5)
277 - c.Assert(parts, check.HasLen, 1)
278 - c.Assert(parts[0].ETag, check.Equals, `"etag1"`)
279 - c.Assert(err, check.IsNil)
280 -
281 - // Init
282 - testServer.WaitRequest()
283 -
284 - // List old parts. Won't find anything.
285 - req := testServer.WaitRequest()
286 - c.Assert(req.Method, check.Equals, "GET")
287 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
288 -
289 - // Send empty part.
290 - req = testServer.WaitRequest()
291 - c.Assert(req.Method, check.Equals, "PUT")
292 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
293 - c.Assert(req.Form["partNumber"], check.DeepEquals, []string{"1"})
294 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"0"})
295 - c.Assert(readAll(req.Body), check.Equals, "")
296 -}
297 -
298 -func (s *S) TestPutAllResume(c *check.C) {
299 - etag2 := map[string]string{"ETag": `"etag2"`}
300 - testServer.Response(200, nil, InitMultiResultDump)
301 - testServer.Response(200, nil, ListPartsResultDump1)
302 - testServer.Response(200, nil, ListPartsResultDump2)
303 - testServer.Response(200, etag2, "")
304 -
305 - b := s.s3.Bucket("sample")
306 -
307 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
308 - c.Assert(err, check.IsNil)
309 -
310 - // "part1" and "part3" match the checksums in ResultDump1.
311 - // The middle one is a mismatch (it refers to "part2").
312 - parts, err := multi.PutAll(strings.NewReader("part1partXpart3"), 5)
313 - c.Assert(parts, check.HasLen, 3)
314 - c.Assert(parts[0].N, check.Equals, 1)
315 - c.Assert(parts[0].Size, check.Equals, int64(5))
316 - c.Assert(parts[0].ETag, check.Equals, `"ffc88b4ca90a355f8ddba6b2c3b2af5c"`)
317 - c.Assert(parts[1].N, check.Equals, 2)
318 - c.Assert(parts[1].Size, check.Equals, int64(5))
319 - c.Assert(parts[1].ETag, check.Equals, `"etag2"`)
320 - c.Assert(parts[2].N, check.Equals, 3)
321 - c.Assert(parts[2].Size, check.Equals, int64(5))
322 - c.Assert(parts[2].ETag, check.Equals, `"49dcd91231f801159e893fb5c6674985"`)
323 - c.Assert(err, check.IsNil)
324 -
325 - // Init
326 - testServer.WaitRequest()
327 -
328 - // List old parts, broken in two requests.
329 - for i := 0; i < 2; i++ {
330 - req := testServer.WaitRequest()
331 - c.Assert(req.Method, check.Equals, "GET")
332 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
333 - }
334 -
335 - // Send part 2, as it didn't match the checksum.
336 - req := testServer.WaitRequest()
337 - c.Assert(req.Method, check.Equals, "PUT")
338 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
339 - c.Assert(req.Form["partNumber"], check.DeepEquals, []string{"2"})
340 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"5"})
341 - c.Assert(readAll(req.Body), check.Equals, "partX")
342 -}
343 -
344 -func (s *S) TestMultiComplete(c *check.C) {
345 - testServer.Response(200, nil, InitMultiResultDump)
346 - // Note the 200 response. Completing will hold the connection on some
347 - // kind of long poll, and may return a late error even after a 200.
348 - testServer.Response(200, nil, InternalErrorDump)
349 - testServer.Response(200, nil, "")
350 -
351 - b := s.s3.Bucket("sample")
352 -
353 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
354 - c.Assert(err, check.IsNil)
355 -
356 - err = multi.Complete([]s3.Part{{2, `"ETag2"`, 32}, {1, `"ETag1"`, 64}})
357 - c.Assert(err, check.IsNil)
358 -
359 - testServer.WaitRequest()
360 - req := testServer.WaitRequest()
361 - c.Assert(req.Method, check.Equals, "POST")
362 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
363 - c.Assert(req.Form.Get("uploadId"), check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
364 -
365 - var payload struct {
366 - XMLName xml.Name
367 - Part []struct {
368 - PartNumber int
369 - ETag string
370 - }
371 - }
372 -
373 - dec := xml.NewDecoder(req.Body)
374 - err = dec.Decode(&payload)
375 - c.Assert(err, check.IsNil)
376 -
377 - c.Assert(payload.XMLName.Local, check.Equals, "CompleteMultipartUpload")
378 - c.Assert(len(payload.Part), check.Equals, 2)
379 - c.Assert(payload.Part[0].PartNumber, check.Equals, 1)
380 - c.Assert(payload.Part[0].ETag, check.Equals, `"ETag1"`)
381 - c.Assert(payload.Part[1].PartNumber, check.Equals, 2)
382 - c.Assert(payload.Part[1].ETag, check.Equals, `"ETag2"`)
383 -}
384 -
385 -func (s *S) TestMultiAbort(c *check.C) {
386 - testServer.Response(200, nil, InitMultiResultDump)
387 - testServer.Response(200, nil, "")
388 -
389 - b := s.s3.Bucket("sample")
390 -
391 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
392 - c.Assert(err, check.IsNil)
393 -
394 - err = multi.Abort()
395 - c.Assert(err, check.IsNil)
396 -
397 - testServer.WaitRequest()
398 - req := testServer.WaitRequest()
399 - c.Assert(req.Method, check.Equals, "DELETE")
400 - c.Assert(req.URL.Path, check.Equals, "/sample/multi")
401 - c.Assert(req.Form.Get("uploadId"), check.Matches, "JNbR_[A-Za-z0-9.]+QQ--")
402 -}
403 -
404 -func (s *S) TestListMulti(c *check.C) {
405 - testServer.Response(200, nil, ListMultiResultDump)
406 -
407 - b := s.s3.Bucket("sample")
408 -
409 - multis, prefixes, err := b.ListMulti("", "/")
410 - c.Assert(err, check.IsNil)
411 - c.Assert(prefixes, check.DeepEquals, []string{"a/", "b/"})
412 - c.Assert(multis, check.HasLen, 2)
413 - c.Assert(multis[0].Key, check.Equals, "multi1")
414 - c.Assert(multis[0].UploadId, check.Equals, "iUVug89pPvSswrikD")
415 - c.Assert(multis[1].Key, check.Equals, "multi2")
416 - c.Assert(multis[1].UploadId, check.Equals, "DkirwsSvPp98guVUi")
417 -
418 - req := testServer.WaitRequest()
419 - c.Assert(req.Method, check.Equals, "GET")
420 - c.Assert(req.URL.Path, check.Equals, "/sample/")
421 - c.Assert(req.Form["uploads"], check.DeepEquals, []string{""})
422 - c.Assert(req.Form["prefix"], check.DeepEquals, []string{""})
423 - c.Assert(req.Form["delimiter"], check.DeepEquals, []string{"/"})
424 - c.Assert(req.Form["max-uploads"], check.DeepEquals, []string{"1000"})
425 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/responses_test.go deleted
-239
@@ -1,239 +0,0 @@
1 -package s3_test
2 -
3 -var PutCopyResultDump = `
4 -<?xml version="1.0" encoding="UTF-8"?>
5 -<CopyObjectResult>
6 - <LastModified>2009-10-28T22:32:00</LastModified>
7 - <ETag>&quot;9b2cf535f27731c974343645a3985328&quot;</ETag>
8 -</CopyObjectResult>
9 -`
10 -
11 -var GetObjectErrorDump = `
12 -<?xml version="1.0" encoding="UTF-8"?>
13 -<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message>
14 -<BucketName>non-existent-bucket</BucketName><RequestId>3F1B667FAD71C3D8</RequestId>
15 -<HostId>L4ee/zrm1irFXY5F45fKXIRdOf9ktsKY/8TDVawuMK2jWRb1RF84i1uBzkdNqS5D</HostId></Error>
16 -`
17 -
18 -var GetListResultDump1 = `
19 -<?xml version="1.0" encoding="UTF-8"?>
20 -<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
21 - <Name>quotes</Name>
22 - <Prefix>N</Prefix>
23 - <IsTruncated>false</IsTruncated>
24 - <Contents>
25 - <Key>Nelson</Key>
26 - <LastModified>2006-01-01T12:00:00.000Z</LastModified>
27 - <ETag>&quot;828ef3fdfa96f00ad9f27c383fc9ac7f&quot;</ETag>
28 - <Size>5</Size>
29 - <StorageClass>STANDARD</StorageClass>
30 - <Owner>
31 - <ID>bcaf161ca5fb16fd081034f</ID>
32 - <DisplayName>webfile</DisplayName>
33 - </Owner>
34 - </Contents>
35 - <Contents>
36 - <Key>Neo</Key>
37 - <LastModified>2006-01-01T12:00:00.000Z</LastModified>
38 - <ETag>&quot;828ef3fdfa96f00ad9f27c383fc9ac7f&quot;</ETag>
39 - <Size>4</Size>
40 - <StorageClass>STANDARD</StorageClass>
41 - <Owner>
42 - <ID>bcaf1ffd86a5fb16fd081034f</ID>
43 - <DisplayName>webfile</DisplayName>
44 - </Owner>
45 - </Contents>
46 -</ListBucketResult>
47 -`
48 -
49 -var GetListResultDump2 = `
50 -<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
51 - <Name>example-bucket</Name>
52 - <Prefix>photos/2006/</Prefix>
53 - <Marker>some-marker</Marker>
54 - <MaxKeys>1000</MaxKeys>
55 - <Delimiter>/</Delimiter>
56 - <IsTruncated>false</IsTruncated>
57 -
58 - <CommonPrefixes>
59 - <Prefix>photos/2006/feb/</Prefix>
60 - </CommonPrefixes>
61 - <CommonPrefixes>
62 - <Prefix>photos/2006/jan/</Prefix>
63 - </CommonPrefixes>
64 -</ListBucketResult>
65 -`
66 -
67 -var InitMultiResultDump = `
68 -<?xml version="1.0" encoding="UTF-8"?>
69 -<InitiateMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
70 - <Bucket>sample</Bucket>
71 - <Key>multi</Key>
72 - <UploadId>JNbR_cMdwnGiD12jKAd6WK2PUkfj2VxA7i4nCwjE6t71nI9Tl3eVDPFlU0nOixhftH7I17ZPGkV3QA.l7ZD.QQ--</UploadId>
73 -</InitiateMultipartUploadResult>
74 -`
75 -
76 -var ListPartsResultDump1 = `
77 -<?xml version="1.0" encoding="UTF-8"?>
78 -<ListPartsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
79 - <Bucket>sample</Bucket>
80 - <Key>multi</Key>
81 - <UploadId>JNbR_cMdwnGiD12jKAd6WK2PUkfj2VxA7i4nCwjE6t71nI9Tl3eVDPFlU0nOixhftH7I17ZPGkV3QA.l7ZD.QQ--</UploadId>
82 - <Initiator>
83 - <ID>bb5c0f63b0b25f2d099c</ID>
84 - <DisplayName>joe</DisplayName>
85 - </Initiator>
86 - <Owner>
87 - <ID>bb5c0f63b0b25f2d099c</ID>
88 - <DisplayName>joe</DisplayName>
89 - </Owner>
90 - <StorageClass>STANDARD</StorageClass>
91 - <PartNumberMarker>0</PartNumberMarker>
92 - <NextPartNumberMarker>2</NextPartNumberMarker>
93 - <MaxParts>2</MaxParts>
94 - <IsTruncated>true</IsTruncated>
95 - <Part>
96 - <PartNumber>1</PartNumber>
97 - <LastModified>2013-01-30T13:45:51.000Z</LastModified>
98 - <ETag>&quot;ffc88b4ca90a355f8ddba6b2c3b2af5c&quot;</ETag>
99 - <Size>5</Size>
100 - </Part>
101 - <Part>
102 - <PartNumber>2</PartNumber>
103 - <LastModified>2013-01-30T13:45:52.000Z</LastModified>
104 - <ETag>&quot;d067a0fa9dc61a6e7195ca99696b5a89&quot;</ETag>
105 - <Size>5</Size>
106 - </Part>
107 -</ListPartsResult>
108 -`
109 -
110 -var ListPartsResultDump2 = `
111 -<?xml version="1.0" encoding="UTF-8"?>
112 -<ListPartsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
113 - <Bucket>sample</Bucket>
114 - <Key>multi</Key>
115 - <UploadId>JNbR_cMdwnGiD12jKAd6WK2PUkfj2VxA7i4nCwjE6t71nI9Tl3eVDPFlU0nOixhftH7I17ZPGkV3QA.l7ZD.QQ--</UploadId>
116 - <Initiator>
117 - <ID>bb5c0f63b0b25f2d099c</ID>
118 - <DisplayName>joe</DisplayName>
119 - </Initiator>
120 - <Owner>
121 - <ID>bb5c0f63b0b25f2d099c</ID>
122 - <DisplayName>joe</DisplayName>
123 - </Owner>
124 - <StorageClass>STANDARD</StorageClass>
125 - <PartNumberMarker>2</PartNumberMarker>
126 - <NextPartNumberMarker>3</NextPartNumberMarker>
127 - <MaxParts>2</MaxParts>
128 - <IsTruncated>false</IsTruncated>
129 - <Part>
130 - <PartNumber>3</PartNumber>
131 - <LastModified>2013-01-30T13:46:50.000Z</LastModified>
132 - <ETag>&quot;49dcd91231f801159e893fb5c6674985&quot;</ETag>
133 - <Size>5</Size>
134 - </Part>
135 -</ListPartsResult>
136 -`
137 -
138 -var ListMultiResultDump = `
139 -<?xml version="1.0"?>
140 -<ListMultipartUploadsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
141 - <Bucket>goamz-test-bucket-us-east-1-akiajk3wyewhctyqbf7a</Bucket>
142 - <KeyMarker/>
143 - <UploadIdMarker/>
144 - <NextKeyMarker>multi1</NextKeyMarker>
145 - <NextUploadIdMarker>iUVug89pPvSswrikD72p8uO62EzhNtpDxRmwC5WSiWDdK9SfzmDqe3xpP1kMWimyimSnz4uzFc3waVM5ufrKYQ--</NextUploadIdMarker>
146 - <Delimiter>/</Delimiter>
147 - <MaxUploads>1000</MaxUploads>
148 - <IsTruncated>false</IsTruncated>
149 - <Upload>
150 - <Key>multi1</Key>
151 - <UploadId>iUVug89pPvSswrikD</UploadId>
152 - <Initiator>
153 - <ID>bb5c0f63b0b25f2d0</ID>
154 - <DisplayName>gustavoniemeyer</DisplayName>
155 - </Initiator>
156 - <Owner>
157 - <ID>bb5c0f63b0b25f2d0</ID>
158 - <DisplayName>gustavoniemeyer</DisplayName>
159 - </Owner>
160 - <StorageClass>STANDARD</StorageClass>
161 - <Initiated>2013-01-30T18:15:47.000Z</Initiated>
162 - </Upload>
163 - <Upload>
164 - <Key>multi2</Key>
165 - <UploadId>DkirwsSvPp98guVUi</UploadId>
166 - <Initiator>
167 - <ID>bb5c0f63b0b25f2d0</ID>
168 - <DisplayName>joe</DisplayName>
169 - </Initiator>
170 - <Owner>
171 - <ID>bb5c0f63b0b25f2d0</ID>
172 - <DisplayName>joe</DisplayName>
173 - </Owner>
174 - <StorageClass>STANDARD</StorageClass>
175 - <Initiated>2013-01-30T18:15:47.000Z</Initiated>
176 - </Upload>
177 - <CommonPrefixes>
178 - <Prefix>a/</Prefix>
179 - </CommonPrefixes>
180 - <CommonPrefixes>
181 - <Prefix>b/</Prefix>
182 - </CommonPrefixes>
183 -</ListMultipartUploadsResult>
184 -`
185 -
186 -var NoSuchUploadErrorDump = `
187 -<?xml version="1.0" encoding="UTF-8"?>
188 -<Error>
189 - <Code>NoSuchUpload</Code>
190 - <Message>Not relevant</Message>
191 - <BucketName>sample</BucketName>
192 - <RequestId>3F1B667FAD71C3D8</RequestId>
193 - <HostId>kjhwqk</HostId>
194 -</Error>
195 -`
196 -
197 -var InternalErrorDump = `
198 -<?xml version="1.0" encoding="UTF-8"?>
199 -<Error>
200 - <Code>InternalError</Code>
201 - <Message>Not relevant</Message>
202 - <BucketName>sample</BucketName>
203 - <RequestId>3F1B667FAD71C3D8</RequestId>
204 - <HostId>kjhwqk</HostId>
205 -</Error>
206 -`
207 -
208 -var GetServiceDump = `
209 -<?xml version="1.0" encoding="UTF-8"?>
210 -<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
211 - <Owner>
212 - <ID>bcaf1ffd86f461ca5fb16fd081034f</ID>
213 - <DisplayName>webfile</DisplayName>
214 - </Owner>
215 - <Buckets>
216 - <Bucket>
217 - <Name>quotes</Name>
218 - <CreationDate>2006-02-03T16:45:09.000Z</CreationDate>
219 - </Bucket>
220 - <Bucket>
221 - <Name>samples</Name>
222 - <CreationDate>2006-02-03T16:41:58.000Z</CreationDate>
223 - </Bucket>
224 - </Buckets>
225 -</ListAllMyBucketsResult>
226 -`
227 -
228 -var GetLocationUsStandard = `
229 -<?xml version="1.0" encoding="UTF-8"?>
230 -<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>
231 -`
232 -
233 -var GetLocationUsWest1 = `
234 -<?xml version="1.0" encoding="UTF-8"?>
235 -<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">us-west-1</LocationConstraint>
236 -`
237 -
238 -var BucketWebsiteConfigurationDump = `<?xml version="1.0" encoding="UTF-8"?>
239 -<WebsiteConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><RedirectAllRequestsTo><HostName>example.com</HostName></RedirectAllRequestsTo></WebsiteConfiguration>`
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/s3.go deleted
-1248
@@ -1,1248 +0,0 @@
1 -//
2 -// goamz - Go packages to interact with the Amazon Web Services.
3 -//
4 -// https://wiki.ubuntu.com/goamz
5 -//
6 -// Copyright (c) 2011 Canonical Ltd.
7 -//
8 -// Written by Gustavo Niemeyer <gustavo.niemeyer@canonical.com>
9 -//
10 -
11 -package s3
12 -
13 -import (
14 - "bytes"
15 - "crypto/hmac"
16 - "crypto/md5"
17 - "crypto/sha1"
18 - "encoding/base64"
19 - "encoding/xml"
20 - "fmt"
21 - "io"
22 - "io/ioutil"
23 - "log"
24 - "net"
25 - "net/http"
26 - "net/http/httputil"
27 - "net/url"
28 - "strconv"
29 - "strings"
30 - "time"
31 -
32 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
33 -)
34 -
35 -const debug = false
36 -
37 -// The S3 type encapsulates operations with an S3 region.
38 -type S3 struct {
39 - aws.Auth
40 - aws.Region
41 - ConnectTimeout time.Duration
42 - ReadTimeout time.Duration
43 - Signature int
44 - private byte // Reserve the right of using private data.
45 -}
46 -
47 -// The Bucket type encapsulates operations with an S3 bucket.
48 -type Bucket struct {
49 - *S3
50 - Name string
51 -}
52 -
53 -// The Owner type represents the owner of the object in an S3 bucket.
54 -type Owner struct {
55 - ID string
56 - DisplayName string
57 -}
58 -
59 -// Fold options into an Options struct
60 -//
61 -type Options struct {
62 - SSE bool
63 - SSECustomerAlgorithm string
64 - SSECustomerKey string
65 - SSECustomerKeyMD5 string
66 - Meta map[string][]string
67 - ContentEncoding string
68 - CacheControl string
69 - RedirectLocation string
70 - ContentMD5 string
71 - ContentDisposition string
72 - Range string
73 - // What else?
74 - //// The following become headers so they are []strings rather than strings... I think
75 - // x-amz-storage-class []string
76 -}
77 -
78 -type CopyOptions struct {
79 - Options
80 - CopySourceOptions string
81 - MetadataDirective string
82 - ContentType string
83 -}
84 -
85 -// CopyObjectResult is the output from a Copy request
86 -type CopyObjectResult struct {
87 - ETag string
88 - LastModified string
89 -}
90 -
91 -var attempts = aws.AttemptStrategy{
92 - Min: 5,
93 - Total: 5 * time.Second,
94 - Delay: 200 * time.Millisecond,
95 -}
96 -
97 -// New creates a new S3.
98 -func New(auth aws.Auth, region aws.Region) *S3 {
99 - return &S3{auth, region, 0, 0, 0, aws.V2Signature}
100 -}
101 -
102 -// Bucket returns a Bucket with the given name.
103 -func (s3 *S3) Bucket(name string) *Bucket {
104 - if s3.Region.S3BucketEndpoint != "" || s3.Region.S3LowercaseBucket {
105 - name = strings.ToLower(name)
106 - }
107 - return &Bucket{s3, name}
108 -}
109 -
110 -type BucketInfo struct {
111 - Name string
112 - CreationDate string
113 -}
114 -
115 -type GetServiceResp struct {
116 - Owner Owner
117 - Buckets []BucketInfo `xml:">Bucket"`
118 -}
119 -
120 -// GetService gets a list of all buckets owned by an account.
121 -//
122 -// See http://goo.gl/wbHkGj for details.
123 -func (s3 *S3) GetService() (*GetServiceResp, error) {
124 - bucket := s3.Bucket("")
125 -
126 - r, err := bucket.Get("")
127 - if err != nil {
128 - return nil, err
129 - }
130 -
131 - // Parse the XML response.
132 - var resp GetServiceResp
133 - if err = xml.Unmarshal(r, &resp); err != nil {
134 - return nil, err
135 - }
136 -
137 - return &resp, nil
138 -}
139 -
140 -var createBucketConfiguration = `<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
141 - <LocationConstraint>%s</LocationConstraint>
142 -</CreateBucketConfiguration>`
143 -
144 -// locationConstraint returns an io.Reader specifying a LocationConstraint if
145 -// required for the region.
146 -//
147 -// See http://goo.gl/bh9Kq for details.
148 -func (s3 *S3) locationConstraint() io.Reader {
149 - constraint := ""
150 - if s3.Region.S3LocationConstraint {
151 - constraint = fmt.Sprintf(createBucketConfiguration, s3.Region.Name)
152 - }
153 - return strings.NewReader(constraint)
154 -}
155 -
156 -type ACL string
157 -
158 -const (
159 - Private = ACL("private")
160 - PublicRead = ACL("public-read")
161 - PublicReadWrite = ACL("public-read-write")
162 - AuthenticatedRead = ACL("authenticated-read")
163 - BucketOwnerRead = ACL("bucket-owner-read")
164 - BucketOwnerFull = ACL("bucket-owner-full-control")
165 -)
166 -
167 -// PutBucket creates a new bucket.
168 -//
169 -// See http://goo.gl/ndjnR for details.
170 -func (b *Bucket) PutBucket(perm ACL) error {
171 - headers := map[string][]string{
172 - "x-amz-acl": {string(perm)},
173 - }
174 - req := &request{
175 - method: "PUT",
176 - bucket: b.Name,
177 - path: "/",
178 - headers: headers,
179 - payload: b.locationConstraint(),
180 - }
181 - return b.S3.query(req, nil)
182 -}
183 -
184 -// DelBucket removes an existing S3 bucket. All objects in the bucket must
185 -// be removed before the bucket itself can be removed.
186 -//
187 -// See http://goo.gl/GoBrY for details.
188 -func (b *Bucket) DelBucket() (err error) {
189 - req := &request{
190 - method: "DELETE",
191 - bucket: b.Name,
192 - path: "/",
193 - }
194 - for attempt := attempts.Start(); attempt.Next(); {
195 - err = b.S3.query(req, nil)
196 - if !shouldRetry(err) {
197 - break
198 - }
199 - }
200 - return err
201 -}
202 -
203 -// Get retrieves an object from an S3 bucket.
204 -//
205 -// See http://goo.gl/isCO7 for details.
206 -func (b *Bucket) Get(path string) (data []byte, err error) {
207 - body, err := b.GetReader(path)
208 - if err != nil {
209 - return nil, err
210 - }
211 - data, err = ioutil.ReadAll(body)
212 - body.Close()
213 - return data, err
214 -}
215 -
216 -// GetReader retrieves an object from an S3 bucket,
217 -// returning the body of the HTTP response.
218 -// It is the caller's responsibility to call Close on rc when
219 -// finished reading.
220 -func (b *Bucket) GetReader(path string) (rc io.ReadCloser, err error) {
221 - resp, err := b.GetResponse(path)
222 - if resp != nil {
223 - return resp.Body, err
224 - }
225 - return nil, err
226 -}
227 -
228 -// GetResponse retrieves an object from an S3 bucket,
229 -// returning the HTTP response.
230 -// It is the caller's responsibility to call Close on rc when
231 -// finished reading
232 -func (b *Bucket) GetResponse(path string) (resp *http.Response, err error) {
233 - return b.GetResponseWithHeaders(path, make(http.Header))
234 -}
235 -
236 -// GetReaderWithHeaders retrieves an object from an S3 bucket
237 -// Accepts custom headers to be sent as the second parameter
238 -// returning the body of the HTTP response.
239 -// It is the caller's responsibility to call Close on rc when
240 -// finished reading
241 -func (b *Bucket) GetResponseWithHeaders(path string, headers map[string][]string) (resp *http.Response, err error) {
242 - req := &request{
243 - bucket: b.Name,
244 - path: path,
245 - headers: headers,
246 - }
247 - err = b.S3.prepare(req)
248 - if err != nil {
249 - return nil, err
250 - }
251 - for attempt := attempts.Start(); attempt.Next(); {
252 - resp, err := b.S3.run(req, nil)
253 - if shouldRetry(err) && attempt.HasNext() {
254 - continue
255 - }
256 - if err != nil {
257 - return nil, err
258 - }
259 - return resp, nil
260 - }
261 - panic("unreachable")
262 -}
263 -
264 -// Exists checks whether or not an object exists on an S3 bucket using a HEAD request.
265 -func (b *Bucket) Exists(path string) (exists bool, err error) {
266 - req := &request{
267 - method: "HEAD",
268 - bucket: b.Name,
269 - path: path,
270 - }
271 - err = b.S3.prepare(req)
272 - if err != nil {
273 - return
274 - }
275 - for attempt := attempts.Start(); attempt.Next(); {
276 - resp, err := b.S3.run(req, nil)
277 -
278 - if shouldRetry(err) && attempt.HasNext() {
279 - continue
280 - }
281 -
282 - if err != nil {
283 - // We can treat a 403 or 404 as non existance
284 - if e, ok := err.(*Error); ok && (e.StatusCode == 403 || e.StatusCode == 404) {
285 - return false, nil
286 - }
287 - return false, err
288 - }
289 -
290 - if resp.StatusCode/100 == 2 {
291 - exists = true
292 - }
293 - if resp.Body != nil {
294 - resp.Body.Close()
295 - }
296 - return exists, err
297 - }
298 - return false, fmt.Errorf("S3 Currently Unreachable")
299 -}
300 -
301 -// Head HEADs an object in the S3 bucket, returns the response with
302 -// no body see http://bit.ly/17K1ylI
303 -func (b *Bucket) Head(path string, headers map[string][]string) (*http.Response, error) {
304 - req := &request{
305 - method: "HEAD",
306 - bucket: b.Name,
307 - path: path,
308 - headers: headers,
309 - }
310 - err := b.S3.prepare(req)
311 - if err != nil {
312 - return nil, err
313 - }
314 -
315 - for attempt := attempts.Start(); attempt.Next(); {
316 - resp, err := b.S3.run(req, nil)
317 - if shouldRetry(err) && attempt.HasNext() {
318 - continue
319 - }
320 - if err != nil {
321 - return nil, err
322 - }
323 - return resp, err
324 - }
325 - return nil, fmt.Errorf("S3 Currently Unreachable")
326 -}
327 -
328 -// Put inserts an object into the S3 bucket.
329 -//
330 -// See http://goo.gl/FEBPD for details.
331 -func (b *Bucket) Put(path string, data []byte, contType string, perm ACL, options Options) error {
332 - body := bytes.NewBuffer(data)
333 - return b.PutReader(path, body, int64(len(data)), contType, perm, options)
334 -}
335 -
336 -// PutCopy puts a copy of an object given by the key path into bucket b using b.Path as the target key
337 -func (b *Bucket) PutCopy(path string, perm ACL, options CopyOptions, source string) (*CopyObjectResult, error) {
338 - headers := map[string][]string{
339 - "x-amz-acl": {string(perm)},
340 - "x-amz-copy-source": {url.QueryEscape(source)},
341 - }
342 - options.addHeaders(headers)
343 - req := &request{
344 - method: "PUT",
345 - bucket: b.Name,
346 - path: path,
347 - headers: headers,
348 - }
349 - resp := &CopyObjectResult{}
350 - err := b.S3.query(req, resp)
351 - if err != nil {
352 - return resp, err
353 - }
354 - return resp, nil
355 -}
356 -
357 -// PutReader inserts an object into the S3 bucket by consuming data
358 -// from r until EOF.
359 -func (b *Bucket) PutReader(path string, r io.Reader, length int64, contType string, perm ACL, options Options) error {
360 - headers := map[string][]string{
361 - "Content-Length": {strconv.FormatInt(length, 10)},
362 - "Content-Type": {contType},
363 - "x-amz-acl": {string(perm)},
364 - }
365 - options.addHeaders(headers)
366 - req := &request{
367 - method: "PUT",
368 - bucket: b.Name,
369 - path: path,
370 - headers: headers,
371 - payload: r,
372 - }
373 - return b.S3.query(req, nil)
374 -}
375 -
376 -// addHeaders adds o's specified fields to headers
377 -func (o Options) addHeaders(headers map[string][]string) {
378 - if o.SSE {
379 - headers["x-amz-server-side-encryption"] = []string{"AES256"}
380 - } else if len(o.SSECustomerAlgorithm) != 0 && len(o.SSECustomerKey) != 0 && len(o.SSECustomerKeyMD5) != 0 {
381 - // Amazon-managed keys and customer-managed keys are mutually exclusive
382 - headers["x-amz-server-side-encryption-customer-algorithm"] = []string{o.SSECustomerAlgorithm}
383 - headers["x-amz-server-side-encryption-customer-key"] = []string{o.SSECustomerKey}
384 - headers["x-amz-server-side-encryption-customer-key-MD5"] = []string{o.SSECustomerKeyMD5}
385 - }
386 - if len(o.Range) != 0 {
387 - headers["Range"] = []string{o.Range}
388 - }
389 - if len(o.ContentEncoding) != 0 {
390 - headers["Content-Encoding"] = []string{o.ContentEncoding}
391 - }
392 - if len(o.CacheControl) != 0 {
393 - headers["Cache-Control"] = []string{o.CacheControl}
394 - }
395 - if len(o.ContentMD5) != 0 {
396 - headers["Content-MD5"] = []string{o.ContentMD5}
397 - }
398 - if len(o.RedirectLocation) != 0 {
399 - headers["x-amz-website-redirect-location"] = []string{o.RedirectLocation}
400 - }
401 - if len(o.ContentDisposition) != 0 {
402 - headers["Content-Disposition"] = []string{o.ContentDisposition}
403 - }
404 - for k, v := range o.Meta {
405 - headers["x-amz-meta-"+k] = v
406 - }
407 -}
408 -
409 -// addHeaders adds o's specified fields to headers
410 -func (o CopyOptions) addHeaders(headers map[string][]string) {
411 - o.Options.addHeaders(headers)
412 - if len(o.MetadataDirective) != 0 {
413 - headers["x-amz-metadata-directive"] = []string{o.MetadataDirective}
414 - }
415 - if len(o.CopySourceOptions) != 0 {
416 - headers["x-amz-copy-source-range"] = []string{o.CopySourceOptions}
417 - }
418 - if len(o.ContentType) != 0 {
419 - headers["Content-Type"] = []string{o.ContentType}
420 - }
421 -}
422 -
423 -func makeXmlBuffer(doc []byte) *bytes.Buffer {
424 - buf := new(bytes.Buffer)
425 - buf.WriteString(xml.Header)
426 - buf.Write(doc)
427 - return buf
428 -}
429 -
430 -type IndexDocument struct {
431 - Suffix string `xml:"Suffix"`
432 -}
433 -
434 -type ErrorDocument struct {
435 - Key string `xml:"Key"`
436 -}
437 -
438 -type RoutingRule struct {
439 - ConditionKeyPrefixEquals string `xml:"Condition>KeyPrefixEquals"`
440 - RedirectReplaceKeyPrefixWith string `xml:"Redirect>ReplaceKeyPrefixWith,omitempty"`
441 - RedirectReplaceKeyWith string `xml:"Redirect>ReplaceKeyWith,omitempty"`
442 -}
443 -
444 -type RedirectAllRequestsTo struct {
445 - HostName string `xml:"HostName"`
446 - Protocol string `xml:"Protocol,omitempty"`
447 -}
448 -
449 -type WebsiteConfiguration struct {
450 - XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ WebsiteConfiguration"`
451 - IndexDocument *IndexDocument `xml:"IndexDocument,omitempty"`
452 - ErrorDocument *ErrorDocument `xml:"ErrorDocument,omitempty"`
453 - RoutingRules *[]RoutingRule `xml:"RoutingRules>RoutingRule,omitempty"`
454 - RedirectAllRequestsTo *RedirectAllRequestsTo `xml:"RedirectAllRequestsTo,omitempty"`
455 -}
456 -
457 -// PutBucketWebsite configures a bucket as a website.
458 -//
459 -// See http://goo.gl/TpRlUy for details.
460 -func (b *Bucket) PutBucketWebsite(configuration WebsiteConfiguration) error {
461 - doc, err := xml.Marshal(configuration)
462 - if err != nil {
463 - return err
464 - }
465 -
466 - buf := makeXmlBuffer(doc)
467 -
468 - return b.PutBucketSubresource("website", buf, int64(buf.Len()))
469 -}
470 -
471 -func (b *Bucket) PutBucketSubresource(subresource string, r io.Reader, length int64) error {
472 - headers := map[string][]string{
473 - "Content-Length": {strconv.FormatInt(length, 10)},
474 - }
475 - req := &request{
476 - path: "/",
477 - method: "PUT",
478 - bucket: b.Name,
479 - headers: headers,
480 - payload: r,
481 - params: url.Values{subresource: {""}},
482 - }
483 -
484 - return b.S3.query(req, nil)
485 -}
486 -
487 -// Del removes an object from the S3 bucket.
488 -//
489 -// See http://goo.gl/APeTt for details.
490 -func (b *Bucket) Del(path string) error {
491 - req := &request{
492 - method: "DELETE",
493 - bucket: b.Name,
494 - path: path,
495 - }
496 - return b.S3.query(req, nil)
497 -}
498 -
499 -type Delete struct {
500 - Quiet bool `xml:"Quiet,omitempty"`
501 - Objects []Object `xml:"Object"`
502 -}
503 -
504 -type Object struct {
505 - Key string `xml:"Key"`
506 - VersionId string `xml:"VersionId,omitempty"`
507 -}
508 -
509 -// DelMulti removes up to 1000 objects from the S3 bucket.
510 -//
511 -// See http://goo.gl/jx6cWK for details.
512 -func (b *Bucket) DelMulti(objects Delete) error {
513 - doc, err := xml.Marshal(objects)
514 - if err != nil {
515 - return err
516 - }
517 -
518 - buf := makeXmlBuffer(doc)
519 - digest := md5.New()
520 - size, err := digest.Write(buf.Bytes())
521 - if err != nil {
522 - return err
523 - }
524 -
525 - headers := map[string][]string{
526 - "Content-Length": {strconv.FormatInt(int64(size), 10)},
527 - "Content-MD5": {base64.StdEncoding.EncodeToString(digest.Sum(nil))},
528 - "Content-Type": {"text/xml"},
529 - }
530 - req := &request{
531 - path: "/",
532 - method: "POST",
533 - params: url.Values{"delete": {""}},
534 - bucket: b.Name,
535 - headers: headers,
536 - payload: buf,
537 - }
538 -
539 - return b.S3.query(req, nil)
540 -}
541 -
542 -// The ListResp type holds the results of a List bucket operation.
543 -type ListResp struct {
544 - Name string
545 - Prefix string
546 - Delimiter string
547 - Marker string
548 - MaxKeys int
549 - // IsTruncated is true if the results have been truncated because
550 - // there are more keys and prefixes than can fit in MaxKeys.
551 - // N.B. this is the opposite sense to that documented (incorrectly) in
552 - // http://goo.gl/YjQTc
553 - IsTruncated bool
554 - Contents []Key
555 - CommonPrefixes []string `xml:">Prefix"`
556 - // if IsTruncated is true, pass NextMarker as marker argument to List()
557 - // to get the next set of keys
558 - NextMarker string
559 -}
560 -
561 -// The Key type represents an item stored in an S3 bucket.
562 -type Key struct {
563 - Key string
564 - LastModified string
565 - Size int64
566 - // ETag gives the hex-encoded MD5 sum of the contents,
567 - // surrounded with double-quotes.
568 - ETag string
569 - StorageClass string
570 - Owner Owner
571 -}
572 -
573 -// List returns information about objects in an S3 bucket.
574 -//
575 -// The prefix parameter limits the response to keys that begin with the
576 -// specified prefix.
577 -//
578 -// The delim parameter causes the response to group all of the keys that
579 -// share a common prefix up to the next delimiter in a single entry within
580 -// the CommonPrefixes field. You can use delimiters to separate a bucket
581 -// into different groupings of keys, similar to how folders would work.
582 -//
583 -// The marker parameter specifies the key to start with when listing objects
584 -// in a bucket. Amazon S3 lists objects in alphabetical order and
585 -// will return keys alphabetically greater than the marker.
586 -//
587 -// The max parameter specifies how many keys + common prefixes to return in
588 -// the response. The default is 1000.
589 -//
590 -// For example, given these keys in a bucket:
591 -//
592 -// index.html
593 -// index2.html
594 -// photos/2006/January/sample.jpg
595 -// photos/2006/February/sample2.jpg
596 -// photos/2006/February/sample3.jpg
597 -// photos/2006/February/sample4.jpg
598 -//
599 -// Listing this bucket with delimiter set to "/" would yield the
600 -// following result:
601 -//
602 -// &ListResp{
603 -// Name: "sample-bucket",
604 -// MaxKeys: 1000,
605 -// Delimiter: "/",
606 -// Contents: []Key{
607 -// {Key: "index.html", "index2.html"},
608 -// },
609 -// CommonPrefixes: []string{
610 -// "photos/",
611 -// },
612 -// }
613 -//
614 -// Listing the same bucket with delimiter set to "/" and prefix set to
615 -// "photos/2006/" would yield the following result:
616 -//
617 -// &ListResp{
618 -// Name: "sample-bucket",
619 -// MaxKeys: 1000,
620 -// Delimiter: "/",
621 -// Prefix: "photos/2006/",
622 -// CommonPrefixes: []string{
623 -// "photos/2006/February/",
624 -// "photos/2006/January/",
625 -// },
626 -// }
627 -//
628 -// See http://goo.gl/YjQTc for details.
629 -func (b *Bucket) List(prefix, delim, marker string, max int) (result *ListResp, err error) {
630 - params := map[string][]string{
631 - "prefix": {prefix},
632 - "delimiter": {delim},
633 - "marker": {marker},
634 - }
635 - if max != 0 {
636 - params["max-keys"] = []string{strconv.FormatInt(int64(max), 10)}
637 - }
638 - req := &request{
639 - bucket: b.Name,
640 - params: params,
641 - }
642 - result = &ListResp{}
643 - for attempt := attempts.Start(); attempt.Next(); {
644 - err = b.S3.query(req, result)
645 - if !shouldRetry(err) {
646 - break
647 - }
648 - }
649 - if err != nil {
650 - return nil, err
651 - }
652 - // if NextMarker is not returned, it should be set to the name of last key,
653 - // so let's do it so that each caller doesn't have to
654 - if result.IsTruncated && result.NextMarker == "" {
655 - n := len(result.Contents)
656 - if n > 0 {
657 - result.NextMarker = result.Contents[n-1].Key
658 - }
659 - }
660 - return result, nil
661 -}
662 -
663 -// The VersionsResp type holds the results of a list bucket Versions operation.
664 -type VersionsResp struct {
665 - Name string
666 - Prefix string
667 - KeyMarker string
668 - VersionIdMarker string
669 - MaxKeys int
670 - Delimiter string
671 - IsTruncated bool
672 - Versions []Version `xml:"Version"`
673 - CommonPrefixes []string `xml:">Prefix"`
674 -}
675 -
676 -// The Version type represents an object version stored in an S3 bucket.
677 -type Version struct {
678 - Key string
679 - VersionId string
680 - IsLatest bool
681 - LastModified string
682 - // ETag gives the hex-encoded MD5 sum of the contents,
683 - // surrounded with double-quotes.
684 - ETag string
685 - Size int64
686 - Owner Owner
687 - StorageClass string
688 -}
689 -
690 -func (b *Bucket) Versions(prefix, delim, keyMarker string, versionIdMarker string, max int) (result *VersionsResp, err error) {
691 - params := map[string][]string{
692 - "versions": {""},
693 - "prefix": {prefix},
694 - "delimiter": {delim},
695 - }
696 -
697 - if len(versionIdMarker) != 0 {
698 - params["version-id-marker"] = []string{versionIdMarker}
699 - }
700 - if len(keyMarker) != 0 {
701 - params["key-marker"] = []string{keyMarker}
702 - }
703 -
704 - if max != 0 {
705 - params["max-keys"] = []string{strconv.FormatInt(int64(max), 10)}
706 - }
707 - req := &request{
708 - bucket: b.Name,
709 - params: params,
710 - }
711 - result = &VersionsResp{}
712 - for attempt := attempts.Start(); attempt.Next(); {
713 - err = b.S3.query(req, result)
714 - if !shouldRetry(err) {
715 - break
716 - }
717 - }
718 - if err != nil {
719 - return nil, err
720 - }
721 - return result, nil
722 -}
723 -
724 -type GetLocationResp struct {
725 - Location string `xml:",innerxml"`
726 -}
727 -
728 -func (b *Bucket) Location() (string, error) {
729 - r, err := b.Get("/?location")
730 - if err != nil {
731 - return "", err
732 - }
733 -
734 - // Parse the XML response.
735 - var resp GetLocationResp
736 - if err = xml.Unmarshal(r, &resp); err != nil {
737 - return "", err
738 - }
739 -
740 - if resp.Location == "" {
741 - return "us-east-1", nil
742 - } else {
743 - return resp.Location, nil
744 - }
745 -}
746 -
747 -// URL returns a non-signed URL that allows retriving the
748 -// object at path. It only works if the object is publicly
749 -// readable (see SignedURL).
750 -func (b *Bucket) URL(path string) string {
751 - req := &request{
752 - bucket: b.Name,
753 - path: path,
754 - }
755 - err := b.S3.prepare(req)
756 - if err != nil {
757 - panic(err)
758 - }
759 - u, err := req.url()
760 - if err != nil {
761 - panic(err)
762 - }
763 - u.RawQuery = ""
764 - return u.String()
765 -}
766 -
767 -// SignedURL returns a signed URL that allows anyone holding the URL
768 -// to retrieve the object at path. The signature is valid until expires.
769 -func (b *Bucket) SignedURL(path string, expires time.Time) string {
770 - return b.SignedURLWithArgs(path, expires, nil, nil)
771 -}
772 -
773 -// SignedURLWithArgs returns a signed URL that allows anyone holding the URL
774 -// to retrieve the object at path. The signature is valid until expires.
775 -func (b *Bucket) SignedURLWithArgs(path string, expires time.Time, params url.Values, headers http.Header) string {
776 - return b.SignedURLWithMethod("GET", path, expires, params, headers)
777 -}
778 -
779 -// SignedURLWithMethod returns a signed URL that allows anyone holding the URL
780 -// to either retrieve the object at path or make a HEAD request against it. The signature is valid until expires.
781 -func (b *Bucket) SignedURLWithMethod(method, path string, expires time.Time, params url.Values, headers http.Header) string {
782 - var uv = url.Values{}
783 -
784 - if params != nil {
785 - uv = params
786 - }
787 -
788 - if b.S3.Signature == aws.V2Signature {
789 - uv.Set("Expires", strconv.FormatInt(expires.Unix(), 10))
790 - } else {
791 - uv.Set("X-Amz-Expires", strconv.FormatInt(expires.Unix()-time.Now().Unix(), 10))
792 - }
793 -
794 - req := &request{
795 - method: method,
796 - bucket: b.Name,
797 - path: path,
798 - params: uv,
799 - headers: headers,
800 - }
801 - err := b.S3.prepare(req)
802 - if err != nil {
803 - panic(err)
804 - }
805 - u, err := req.url()
806 - if err != nil {
807 - panic(err)
808 - }
809 - if b.S3.Auth.Token() != "" {
810 - return u.String() + "&x-amz-security-token=" + url.QueryEscape(req.headers["X-Amz-Security-Token"][0])
811 - } else {
812 - return u.String()
813 - }
814 -}
815 -
816 -// UploadSignedURL returns a signed URL that allows anyone holding the URL
817 -// to upload the object at path. The signature is valid until expires.
818 -// contenttype is a string like image/png
819 -// path is the resource name in s3 terminalogy like images/ali.png [obviously exclusing the bucket name itself]
820 -func (b *Bucket) UploadSignedURL(path, method, content_type string, expires time.Time) string {
821 - expire_date := expires.Unix()
822 - if method != "POST" {
823 - method = "PUT"
824 - }
825 -
826 - a := b.S3.Auth
827 - tokenData := ""
828 -
829 - if a.Token() != "" {
830 - tokenData = "x-amz-security-token:" + a.Token() + "\n"
831 - }
832 -
833 - stringToSign := method + "\n\n" + content_type + "\n" + strconv.FormatInt(expire_date, 10) + "\n" + tokenData + "/" + b.Name + "/" + path
834 - secretKey := a.SecretKey
835 - accessId := a.AccessKey
836 - mac := hmac.New(sha1.New, []byte(secretKey))
837 - mac.Write([]byte(stringToSign))
838 - macsum := mac.Sum(nil)
839 - signature := base64.StdEncoding.EncodeToString([]byte(macsum))
840 - signature = strings.TrimSpace(signature)
841 -
842 - signedurl, err := url.Parse("https://" + b.Name + ".s3.amazonaws.com/")
843 - if err != nil {
844 - log.Println("ERROR sining url for S3 upload", err)
845 - return ""
846 - }
847 - signedurl.Path += path
848 - params := url.Values{}
849 - params.Add("AWSAccessKeyId", accessId)
850 - params.Add("Expires", strconv.FormatInt(expire_date, 10))
851 - params.Add("Signature", signature)
852 - if a.Token() != "" {
853 - params.Add("x-amz-security-token", a.Token())
854 - }
855 -
856 - signedurl.RawQuery = params.Encode()
857 - return signedurl.String()
858 -}
859 -
860 -// PostFormArgs returns the action and input fields needed to allow anonymous
861 -// uploads to a bucket within the expiration limit
862 -// Additional conditions can be specified with conds
863 -func (b *Bucket) PostFormArgsEx(path string, expires time.Time, redirect string, conds []string) (action string, fields map[string]string) {
864 - conditions := make([]string, 0)
865 - fields = map[string]string{
866 - "AWSAccessKeyId": b.Auth.AccessKey,
867 - "key": path,
868 - }
869 -
870 - if conds != nil {
871 - conditions = append(conditions, conds...)
872 - }
873 -
874 - conditions = append(conditions, fmt.Sprintf("{\"key\": \"%s\"}", path))
875 - conditions = append(conditions, fmt.Sprintf("{\"bucket\": \"%s\"}", b.Name))
876 - if redirect != "" {
877 - conditions = append(conditions, fmt.Sprintf("{\"success_action_redirect\": \"%s\"}", redirect))
878 - fields["success_action_redirect"] = redirect
879 - }
880 -
881 - vExpiration := expires.Format("2006-01-02T15:04:05Z")
882 - vConditions := strings.Join(conditions, ",")
883 - policy := fmt.Sprintf("{\"expiration\": \"%s\", \"conditions\": [%s]}", vExpiration, vConditions)
884 - policy64 := base64.StdEncoding.EncodeToString([]byte(policy))
885 - fields["policy"] = policy64
886 -
887 - signer := hmac.New(sha1.New, []byte(b.Auth.SecretKey))
888 - signer.Write([]byte(policy64))
889 - fields["signature"] = base64.StdEncoding.EncodeToString(signer.Sum(nil))
890 -
891 - action = fmt.Sprintf("%s/%s/", b.S3.Region.S3Endpoint, b.Name)
892 - return
893 -}
894 -
895 -// PostFormArgs returns the action and input fields needed to allow anonymous
896 -// uploads to a bucket within the expiration limit
897 -func (b *Bucket) PostFormArgs(path string, expires time.Time, redirect string) (action string, fields map[string]string) {
898 - return b.PostFormArgsEx(path, expires, redirect, nil)
899 -}
900 -
901 -type request struct {
902 - method string
903 - bucket string
904 - path string
905 - params url.Values
906 - headers http.Header
907 - baseurl string
908 - payload io.Reader
909 - prepared bool
910 -}
911 -
912 -func (req *request) url() (*url.URL, error) {
913 - u, err := url.Parse(req.baseurl)
914 - if err != nil {
915 - return nil, fmt.Errorf("bad S3 endpoint URL %q: %v", req.baseurl, err)
916 - }
917 - u.RawQuery = req.params.Encode()
918 - u.Path = req.path
919 - return u, nil
920 -}
921 -
922 -// query prepares and runs the req request.
923 -// If resp is not nil, the XML data contained in the response
924 -// body will be unmarshalled on it.
925 -func (s3 *S3) query(req *request, resp interface{}) error {
926 - err := s3.prepare(req)
927 - if err != nil {
928 - return err
929 - }
930 - r, err := s3.run(req, resp)
931 - if r != nil && r.Body != nil {
932 - r.Body.Close()
933 - }
934 - return err
935 -}
936 -
937 -// queryV4Signprepares and runs the req request, signed with aws v4 signatures.
938 -// If resp is not nil, the XML data contained in the response
939 -// body will be unmarshalled on it.
940 -func (s3 *S3) queryV4Sign(req *request, resp interface{}) error {
941 - if req.headers == nil {
942 - req.headers = map[string][]string{}
943 - }
944 -
945 - err := s3.setBaseURL(req)
946 - if err != nil {
947 - return err
948 - }
949 -
950 - hreq, err := s3.setupHttpRequest(req)
951 - if err != nil {
952 - return err
953 - }
954 -
955 - // req.Host must be set for V4 signature calculation
956 - hreq.Host = hreq.URL.Host
957 -
958 - signer := aws.NewV4Signer(s3.Auth, "s3", s3.Region)
959 - signer.IncludeXAmzContentSha256 = true
960 - signer.Sign(hreq)
961 -
962 - _, err = s3.doHttpRequest(hreq, resp)
963 - return err
964 -}
965 -
966 -// Sets baseurl on req from bucket name and the region endpoint
967 -func (s3 *S3) setBaseURL(req *request) error {
968 - if req.bucket == "" {
969 - req.baseurl = s3.Region.S3Endpoint
970 - } else {
971 - req.baseurl = s3.Region.S3BucketEndpoint
972 - if req.baseurl == "" {
973 - // Use the path method to address the bucket.
974 - req.baseurl = s3.Region.S3Endpoint
975 - req.path = "/" + req.bucket + req.path
976 - } else {
977 - // Just in case, prevent injection.
978 - if strings.IndexAny(req.bucket, "/:@") >= 0 {
979 - return fmt.Errorf("bad S3 bucket: %q", req.bucket)
980 - }
981 - req.baseurl = strings.Replace(req.baseurl, "${bucket}", req.bucket, -1)
982 - }
983 - }
984 -
985 - return nil
986 -}
987 -
988 -// partiallyEscapedPath partially escapes the S3 path allowing for all S3 REST API calls.
989 -//
990 -// Some commands including:
991 -// GET Bucket acl http://goo.gl/aoXflF
992 -// GET Bucket cors http://goo.gl/UlmBdx
993 -// GET Bucket lifecycle http://goo.gl/8Fme7M
994 -// GET Bucket policy http://goo.gl/ClXIo3
995 -// GET Bucket location http://goo.gl/5lh8RD
996 -// GET Bucket Logging http://goo.gl/sZ5ckF
997 -// GET Bucket notification http://goo.gl/qSSZKD
998 -// GET Bucket tagging http://goo.gl/QRvxnM
999 -// require the first character after the bucket name in the path to be a literal '?' and
1000 -// not the escaped hex representation '%3F'.
1001 -func partiallyEscapedPath(path string) string {
1002 - pathEscapedAndSplit := strings.Split((&url.URL{Path: path}).String(), "/")
1003 - if len(pathEscapedAndSplit) >= 3 {
1004 - if len(pathEscapedAndSplit[2]) >= 3 {
1005 - // Check for the one "?" that should not be escaped.
1006 - if pathEscapedAndSplit[2][0:3] == "%3F" {
1007 - pathEscapedAndSplit[2] = "?" + pathEscapedAndSplit[2][3:]
1008 - }
1009 - }
1010 - }
1011 - return strings.Replace(strings.Join(pathEscapedAndSplit, "/"), "+", "%2B", -1)
1012 -}
1013 -
1014 -// prepare sets up req to be delivered to S3.
1015 -func (s3 *S3) prepare(req *request) error {
1016 - // Copy so they can be mutated without affecting on retries.
1017 - params := make(url.Values)
1018 - headers := make(http.Header)
1019 - for k, v := range req.params {
1020 - params[k] = v
1021 - }
1022 - for k, v := range req.headers {
1023 - headers[k] = v
1024 - }
1025 - req.params = params
1026 - req.headers = headers
1027 -
1028 - if !req.prepared {
1029 - req.prepared = true
1030 - if req.method == "" {
1031 - req.method = "GET"
1032 - }
1033 -
1034 - if !strings.HasPrefix(req.path, "/") {
1035 - req.path = "/" + req.path
1036 - }
1037 -
1038 - err := s3.setBaseURL(req)
1039 - if err != nil {
1040 - return err
1041 - }
1042 - }
1043 -
1044 - if s3.Auth.Token() != "" {
1045 - req.headers["X-Amz-Security-Token"] = []string{s3.Auth.Token()}
1046 - }
1047 -
1048 - if s3.Signature == aws.V2Signature {
1049 - // Always sign again as it's not clear how far the
1050 - // server has handled a previous attempt.
1051 - u, err := url.Parse(req.baseurl)
1052 - if err != nil {
1053 - return err
1054 - }
1055 -
1056 - signpathPatiallyEscaped := partiallyEscapedPath(req.path)
1057 - req.headers["Host"] = []string{u.Host}
1058 - req.headers["Date"] = []string{time.Now().In(time.UTC).Format(time.RFC1123)}
1059 -
1060 - sign(s3.Auth, req.method, signpathPatiallyEscaped, req.params, req.headers)
1061 - } else {
1062 - hreq, err := s3.setupHttpRequest(req)
1063 - if err != nil {
1064 - return err
1065 - }
1066 -
1067 - hreq.Host = hreq.URL.Host
1068 - signer := aws.NewV4Signer(s3.Auth, "s3", s3.Region)
1069 - signer.IncludeXAmzContentSha256 = true
1070 - signer.Sign(hreq)
1071 -
1072 - req.payload = hreq.Body
1073 - if _, ok := headers["Content-Length"]; ok {
1074 - req.headers["Content-Length"] = headers["Content-Length"]
1075 - }
1076 - }
1077 - return nil
1078 -}
1079 -
1080 -// Prepares an *http.Request for doHttpRequest
1081 -func (s3 *S3) setupHttpRequest(req *request) (*http.Request, error) {
1082 - // Copy so that signing the http request will not mutate it
1083 - headers := make(http.Header)
1084 - for k, v := range req.headers {
1085 - headers[k] = v
1086 - }
1087 - req.headers = headers
1088 -
1089 - u, err := req.url()
1090 - if err != nil {
1091 - return nil, err
1092 - }
1093 - u.Opaque = fmt.Sprintf("//%s%s", u.Host, partiallyEscapedPath(u.Path))
1094 -
1095 - hreq := http.Request{
1096 - URL: u,
1097 - Method: req.method,
1098 - ProtoMajor: 1,
1099 - ProtoMinor: 1,
1100 - Close: true,
1101 - Header: req.headers,
1102 - Form: req.params,
1103 - }
1104 -
1105 - if v, ok := req.headers["Content-Length"]; ok {
1106 - hreq.ContentLength, _ = strconv.ParseInt(v[0], 10, 64)
1107 - delete(req.headers, "Content-Length")
1108 - }
1109 - if req.payload != nil {
1110 - hreq.Body = ioutil.NopCloser(req.payload)
1111 - }
1112 -
1113 - return &hreq, nil
1114 -}
1115 -
1116 -// doHttpRequest sends hreq and returns the http response from the server.
1117 -// If resp is not nil, the XML data contained in the response
1118 -// body will be unmarshalled on it.
1119 -func (s3 *S3) doHttpRequest(hreq *http.Request, resp interface{}) (*http.Response, error) {
1120 - c := http.Client{
1121 - Transport: &http.Transport{
1122 - Dial: func(netw, addr string) (c net.Conn, err error) {
1123 - deadline := time.Now().Add(s3.ReadTimeout)
1124 - if s3.ConnectTimeout > 0 {
1125 - c, err = net.DialTimeout(netw, addr, s3.ConnectTimeout)
1126 - } else {
1127 - c, err = net.Dial(netw, addr)
1128 - }
1129 - if err != nil {
1130 - return
1131 - }
1132 - if s3.ReadTimeout > 0 {
1133 - err = c.SetDeadline(deadline)
1134 - }
1135 - return
1136 - },
1137 - Proxy: http.ProxyFromEnvironment,
1138 - },
1139 - }
1140 -
1141 - hresp, err := c.Do(hreq)
1142 - if err != nil {
1143 - return nil, err
1144 - }
1145 - if debug {
1146 - dump, _ := httputil.DumpResponse(hresp, true)
1147 - log.Printf("} -> %s\n", dump)
1148 - }
1149 - if hresp.StatusCode != 200 && hresp.StatusCode != 204 && hresp.StatusCode != 206 {
1150 - return nil, buildError(hresp)
1151 - }
1152 - if resp != nil {
1153 - err = xml.NewDecoder(hresp.Body).Decode(resp)
1154 - hresp.Body.Close()
1155 -
1156 - if debug {
1157 - log.Printf("goamz.s3> decoded xml into %#v", resp)
1158 - }
1159 -
1160 - }
1161 - return hresp, err
1162 -}
1163 -
1164 -// run sends req and returns the http response from the server.
1165 -// If resp is not nil, the XML data contained in the response
1166 -// body will be unmarshalled on it.
1167 -func (s3 *S3) run(req *request, resp interface{}) (*http.Response, error) {
1168 - if debug {
1169 - log.Printf("Running S3 request: %#v", req)
1170 - }
1171 -
1172 - hreq, err := s3.setupHttpRequest(req)
1173 - if err != nil {
1174 - return nil, err
1175 - }
1176 -
1177 - return s3.doHttpRequest(hreq, resp)
1178 -}
1179 -
1180 -// Error represents an error in an operation with S3.
1181 -type Error struct {
1182 - StatusCode int // HTTP status code (200, 403, ...)
1183 - Code string // EC2 error code ("UnsupportedOperation", ...)
1184 - Message string // The human-oriented error message
1185 - BucketName string
1186 - RequestId string
1187 - HostId string
1188 -}
1189 -
1190 -func (e *Error) Error() string {
1191 - return e.Message
1192 -}
1193 -
1194 -func buildError(r *http.Response) error {
1195 - if debug {
1196 - log.Printf("got error (status code %v)", r.StatusCode)
1197 - data, err := ioutil.ReadAll(r.Body)
1198 - if err != nil {
1199 - log.Printf("\tread error: %v", err)
1200 - } else {
1201 - log.Printf("\tdata:\n%s\n\n", data)
1202 - }
1203 - r.Body = ioutil.NopCloser(bytes.NewBuffer(data))
1204 - }
1205 -
1206 - err := Error{}
1207 - // TODO return error if Unmarshal fails?
1208 - xml.NewDecoder(r.Body).Decode(&err)
1209 - r.Body.Close()
1210 - err.StatusCode = r.StatusCode
1211 - if err.Message == "" {
1212 - err.Message = r.Status
1213 - }
1214 - if debug {
1215 - log.Printf("err: %#v\n", err)
1216 - }
1217 - return &err
1218 -}
1219 -
1220 -func shouldRetry(err error) bool {
1221 - if err == nil {
1222 - return false
1223 - }
1224 - switch err {
1225 - case io.ErrUnexpectedEOF, io.EOF:
1226 - return true
1227 - }
1228 - switch e := err.(type) {
1229 - case *net.DNSError:
1230 - return true
1231 - case *net.OpError:
1232 - switch e.Op {
1233 - case "read", "write":
1234 - return true
1235 - }
1236 - case *Error:
1237 - switch e.Code {
1238 - case "InternalError", "NoSuchUpload", "NoSuchBucket":
1239 - return true
1240 - }
1241 - }
1242 - return false
1243 -}
1244 -
1245 -func hasCode(err error, code string) bool {
1246 - s3err, ok := err.(*Error)
1247 - return ok && s3err.Code == code
1248 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/s3_test.go deleted
-486
@@ -1,486 +0,0 @@
1 -package s3_test
2 -
3 -import (
4 - "bytes"
5 - "io/ioutil"
6 - "net/http"
7 - "testing"
8 - "time"
9 -
10 - "github.com/crowdmob/goamz/testutil"
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
13 - "gopkg.in/check.v1"
14 -)
15 -
16 -func Test(t *testing.T) {
17 - check.TestingT(t)
18 -}
19 -
20 -type S struct {
21 - s3 *s3.S3
22 -}
23 -
24 -var _ = check.Suite(&S{})
25 -
26 -var testServer = testutil.NewHTTPServer()
27 -
28 -func (s *S) SetUpSuite(c *check.C) {
29 - testServer.Start()
30 - auth := aws.Auth{AccessKey: "abc", SecretKey: "123"}
31 - s.s3 = s3.New(auth, aws.Region{Name: "faux-region-1", S3Endpoint: testServer.URL})
32 -}
33 -
34 -func (s *S) TearDownSuite(c *check.C) {
35 - s3.SetAttemptStrategy(nil)
36 -}
37 -
38 -func (s *S) SetUpTest(c *check.C) {
39 - attempts := aws.AttemptStrategy{
40 - Total: 300 * time.Millisecond,
41 - Delay: 100 * time.Millisecond,
42 - }
43 - s3.SetAttemptStrategy(&attempts)
44 -}
45 -
46 -func (s *S) TearDownTest(c *check.C) {
47 - testServer.Flush()
48 -}
49 -
50 -func (s *S) DisableRetries() {
51 - s3.SetAttemptStrategy(&aws.AttemptStrategy{})
52 -}
53 -
54 -// PutBucket docs: http://goo.gl/kBTCu
55 -
56 -func (s *S) TestPutBucket(c *check.C) {
57 - testServer.Response(200, nil, "")
58 -
59 - b := s.s3.Bucket("bucket")
60 - err := b.PutBucket(s3.Private)
61 - c.Assert(err, check.IsNil)
62 -
63 - req := testServer.WaitRequest()
64 - c.Assert(req.Method, check.Equals, "PUT")
65 - c.Assert(req.URL.Path, check.Equals, "/bucket/")
66 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
67 -}
68 -
69 -// PutBucketWebsite docs: http://goo.gl/TpRlUy
70 -
71 -func (s *S) TestPutBucketWebsite(c *check.C) {
72 - testServer.Response(200, nil, "")
73 -
74 - b := s.s3.Bucket("bucket")
75 - config := s3.WebsiteConfiguration{
76 - RedirectAllRequestsTo: &s3.RedirectAllRequestsTo{HostName: "example.com"},
77 - }
78 - err := b.PutBucketWebsite(config)
79 - c.Assert(err, check.IsNil)
80 -
81 - req := testServer.WaitRequest()
82 - body, err := ioutil.ReadAll(req.Body)
83 - req.Body.Close()
84 - c.Assert(err, check.IsNil)
85 - c.Assert(string(body), check.Equals, BucketWebsiteConfigurationDump)
86 - c.Assert(req.Method, check.Equals, "PUT")
87 - c.Assert(req.URL.Path, check.Equals, "/bucket/")
88 - c.Assert(req.URL.RawQuery, check.Equals, "website=")
89 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
90 -}
91 -
92 -// Head docs: http://bit.ly/17K1ylI
93 -
94 -func (s *S) TestHead(c *check.C) {
95 - testServer.Response(200, nil, "content")
96 -
97 - b := s.s3.Bucket("bucket")
98 - resp, err := b.Head("name", nil)
99 -
100 - req := testServer.WaitRequest()
101 - c.Assert(req.Method, check.Equals, "HEAD")
102 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
103 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
104 -
105 - c.Assert(err, check.IsNil)
106 - c.Assert(resp.ContentLength, check.FitsTypeOf, int64(0))
107 - c.Assert(resp, check.FitsTypeOf, &http.Response{})
108 -}
109 -
110 -// DeleteBucket docs: http://goo.gl/GoBrY
111 -
112 -func (s *S) TestDelBucket(c *check.C) {
113 - testServer.Response(204, nil, "")
114 -
115 - b := s.s3.Bucket("bucket")
116 - err := b.DelBucket()
117 - c.Assert(err, check.IsNil)
118 -
119 - req := testServer.WaitRequest()
120 - c.Assert(req.Method, check.Equals, "DELETE")
121 - c.Assert(req.URL.Path, check.Equals, "/bucket/")
122 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
123 -}
124 -
125 -// GetObject docs: http://goo.gl/isCO7
126 -
127 -func (s *S) TestGet(c *check.C) {
128 - testServer.Response(200, nil, "content")
129 -
130 - b := s.s3.Bucket("bucket")
131 - data, err := b.Get("name")
132 -
133 - req := testServer.WaitRequest()
134 - c.Assert(req.Method, check.Equals, "GET")
135 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
136 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
137 -
138 - c.Assert(err, check.IsNil)
139 - c.Assert(string(data), check.Equals, "content")
140 -}
141 -
142 -func (s *S) TestGetWithPlus(c *check.C) {
143 - testServer.Response(200, nil, "content")
144 -
145 - b := s.s3.Bucket("bucket")
146 - _, err := b.Get("has+plus")
147 -
148 - req := testServer.WaitRequest()
149 - c.Assert(err, check.IsNil)
150 - c.Assert(req.RequestURI, check.Equals, "http://localhost:4444/bucket/has%2Bplus")
151 -}
152 -
153 -func (s *S) TestURL(c *check.C) {
154 - testServer.Response(200, nil, "content")
155 -
156 - b := s.s3.Bucket("bucket")
157 - url := b.URL("name")
158 - r, err := http.Get(url)
159 - c.Assert(err, check.IsNil)
160 - data, err := ioutil.ReadAll(r.Body)
161 - r.Body.Close()
162 - c.Assert(err, check.IsNil)
163 - c.Assert(string(data), check.Equals, "content")
164 -
165 - req := testServer.WaitRequest()
166 - c.Assert(req.Method, check.Equals, "GET")
167 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
168 -}
169 -
170 -func (s *S) TestGetReader(c *check.C) {
171 - testServer.Response(200, nil, "content")
172 -
173 - b := s.s3.Bucket("bucket")
174 - rc, err := b.GetReader("name")
175 - c.Assert(err, check.IsNil)
176 - data, err := ioutil.ReadAll(rc)
177 - rc.Close()
178 - c.Assert(err, check.IsNil)
179 - c.Assert(string(data), check.Equals, "content")
180 -
181 - req := testServer.WaitRequest()
182 - c.Assert(req.Method, check.Equals, "GET")
183 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
184 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
185 -}
186 -
187 -func (s *S) TestGetNotFound(c *check.C) {
188 - for i := 0; i < 10; i++ {
189 - testServer.Response(404, nil, GetObjectErrorDump)
190 - }
191 -
192 - b := s.s3.Bucket("non-existent-bucket")
193 - data, err := b.Get("non-existent")
194 -
195 - req := testServer.WaitRequest()
196 - c.Assert(req.Method, check.Equals, "GET")
197 - c.Assert(req.URL.Path, check.Equals, "/non-existent-bucket/non-existent")
198 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
199 -
200 - s3err, _ := err.(*s3.Error)
201 - c.Assert(s3err, check.NotNil)
202 - c.Assert(s3err.StatusCode, check.Equals, 404)
203 - c.Assert(s3err.BucketName, check.Equals, "non-existent-bucket")
204 - c.Assert(s3err.RequestId, check.Equals, "3F1B667FAD71C3D8")
205 - c.Assert(s3err.HostId, check.Equals, "L4ee/zrm1irFXY5F45fKXIRdOf9ktsKY/8TDVawuMK2jWRb1RF84i1uBzkdNqS5D")
206 - c.Assert(s3err.Code, check.Equals, "NoSuchBucket")
207 - c.Assert(s3err.Message, check.Equals, "The specified bucket does not exist")
208 - c.Assert(s3err.Error(), check.Equals, "The specified bucket does not exist")
209 - c.Assert(data, check.IsNil)
210 -}
211 -
212 -// PutObject docs: http://goo.gl/FEBPD
213 -
214 -func (s *S) TestPutObject(c *check.C) {
215 - testServer.Response(200, nil, "")
216 - const DISPOSITION = "attachment; filename=\"0x1a2b3c.jpg\""
217 -
218 - b := s.s3.Bucket("bucket")
219 - err := b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{ContentDisposition: DISPOSITION})
220 - c.Assert(err, check.IsNil)
221 -
222 - req := testServer.WaitRequest()
223 - c.Assert(req.Method, check.Equals, "PUT")
224 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
225 - c.Assert(req.Header["Date"], check.Not(check.DeepEquals), []string{""})
226 - c.Assert(req.Header["Content-Type"], check.DeepEquals, []string{"content-type"})
227 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"7"})
228 - c.Assert(req.Header["Content-Disposition"], check.DeepEquals, []string{DISPOSITION})
229 - //c.Assert(req.Header["Content-MD5"], gocheck.DeepEquals, "...")
230 - c.Assert(req.Header["X-Amz-Acl"], check.DeepEquals, []string{"private"})
231 -}
232 -
233 -// PutCopy docs: http://goo.gl/mhEHtA
234 -func (s *S) TestPutCopy(c *check.C) {
235 - testServer.Response(200, nil, PutCopyResultDump)
236 -
237 - b := s.s3.Bucket("bucket")
238 - res, err := b.PutCopy("name", s3.Private, s3.CopyOptions{},
239 - // 0xFC is &uuml; - 0xE9 is &eacute;
240 - "source-bucket/\u00FCber-fil\u00E9.jpg")
241 - c.Assert(err, check.IsNil)
242 - c.Assert(res, check.DeepEquals, &s3.CopyObjectResult{
243 - ETag: `"9b2cf535f27731c974343645a3985328"`,
244 - LastModified: `2009-10-28T22:32:00`})
245 -
246 - req := testServer.WaitRequest()
247 - c.Assert(req.Method, check.Equals, "PUT")
248 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
249 - c.Assert(req.Header["Date"], check.Not(check.DeepEquals), []string{""})
250 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"0"})
251 - c.Assert(req.Header["X-Amz-Copy-Source"], check.DeepEquals, []string{`source-bucket%2F%C3%BCber-fil%C3%A9.jpg`})
252 - c.Assert(req.Header["X-Amz-Acl"], check.DeepEquals, []string{"private"})
253 -}
254 -
255 -func (s *S) TestPutObjectReadTimeout(c *check.C) {
256 - s.s3.ReadTimeout = 50 * time.Millisecond
257 - defer func() {
258 - s.s3.ReadTimeout = 0
259 - }()
260 -
261 - b := s.s3.Bucket("bucket")
262 - err := b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{})
263 -
264 - // Make sure that we get a timeout error.
265 - c.Assert(err, check.NotNil)
266 -
267 - // Set the response after the request times out so that the next request will work.
268 - testServer.Response(200, nil, "")
269 -
270 - // This time set the response within our timeout period so that we expect the call
271 - // to return successfully.
272 - go func() {
273 - time.Sleep(25 * time.Millisecond)
274 - testServer.Response(200, nil, "")
275 - }()
276 - err = b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{})
277 - c.Assert(err, check.IsNil)
278 -}
279 -
280 -func (s *S) TestPutReader(c *check.C) {
281 - testServer.Response(200, nil, "")
282 -
283 - b := s.s3.Bucket("bucket")
284 - buf := bytes.NewBufferString("content")
285 - err := b.PutReader("name", buf, int64(buf.Len()), "content-type", s3.Private, s3.Options{})
286 - c.Assert(err, check.IsNil)
287 -
288 - req := testServer.WaitRequest()
289 - c.Assert(req.Method, check.Equals, "PUT")
290 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
291 - c.Assert(req.Header["Date"], check.Not(check.DeepEquals), []string{""})
292 - c.Assert(req.Header["Content-Type"], check.DeepEquals, []string{"content-type"})
293 - c.Assert(req.Header["Content-Length"], check.DeepEquals, []string{"7"})
294 - //c.Assert(req.Header["Content-MD5"], gocheck.Equals, "...")
295 - c.Assert(req.Header["X-Amz-Acl"], check.DeepEquals, []string{"private"})
296 -}
297 -
298 -// DelObject docs: http://goo.gl/APeTt
299 -
300 -func (s *S) TestDelObject(c *check.C) {
301 - testServer.Response(200, nil, "")
302 -
303 - b := s.s3.Bucket("bucket")
304 - err := b.Del("name")
305 - c.Assert(err, check.IsNil)
306 -
307 - req := testServer.WaitRequest()
308 - c.Assert(req.Method, check.Equals, "DELETE")
309 - c.Assert(req.URL.Path, check.Equals, "/bucket/name")
310 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
311 -}
312 -
313 -func (s *S) TestDelMultiObjects(c *check.C) {
314 - testServer.Response(200, nil, "")
315 -
316 - b := s.s3.Bucket("bucket")
317 - objects := []s3.Object{s3.Object{Key: "test"}}
318 - err := b.DelMulti(s3.Delete{
319 - Quiet: false,
320 - Objects: objects,
321 - })
322 - c.Assert(err, check.IsNil)
323 -
324 - req := testServer.WaitRequest()
325 - c.Assert(req.Method, check.Equals, "POST")
326 - c.Assert(req.URL.RawQuery, check.Equals, "delete=")
327 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
328 - c.Assert(req.Header["Content-MD5"], check.Not(check.Equals), "")
329 - c.Assert(req.Header["Content-Type"], check.Not(check.Equals), "")
330 - c.Assert(req.ContentLength, check.Not(check.Equals), "")
331 -}
332 -
333 -// Bucket List Objects docs: http://goo.gl/YjQTc
334 -
335 -func (s *S) TestList(c *check.C) {
336 - testServer.Response(200, nil, GetListResultDump1)
337 -
338 - b := s.s3.Bucket("quotes")
339 -
340 - data, err := b.List("N", "", "", 0)
341 - c.Assert(err, check.IsNil)
342 -
343 - req := testServer.WaitRequest()
344 - c.Assert(req.Method, check.Equals, "GET")
345 - c.Assert(req.URL.Path, check.Equals, "/quotes/")
346 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
347 - c.Assert(req.Form["prefix"], check.DeepEquals, []string{"N"})
348 - c.Assert(req.Form["delimiter"], check.DeepEquals, []string{""})
349 - c.Assert(req.Form["marker"], check.DeepEquals, []string{""})
350 - c.Assert(req.Form["max-keys"], check.DeepEquals, []string(nil))
351 -
352 - c.Assert(data.Name, check.Equals, "quotes")
353 - c.Assert(data.Prefix, check.Equals, "N")
354 - c.Assert(data.IsTruncated, check.Equals, false)
355 - c.Assert(len(data.Contents), check.Equals, 2)
356 -
357 - c.Assert(data.Contents[0].Key, check.Equals, "Nelson")
358 - c.Assert(data.Contents[0].LastModified, check.Equals, "2006-01-01T12:00:00.000Z")
359 - c.Assert(data.Contents[0].ETag, check.Equals, `"828ef3fdfa96f00ad9f27c383fc9ac7f"`)
360 - c.Assert(data.Contents[0].Size, check.Equals, int64(5))
361 - c.Assert(data.Contents[0].StorageClass, check.Equals, "STANDARD")
362 - c.Assert(data.Contents[0].Owner.ID, check.Equals, "bcaf161ca5fb16fd081034f")
363 - c.Assert(data.Contents[0].Owner.DisplayName, check.Equals, "webfile")
364 -
365 - c.Assert(data.Contents[1].Key, check.Equals, "Neo")
366 - c.Assert(data.Contents[1].LastModified, check.Equals, "2006-01-01T12:00:00.000Z")
367 - c.Assert(data.Contents[1].ETag, check.Equals, `"828ef3fdfa96f00ad9f27c383fc9ac7f"`)
368 - c.Assert(data.Contents[1].Size, check.Equals, int64(4))
369 - c.Assert(data.Contents[1].StorageClass, check.Equals, "STANDARD")
370 - c.Assert(data.Contents[1].Owner.ID, check.Equals, "bcaf1ffd86a5fb16fd081034f")
371 - c.Assert(data.Contents[1].Owner.DisplayName, check.Equals, "webfile")
372 -}
373 -
374 -func (s *S) TestListWithDelimiter(c *check.C) {
375 - testServer.Response(200, nil, GetListResultDump2)
376 -
377 - b := s.s3.Bucket("quotes")
378 -
379 - data, err := b.List("photos/2006/", "/", "some-marker", 1000)
380 - c.Assert(err, check.IsNil)
381 -
382 - req := testServer.WaitRequest()
383 - c.Assert(req.Method, check.Equals, "GET")
384 - c.Assert(req.URL.Path, check.Equals, "/quotes/")
385 - c.Assert(req.Header["Date"], check.Not(check.Equals), "")
386 - c.Assert(req.Form["prefix"], check.DeepEquals, []string{"photos/2006/"})
387 - c.Assert(req.Form["delimiter"], check.DeepEquals, []string{"/"})
388 - c.Assert(req.Form["marker"], check.DeepEquals, []string{"some-marker"})
389 - c.Assert(req.Form["max-keys"], check.DeepEquals, []string{"1000"})
390 -
391 - c.Assert(data.Name, check.Equals, "example-bucket")
392 - c.Assert(data.Prefix, check.Equals, "photos/2006/")
393 - c.Assert(data.Delimiter, check.Equals, "/")
394 - c.Assert(data.Marker, check.Equals, "some-marker")
395 - c.Assert(data.IsTruncated, check.Equals, false)
396 - c.Assert(len(data.Contents), check.Equals, 0)
397 - c.Assert(data.CommonPrefixes, check.DeepEquals, []string{"photos/2006/feb/", "photos/2006/jan/"})
398 -}
399 -
400 -func (s *S) TestExists(c *check.C) {
401 - testServer.Response(200, nil, "")
402 -
403 - b := s.s3.Bucket("bucket")
404 - result, err := b.Exists("name")
405 -
406 - req := testServer.WaitRequest()
407 -
408 - c.Assert(req.Method, check.Equals, "HEAD")
409 -
410 - c.Assert(err, check.IsNil)
411 - c.Assert(result, check.Equals, true)
412 -}
413 -
414 -func (s *S) TestExistsNotFound404(c *check.C) {
415 - testServer.Response(404, nil, "")
416 -
417 - b := s.s3.Bucket("bucket")
418 - result, err := b.Exists("name")
419 -
420 - req := testServer.WaitRequest()
421 -
422 - c.Assert(req.Method, check.Equals, "HEAD")
423 -
424 - c.Assert(err, check.IsNil)
425 - c.Assert(result, check.Equals, false)
426 -}
427 -
428 -func (s *S) TestExistsNotFound403(c *check.C) {
429 - testServer.Response(403, nil, "")
430 -
431 - b := s.s3.Bucket("bucket")
432 - result, err := b.Exists("name")
433 -
434 - req := testServer.WaitRequest()
435 -
436 - c.Assert(req.Method, check.Equals, "HEAD")
437 -
438 - c.Assert(err, check.IsNil)
439 - c.Assert(result, check.Equals, false)
440 -}
441 -
442 -func (s *S) TestGetService(c *check.C) {
443 - testServer.Response(200, nil, GetServiceDump)
444 -
445 - expected := s3.GetServiceResp{
446 - Owner: s3.Owner{
447 - ID: "bcaf1ffd86f461ca5fb16fd081034f",
448 - DisplayName: "webfile",
449 - },
450 - Buckets: []s3.BucketInfo{
451 - s3.BucketInfo{
452 - Name: "quotes",
453 - CreationDate: "2006-02-03T16:45:09.000Z",
454 - },
455 - s3.BucketInfo{
456 - Name: "samples",
457 - CreationDate: "2006-02-03T16:41:58.000Z",
458 - },
459 - },
460 - }
461 -
462 - received, err := s.s3.GetService()
463 -
464 - c.Assert(err, check.IsNil)
465 - c.Assert(*received, check.DeepEquals, expected)
466 -}
467 -
468 -func (s *S) TestLocation(c *check.C) {
469 - testServer.Response(200, nil, GetLocationUsStandard)
470 - expectedUsStandard := "us-east-1"
471 -
472 - bucketUsStandard := s.s3.Bucket("us-east-1")
473 - resultUsStandard, err := bucketUsStandard.Location()
474 -
475 - c.Assert(err, check.IsNil)
476 - c.Assert(resultUsStandard, check.Equals, expectedUsStandard)
477 -
478 - testServer.Response(200, nil, GetLocationUsWest1)
479 - expectedUsWest1 := "us-west-1"
480 -
481 - bucketUsWest1 := s.s3.Bucket("us-west-1")
482 - resultUsWest1, err := bucketUsWest1.Location()
483 -
484 - c.Assert(err, check.IsNil)
485 - c.Assert(resultUsWest1, check.Equals, expectedUsWest1)
486 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/s3i_test.go deleted
-589
@@ -1,589 +0,0 @@
1 -package s3_test
2 -
3 -import (
4 - "bytes"
5 - "crypto/md5"
6 - "fmt"
7 - "github.com/crowdmob/goamz/testutil"
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
9 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
10 - "gopkg.in/check.v1"
11 - "io/ioutil"
12 - "net"
13 - "net/http"
14 - "sort"
15 - "strings"
16 - "time"
17 -)
18 -
19 -// AmazonServer represents an Amazon S3 server.
20 -type AmazonServer struct {
21 - auth aws.Auth
22 -}
23 -
24 -func (s *AmazonServer) SetUp(c *check.C) {
25 - auth, err := aws.EnvAuth()
26 - if err != nil {
27 - c.Fatal(err.Error())
28 - }
29 - s.auth = auth
30 -}
31 -
32 -var _ = check.Suite(&AmazonClientSuite{Region: aws.USEast})
33 -var _ = check.Suite(&AmazonClientSuite{Region: aws.EUWest})
34 -var _ = check.Suite(&AmazonDomainClientSuite{Region: aws.USEast})
35 -
36 -// AmazonClientSuite tests the client against a live S3 server.
37 -type AmazonClientSuite struct {
38 - aws.Region
39 - srv AmazonServer
40 - ClientTests
41 -}
42 -
43 -func (s *AmazonClientSuite) SetUpSuite(c *check.C) {
44 - if !testutil.Amazon {
45 - c.Skip("live tests against AWS disabled (no -amazon)")
46 - }
47 - s.srv.SetUp(c)
48 - s.s3 = s3.New(s.srv.auth, s.Region)
49 - // In case tests were interrupted in the middle before.
50 - s.ClientTests.Cleanup()
51 -}
52 -
53 -func (s *AmazonClientSuite) TearDownTest(c *check.C) {
54 - s.ClientTests.Cleanup()
55 -}
56 -
57 -// AmazonDomainClientSuite tests the client against a live S3
58 -// server using bucket names in the endpoint domain name rather
59 -// than the request path.
60 -type AmazonDomainClientSuite struct {
61 - aws.Region
62 - srv AmazonServer
63 - ClientTests
64 -}
65 -
66 -func (s *AmazonDomainClientSuite) SetUpSuite(c *check.C) {
67 - if !testutil.Amazon {
68 - c.Skip("live tests against AWS disabled (no -amazon)")
69 - }
70 - s.srv.SetUp(c)
71 - region := s.Region
72 - region.S3BucketEndpoint = "https://${bucket}.s3.amazonaws.com"
73 - s.s3 = s3.New(s.srv.auth, region)
74 - s.ClientTests.Cleanup()
75 -}
76 -
77 -func (s *AmazonDomainClientSuite) TearDownTest(c *check.C) {
78 - s.ClientTests.Cleanup()
79 -}
80 -
81 -// ClientTests defines integration tests designed to test the client.
82 -// It is not used as a test suite in itself, but embedded within
83 -// another type.
84 -type ClientTests struct {
85 - s3 *s3.S3
86 - authIsBroken bool
87 -}
88 -
89 -func (s *ClientTests) Cleanup() {
90 - killBucket(testBucket(s.s3))
91 -}
92 -
93 -func testBucket(s *s3.S3) *s3.Bucket {
94 - // Watch out! If this function is corrupted and made to match with something
95 - // people own, killBucket will happily remove *everything* inside the bucket.
96 - key := s.Auth.AccessKey
97 - if len(key) >= 8 {
98 - key = s.Auth.AccessKey[:8]
99 - }
100 - return s.Bucket(fmt.Sprintf("goamz-%s-%s", s.Region.Name, key))
101 -}
102 -
103 -var attempts = aws.AttemptStrategy{
104 - Min: 5,
105 - Total: 20 * time.Second,
106 - Delay: 100 * time.Millisecond,
107 -}
108 -
109 -func killBucket(b *s3.Bucket) {
110 - var err error
111 - for attempt := attempts.Start(); attempt.Next(); {
112 - err = b.DelBucket()
113 - if err == nil {
114 - return
115 - }
116 - if _, ok := err.(*net.DNSError); ok {
117 - return
118 - }
119 - e, ok := err.(*s3.Error)
120 - if ok && e.Code == "NoSuchBucket" {
121 - return
122 - }
123 - if ok && e.Code == "BucketNotEmpty" {
124 - // Errors are ignored here. Just retry.
125 - resp, err := b.List("", "", "", 1000)
126 - if err == nil {
127 - for _, key := range resp.Contents {
128 - _ = b.Del(key.Key)
129 - }
130 - }
131 - multis, _, _ := b.ListMulti("", "")
132 - for _, m := range multis {
133 - _ = m.Abort()
134 - }
135 - }
136 - }
137 - message := "cannot delete test bucket"
138 - if err != nil {
139 - message += ": " + err.Error()
140 - }
141 - panic(message)
142 -}
143 -
144 -func get(url string) ([]byte, error) {
145 - for attempt := attempts.Start(); attempt.Next(); {
146 - resp, err := http.Get(url)
147 - if err != nil {
148 - if attempt.HasNext() {
149 - continue
150 - }
151 - return nil, err
152 - }
153 - data, err := ioutil.ReadAll(resp.Body)
154 - resp.Body.Close()
155 - if err != nil {
156 - if attempt.HasNext() {
157 - continue
158 - }
159 - return nil, err
160 - }
161 - return data, err
162 - }
163 - panic("unreachable")
164 -}
165 -
166 -func (s *ClientTests) TestBasicFunctionality(c *check.C) {
167 - b := testBucket(s.s3)
168 - err := b.PutBucket(s3.PublicRead)
169 - c.Assert(err, check.IsNil)
170 -
171 - err = b.Put("name", []byte("yo!"), "text/plain", s3.PublicRead, s3.Options{})
172 - c.Assert(err, check.IsNil)
173 - defer b.Del("name")
174 -
175 - data, err := b.Get("name")
176 - c.Assert(err, check.IsNil)
177 - c.Assert(string(data), check.Equals, "yo!")
178 -
179 - data, err = get(b.URL("name"))
180 - c.Assert(err, check.IsNil)
181 - c.Assert(string(data), check.Equals, "yo!")
182 -
183 - buf := bytes.NewBufferString("hey!")
184 - err = b.PutReader("name2", buf, int64(buf.Len()), "text/plain", s3.Private, s3.Options{})
185 - c.Assert(err, check.IsNil)
186 - defer b.Del("name2")
187 -
188 - rc, err := b.GetReader("name2")
189 - c.Assert(err, check.IsNil)
190 - data, err = ioutil.ReadAll(rc)
191 - c.Check(err, check.IsNil)
192 - c.Check(string(data), check.Equals, "hey!")
193 - rc.Close()
194 -
195 - data, err = get(b.SignedURL("name2", time.Now().Add(time.Hour)))
196 - c.Assert(err, check.IsNil)
197 - c.Assert(string(data), check.Equals, "hey!")
198 -
199 - if !s.authIsBroken {
200 - data, err = get(b.SignedURL("name2", time.Now().Add(-time.Hour)))
201 - c.Assert(err, check.IsNil)
202 - c.Assert(string(data), check.Matches, "(?s).*AccessDenied.*")
203 - }
204 -
205 - err = b.DelBucket()
206 - c.Assert(err, check.NotNil)
207 -
208 - s3err, ok := err.(*s3.Error)
209 - c.Assert(ok, check.Equals, true)
210 - c.Assert(s3err.Code, check.Equals, "BucketNotEmpty")
211 - c.Assert(s3err.BucketName, check.Equals, b.Name)
212 - c.Assert(s3err.Message, check.Equals, "The bucket you tried to delete is not empty")
213 -
214 - err = b.Del("name")
215 - c.Assert(err, check.IsNil)
216 - err = b.Del("name2")
217 - c.Assert(err, check.IsNil)
218 -
219 - err = b.DelBucket()
220 - c.Assert(err, check.IsNil)
221 -}
222 -
223 -func (s *ClientTests) TestGetNotFound(c *check.C) {
224 - b := s.s3.Bucket("goamz-" + s.s3.Auth.AccessKey)
225 - data, err := b.Get("non-existent")
226 -
227 - s3err, _ := err.(*s3.Error)
228 - c.Assert(s3err, check.NotNil)
229 - c.Assert(s3err.StatusCode, check.Equals, 404)
230 - c.Assert(s3err.Code, check.Equals, "NoSuchBucket")
231 - c.Assert(s3err.Message, check.Equals, "The specified bucket does not exist")
232 - c.Assert(data, check.IsNil)
233 -}
234 -
235 -// Communicate with all endpoints to see if they are alive.
236 -func (s *ClientTests) TestRegions(c *check.C) {
237 - errs := make(chan error, len(aws.Regions))
238 - for _, region := range aws.Regions {
239 - go func(r aws.Region) {
240 - s := s3.New(s.s3.Auth, r)
241 - b := s.Bucket("goamz-" + s.Auth.AccessKey)
242 - _, err := b.Get("non-existent")
243 - errs <- err
244 - }(region)
245 - }
246 - for _ = range aws.Regions {
247 - err := <-errs
248 - if err != nil {
249 - s3_err, ok := err.(*s3.Error)
250 - if ok {
251 - c.Check(s3_err.Code, check.Matches, "NoSuchBucket")
252 - } else if _, ok = err.(*net.DNSError); ok {
253 - // Okay as well.
254 - } else {
255 - c.Errorf("Non-S3 error: %s", err)
256 - }
257 - } else {
258 - c.Errorf("Test should have errored but it seems to have succeeded")
259 - }
260 - }
261 -}
262 -
263 -var objectNames = []string{
264 - "index.html",
265 - "index2.html",
266 - "photos/2006/February/sample2.jpg",
267 - "photos/2006/February/sample3.jpg",
268 - "photos/2006/February/sample4.jpg",
269 - "photos/2006/January/sample.jpg",
270 - "test/bar",
271 - "test/foo",
272 -}
273 -
274 -func keys(names ...string) []s3.Key {
275 - ks := make([]s3.Key, len(names))
276 - for i, name := range names {
277 - ks[i].Key = name
278 - }
279 - return ks
280 -}
281 -
282 -// As the ListResp specifies all the parameters to the
283 -// request too, we use it to specify request parameters
284 -// and expected results. The Contents field is
285 -// used only for the key names inside it.
286 -var listTests = []s3.ListResp{
287 - // normal list.
288 - {
289 - Contents: keys(objectNames...),
290 - }, {
291 - Marker: objectNames[0],
292 - Contents: keys(objectNames[1:]...),
293 - }, {
294 - Marker: objectNames[0] + "a",
295 - Contents: keys(objectNames[1:]...),
296 - }, {
297 - Marker: "z",
298 - },
299 -
300 - // limited results.
301 - {
302 - MaxKeys: 2,
303 - Contents: keys(objectNames[0:2]...),
304 - IsTruncated: true,
305 - }, {
306 - MaxKeys: 2,
307 - Marker: objectNames[0],
308 - Contents: keys(objectNames[1:3]...),
309 - IsTruncated: true,
310 - }, {
311 - MaxKeys: 2,
312 - Marker: objectNames[len(objectNames)-2],
313 - Contents: keys(objectNames[len(objectNames)-1:]...),
314 - },
315 -
316 - // with delimiter
317 - {
318 - Delimiter: "/",
319 - CommonPrefixes: []string{"photos/", "test/"},
320 - Contents: keys("index.html", "index2.html"),
321 - }, {
322 - Delimiter: "/",
323 - Prefix: "photos/2006/",
324 - CommonPrefixes: []string{"photos/2006/February/", "photos/2006/January/"},
325 - }, {
326 - Delimiter: "/",
327 - Prefix: "t",
328 - CommonPrefixes: []string{"test/"},
329 - }, {
330 - Delimiter: "/",
331 - MaxKeys: 1,
332 - Contents: keys("index.html"),
333 - IsTruncated: true,
334 - }, {
335 - Delimiter: "/",
336 - MaxKeys: 1,
337 - Marker: "index2.html",
338 - CommonPrefixes: []string{"photos/"},
339 - IsTruncated: true,
340 - }, {
341 - Delimiter: "/",
342 - MaxKeys: 1,
343 - Marker: "photos/",
344 - CommonPrefixes: []string{"test/"},
345 - IsTruncated: false,
346 - }, {
347 - Delimiter: "Feb",
348 - CommonPrefixes: []string{"photos/2006/Feb"},
349 - Contents: keys("index.html", "index2.html", "photos/2006/January/sample.jpg", "test/bar", "test/foo"),
350 - },
351 -}
352 -
353 -func (s *ClientTests) TestDoublePutBucket(c *check.C) {
354 - b := testBucket(s.s3)
355 - err := b.PutBucket(s3.PublicRead)
356 - c.Assert(err, check.IsNil)
357 -
358 - err = b.PutBucket(s3.PublicRead)
359 - if err != nil {
360 - c.Assert(err, check.FitsTypeOf, new(s3.Error))
361 - c.Assert(err.(*s3.Error).Code, check.Equals, "BucketAlreadyOwnedByYou")
362 - }
363 -}
364 -
365 -func (s *ClientTests) TestBucketList(c *check.C) {
366 - b := testBucket(s.s3)
367 - err := b.PutBucket(s3.Private)
368 - c.Assert(err, check.IsNil)
369 -
370 - objData := make(map[string][]byte)
371 - for i, path := range objectNames {
372 - data := []byte(strings.Repeat("a", i))
373 - err := b.Put(path, data, "text/plain", s3.Private, s3.Options{})
374 - c.Assert(err, check.IsNil)
375 - defer b.Del(path)
376 - objData[path] = data
377 - }
378 -
379 - for i, t := range listTests {
380 - c.Logf("test %d", i)
381 - resp, err := b.List(t.Prefix, t.Delimiter, t.Marker, t.MaxKeys)
382 - c.Assert(err, check.IsNil)
383 - c.Check(resp.Name, check.Equals, b.Name)
384 - c.Check(resp.Delimiter, check.Equals, t.Delimiter)
385 - c.Check(resp.IsTruncated, check.Equals, t.IsTruncated)
386 - c.Check(resp.CommonPrefixes, check.DeepEquals, t.CommonPrefixes)
387 - checkContents(c, resp.Contents, objData, t.Contents)
388 - }
389 -}
390 -
391 -func etag(data []byte) string {
392 - sum := md5.New()
393 - sum.Write(data)
394 - return fmt.Sprintf(`"%x"`, sum.Sum(nil))
395 -}
396 -
397 -func checkContents(c *check.C, contents []s3.Key, data map[string][]byte, expected []s3.Key) {
398 - c.Assert(contents, check.HasLen, len(expected))
399 - for i, k := range contents {
400 - c.Check(k.Key, check.Equals, expected[i].Key)
401 - // TODO mtime
402 - c.Check(k.Size, check.Equals, int64(len(data[k.Key])))
403 - c.Check(k.ETag, check.Equals, etag(data[k.Key]))
404 - }
405 -}
406 -
407 -func (s *ClientTests) TestMultiInitPutList(c *check.C) {
408 - b := testBucket(s.s3)
409 - err := b.PutBucket(s3.Private)
410 - c.Assert(err, check.IsNil)
411 -
412 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
413 - c.Assert(err, check.IsNil)
414 - c.Assert(multi.UploadId, check.Matches, ".+")
415 - defer multi.Abort()
416 -
417 - var sent []s3.Part
418 -
419 - for i := 0; i < 5; i++ {
420 - p, err := multi.PutPart(i+1, strings.NewReader(fmt.Sprintf("<part %d>", i+1)))
421 - c.Assert(err, check.IsNil)
422 - c.Assert(p.N, check.Equals, i+1)
423 - c.Assert(p.Size, check.Equals, int64(8))
424 - c.Assert(p.ETag, check.Matches, ".+")
425 - sent = append(sent, p)
426 - }
427 -
428 - s3.SetListPartsMax(2)
429 -
430 - parts, err := multi.ListParts()
431 - c.Assert(err, check.IsNil)
432 - c.Assert(parts, check.HasLen, len(sent))
433 - for i := range parts {
434 - c.Assert(parts[i].N, check.Equals, sent[i].N)
435 - c.Assert(parts[i].Size, check.Equals, sent[i].Size)
436 - c.Assert(parts[i].ETag, check.Equals, sent[i].ETag)
437 - }
438 -
439 - err = multi.Complete(parts)
440 - s3err, failed := err.(*s3.Error)
441 - c.Assert(failed, check.Equals, true)
442 - c.Assert(s3err.Code, check.Equals, "EntityTooSmall")
443 -
444 - err = multi.Abort()
445 - c.Assert(err, check.IsNil)
446 - _, err = multi.ListParts()
447 - s3err, ok := err.(*s3.Error)
448 - c.Assert(ok, check.Equals, true)
449 - c.Assert(s3err.Code, check.Equals, "NoSuchUpload")
450 -}
451 -
452 -// This may take a minute or more due to the minimum size accepted S3
453 -// on multipart upload parts.
454 -func (s *ClientTests) TestMultiComplete(c *check.C) {
455 - b := testBucket(s.s3)
456 - err := b.PutBucket(s3.Private)
457 - c.Assert(err, check.IsNil)
458 -
459 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
460 - c.Assert(err, check.IsNil)
461 - c.Assert(multi.UploadId, check.Matches, ".+")
462 - defer multi.Abort()
463 -
464 - // Minimum size S3 accepts for all but the last part is 5MB.
465 - data1 := make([]byte, 5*1024*1024)
466 - data2 := []byte("<part 2>")
467 -
468 - part1, err := multi.PutPart(1, bytes.NewReader(data1))
469 - c.Assert(err, check.IsNil)
470 - part2, err := multi.PutPart(2, bytes.NewReader(data2))
471 - c.Assert(err, check.IsNil)
472 -
473 - // Purposefully reversed. The order requirement must be handled.
474 - err = multi.Complete([]s3.Part{part2, part1})
475 - c.Assert(err, check.IsNil)
476 -
477 - data, err := b.Get("multi")
478 - c.Assert(err, check.IsNil)
479 -
480 - c.Assert(len(data), check.Equals, len(data1)+len(data2))
481 - for i := range data1 {
482 - if data[i] != data1[i] {
483 - c.Fatalf("uploaded object at byte %d: want %d, got %d", data1[i], data[i])
484 - }
485 - }
486 - c.Assert(string(data[len(data1):]), check.Equals, string(data2))
487 -}
488 -
489 -type multiList []*s3.Multi
490 -
491 -func (l multiList) Len() int { return len(l) }
492 -func (l multiList) Less(i, j int) bool { return l[i].Key < l[j].Key }
493 -func (l multiList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
494 -
495 -func (s *ClientTests) TestListMulti(c *check.C) {
496 - b := testBucket(s.s3)
497 - err := b.PutBucket(s3.Private)
498 - c.Assert(err, check.IsNil)
499 -
500 - // Ensure an empty state before testing its behavior.
501 - multis, _, err := b.ListMulti("", "")
502 - for _, m := range multis {
503 - err := m.Abort()
504 - c.Assert(err, check.IsNil)
505 - }
506 -
507 - keys := []string{
508 - "a/multi2",
509 - "a/multi3",
510 - "b/multi4",
511 - "multi1",
512 - }
513 - for _, key := range keys {
514 - m, err := b.InitMulti(key, "", s3.Private, s3.Options{})
515 - c.Assert(err, check.IsNil)
516 - defer m.Abort()
517 - }
518 -
519 - // Amazon's implementation of the multiple-request listing for
520 - // multipart uploads in progress seems broken in multiple ways.
521 - // (next tokens are not provided, etc).
522 - //s3.SetListMultiMax(2)
523 -
524 - multis, prefixes, err := b.ListMulti("", "")
525 - c.Assert(err, check.IsNil)
526 - for attempt := attempts.Start(); attempt.Next() && len(multis) < len(keys); {
527 - multis, prefixes, err = b.ListMulti("", "")
528 - c.Assert(err, check.IsNil)
529 - }
530 - sort.Sort(multiList(multis))
531 - c.Assert(prefixes, check.IsNil)
532 - var gotKeys []string
533 - for _, m := range multis {
534 - gotKeys = append(gotKeys, m.Key)
535 - }
536 - c.Assert(gotKeys, check.DeepEquals, keys)
537 - for _, m := range multis {
538 - c.Assert(m.Bucket, check.Equals, b)
539 - c.Assert(m.UploadId, check.Matches, ".+")
540 - }
541 -
542 - multis, prefixes, err = b.ListMulti("", "/")
543 - for attempt := attempts.Start(); attempt.Next() && len(prefixes) < 2; {
544 - multis, prefixes, err = b.ListMulti("", "")
545 - c.Assert(err, check.IsNil)
546 - }
547 - c.Assert(err, check.IsNil)
548 - c.Assert(prefixes, check.DeepEquals, []string{"a/", "b/"})
549 - c.Assert(multis, check.HasLen, 1)
550 - c.Assert(multis[0].Bucket, check.Equals, b)
551 - c.Assert(multis[0].Key, check.Equals, "multi1")
552 - c.Assert(multis[0].UploadId, check.Matches, ".+")
553 -
554 - for attempt := attempts.Start(); attempt.Next() && len(multis) < 2; {
555 - multis, prefixes, err = b.ListMulti("", "")
556 - c.Assert(err, check.IsNil)
557 - }
558 - multis, prefixes, err = b.ListMulti("a/", "/")
559 - c.Assert(err, check.IsNil)
560 - c.Assert(prefixes, check.IsNil)
561 - c.Assert(multis, check.HasLen, 2)
562 - c.Assert(multis[0].Bucket, check.Equals, b)
563 - c.Assert(multis[0].Key, check.Equals, "a/multi2")
564 - c.Assert(multis[0].UploadId, check.Matches, ".+")
565 - c.Assert(multis[1].Bucket, check.Equals, b)
566 - c.Assert(multis[1].Key, check.Equals, "a/multi3")
567 - c.Assert(multis[1].UploadId, check.Matches, ".+")
568 -}
569 -
570 -func (s *ClientTests) TestMultiPutAllZeroLength(c *check.C) {
571 - b := testBucket(s.s3)
572 - err := b.PutBucket(s3.Private)
573 - c.Assert(err, check.IsNil)
574 -
575 - multi, err := b.InitMulti("multi", "text/plain", s3.Private, s3.Options{})
576 - c.Assert(err, check.IsNil)
577 - defer multi.Abort()
578 -
579 - // This tests an edge case. Amazon requires at least one
580 - // part for multiprat uploads to work, even the part is empty.
581 - parts, err := multi.PutAll(strings.NewReader(""), 5*1024*1024)
582 - c.Assert(err, check.IsNil)
583 - c.Assert(parts, check.HasLen, 1)
584 - c.Assert(parts[0].Size, check.Equals, int64(0))
585 - c.Assert(parts[0].ETag, check.Equals, `"d41d8cd98f00b204e9800998ecf8427e"`)
586 -
587 - err = multi.Complete(parts)
588 - c.Assert(err, check.IsNil)
589 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/s3t_test.go deleted
-79
@@ -1,79 +0,0 @@
1 -package s3_test
2 -
3 -import (
4 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
5 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
6 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3/s3test"
7 - "gopkg.in/check.v1"
8 -)
9 -
10 -type LocalServer struct {
11 - auth aws.Auth
12 - region aws.Region
13 - srv *s3test.Server
14 - config *s3test.Config
15 -}
16 -
17 -func (s *LocalServer) SetUp(c *check.C) {
18 - srv, err := s3test.NewServer(s.config)
19 - c.Assert(err, check.IsNil)
20 - c.Assert(srv, check.NotNil)
21 -
22 - s.srv = srv
23 - s.region = aws.Region{
24 - Name: "faux-region-1",
25 - S3Endpoint: srv.URL(),
26 - S3LocationConstraint: true, // s3test server requires a LocationConstraint
27 - }
28 -}
29 -
30 -// LocalServerSuite defines tests that will run
31 -// against the local s3test server. It includes
32 -// selected tests from ClientTests;
33 -// when the s3test functionality is sufficient, it should
34 -// include all of them, and ClientTests can be simply embedded.
35 -type LocalServerSuite struct {
36 - srv LocalServer
37 - clientTests ClientTests
38 -}
39 -
40 -var (
41 - // run tests twice, once in us-east-1 mode, once not.
42 - _ = check.Suite(&LocalServerSuite{})
43 - _ = check.Suite(&LocalServerSuite{
44 - srv: LocalServer{
45 - config: &s3test.Config{
46 - Send409Conflict: true,
47 - },
48 - },
49 - })
50 -)
51 -
52 -func (s *LocalServerSuite) SetUpSuite(c *check.C) {
53 - s.srv.SetUp(c)
54 - s.clientTests.s3 = s3.New(s.srv.auth, s.srv.region)
55 -
56 - // TODO Sadly the fake server ignores auth completely right now. :-(
57 - s.clientTests.authIsBroken = true
58 - s.clientTests.Cleanup()
59 -}
60 -
61 -func (s *LocalServerSuite) TearDownTest(c *check.C) {
62 - s.clientTests.Cleanup()
63 -}
64 -
65 -func (s *LocalServerSuite) TestBasicFunctionality(c *check.C) {
66 - s.clientTests.TestBasicFunctionality(c)
67 -}
68 -
69 -func (s *LocalServerSuite) TestGetNotFound(c *check.C) {
70 - s.clientTests.TestGetNotFound(c)
71 -}
72 -
73 -func (s *LocalServerSuite) TestBucketList(c *check.C) {
74 - s.clientTests.TestBucketList(c)
75 -}
76 -
77 -func (s *LocalServerSuite) TestDoublePutBucket(c *check.C) {
78 - s.clientTests.TestDoublePutBucket(c)
79 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/s3test/server.go deleted
-629
@@ -1,629 +0,0 @@
1 -package s3test
2 -
3 -import (
4 - "bytes"
5 - "crypto/md5"
6 - "encoding/base64"
7 - "encoding/hex"
8 - "encoding/xml"
9 - "fmt"
10 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
11 - "io"
12 - "io/ioutil"
13 - "log"
14 - "net"
15 - "net/http"
16 - "net/url"
17 - "regexp"
18 - "sort"
19 - "strconv"
20 - "strings"
21 - "sync"
22 - "time"
23 -)
24 -
25 -const debug = false
26 -
27 -type s3Error struct {
28 - statusCode int
29 - XMLName struct{} `xml:"Error"`
30 - Code string
31 - Message string
32 - BucketName string
33 - RequestId string
34 - HostId string
35 -}
36 -
37 -type action struct {
38 - srv *Server
39 - w http.ResponseWriter
40 - req *http.Request
41 - reqId string
42 -}
43 -
44 -// Config controls the internal behaviour of the Server. A nil config is the default
45 -// and behaves as if all configurations assume their default behaviour. Once passed
46 -// to NewServer, the configuration must not be modified.
47 -type Config struct {
48 - // Send409Conflict controls how the Server will respond to calls to PUT on a
49 - // previously existing bucket. The default is false, and corresponds to the
50 - // us-east-1 s3 enpoint. Setting this value to true emulates the behaviour of
51 - // all other regions.
52 - // http://docs.amazonwebservices.com/AmazonS3/latest/API/ErrorResponses.html
53 - Send409Conflict bool
54 -}
55 -
56 -func (c *Config) send409Conflict() bool {
57 - if c != nil {
58 - return c.Send409Conflict
59 - }
60 - return false
61 -}
62 -
63 -// Server is a fake S3 server for testing purposes.
64 -// All of the data for the server is kept in memory.
65 -type Server struct {
66 - url string
67 - reqId int
68 - listener net.Listener
69 - mu sync.Mutex
70 - buckets map[string]*bucket
71 - config *Config
72 -}
73 -
74 -type bucket struct {
75 - name string
76 - acl s3.ACL
77 - ctime time.Time
78 - objects map[string]*object
79 -}
80 -
81 -type object struct {
82 - name string
83 - mtime time.Time
84 - meta http.Header // metadata to return with requests.
85 - checksum []byte // also held as Content-MD5 in meta.
86 - data []byte
87 -}
88 -
89 -// A resource encapsulates the subject of an HTTP request.
90 -// The resource referred to may or may not exist
91 -// when the request is made.
92 -type resource interface {
93 - put(a *action) interface{}
94 - get(a *action) interface{}
95 - post(a *action) interface{}
96 - delete(a *action) interface{}
97 -}
98 -
99 -func NewServer(config *Config) (*Server, error) {
100 - l, err := net.Listen("tcp", "localhost:0")
101 - if err != nil {
102 - return nil, fmt.Errorf("cannot listen on localhost: %v", err)
103 - }
104 - srv := &Server{
105 - listener: l,
106 - url: "http://" + l.Addr().String(),
107 - buckets: make(map[string]*bucket),
108 - config: config,
109 - }
110 - go http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
111 - srv.serveHTTP(w, req)
112 - }))
113 - return srv, nil
114 -}
115 -
116 -// Quit closes down the server.
117 -func (srv *Server) Quit() {
118 - srv.listener.Close()
119 -}
120 -
121 -// URL returns a URL for the server.
122 -func (srv *Server) URL() string {
123 - return srv.url
124 -}
125 -
126 -func fatalf(code int, codeStr string, errf string, a ...interface{}) {
127 - panic(&s3Error{
128 - statusCode: code,
129 - Code: codeStr,
130 - Message: fmt.Sprintf(errf, a...),
131 - })
132 -}
133 -
134 -// serveHTTP serves the S3 protocol.
135 -func (srv *Server) serveHTTP(w http.ResponseWriter, req *http.Request) {
136 - // ignore error from ParseForm as it's usually spurious.
137 - req.ParseForm()
138 -
139 - srv.mu.Lock()
140 - defer srv.mu.Unlock()
141 -
142 - if debug {
143 - log.Printf("s3test %q %q", req.Method, req.URL)
144 - }
145 - a := &action{
146 - srv: srv,
147 - w: w,
148 - req: req,
149 - reqId: fmt.Sprintf("%09X", srv.reqId),
150 - }
151 - srv.reqId++
152 -
153 - var r resource
154 - defer func() {
155 - switch err := recover().(type) {
156 - case *s3Error:
157 - switch r := r.(type) {
158 - case objectResource:
159 - err.BucketName = r.bucket.name
160 - case bucketResource:
161 - err.BucketName = r.name
162 - }
163 - err.RequestId = a.reqId
164 - // TODO HostId
165 - w.Header().Set("Content-Type", `xml version="1.0" encoding="UTF-8"`)
166 - w.WriteHeader(err.statusCode)
167 - xmlMarshal(w, err)
168 - case nil:
169 - default:
170 - panic(err)
171 - }
172 - }()
173 -
174 - r = srv.resourceForURL(req.URL)
175 -
176 - var resp interface{}
177 - switch req.Method {
178 - case "PUT":
179 - resp = r.put(a)
180 - case "GET", "HEAD":
181 - resp = r.get(a)
182 - case "DELETE":
183 - resp = r.delete(a)
184 - case "POST":
185 - resp = r.post(a)
186 - default:
187 - fatalf(400, "MethodNotAllowed", "unknown http request method %q", req.Method)
188 - }
189 - if resp != nil && req.Method != "HEAD" {
190 - xmlMarshal(w, resp)
191 - }
192 -}
193 -
194 -// xmlMarshal is the same as xml.Marshal except that
195 -// it panics on error. The marshalling should not fail,
196 -// but we want to know if it does.
197 -func xmlMarshal(w io.Writer, x interface{}) {
198 - if err := xml.NewEncoder(w).Encode(x); err != nil {
199 - panic(fmt.Errorf("error marshalling %#v: %v", x, err))
200 - }
201 -}
202 -
203 -// In a fully implemented test server, each of these would have
204 -// its own resource type.
205 -var unimplementedBucketResourceNames = map[string]bool{
206 - "acl": true,
207 - "lifecycle": true,
208 - "policy": true,
209 - "location": true,
210 - "logging": true,
211 - "notification": true,
212 - "versions": true,
213 - "requestPayment": true,
214 - "versioning": true,
215 - "website": true,
216 - "uploads": true,
217 -}
218 -
219 -var unimplementedObjectResourceNames = map[string]bool{
220 - "uploadId": true,
221 - "acl": true,
222 - "torrent": true,
223 - "uploads": true,
224 -}
225 -
226 -var pathRegexp = regexp.MustCompile("/(([^/]+)(/(.*))?)?")
227 -
228 -// resourceForURL returns a resource object for the given URL.
229 -func (srv *Server) resourceForURL(u *url.URL) (r resource) {
230 - m := pathRegexp.FindStringSubmatch(u.Path)
231 - if m == nil {
232 - fatalf(404, "InvalidURI", "Couldn't parse the specified URI")
233 - }
234 - bucketName := m[2]
235 - objectName := m[4]
236 - if bucketName == "" {
237 - return nullResource{} // root
238 - }
239 - b := bucketResource{
240 - name: bucketName,
241 - bucket: srv.buckets[bucketName],
242 - }
243 - q := u.Query()
244 - if objectName == "" {
245 - for name := range q {
246 - if unimplementedBucketResourceNames[name] {
247 - return nullResource{}
248 - }
249 - }
250 - return b
251 -
252 - }
253 - if b.bucket == nil {
254 - fatalf(404, "NoSuchBucket", "The specified bucket does not exist")
255 - }
256 - objr := objectResource{
257 - name: objectName,
258 - version: q.Get("versionId"),
259 - bucket: b.bucket,
260 - }
261 - for name := range q {
262 - if unimplementedObjectResourceNames[name] {
263 - return nullResource{}
264 - }
265 - }
266 - if obj := objr.bucket.objects[objr.name]; obj != nil {
267 - objr.object = obj
268 - }
269 - return objr
270 -}
271 -
272 -// nullResource has error stubs for all resource methods.
273 -type nullResource struct{}
274 -
275 -func notAllowed() interface{} {
276 - fatalf(400, "MethodNotAllowed", "The specified method is not allowed against this resource")
277 - return nil
278 -}
279 -
280 -func (nullResource) put(a *action) interface{} { return notAllowed() }
281 -func (nullResource) get(a *action) interface{} { return notAllowed() }
282 -func (nullResource) post(a *action) interface{} { return notAllowed() }
283 -func (nullResource) delete(a *action) interface{} { return notAllowed() }
284 -
285 -const timeFormat = "2006-01-02T15:04:05.000Z07:00"
286 -
287 -type bucketResource struct {
288 - name string
289 - bucket *bucket // non-nil if the bucket already exists.
290 -}
291 -
292 -// GET on a bucket lists the objects in the bucket.
293 -// http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGET.html
294 -func (r bucketResource) get(a *action) interface{} {
295 - if r.bucket == nil {
296 - fatalf(404, "NoSuchBucket", "The specified bucket does not exist")
297 - }
298 - delimiter := a.req.Form.Get("delimiter")
299 - marker := a.req.Form.Get("marker")
300 - maxKeys := -1
301 - if s := a.req.Form.Get("max-keys"); s != "" {
302 - i, err := strconv.Atoi(s)
303 - if err != nil || i < 0 {
304 - fatalf(400, "invalid value for max-keys: %q", s)
305 - }
306 - maxKeys = i
307 - }
308 - prefix := a.req.Form.Get("prefix")
309 - a.w.Header().Set("Content-Type", "application/xml")
310 -
311 - if a.req.Method == "HEAD" {
312 - return nil
313 - }
314 -
315 - var objs orderedObjects
316 -
317 - // first get all matching objects and arrange them in alphabetical order.
318 - for name, obj := range r.bucket.objects {
319 - if strings.HasPrefix(name, prefix) {
320 - objs = append(objs, obj)
321 - }
322 - }
323 - sort.Sort(objs)
324 -
325 - if maxKeys <= 0 {
326 - maxKeys = 1000
327 - }
328 - resp := &s3.ListResp{
329 - Name: r.bucket.name,
330 - Prefix: prefix,
331 - Delimiter: delimiter,
332 - Marker: marker,
333 - MaxKeys: maxKeys,
334 - }
335 -
336 - var prefixes []string
337 - for _, obj := range objs {
338 - if !strings.HasPrefix(obj.name, prefix) {
339 - continue
340 - }
341 - name := obj.name
342 - isPrefix := false
343 - if delimiter != "" {
344 - if i := strings.Index(obj.name[len(prefix):], delimiter); i >= 0 {
345 - name = obj.name[:len(prefix)+i+len(delimiter)]
346 - if prefixes != nil && prefixes[len(prefixes)-1] == name {
347 - continue
348 - }
349 - isPrefix = true
350 - }
351 - }
352 - if name <= marker {
353 - continue
354 - }
355 - if len(resp.Contents)+len(prefixes) >= maxKeys {
356 - resp.IsTruncated = true
357 - break
358 - }
359 - if isPrefix {
360 - prefixes = append(prefixes, name)
361 - } else {
362 - // Contents contains only keys not found in CommonPrefixes
363 - resp.Contents = append(resp.Contents, obj.s3Key())
364 - }
365 - }
366 - resp.CommonPrefixes = prefixes
367 - return resp
368 -}
369 -
370 -// orderedObjects holds a slice of objects that can be sorted
371 -// by name.
372 -type orderedObjects []*object
373 -
374 -func (s orderedObjects) Len() int {
375 - return len(s)
376 -}
377 -func (s orderedObjects) Swap(i, j int) {
378 - s[i], s[j] = s[j], s[i]
379 -}
380 -func (s orderedObjects) Less(i, j int) bool {
381 - return s[i].name < s[j].name
382 -}
383 -
384 -func (obj *object) s3Key() s3.Key {
385 - return s3.Key{
386 - Key: obj.name,
387 - LastModified: obj.mtime.Format(timeFormat),
388 - Size: int64(len(obj.data)),
389 - ETag: fmt.Sprintf(`"%x"`, obj.checksum),
390 - // TODO StorageClass
391 - // TODO Owner
392 - }
393 -}
394 -
395 -// DELETE on a bucket deletes the bucket if it's not empty.
396 -func (r bucketResource) delete(a *action) interface{} {
397 - b := r.bucket
398 - if b == nil {
399 - fatalf(404, "NoSuchBucket", "The specified bucket does not exist")
400 - }
401 - if len(b.objects) > 0 {
402 - fatalf(400, "BucketNotEmpty", "The bucket you tried to delete is not empty")
403 - }
404 - delete(a.srv.buckets, b.name)
405 - return nil
406 -}
407 -
408 -// PUT on a bucket creates the bucket.
409 -// http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html
410 -func (r bucketResource) put(a *action) interface{} {
411 - var created bool
412 - if r.bucket == nil {
413 - if !validBucketName(r.name) {
414 - fatalf(400, "InvalidBucketName", "The specified bucket is not valid")
415 - }
416 - if loc := locationConstraint(a); loc == "" {
417 - fatalf(400, "InvalidRequets", "The unspecified location constraint is incompatible for the region specific endpoint this request was sent to.")
418 - }
419 - // TODO validate acl
420 - r.bucket = &bucket{
421 - name: r.name,
422 - // TODO default acl
423 - objects: make(map[string]*object),
424 - }
425 - a.srv.buckets[r.name] = r.bucket
426 - created = true
427 - }
428 - if !created && a.srv.config.send409Conflict() {
429 - fatalf(409, "BucketAlreadyOwnedByYou", "Your previous request to create the named bucket succeeded and you already own it.")
430 - }
431 - r.bucket.acl = s3.ACL(a.req.Header.Get("x-amz-acl"))
432 - return nil
433 -}
434 -
435 -func (bucketResource) post(a *action) interface{} {
436 - fatalf(400, "Method", "bucket POST method not available")
437 - return nil
438 -}
439 -
440 -// validBucketName returns whether name is a valid bucket name.
441 -// Here are the rules, from:
442 -// http://docs.amazonwebservices.com/AmazonS3/2006-03-01/dev/BucketRestrictions.html
443 -//
444 -// Can contain lowercase letters, numbers, periods (.), underscores (_),
445 -// and dashes (-). You can use uppercase letters for buckets only in the
446 -// US Standard region.
447 -//
448 -// Must start with a number or letter
449 -//
450 -// Must be between 3 and 255 characters long
451 -//
452 -// There's one extra rule (Must not be formatted as an IP address (e.g., 192.168.5.4)
453 -// but the real S3 server does not seem to check that rule, so we will not
454 -// check it either.
455 -//
456 -func validBucketName(name string) bool {
457 - if len(name) < 3 || len(name) > 255 {
458 - return false
459 - }
460 - r := name[0]
461 - if !(r >= '0' && r <= '9' || r >= 'a' && r <= 'z') {
462 - return false
463 - }
464 - for _, r := range name {
465 - switch {
466 - case r >= '0' && r <= '9':
467 - case r >= 'a' && r <= 'z':
468 - case r == '_' || r == '-':
469 - case r == '.':
470 - default:
471 - return false
472 - }
473 - }
474 - return true
475 -}
476 -
477 -var responseParams = map[string]bool{
478 - "content-type": true,
479 - "content-language": true,
480 - "expires": true,
481 - "cache-control": true,
482 - "content-disposition": true,
483 - "content-encoding": true,
484 -}
485 -
486 -type objectResource struct {
487 - name string
488 - version string
489 - bucket *bucket // always non-nil.
490 - object *object // may be nil.
491 -}
492 -
493 -// GET on an object gets the contents of the object.
494 -// http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html
495 -func (objr objectResource) get(a *action) interface{} {
496 - obj := objr.object
497 - if obj == nil {
498 - fatalf(404, "NoSuchKey", "The specified key does not exist.")
499 - }
500 - h := a.w.Header()
501 - // add metadata
502 - for name, d := range obj.meta {
503 - h[name] = d
504 - }
505 - // override header values in response to request parameters.
506 - for name, vals := range a.req.Form {
507 - if strings.HasPrefix(name, "response-") {
508 - name = name[len("response-"):]
509 - if !responseParams[name] {
510 - continue
511 - }
512 - h.Set(name, vals[0])
513 - }
514 - }
515 - if r := a.req.Header.Get("Range"); r != "" {
516 - fatalf(400, "NotImplemented", "range unimplemented")
517 - }
518 - // TODO Last-Modified-Since
519 - // TODO If-Modified-Since
520 - // TODO If-Unmodified-Since
521 - // TODO If-Match
522 - // TODO If-None-Match
523 - // TODO Connection: close ??
524 - // TODO x-amz-request-id
525 - h.Set("Content-Length", fmt.Sprint(len(obj.data)))
526 - h.Set("ETag", hex.EncodeToString(obj.checksum))
527 - h.Set("Last-Modified", obj.mtime.Format(time.RFC1123))
528 - if a.req.Method == "HEAD" {
529 - return nil
530 - }
531 - // TODO avoid holding the lock when writing data.
532 - _, err := a.w.Write(obj.data)
533 - if err != nil {
534 - // we can't do much except just log the fact.
535 - log.Printf("error writing data: %v", err)
536 - }
537 - return nil
538 -}
539 -
540 -var metaHeaders = map[string]bool{
541 - "Content-MD5": true,
542 - "x-amz-acl": true,
543 - "Content-Type": true,
544 - "Content-Encoding": true,
545 - "Content-Disposition": true,
546 -}
547 -
548 -// PUT on an object creates the object.
549 -func (objr objectResource) put(a *action) interface{} {
550 - // TODO Cache-Control header
551 - // TODO Expires header
552 - // TODO x-amz-server-side-encryption
553 - // TODO x-amz-storage-class
554 -
555 - // TODO is this correct, or should we erase all previous metadata?
556 - obj := objr.object
557 - if obj == nil {
558 - obj = &object{
559 - name: objr.name,
560 - meta: make(http.Header),
561 - }
562 - }
563 -
564 - var expectHash []byte
565 - if c := a.req.Header.Get("Content-MD5"); c != "" {
566 - var err error
567 - expectHash, err = base64.StdEncoding.DecodeString(c)
568 - if err != nil || len(expectHash) != md5.Size {
569 - fatalf(400, "InvalidDigest", "The Content-MD5 you specified was invalid")
570 - }
571 - }
572 - sum := md5.New()
573 - // TODO avoid holding lock while reading data.
574 - data, err := ioutil.ReadAll(io.TeeReader(a.req.Body, sum))
575 - if err != nil {
576 - fatalf(400, "TODO", "read error")
577 - }
578 - gotHash := sum.Sum(nil)
579 - if expectHash != nil && bytes.Compare(gotHash, expectHash) != 0 {
580 - fatalf(400, "BadDigest", "The Content-MD5 you specified did not match what we received")
581 - }
582 - if a.req.ContentLength >= 0 && int64(len(data)) != a.req.ContentLength {
583 - fatalf(400, "IncompleteBody", "You did not provide the number of bytes specified by the Content-Length HTTP header")
584 - }
585 -
586 - // PUT request has been successful - save data and metadata
587 - for key, values := range a.req.Header {
588 - key = http.CanonicalHeaderKey(key)
589 - if metaHeaders[key] || strings.HasPrefix(key, "X-Amz-Meta-") {
590 - obj.meta[key] = values
591 - }
592 - }
593 - obj.data = data
594 - obj.checksum = gotHash
595 - obj.mtime = time.Now()
596 - objr.bucket.objects[objr.name] = obj
597 - return nil
598 -}
599 -
600 -func (objr objectResource) delete(a *action) interface{} {
601 - delete(objr.bucket.objects, objr.name)
602 - return nil
603 -}
604 -
605 -func (objr objectResource) post(a *action) interface{} {
606 - fatalf(400, "MethodNotAllowed", "The specified method is not allowed against this resource")
607 - return nil
608 -}
609 -
610 -type CreateBucketConfiguration struct {
611 - LocationConstraint string
612 -}
613 -
614 -// locationConstraint parses the <CreateBucketConfiguration /> request body (if present).
615 -// If there is no body, an empty string will be returned.
616 -func locationConstraint(a *action) string {
617 - var body bytes.Buffer
618 - if _, err := io.Copy(&body, a.req.Body); err != nil {
619 - fatalf(400, "InvalidRequest", err.Error())
620 - }
621 - if body.Len() == 0 {
622 - return ""
623 - }
624 - var loc CreateBucketConfiguration
625 - if err := xml.NewDecoder(&body).Decode(&loc); err != nil {
626 - fatalf(400, "InvalidRequest", err.Error())
627 - }
628 - return loc.LocationConstraint
629 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/sign.go deleted
-120
@@ -1,120 +0,0 @@
1 -package s3
2 -
3 -import (
4 - "crypto/hmac"
5 - "crypto/sha1"
6 - "encoding/base64"
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
8 - "log"
9 - "sort"
10 - "strings"
11 -)
12 -
13 -var b64 = base64.StdEncoding
14 -
15 -// ----------------------------------------------------------------------------
16 -// S3 signing (http://goo.gl/G1LrK)
17 -
18 -var s3ParamsToSign = map[string]bool{
19 - "acl": true,
20 - "location": true,
21 - "logging": true,
22 - "notification": true,
23 - "partNumber": true,
24 - "policy": true,
25 - "requestPayment": true,
26 - "torrent": true,
27 - "uploadId": true,
28 - "uploads": true,
29 - "versionId": true,
30 - "versioning": true,
31 - "versions": true,
32 - "response-content-type": true,
33 - "response-content-language": true,
34 - "response-expires": true,
35 - "response-cache-control": true,
36 - "response-content-disposition": true,
37 - "response-content-encoding": true,
38 - "website": true,
39 - "delete": true,
40 -}
41 -
42 -func sign(auth aws.Auth, method, canonicalPath string, params, headers map[string][]string) {
43 - var md5, ctype, date, xamz string
44 - var xamzDate bool
45 - var keys, sarray []string
46 - xheaders := make(map[string]string)
47 - for k, v := range headers {
48 - k = strings.ToLower(k)
49 - switch k {
50 - case "content-md5":
51 - md5 = v[0]
52 - case "content-type":
53 - ctype = v[0]
54 - case "date":
55 - if !xamzDate {
56 - date = v[0]
57 - }
58 - default:
59 - if strings.HasPrefix(k, "x-amz-") {
60 - keys = append(keys, k)
61 - xheaders[k] = strings.Join(v, ",")
62 - if k == "x-amz-date" {
63 - xamzDate = true
64 - date = ""
65 - }
66 - }
67 - }
68 - }
69 - if len(keys) > 0 {
70 - sort.StringSlice(keys).Sort()
71 - for i := range keys {
72 - key := keys[i]
73 - value := xheaders[key]
74 - sarray = append(sarray, key+":"+value)
75 - }
76 - xamz = strings.Join(sarray, "\n") + "\n"
77 - }
78 -
79 - expires := false
80 - if v, ok := params["Expires"]; ok {
81 - // Query string request authentication alternative.
82 - expires = true
83 - date = v[0]
84 - params["AWSAccessKeyId"] = []string{auth.AccessKey}
85 - }
86 -
87 - sarray = sarray[0:0]
88 - for k, v := range params {
89 - if s3ParamsToSign[k] {
90 - for _, vi := range v {
91 - if vi == "" {
92 - sarray = append(sarray, k)
93 - } else {
94 - // "When signing you do not encode these values."
95 - sarray = append(sarray, k+"="+vi)
96 - }
97 - }
98 - }
99 - }
100 - if len(sarray) > 0 {
101 - sort.StringSlice(sarray).Sort()
102 - canonicalPath = canonicalPath + "?" + strings.Join(sarray, "&")
103 - }
104 -
105 - payload := method + "\n" + md5 + "\n" + ctype + "\n" + date + "\n" + xamz + canonicalPath
106 - hash := hmac.New(sha1.New, []byte(auth.SecretKey))
107 - hash.Write([]byte(payload))
108 - signature := make([]byte, b64.EncodedLen(hash.Size()))
109 - b64.Encode(signature, hash.Sum(nil))
110 -
111 - if expires {
112 - params["Signature"] = []string{string(signature)}
113 - } else {
114 - headers["Authorization"] = []string{"AWS " + auth.AccessKey + ":" + string(signature)}
115 - }
116 - if debug {
117 - log.Printf("Signature payload: %q", payload)
118 - log.Printf("Signature: %q", signature)
119 - }
120 -}
Godeps/_workspace/src/github.com/crowdmob/goamz/s3/sign_test.go deleted
-148
@@ -1,148 +0,0 @@
1 -package s3_test
2 -
3 -import (
4 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
5 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
6 - "gopkg.in/check.v1"
7 -)
8 -
9 -// S3 ReST authentication docs: http://goo.gl/G1LrK
10 -
11 -var testAuth = aws.Auth{AccessKey: "0PN5J17HBGZHT7JJ3X82", SecretKey: "uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o"}
12 -
13 -func (s *S) TestSignExampleObjectGet(c *check.C) {
14 - method := "GET"
15 - path := "/johnsmith/photos/puppy.jpg"
16 - headers := map[string][]string{
17 - "Host": {"johnsmith.s3.amazonaws.com"},
18 - "Date": {"Tue, 27 Mar 2007 19:36:42 +0000"},
19 - }
20 - s3.Sign(testAuth, method, path, nil, headers)
21 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:xXjDGYUmKxnwqr5KXNPGldn5LbA="
22 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
23 -}
24 -
25 -func (s *S) TestSignExampleObjectPut(c *check.C) {
26 - method := "PUT"
27 - path := "/johnsmith/photos/puppy.jpg"
28 - headers := map[string][]string{
29 - "Host": {"johnsmith.s3.amazonaws.com"},
30 - "Date": {"Tue, 27 Mar 2007 21:15:45 +0000"},
31 - "Content-Type": {"image/jpeg"},
32 - "Content-Length": {"94328"},
33 - }
34 - s3.Sign(testAuth, method, path, nil, headers)
35 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:hcicpDDvL9SsO6AkvxqmIWkmOuQ="
36 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
37 -}
38 -
39 -func (s *S) TestSignExampleList(c *check.C) {
40 - method := "GET"
41 - path := "/johnsmith/"
42 - params := map[string][]string{
43 - "prefix": {"photos"},
44 - "max-keys": {"50"},
45 - "marker": {"puppy"},
46 - }
47 - headers := map[string][]string{
48 - "Host": {"johnsmith.s3.amazonaws.com"},
49 - "Date": {"Tue, 27 Mar 2007 19:42:41 +0000"},
50 - "User-Agent": {"Mozilla/5.0"},
51 - }
52 - s3.Sign(testAuth, method, path, params, headers)
53 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:jsRt/rhG+Vtp88HrYL706QhE4w4="
54 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
55 -}
56 -
57 -func (s *S) TestSignExampleFetch(c *check.C) {
58 - method := "GET"
59 - path := "/johnsmith/"
60 - params := map[string][]string{
61 - "acl": {""},
62 - }
63 - headers := map[string][]string{
64 - "Host": {"johnsmith.s3.amazonaws.com"},
65 - "Date": {"Tue, 27 Mar 2007 19:44:46 +0000"},
66 - }
67 - s3.Sign(testAuth, method, path, params, headers)
68 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:thdUi9VAkzhkniLj96JIrOPGi0g="
69 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
70 -}
71 -
72 -func (s *S) TestSignExampleDelete(c *check.C) {
73 - method := "DELETE"
74 - path := "/johnsmith/photos/puppy.jpg"
75 - params := map[string][]string{}
76 - headers := map[string][]string{
77 - "Host": {"s3.amazonaws.com"},
78 - "Date": {"Tue, 27 Mar 2007 21:20:27 +0000"},
79 - "User-Agent": {"dotnet"},
80 - "x-amz-date": {"Tue, 27 Mar 2007 21:20:26 +0000"},
81 - }
82 - s3.Sign(testAuth, method, path, params, headers)
83 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:k3nL7gH3+PadhTEVn5Ip83xlYzk="
84 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
85 -}
86 -
87 -func (s *S) TestSignExampleUpload(c *check.C) {
88 - method := "PUT"
89 - path := "/static.johnsmith.net/db-backup.dat.gz"
90 - params := map[string][]string{}
91 - headers := map[string][]string{
92 - "Host": {"static.johnsmith.net:8080"},
93 - "Date": {"Tue, 27 Mar 2007 21:06:08 +0000"},
94 - "User-Agent": {"curl/7.15.5"},
95 - "x-amz-acl": {"public-read"},
96 - "content-type": {"application/x-download"},
97 - "Content-MD5": {"4gJE4saaMU4BqNR0kLY+lw=="},
98 - "X-Amz-Meta-ReviewedBy": {"joe@johnsmith.net,jane@johnsmith.net"},
99 - "X-Amz-Meta-FileChecksum": {"0x02661779"},
100 - "X-Amz-Meta-ChecksumAlgorithm": {"crc32"},
101 - "Content-Disposition": {"attachment; filename=database.dat"},
102 - "Content-Encoding": {"gzip"},
103 - "Content-Length": {"5913339"},
104 - }
105 - s3.Sign(testAuth, method, path, params, headers)
106 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:C0FlOtU8Ylb9KDTpZqYkZPX91iI="
107 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
108 -}
109 -
110 -func (s *S) TestSignExampleListAllMyBuckets(c *check.C) {
111 - method := "GET"
112 - path := "/"
113 - headers := map[string][]string{
114 - "Host": {"s3.amazonaws.com"},
115 - "Date": {"Wed, 28 Mar 2007 01:29:59 +0000"},
116 - }
117 - s3.Sign(testAuth, method, path, nil, headers)
118 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:Db+gepJSUbZKwpx1FR0DLtEYoZA="
119 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
120 -}
121 -
122 -func (s *S) TestSignExampleUnicodeKeys(c *check.C) {
123 - method := "GET"
124 - path := "/dictionary/fran%C3%A7ais/pr%c3%a9f%c3%a8re"
125 - headers := map[string][]string{
126 - "Host": {"s3.amazonaws.com"},
127 - "Date": {"Wed, 28 Mar 2007 01:49:49 +0000"},
128 - }
129 - s3.Sign(testAuth, method, path, nil, headers)
130 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:dxhSBHoI6eVSPcXJqEghlUzZMnY="
131 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
132 -}
133 -
134 -func (s *S) TestSignExampleCustomSSE(c *check.C) {
135 - method := "GET"
136 - path := "/secret/config"
137 - params := map[string][]string{}
138 - headers := map[string][]string{
139 - "Host": {"secret.johnsmith.net:8080"},
140 - "Date": {"Tue, 27 Mar 2007 21:06:08 +0000"},
141 - "x-amz-server-side-encryption-customer-key": {"MWJhakVna1dQT1B0SDFMeGtVVnRQRTFGaU1ldFJrU0I="},
142 - "x-amz-server-side-encryption-customer-key-MD5": {"glIqxpqQ4a9aoK/iLttKzQ=="},
143 - "x-amz-server-side-encryption-customer-algorithm": {"AES256"},
144 - }
145 - s3.Sign(testAuth, method, path, params, headers)
146 - expected := "AWS 0PN5J17HBGZHT7JJ3X82:Xq6PWmIo0aOWq+LDjCEiCGgbmHE="
147 - c.Assert(headers["Authorization"], check.DeepEquals, []string{expected})
148 -}
Godeps/_workspace/src/github.com/fd/go-nat/LICENSE deleted
-191
@@ -1,191 +0,0 @@
1 -Apache License
2 -Version 2.0, January 2004
3 -http://www.apache.org/licenses/
4 -
5 -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 -
7 -1. Definitions.
8 -
9 -"License" shall mean the terms and conditions for use, reproduction, and
10 -distribution as defined by Sections 1 through 9 of this document.
11 -
12 -"Licensor" shall mean the copyright owner or entity authorized by the copyright
13 -owner that is granting the License.
14 -
15 -"Legal Entity" shall mean the union of the acting entity and all other entities
16 -that control, are controlled by, or are under common control with that entity.
17 -For the purposes of this definition, "control" means (i) the power, direct or
18 -indirect, to cause the direction or management of such entity, whether by
19 -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 -outstanding shares, or (iii) beneficial ownership of such entity.
21 -
22 -"You" (or "Your") shall mean an individual or Legal Entity exercising
23 -permissions granted by this License.
24 -
25 -"Source" form shall mean the preferred form for making modifications, including
26 -but not limited to software source code, documentation source, and configuration
27 -files.
28 -
29 -"Object" form shall mean any form resulting from mechanical transformation or
30 -translation of a Source form, including but not limited to compiled object code,
31 -generated documentation, and conversions to other media types.
32 -
33 -"Work" shall mean the work of authorship, whether in Source or Object form, made
34 -available under the License, as indicated by a copyright notice that is included
35 -in or attached to the work (an example is provided in the Appendix below).
36 -
37 -"Derivative Works" shall mean any work, whether in Source or Object form, that
38 -is based on (or derived from) the Work and for which the editorial revisions,
39 -annotations, elaborations, or other modifications represent, as a whole, an
40 -original work of authorship. For the purposes of this License, Derivative Works
41 -shall not include works that remain separable from, or merely link (or bind by
42 -name) to the interfaces of, the Work and Derivative Works thereof.
43 -
44 -"Contribution" shall mean any work of authorship, including the original version
45 -of the Work and any modifications or additions to that Work or Derivative Works
46 -thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 -by the copyright owner or by an individual or Legal Entity authorized to submit
48 -on behalf of the copyright owner. For the purposes of this definition,
49 -"submitted" means any form of electronic, verbal, or written communication sent
50 -to the Licensor or its representatives, including but not limited to
51 -communication on electronic mailing lists, source code control systems, and
52 -issue tracking systems that are managed by, or on behalf of, the Licensor for
53 -the purpose of discussing and improving the Work, but excluding communication
54 -that is conspicuously marked or otherwise designated in writing by the copyright
55 -owner as "Not a Contribution."
56 -
57 -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 -of whom a Contribution has been received by Licensor and subsequently
59 -incorporated within the Work.
60 -
61 -2. Grant of Copyright License.
62 -
63 -Subject to the terms and conditions of this License, each Contributor hereby
64 -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 -irrevocable copyright license to reproduce, prepare Derivative Works of,
66 -publicly display, publicly perform, sublicense, and distribute the Work and such
67 -Derivative Works in Source or Object form.
68 -
69 -3. Grant of Patent License.
70 -
71 -Subject to the terms and conditions of this License, each Contributor hereby
72 -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 -irrevocable (except as stated in this section) patent license to make, have
74 -made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 -such license applies only to those patent claims licensable by such Contributor
76 -that are necessarily infringed by their Contribution(s) alone or by combination
77 -of their Contribution(s) with the Work to which such Contribution(s) was
78 -submitted. If You institute patent litigation against any entity (including a
79 -cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 -Contribution incorporated within the Work constitutes direct or contributory
81 -patent infringement, then any patent licenses granted to You under this License
82 -for that Work shall terminate as of the date such litigation is filed.
83 -
84 -4. Redistribution.
85 -
86 -You may reproduce and distribute copies of the Work or Derivative Works thereof
87 -in any medium, with or without modifications, and in Source or Object form,
88 -provided that You meet the following conditions:
89 -
90 -You must give any other recipients of the Work or Derivative Works a copy of
91 -this License; and
92 -You must cause any modified files to carry prominent notices stating that You
93 -changed the files; and
94 -You must retain, in the Source form of any Derivative Works that You distribute,
95 -all copyright, patent, trademark, and attribution notices from the Source form
96 -of the Work, excluding those notices that do not pertain to any part of the
97 -Derivative Works; and
98 -If the Work includes a "NOTICE" text file as part of its distribution, then any
99 -Derivative Works that You distribute must include a readable copy of the
100 -attribution notices contained within such NOTICE file, excluding those notices
101 -that do not pertain to any part of the Derivative Works, in at least one of the
102 -following places: within a NOTICE text file distributed as part of the
103 -Derivative Works; within the Source form or documentation, if provided along
104 -with the Derivative Works; or, within a display generated by the Derivative
105 -Works, if and wherever such third-party notices normally appear. The contents of
106 -the NOTICE file are for informational purposes only and do not modify the
107 -License. You may add Your own attribution notices within Derivative Works that
108 -You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 -provided that such additional attribution notices cannot be construed as
110 -modifying the License.
111 -You may add Your own copyright statement to Your modifications and may provide
112 -additional or different license terms and conditions for use, reproduction, or
113 -distribution of Your modifications, or for any such Derivative Works as a whole,
114 -provided Your use, reproduction, and distribution of the Work otherwise complies
115 -with the conditions stated in this License.
116 -
117 -5. Submission of Contributions.
118 -
119 -Unless You explicitly state otherwise, any Contribution intentionally submitted
120 -for inclusion in the Work by You to the Licensor shall be under the terms and
121 -conditions of this License, without any additional terms or conditions.
122 -Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 -any separate license agreement you may have executed with Licensor regarding
124 -such Contributions.
125 -
126 -6. Trademarks.
127 -
128 -This License does not grant permission to use the trade names, trademarks,
129 -service marks, or product names of the Licensor, except as required for
130 -reasonable and customary use in describing the origin of the Work and
131 -reproducing the content of the NOTICE file.
132 -
133 -7. Disclaimer of Warranty.
134 -
135 -Unless required by applicable law or agreed to in writing, Licensor provides the
136 -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 -including, without limitation, any warranties or conditions of TITLE,
139 -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 -solely responsible for determining the appropriateness of using or
141 -redistributing the Work and assume any risks associated with Your exercise of
142 -permissions under this License.
143 -
144 -8. Limitation of Liability.
145 -
146 -In no event and under no legal theory, whether in tort (including negligence),
147 -contract, or otherwise, unless required by applicable law (such as deliberate
148 -and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 -liable to You for damages, including any direct, indirect, special, incidental,
150 -or consequential damages of any character arising as a result of this License or
151 -out of the use or inability to use the Work (including but not limited to
152 -damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 -any and all other commercial damages or losses), even if such Contributor has
154 -been advised of the possibility of such damages.
155 -
156 -9. Accepting Warranty or Additional Liability.
157 -
158 -While redistributing the Work or Derivative Works thereof, You may choose to
159 -offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 -other liability obligations and/or rights consistent with this License. However,
161 -in accepting such obligations, You may act only on Your own behalf and on Your
162 -sole responsibility, not on behalf of any other Contributor, and only if You
163 -agree to indemnify, defend, and hold each Contributor harmless for any liability
164 -incurred by, or claims asserted against, such Contributor by reason of your
165 -accepting any such warranty or additional liability.
166 -
167 -END OF TERMS AND CONDITIONS
168 -
169 -APPENDIX: How to apply the Apache License to your work
170 -
171 -To apply the Apache License to your work, attach the following boilerplate
172 -notice, with the fields enclosed by brackets "[]" replaced with your own
173 -identifying information. (Don't include the brackets!) The text should be
174 -enclosed in the appropriate comment syntax for the file format. We also
175 -recommend that a file or class name and description of purpose be included on
176 -the same "printed page" as the copyright notice for easier identification within
177 -third-party archives.
178 -
179 - Copyright [yyyy] [name of copyright owner]
180 -
181 - Licensed under the Apache License, Version 2.0 (the "License");
182 - you may not use this file except in compliance with the License.
183 - You may obtain a copy of the License at
184 -
185 - http://www.apache.org/licenses/LICENSE-2.0
186 -
187 - Unless required by applicable law or agreed to in writing, software
188 - distributed under the License is distributed on an "AS IS" BASIS,
189 - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 - See the License for the specific language governing permissions and
191 - limitations under the License.
Godeps/_workspace/src/github.com/fd/go-nat/README.md deleted
-3
@@ -1,3 +0,0 @@
1 -# go-nat
2 -
3 -[![GoDoc](https://godoc.org/github.com/fd/go-nat?status.svg)](https://godoc.org/github.com/fd/go-nat) [![status](https://sourcegraph.com/api/repos/github.com/fd/go-nat/.badges/status.png)](https://sourcegraph.com/github.com/fd/go-nat)
Godeps/_workspace/src/github.com/fd/go-nat/nat.go deleted
-54
@@ -1,54 +0,0 @@
1 -// Package nat implements NAT handling facilities
2 -package nat
3 -
4 -import (
5 - "errors"
6 - "math"
7 - "math/rand"
8 - "net"
9 - "time"
10 -)
11 -
12 -var ErrNoExternalAddress = errors.New("no external address")
13 -var ErrNoInternalAddress = errors.New("no internal address")
14 -var ErrNoNATFound = errors.New("no NAT found")
15 -
16 -// protocol is either "udp" or "tcp"
17 -type NAT interface {
18 - // Type returns the kind of NAT port mapping service that is used
19 - Type() string
20 -
21 - // GetDeviceAddress returns the internal address of the gateway device.
22 - GetDeviceAddress() (addr net.IP, err error)
23 -
24 - // GetExternalAddress returns the external address of the gateway device.
25 - GetExternalAddress() (addr net.IP, err error)
26 -
27 - // GetInternalAddress returns the address of the local host.
28 - GetInternalAddress() (addr net.IP, err error)
29 -
30 - // AddPortMapping maps a port on the local host to an external port.
31 - AddPortMapping(protocol string, internalPort int, description string, timeout time.Duration) (mappedExternalPort int, err error)
32 -
33 - // DeletePortMapping removes a port mapping.
34 - DeletePortMapping(protocol string, internalPort int) (err error)
35 -}
36 -
37 -// DiscoverGateway attempts to find a gateway device.
38 -func DiscoverGateway() (NAT, error) {
39 - select {
40 - case nat := <-discoverUPNP_IG1():
41 - return nat, nil
42 - case nat := <-discoverUPNP_IG2():
43 - return nat, nil
44 - case nat := <-discoverNATPMP():
45 - return nat, nil
46 - case <-time.After(10 * time.Second):
47 - return nil, ErrNoNATFound
48 - }
49 -}
50 -
51 -func randomPort() int {
52 - rand.Seed(time.Now().UnixNano())
53 - return rand.Intn(math.MaxUint16-10000) + 10000
54 -}
Godeps/_workspace/src/github.com/fd/go-nat/natpmp.go deleted
-178
@@ -1,178 +0,0 @@
1 -package nat
2 -
3 -import (
4 - "net"
5 - "time"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jackpal/go-nat-pmp"
8 -)
9 -
10 -var (
11 - _ NAT = (*natpmp_NAT)(nil)
12 -)
13 -
14 -func natpmp_PotentialGateways() ([]net.IP, error) {
15 - _, ipNet_10, err := net.ParseCIDR("10.0.0.0/8")
16 - if err != nil {
17 - panic(err)
18 - }
19 -
20 - _, ipNet_172_16, err := net.ParseCIDR("172.16.0.0/12")
21 - if err != nil {
22 - panic(err)
23 - }
24 -
25 - _, ipNet_192_168, err := net.ParseCIDR("192.168.0.0/16")
26 - if err != nil {
27 - panic(err)
28 - }
29 -
30 - ifaces, err := net.Interfaces()
31 - if err != nil {
32 - return nil, err
33 - }
34 -
35 - var ips []net.IP
36 -
37 - for _, iface := range ifaces {
38 - addrs, err := iface.Addrs()
39 - if err != nil {
40 - return nil, err
41 - }
42 -
43 - for _, addr := range addrs {
44 - switch x := addr.(type) {
45 - case *net.IPNet:
46 - var ipNet *net.IPNet
47 - if ipNet_10.Contains(x.IP) {
48 - ipNet = ipNet_10
49 - } else if ipNet_172_16.Contains(x.IP) {
50 - ipNet = ipNet_172_16
51 - } else if ipNet_192_168.Contains(x.IP) {
52 - ipNet = ipNet_192_168
53 - }
54 -
55 - if ipNet != nil {
56 - ip := x.IP.Mask(x.Mask)
57 - ip = ip.To4()
58 - if ip != nil {
59 - ip[3] = ip[3] | 0x01
60 - ips = append(ips, ip)
61 - }
62 - }
63 - }
64 - }
65 - }
66 -
67 - if len(ips) == 0 {
68 - return nil, ErrNoNATFound
69 - }
70 -
71 - return ips, nil
72 -}
73 -
74 -func discoverNATPMP() <-chan NAT {
75 - ips, err := natpmp_PotentialGateways()
76 - if err != nil {
77 - return nil
78 - }
79 -
80 - res := make(chan NAT, len(ips))
81 -
82 - for _, ip := range ips {
83 - go discoverNATPMPWithAddr(res, ip)
84 - }
85 -
86 - return res
87 -}
88 -
89 -func discoverNATPMPWithAddr(c chan NAT, ip net.IP) {
90 - client := natpmp.NewClient(ip)
91 - _, err := client.GetExternalAddress()
92 - if err != nil {
93 - return
94 - }
95 -
96 - c <- &natpmp_NAT{client, ip, make(map[int]int)}
97 -}
98 -
99 -type natpmp_NAT struct {
100 - c *natpmp.Client
101 - gateway net.IP
102 - ports map[int]int
103 -}
104 -
105 -func (n *natpmp_NAT) GetDeviceAddress() (addr net.IP, err error) {
106 - return n.gateway, nil
107 -}
108 -
109 -func (n *natpmp_NAT) GetInternalAddress() (addr net.IP, err error) {
110 - ifaces, err := net.Interfaces()
111 - if err != nil {
112 - return nil, err
113 - }
114 -
115 - for _, iface := range ifaces {
116 - addrs, err := iface.Addrs()
117 - if err != nil {
118 - return nil, err
119 - }
120 -
121 - for _, addr := range addrs {
122 - switch x := addr.(type) {
123 - case *net.IPNet:
124 - if x.Contains(n.gateway) {
125 - return x.IP, nil
126 - }
127 - }
128 - }
129 - }
130 -
131 - return nil, ErrNoInternalAddress
132 -}
133 -
134 -func (n *natpmp_NAT) GetExternalAddress() (addr net.IP, err error) {
135 - res, err := n.c.GetExternalAddress()
136 - if err != nil {
137 - return nil, err
138 - }
139 -
140 - d := res.ExternalIPAddress
141 - return net.IPv4(d[0], d[1], d[2], d[3]), nil
142 -}
143 -
144 -func (n *natpmp_NAT) AddPortMapping(protocol string, internalPort int, description string, timeout time.Duration) (int, error) {
145 - var (
146 - err error
147 - )
148 -
149 - timeoutInSeconds := int(timeout / time.Second)
150 -
151 - if externalPort := n.ports[internalPort]; externalPort > 0 {
152 - _, err = n.c.AddPortMapping(protocol, internalPort, externalPort, timeoutInSeconds)
153 - if err == nil {
154 - n.ports[internalPort] = externalPort
155 - return externalPort, nil
156 - }
157 - }
158 -
159 - for i := 0; i < 3; i++ {
160 - externalPort := randomPort()
161 - _, err = n.c.AddPortMapping(protocol, internalPort, externalPort, timeoutInSeconds)
162 - if err == nil {
163 - n.ports[internalPort] = externalPort
164 - return externalPort, nil
165 - }
166 - }
167 -
168 - return 0, err
169 -}
170 -
171 -func (n *natpmp_NAT) DeletePortMapping(protocol string, internalPort int) (err error) {
172 - delete(n.ports, internalPort)
173 - return nil
174 -}
175 -
176 -func (n *natpmp_NAT) Type() string {
177 - return "NAT-PMP"
178 -}
Godeps/_workspace/src/github.com/fd/go-nat/upnp.go deleted
-239
@@ -1,239 +0,0 @@
1 -package nat
2 -
3 -import (
4 - "net"
5 - "time"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp"
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1"
9 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway2"
10 -)
11 -
12 -var (
13 - _ NAT = (*upnp_NAT)(nil)
14 -)
15 -
16 -func discoverUPNP_IG1() <-chan NAT {
17 - res := make(chan NAT, 1)
18 - go func() {
19 -
20 - // find devices
21 - devs, err := goupnp.DiscoverDevices(internetgateway1.URN_WANConnectionDevice_1)
22 - if err != nil {
23 - return
24 - }
25 -
26 - for _, dev := range devs {
27 - if dev.Root == nil {
28 - continue
29 - }
30 -
31 - dev.Root.Device.VisitServices(func(srv *goupnp.Service) {
32 - switch srv.ServiceType {
33 - case internetgateway1.URN_WANIPConnection_1:
34 - client := &internetgateway1.WANIPConnection1{ServiceClient: goupnp.ServiceClient{
35 - SOAPClient: srv.NewSOAPClient(),
36 - RootDevice: dev.Root,
37 - Service: srv,
38 - }}
39 - _, isNat, err := client.GetNATRSIPStatus()
40 - if err == nil && isNat {
41 - res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG1-IP1)", dev.Root}
42 - return
43 - }
44 -
45 - case internetgateway1.URN_WANPPPConnection_1:
46 - client := &internetgateway1.WANPPPConnection1{ServiceClient: goupnp.ServiceClient{
47 - SOAPClient: srv.NewSOAPClient(),
48 - RootDevice: dev.Root,
49 - Service: srv,
50 - }}
51 - _, isNat, err := client.GetNATRSIPStatus()
52 - if err == nil && isNat {
53 - res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG1-PPP1)", dev.Root}
54 - return
55 - }
56 -
57 - }
58 - })
59 - }
60 -
61 - }()
62 - return res
63 -}
64 -
65 -func discoverUPNP_IG2() <-chan NAT {
66 - res := make(chan NAT, 1)
67 - go func() {
68 -
69 - // find devices
70 - devs, err := goupnp.DiscoverDevices(internetgateway2.URN_WANConnectionDevice_2)
71 - if err != nil {
72 - return
73 - }
74 -
75 - for _, dev := range devs {
76 - if dev.Root == nil {
77 - continue
78 - }
79 -
80 - dev.Root.Device.VisitServices(func(srv *goupnp.Service) {
81 - switch srv.ServiceType {
82 - case internetgateway2.URN_WANIPConnection_1:
83 - client := &internetgateway2.WANIPConnection1{ServiceClient: goupnp.ServiceClient{
84 - SOAPClient: srv.NewSOAPClient(),
85 - RootDevice: dev.Root,
86 - Service: srv,
87 - }}
88 - _, isNat, err := client.GetNATRSIPStatus()
89 - if err == nil && isNat {
90 - res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG2-IP1)", dev.Root}
91 - return
92 - }
93 -
94 - case internetgateway2.URN_WANIPConnection_2:
95 - client := &internetgateway2.WANIPConnection2{ServiceClient: goupnp.ServiceClient{
96 - SOAPClient: srv.NewSOAPClient(),
97 - RootDevice: dev.Root,
98 - Service: srv,
99 - }}
100 - _, isNat, err := client.GetNATRSIPStatus()
101 - if err == nil && isNat {
102 - res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG2-IP2)", dev.Root}
103 - return
104 - }
105 -
106 - case internetgateway2.URN_WANPPPConnection_1:
107 - client := &internetgateway2.WANPPPConnection1{ServiceClient: goupnp.ServiceClient{
108 - SOAPClient: srv.NewSOAPClient(),
109 - RootDevice: dev.Root,
110 - Service: srv,
111 - }}
112 - _, isNat, err := client.GetNATRSIPStatus()
113 - if err == nil && isNat {
114 - res <- &upnp_NAT{client, make(map[int]int), "UPNP (IG2-PPP1)", dev.Root}
115 - return
116 - }
117 -
118 - }
119 - })
120 - }
121 -
122 - }()
123 - return res
124 -}
125 -
126 -type upnp_NAT_Client interface {
127 - GetExternalIPAddress() (string, error)
128 - AddPortMapping(string, uint16, string, uint16, string, bool, string, uint32) error
129 - DeletePortMapping(string, uint16, string) error
130 -}
131 -
132 -type upnp_NAT struct {
133 - c upnp_NAT_Client
134 - ports map[int]int
135 - typ string
136 - rootDevice *goupnp.RootDevice
137 -}
138 -
139 -func (u *upnp_NAT) GetExternalAddress() (addr net.IP, err error) {
140 - ipString, err := u.c.GetExternalIPAddress()
141 - if err != nil {
142 - return nil, err
143 - }
144 -
145 - ip := net.ParseIP(ipString)
146 - if ip == nil {
147 - return nil, ErrNoExternalAddress
148 - }
149 -
150 - return ip, nil
151 -}
152 -
153 -func mapProtocol(s string) string {
154 - switch s {
155 - case "udp":
156 - return "UDP"
157 - case "tcp":
158 - return "TCP"
159 - default:
160 - panic("invalid protocol: " + s)
161 - }
162 -}
163 -
164 -func (u *upnp_NAT) AddPortMapping(protocol string, internalPort int, description string, timeout time.Duration) (int, error) {
165 - ip, err := u.GetInternalAddress()
166 - if err != nil {
167 - return 0, nil
168 - }
169 -
170 - timeoutInSeconds := uint32(timeout / time.Second)
171 -
172 - if externalPort := u.ports[internalPort]; externalPort > 0 {
173 - err = u.c.AddPortMapping("", uint16(externalPort), mapProtocol(protocol), uint16(internalPort), ip.String(), true, description, timeoutInSeconds)
174 - if err == nil {
175 - return externalPort, nil
176 - }
177 - }
178 -
179 - for i := 0; i < 3; i++ {
180 - externalPort := randomPort()
181 - err = u.c.AddPortMapping("", uint16(externalPort), mapProtocol(protocol), uint16(internalPort), ip.String(), true, description, timeoutInSeconds)
182 - if err == nil {
183 - u.ports[internalPort] = externalPort
184 - return externalPort, nil
185 - }
186 - }
187 -
188 - return 0, err
189 -}
190 -
191 -func (u *upnp_NAT) DeletePortMapping(protocol string, internalPort int) error {
192 - if externalPort := u.ports[internalPort]; externalPort > 0 {
193 - delete(u.ports, internalPort)
194 - return u.c.DeletePortMapping("", uint16(externalPort), mapProtocol(protocol))
195 - }
196 -
197 - return nil
198 -}
199 -
200 -func (u *upnp_NAT) GetDeviceAddress() (net.IP, error) {
201 - addr, err := net.ResolveUDPAddr("udp4", u.rootDevice.URLBase.Host)
202 - if err != nil {
203 - return nil, err
204 - }
205 -
206 - return addr.IP, nil
207 -}
208 -
209 -func (u *upnp_NAT) GetInternalAddress() (net.IP, error) {
210 - devAddr, err := u.GetDeviceAddress()
211 - if err != nil {
212 - return nil, err
213 - }
214 -
215 - ifaces, err := net.Interfaces()
216 - if err != nil {
217 - return nil, err
218 - }
219 -
220 - for _, iface := range ifaces {
221 - addrs, err := iface.Addrs()
222 - if err != nil {
223 - return nil, err
224 - }
225 -
226 - for _, addr := range addrs {
227 - switch x := addr.(type) {
228 - case *net.IPNet:
229 - if x.Contains(devAddr) {
230 - return x.IP, nil
231 - }
232 - }
233 - }
234 - }
235 -
236 - return nil, ErrNoInternalAddress
237 -}
238 -
239 -func (n *upnp_NAT) Type() string { return n.typ }
Godeps/_workspace/src/github.com/hashicorp/yamux/.gitignore deleted
-23
@@ -1,23 +0,0 @@
1 -# Compiled Object files, Static and Dynamic libs (Shared Objects)
2 -*.o
3 -*.a
4 -*.so
5 -
6 -# Folders
7 -_obj
8 -_test
9 -
10 -# Architecture specific extensions/prefixes
11 -*.[568vq]
12 -[568vq].out
13 -
14 -*.cgo1.go
15 -*.cgo2.c
16 -_cgo_defun.c
17 -_cgo_gotypes.go
18 -_cgo_export.*
19 -
20 -_testmain.go
21 -
22 -*.exe
23 -*.test
Godeps/_workspace/src/github.com/hashicorp/yamux/LICENSE deleted
-362
@@ -1,362 +0,0 @@
1 -Mozilla Public License, version 2.0
2 -
3 -1. Definitions
4 -
5 -1.1. "Contributor"
6 -
7 - means each individual or legal entity that creates, contributes to the
8 - creation of, or owns Covered Software.
9 -
10 -1.2. "Contributor Version"
11 -
12 - means the combination of the Contributions of others (if any) used by a
13 - Contributor and that particular Contributor's Contribution.
14 -
15 -1.3. "Contribution"
16 -
17 - means Covered Software of a particular Contributor.
18 -
19 -1.4. "Covered Software"
20 -
21 - means Source Code Form to which the initial Contributor has attached the
22 - notice in Exhibit A, the Executable Form of such Source Code Form, and
23 - Modifications of such Source Code Form, in each case including portions
24 - thereof.
25 -
26 -1.5. "Incompatible With Secondary Licenses"
27 - means
28 -
29 - a. that the initial Contributor has attached the notice described in
30 - Exhibit B to the Covered Software; or
31 -
32 - b. that the Covered Software was made available under the terms of
33 - version 1.1 or earlier of the License, but not also under the terms of
34 - a Secondary License.
35 -
36 -1.6. "Executable Form"
37 -
38 - means any form of the work other than Source Code Form.
39 -
40 -1.7. "Larger Work"
41 -
42 - means a work that combines Covered Software with other material, in a
43 - separate file or files, that is not Covered Software.
44 -
45 -1.8. "License"
46 -
47 - means this document.
48 -
49 -1.9. "Licensable"
50 -
51 - means having the right to grant, to the maximum extent possible, whether
52 - at the time of the initial grant or subsequently, any and all of the
53 - rights conveyed by this License.
54 -
55 -1.10. "Modifications"
56 -
57 - means any of the following:
58 -
59 - a. any file in Source Code Form that results from an addition to,
60 - deletion from, or modification of the contents of Covered Software; or
61 -
62 - b. any new file in Source Code Form that contains any Covered Software.
63 -
64 -1.11. "Patent Claims" of a Contributor
65 -
66 - means any patent claim(s), including without limitation, method,
67 - process, and apparatus claims, in any patent Licensable by such
68 - Contributor that would be infringed, but for the grant of the License,
69 - by the making, using, selling, offering for sale, having made, import,
70 - or transfer of either its Contributions or its Contributor Version.
71 -
72 -1.12. "Secondary License"
73 -
74 - means either the GNU General Public License, Version 2.0, the GNU Lesser
75 - General Public License, Version 2.1, the GNU Affero General Public
76 - License, Version 3.0, or any later versions of those licenses.
77 -
78 -1.13. "Source Code Form"
79 -
80 - means the form of the work preferred for making modifications.
81 -
82 -1.14. "You" (or "Your")
83 -
84 - means an individual or a legal entity exercising rights under this
85 - License. For legal entities, "You" includes any entity that controls, is
86 - controlled by, or is under common control with You. For purposes of this
87 - definition, "control" means (a) the power, direct or indirect, to cause
88 - the direction or management of such entity, whether by contract or
89 - otherwise, or (b) ownership of more than fifty percent (50%) of the
90 - outstanding shares or beneficial ownership of such entity.
91 -
92 -
93 -2. License Grants and Conditions
94 -
95 -2.1. Grants
96 -
97 - Each Contributor hereby grants You a world-wide, royalty-free,
98 - non-exclusive license:
99 -
100 - a. under intellectual property rights (other than patent or trademark)
101 - Licensable by such Contributor to use, reproduce, make available,
102 - modify, display, perform, distribute, and otherwise exploit its
103 - Contributions, either on an unmodified basis, with Modifications, or
104 - as part of a Larger Work; and
105 -
106 - b. under Patent Claims of such Contributor to make, use, sell, offer for
107 - sale, have made, import, and otherwise transfer either its
108 - Contributions or its Contributor Version.
109 -
110 -2.2. Effective Date
111 -
112 - The licenses granted in Section 2.1 with respect to any Contribution
113 - become effective for each Contribution on the date the Contributor first
114 - distributes such Contribution.
115 -
116 -2.3. Limitations on Grant Scope
117 -
118 - The licenses granted in this Section 2 are the only rights granted under
119 - this License. No additional rights or licenses will be implied from the
120 - distribution or licensing of Covered Software under this License.
121 - Notwithstanding Section 2.1(b) above, no patent license is granted by a
122 - Contributor:
123 -
124 - a. for any code that a Contributor has removed from Covered Software; or
125 -
126 - b. for infringements caused by: (i) Your and any other third party's
127 - modifications of Covered Software, or (ii) the combination of its
128 - Contributions with other software (except as part of its Contributor
129 - Version); or
130 -
131 - c. under Patent Claims infringed by Covered Software in the absence of
132 - its Contributions.
133 -
134 - This License does not grant any rights in the trademarks, service marks,
135 - or logos of any Contributor (except as may be necessary to comply with
136 - the notice requirements in Section 3.4).
137 -
138 -2.4. Subsequent Licenses
139 -
140 - No Contributor makes additional grants as a result of Your choice to
141 - distribute the Covered Software under a subsequent version of this
142 - License (see Section 10.2) or under the terms of a Secondary License (if
143 - permitted under the terms of Section 3.3).
144 -
145 -2.5. Representation
146 -
147 - Each Contributor represents that the Contributor believes its
148 - Contributions are its original creation(s) or it has sufficient rights to
149 - grant the rights to its Contributions conveyed by this License.
150 -
151 -2.6. Fair Use
152 -
153 - This License is not intended to limit any rights You have under
154 - applicable copyright doctrines of fair use, fair dealing, or other
155 - equivalents.
156 -
157 -2.7. Conditions
158 -
159 - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
160 - Section 2.1.
161 -
162 -
163 -3. Responsibilities
164 -
165 -3.1. Distribution of Source Form
166 -
167 - All distribution of Covered Software in Source Code Form, including any
168 - Modifications that You create or to which You contribute, must be under
169 - the terms of this License. You must inform recipients that the Source
170 - Code Form of the Covered Software is governed by the terms of this
171 - License, and how they can obtain a copy of this License. You may not
172 - attempt to alter or restrict the recipients' rights in the Source Code
173 - Form.
174 -
175 -3.2. Distribution of Executable Form
176 -
177 - If You distribute Covered Software in Executable Form then:
178 -
179 - a. such Covered Software must also be made available in Source Code Form,
180 - as described in Section 3.1, and You must inform recipients of the
181 - Executable Form how they can obtain a copy of such Source Code Form by
182 - reasonable means in a timely manner, at a charge no more than the cost
183 - of distribution to the recipient; and
184 -
185 - b. You may distribute such Executable Form under the terms of this
186 - License, or sublicense it under different terms, provided that the
187 - license for the Executable Form does not attempt to limit or alter the
188 - recipients' rights in the Source Code Form under this License.
189 -
190 -3.3. Distribution of a Larger Work
191 -
192 - You may create and distribute a Larger Work under terms of Your choice,
193 - provided that You also comply with the requirements of this License for
194 - the Covered Software. If the Larger Work is a combination of Covered
195 - Software with a work governed by one or more Secondary Licenses, and the
196 - Covered Software is not Incompatible With Secondary Licenses, this
197 - License permits You to additionally distribute such Covered Software
198 - under the terms of such Secondary License(s), so that the recipient of
199 - the Larger Work may, at their option, further distribute the Covered
200 - Software under the terms of either this License or such Secondary
201 - License(s).
202 -
203 -3.4. Notices
204 -
205 - You may not remove or alter the substance of any license notices
206 - (including copyright notices, patent notices, disclaimers of warranty, or
207 - limitations of liability) contained within the Source Code Form of the
208 - Covered Software, except that You may alter any license notices to the
209 - extent required to remedy known factual inaccuracies.
210 -
211 -3.5. Application of Additional Terms
212 -
213 - You may choose to offer, and to charge a fee for, warranty, support,
214 - indemnity or liability obligations to one or more recipients of Covered
215 - Software. However, You may do so only on Your own behalf, and not on
216 - behalf of any Contributor. You must make it absolutely clear that any
217 - such warranty, support, indemnity, or liability obligation is offered by
218 - You alone, and You hereby agree to indemnify every Contributor for any
219 - liability incurred by such Contributor as a result of warranty, support,
220 - indemnity or liability terms You offer. You may include additional
221 - disclaimers of warranty and limitations of liability specific to any
222 - jurisdiction.
223 -
224 -4. Inability to Comply Due to Statute or Regulation
225 -
226 - If it is impossible for You to comply with any of the terms of this License
227 - with respect to some or all of the Covered Software due to statute,
228 - judicial order, or regulation then You must: (a) comply with the terms of
229 - this License to the maximum extent possible; and (b) describe the
230 - limitations and the code they affect. Such description must be placed in a
231 - text file included with all distributions of the Covered Software under
232 - this License. Except to the extent prohibited by statute or regulation,
233 - such description must be sufficiently detailed for a recipient of ordinary
234 - skill to be able to understand it.
235 -
236 -5. Termination
237 -
238 -5.1. The rights granted under this License will terminate automatically if You
239 - fail to comply with any of its terms. However, if You become compliant,
240 - then the rights granted under this License from a particular Contributor
241 - are reinstated (a) provisionally, unless and until such Contributor
242 - explicitly and finally terminates Your grants, and (b) on an ongoing
243 - basis, if such Contributor fails to notify You of the non-compliance by
244 - some reasonable means prior to 60 days after You have come back into
245 - compliance. Moreover, Your grants from a particular Contributor are
246 - reinstated on an ongoing basis if such Contributor notifies You of the
247 - non-compliance by some reasonable means, this is the first time You have
248 - received notice of non-compliance with this License from such
249 - Contributor, and You become compliant prior to 30 days after Your receipt
250 - of the notice.
251 -
252 -5.2. If You initiate litigation against any entity by asserting a patent
253 - infringement claim (excluding declaratory judgment actions,
254 - counter-claims, and cross-claims) alleging that a Contributor Version
255 - directly or indirectly infringes any patent, then the rights granted to
256 - You by any and all Contributors for the Covered Software under Section
257 - 2.1 of this License shall terminate.
258 -
259 -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
260 - license agreements (excluding distributors and resellers) which have been
261 - validly granted by You or Your distributors under this License prior to
262 - termination shall survive termination.
263 -
264 -6. Disclaimer of Warranty
265 -
266 - Covered Software is provided under this License on an "as is" basis,
267 - without warranty of any kind, either expressed, implied, or statutory,
268 - including, without limitation, warranties that the Covered Software is free
269 - of defects, merchantable, fit for a particular purpose or non-infringing.
270 - The entire risk as to the quality and performance of the Covered Software
271 - is with You. Should any Covered Software prove defective in any respect,
272 - You (not any Contributor) assume the cost of any necessary servicing,
273 - repair, or correction. This disclaimer of warranty constitutes an essential
274 - part of this License. No use of any Covered Software is authorized under
275 - this License except under this disclaimer.
276 -
277 -7. Limitation of Liability
278 -
279 - Under no circumstances and under no legal theory, whether tort (including
280 - negligence), contract, or otherwise, shall any Contributor, or anyone who
281 - distributes Covered Software as permitted above, be liable to You for any
282 - direct, indirect, special, incidental, or consequential damages of any
283 - character including, without limitation, damages for lost profits, loss of
284 - goodwill, work stoppage, computer failure or malfunction, or any and all
285 - other commercial damages or losses, even if such party shall have been
286 - informed of the possibility of such damages. This limitation of liability
287 - shall not apply to liability for death or personal injury resulting from
288 - such party's negligence to the extent applicable law prohibits such
289 - limitation. Some jurisdictions do not allow the exclusion or limitation of
290 - incidental or consequential damages, so this exclusion and limitation may
291 - not apply to You.
292 -
293 -8. Litigation
294 -
295 - Any litigation relating to this License may be brought only in the courts
296 - of a jurisdiction where the defendant maintains its principal place of
297 - business and such litigation shall be governed by laws of that
298 - jurisdiction, without reference to its conflict-of-law provisions. Nothing
299 - in this Section shall prevent a party's ability to bring cross-claims or
300 - counter-claims.
301 -
302 -9. Miscellaneous
303 -
304 - This License represents the complete agreement concerning the subject
305 - matter hereof. If any provision of this License is held to be
306 - unenforceable, such provision shall be reformed only to the extent
307 - necessary to make it enforceable. Any law or regulation which provides that
308 - the language of a contract shall be construed against the drafter shall not
309 - be used to construe this License against a Contributor.
310 -
311 -
312 -10. Versions of the License
313 -
314 -10.1. New Versions
315 -
316 - Mozilla Foundation is the license steward. Except as provided in Section
317 - 10.3, no one other than the license steward has the right to modify or
318 - publish new versions of this License. Each version will be given a
319 - distinguishing version number.
320 -
321 -10.2. Effect of New Versions
322 -
323 - You may distribute the Covered Software under the terms of the version
324 - of the License under which You originally received the Covered Software,
325 - or under the terms of any subsequent version published by the license
326 - steward.
327 -
328 -10.3. Modified Versions
329 -
330 - If you create software not governed by this License, and you want to
331 - create a new license for such software, you may create and use a
332 - modified version of this License if you rename the license and remove
333 - any references to the name of the license steward (except to note that
334 - such modified license differs from this License).
335 -
336 -10.4. Distributing Source Code Form that is Incompatible With Secondary
337 - Licenses If You choose to distribute Source Code Form that is
338 - Incompatible With Secondary Licenses under the terms of this version of
339 - the License, the notice described in Exhibit B of this License must be
340 - attached.
341 -
342 -Exhibit A - Source Code Form License Notice
343 -
344 - This Source Code Form is subject to the
345 - terms of the Mozilla Public License, v.
346 - 2.0. If a copy of the MPL was not
347 - distributed with this file, You can
348 - obtain one at
349 - http://mozilla.org/MPL/2.0/.
350 -
351 -If it is not possible or desirable to put the notice in a particular file,
352 -then You may include the notice in a location (such as a LICENSE file in a
353 -relevant directory) where a recipient would be likely to look for such a
354 -notice.
355 -
356 -You may add additional accurate notices of copyright ownership.
357 -
358 -Exhibit B - "Incompatible With Secondary Licenses" Notice
359 -
360 - This Source Code Form is "Incompatible
361 - With Secondary Licenses", as defined by
362 - the Mozilla Public License, v. 2.0.
\ No newline at end of file
Godeps/_workspace/src/github.com/hashicorp/yamux/README.md deleted
-86
@@ -1,86 +0,0 @@
1 -# Yamux
2 -
3 -Yamux (Yet another Multiplexer) is a multiplexing library for Golang.
4 -It relies on an underlying connection to provide reliability
5 -and ordering, such as TCP or Unix domain sockets, and provides
6 -stream-oriented multiplexing. It is inspired by SPDY but is not
7 -interoperable with it.
8 -
9 -Yamux features include:
10 -
11 -* Bi-directional streams
12 - * Streams can be opened by either client or server
13 - * Useful for NAT traversal
14 - * Server-side push support
15 -* Flow control
16 - * Avoid starvation
17 - * Back-pressure to prevent overwhelming a receiver
18 -* Keep Alives
19 - * Enables persistent connections over a load balancer
20 -* Efficient
21 - * Enables thousands of logical streams with low overhead
22 -
23 -## Documentation
24 -
25 -For complete documentation, see the associated [Godoc](http://godoc.org/github.com/hashicorp/yamux).
26 -
27 -## Specification
28 -
29 -The full specification for Yamux is provided in the `spec.md` file.
30 -It can be used as a guide to implementors of interoperable libraries.
31 -
32 -## Usage
33 -
34 -Using Yamux is remarkably simple:
35 -
36 -```go
37 -
38 -func client() {
39 - // Get a TCP connection
40 - conn, err := net.Dial(...)
41 - if err != nil {
42 - panic(err)
43 - }
44 -
45 - // Setup client side of yamux
46 - session, err := yamux.Client(conn, nil)
47 - if err != nil {
48 - panic(err)
49 - }
50 -
51 - // Open a new stream
52 - stream, err := session.Open()
53 - if err != nil {
54 - panic(err)
55 - }
56 -
57 - // Stream implements net.Conn
58 - stream.Write([]byte("ping"))
59 -}
60 -
61 -func server() {
62 - // Accept a TCP connection
63 - conn, err := listener.Accept()
64 - if err != nil {
65 - panic(err)
66 - }
67 -
68 - // Setup server side of yamux
69 - session, err := yamux.Server(conn, nil)
70 - if err != nil {
71 - panic(err)
72 - }
73 -
74 - // Accept a stream
75 - stream, err := session.Accept()
76 - if err != nil {
77 - panic(err)
78 - }
79 -
80 - // Listen for a message
81 - buf := make([]byte, 4)
82 - stream.Read(buf)
83 -}
84 -
85 -```
86 -
Godeps/_workspace/src/github.com/hashicorp/yamux/addr.go deleted
-60
@@ -1,60 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "fmt"
5 - "net"
6 -)
7 -
8 -// hasAddr is used to get the address from the underlying connection
9 -type hasAddr interface {
10 - LocalAddr() net.Addr
11 - RemoteAddr() net.Addr
12 -}
13 -
14 -// yamuxAddr is used when we cannot get the underlying address
15 -type yamuxAddr struct {
16 - Addr string
17 -}
18 -
19 -func (*yamuxAddr) Network() string {
20 - return "yamux"
21 -}
22 -
23 -func (y *yamuxAddr) String() string {
24 - return fmt.Sprintf("yamux:%s", y.Addr)
25 -}
26 -
27 -// Addr is used to get the address of the listener.
28 -func (s *Session) Addr() net.Addr {
29 - return s.LocalAddr()
30 -}
31 -
32 -// LocalAddr is used to get the local address of the
33 -// underlying connection.
34 -func (s *Session) LocalAddr() net.Addr {
35 - addr, ok := s.conn.(hasAddr)
36 - if !ok {
37 - return &yamuxAddr{"local"}
38 - }
39 - return addr.LocalAddr()
40 -}
41 -
42 -// RemoteAddr is used to get the address of remote end
43 -// of the underlying connection
44 -func (s *Session) RemoteAddr() net.Addr {
45 - addr, ok := s.conn.(hasAddr)
46 - if !ok {
47 - return &yamuxAddr{"remote"}
48 - }
49 - return addr.RemoteAddr()
50 -}
51 -
52 -// LocalAddr returns the local address
53 -func (s *Stream) LocalAddr() net.Addr {
54 - return s.session.LocalAddr()
55 -}
56 -
57 -// LocalAddr returns the remote address
58 -func (s *Stream) RemoteAddr() net.Addr {
59 - return s.session.RemoteAddr()
60 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/bench_test.go deleted
-81
@@ -1,81 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "testing"
5 -)
6 -
7 -func BenchmarkPing(b *testing.B) {
8 - client, server := testClientServer()
9 - defer client.Close()
10 - defer server.Close()
11 -
12 - for i := 0; i < b.N; i++ {
13 - rtt, err := client.Ping()
14 - if err != nil {
15 - b.Fatalf("err: %v", err)
16 - }
17 - if rtt == 0 {
18 - b.Fatalf("bad: %v", rtt)
19 - }
20 - }
21 -}
22 -
23 -func BenchmarkAccept(b *testing.B) {
24 - client, server := testClientServer()
25 - defer client.Close()
26 - defer server.Close()
27 -
28 - go func() {
29 - for i := 0; i < b.N; i++ {
30 - stream, err := server.AcceptStream()
31 - if err != nil {
32 - return
33 - }
34 - stream.Close()
35 - }
36 - }()
37 -
38 - for i := 0; i < b.N; i++ {
39 - stream, err := client.Open()
40 - if err != nil {
41 - b.Fatalf("err: %v", err)
42 - }
43 - stream.Close()
44 - }
45 -}
46 -
47 -func BenchmarkSendRecv(b *testing.B) {
48 - client, server := testClientServer()
49 - defer client.Close()
50 - defer server.Close()
51 -
52 - sendBuf := make([]byte, 512)
53 - recvBuf := make([]byte, 512)
54 -
55 - doneCh := make(chan struct{})
56 - go func() {
57 - stream, err := server.AcceptStream()
58 - if err != nil {
59 - return
60 - }
61 - defer stream.Close()
62 - for i := 0; i < b.N; i++ {
63 - if _, err := stream.Read(recvBuf); err != nil {
64 - b.Fatalf("err: %v", err)
65 - }
66 - }
67 - close(doneCh)
68 - }()
69 -
70 - stream, err := client.Open()
71 - if err != nil {
72 - b.Fatalf("err: %v", err)
73 - }
74 - defer stream.Close()
75 - for i := 0; i < b.N; i++ {
76 - if _, err := stream.Write(sendBuf); err != nil {
77 - b.Fatalf("err: %v", err)
78 - }
79 - }
80 - <-doneCh
81 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/const.go deleted
-150
@@ -1,150 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "encoding/binary"
5 - "fmt"
6 -)
7 -
8 -var (
9 - // ErrInvalidVersion means we received a frame with an
10 - // invalid version
11 - ErrInvalidVersion = fmt.Errorf("invalid protocol version")
12 -
13 - // ErrInvalidMsgType means we received a frame with an
14 - // invalid message type
15 - ErrInvalidMsgType = fmt.Errorf("invalid msg type")
16 -
17 - // ErrSessionShutdown is used if there is a shutdown during
18 - // an operation
19 - ErrSessionShutdown = fmt.Errorf("session shutdown")
20 -
21 - // ErrStreamsExhausted is returned if we have no more
22 - // stream ids to issue
23 - ErrStreamsExhausted = fmt.Errorf("streams exhausted")
24 -
25 - // ErrDuplicateStream is used if a duplicate stream is
26 - // opened inbound
27 - ErrDuplicateStream = fmt.Errorf("duplicate stream initiated")
28 -
29 - // ErrReceiveWindowExceeded indicates the window was exceeded
30 - ErrRecvWindowExceeded = fmt.Errorf("recv window exceeded")
31 -
32 - // ErrTimeout is used when we reach an IO deadline
33 - ErrTimeout = fmt.Errorf("i/o deadline reached")
34 -
35 - // ErrStreamClosed is returned when using a closed stream
36 - ErrStreamClosed = fmt.Errorf("stream closed")
37 -
38 - // ErrUnexpectedFlag is set when we get an unexpected flag
39 - ErrUnexpectedFlag = fmt.Errorf("unexpected flag")
40 -
41 - // ErrRemoteGoAway is used when we get a go away from the other side
42 - ErrRemoteGoAway = fmt.Errorf("remote end is not accepting connections")
43 -
44 - // ErrConnectionReset is sent if a stream is reset. This can happen
45 - // if the backlog is exceeded, or if there was a remote GoAway.
46 - ErrConnectionReset = fmt.Errorf("connection reset")
47 -)
48 -
49 -const (
50 - // protoVersion is the only version we support
51 - protoVersion uint8 = 0
52 -)
53 -
54 -const (
55 - // Data is used for data frames. They are followed
56 - // by length bytes worth of payload.
57 - typeData uint8 = iota
58 -
59 - // WindowUpdate is used to change the window of
60 - // a given stream. The length indicates the delta
61 - // update to the window.
62 - typeWindowUpdate
63 -
64 - // Ping is sent as a keep-alive or to measure
65 - // the RTT. The StreamID and Length value are echoed
66 - // back in the response.
67 - typePing
68 -
69 - // GoAway is sent to terminate a session. The StreamID
70 - // should be 0 and the length is an error code.
71 - typeGoAway
72 -)
73 -
74 -const (
75 - // SYN is sent to signal a new stream. May
76 - // be sent with a data payload
77 - flagSYN uint16 = 1 << iota
78 -
79 - // ACK is sent to acknowledge a new stream. May
80 - // be sent with a data payload
81 - flagACK
82 -
83 - // FIN is sent to half-close the given stream.
84 - // May be sent with a data payload.
85 - flagFIN
86 -
87 - // RST is used to hard close a given stream.
88 - flagRST
89 -)
90 -
91 -const (
92 - // initialStreamWindow is the initial stream window size
93 - initialStreamWindow uint32 = 256 * 1024
94 -)
95 -
96 -const (
97 - // goAwayNormal is sent on a normal termination
98 - goAwayNormal uint32 = iota
99 -
100 - // goAwayProtoErr sent on a protocol error
101 - goAwayProtoErr
102 -
103 - // goAwayInternalErr sent on an internal error
104 - goAwayInternalErr
105 -)
106 -
107 -const (
108 - sizeOfVersion = 1
109 - sizeOfType = 1
110 - sizeOfFlags = 2
111 - sizeOfStreamID = 4
112 - sizeOfLength = 4
113 - headerSize = sizeOfVersion + sizeOfType + sizeOfFlags +
114 - sizeOfStreamID + sizeOfLength
115 -)
116 -
117 -type header []byte
118 -
119 -func (h header) Version() uint8 {
120 - return h[0]
121 -}
122 -
123 -func (h header) MsgType() uint8 {
124 - return h[1]
125 -}
126 -
127 -func (h header) Flags() uint16 {
128 - return binary.BigEndian.Uint16(h[2:4])
129 -}
130 -
131 -func (h header) StreamID() uint32 {
132 - return binary.BigEndian.Uint32(h[4:8])
133 -}
134 -
135 -func (h header) Length() uint32 {
136 - return binary.BigEndian.Uint32(h[8:12])
137 -}
138 -
139 -func (h header) String() string {
140 - return fmt.Sprintf("Vsn:%d Type:%d Flags:%d StreamID:%d Length:%d",
141 - h.Version(), h.MsgType(), h.Flags(), h.StreamID(), h.Length())
142 -}
143 -
144 -func (h header) encode(msgType uint8, flags uint16, streamID uint32, length uint32) {
145 - h[0] = protoVersion
146 - h[1] = msgType
147 - binary.BigEndian.PutUint16(h[2:4], flags)
148 - binary.BigEndian.PutUint32(h[4:8], streamID)
149 - binary.BigEndian.PutUint32(h[8:12], length)
150 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/const_test.go deleted
-72
@@ -1,72 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "testing"
5 -)
6 -
7 -func TestConst(t *testing.T) {
8 - if protoVersion != 0 {
9 - t.Fatalf("bad: %v", protoVersion)
10 - }
11 -
12 - if typeData != 0 {
13 - t.Fatalf("bad: %v", typeData)
14 - }
15 - if typeWindowUpdate != 1 {
16 - t.Fatalf("bad: %v", typeWindowUpdate)
17 - }
18 - if typePing != 2 {
19 - t.Fatalf("bad: %v", typePing)
20 - }
21 - if typeGoAway != 3 {
22 - t.Fatalf("bad: %v", typeGoAway)
23 - }
24 -
25 - if flagSYN != 1 {
26 - t.Fatalf("bad: %v", flagSYN)
27 - }
28 - if flagACK != 2 {
29 - t.Fatalf("bad: %v", flagACK)
30 - }
31 - if flagFIN != 4 {
32 - t.Fatalf("bad: %v", flagFIN)
33 - }
34 - if flagRST != 8 {
35 - t.Fatalf("bad: %v", flagRST)
36 - }
37 -
38 - if goAwayNormal != 0 {
39 - t.Fatalf("bad: %v", goAwayNormal)
40 - }
41 - if goAwayProtoErr != 1 {
42 - t.Fatalf("bad: %v", goAwayProtoErr)
43 - }
44 - if goAwayInternalErr != 2 {
45 - t.Fatalf("bad: %v", goAwayInternalErr)
46 - }
47 -
48 - if headerSize != 12 {
49 - t.Fatalf("bad header size")
50 - }
51 -}
52 -
53 -func TestEncodeDecode(t *testing.T) {
54 - hdr := header(make([]byte, headerSize))
55 - hdr.encode(typeWindowUpdate, flagACK|flagRST, 1234, 4321)
56 -
57 - if hdr.Version() != protoVersion {
58 - t.Fatalf("bad: %v", hdr)
59 - }
60 - if hdr.MsgType() != typeWindowUpdate {
61 - t.Fatalf("bad: %v", hdr)
62 - }
63 - if hdr.Flags() != flagACK|flagRST {
64 - t.Fatalf("bad: %v", hdr)
65 - }
66 - if hdr.StreamID() != 1234 {
67 - t.Fatalf("bad: %v", hdr)
68 - }
69 - if hdr.Length() != 4321 {
70 - t.Fatalf("bad: %v", hdr)
71 - }
72 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/mux.go deleted
-80
@@ -1,80 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "fmt"
5 - "io"
6 - "os"
7 - "time"
8 -)
9 -
10 -// Config is used to tune the Yamux session
11 -type Config struct {
12 - // AcceptBacklog is used to limit how many streams may be
13 - // waiting an accept.
14 - AcceptBacklog int
15 -
16 - // EnableKeepalive is used to do a period keep alive
17 - // messages using a ping.
18 - EnableKeepAlive bool
19 -
20 - // KeepAliveInterval is how often to perform the keep alive
21 - KeepAliveInterval time.Duration
22 -
23 - // MaxStreamWindowSize is used to control the maximum
24 - // window size that we allow for a stream.
25 - MaxStreamWindowSize uint32
26 -
27 - // LogOutput is used to control the log destination
28 - LogOutput io.Writer
29 -}
30 -
31 -// DefaultConfig is used to return a default configuration
32 -func DefaultConfig() *Config {
33 - return &Config{
34 - AcceptBacklog: 256,
35 - EnableKeepAlive: true,
36 - KeepAliveInterval: 30 * time.Second,
37 - MaxStreamWindowSize: initialStreamWindow,
38 - LogOutput: os.Stderr,
39 - }
40 -}
41 -
42 -// VerifyConfig is used to verify the sanity of configuration
43 -func VerifyConfig(config *Config) error {
44 - if config.AcceptBacklog <= 0 {
45 - return fmt.Errorf("backlog must be positive")
46 - }
47 - if config.KeepAliveInterval == 0 {
48 - return fmt.Errorf("keep-alive interval must be positive")
49 - }
50 - if config.MaxStreamWindowSize < initialStreamWindow {
51 - return fmt.Errorf("MaxStreamWindowSize must be larger than %d", initialStreamWindow)
52 - }
53 - return nil
54 -}
55 -
56 -// Server is used to initialize a new server-side connection.
57 -// There must be at most one server-side connection. If a nil config is
58 -// provided, the DefaultConfiguration will be used.
59 -func Server(conn io.ReadWriteCloser, config *Config) (*Session, error) {
60 - if config == nil {
61 - config = DefaultConfig()
62 - }
63 - if err := VerifyConfig(config); err != nil {
64 - return nil, err
65 - }
66 - return newSession(config, conn, false), nil
67 -}
68 -
69 -// Client is used to initialize a new client-side connection.
70 -// There must be at most one client-side connection.
71 -func Client(conn io.ReadWriteCloser, config *Config) (*Session, error) {
72 - if config == nil {
73 - config = DefaultConfig()
74 - }
75 -
76 - if err := VerifyConfig(config); err != nil {
77 - return nil, err
78 - }
79 - return newSession(config, conn, true), nil
80 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/session.go deleted
-505
@@ -1,505 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "bufio"
5 - "fmt"
6 - "io"
7 - "io/ioutil"
8 - "log"
9 - "math"
10 - "net"
11 - "strings"
12 - "sync"
13 - "sync/atomic"
14 - "time"
15 -)
16 -
17 -// Session is used to wrap a reliable ordered connection and to
18 -// multiplex it into multiple streams.
19 -type Session struct {
20 - // remoteGoAway indicates the remote side does
21 - // not want futher connections. Must be first for alignment.
22 - remoteGoAway int32
23 -
24 - // localGoAway indicates that we should stop
25 - // accepting futher connections. Must be first for alignment.
26 - localGoAway int32
27 -
28 - // nextStreamID is the next stream we should
29 - // send. This depends if we are a client/server.
30 - nextStreamID uint32
31 -
32 - // config holds our configuration
33 - config *Config
34 -
35 - // logger is used for our logs
36 - logger *log.Logger
37 -
38 - // conn is the underlying connection
39 - conn io.ReadWriteCloser
40 -
41 - // bufRead is a buffered reader
42 - bufRead *bufio.Reader
43 -
44 - // pings is used to track inflight pings
45 - pings map[uint32]chan struct{}
46 - pingID uint32
47 - pingLock sync.Mutex
48 -
49 - // streams maps a stream id to a stream
50 - streams map[uint32]*Stream
51 - streamLock sync.Mutex
52 -
53 - // acceptCh is used to pass ready streams to the client
54 - acceptCh chan *Stream
55 -
56 - // sendCh is used to mark a stream as ready to send,
57 - // or to send a header out directly.
58 - sendCh chan sendReady
59 -
60 - // shutdown is used to safely close a session
61 - shutdown bool
62 - shutdownErr error
63 - shutdownCh chan struct{}
64 - shutdownLock sync.Mutex
65 -}
66 -
67 -// sendReady is used to either mark a stream as ready
68 -// or to directly send a header
69 -type sendReady struct {
70 - Hdr []byte
71 - Body io.Reader
72 - Err chan error
73 -}
74 -
75 -// newSession is used to construct a new session
76 -func newSession(config *Config, conn io.ReadWriteCloser, client bool) *Session {
77 - s := &Session{
78 - config: config,
79 - logger: log.New(config.LogOutput, "", log.LstdFlags),
80 - conn: conn,
81 - bufRead: bufio.NewReader(conn),
82 - pings: make(map[uint32]chan struct{}),
83 - streams: make(map[uint32]*Stream),
84 - acceptCh: make(chan *Stream, config.AcceptBacklog),
85 - sendCh: make(chan sendReady, 64),
86 - shutdownCh: make(chan struct{}),
87 - }
88 - if client {
89 - s.nextStreamID = 1
90 - } else {
91 - s.nextStreamID = 2
92 - }
93 - go s.recv()
94 - go s.send()
95 - if config.EnableKeepAlive {
96 - go s.keepalive()
97 - }
98 - return s
99 -}
100 -
101 -// IsClosed does a safe check to see if we have shutdown
102 -func (s *Session) IsClosed() bool {
103 - select {
104 - case <-s.shutdownCh:
105 - return true
106 - default:
107 - return false
108 - }
109 -}
110 -
111 -// Open is used to create a new stream as a net.Conn
112 -func (s *Session) Open() (net.Conn, error) {
113 - return s.OpenStream()
114 -}
115 -
116 -// OpenStream is used to create a new stream
117 -func (s *Session) OpenStream() (*Stream, error) {
118 - if s.IsClosed() {
119 - return nil, ErrSessionShutdown
120 - }
121 - if atomic.LoadInt32(&s.remoteGoAway) == 1 {
122 - return nil, ErrRemoteGoAway
123 - }
124 -
125 -GET_ID:
126 - // Get and ID, and check for stream exhaustion
127 - id := atomic.LoadUint32(&s.nextStreamID)
128 - if id >= math.MaxUint32-1 {
129 - return nil, ErrStreamsExhausted
130 - }
131 - if !atomic.CompareAndSwapUint32(&s.nextStreamID, id, id+2) {
132 - goto GET_ID
133 - }
134 -
135 - // Register the stream
136 - stream := newStream(s, id, streamInit)
137 - s.streamLock.Lock()
138 - s.streams[id] = stream
139 - s.streamLock.Unlock()
140 -
141 - // Send the window update to create
142 - return stream, stream.sendWindowUpdate()
143 -}
144 -
145 -// Accept is used to block until the next available stream
146 -// is ready to be accepted.
147 -func (s *Session) Accept() (net.Conn, error) {
148 - return s.AcceptStream()
149 -}
150 -
151 -// AcceptStream is used to block until the next available stream
152 -// is ready to be accepted.
153 -func (s *Session) AcceptStream() (*Stream, error) {
154 - select {
155 - case stream := <-s.acceptCh:
156 - return stream, stream.sendWindowUpdate()
157 - case <-s.shutdownCh:
158 - return nil, s.shutdownErr
159 - }
160 -}
161 -
162 -// Close is used to close the session and all streams.
163 -// Attempts to send a GoAway before closing the connection.
164 -func (s *Session) Close() error {
165 - s.shutdownLock.Lock()
166 - defer s.shutdownLock.Unlock()
167 -
168 - if s.shutdown {
169 - return nil
170 - }
171 - s.shutdown = true
172 - if s.shutdownErr == nil {
173 - s.shutdownErr = ErrSessionShutdown
174 - }
175 - close(s.shutdownCh)
176 - s.conn.Close()
177 -
178 - s.streamLock.Lock()
179 - defer s.streamLock.Unlock()
180 - for _, stream := range s.streams {
181 - stream.forceClose()
182 - }
183 - return nil
184 -}
185 -
186 -// exitErr is used to handle an error that is causing the
187 -// session to terminate.
188 -func (s *Session) exitErr(err error) {
189 - s.shutdownLock.Lock()
190 - if s.shutdownErr == nil {
191 - s.shutdownErr = err
192 - }
193 - s.shutdownLock.Unlock()
194 - s.Close()
195 -}
196 -
197 -// GoAway can be used to prevent accepting further
198 -// connections. It does not close the underlying conn.
199 -func (s *Session) GoAway() error {
200 - return s.waitForSend(s.goAway(goAwayNormal), nil)
201 -}
202 -
203 -// goAway is used to send a goAway message
204 -func (s *Session) goAway(reason uint32) header {
205 - atomic.SwapInt32(&s.localGoAway, 1)
206 - hdr := header(make([]byte, headerSize))
207 - hdr.encode(typeGoAway, 0, 0, reason)
208 - return hdr
209 -}
210 -
211 -// Ping is used to measure the RTT response time
212 -func (s *Session) Ping() (time.Duration, error) {
213 - // Get a channel for the ping
214 - ch := make(chan struct{})
215 -
216 - // Get a new ping id, mark as pending
217 - s.pingLock.Lock()
218 - id := s.pingID
219 - s.pingID++
220 - s.pings[id] = ch
221 - s.pingLock.Unlock()
222 -
223 - // Send the ping request
224 - hdr := header(make([]byte, headerSize))
225 - hdr.encode(typePing, flagSYN, 0, id)
226 - if err := s.waitForSend(hdr, nil); err != nil {
227 - return 0, err
228 - }
229 -
230 - // Wait for a response
231 - start := time.Now()
232 - select {
233 - case <-ch:
234 - case <-s.shutdownCh:
235 - return 0, ErrSessionShutdown
236 - }
237 -
238 - // Compute the RTT
239 - return time.Now().Sub(start), nil
240 -}
241 -
242 -// keepalive is a long running goroutine that periodically does
243 -// a ping to keep the connection alive.
244 -func (s *Session) keepalive() {
245 - for {
246 - select {
247 - case <-time.After(s.config.KeepAliveInterval):
248 - s.Ping()
249 - case <-s.shutdownCh:
250 - return
251 - }
252 - }
253 -}
254 -
255 -// waitForSendErr waits to send a header, checking for a potential shutdown
256 -func (s *Session) waitForSend(hdr header, body io.Reader) error {
257 - errCh := make(chan error, 1)
258 - return s.waitForSendErr(hdr, body, errCh)
259 -}
260 -
261 -// waitForSendErr waits to send a header, checking for a potential shutdown
262 -func (s *Session) waitForSendErr(hdr header, body io.Reader, errCh chan error) error {
263 - ready := sendReady{Hdr: hdr, Body: body, Err: errCh}
264 - select {
265 - case s.sendCh <- ready:
266 - case <-s.shutdownCh:
267 - return ErrSessionShutdown
268 - }
269 - select {
270 - case err := <-errCh:
271 - return err
272 - case <-s.shutdownCh:
273 - return ErrSessionShutdown
274 - }
275 -}
276 -
277 -// sendNoWait does a send without waiting
278 -func (s *Session) sendNoWait(hdr header) error {
279 - select {
280 - case s.sendCh <- sendReady{Hdr: hdr}:
281 - return nil
282 - case <-s.shutdownCh:
283 - return ErrSessionShutdown
284 - }
285 -}
286 -
287 -// send is a long running goroutine that sends data
288 -func (s *Session) send() {
289 - for {
290 - select {
291 - case ready := <-s.sendCh:
292 - // Send a header if ready
293 - if ready.Hdr != nil {
294 - sent := 0
295 - for sent < len(ready.Hdr) {
296 - n, err := s.conn.Write(ready.Hdr[sent:])
297 - if err != nil {
298 - s.logger.Printf("[ERR] yamux: Failed to write header: %v", err)
299 - asyncSendErr(ready.Err, err)
300 - s.exitErr(err)
301 - return
302 - }
303 - sent += n
304 - }
305 - }
306 -
307 - // Send data from a body if given
308 - if ready.Body != nil {
309 - _, err := io.Copy(s.conn, ready.Body)
310 - if err != nil {
311 - s.logger.Printf("[ERR] yamux: Failed to write body: %v", err)
312 - asyncSendErr(ready.Err, err)
313 - s.exitErr(err)
314 - return
315 - }
316 - }
317 -
318 - // No error, successful send
319 - asyncSendErr(ready.Err, nil)
320 - case <-s.shutdownCh:
321 - return
322 - }
323 - }
324 -}
325 -
326 -// recv is a long running goroutine that accepts new data
327 -func (s *Session) recv() {
328 - hdr := header(make([]byte, headerSize))
329 - var handler func(header) error
330 - for {
331 - // Read the header
332 - if _, err := io.ReadFull(s.bufRead, hdr); err != nil {
333 - if err != io.EOF && !strings.Contains(err.Error(), "closed") && !strings.Contains(err.Error(), "reset by peer") {
334 - s.logger.Printf("[ERR] yamux: Failed to read header: %v", err)
335 - }
336 - s.exitErr(err)
337 - return
338 - }
339 -
340 - // Verify the version
341 - if hdr.Version() != protoVersion {
342 - s.logger.Printf("[ERR] yamux: Invalid protocol version: %d", hdr.Version())
343 - s.exitErr(ErrInvalidVersion)
344 - return
345 - }
346 -
347 - // Switch on the type
348 - switch hdr.MsgType() {
349 - case typeData:
350 - handler = s.handleStreamMessage
351 - case typeWindowUpdate:
352 - handler = s.handleStreamMessage
353 - case typeGoAway:
354 - handler = s.handleGoAway
355 - case typePing:
356 - handler = s.handlePing
357 - default:
358 - s.exitErr(ErrInvalidMsgType)
359 - return
360 - }
361 -
362 - // Invoke the handler
363 - if err := handler(hdr); err != nil {
364 - s.exitErr(err)
365 - return
366 - }
367 - }
368 -}
369 -
370 -// handleStreamMessage handles either a data or window update frame
371 -func (s *Session) handleStreamMessage(hdr header) error {
372 - // Check for a new stream creation
373 - id := hdr.StreamID()
374 - flags := hdr.Flags()
375 - if flags&flagSYN == flagSYN {
376 - if err := s.incomingStream(id); err != nil {
377 - return err
378 - }
379 - }
380 -
381 - // Get the stream
382 - s.streamLock.Lock()
383 - stream := s.streams[id]
384 - s.streamLock.Unlock()
385 -
386 - // If we do not have a stream, likely we sent a RST
387 - if stream == nil {
388 - // Drain any data on the wire
389 - if hdr.MsgType() == typeData && hdr.Length() > 0 {
390 - s.logger.Printf("[WARN] yamux: Discarding data for stream: %d", id)
391 - if _, err := io.CopyN(ioutil.Discard, s.bufRead, int64(hdr.Length())); err != nil {
392 - s.logger.Printf("[ERR] yamux: Failed to discard data: %v", err)
393 - return nil
394 - }
395 - } else {
396 - s.logger.Printf("[WARN] yamux: frame for missing stream: %v", hdr)
397 - }
398 - return nil
399 - }
400 -
401 - // Check if this is a window update
402 - if hdr.MsgType() == typeWindowUpdate {
403 - if err := stream.incrSendWindow(hdr, flags); err != nil {
404 - s.sendNoWait(s.goAway(goAwayProtoErr))
405 - return err
406 - }
407 - return nil
408 - }
409 -
410 - // Read the new data
411 - if err := stream.readData(hdr, flags, s.bufRead); err != nil {
412 - s.sendNoWait(s.goAway(goAwayProtoErr))
413 - return err
414 - }
415 - return nil
416 -}
417 -
418 -// handlePing is invokde for a typePing frame
419 -func (s *Session) handlePing(hdr header) error {
420 - flags := hdr.Flags()
421 - pingID := hdr.Length()
422 -
423 - // Check if this is a query, respond back
424 - if flags&flagSYN == flagSYN {
425 - hdr := header(make([]byte, headerSize))
426 - hdr.encode(typePing, flagACK, 0, pingID)
427 - s.sendNoWait(hdr)
428 - return nil
429 - }
430 -
431 - // Handle a response
432 - s.pingLock.Lock()
433 - ch := s.pings[pingID]
434 - if ch != nil {
435 - delete(s.pings, pingID)
436 - close(ch)
437 - }
438 - s.pingLock.Unlock()
439 - return nil
440 -}
441 -
442 -// handleGoAway is invokde for a typeGoAway frame
443 -func (s *Session) handleGoAway(hdr header) error {
444 - code := hdr.Length()
445 - switch code {
446 - case goAwayNormal:
447 - atomic.SwapInt32(&s.remoteGoAway, 1)
448 - case goAwayProtoErr:
449 - s.logger.Printf("[ERR] yamux: received protocol error go away")
450 - return fmt.Errorf("yamux protocol error")
451 - case goAwayInternalErr:
452 - s.logger.Printf("[ERR] yamux: received internal error go away")
453 - return fmt.Errorf("remote yamux internal error")
454 - default:
455 - s.logger.Printf("[ERR] yamux: received unexpected go away")
456 - return fmt.Errorf("unexpected go away received")
457 - }
458 - return nil
459 -}
460 -
461 -// incomingStream is used to create a new incoming stream
462 -func (s *Session) incomingStream(id uint32) error {
463 - // Reject immediately if we are doing a go away
464 - if atomic.LoadInt32(&s.localGoAway) == 1 {
465 - hdr := header(make([]byte, headerSize))
466 - hdr.encode(typeWindowUpdate, flagRST, id, 0)
467 - return s.sendNoWait(hdr)
468 - }
469 -
470 - // Allocate a new stream
471 - stream := newStream(s, id, streamSYNReceived)
472 -
473 - s.streamLock.Lock()
474 - defer s.streamLock.Unlock()
475 -
476 - // Check if stream already exists
477 - if _, ok := s.streams[id]; ok {
478 - s.logger.Printf("[ERR] yamux: duplicate stream declared")
479 - s.sendNoWait(s.goAway(goAwayProtoErr))
480 - return ErrDuplicateStream
481 - }
482 -
483 - // Register the stream
484 - s.streams[id] = stream
485 -
486 - // Check if we've exceeded the backlog
487 - select {
488 - case s.acceptCh <- stream:
489 - return nil
490 - default:
491 - // Backlog exceeded! RST the stream
492 - s.logger.Printf("[WARN] yamux: backlog exceeded, forcing connection reset")
493 - delete(s.streams, id)
494 - stream.sendHdr.encode(typeWindowUpdate, flagRST, id, 0)
495 - return s.sendNoWait(stream.sendHdr)
496 - }
497 -}
498 -
499 -// closeStream is used to close a stream once both sides have
500 -// issued a close.
501 -func (s *Session) closeStream(id uint32) {
502 - s.streamLock.Lock()
503 - delete(s.streams, id)
504 - s.streamLock.Unlock()
505 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/session_test.go deleted
-729
@@ -1,729 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "bytes"
5 - "fmt"
6 - "io"
7 - "io/ioutil"
8 - "runtime"
9 - "sync"
10 - "testing"
11 - "time"
12 -)
13 -
14 -type pipeConn struct {
15 - reader *io.PipeReader
16 - writer *io.PipeWriter
17 -}
18 -
19 -func (p *pipeConn) Read(b []byte) (int, error) {
20 - return p.reader.Read(b)
21 -}
22 -
23 -func (p *pipeConn) Write(b []byte) (int, error) {
24 - return p.writer.Write(b)
25 -}
26 -
27 -func (p *pipeConn) Close() error {
28 - p.reader.Close()
29 - return p.writer.Close()
30 -}
31 -
32 -func testConn() (io.ReadWriteCloser, io.ReadWriteCloser) {
33 - read1, write1 := io.Pipe()
34 - read2, write2 := io.Pipe()
35 - return &pipeConn{read1, write2}, &pipeConn{read2, write1}
36 -}
37 -
38 -func testClientServer() (*Session, *Session) {
39 - conf := DefaultConfig()
40 - conf.AcceptBacklog = 64
41 - conf.KeepAliveInterval = 100 * time.Millisecond
42 - return testClientServerConfig(conf)
43 -}
44 -
45 -func testClientServerConfig(conf *Config) (*Session, *Session) {
46 - conn1, conn2 := testConn()
47 - client, _ := Client(conn1, conf)
48 - server, _ := Server(conn2, conf)
49 - return client, server
50 -}
51 -
52 -func TestPing(t *testing.T) {
53 - client, server := testClientServer()
54 - defer client.Close()
55 - defer server.Close()
56 -
57 - rtt, err := client.Ping()
58 - if err != nil {
59 - t.Fatalf("err: %v", err)
60 - }
61 - if rtt == 0 {
62 - t.Fatalf("bad: %v", rtt)
63 - }
64 -
65 - rtt, err = server.Ping()
66 - if err != nil {
67 - t.Fatalf("err: %v", err)
68 - }
69 - if rtt == 0 {
70 - t.Fatalf("bad: %v", rtt)
71 - }
72 -}
73 -
74 -func TestAccept(t *testing.T) {
75 - client, server := testClientServer()
76 - defer client.Close()
77 - defer server.Close()
78 -
79 - wg := &sync.WaitGroup{}
80 - wg.Add(4)
81 -
82 - go func() {
83 - defer wg.Done()
84 - stream, err := server.AcceptStream()
85 - if err != nil {
86 - t.Fatalf("err: %v", err)
87 - }
88 - if id := stream.StreamID(); id != 1 {
89 - t.Fatalf("bad: %v", id)
90 - }
91 - if err := stream.Close(); err != nil {
92 - t.Fatalf("err: %v", err)
93 - }
94 - }()
95 -
96 - go func() {
97 - defer wg.Done()
98 - stream, err := client.AcceptStream()
99 - if err != nil {
100 - t.Fatalf("err: %v", err)
101 - }
102 - if id := stream.StreamID(); id != 2 {
103 - t.Fatalf("bad: %v", id)
104 - }
105 - if err := stream.Close(); err != nil {
106 - t.Fatalf("err: %v", err)
107 - }
108 - }()
109 -
110 - go func() {
111 - defer wg.Done()
112 - stream, err := server.OpenStream()
113 - if err != nil {
114 - t.Fatalf("err: %v", err)
115 - }
116 - if id := stream.StreamID(); id != 2 {
117 - t.Fatalf("bad: %v", id)
118 - }
119 - if err := stream.Close(); err != nil {
120 - t.Fatalf("err: %v", err)
121 - }
122 - }()
123 -
124 - go func() {
125 - defer wg.Done()
126 - stream, err := client.OpenStream()
127 - if err != nil {
128 - t.Fatalf("err: %v", err)
129 - }
130 - if id := stream.StreamID(); id != 1 {
131 - t.Fatalf("bad: %v", id)
132 - }
133 - if err := stream.Close(); err != nil {
134 - t.Fatalf("err: %v", err)
135 - }
136 - }()
137 -
138 - doneCh := make(chan struct{})
139 - go func() {
140 - wg.Wait()
141 - close(doneCh)
142 - }()
143 -
144 - select {
145 - case <-doneCh:
146 - case <-time.After(time.Second):
147 - panic("timeout")
148 - }
149 -}
150 -
151 -func TestSendData_Small(t *testing.T) {
152 - client, server := testClientServer()
153 - defer client.Close()
154 - defer server.Close()
155 -
156 - wg := &sync.WaitGroup{}
157 - wg.Add(2)
158 -
159 - go func() {
160 - defer wg.Done()
161 - stream, err := server.AcceptStream()
162 - if err != nil {
163 - t.Fatalf("err: %v", err)
164 - }
165 -
166 - buf := make([]byte, 4)
167 - for i := 0; i < 1000; i++ {
168 - n, err := stream.Read(buf)
169 - if err != nil {
170 - t.Fatalf("err: %v", err)
171 - }
172 - if n != 4 {
173 - t.Fatalf("short read: %d", n)
174 - }
175 - if string(buf) != "test" {
176 - t.Fatalf("bad: %s", buf)
177 - }
178 - }
179 -
180 - if err := stream.Close(); err != nil {
181 - t.Fatalf("err: %v", err)
182 - }
183 - }()
184 -
185 - go func() {
186 - defer wg.Done()
187 - stream, err := client.Open()
188 - if err != nil {
189 - t.Fatalf("err: %v", err)
190 - }
191 -
192 - for i := 0; i < 1000; i++ {
193 - n, err := stream.Write([]byte("test"))
194 - if err != nil {
195 - t.Fatalf("err: %v", err)
196 - }
197 - if n != 4 {
198 - t.Fatalf("short write %d", n)
199 - }
200 - }
201 -
202 - if err := stream.Close(); err != nil {
203 - t.Fatalf("err: %v", err)
204 - }
205 - }()
206 -
207 - doneCh := make(chan struct{})
208 - go func() {
209 - wg.Wait()
210 - close(doneCh)
211 - }()
212 - select {
213 - case <-doneCh:
214 - case <-time.After(time.Second):
215 - panic("timeout")
216 - }
217 -}
218 -
219 -func TestSendData_Large(t *testing.T) {
220 - client, server := testClientServer()
221 - defer client.Close()
222 - defer server.Close()
223 -
224 - data := make([]byte, 512*1024)
225 - for idx := range data {
226 - data[idx] = byte(idx % 256)
227 - }
228 -
229 - wg := &sync.WaitGroup{}
230 - wg.Add(2)
231 -
232 - go func() {
233 - defer wg.Done()
234 - stream, err := server.AcceptStream()
235 - if err != nil {
236 - t.Fatalf("err: %v", err)
237 - }
238 -
239 - buf := make([]byte, 4*1024)
240 - for i := 0; i < 128; i++ {
241 - n, err := stream.Read(buf)
242 - if err != nil {
243 - t.Fatalf("err: %v", err)
244 - }
245 - if n != 4*1024 {
246 - t.Fatalf("short read: %d", n)
247 - }
248 - for idx := range buf {
249 - if buf[idx] != byte(idx%256) {
250 - t.Fatalf("bad: %v %v %v", i, idx, buf[idx])
251 - }
252 - }
253 - }
254 -
255 - if err := stream.Close(); err != nil {
256 - t.Fatalf("err: %v", err)
257 - }
258 - }()
259 -
260 - go func() {
261 - defer wg.Done()
262 - stream, err := client.Open()
263 - if err != nil {
264 - t.Fatalf("err: %v", err)
265 - }
266 -
267 - n, err := stream.Write(data)
268 - if err != nil {
269 - t.Fatalf("err: %v", err)
270 - }
271 - if n != len(data) {
272 - t.Fatalf("short write %d", n)
273 - }
274 -
275 - if err := stream.Close(); err != nil {
276 - t.Fatalf("err: %v", err)
277 - }
278 - }()
279 -
280 - doneCh := make(chan struct{})
281 - go func() {
282 - wg.Wait()
283 - close(doneCh)
284 - }()
285 - select {
286 - case <-doneCh:
287 - case <-time.After(time.Second):
288 - panic("timeout")
289 - }
290 -}
291 -
292 -func TestGoAway(t *testing.T) {
293 - client, server := testClientServer()
294 - defer client.Close()
295 - defer server.Close()
296 -
297 - if err := server.GoAway(); err != nil {
298 - t.Fatalf("err: %v", err)
299 - }
300 -
301 - _, err := client.Open()
302 - if err != ErrRemoteGoAway {
303 - t.Fatalf("err: %v", err)
304 - }
305 -}
306 -
307 -func TestManyStreams(t *testing.T) {
308 - client, server := testClientServer()
309 - defer client.Close()
310 - defer server.Close()
311 -
312 - wg := &sync.WaitGroup{}
313 -
314 - acceptor := func(i int) {
315 - defer wg.Done()
316 - stream, err := server.AcceptStream()
317 - if err != nil {
318 - t.Fatalf("err: %v", err)
319 - }
320 - defer stream.Close()
321 -
322 - buf := make([]byte, 512)
323 - for {
324 - n, err := stream.Read(buf)
325 - if err == io.EOF {
326 - return
327 - }
328 - if err != nil {
329 - t.Fatalf("err: %v", err)
330 - }
331 - if n == 0 {
332 - t.Fatalf("err: %v", err)
333 - }
334 - }
335 - }
336 - sender := func(i int) {
337 - defer wg.Done()
338 - stream, err := client.Open()
339 - if err != nil {
340 - t.Fatalf("err: %v", err)
341 - }
342 - defer stream.Close()
343 -
344 - msg := fmt.Sprintf("%08d", i)
345 - for i := 0; i < 1000; i++ {
346 - n, err := stream.Write([]byte(msg))
347 - if err != nil {
348 - t.Fatalf("err: %v", err)
349 - }
350 - if n != len(msg) {
351 - t.Fatalf("short write %d", n)
352 - }
353 - }
354 - }
355 -
356 - for i := 0; i < 50; i++ {
357 - wg.Add(2)
358 - go acceptor(i)
359 - go sender(i)
360 - }
361 -
362 - wg.Wait()
363 -}
364 -
365 -func TestManyStreams_PingPong(t *testing.T) {
366 - client, server := testClientServer()
367 - defer client.Close()
368 - defer server.Close()
369 -
370 - wg := &sync.WaitGroup{}
371 -
372 - ping := []byte("ping")
373 - pong := []byte("pong")
374 -
375 - acceptor := func(i int) {
376 - defer wg.Done()
377 - stream, err := server.AcceptStream()
378 - if err != nil {
379 - t.Fatalf("err: %v", err)
380 - }
381 - defer stream.Close()
382 -
383 - buf := make([]byte, 4)
384 - for {
385 - n, err := stream.Read(buf)
386 - if err == io.EOF {
387 - return
388 - }
389 - if err != nil {
390 - t.Fatalf("err: %v", err)
391 - }
392 - if n != 4 {
393 - t.Fatalf("err: %v", err)
394 - }
395 - if !bytes.Equal(buf, ping) {
396 - t.Fatalf("bad: %s", buf)
397 - }
398 - n, err = stream.Write(pong)
399 - if err != nil {
400 - t.Fatalf("err: %v", err)
401 - }
402 - if n != 4 {
403 - t.Fatalf("err: %v", err)
404 - }
405 - }
406 - }
407 - sender := func(i int) {
408 - defer wg.Done()
409 - stream, err := client.Open()
410 - if err != nil {
411 - t.Fatalf("err: %v", err)
412 - }
413 - defer stream.Close()
414 -
415 - buf := make([]byte, 4)
416 - for i := 0; i < 1000; i++ {
417 - n, err := stream.Write(ping)
418 - if err != nil {
419 - t.Fatalf("err: %v", err)
420 - }
421 - if n != 4 {
422 - t.Fatalf("short write %d", n)
423 - }
424 -
425 - n, err = stream.Read(buf)
426 - if err != nil {
427 - t.Fatalf("err: %v", err)
428 - }
429 - if n != 4 {
430 - t.Fatalf("err: %v", err)
431 - }
432 - if !bytes.Equal(buf, pong) {
433 - t.Fatalf("bad: %s", buf)
434 - }
435 - }
436 - }
437 -
438 - for i := 0; i < 50; i++ {
439 - wg.Add(2)
440 - go acceptor(i)
441 - go sender(i)
442 - }
443 -
444 - wg.Wait()
445 -}
446 -
447 -func TestHalfClose(t *testing.T) {
448 - client, server := testClientServer()
449 - defer client.Close()
450 - defer server.Close()
451 -
452 - stream, err := client.Open()
453 - if err != nil {
454 - t.Fatalf("err: %v", err)
455 - }
456 - if _, err := stream.Write([]byte("a")); err != nil {
457 - t.Fatalf("err: %v", err)
458 - }
459 -
460 - stream2, err := server.Accept()
461 - if err != nil {
462 - t.Fatalf("err: %v", err)
463 - }
464 - stream2.Close() // Half close
465 -
466 - buf := make([]byte, 4)
467 - n, err := stream2.Read(buf)
468 - if err != nil {
469 - t.Fatalf("err: %v", err)
470 - }
471 - if n != 1 {
472 - t.Fatalf("bad: %v", n)
473 - }
474 -
475 - // Send more
476 - if _, err := stream.Write([]byte("bcd")); err != nil {
477 - t.Fatalf("err: %v", err)
478 - }
479 - stream.Close()
480 -
481 - // Read after close
482 - n, err = stream2.Read(buf)
483 - if err != nil {
484 - t.Fatalf("err: %v", err)
485 - }
486 - if n != 3 {
487 - t.Fatalf("bad: %v", n)
488 - }
489 -
490 - // EOF after close
491 - n, err = stream2.Read(buf)
492 - if err != io.EOF {
493 - t.Fatalf("err: %v", err)
494 - }
495 - if n != 0 {
496 - t.Fatalf("bad: %v", n)
497 - }
498 -}
499 -
500 -func TestReadDeadline(t *testing.T) {
501 - client, server := testClientServer()
502 - defer client.Close()
503 - defer server.Close()
504 -
505 - stream, err := client.Open()
506 - if err != nil {
507 - t.Fatalf("err: %v", err)
508 - }
509 - defer stream.Close()
510 -
511 - stream2, err := server.Accept()
512 - if err != nil {
513 - t.Fatalf("err: %v", err)
514 - }
515 - defer stream2.Close()
516 -
517 - if err := stream.SetReadDeadline(time.Now().Add(5 * time.Millisecond)); err != nil {
518 - t.Fatalf("err: %v", err)
519 - }
520 -
521 - buf := make([]byte, 4)
522 - if _, err := stream.Read(buf); err != ErrTimeout {
523 - t.Fatalf("err: %v", err)
524 - }
525 -}
526 -
527 -func TestWriteDeadline(t *testing.T) {
528 - client, server := testClientServer()
529 - defer client.Close()
530 - defer server.Close()
531 -
532 - stream, err := client.Open()
533 - if err != nil {
534 - t.Fatalf("err: %v", err)
535 - }
536 - defer stream.Close()
537 -
538 - stream2, err := server.Accept()
539 - if err != nil {
540 - t.Fatalf("err: %v", err)
541 - }
542 - defer stream2.Close()
543 -
544 - if err := stream.SetWriteDeadline(time.Now().Add(50 * time.Millisecond)); err != nil {
545 - t.Fatalf("err: %v", err)
546 - }
547 -
548 - buf := make([]byte, 512)
549 - for i := 0; i < int(initialStreamWindow); i++ {
550 - _, err := stream.Write(buf)
551 - if err != nil && err == ErrTimeout {
552 - return
553 - } else if err != nil {
554 - t.Fatalf("err: %v", err)
555 - }
556 - }
557 - t.Fatalf("Expected timeout")
558 -}
559 -
560 -func TestBacklogExceeded(t *testing.T) {
561 - client, server := testClientServer()
562 - defer client.Close()
563 - defer server.Close()
564 -
565 - // Fill the backlog
566 - max := client.config.AcceptBacklog
567 - for i := 0; i < max; i++ {
568 - stream, err := client.Open()
569 - if err != nil {
570 - t.Fatalf("err: %v", err)
571 - }
572 - defer stream.Close()
573 -
574 - if _, err := stream.Write([]byte("foo")); err != nil {
575 - t.Fatalf("err: %v", err)
576 - }
577 - }
578 -
579 - // Exceed the backlog!
580 - stream, err := client.Open()
581 - if err != nil {
582 - t.Fatalf("err: %v", err)
583 - }
584 - defer stream.Close()
585 -
586 - if _, err := stream.Write([]byte("foo")); err != nil {
587 - t.Fatalf("err: %v", err)
588 - }
589 -
590 - buf := make([]byte, 4)
591 - stream.SetReadDeadline(time.Now().Add(50 * time.Millisecond))
592 - if _, err := stream.Read(buf); err != ErrConnectionReset {
593 - t.Fatalf("err: %v", err)
594 - }
595 -}
596 -
597 -func TestKeepAlive(t *testing.T) {
598 - client, server := testClientServer()
599 - defer client.Close()
600 - defer server.Close()
601 -
602 - time.Sleep(200 * time.Millisecond)
603 -
604 - // Ping value should increase
605 - client.pingLock.Lock()
606 - defer client.pingLock.Unlock()
607 - if client.pingID == 0 {
608 - t.Fatalf("should ping")
609 - }
610 -
611 - server.pingLock.Lock()
612 - defer server.pingLock.Unlock()
613 - if server.pingID == 0 {
614 - t.Fatalf("should ping")
615 - }
616 -}
617 -
618 -func TestLargeWindow(t *testing.T) {
619 - conf := DefaultConfig()
620 - conf.MaxStreamWindowSize *= 2
621 -
622 - client, server := testClientServerConfig(conf)
623 - defer client.Close()
624 - defer server.Close()
625 -
626 - stream, err := client.Open()
627 - if err != nil {
628 - t.Fatalf("err: %v", err)
629 - }
630 - defer stream.Close()
631 -
632 - stream2, err := server.Accept()
633 - if err != nil {
634 - t.Fatalf("err: %v", err)
635 - }
636 - defer stream2.Close()
637 -
638 - stream.SetWriteDeadline(time.Now().Add(10 * time.Millisecond))
639 - buf := make([]byte, conf.MaxStreamWindowSize)
640 - n, err := stream.Write(buf)
641 - if err != nil {
642 - t.Fatalf("err: %v", err)
643 - }
644 - if n != len(buf) {
645 - t.Fatalf("short write: %d", n)
646 - }
647 -}
648 -
649 -type UnlimitedReader struct{}
650 -
651 -func (u *UnlimitedReader) Read(p []byte) (int, error) {
652 - runtime.Gosched()
653 - return len(p), nil
654 -}
655 -
656 -func TestSendData_VeryLarge(t *testing.T) {
657 - client, server := testClientServer()
658 - defer client.Close()
659 - defer server.Close()
660 -
661 - var n int64 = 1 * 1024 * 1024 * 1024
662 - var workers int = 16
663 -
664 - wg := &sync.WaitGroup{}
665 - wg.Add(workers * 2)
666 -
667 - for i := 0; i < workers; i++ {
668 - go func() {
669 - defer wg.Done()
670 - stream, err := server.AcceptStream()
671 - if err != nil {
672 - t.Fatalf("err: %v", err)
673 - }
674 - defer stream.Close()
675 -
676 - buf := make([]byte, 4)
677 - _, err = stream.Read(buf)
678 - if err != nil {
679 - t.Fatalf("err: %v", err)
680 - }
681 - if !bytes.Equal(buf, []byte{0, 1, 2, 3}) {
682 - t.Fatalf("bad header")
683 - }
684 -
685 - recv, err := io.Copy(ioutil.Discard, stream)
686 - if err != nil {
687 - t.Fatalf("err: %v", err)
688 - }
689 - if recv != n {
690 - t.Fatalf("bad: %v", recv)
691 - }
692 - }()
693 - }
694 - for i := 0; i < workers; i++ {
695 - go func() {
696 - defer wg.Done()
697 - stream, err := client.Open()
698 - if err != nil {
699 - t.Fatalf("err: %v", err)
700 - }
701 - defer stream.Close()
702 -
703 - _, err = stream.Write([]byte{0, 1, 2, 3})
704 - if err != nil {
705 - t.Fatalf("err: %v", err)
706 - }
707 -
708 - unlimited := &UnlimitedReader{}
709 - sent, err := io.Copy(stream, io.LimitReader(unlimited, n))
710 - if err != nil {
711 - t.Fatalf("err: %v", err)
712 - }
713 - if sent != n {
714 - t.Fatalf("bad: %v", sent)
715 - }
716 - }()
717 - }
718 -
719 - doneCh := make(chan struct{})
720 - go func() {
721 - wg.Wait()
722 - close(doneCh)
723 - }()
724 - select {
725 - case <-doneCh:
726 - case <-time.After(20 * time.Second):
727 - panic("timeout")
728 - }
729 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/spec.md deleted
-141
@@ -1,141 +0,0 @@
1 -# Specification
2 -
3 -We use this document to detail the internal specification of Yamux.
4 -This is used both as a guide for implementing Yamux, but also for
5 -alternative interoperable libraries to be built.
6 -
7 -# Framing
8 -
9 -Yamux uses a streaming connection underneath, but imposes a message
10 -framing so that it can be shared between many logical streams. Each
11 -frame contains a header like:
12 -
13 -* Version (8 bits)
14 -* Type (8 bits)
15 -* Flags (16 bits)
16 -* StreamID (32 bits)
17 -* Length (32 bits)
18 -
19 -This means that each header has a 12 byte overhead.
20 -All fields are encoded in network order (big endian).
21 -Each field is described below:
22 -
23 -## Version Field
24 -
25 -The version field is used for future backwards compatibily. At the
26 -current time, the field is always set to 0, to indicate the initial
27 -version.
28 -
29 -## Type Field
30 -
31 -The type field is used to switch the frame message type. The following
32 -message types are supported:
33 -
34 -* 0x0 Data - Used to transmit data. May transmit zero length payloads
35 - depending on the flags.
36 -
37 -* 0x1 Window Update - Used to updated the senders receive window size.
38 - This is used to implement per-session flow control.
39 -
40 -* 0x2 Ping - Used to measure RTT. It can also be used to heart-beat
41 - and do keep-alives over TCP.
42 -
43 -* 0x3 Go Away - Used to close a session.
44 -
45 -## Flag Field
46 -
47 -The flags field is used to provide additional information related
48 -to the message type. The following flags are supported:
49 -
50 -* 0x1 SYN - Signals the start of a new stream. May be sent with a data or
51 - window update message. Also sent with a ping to indicate outbound.
52 -
53 -* 0x2 ACK - Acknowledges the start of a new stream. May be sent with a data
54 - or window update message. Also sent with a ping to indicate response.
55 -
56 -* 0x4 FIN - Performs a half-close of a stream. May be sent with a data
57 - message or window update.
58 -
59 -* 0x8 RST - Reset a stream immediately. May be sent with a data or
60 - window update message.
61 -
62 -## StreamID Field
63 -
64 -The StreamID field is used to identify the logical stream the frame
65 -is addressing. The client side should use odd ID's, and the server even.
66 -This prevents any collisions. Additionally, the 0 ID is reserved to represent
67 -the session.
68 -
69 -Both Ping and Go Away messages should always use the 0 StreamID.
70 -
71 -## Length Field
72 -
73 -The meaning of the length field depends on the message type:
74 -
75 -* Data - provides the length of bytes following the header
76 -* Window update - provides a delta update to the window size
77 -* Ping - Contains an opaque value, echoed back
78 -* Go Away - Contains an error code
79 -
80 -# Message Flow
81 -
82 -There is no explicit connection setup, as Yamux relies on an underlying
83 -transport to be provided. However, there is a distinction between client
84 -and server side of the connection.
85 -
86 -## Opening a stream
87 -
88 -To open a stream, an initial data or window update frame is sent
89 -with a new StreamID. The SYN flag should be set to signal a new stream.
90 -
91 -The receiver must then reply with either a data or window update frame
92 -with the StreamID along with the ACK flag to accept the stream or with
93 -the RST flag to reject the stream.
94 -
95 -Because we are relying on the reliable stream underneath, a connection
96 -can begin sending data once the SYN flag is sent. The corresponding
97 -ACK does not need to be received. This is particularly well suited
98 -for an RPC system where a client wants to open a stream and immediately
99 -fire a request without wiating for the RTT of the ACK.
100 -
101 -This does introduce the possibility of a connection being rejected
102 -after data has been sent already. This is a slight semantic difference
103 -from TCP, where the conection cannot be refused after it is opened.
104 -Clients should be prepared to handle this by checking for an error
105 -that indicates a RST was received.
106 -
107 -## Closing a stream
108 -
109 -To close a stream, either side sends a data or window update frame
110 -along with the FIN flag. This does a half-close indicating the sender
111 -will send no further data.
112 -
113 -Once both sides have closed the connection, the stream is closed.
114 -
115 -Alternatively, if an error occurs, the RST flag can be used to
116 -hard close a stream immediately.
117 -
118 -## Flow Control
119 -
120 -When Yamux is initially starts each stream with a 256KB window size.
121 -There is no window size for the session.
122 -
123 -To prevent the streams from stalling, window update frames should be
124 -sent regularly. Yamux can be configured to provide a larger limit for
125 -windows sizes. Both sides assume the initial 256KB window, but can
126 -immediately send a window update as part of the SYN/ACK indicating a
127 -larger window.
128 -
129 -Both sides should track the number of bytes sent in Data frames
130 -only, as only they are tracked as part of the window size.
131 -
132 -## Session termination
133 -
134 -When a session is being terminated, the Go Away message should
135 -be sent. The Length should be set to one of the following to
136 -provide an error code:
137 -
138 -* 0x0 Normal termination
139 -* 0x1 Protocol error
140 -* 0x2 Internal error
141 -
Godeps/_workspace/src/github.com/hashicorp/yamux/stream.go deleted
-417
@@ -1,417 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "bytes"
5 - "io"
6 - "sync"
7 - "sync/atomic"
8 - "time"
9 -)
10 -
11 -type streamState int
12 -
13 -const (
14 - streamInit streamState = iota
15 - streamSYNSent
16 - streamSYNReceived
17 - streamEstablished
18 - streamLocalClose
19 - streamRemoteClose
20 - streamClosed
21 - streamReset
22 -)
23 -
24 -// Stream is used to represent a logical stream
25 -// within a session.
26 -type Stream struct {
27 - recvWindow uint32
28 - sendWindow uint32
29 -
30 - id uint32
31 - session *Session
32 -
33 - state streamState
34 - stateLock sync.Mutex
35 -
36 - recvBuf bytes.Buffer
37 - recvLock sync.Mutex
38 -
39 - controlHdr header
40 - controlErr chan error
41 - controlHdrLock sync.Mutex
42 -
43 - sendHdr header
44 - sendErr chan error
45 - sendLock sync.Mutex
46 -
47 - recvNotifyCh chan struct{}
48 - sendNotifyCh chan struct{}
49 -
50 - readDeadline time.Time
51 - writeDeadline time.Time
52 -}
53 -
54 -// newStream is used to construct a new stream within
55 -// a given session for an ID
56 -func newStream(session *Session, id uint32, state streamState) *Stream {
57 - s := &Stream{
58 - id: id,
59 - session: session,
60 - state: state,
61 - controlHdr: header(make([]byte, headerSize)),
62 - controlErr: make(chan error, 1),
63 - sendHdr: header(make([]byte, headerSize)),
64 - sendErr: make(chan error, 1),
65 - recvWindow: initialStreamWindow,
66 - sendWindow: initialStreamWindow,
67 - recvNotifyCh: make(chan struct{}, 1),
68 - sendNotifyCh: make(chan struct{}, 1),
69 - }
70 - return s
71 -}
72 -
73 -// Session returns the associated stream session
74 -func (s *Stream) Session() *Session {
75 - return s.session
76 -}
77 -
78 -// StreamID returns the ID of this stream
79 -func (s *Stream) StreamID() uint32 {
80 - return s.id
81 -}
82 -
83 -// Read is used to read from the stream
84 -func (s *Stream) Read(b []byte) (n int, err error) {
85 - defer asyncNotify(s.recvNotifyCh)
86 -START:
87 - s.stateLock.Lock()
88 - switch s.state {
89 - case streamRemoteClose:
90 - fallthrough
91 - case streamClosed:
92 - if s.recvBuf.Len() == 0 {
93 - s.stateLock.Unlock()
94 - return 0, io.EOF
95 - }
96 - case streamReset:
97 - s.stateLock.Unlock()
98 - return 0, ErrConnectionReset
99 - }
100 - s.stateLock.Unlock()
101 -
102 - // If there is no data available, block
103 - s.recvLock.Lock()
104 - if s.recvBuf.Len() == 0 {
105 - s.recvLock.Unlock()
106 - goto WAIT
107 - }
108 -
109 - // Read any bytes
110 - n, _ = s.recvBuf.Read(b)
111 - s.recvLock.Unlock()
112 -
113 - // Send a window update potentially
114 - err = s.sendWindowUpdate()
115 - return n, err
116 -
117 -WAIT:
118 - var timeout <-chan time.Time
119 - if !s.readDeadline.IsZero() {
120 - delay := s.readDeadline.Sub(time.Now())
121 - timeout = time.After(delay)
122 - }
123 - select {
124 - case <-s.recvNotifyCh:
125 - goto START
126 - case <-timeout:
127 - return 0, ErrTimeout
128 - }
129 -}
130 -
131 -// Write is used to write to the stream
132 -func (s *Stream) Write(b []byte) (n int, err error) {
133 - s.sendLock.Lock()
134 - defer s.sendLock.Unlock()
135 - total := 0
136 - for total < len(b) {
137 - n, err := s.write(b[total:])
138 - total += n
139 - if err != nil {
140 - return total, err
141 - }
142 - }
143 - return total, nil
144 -}
145 -
146 -// write is used to write to the stream, may return on
147 -// a short write.
148 -func (s *Stream) write(b []byte) (n int, err error) {
149 - var flags uint16
150 - var max uint32
151 - var body io.Reader
152 -START:
153 - s.stateLock.Lock()
154 - switch s.state {
155 - case streamLocalClose:
156 - fallthrough
157 - case streamClosed:
158 - s.stateLock.Unlock()
159 - return 0, ErrStreamClosed
160 - case streamReset:
161 - s.stateLock.Unlock()
162 - return 0, ErrConnectionReset
163 - }
164 - s.stateLock.Unlock()
165 -
166 - // If there is no data available, block
167 - window := atomic.LoadUint32(&s.sendWindow)
168 - if window == 0 {
169 - goto WAIT
170 - }
171 -
172 - // Determine the flags if any
173 - flags = s.sendFlags()
174 -
175 - // Send up to our send window
176 - max = min(window, uint32(len(b)))
177 - body = bytes.NewReader(b[:max])
178 -
179 - // Send the header
180 - s.sendHdr.encode(typeData, flags, s.id, max)
181 - if err := s.session.waitForSendErr(s.sendHdr, body, s.sendErr); err != nil {
182 - return 0, err
183 - }
184 -
185 - // Reduce our send window
186 - atomic.AddUint32(&s.sendWindow, ^uint32(max-1))
187 -
188 - // Unlock
189 - return int(max), err
190 -
191 -WAIT:
192 - var timeout <-chan time.Time
193 - if !s.writeDeadline.IsZero() {
194 - delay := s.writeDeadline.Sub(time.Now())
195 - timeout = time.After(delay)
196 - }
197 - select {
198 - case <-s.sendNotifyCh:
199 - goto START
200 - case <-timeout:
201 - return 0, ErrTimeout
202 - }
203 - return 0, nil
204 -}
205 -
206 -// sendFlags determines any flags that are appropriate
207 -// based on the current stream state
208 -func (s *Stream) sendFlags() uint16 {
209 - s.stateLock.Lock()
210 - defer s.stateLock.Unlock()
211 - var flags uint16
212 - switch s.state {
213 - case streamInit:
214 - flags |= flagSYN
215 - s.state = streamSYNSent
216 - case streamSYNReceived:
217 - flags |= flagACK
218 - s.state = streamEstablished
219 - }
220 - return flags
221 -}
222 -
223 -// sendWindowUpdate potentially sends a window update enabling
224 -// further writes to take place. Must be invoked with the lock.
225 -func (s *Stream) sendWindowUpdate() error {
226 - s.controlHdrLock.Lock()
227 - defer s.controlHdrLock.Unlock()
228 -
229 - // Determine the delta update
230 - max := s.session.config.MaxStreamWindowSize
231 - delta := max - atomic.LoadUint32(&s.recvWindow)
232 -
233 - // Determine the flags if any
234 - flags := s.sendFlags()
235 -
236 - // Check if we can omit the update
237 - if delta < (max/2) && flags == 0 {
238 - return nil
239 - }
240 -
241 - // Update our window
242 - atomic.AddUint32(&s.recvWindow, delta)
243 -
244 - // Send the header
245 - s.controlHdr.encode(typeWindowUpdate, flags, s.id, delta)
246 - if err := s.session.waitForSendErr(s.controlHdr, nil, s.controlErr); err != nil {
247 - return err
248 - }
249 - return nil
250 -}
251 -
252 -// sendClose is used to send a FIN
253 -func (s *Stream) sendClose() error {
254 - s.controlHdrLock.Lock()
255 - defer s.controlHdrLock.Unlock()
256 -
257 - flags := s.sendFlags()
258 - flags |= flagFIN
259 - s.controlHdr.encode(typeWindowUpdate, flags, s.id, 0)
260 - if err := s.session.waitForSendErr(s.controlHdr, nil, s.controlErr); err != nil {
261 - return err
262 - }
263 - return nil
264 -}
265 -
266 -// Close is used to close the stream
267 -func (s *Stream) Close() error {
268 - s.stateLock.Lock()
269 - switch s.state {
270 - // Opened means we need to signal a close
271 - case streamSYNSent:
272 - fallthrough
273 - case streamSYNReceived:
274 - fallthrough
275 - case streamEstablished:
276 - s.state = streamLocalClose
277 - goto SEND_CLOSE
278 -
279 - case streamLocalClose:
280 - case streamRemoteClose:
281 - s.state = streamClosed
282 - s.session.closeStream(s.id)
283 - goto SEND_CLOSE
284 -
285 - case streamClosed:
286 - case streamReset:
287 - default:
288 - panic("unhandled state")
289 - }
290 - s.stateLock.Unlock()
291 - return nil
292 -SEND_CLOSE:
293 - s.stateLock.Unlock()
294 - s.sendClose()
295 - s.notifyWaiting()
296 - return nil
297 -}
298 -
299 -// forceClose is used for when the session is exiting
300 -func (s *Stream) forceClose() {
301 - s.stateLock.Lock()
302 - s.state = streamClosed
303 - s.stateLock.Unlock()
304 - s.notifyWaiting()
305 -}
306 -
307 -// processFlags is used to update the state of the stream
308 -// based on set flags, if any. Lock must be held
309 -func (s *Stream) processFlags(flags uint16) error {
310 - s.stateLock.Lock()
311 - defer s.stateLock.Unlock()
312 - if flags&flagACK == flagACK {
313 - if s.state == streamSYNSent {
314 - s.state = streamEstablished
315 - }
316 -
317 - } else if flags&flagFIN == flagFIN {
318 - switch s.state {
319 - case streamSYNSent:
320 - fallthrough
321 - case streamSYNReceived:
322 - fallthrough
323 - case streamEstablished:
324 - s.state = streamRemoteClose
325 - s.notifyWaiting()
326 - case streamLocalClose:
327 - s.state = streamClosed
328 - s.session.closeStream(s.id)
329 - s.notifyWaiting()
330 - default:
331 - s.session.logger.Printf("[ERR] yamux: unexpected FIN flag in state %d", s.state)
332 - return ErrUnexpectedFlag
333 - }
334 - } else if flags&flagRST == flagRST {
335 - s.state = streamReset
336 - s.session.closeStream(s.id)
337 - s.notifyWaiting()
338 - }
339 - return nil
340 -}
341 -
342 -// notifyWaiting notifies all the waiting channels
343 -func (s *Stream) notifyWaiting() {
344 - asyncNotify(s.recvNotifyCh)
345 - asyncNotify(s.sendNotifyCh)
346 -}
347 -
348 -// incrSendWindow updates the size of our send window
349 -func (s *Stream) incrSendWindow(hdr header, flags uint16) error {
350 - if err := s.processFlags(flags); err != nil {
351 - return err
352 - }
353 -
354 - // Increase window, unblock a sender
355 - atomic.AddUint32(&s.sendWindow, hdr.Length())
356 - asyncNotify(s.sendNotifyCh)
357 - return nil
358 -}
359 -
360 -// readData is used to handle a data frame
361 -func (s *Stream) readData(hdr header, flags uint16, conn io.Reader) error {
362 - if err := s.processFlags(flags); err != nil {
363 - return err
364 - }
365 -
366 - // Check that our recv window is not exceeded
367 - length := hdr.Length()
368 - if length == 0 {
369 - return nil
370 - }
371 - if remain := atomic.LoadUint32(&s.recvWindow); length > remain {
372 - s.session.logger.Printf("[ERR] yamux: receive window exceeded (stream: %d, remain: %d, recv: %d)", s.id, remain, length)
373 - return ErrRecvWindowExceeded
374 - }
375 -
376 - // Wrap in a limited reader
377 - conn = &io.LimitedReader{R: conn, N: int64(length)}
378 -
379 - // Copy into buffer
380 - s.recvLock.Lock()
381 - if _, err := io.Copy(&s.recvBuf, conn); err != nil {
382 - s.session.logger.Printf("[ERR] yamux: Failed to read stream data: %v", err)
383 - s.recvLock.Unlock()
384 - return err
385 - }
386 -
387 - // Decrement the receive window
388 - atomic.AddUint32(&s.recvWindow, ^uint32(length-1))
389 - s.recvLock.Unlock()
390 -
391 - // Unblock any readers
392 - asyncNotify(s.recvNotifyCh)
393 - return nil
394 -}
395 -
396 -// SetDeadline sets the read and write deadlines
397 -func (s *Stream) SetDeadline(t time.Time) error {
398 - if err := s.SetReadDeadline(t); err != nil {
399 - return err
400 - }
401 - if err := s.SetWriteDeadline(t); err != nil {
402 - return err
403 - }
404 - return nil
405 -}
406 -
407 -// SetReadDeadline sets the deadline for future Read calls.
408 -func (s *Stream) SetReadDeadline(t time.Time) error {
409 - s.readDeadline = t
410 - return nil
411 -}
412 -
413 -// SetWriteDeadline sets the deadline for future Write calls
414 -func (s *Stream) SetWriteDeadline(t time.Time) error {
415 - s.writeDeadline = t
416 - return nil
417 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/util.go deleted
-28
@@ -1,28 +0,0 @@
1 -package yamux
2 -
3 -// asyncSendErr is used to try an async send of an error
4 -func asyncSendErr(ch chan error, err error) {
5 - if ch == nil {
6 - return
7 - }
8 - select {
9 - case ch <- err:
10 - default:
11 - }
12 -}
13 -
14 -// asyncNotify is used to signal a waiting goroutine
15 -func asyncNotify(ch chan struct{}) {
16 - select {
17 - case ch <- struct{}{}:
18 - default:
19 - }
20 -}
21 -
22 -// min computes the minimum of two values
23 -func min(a, b uint32) uint32 {
24 - if a < b {
25 - return a
26 - }
27 - return b
28 -}
Godeps/_workspace/src/github.com/hashicorp/yamux/util_test.go deleted
-50
@@ -1,50 +0,0 @@
1 -package yamux
2 -
3 -import (
4 - "testing"
5 -)
6 -
7 -func TestAsyncSendErr(t *testing.T) {
8 - ch := make(chan error)
9 - asyncSendErr(ch, ErrTimeout)
10 - select {
11 - case <-ch:
12 - t.Fatalf("should not get")
13 - default:
14 - }
15 -
16 - ch = make(chan error, 1)
17 - asyncSendErr(ch, ErrTimeout)
18 - select {
19 - case <-ch:
20 - default:
21 - t.Fatalf("should get")
22 - }
23 -}
24 -
25 -func TestAsyncNotify(t *testing.T) {
26 - ch := make(chan struct{})
27 - asyncNotify(ch)
28 - select {
29 - case <-ch:
30 - t.Fatalf("should not get")
31 - default:
32 - }
33 -
34 - ch = make(chan struct{}, 1)
35 - asyncNotify(ch)
36 - select {
37 - case <-ch:
38 - default:
39 - t.Fatalf("should get")
40 - }
41 -}
42 -
43 -func TestMin(t *testing.T) {
44 - if min(1, 2) != 1 {
45 - t.Fatalf("bad")
46 - }
47 - if min(2, 1) != 1 {
48 - t.Fatalf("bad")
49 - }
50 -}
Godeps/_workspace/src/github.com/huin/goupnp/LICENSE deleted
-23
@@ -1,23 +0,0 @@
1 -Copyright (c) 2013, John Beisley <greatred@gmail.com>
2 -All rights reserved.
3 -
4 -Redistribution and use in source and binary forms, with or without modification,
5 -are permitted provided that the following conditions are met:
6 -
7 -* Redistributions of source code must retain the above copyright notice, this
8 - list of conditions and the following disclaimer.
9 -
10 -* Redistributions in binary form must reproduce the above copyright notice, this
11 - list of conditions and the following disclaimer in the documentation and/or
12 - other materials provided with the distribution.
13 -
14 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
18 -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Godeps/_workspace/src/github.com/huin/goupnp/README.md deleted
-14
@@ -1,14 +0,0 @@
1 -goupnp is a UPnP client library for Go
2 -
3 -Installation
4 -------------
5 -
6 -Run `go get -u github.com/huin/goupnp`.
7 -
8 -Regenerating dcps generated source code:
9 -----------------------------------------
10 -
11 -1. Install gotasks: `go get -u github.com/jingweno/gotask`
12 -2. Change to the gotasks directory: `cd gotasks`
13 -3. Download UPnP specification data (if not done already): `wget http://upnp.org/resources/upnpresources.zip`
14 -4. Regenerate source code: `gotask specgen -s upnpresources.zip -o ../dcps`
Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_httpu_serving/example_httpu_serving.go deleted
-20
@@ -1,20 +0,0 @@
1 -package main
2 -
3 -import (
4 - "log"
5 - "net/http"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/httpu"
8 -)
9 -
10 -func main() {
11 - srv := httpu.Server{
12 - Addr: "239.255.255.250:1900",
13 - Multicast: true,
14 - Handler: httpu.HandlerFunc(func(r *http.Request) {
15 - log.Printf("Got %s %s message from %v: %v", r.Method, r.URL.Path, r.RemoteAddr, r.Header)
16 - }),
17 - }
18 - err := srv.ListenAndServe()
19 - log.Printf("Serving failed with error: %v", err)
20 -}
Godeps/_workspace/src/github.com/huin/goupnp/cmd/example_internetgateway1/example_internetgateway1.go deleted
-67
@@ -1,67 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 - "log"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1"
8 -)
9 -
10 -func main() {
11 - clients, errors, err := internetgateway1.NewWANPPPConnection1Clients()
12 - if err != nil {
13 - log.Fatal(err)
14 - }
15 -
16 - fmt.Printf("Got %d errors finding servers and %d successfully discovered.\n",
17 - len(errors), len(clients))
18 - for i, e := range errors {
19 - fmt.Printf("Error finding server #%d: %v\n", i+1, e)
20 - }
21 -
22 - for _, c := range clients {
23 - dev := &c.ServiceClient.RootDevice.Device
24 - srv := c.ServiceClient.Service
25 - fmt.Println(dev.FriendlyName, " :: ", srv.String())
26 - scpd, err := srv.RequestSCDP()
27 - if err != nil {
28 - fmt.Printf(" Error requesting service SCPD: %v\n", err)
29 - } else {
30 - fmt.Println(" Available actions:")
31 - for _, action := range scpd.Actions {
32 - fmt.Printf(" * %s\n", action.Name)
33 - for _, arg := range action.Arguments {
34 - var varDesc string
35 - if stateVar := scpd.GetStateVariable(arg.RelatedStateVariable); stateVar != nil {
36 - varDesc = fmt.Sprintf(" (%s)", stateVar.DataType.Name)
37 - }
38 - fmt.Printf(" * [%s] %s%s\n", arg.Direction, arg.Name, varDesc)
39 - }
40 - }
41 - }
42 -
43 - if scpd == nil || scpd.GetAction("GetExternalIPAddress") != nil {
44 - ip, err := c.GetExternalIPAddress()
45 - fmt.Println("GetExternalIPAddress: ", ip, err)
46 - }
47 -
48 - if scpd == nil || scpd.GetAction("GetStatusInfo") != nil {
49 - status, lastErr, uptime, err := c.GetStatusInfo()
50 - fmt.Println("GetStatusInfo: ", status, lastErr, uptime, err)
51 - }
52 -
53 - if scpd == nil || scpd.GetAction("GetIdleDisconnectTime") != nil {
54 - idleTime, err := c.GetIdleDisconnectTime()
55 - fmt.Println("GetIdleDisconnectTime: ", idleTime, err)
56 - }
57 -
58 - if scpd == nil || scpd.GetAction("AddPortMapping") != nil {
59 - err := c.AddPortMapping("", 5000, "TCP", 5001, "192.168.1.2", true, "Test port mapping", 0)
60 - fmt.Println("AddPortMapping: ", err)
61 - }
62 - if scpd == nil || scpd.GetAction("DeletePortMapping") != nil {
63 - err := c.DeletePortMapping("", 5000, "TCP")
64 - fmt.Println("DeletePortMapping: ", err)
65 - }
66 - }
67 -}
Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go deleted
-3957
@@ -1,3957 +0,0 @@
1 -// Client for UPnP Device Control Protocol Internet Gateway Device v1.
2 -//
3 -// This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf
4 -//
5 -// Typically, use one of the New* functions to discover services on the local
6 -// network.
7 -package internetgateway1
8 -
9 -// Generated file - do not edit by hand. See README.md
10 -
11 -import (
12 - "time"
13 -
14 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp"
15 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/soap"
16 -)
17 -
18 -// Hack to avoid Go complaining if time isn't used.
19 -var _ time.Time
20 -
21 -// Device URNs:
22 -const (
23 - URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1"
24 - URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1"
25 - URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1"
26 -)
27 -
28 -// Service URNs:
29 -const (
30 - URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1"
31 - URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1"
32 - URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1"
33 - URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"
34 - URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1"
35 - URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1"
36 - URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1"
37 - URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1"
38 - URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1"
39 -)
40 -
41 -// LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See
42 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
43 -// are provided for informational value.
44 -type LANHostConfigManagement1 struct {
45 - goupnp.ServiceClient
46 -}
47 -
48 -// NewLANHostConfigManagement1Clients discovers instances of the service on the network,
49 -// and returns clients to any that are found. errors will contain an error for
50 -// any devices that replied but which could not be queried, and err will be set
51 -// if the discovery process failed outright.
52 -//
53 -// This is a typical entry calling point into this package.
54 -func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
55 - var genericClients []goupnp.ServiceClient
56 - if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil {
57 - return
58 - }
59 - clients = make([]*LANHostConfigManagement1, len(genericClients))
60 - for i := range genericClients {
61 - clients[i] = &LANHostConfigManagement1{genericClients[i]}
62 - }
63 - return
64 -}
65 -
66 -// Arguments:
67 -//
68 -// * NewDHCPServerConfigurable:
69 -//
70 -//
71 -func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) {
72 - // Request structure.
73 - request := &struct {
74 - NewDHCPServerConfigurable string
75 - }{}
76 - // BEGIN Marshal arguments into request.
77 -
78 - if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil {
79 - return
80 - }
81 - // END Marshal arguments into request.
82 -
83 - // Response structure.
84 - response := interface{}(nil)
85 -
86 - // Perform the SOAP call.
87 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil {
88 - return
89 - }
90 -
91 - // BEGIN Unmarshal arguments from response.
92 -
93 - // END Unmarshal arguments from response.
94 - return
95 -}
96 -
97 -//
98 -//
99 -// Return values:
100 -//
101 -// * NewDHCPServerConfigurable:
102 -func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) {
103 - // Request structure.
104 - request := interface{}(nil)
105 - // BEGIN Marshal arguments into request.
106 -
107 - // END Marshal arguments into request.
108 -
109 - // Response structure.
110 - response := &struct {
111 - NewDHCPServerConfigurable string
112 - }{}
113 -
114 - // Perform the SOAP call.
115 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil {
116 - return
117 - }
118 -
119 - // BEGIN Unmarshal arguments from response.
120 -
121 - if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil {
122 - return
123 - }
124 - // END Unmarshal arguments from response.
125 - return
126 -}
127 -
128 -// Arguments:
129 -//
130 -// * NewDHCPRelay:
131 -//
132 -//
133 -func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) {
134 - // Request structure.
135 - request := &struct {
136 - NewDHCPRelay string
137 - }{}
138 - // BEGIN Marshal arguments into request.
139 -
140 - if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil {
141 - return
142 - }
143 - // END Marshal arguments into request.
144 -
145 - // Response structure.
146 - response := interface{}(nil)
147 -
148 - // Perform the SOAP call.
149 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil {
150 - return
151 - }
152 -
153 - // BEGIN Unmarshal arguments from response.
154 -
155 - // END Unmarshal arguments from response.
156 - return
157 -}
158 -
159 -//
160 -//
161 -// Return values:
162 -//
163 -// * NewDHCPRelay:
164 -func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) {
165 - // Request structure.
166 - request := interface{}(nil)
167 - // BEGIN Marshal arguments into request.
168 -
169 - // END Marshal arguments into request.
170 -
171 - // Response structure.
172 - response := &struct {
173 - NewDHCPRelay string
174 - }{}
175 -
176 - // Perform the SOAP call.
177 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil {
178 - return
179 - }
180 -
181 - // BEGIN Unmarshal arguments from response.
182 -
183 - if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil {
184 - return
185 - }
186 - // END Unmarshal arguments from response.
187 - return
188 -}
189 -
190 -// Arguments:
191 -//
192 -// * NewSubnetMask:
193 -//
194 -//
195 -func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) {
196 - // Request structure.
197 - request := &struct {
198 - NewSubnetMask string
199 - }{}
200 - // BEGIN Marshal arguments into request.
201 -
202 - if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil {
203 - return
204 - }
205 - // END Marshal arguments into request.
206 -
207 - // Response structure.
208 - response := interface{}(nil)
209 -
210 - // Perform the SOAP call.
211 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil {
212 - return
213 - }
214 -
215 - // BEGIN Unmarshal arguments from response.
216 -
217 - // END Unmarshal arguments from response.
218 - return
219 -}
220 -
221 -//
222 -//
223 -// Return values:
224 -//
225 -// * NewSubnetMask:
226 -func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) {
227 - // Request structure.
228 - request := interface{}(nil)
229 - // BEGIN Marshal arguments into request.
230 -
231 - // END Marshal arguments into request.
232 -
233 - // Response structure.
234 - response := &struct {
235 - NewSubnetMask string
236 - }{}
237 -
238 - // Perform the SOAP call.
239 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil {
240 - return
241 - }
242 -
243 - // BEGIN Unmarshal arguments from response.
244 -
245 - if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil {
246 - return
247 - }
248 - // END Unmarshal arguments from response.
249 - return
250 -}
251 -
252 -// Arguments:
253 -//
254 -// * NewIPRouters:
255 -//
256 -//
257 -func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) {
258 - // Request structure.
259 - request := &struct {
260 - NewIPRouters string
261 - }{}
262 - // BEGIN Marshal arguments into request.
263 -
264 - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil {
265 - return
266 - }
267 - // END Marshal arguments into request.
268 -
269 - // Response structure.
270 - response := interface{}(nil)
271 -
272 - // Perform the SOAP call.
273 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil {
274 - return
275 - }
276 -
277 - // BEGIN Unmarshal arguments from response.
278 -
279 - // END Unmarshal arguments from response.
280 - return
281 -}
282 -
283 -// Arguments:
284 -//
285 -// * NewIPRouters:
286 -//
287 -//
288 -func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) {
289 - // Request structure.
290 - request := &struct {
291 - NewIPRouters string
292 - }{}
293 - // BEGIN Marshal arguments into request.
294 -
295 - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil {
296 - return
297 - }
298 - // END Marshal arguments into request.
299 -
300 - // Response structure.
301 - response := interface{}(nil)
302 -
303 - // Perform the SOAP call.
304 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil {
305 - return
306 - }
307 -
308 - // BEGIN Unmarshal arguments from response.
309 -
310 - // END Unmarshal arguments from response.
311 - return
312 -}
313 -
314 -//
315 -//
316 -// Return values:
317 -//
318 -// * NewIPRouters:
319 -func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) {
320 - // Request structure.
321 - request := interface{}(nil)
322 - // BEGIN Marshal arguments into request.
323 -
324 - // END Marshal arguments into request.
325 -
326 - // Response structure.
327 - response := &struct {
328 - NewIPRouters string
329 - }{}
330 -
331 - // Perform the SOAP call.
332 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil {
333 - return
334 - }
335 -
336 - // BEGIN Unmarshal arguments from response.
337 -
338 - if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil {
339 - return
340 - }
341 - // END Unmarshal arguments from response.
342 - return
343 -}
344 -
345 -// Arguments:
346 -//
347 -// * NewDomainName:
348 -//
349 -//
350 -func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) {
351 - // Request structure.
352 - request := &struct {
353 - NewDomainName string
354 - }{}
355 - // BEGIN Marshal arguments into request.
356 -
357 - if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil {
358 - return
359 - }
360 - // END Marshal arguments into request.
361 -
362 - // Response structure.
363 - response := interface{}(nil)
364 -
365 - // Perform the SOAP call.
366 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil {
367 - return
368 - }
369 -
370 - // BEGIN Unmarshal arguments from response.
371 -
372 - // END Unmarshal arguments from response.
373 - return
374 -}
375 -
376 -//
377 -//
378 -// Return values:
379 -//
380 -// * NewDomainName:
381 -func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) {
382 - // Request structure.
383 - request := interface{}(nil)
384 - // BEGIN Marshal arguments into request.
385 -
386 - // END Marshal arguments into request.
387 -
388 - // Response structure.
389 - response := &struct {
390 - NewDomainName string
391 - }{}
392 -
393 - // Perform the SOAP call.
394 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil {
395 - return
396 - }
397 -
398 - // BEGIN Unmarshal arguments from response.
399 -
400 - if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil {
401 - return
402 - }
403 - // END Unmarshal arguments from response.
404 - return
405 -}
406 -
407 -// Arguments:
408 -//
409 -// * NewMinAddress:
410 -//
411 -// * NewMaxAddress:
412 -//
413 -//
414 -func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) {
415 - // Request structure.
416 - request := &struct {
417 - NewMinAddress string
418 -
419 - NewMaxAddress string
420 - }{}
421 - // BEGIN Marshal arguments into request.
422 -
423 - if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil {
424 - return
425 - }
426 - if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil {
427 - return
428 - }
429 - // END Marshal arguments into request.
430 -
431 - // Response structure.
432 - response := interface{}(nil)
433 -
434 - // Perform the SOAP call.
435 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil {
436 - return
437 - }
438 -
439 - // BEGIN Unmarshal arguments from response.
440 -
441 - // END Unmarshal arguments from response.
442 - return
443 -}
444 -
445 -//
446 -//
447 -// Return values:
448 -//
449 -// * NewMinAddress:
450 -//
451 -// * NewMaxAddress:
452 -func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) {
453 - // Request structure.
454 - request := interface{}(nil)
455 - // BEGIN Marshal arguments into request.
456 -
457 - // END Marshal arguments into request.
458 -
459 - // Response structure.
460 - response := &struct {
461 - NewMinAddress string
462 -
463 - NewMaxAddress string
464 - }{}
465 -
466 - // Perform the SOAP call.
467 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil {
468 - return
469 - }
470 -
471 - // BEGIN Unmarshal arguments from response.
472 -
473 - if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil {
474 - return
475 - }
476 - if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil {
477 - return
478 - }
479 - // END Unmarshal arguments from response.
480 - return
481 -}
482 -
483 -// Arguments:
484 -//
485 -// * NewReservedAddresses:
486 -//
487 -//
488 -func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) {
489 - // Request structure.
490 - request := &struct {
491 - NewReservedAddresses string
492 - }{}
493 - // BEGIN Marshal arguments into request.
494 -
495 - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil {
496 - return
497 - }
498 - // END Marshal arguments into request.
499 -
500 - // Response structure.
501 - response := interface{}(nil)
502 -
503 - // Perform the SOAP call.
504 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil {
505 - return
506 - }
507 -
508 - // BEGIN Unmarshal arguments from response.
509 -
510 - // END Unmarshal arguments from response.
511 - return
512 -}
513 -
514 -// Arguments:
515 -//
516 -// * NewReservedAddresses:
517 -//
518 -//
519 -func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) {
520 - // Request structure.
521 - request := &struct {
522 - NewReservedAddresses string
523 - }{}
524 - // BEGIN Marshal arguments into request.
525 -
526 - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil {
527 - return
528 - }
529 - // END Marshal arguments into request.
530 -
531 - // Response structure.
532 - response := interface{}(nil)
533 -
534 - // Perform the SOAP call.
535 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil {
536 - return
537 - }
538 -
539 - // BEGIN Unmarshal arguments from response.
540 -
541 - // END Unmarshal arguments from response.
542 - return
543 -}
544 -
545 -//
546 -//
547 -// Return values:
548 -//
549 -// * NewReservedAddresses:
550 -func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) {
551 - // Request structure.
552 - request := interface{}(nil)
553 - // BEGIN Marshal arguments into request.
554 -
555 - // END Marshal arguments into request.
556 -
557 - // Response structure.
558 - response := &struct {
559 - NewReservedAddresses string
560 - }{}
561 -
562 - // Perform the SOAP call.
563 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil {
564 - return
565 - }
566 -
567 - // BEGIN Unmarshal arguments from response.
568 -
569 - if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil {
570 - return
571 - }
572 - // END Unmarshal arguments from response.
573 - return
574 -}
575 -
576 -// Arguments:
577 -//
578 -// * NewDNSServers:
579 -//
580 -//
581 -func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) {
582 - // Request structure.
583 - request := &struct {
584 - NewDNSServers string
585 - }{}
586 - // BEGIN Marshal arguments into request.
587 -
588 - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil {
589 - return
590 - }
591 - // END Marshal arguments into request.
592 -
593 - // Response structure.
594 - response := interface{}(nil)
595 -
596 - // Perform the SOAP call.
597 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil {
598 - return
599 - }
600 -
601 - // BEGIN Unmarshal arguments from response.
602 -
603 - // END Unmarshal arguments from response.
604 - return
605 -}
606 -
607 -// Arguments:
608 -//
609 -// * NewDNSServers:
610 -//
611 -//
612 -func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) {
613 - // Request structure.
614 - request := &struct {
615 - NewDNSServers string
616 - }{}
617 - // BEGIN Marshal arguments into request.
618 -
619 - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil {
620 - return
621 - }
622 - // END Marshal arguments into request.
623 -
624 - // Response structure.
625 - response := interface{}(nil)
626 -
627 - // Perform the SOAP call.
628 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil {
629 - return
630 - }
631 -
632 - // BEGIN Unmarshal arguments from response.
633 -
634 - // END Unmarshal arguments from response.
635 - return
636 -}
637 -
638 -//
639 -//
640 -// Return values:
641 -//
642 -// * NewDNSServers:
643 -func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) {
644 - // Request structure.
645 - request := interface{}(nil)
646 - // BEGIN Marshal arguments into request.
647 -
648 - // END Marshal arguments into request.
649 -
650 - // Response structure.
651 - response := &struct {
652 - NewDNSServers string
653 - }{}
654 -
655 - // Perform the SOAP call.
656 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil {
657 - return
658 - }
659 -
660 - // BEGIN Unmarshal arguments from response.
661 -
662 - if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil {
663 - return
664 - }
665 - // END Unmarshal arguments from response.
666 - return
667 -}
668 -
669 -// Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See
670 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
671 -// are provided for informational value.
672 -type Layer3Forwarding1 struct {
673 - goupnp.ServiceClient
674 -}
675 -
676 -// NewLayer3Forwarding1Clients discovers instances of the service on the network,
677 -// and returns clients to any that are found. errors will contain an error for
678 -// any devices that replied but which could not be queried, and err will be set
679 -// if the discovery process failed outright.
680 -//
681 -// This is a typical entry calling point into this package.
682 -func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
683 - var genericClients []goupnp.ServiceClient
684 - if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil {
685 - return
686 - }
687 - clients = make([]*Layer3Forwarding1, len(genericClients))
688 - for i := range genericClients {
689 - clients[i] = &Layer3Forwarding1{genericClients[i]}
690 - }
691 - return
692 -}
693 -
694 -// Arguments:
695 -//
696 -// * NewDefaultConnectionService:
697 -//
698 -//
699 -func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) {
700 - // Request structure.
701 - request := &struct {
702 - NewDefaultConnectionService string
703 - }{}
704 - // BEGIN Marshal arguments into request.
705 -
706 - if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil {
707 - return
708 - }
709 - // END Marshal arguments into request.
710 -
711 - // Response structure.
712 - response := interface{}(nil)
713 -
714 - // Perform the SOAP call.
715 - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil {
716 - return
717 - }
718 -
719 - // BEGIN Unmarshal arguments from response.
720 -
721 - // END Unmarshal arguments from response.
722 - return
723 -}
724 -
725 -//
726 -//
727 -// Return values:
728 -//
729 -// * NewDefaultConnectionService:
730 -func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) {
731 - // Request structure.
732 - request := interface{}(nil)
733 - // BEGIN Marshal arguments into request.
734 -
735 - // END Marshal arguments into request.
736 -
737 - // Response structure.
738 - response := &struct {
739 - NewDefaultConnectionService string
740 - }{}
741 -
742 - // Perform the SOAP call.
743 - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil {
744 - return
745 - }
746 -
747 - // BEGIN Unmarshal arguments from response.
748 -
749 - if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil {
750 - return
751 - }
752 - // END Unmarshal arguments from response.
753 - return
754 -}
755 -
756 -// WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See
757 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
758 -// are provided for informational value.
759 -type WANCableLinkConfig1 struct {
760 - goupnp.ServiceClient
761 -}
762 -
763 -// NewWANCableLinkConfig1Clients discovers instances of the service on the network,
764 -// and returns clients to any that are found. errors will contain an error for
765 -// any devices that replied but which could not be queried, and err will be set
766 -// if the discovery process failed outright.
767 -//
768 -// This is a typical entry calling point into this package.
769 -func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
770 - var genericClients []goupnp.ServiceClient
771 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil {
772 - return
773 - }
774 - clients = make([]*WANCableLinkConfig1, len(genericClients))
775 - for i := range genericClients {
776 - clients[i] = &WANCableLinkConfig1{genericClients[i]}
777 - }
778 - return
779 -}
780 -
781 -//
782 -//
783 -// Return values:
784 -//
785 -// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied
786 -//
787 -// * NewLinkType: allowed values: Ethernet
788 -func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) {
789 - // Request structure.
790 - request := interface{}(nil)
791 - // BEGIN Marshal arguments into request.
792 -
793 - // END Marshal arguments into request.
794 -
795 - // Response structure.
796 - response := &struct {
797 - NewCableLinkConfigState string
798 -
799 - NewLinkType string
800 - }{}
801 -
802 - // Perform the SOAP call.
803 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil {
804 - return
805 - }
806 -
807 - // BEGIN Unmarshal arguments from response.
808 -
809 - if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil {
810 - return
811 - }
812 - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil {
813 - return
814 - }
815 - // END Unmarshal arguments from response.
816 - return
817 -}
818 -
819 -//
820 -//
821 -// Return values:
822 -//
823 -// * NewDownstreamFrequency:
824 -func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) {
825 - // Request structure.
826 - request := interface{}(nil)
827 - // BEGIN Marshal arguments into request.
828 -
829 - // END Marshal arguments into request.
830 -
831 - // Response structure.
832 - response := &struct {
833 - NewDownstreamFrequency string
834 - }{}
835 -
836 - // Perform the SOAP call.
837 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil {
838 - return
839 - }
840 -
841 - // BEGIN Unmarshal arguments from response.
842 -
843 - if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil {
844 - return
845 - }
846 - // END Unmarshal arguments from response.
847 - return
848 -}
849 -
850 -//
851 -//
852 -// Return values:
853 -//
854 -// * NewDownstreamModulation: allowed values: 64QAM, 256QAM
855 -func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) {
856 - // Request structure.
857 - request := interface{}(nil)
858 - // BEGIN Marshal arguments into request.
859 -
860 - // END Marshal arguments into request.
861 -
862 - // Response structure.
863 - response := &struct {
864 - NewDownstreamModulation string
865 - }{}
866 -
867 - // Perform the SOAP call.
868 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil {
869 - return
870 - }
871 -
872 - // BEGIN Unmarshal arguments from response.
873 -
874 - if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil {
875 - return
876 - }
877 - // END Unmarshal arguments from response.
878 - return
879 -}
880 -
881 -//
882 -//
883 -// Return values:
884 -//
885 -// * NewUpstreamFrequency:
886 -func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) {
887 - // Request structure.
888 - request := interface{}(nil)
889 - // BEGIN Marshal arguments into request.
890 -
891 - // END Marshal arguments into request.
892 -
893 - // Response structure.
894 - response := &struct {
895 - NewUpstreamFrequency string
896 - }{}
897 -
898 - // Perform the SOAP call.
899 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil {
900 - return
901 - }
902 -
903 - // BEGIN Unmarshal arguments from response.
904 -
905 - if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil {
906 - return
907 - }
908 - // END Unmarshal arguments from response.
909 - return
910 -}
911 -
912 -//
913 -//
914 -// Return values:
915 -//
916 -// * NewUpstreamModulation: allowed values: QPSK, 16QAM
917 -func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) {
918 - // Request structure.
919 - request := interface{}(nil)
920 - // BEGIN Marshal arguments into request.
921 -
922 - // END Marshal arguments into request.
923 -
924 - // Response structure.
925 - response := &struct {
926 - NewUpstreamModulation string
927 - }{}
928 -
929 - // Perform the SOAP call.
930 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil {
931 - return
932 - }
933 -
934 - // BEGIN Unmarshal arguments from response.
935 -
936 - if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil {
937 - return
938 - }
939 - // END Unmarshal arguments from response.
940 - return
941 -}
942 -
943 -//
944 -//
945 -// Return values:
946 -//
947 -// * NewUpstreamChannelID:
948 -func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) {
949 - // Request structure.
950 - request := interface{}(nil)
951 - // BEGIN Marshal arguments into request.
952 -
953 - // END Marshal arguments into request.
954 -
955 - // Response structure.
956 - response := &struct {
957 - NewUpstreamChannelID string
958 - }{}
959 -
960 - // Perform the SOAP call.
961 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil {
962 - return
963 - }
964 -
965 - // BEGIN Unmarshal arguments from response.
966 -
967 - if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil {
968 - return
969 - }
970 - // END Unmarshal arguments from response.
971 - return
972 -}
973 -
974 -//
975 -//
976 -// Return values:
977 -//
978 -// * NewUpstreamPowerLevel:
979 -func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) {
980 - // Request structure.
981 - request := interface{}(nil)
982 - // BEGIN Marshal arguments into request.
983 -
984 - // END Marshal arguments into request.
985 -
986 - // Response structure.
987 - response := &struct {
988 - NewUpstreamPowerLevel string
989 - }{}
990 -
991 - // Perform the SOAP call.
992 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil {
993 - return
994 - }
995 -
996 - // BEGIN Unmarshal arguments from response.
997 -
998 - if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil {
999 - return
1000 - }
1001 - // END Unmarshal arguments from response.
1002 - return
1003 -}
1004 -
1005 -//
1006 -//
1007 -// Return values:
1008 -//
1009 -// * NewBPIEncryptionEnabled:
1010 -func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) {
1011 - // Request structure.
1012 - request := interface{}(nil)
1013 - // BEGIN Marshal arguments into request.
1014 -
1015 - // END Marshal arguments into request.
1016 -
1017 - // Response structure.
1018 - response := &struct {
1019 - NewBPIEncryptionEnabled string
1020 - }{}
1021 -
1022 - // Perform the SOAP call.
1023 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil {
1024 - return
1025 - }
1026 -
1027 - // BEGIN Unmarshal arguments from response.
1028 -
1029 - if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil {
1030 - return
1031 - }
1032 - // END Unmarshal arguments from response.
1033 - return
1034 -}
1035 -
1036 -//
1037 -//
1038 -// Return values:
1039 -//
1040 -// * NewConfigFile:
1041 -func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) {
1042 - // Request structure.
1043 - request := interface{}(nil)
1044 - // BEGIN Marshal arguments into request.
1045 -
1046 - // END Marshal arguments into request.
1047 -
1048 - // Response structure.
1049 - response := &struct {
1050 - NewConfigFile string
1051 - }{}
1052 -
1053 - // Perform the SOAP call.
1054 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil {
1055 - return
1056 - }
1057 -
1058 - // BEGIN Unmarshal arguments from response.
1059 -
1060 - if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil {
1061 - return
1062 - }
1063 - // END Unmarshal arguments from response.
1064 - return
1065 -}
1066 -
1067 -//
1068 -//
1069 -// Return values:
1070 -//
1071 -// * NewTFTPServer:
1072 -func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) {
1073 - // Request structure.
1074 - request := interface{}(nil)
1075 - // BEGIN Marshal arguments into request.
1076 -
1077 - // END Marshal arguments into request.
1078 -
1079 - // Response structure.
1080 - response := &struct {
1081 - NewTFTPServer string
1082 - }{}
1083 -
1084 - // Perform the SOAP call.
1085 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil {
1086 - return
1087 - }
1088 -
1089 - // BEGIN Unmarshal arguments from response.
1090 -
1091 - if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil {
1092 - return
1093 - }
1094 - // END Unmarshal arguments from response.
1095 - return
1096 -}
1097 -
1098 -// WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See
1099 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1100 -// are provided for informational value.
1101 -type WANCommonInterfaceConfig1 struct {
1102 - goupnp.ServiceClient
1103 -}
1104 -
1105 -// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network,
1106 -// and returns clients to any that are found. errors will contain an error for
1107 -// any devices that replied but which could not be queried, and err will be set
1108 -// if the discovery process failed outright.
1109 -//
1110 -// This is a typical entry calling point into this package.
1111 -func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
1112 - var genericClients []goupnp.ServiceClient
1113 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil {
1114 - return
1115 - }
1116 - clients = make([]*WANCommonInterfaceConfig1, len(genericClients))
1117 - for i := range genericClients {
1118 - clients[i] = &WANCommonInterfaceConfig1{genericClients[i]}
1119 - }
1120 - return
1121 -}
1122 -
1123 -// Arguments:
1124 -//
1125 -// * NewEnabledForInternet:
1126 -//
1127 -//
1128 -func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) {
1129 - // Request structure.
1130 - request := &struct {
1131 - NewEnabledForInternet string
1132 - }{}
1133 - // BEGIN Marshal arguments into request.
1134 -
1135 - if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil {
1136 - return
1137 - }
1138 - // END Marshal arguments into request.
1139 -
1140 - // Response structure.
1141 - response := interface{}(nil)
1142 -
1143 - // Perform the SOAP call.
1144 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil {
1145 - return
1146 - }
1147 -
1148 - // BEGIN Unmarshal arguments from response.
1149 -
1150 - // END Unmarshal arguments from response.
1151 - return
1152 -}
1153 -
1154 -//
1155 -//
1156 -// Return values:
1157 -//
1158 -// * NewEnabledForInternet:
1159 -func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) {
1160 - // Request structure.
1161 - request := interface{}(nil)
1162 - // BEGIN Marshal arguments into request.
1163 -
1164 - // END Marshal arguments into request.
1165 -
1166 - // Response structure.
1167 - response := &struct {
1168 - NewEnabledForInternet string
1169 - }{}
1170 -
1171 - // Perform the SOAP call.
1172 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil {
1173 - return
1174 - }
1175 -
1176 - // BEGIN Unmarshal arguments from response.
1177 -
1178 - if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil {
1179 - return
1180 - }
1181 - // END Unmarshal arguments from response.
1182 - return
1183 -}
1184 -
1185 -//
1186 -//
1187 -// Return values:
1188 -//
1189 -// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet
1190 -//
1191 -// * NewLayer1UpstreamMaxBitRate:
1192 -//
1193 -// * NewLayer1DownstreamMaxBitRate:
1194 -//
1195 -// * NewPhysicalLinkStatus: allowed values: Up, Down
1196 -func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) {
1197 - // Request structure.
1198 - request := interface{}(nil)
1199 - // BEGIN Marshal arguments into request.
1200 -
1201 - // END Marshal arguments into request.
1202 -
1203 - // Response structure.
1204 - response := &struct {
1205 - NewWANAccessType string
1206 -
1207 - NewLayer1UpstreamMaxBitRate string
1208 -
1209 - NewLayer1DownstreamMaxBitRate string
1210 -
1211 - NewPhysicalLinkStatus string
1212 - }{}
1213 -
1214 - // Perform the SOAP call.
1215 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil {
1216 - return
1217 - }
1218 -
1219 - // BEGIN Unmarshal arguments from response.
1220 -
1221 - if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil {
1222 - return
1223 - }
1224 - if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil {
1225 - return
1226 - }
1227 - if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil {
1228 - return
1229 - }
1230 - if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil {
1231 - return
1232 - }
1233 - // END Unmarshal arguments from response.
1234 - return
1235 -}
1236 -
1237 -//
1238 -//
1239 -// Return values:
1240 -//
1241 -// * NewWANAccessProvider:
1242 -func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) {
1243 - // Request structure.
1244 - request := interface{}(nil)
1245 - // BEGIN Marshal arguments into request.
1246 -
1247 - // END Marshal arguments into request.
1248 -
1249 - // Response structure.
1250 - response := &struct {
1251 - NewWANAccessProvider string
1252 - }{}
1253 -
1254 - // Perform the SOAP call.
1255 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil {
1256 - return
1257 - }
1258 -
1259 - // BEGIN Unmarshal arguments from response.
1260 -
1261 - if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil {
1262 - return
1263 - }
1264 - // END Unmarshal arguments from response.
1265 - return
1266 -}
1267 -
1268 -//
1269 -//
1270 -// Return values:
1271 -//
1272 -// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1
1273 -func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) {
1274 - // Request structure.
1275 - request := interface{}(nil)
1276 - // BEGIN Marshal arguments into request.
1277 -
1278 - // END Marshal arguments into request.
1279 -
1280 - // Response structure.
1281 - response := &struct {
1282 - NewMaximumActiveConnections string
1283 - }{}
1284 -
1285 - // Perform the SOAP call.
1286 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil {
1287 - return
1288 - }
1289 -
1290 - // BEGIN Unmarshal arguments from response.
1291 -
1292 - if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil {
1293 - return
1294 - }
1295 - // END Unmarshal arguments from response.
1296 - return
1297 -}
1298 -
1299 -//
1300 -//
1301 -// Return values:
1302 -//
1303 -// * NewTotalBytesSent:
1304 -func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) {
1305 - // Request structure.
1306 - request := interface{}(nil)
1307 - // BEGIN Marshal arguments into request.
1308 -
1309 - // END Marshal arguments into request.
1310 -
1311 - // Response structure.
1312 - response := &struct {
1313 - NewTotalBytesSent string
1314 - }{}
1315 -
1316 - // Perform the SOAP call.
1317 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil {
1318 - return
1319 - }
1320 -
1321 - // BEGIN Unmarshal arguments from response.
1322 -
1323 - if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil {
1324 - return
1325 - }
1326 - // END Unmarshal arguments from response.
1327 - return
1328 -}
1329 -
1330 -//
1331 -//
1332 -// Return values:
1333 -//
1334 -// * NewTotalBytesReceived:
1335 -func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) {
1336 - // Request structure.
1337 - request := interface{}(nil)
1338 - // BEGIN Marshal arguments into request.
1339 -
1340 - // END Marshal arguments into request.
1341 -
1342 - // Response structure.
1343 - response := &struct {
1344 - NewTotalBytesReceived string
1345 - }{}
1346 -
1347 - // Perform the SOAP call.
1348 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil {
1349 - return
1350 - }
1351 -
1352 - // BEGIN Unmarshal arguments from response.
1353 -
1354 - if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil {
1355 - return
1356 - }
1357 - // END Unmarshal arguments from response.
1358 - return
1359 -}
1360 -
1361 -//
1362 -//
1363 -// Return values:
1364 -//
1365 -// * NewTotalPacketsSent:
1366 -func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) {
1367 - // Request structure.
1368 - request := interface{}(nil)
1369 - // BEGIN Marshal arguments into request.
1370 -
1371 - // END Marshal arguments into request.
1372 -
1373 - // Response structure.
1374 - response := &struct {
1375 - NewTotalPacketsSent string
1376 - }{}
1377 -
1378 - // Perform the SOAP call.
1379 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil {
1380 - return
1381 - }
1382 -
1383 - // BEGIN Unmarshal arguments from response.
1384 -
1385 - if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil {
1386 - return
1387 - }
1388 - // END Unmarshal arguments from response.
1389 - return
1390 -}
1391 -
1392 -//
1393 -//
1394 -// Return values:
1395 -//
1396 -// * NewTotalPacketsReceived:
1397 -func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) {
1398 - // Request structure.
1399 - request := interface{}(nil)
1400 - // BEGIN Marshal arguments into request.
1401 -
1402 - // END Marshal arguments into request.
1403 -
1404 - // Response structure.
1405 - response := &struct {
1406 - NewTotalPacketsReceived string
1407 - }{}
1408 -
1409 - // Perform the SOAP call.
1410 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil {
1411 - return
1412 - }
1413 -
1414 - // BEGIN Unmarshal arguments from response.
1415 -
1416 - if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil {
1417 - return
1418 - }
1419 - // END Unmarshal arguments from response.
1420 - return
1421 -}
1422 -
1423 -// Arguments:
1424 -//
1425 -// * NewActiveConnectionIndex:
1426 -//
1427 -// Return values:
1428 -//
1429 -// * NewActiveConnDeviceContainer:
1430 -//
1431 -// * NewActiveConnectionServiceID:
1432 -func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) {
1433 - // Request structure.
1434 - request := &struct {
1435 - NewActiveConnectionIndex string
1436 - }{}
1437 - // BEGIN Marshal arguments into request.
1438 -
1439 - if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil {
1440 - return
1441 - }
1442 - // END Marshal arguments into request.
1443 -
1444 - // Response structure.
1445 - response := &struct {
1446 - NewActiveConnDeviceContainer string
1447 -
1448 - NewActiveConnectionServiceID string
1449 - }{}
1450 -
1451 - // Perform the SOAP call.
1452 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil {
1453 - return
1454 - }
1455 -
1456 - // BEGIN Unmarshal arguments from response.
1457 -
1458 - if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil {
1459 - return
1460 - }
1461 - if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil {
1462 - return
1463 - }
1464 - // END Unmarshal arguments from response.
1465 - return
1466 -}
1467 -
1468 -// WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See
1469 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1470 -// are provided for informational value.
1471 -type WANDSLLinkConfig1 struct {
1472 - goupnp.ServiceClient
1473 -}
1474 -
1475 -// NewWANDSLLinkConfig1Clients discovers instances of the service on the network,
1476 -// and returns clients to any that are found. errors will contain an error for
1477 -// any devices that replied but which could not be queried, and err will be set
1478 -// if the discovery process failed outright.
1479 -//
1480 -// This is a typical entry calling point into this package.
1481 -func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
1482 - var genericClients []goupnp.ServiceClient
1483 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil {
1484 - return
1485 - }
1486 - clients = make([]*WANDSLLinkConfig1, len(genericClients))
1487 - for i := range genericClients {
1488 - clients[i] = &WANDSLLinkConfig1{genericClients[i]}
1489 - }
1490 - return
1491 -}
1492 -
1493 -// Arguments:
1494 -//
1495 -// * NewLinkType:
1496 -//
1497 -//
1498 -func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) {
1499 - // Request structure.
1500 - request := &struct {
1501 - NewLinkType string
1502 - }{}
1503 - // BEGIN Marshal arguments into request.
1504 -
1505 - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil {
1506 - return
1507 - }
1508 - // END Marshal arguments into request.
1509 -
1510 - // Response structure.
1511 - response := interface{}(nil)
1512 -
1513 - // Perform the SOAP call.
1514 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil {
1515 - return
1516 - }
1517 -
1518 - // BEGIN Unmarshal arguments from response.
1519 -
1520 - // END Unmarshal arguments from response.
1521 - return
1522 -}
1523 -
1524 -//
1525 -//
1526 -// Return values:
1527 -//
1528 -// * NewLinkType:
1529 -//
1530 -// * NewLinkStatus: allowed values: Up, Down
1531 -func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) {
1532 - // Request structure.
1533 - request := interface{}(nil)
1534 - // BEGIN Marshal arguments into request.
1535 -
1536 - // END Marshal arguments into request.
1537 -
1538 - // Response structure.
1539 - response := &struct {
1540 - NewLinkType string
1541 -
1542 - NewLinkStatus string
1543 - }{}
1544 -
1545 - // Perform the SOAP call.
1546 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil {
1547 - return
1548 - }
1549 -
1550 - // BEGIN Unmarshal arguments from response.
1551 -
1552 - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil {
1553 - return
1554 - }
1555 - if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil {
1556 - return
1557 - }
1558 - // END Unmarshal arguments from response.
1559 - return
1560 -}
1561 -
1562 -//
1563 -//
1564 -// Return values:
1565 -//
1566 -// * NewAutoConfig:
1567 -func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) {
1568 - // Request structure.
1569 - request := interface{}(nil)
1570 - // BEGIN Marshal arguments into request.
1571 -
1572 - // END Marshal arguments into request.
1573 -
1574 - // Response structure.
1575 - response := &struct {
1576 - NewAutoConfig string
1577 - }{}
1578 -
1579 - // Perform the SOAP call.
1580 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil {
1581 - return
1582 - }
1583 -
1584 - // BEGIN Unmarshal arguments from response.
1585 -
1586 - if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil {
1587 - return
1588 - }
1589 - // END Unmarshal arguments from response.
1590 - return
1591 -}
1592 -
1593 -//
1594 -//
1595 -// Return values:
1596 -//
1597 -// * NewModulationType:
1598 -func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) {
1599 - // Request structure.
1600 - request := interface{}(nil)
1601 - // BEGIN Marshal arguments into request.
1602 -
1603 - // END Marshal arguments into request.
1604 -
1605 - // Response structure.
1606 - response := &struct {
1607 - NewModulationType string
1608 - }{}
1609 -
1610 - // Perform the SOAP call.
1611 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil {
1612 - return
1613 - }
1614 -
1615 - // BEGIN Unmarshal arguments from response.
1616 -
1617 - if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil {
1618 - return
1619 - }
1620 - // END Unmarshal arguments from response.
1621 - return
1622 -}
1623 -
1624 -// Arguments:
1625 -//
1626 -// * NewDestinationAddress:
1627 -//
1628 -//
1629 -func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) {
1630 - // Request structure.
1631 - request := &struct {
1632 - NewDestinationAddress string
1633 - }{}
1634 - // BEGIN Marshal arguments into request.
1635 -
1636 - if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil {
1637 - return
1638 - }
1639 - // END Marshal arguments into request.
1640 -
1641 - // Response structure.
1642 - response := interface{}(nil)
1643 -
1644 - // Perform the SOAP call.
1645 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil {
1646 - return
1647 - }
1648 -
1649 - // BEGIN Unmarshal arguments from response.
1650 -
1651 - // END Unmarshal arguments from response.
1652 - return
1653 -}
1654 -
1655 -//
1656 -//
1657 -// Return values:
1658 -//
1659 -// * NewDestinationAddress:
1660 -func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) {
1661 - // Request structure.
1662 - request := interface{}(nil)
1663 - // BEGIN Marshal arguments into request.
1664 -
1665 - // END Marshal arguments into request.
1666 -
1667 - // Response structure.
1668 - response := &struct {
1669 - NewDestinationAddress string
1670 - }{}
1671 -
1672 - // Perform the SOAP call.
1673 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil {
1674 - return
1675 - }
1676 -
1677 - // BEGIN Unmarshal arguments from response.
1678 -
1679 - if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil {
1680 - return
1681 - }
1682 - // END Unmarshal arguments from response.
1683 - return
1684 -}
1685 -
1686 -// Arguments:
1687 -//
1688 -// * NewATMEncapsulation:
1689 -//
1690 -//
1691 -func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) {
1692 - // Request structure.
1693 - request := &struct {
1694 - NewATMEncapsulation string
1695 - }{}
1696 - // BEGIN Marshal arguments into request.
1697 -
1698 - if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil {
1699 - return
1700 - }
1701 - // END Marshal arguments into request.
1702 -
1703 - // Response structure.
1704 - response := interface{}(nil)
1705 -
1706 - // Perform the SOAP call.
1707 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil {
1708 - return
1709 - }
1710 -
1711 - // BEGIN Unmarshal arguments from response.
1712 -
1713 - // END Unmarshal arguments from response.
1714 - return
1715 -}
1716 -
1717 -//
1718 -//
1719 -// Return values:
1720 -//
1721 -// * NewATMEncapsulation:
1722 -func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) {
1723 - // Request structure.
1724 - request := interface{}(nil)
1725 - // BEGIN Marshal arguments into request.
1726 -
1727 - // END Marshal arguments into request.
1728 -
1729 - // Response structure.
1730 - response := &struct {
1731 - NewATMEncapsulation string
1732 - }{}
1733 -
1734 - // Perform the SOAP call.
1735 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil {
1736 - return
1737 - }
1738 -
1739 - // BEGIN Unmarshal arguments from response.
1740 -
1741 - if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil {
1742 - return
1743 - }
1744 - // END Unmarshal arguments from response.
1745 - return
1746 -}
1747 -
1748 -// Arguments:
1749 -//
1750 -// * NewFCSPreserved:
1751 -//
1752 -//
1753 -func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) {
1754 - // Request structure.
1755 - request := &struct {
1756 - NewFCSPreserved string
1757 - }{}
1758 - // BEGIN Marshal arguments into request.
1759 -
1760 - if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil {
1761 - return
1762 - }
1763 - // END Marshal arguments into request.
1764 -
1765 - // Response structure.
1766 - response := interface{}(nil)
1767 -
1768 - // Perform the SOAP call.
1769 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil {
1770 - return
1771 - }
1772 -
1773 - // BEGIN Unmarshal arguments from response.
1774 -
1775 - // END Unmarshal arguments from response.
1776 - return
1777 -}
1778 -
1779 -//
1780 -//
1781 -// Return values:
1782 -//
1783 -// * NewFCSPreserved:
1784 -func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) {
1785 - // Request structure.
1786 - request := interface{}(nil)
1787 - // BEGIN Marshal arguments into request.
1788 -
1789 - // END Marshal arguments into request.
1790 -
1791 - // Response structure.
1792 - response := &struct {
1793 - NewFCSPreserved string
1794 - }{}
1795 -
1796 - // Perform the SOAP call.
1797 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil {
1798 - return
1799 - }
1800 -
1801 - // BEGIN Unmarshal arguments from response.
1802 -
1803 - if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil {
1804 - return
1805 - }
1806 - // END Unmarshal arguments from response.
1807 - return
1808 -}
1809 -
1810 -// WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See
1811 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1812 -// are provided for informational value.
1813 -type WANEthernetLinkConfig1 struct {
1814 - goupnp.ServiceClient
1815 -}
1816 -
1817 -// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network,
1818 -// and returns clients to any that are found. errors will contain an error for
1819 -// any devices that replied but which could not be queried, and err will be set
1820 -// if the discovery process failed outright.
1821 -//
1822 -// This is a typical entry calling point into this package.
1823 -func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
1824 - var genericClients []goupnp.ServiceClient
1825 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil {
1826 - return
1827 - }
1828 - clients = make([]*WANEthernetLinkConfig1, len(genericClients))
1829 - for i := range genericClients {
1830 - clients[i] = &WANEthernetLinkConfig1{genericClients[i]}
1831 - }
1832 - return
1833 -}
1834 -
1835 -//
1836 -//
1837 -// Return values:
1838 -//
1839 -// * NewEthernetLinkStatus: allowed values: Up, Down
1840 -func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) {
1841 - // Request structure.
1842 - request := interface{}(nil)
1843 - // BEGIN Marshal arguments into request.
1844 -
1845 - // END Marshal arguments into request.
1846 -
1847 - // Response structure.
1848 - response := &struct {
1849 - NewEthernetLinkStatus string
1850 - }{}
1851 -
1852 - // Perform the SOAP call.
1853 - if err = client.SOAPClient.PerformAction(URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil {
1854 - return
1855 - }
1856 -
1857 - // BEGIN Unmarshal arguments from response.
1858 -
1859 - if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil {
1860 - return
1861 - }
1862 - // END Unmarshal arguments from response.
1863 - return
1864 -}
1865 -
1866 -// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See
1867 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1868 -// are provided for informational value.
1869 -type WANIPConnection1 struct {
1870 - goupnp.ServiceClient
1871 -}
1872 -
1873 -// NewWANIPConnection1Clients discovers instances of the service on the network,
1874 -// and returns clients to any that are found. errors will contain an error for
1875 -// any devices that replied but which could not be queried, and err will be set
1876 -// if the discovery process failed outright.
1877 -//
1878 -// This is a typical entry calling point into this package.
1879 -func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
1880 - var genericClients []goupnp.ServiceClient
1881 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil {
1882 - return
1883 - }
1884 - clients = make([]*WANIPConnection1, len(genericClients))
1885 - for i := range genericClients {
1886 - clients[i] = &WANIPConnection1{genericClients[i]}
1887 - }
1888 - return
1889 -}
1890 -
1891 -// Arguments:
1892 -//
1893 -// * NewConnectionType:
1894 -//
1895 -//
1896 -func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) {
1897 - // Request structure.
1898 - request := &struct {
1899 - NewConnectionType string
1900 - }{}
1901 - // BEGIN Marshal arguments into request.
1902 -
1903 - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil {
1904 - return
1905 - }
1906 - // END Marshal arguments into request.
1907 -
1908 - // Response structure.
1909 - response := interface{}(nil)
1910 -
1911 - // Perform the SOAP call.
1912 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil {
1913 - return
1914 - }
1915 -
1916 - // BEGIN Unmarshal arguments from response.
1917 -
1918 - // END Unmarshal arguments from response.
1919 - return
1920 -}
1921 -
1922 -//
1923 -//
1924 -// Return values:
1925 -//
1926 -// * NewConnectionType:
1927 -//
1928 -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged
1929 -func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) {
1930 - // Request structure.
1931 - request := interface{}(nil)
1932 - // BEGIN Marshal arguments into request.
1933 -
1934 - // END Marshal arguments into request.
1935 -
1936 - // Response structure.
1937 - response := &struct {
1938 - NewConnectionType string
1939 -
1940 - NewPossibleConnectionTypes string
1941 - }{}
1942 -
1943 - // Perform the SOAP call.
1944 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil {
1945 - return
1946 - }
1947 -
1948 - // BEGIN Unmarshal arguments from response.
1949 -
1950 - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil {
1951 - return
1952 - }
1953 - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil {
1954 - return
1955 - }
1956 - // END Unmarshal arguments from response.
1957 - return
1958 -}
1959 -
1960 -//
1961 -//
1962 -//
1963 -func (client *WANIPConnection1) RequestConnection() (err error) {
1964 - // Request structure.
1965 - request := interface{}(nil)
1966 - // BEGIN Marshal arguments into request.
1967 -
1968 - // END Marshal arguments into request.
1969 -
1970 - // Response structure.
1971 - response := interface{}(nil)
1972 -
1973 - // Perform the SOAP call.
1974 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestConnection", request, response); err != nil {
1975 - return
1976 - }
1977 -
1978 - // BEGIN Unmarshal arguments from response.
1979 -
1980 - // END Unmarshal arguments from response.
1981 - return
1982 -}
1983 -
1984 -//
1985 -//
1986 -//
1987 -func (client *WANIPConnection1) RequestTermination() (err error) {
1988 - // Request structure.
1989 - request := interface{}(nil)
1990 - // BEGIN Marshal arguments into request.
1991 -
1992 - // END Marshal arguments into request.
1993 -
1994 - // Response structure.
1995 - response := interface{}(nil)
1996 -
1997 - // Perform the SOAP call.
1998 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestTermination", request, response); err != nil {
1999 - return
2000 - }
2001 -
2002 - // BEGIN Unmarshal arguments from response.
2003 -
2004 - // END Unmarshal arguments from response.
2005 - return
2006 -}
2007 -
2008 -//
2009 -//
2010 -//
2011 -func (client *WANIPConnection1) ForceTermination() (err error) {
2012 - // Request structure.
2013 - request := interface{}(nil)
2014 - // BEGIN Marshal arguments into request.
2015 -
2016 - // END Marshal arguments into request.
2017 -
2018 - // Response structure.
2019 - response := interface{}(nil)
2020 -
2021 - // Perform the SOAP call.
2022 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "ForceTermination", request, response); err != nil {
2023 - return
2024 - }
2025 -
2026 - // BEGIN Unmarshal arguments from response.
2027 -
2028 - // END Unmarshal arguments from response.
2029 - return
2030 -}
2031 -
2032 -// Arguments:
2033 -//
2034 -// * NewAutoDisconnectTime:
2035 -//
2036 -//
2037 -func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) {
2038 - // Request structure.
2039 - request := &struct {
2040 - NewAutoDisconnectTime string
2041 - }{}
2042 - // BEGIN Marshal arguments into request.
2043 -
2044 - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil {
2045 - return
2046 - }
2047 - // END Marshal arguments into request.
2048 -
2049 - // Response structure.
2050 - response := interface{}(nil)
2051 -
2052 - // Perform the SOAP call.
2053 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil {
2054 - return
2055 - }
2056 -
2057 - // BEGIN Unmarshal arguments from response.
2058 -
2059 - // END Unmarshal arguments from response.
2060 - return
2061 -}
2062 -
2063 -// Arguments:
2064 -//
2065 -// * NewIdleDisconnectTime:
2066 -//
2067 -//
2068 -func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) {
2069 - // Request structure.
2070 - request := &struct {
2071 - NewIdleDisconnectTime string
2072 - }{}
2073 - // BEGIN Marshal arguments into request.
2074 -
2075 - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil {
2076 - return
2077 - }
2078 - // END Marshal arguments into request.
2079 -
2080 - // Response structure.
2081 - response := interface{}(nil)
2082 -
2083 - // Perform the SOAP call.
2084 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil {
2085 - return
2086 - }
2087 -
2088 - // BEGIN Unmarshal arguments from response.
2089 -
2090 - // END Unmarshal arguments from response.
2091 - return
2092 -}
2093 -
2094 -// Arguments:
2095 -//
2096 -// * NewWarnDisconnectDelay:
2097 -//
2098 -//
2099 -func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) {
2100 - // Request structure.
2101 - request := &struct {
2102 - NewWarnDisconnectDelay string
2103 - }{}
2104 - // BEGIN Marshal arguments into request.
2105 -
2106 - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil {
2107 - return
2108 - }
2109 - // END Marshal arguments into request.
2110 -
2111 - // Response structure.
2112 - response := interface{}(nil)
2113 -
2114 - // Perform the SOAP call.
2115 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil {
2116 - return
2117 - }
2118 -
2119 - // BEGIN Unmarshal arguments from response.
2120 -
2121 - // END Unmarshal arguments from response.
2122 - return
2123 -}
2124 -
2125 -//
2126 -//
2127 -// Return values:
2128 -//
2129 -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
2130 -//
2131 -// * NewLastConnectionError: allowed values: ERROR_NONE
2132 -//
2133 -// * NewUptime:
2134 -func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) {
2135 - // Request structure.
2136 - request := interface{}(nil)
2137 - // BEGIN Marshal arguments into request.
2138 -
2139 - // END Marshal arguments into request.
2140 -
2141 - // Response structure.
2142 - response := &struct {
2143 - NewConnectionStatus string
2144 -
2145 - NewLastConnectionError string
2146 -
2147 - NewUptime string
2148 - }{}
2149 -
2150 - // Perform the SOAP call.
2151 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil {
2152 - return
2153 - }
2154 -
2155 - // BEGIN Unmarshal arguments from response.
2156 -
2157 - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil {
2158 - return
2159 - }
2160 - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil {
2161 - return
2162 - }
2163 - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil {
2164 - return
2165 - }
2166 - // END Unmarshal arguments from response.
2167 - return
2168 -}
2169 -
2170 -//
2171 -//
2172 -// Return values:
2173 -//
2174 -// * NewAutoDisconnectTime:
2175 -func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) {
2176 - // Request structure.
2177 - request := interface{}(nil)
2178 - // BEGIN Marshal arguments into request.
2179 -
2180 - // END Marshal arguments into request.
2181 -
2182 - // Response structure.
2183 - response := &struct {
2184 - NewAutoDisconnectTime string
2185 - }{}
2186 -
2187 - // Perform the SOAP call.
2188 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil {
2189 - return
2190 - }
2191 -
2192 - // BEGIN Unmarshal arguments from response.
2193 -
2194 - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil {
2195 - return
2196 - }
2197 - // END Unmarshal arguments from response.
2198 - return
2199 -}
2200 -
2201 -//
2202 -//
2203 -// Return values:
2204 -//
2205 -// * NewIdleDisconnectTime:
2206 -func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) {
2207 - // Request structure.
2208 - request := interface{}(nil)
2209 - // BEGIN Marshal arguments into request.
2210 -
2211 - // END Marshal arguments into request.
2212 -
2213 - // Response structure.
2214 - response := &struct {
2215 - NewIdleDisconnectTime string
2216 - }{}
2217 -
2218 - // Perform the SOAP call.
2219 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil {
2220 - return
2221 - }
2222 -
2223 - // BEGIN Unmarshal arguments from response.
2224 -
2225 - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil {
2226 - return
2227 - }
2228 - // END Unmarshal arguments from response.
2229 - return
2230 -}
2231 -
2232 -//
2233 -//
2234 -// Return values:
2235 -//
2236 -// * NewWarnDisconnectDelay:
2237 -func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) {
2238 - // Request structure.
2239 - request := interface{}(nil)
2240 - // BEGIN Marshal arguments into request.
2241 -
2242 - // END Marshal arguments into request.
2243 -
2244 - // Response structure.
2245 - response := &struct {
2246 - NewWarnDisconnectDelay string
2247 - }{}
2248 -
2249 - // Perform the SOAP call.
2250 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil {
2251 - return
2252 - }
2253 -
2254 - // BEGIN Unmarshal arguments from response.
2255 -
2256 - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil {
2257 - return
2258 - }
2259 - // END Unmarshal arguments from response.
2260 - return
2261 -}
2262 -
2263 -//
2264 -//
2265 -// Return values:
2266 -//
2267 -// * NewRSIPAvailable:
2268 -//
2269 -// * NewNATEnabled:
2270 -func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) {
2271 - // Request structure.
2272 - request := interface{}(nil)
2273 - // BEGIN Marshal arguments into request.
2274 -
2275 - // END Marshal arguments into request.
2276 -
2277 - // Response structure.
2278 - response := &struct {
2279 - NewRSIPAvailable string
2280 -
2281 - NewNATEnabled string
2282 - }{}
2283 -
2284 - // Perform the SOAP call.
2285 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil {
2286 - return
2287 - }
2288 -
2289 - // BEGIN Unmarshal arguments from response.
2290 -
2291 - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil {
2292 - return
2293 - }
2294 - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil {
2295 - return
2296 - }
2297 - // END Unmarshal arguments from response.
2298 - return
2299 -}
2300 -
2301 -// Arguments:
2302 -//
2303 -// * NewPortMappingIndex:
2304 -//
2305 -// Return values:
2306 -//
2307 -// * NewRemoteHost:
2308 -//
2309 -// * NewExternalPort:
2310 -//
2311 -// * NewProtocol: allowed values: TCP, UDP
2312 -//
2313 -// * NewInternalPort:
2314 -//
2315 -// * NewInternalClient:
2316 -//
2317 -// * NewEnabled:
2318 -//
2319 -// * NewPortMappingDescription:
2320 -//
2321 -// * NewLeaseDuration:
2322 -func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
2323 - // Request structure.
2324 - request := &struct {
2325 - NewPortMappingIndex string
2326 - }{}
2327 - // BEGIN Marshal arguments into request.
2328 -
2329 - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil {
2330 - return
2331 - }
2332 - // END Marshal arguments into request.
2333 -
2334 - // Response structure.
2335 - response := &struct {
2336 - NewRemoteHost string
2337 -
2338 - NewExternalPort string
2339 -
2340 - NewProtocol string
2341 -
2342 - NewInternalPort string
2343 -
2344 - NewInternalClient string
2345 -
2346 - NewEnabled string
2347 -
2348 - NewPortMappingDescription string
2349 -
2350 - NewLeaseDuration string
2351 - }{}
2352 -
2353 - // Perform the SOAP call.
2354 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil {
2355 - return
2356 - }
2357 -
2358 - // BEGIN Unmarshal arguments from response.
2359 -
2360 - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil {
2361 - return
2362 - }
2363 - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil {
2364 - return
2365 - }
2366 - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil {
2367 - return
2368 - }
2369 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
2370 - return
2371 - }
2372 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
2373 - return
2374 - }
2375 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
2376 - return
2377 - }
2378 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
2379 - return
2380 - }
2381 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
2382 - return
2383 - }
2384 - // END Unmarshal arguments from response.
2385 - return
2386 -}
2387 -
2388 -// Arguments:
2389 -//
2390 -// * NewRemoteHost:
2391 -//
2392 -// * NewExternalPort:
2393 -//
2394 -// * NewProtocol: allowed values: TCP, UDP
2395 -//
2396 -// Return values:
2397 -//
2398 -// * NewInternalPort:
2399 -//
2400 -// * NewInternalClient:
2401 -//
2402 -// * NewEnabled:
2403 -//
2404 -// * NewPortMappingDescription:
2405 -//
2406 -// * NewLeaseDuration:
2407 -func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
2408 - // Request structure.
2409 - request := &struct {
2410 - NewRemoteHost string
2411 -
2412 - NewExternalPort string
2413 -
2414 - NewProtocol string
2415 - }{}
2416 - // BEGIN Marshal arguments into request.
2417 -
2418 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
2419 - return
2420 - }
2421 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
2422 - return
2423 - }
2424 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
2425 - return
2426 - }
2427 - // END Marshal arguments into request.
2428 -
2429 - // Response structure.
2430 - response := &struct {
2431 - NewInternalPort string
2432 -
2433 - NewInternalClient string
2434 -
2435 - NewEnabled string
2436 -
2437 - NewPortMappingDescription string
2438 -
2439 - NewLeaseDuration string
2440 - }{}
2441 -
2442 - // Perform the SOAP call.
2443 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil {
2444 - return
2445 - }
2446 -
2447 - // BEGIN Unmarshal arguments from response.
2448 -
2449 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
2450 - return
2451 - }
2452 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
2453 - return
2454 - }
2455 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
2456 - return
2457 - }
2458 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
2459 - return
2460 - }
2461 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
2462 - return
2463 - }
2464 - // END Unmarshal arguments from response.
2465 - return
2466 -}
2467 -
2468 -// Arguments:
2469 -//
2470 -// * NewRemoteHost:
2471 -//
2472 -// * NewExternalPort:
2473 -//
2474 -// * NewProtocol: allowed values: TCP, UDP
2475 -//
2476 -// * NewInternalPort:
2477 -//
2478 -// * NewInternalClient:
2479 -//
2480 -// * NewEnabled:
2481 -//
2482 -// * NewPortMappingDescription:
2483 -//
2484 -// * NewLeaseDuration:
2485 -//
2486 -//
2487 -func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) {
2488 - // Request structure.
2489 - request := &struct {
2490 - NewRemoteHost string
2491 -
2492 - NewExternalPort string
2493 -
2494 - NewProtocol string
2495 -
2496 - NewInternalPort string
2497 -
2498 - NewInternalClient string
2499 -
2500 - NewEnabled string
2501 -
2502 - NewPortMappingDescription string
2503 -
2504 - NewLeaseDuration string
2505 - }{}
2506 - // BEGIN Marshal arguments into request.
2507 -
2508 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
2509 - return
2510 - }
2511 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
2512 - return
2513 - }
2514 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
2515 - return
2516 - }
2517 - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil {
2518 - return
2519 - }
2520 - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil {
2521 - return
2522 - }
2523 - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil {
2524 - return
2525 - }
2526 - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil {
2527 - return
2528 - }
2529 - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil {
2530 - return
2531 - }
2532 - // END Marshal arguments into request.
2533 -
2534 - // Response structure.
2535 - response := interface{}(nil)
2536 -
2537 - // Perform the SOAP call.
2538 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil {
2539 - return
2540 - }
2541 -
2542 - // BEGIN Unmarshal arguments from response.
2543 -
2544 - // END Unmarshal arguments from response.
2545 - return
2546 -}
2547 -
2548 -// Arguments:
2549 -//
2550 -// * NewRemoteHost:
2551 -//
2552 -// * NewExternalPort:
2553 -//
2554 -// * NewProtocol: allowed values: TCP, UDP
2555 -//
2556 -//
2557 -func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) {
2558 - // Request structure.
2559 - request := &struct {
2560 - NewRemoteHost string
2561 -
2562 - NewExternalPort string
2563 -
2564 - NewProtocol string
2565 - }{}
2566 - // BEGIN Marshal arguments into request.
2567 -
2568 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
2569 - return
2570 - }
2571 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
2572 - return
2573 - }
2574 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
2575 - return
2576 - }
2577 - // END Marshal arguments into request.
2578 -
2579 - // Response structure.
2580 - response := interface{}(nil)
2581 -
2582 - // Perform the SOAP call.
2583 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil {
2584 - return
2585 - }
2586 -
2587 - // BEGIN Unmarshal arguments from response.
2588 -
2589 - // END Unmarshal arguments from response.
2590 - return
2591 -}
2592 -
2593 -//
2594 -//
2595 -// Return values:
2596 -//
2597 -// * NewExternalIPAddress:
2598 -func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) {
2599 - // Request structure.
2600 - request := interface{}(nil)
2601 - // BEGIN Marshal arguments into request.
2602 -
2603 - // END Marshal arguments into request.
2604 -
2605 - // Response structure.
2606 - response := &struct {
2607 - NewExternalIPAddress string
2608 - }{}
2609 -
2610 - // Perform the SOAP call.
2611 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil {
2612 - return
2613 - }
2614 -
2615 - // BEGIN Unmarshal arguments from response.
2616 -
2617 - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil {
2618 - return
2619 - }
2620 - // END Unmarshal arguments from response.
2621 - return
2622 -}
2623 -
2624 -// WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See
2625 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
2626 -// are provided for informational value.
2627 -type WANPOTSLinkConfig1 struct {
2628 - goupnp.ServiceClient
2629 -}
2630 -
2631 -// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network,
2632 -// and returns clients to any that are found. errors will contain an error for
2633 -// any devices that replied but which could not be queried, and err will be set
2634 -// if the discovery process failed outright.
2635 -//
2636 -// This is a typical entry calling point into this package.
2637 -func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
2638 - var genericClients []goupnp.ServiceClient
2639 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil {
2640 - return
2641 - }
2642 - clients = make([]*WANPOTSLinkConfig1, len(genericClients))
2643 - for i := range genericClients {
2644 - clients[i] = &WANPOTSLinkConfig1{genericClients[i]}
2645 - }
2646 - return
2647 -}
2648 -
2649 -// Arguments:
2650 -//
2651 -// * NewISPPhoneNumber:
2652 -//
2653 -// * NewISPInfo:
2654 -//
2655 -// * NewLinkType: allowed values: PPP_Dialup
2656 -//
2657 -//
2658 -func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) {
2659 - // Request structure.
2660 - request := &struct {
2661 - NewISPPhoneNumber string
2662 -
2663 - NewISPInfo string
2664 -
2665 - NewLinkType string
2666 - }{}
2667 - // BEGIN Marshal arguments into request.
2668 -
2669 - if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil {
2670 - return
2671 - }
2672 - if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil {
2673 - return
2674 - }
2675 - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil {
2676 - return
2677 - }
2678 - // END Marshal arguments into request.
2679 -
2680 - // Response structure.
2681 - response := interface{}(nil)
2682 -
2683 - // Perform the SOAP call.
2684 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil {
2685 - return
2686 - }
2687 -
2688 - // BEGIN Unmarshal arguments from response.
2689 -
2690 - // END Unmarshal arguments from response.
2691 - return
2692 -}
2693 -
2694 -// Arguments:
2695 -//
2696 -// * NewNumberOfRetries:
2697 -//
2698 -// * NewDelayBetweenRetries:
2699 -//
2700 -//
2701 -func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) {
2702 - // Request structure.
2703 - request := &struct {
2704 - NewNumberOfRetries string
2705 -
2706 - NewDelayBetweenRetries string
2707 - }{}
2708 - // BEGIN Marshal arguments into request.
2709 -
2710 - if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil {
2711 - return
2712 - }
2713 - if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil {
2714 - return
2715 - }
2716 - // END Marshal arguments into request.
2717 -
2718 - // Response structure.
2719 - response := interface{}(nil)
2720 -
2721 - // Perform the SOAP call.
2722 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil {
2723 - return
2724 - }
2725 -
2726 - // BEGIN Unmarshal arguments from response.
2727 -
2728 - // END Unmarshal arguments from response.
2729 - return
2730 -}
2731 -
2732 -//
2733 -//
2734 -// Return values:
2735 -//
2736 -// * NewISPPhoneNumber:
2737 -//
2738 -// * NewISPInfo:
2739 -//
2740 -// * NewLinkType: allowed values: PPP_Dialup
2741 -func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) {
2742 - // Request structure.
2743 - request := interface{}(nil)
2744 - // BEGIN Marshal arguments into request.
2745 -
2746 - // END Marshal arguments into request.
2747 -
2748 - // Response structure.
2749 - response := &struct {
2750 - NewISPPhoneNumber string
2751 -
2752 - NewISPInfo string
2753 -
2754 - NewLinkType string
2755 - }{}
2756 -
2757 - // Perform the SOAP call.
2758 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil {
2759 - return
2760 - }
2761 -
2762 - // BEGIN Unmarshal arguments from response.
2763 -
2764 - if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil {
2765 - return
2766 - }
2767 - if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil {
2768 - return
2769 - }
2770 - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil {
2771 - return
2772 - }
2773 - // END Unmarshal arguments from response.
2774 - return
2775 -}
2776 -
2777 -//
2778 -//
2779 -// Return values:
2780 -//
2781 -// * NewNumberOfRetries:
2782 -//
2783 -// * NewDelayBetweenRetries:
2784 -func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) {
2785 - // Request structure.
2786 - request := interface{}(nil)
2787 - // BEGIN Marshal arguments into request.
2788 -
2789 - // END Marshal arguments into request.
2790 -
2791 - // Response structure.
2792 - response := &struct {
2793 - NewNumberOfRetries string
2794 -
2795 - NewDelayBetweenRetries string
2796 - }{}
2797 -
2798 - // Perform the SOAP call.
2799 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil {
2800 - return
2801 - }
2802 -
2803 - // BEGIN Unmarshal arguments from response.
2804 -
2805 - if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil {
2806 - return
2807 - }
2808 - if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil {
2809 - return
2810 - }
2811 - // END Unmarshal arguments from response.
2812 - return
2813 -}
2814 -
2815 -//
2816 -//
2817 -// Return values:
2818 -//
2819 -// * NewFclass:
2820 -func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) {
2821 - // Request structure.
2822 - request := interface{}(nil)
2823 - // BEGIN Marshal arguments into request.
2824 -
2825 - // END Marshal arguments into request.
2826 -
2827 - // Response structure.
2828 - response := &struct {
2829 - NewFclass string
2830 - }{}
2831 -
2832 - // Perform the SOAP call.
2833 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil {
2834 - return
2835 - }
2836 -
2837 - // BEGIN Unmarshal arguments from response.
2838 -
2839 - if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil {
2840 - return
2841 - }
2842 - // END Unmarshal arguments from response.
2843 - return
2844 -}
2845 -
2846 -//
2847 -//
2848 -// Return values:
2849 -//
2850 -// * NewDataModulationSupported:
2851 -func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) {
2852 - // Request structure.
2853 - request := interface{}(nil)
2854 - // BEGIN Marshal arguments into request.
2855 -
2856 - // END Marshal arguments into request.
2857 -
2858 - // Response structure.
2859 - response := &struct {
2860 - NewDataModulationSupported string
2861 - }{}
2862 -
2863 - // Perform the SOAP call.
2864 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil {
2865 - return
2866 - }
2867 -
2868 - // BEGIN Unmarshal arguments from response.
2869 -
2870 - if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil {
2871 - return
2872 - }
2873 - // END Unmarshal arguments from response.
2874 - return
2875 -}
2876 -
2877 -//
2878 -//
2879 -// Return values:
2880 -//
2881 -// * NewDataProtocol:
2882 -func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) {
2883 - // Request structure.
2884 - request := interface{}(nil)
2885 - // BEGIN Marshal arguments into request.
2886 -
2887 - // END Marshal arguments into request.
2888 -
2889 - // Response structure.
2890 - response := &struct {
2891 - NewDataProtocol string
2892 - }{}
2893 -
2894 - // Perform the SOAP call.
2895 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil {
2896 - return
2897 - }
2898 -
2899 - // BEGIN Unmarshal arguments from response.
2900 -
2901 - if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil {
2902 - return
2903 - }
2904 - // END Unmarshal arguments from response.
2905 - return
2906 -}
2907 -
2908 -//
2909 -//
2910 -// Return values:
2911 -//
2912 -// * NewDataCompression:
2913 -func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) {
2914 - // Request structure.
2915 - request := interface{}(nil)
2916 - // BEGIN Marshal arguments into request.
2917 -
2918 - // END Marshal arguments into request.
2919 -
2920 - // Response structure.
2921 - response := &struct {
2922 - NewDataCompression string
2923 - }{}
2924 -
2925 - // Perform the SOAP call.
2926 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil {
2927 - return
2928 - }
2929 -
2930 - // BEGIN Unmarshal arguments from response.
2931 -
2932 - if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil {
2933 - return
2934 - }
2935 - // END Unmarshal arguments from response.
2936 - return
2937 -}
2938 -
2939 -//
2940 -//
2941 -// Return values:
2942 -//
2943 -// * NewPlusVTRCommandSupported:
2944 -func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) {
2945 - // Request structure.
2946 - request := interface{}(nil)
2947 - // BEGIN Marshal arguments into request.
2948 -
2949 - // END Marshal arguments into request.
2950 -
2951 - // Response structure.
2952 - response := &struct {
2953 - NewPlusVTRCommandSupported string
2954 - }{}
2955 -
2956 - // Perform the SOAP call.
2957 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil {
2958 - return
2959 - }
2960 -
2961 - // BEGIN Unmarshal arguments from response.
2962 -
2963 - if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil {
2964 - return
2965 - }
2966 - // END Unmarshal arguments from response.
2967 - return
2968 -}
2969 -
2970 -// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See
2971 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
2972 -// are provided for informational value.
2973 -type WANPPPConnection1 struct {
2974 - goupnp.ServiceClient
2975 -}
2976 -
2977 -// NewWANPPPConnection1Clients discovers instances of the service on the network,
2978 -// and returns clients to any that are found. errors will contain an error for
2979 -// any devices that replied but which could not be queried, and err will be set
2980 -// if the discovery process failed outright.
2981 -//
2982 -// This is a typical entry calling point into this package.
2983 -func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
2984 - var genericClients []goupnp.ServiceClient
2985 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil {
2986 - return
2987 - }
2988 - clients = make([]*WANPPPConnection1, len(genericClients))
2989 - for i := range genericClients {
2990 - clients[i] = &WANPPPConnection1{genericClients[i]}
2991 - }
2992 - return
2993 -}
2994 -
2995 -// Arguments:
2996 -//
2997 -// * NewConnectionType:
2998 -//
2999 -//
3000 -func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) {
3001 - // Request structure.
3002 - request := &struct {
3003 - NewConnectionType string
3004 - }{}
3005 - // BEGIN Marshal arguments into request.
3006 -
3007 - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil {
3008 - return
3009 - }
3010 - // END Marshal arguments into request.
3011 -
3012 - // Response structure.
3013 - response := interface{}(nil)
3014 -
3015 - // Perform the SOAP call.
3016 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil {
3017 - return
3018 - }
3019 -
3020 - // BEGIN Unmarshal arguments from response.
3021 -
3022 - // END Unmarshal arguments from response.
3023 - return
3024 -}
3025 -
3026 -//
3027 -//
3028 -// Return values:
3029 -//
3030 -// * NewConnectionType:
3031 -//
3032 -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay
3033 -func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) {
3034 - // Request structure.
3035 - request := interface{}(nil)
3036 - // BEGIN Marshal arguments into request.
3037 -
3038 - // END Marshal arguments into request.
3039 -
3040 - // Response structure.
3041 - response := &struct {
3042 - NewConnectionType string
3043 -
3044 - NewPossibleConnectionTypes string
3045 - }{}
3046 -
3047 - // Perform the SOAP call.
3048 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil {
3049 - return
3050 - }
3051 -
3052 - // BEGIN Unmarshal arguments from response.
3053 -
3054 - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil {
3055 - return
3056 - }
3057 - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil {
3058 - return
3059 - }
3060 - // END Unmarshal arguments from response.
3061 - return
3062 -}
3063 -
3064 -// Arguments:
3065 -//
3066 -// * NewUserName:
3067 -//
3068 -// * NewPassword:
3069 -//
3070 -//
3071 -func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) {
3072 - // Request structure.
3073 - request := &struct {
3074 - NewUserName string
3075 -
3076 - NewPassword string
3077 - }{}
3078 - // BEGIN Marshal arguments into request.
3079 -
3080 - if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil {
3081 - return
3082 - }
3083 - if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil {
3084 - return
3085 - }
3086 - // END Marshal arguments into request.
3087 -
3088 - // Response structure.
3089 - response := interface{}(nil)
3090 -
3091 - // Perform the SOAP call.
3092 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil {
3093 - return
3094 - }
3095 -
3096 - // BEGIN Unmarshal arguments from response.
3097 -
3098 - // END Unmarshal arguments from response.
3099 - return
3100 -}
3101 -
3102 -//
3103 -//
3104 -//
3105 -func (client *WANPPPConnection1) RequestConnection() (err error) {
3106 - // Request structure.
3107 - request := interface{}(nil)
3108 - // BEGIN Marshal arguments into request.
3109 -
3110 - // END Marshal arguments into request.
3111 -
3112 - // Response structure.
3113 - response := interface{}(nil)
3114 -
3115 - // Perform the SOAP call.
3116 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil {
3117 - return
3118 - }
3119 -
3120 - // BEGIN Unmarshal arguments from response.
3121 -
3122 - // END Unmarshal arguments from response.
3123 - return
3124 -}
3125 -
3126 -//
3127 -//
3128 -//
3129 -func (client *WANPPPConnection1) RequestTermination() (err error) {
3130 - // Request structure.
3131 - request := interface{}(nil)
3132 - // BEGIN Marshal arguments into request.
3133 -
3134 - // END Marshal arguments into request.
3135 -
3136 - // Response structure.
3137 - response := interface{}(nil)
3138 -
3139 - // Perform the SOAP call.
3140 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil {
3141 - return
3142 - }
3143 -
3144 - // BEGIN Unmarshal arguments from response.
3145 -
3146 - // END Unmarshal arguments from response.
3147 - return
3148 -}
3149 -
3150 -//
3151 -//
3152 -//
3153 -func (client *WANPPPConnection1) ForceTermination() (err error) {
3154 - // Request structure.
3155 - request := interface{}(nil)
3156 - // BEGIN Marshal arguments into request.
3157 -
3158 - // END Marshal arguments into request.
3159 -
3160 - // Response structure.
3161 - response := interface{}(nil)
3162 -
3163 - // Perform the SOAP call.
3164 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil {
3165 - return
3166 - }
3167 -
3168 - // BEGIN Unmarshal arguments from response.
3169 -
3170 - // END Unmarshal arguments from response.
3171 - return
3172 -}
3173 -
3174 -// Arguments:
3175 -//
3176 -// * NewAutoDisconnectTime:
3177 -//
3178 -//
3179 -func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) {
3180 - // Request structure.
3181 - request := &struct {
3182 - NewAutoDisconnectTime string
3183 - }{}
3184 - // BEGIN Marshal arguments into request.
3185 -
3186 - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil {
3187 - return
3188 - }
3189 - // END Marshal arguments into request.
3190 -
3191 - // Response structure.
3192 - response := interface{}(nil)
3193 -
3194 - // Perform the SOAP call.
3195 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil {
3196 - return
3197 - }
3198 -
3199 - // BEGIN Unmarshal arguments from response.
3200 -
3201 - // END Unmarshal arguments from response.
3202 - return
3203 -}
3204 -
3205 -// Arguments:
3206 -//
3207 -// * NewIdleDisconnectTime:
3208 -//
3209 -//
3210 -func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) {
3211 - // Request structure.
3212 - request := &struct {
3213 - NewIdleDisconnectTime string
3214 - }{}
3215 - // BEGIN Marshal arguments into request.
3216 -
3217 - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil {
3218 - return
3219 - }
3220 - // END Marshal arguments into request.
3221 -
3222 - // Response structure.
3223 - response := interface{}(nil)
3224 -
3225 - // Perform the SOAP call.
3226 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil {
3227 - return
3228 - }
3229 -
3230 - // BEGIN Unmarshal arguments from response.
3231 -
3232 - // END Unmarshal arguments from response.
3233 - return
3234 -}
3235 -
3236 -// Arguments:
3237 -//
3238 -// * NewWarnDisconnectDelay:
3239 -//
3240 -//
3241 -func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) {
3242 - // Request structure.
3243 - request := &struct {
3244 - NewWarnDisconnectDelay string
3245 - }{}
3246 - // BEGIN Marshal arguments into request.
3247 -
3248 - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil {
3249 - return
3250 - }
3251 - // END Marshal arguments into request.
3252 -
3253 - // Response structure.
3254 - response := interface{}(nil)
3255 -
3256 - // Perform the SOAP call.
3257 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil {
3258 - return
3259 - }
3260 -
3261 - // BEGIN Unmarshal arguments from response.
3262 -
3263 - // END Unmarshal arguments from response.
3264 - return
3265 -}
3266 -
3267 -//
3268 -//
3269 -// Return values:
3270 -//
3271 -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
3272 -//
3273 -// * NewLastConnectionError: allowed values: ERROR_NONE
3274 -//
3275 -// * NewUptime:
3276 -func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) {
3277 - // Request structure.
3278 - request := interface{}(nil)
3279 - // BEGIN Marshal arguments into request.
3280 -
3281 - // END Marshal arguments into request.
3282 -
3283 - // Response structure.
3284 - response := &struct {
3285 - NewConnectionStatus string
3286 -
3287 - NewLastConnectionError string
3288 -
3289 - NewUptime string
3290 - }{}
3291 -
3292 - // Perform the SOAP call.
3293 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil {
3294 - return
3295 - }
3296 -
3297 - // BEGIN Unmarshal arguments from response.
3298 -
3299 - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil {
3300 - return
3301 - }
3302 - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil {
3303 - return
3304 - }
3305 - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil {
3306 - return
3307 - }
3308 - // END Unmarshal arguments from response.
3309 - return
3310 -}
3311 -
3312 -//
3313 -//
3314 -// Return values:
3315 -//
3316 -// * NewUpstreamMaxBitRate:
3317 -//
3318 -// * NewDownstreamMaxBitRate:
3319 -func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) {
3320 - // Request structure.
3321 - request := interface{}(nil)
3322 - // BEGIN Marshal arguments into request.
3323 -
3324 - // END Marshal arguments into request.
3325 -
3326 - // Response structure.
3327 - response := &struct {
3328 - NewUpstreamMaxBitRate string
3329 -
3330 - NewDownstreamMaxBitRate string
3331 - }{}
3332 -
3333 - // Perform the SOAP call.
3334 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil {
3335 - return
3336 - }
3337 -
3338 - // BEGIN Unmarshal arguments from response.
3339 -
3340 - if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil {
3341 - return
3342 - }
3343 - if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil {
3344 - return
3345 - }
3346 - // END Unmarshal arguments from response.
3347 - return
3348 -}
3349 -
3350 -//
3351 -//
3352 -// Return values:
3353 -//
3354 -// * NewPPPEncryptionProtocol:
3355 -func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) {
3356 - // Request structure.
3357 - request := interface{}(nil)
3358 - // BEGIN Marshal arguments into request.
3359 -
3360 - // END Marshal arguments into request.
3361 -
3362 - // Response structure.
3363 - response := &struct {
3364 - NewPPPEncryptionProtocol string
3365 - }{}
3366 -
3367 - // Perform the SOAP call.
3368 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil {
3369 - return
3370 - }
3371 -
3372 - // BEGIN Unmarshal arguments from response.
3373 -
3374 - if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil {
3375 - return
3376 - }
3377 - // END Unmarshal arguments from response.
3378 - return
3379 -}
3380 -
3381 -//
3382 -//
3383 -// Return values:
3384 -//
3385 -// * NewPPPCompressionProtocol:
3386 -func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) {
3387 - // Request structure.
3388 - request := interface{}(nil)
3389 - // BEGIN Marshal arguments into request.
3390 -
3391 - // END Marshal arguments into request.
3392 -
3393 - // Response structure.
3394 - response := &struct {
3395 - NewPPPCompressionProtocol string
3396 - }{}
3397 -
3398 - // Perform the SOAP call.
3399 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil {
3400 - return
3401 - }
3402 -
3403 - // BEGIN Unmarshal arguments from response.
3404 -
3405 - if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil {
3406 - return
3407 - }
3408 - // END Unmarshal arguments from response.
3409 - return
3410 -}
3411 -
3412 -//
3413 -//
3414 -// Return values:
3415 -//
3416 -// * NewPPPAuthenticationProtocol:
3417 -func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) {
3418 - // Request structure.
3419 - request := interface{}(nil)
3420 - // BEGIN Marshal arguments into request.
3421 -
3422 - // END Marshal arguments into request.
3423 -
3424 - // Response structure.
3425 - response := &struct {
3426 - NewPPPAuthenticationProtocol string
3427 - }{}
3428 -
3429 - // Perform the SOAP call.
3430 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil {
3431 - return
3432 - }
3433 -
3434 - // BEGIN Unmarshal arguments from response.
3435 -
3436 - if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil {
3437 - return
3438 - }
3439 - // END Unmarshal arguments from response.
3440 - return
3441 -}
3442 -
3443 -//
3444 -//
3445 -// Return values:
3446 -//
3447 -// * NewUserName:
3448 -func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) {
3449 - // Request structure.
3450 - request := interface{}(nil)
3451 - // BEGIN Marshal arguments into request.
3452 -
3453 - // END Marshal arguments into request.
3454 -
3455 - // Response structure.
3456 - response := &struct {
3457 - NewUserName string
3458 - }{}
3459 -
3460 - // Perform the SOAP call.
3461 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetUserName", request, response); err != nil {
3462 - return
3463 - }
3464 -
3465 - // BEGIN Unmarshal arguments from response.
3466 -
3467 - if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil {
3468 - return
3469 - }
3470 - // END Unmarshal arguments from response.
3471 - return
3472 -}
3473 -
3474 -//
3475 -//
3476 -// Return values:
3477 -//
3478 -// * NewPassword:
3479 -func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) {
3480 - // Request structure.
3481 - request := interface{}(nil)
3482 - // BEGIN Marshal arguments into request.
3483 -
3484 - // END Marshal arguments into request.
3485 -
3486 - // Response structure.
3487 - response := &struct {
3488 - NewPassword string
3489 - }{}
3490 -
3491 - // Perform the SOAP call.
3492 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPassword", request, response); err != nil {
3493 - return
3494 - }
3495 -
3496 - // BEGIN Unmarshal arguments from response.
3497 -
3498 - if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil {
3499 - return
3500 - }
3501 - // END Unmarshal arguments from response.
3502 - return
3503 -}
3504 -
3505 -//
3506 -//
3507 -// Return values:
3508 -//
3509 -// * NewAutoDisconnectTime:
3510 -func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) {
3511 - // Request structure.
3512 - request := interface{}(nil)
3513 - // BEGIN Marshal arguments into request.
3514 -
3515 - // END Marshal arguments into request.
3516 -
3517 - // Response structure.
3518 - response := &struct {
3519 - NewAutoDisconnectTime string
3520 - }{}
3521 -
3522 - // Perform the SOAP call.
3523 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil {
3524 - return
3525 - }
3526 -
3527 - // BEGIN Unmarshal arguments from response.
3528 -
3529 - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil {
3530 - return
3531 - }
3532 - // END Unmarshal arguments from response.
3533 - return
3534 -}
3535 -
3536 -//
3537 -//
3538 -// Return values:
3539 -//
3540 -// * NewIdleDisconnectTime:
3541 -func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) {
3542 - // Request structure.
3543 - request := interface{}(nil)
3544 - // BEGIN Marshal arguments into request.
3545 -
3546 - // END Marshal arguments into request.
3547 -
3548 - // Response structure.
3549 - response := &struct {
3550 - NewIdleDisconnectTime string
3551 - }{}
3552 -
3553 - // Perform the SOAP call.
3554 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil {
3555 - return
3556 - }
3557 -
3558 - // BEGIN Unmarshal arguments from response.
3559 -
3560 - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil {
3561 - return
3562 - }
3563 - // END Unmarshal arguments from response.
3564 - return
3565 -}
3566 -
3567 -//
3568 -//
3569 -// Return values:
3570 -//
3571 -// * NewWarnDisconnectDelay:
3572 -func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) {
3573 - // Request structure.
3574 - request := interface{}(nil)
3575 - // BEGIN Marshal arguments into request.
3576 -
3577 - // END Marshal arguments into request.
3578 -
3579 - // Response structure.
3580 - response := &struct {
3581 - NewWarnDisconnectDelay string
3582 - }{}
3583 -
3584 - // Perform the SOAP call.
3585 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil {
3586 - return
3587 - }
3588 -
3589 - // BEGIN Unmarshal arguments from response.
3590 -
3591 - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil {
3592 - return
3593 - }
3594 - // END Unmarshal arguments from response.
3595 - return
3596 -}
3597 -
3598 -//
3599 -//
3600 -// Return values:
3601 -//
3602 -// * NewRSIPAvailable:
3603 -//
3604 -// * NewNATEnabled:
3605 -func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) {
3606 - // Request structure.
3607 - request := interface{}(nil)
3608 - // BEGIN Marshal arguments into request.
3609 -
3610 - // END Marshal arguments into request.
3611 -
3612 - // Response structure.
3613 - response := &struct {
3614 - NewRSIPAvailable string
3615 -
3616 - NewNATEnabled string
3617 - }{}
3618 -
3619 - // Perform the SOAP call.
3620 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil {
3621 - return
3622 - }
3623 -
3624 - // BEGIN Unmarshal arguments from response.
3625 -
3626 - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil {
3627 - return
3628 - }
3629 - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil {
3630 - return
3631 - }
3632 - // END Unmarshal arguments from response.
3633 - return
3634 -}
3635 -
3636 -// Arguments:
3637 -//
3638 -// * NewPortMappingIndex:
3639 -//
3640 -// Return values:
3641 -//
3642 -// * NewRemoteHost:
3643 -//
3644 -// * NewExternalPort:
3645 -//
3646 -// * NewProtocol: allowed values: TCP, UDP
3647 -//
3648 -// * NewInternalPort:
3649 -//
3650 -// * NewInternalClient:
3651 -//
3652 -// * NewEnabled:
3653 -//
3654 -// * NewPortMappingDescription:
3655 -//
3656 -// * NewLeaseDuration:
3657 -func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
3658 - // Request structure.
3659 - request := &struct {
3660 - NewPortMappingIndex string
3661 - }{}
3662 - // BEGIN Marshal arguments into request.
3663 -
3664 - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil {
3665 - return
3666 - }
3667 - // END Marshal arguments into request.
3668 -
3669 - // Response structure.
3670 - response := &struct {
3671 - NewRemoteHost string
3672 -
3673 - NewExternalPort string
3674 -
3675 - NewProtocol string
3676 -
3677 - NewInternalPort string
3678 -
3679 - NewInternalClient string
3680 -
3681 - NewEnabled string
3682 -
3683 - NewPortMappingDescription string
3684 -
3685 - NewLeaseDuration string
3686 - }{}
3687 -
3688 - // Perform the SOAP call.
3689 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil {
3690 - return
3691 - }
3692 -
3693 - // BEGIN Unmarshal arguments from response.
3694 -
3695 - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil {
3696 - return
3697 - }
3698 - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil {
3699 - return
3700 - }
3701 - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil {
3702 - return
3703 - }
3704 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
3705 - return
3706 - }
3707 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
3708 - return
3709 - }
3710 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
3711 - return
3712 - }
3713 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
3714 - return
3715 - }
3716 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
3717 - return
3718 - }
3719 - // END Unmarshal arguments from response.
3720 - return
3721 -}
3722 -
3723 -// Arguments:
3724 -//
3725 -// * NewRemoteHost:
3726 -//
3727 -// * NewExternalPort:
3728 -//
3729 -// * NewProtocol: allowed values: TCP, UDP
3730 -//
3731 -// Return values:
3732 -//
3733 -// * NewInternalPort:
3734 -//
3735 -// * NewInternalClient:
3736 -//
3737 -// * NewEnabled:
3738 -//
3739 -// * NewPortMappingDescription:
3740 -//
3741 -// * NewLeaseDuration:
3742 -func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
3743 - // Request structure.
3744 - request := &struct {
3745 - NewRemoteHost string
3746 -
3747 - NewExternalPort string
3748 -
3749 - NewProtocol string
3750 - }{}
3751 - // BEGIN Marshal arguments into request.
3752 -
3753 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
3754 - return
3755 - }
3756 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
3757 - return
3758 - }
3759 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3760 - return
3761 - }
3762 - // END Marshal arguments into request.
3763 -
3764 - // Response structure.
3765 - response := &struct {
3766 - NewInternalPort string
3767 -
3768 - NewInternalClient string
3769 -
3770 - NewEnabled string
3771 -
3772 - NewPortMappingDescription string
3773 -
3774 - NewLeaseDuration string
3775 - }{}
3776 -
3777 - // Perform the SOAP call.
3778 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil {
3779 - return
3780 - }
3781 -
3782 - // BEGIN Unmarshal arguments from response.
3783 -
3784 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
3785 - return
3786 - }
3787 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
3788 - return
3789 - }
3790 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
3791 - return
3792 - }
3793 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
3794 - return
3795 - }
3796 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
3797 - return
3798 - }
3799 - // END Unmarshal arguments from response.
3800 - return
3801 -}
3802 -
3803 -// Arguments:
3804 -//
3805 -// * NewRemoteHost:
3806 -//
3807 -// * NewExternalPort:
3808 -//
3809 -// * NewProtocol: allowed values: TCP, UDP
3810 -//
3811 -// * NewInternalPort:
3812 -//
3813 -// * NewInternalClient:
3814 -//
3815 -// * NewEnabled:
3816 -//
3817 -// * NewPortMappingDescription:
3818 -//
3819 -// * NewLeaseDuration:
3820 -//
3821 -//
3822 -func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) {
3823 - // Request structure.
3824 - request := &struct {
3825 - NewRemoteHost string
3826 -
3827 - NewExternalPort string
3828 -
3829 - NewProtocol string
3830 -
3831 - NewInternalPort string
3832 -
3833 - NewInternalClient string
3834 -
3835 - NewEnabled string
3836 -
3837 - NewPortMappingDescription string
3838 -
3839 - NewLeaseDuration string
3840 - }{}
3841 - // BEGIN Marshal arguments into request.
3842 -
3843 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
3844 - return
3845 - }
3846 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
3847 - return
3848 - }
3849 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3850 - return
3851 - }
3852 - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil {
3853 - return
3854 - }
3855 - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil {
3856 - return
3857 - }
3858 - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil {
3859 - return
3860 - }
3861 - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil {
3862 - return
3863 - }
3864 - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil {
3865 - return
3866 - }
3867 - // END Marshal arguments into request.
3868 -
3869 - // Response structure.
3870 - response := interface{}(nil)
3871 -
3872 - // Perform the SOAP call.
3873 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "AddPortMapping", request, response); err != nil {
3874 - return
3875 - }
3876 -
3877 - // BEGIN Unmarshal arguments from response.
3878 -
3879 - // END Unmarshal arguments from response.
3880 - return
3881 -}
3882 -
3883 -// Arguments:
3884 -//
3885 -// * NewRemoteHost:
3886 -//
3887 -// * NewExternalPort:
3888 -//
3889 -// * NewProtocol: allowed values: TCP, UDP
3890 -//
3891 -//
3892 -func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) {
3893 - // Request structure.
3894 - request := &struct {
3895 - NewRemoteHost string
3896 -
3897 - NewExternalPort string
3898 -
3899 - NewProtocol string
3900 - }{}
3901 - // BEGIN Marshal arguments into request.
3902 -
3903 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
3904 - return
3905 - }
3906 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
3907 - return
3908 - }
3909 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3910 - return
3911 - }
3912 - // END Marshal arguments into request.
3913 -
3914 - // Response structure.
3915 - response := interface{}(nil)
3916 -
3917 - // Perform the SOAP call.
3918 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "DeletePortMapping", request, response); err != nil {
3919 - return
3920 - }
3921 -
3922 - // BEGIN Unmarshal arguments from response.
3923 -
3924 - // END Unmarshal arguments from response.
3925 - return
3926 -}
3927 -
3928 -//
3929 -//
3930 -// Return values:
3931 -//
3932 -// * NewExternalIPAddress:
3933 -func (client *WANPPPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) {
3934 - // Request structure.
3935 - request := interface{}(nil)
3936 - // BEGIN Marshal arguments into request.
3937 -
3938 - // END Marshal arguments into request.
3939 -
3940 - // Response structure.
3941 - response := &struct {
3942 - NewExternalIPAddress string
3943 - }{}
3944 -
3945 - // Perform the SOAP call.
3946 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetExternalIPAddress", request, response); err != nil {
3947 - return
3948 - }
3949 -
3950 - // BEGIN Unmarshal arguments from response.
3951 -
3952 - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil {
3953 - return
3954 - }
3955 - // END Unmarshal arguments from response.
3956 - return
3957 -}
Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go deleted
-5271
@@ -1,5271 +0,0 @@
1 -// Client for UPnP Device Control Protocol Internet Gateway Device v2.
2 -//
3 -// This DCP is documented in detail at: http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf
4 -//
5 -// Typically, use one of the New* functions to discover services on the local
6 -// network.
7 -package internetgateway2
8 -
9 -// Generated file - do not edit by hand. See README.md
10 -
11 -import (
12 - "time"
13 -
14 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp"
15 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/soap"
16 -)
17 -
18 -// Hack to avoid Go complaining if time isn't used.
19 -var _ time.Time
20 -
21 -// Device URNs:
22 -const (
23 - URN_LANDevice_1 = "urn:schemas-upnp-org:device:LANDevice:1"
24 - URN_WANConnectionDevice_1 = "urn:schemas-upnp-org:device:WANConnectionDevice:1"
25 - URN_WANConnectionDevice_2 = "urn:schemas-upnp-org:device:WANConnectionDevice:2"
26 - URN_WANDevice_1 = "urn:schemas-upnp-org:device:WANDevice:1"
27 - URN_WANDevice_2 = "urn:schemas-upnp-org:device:WANDevice:2"
28 -)
29 -
30 -// Service URNs:
31 -const (
32 - URN_LANHostConfigManagement_1 = "urn:schemas-upnp-org:service:LANHostConfigManagement:1"
33 - URN_Layer3Forwarding_1 = "urn:schemas-upnp-org:service:Layer3Forwarding:1"
34 - URN_WANCableLinkConfig_1 = "urn:schemas-upnp-org:service:WANCableLinkConfig:1"
35 - URN_WANCommonInterfaceConfig_1 = "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"
36 - URN_WANDSLLinkConfig_1 = "urn:schemas-upnp-org:service:WANDSLLinkConfig:1"
37 - URN_WANEthernetLinkConfig_1 = "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1"
38 - URN_WANIPConnection_1 = "urn:schemas-upnp-org:service:WANIPConnection:1"
39 - URN_WANIPConnection_2 = "urn:schemas-upnp-org:service:WANIPConnection:2"
40 - URN_WANIPv6FirewallControl_1 = "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"
41 - URN_WANPOTSLinkConfig_1 = "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1"
42 - URN_WANPPPConnection_1 = "urn:schemas-upnp-org:service:WANPPPConnection:1"
43 -)
44 -
45 -// LANHostConfigManagement1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:LANHostConfigManagement:1". See
46 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
47 -// are provided for informational value.
48 -type LANHostConfigManagement1 struct {
49 - goupnp.ServiceClient
50 -}
51 -
52 -// NewLANHostConfigManagement1Clients discovers instances of the service on the network,
53 -// and returns clients to any that are found. errors will contain an error for
54 -// any devices that replied but which could not be queried, and err will be set
55 -// if the discovery process failed outright.
56 -//
57 -// This is a typical entry calling point into this package.
58 -func NewLANHostConfigManagement1Clients() (clients []*LANHostConfigManagement1, errors []error, err error) {
59 - var genericClients []goupnp.ServiceClient
60 - if genericClients, errors, err = goupnp.NewServiceClients(URN_LANHostConfigManagement_1); err != nil {
61 - return
62 - }
63 - clients = make([]*LANHostConfigManagement1, len(genericClients))
64 - for i := range genericClients {
65 - clients[i] = &LANHostConfigManagement1{genericClients[i]}
66 - }
67 - return
68 -}
69 -
70 -// Arguments:
71 -//
72 -// * NewDHCPServerConfigurable:
73 -//
74 -//
75 -func (client *LANHostConfigManagement1) SetDHCPServerConfigurable(NewDHCPServerConfigurable bool) (err error) {
76 - // Request structure.
77 - request := &struct {
78 - NewDHCPServerConfigurable string
79 - }{}
80 - // BEGIN Marshal arguments into request.
81 -
82 - if request.NewDHCPServerConfigurable, err = soap.MarshalBoolean(NewDHCPServerConfigurable); err != nil {
83 - return
84 - }
85 - // END Marshal arguments into request.
86 -
87 - // Response structure.
88 - response := interface{}(nil)
89 -
90 - // Perform the SOAP call.
91 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPServerConfigurable", request, response); err != nil {
92 - return
93 - }
94 -
95 - // BEGIN Unmarshal arguments from response.
96 -
97 - // END Unmarshal arguments from response.
98 - return
99 -}
100 -
101 -//
102 -//
103 -// Return values:
104 -//
105 -// * NewDHCPServerConfigurable:
106 -func (client *LANHostConfigManagement1) GetDHCPServerConfigurable() (NewDHCPServerConfigurable bool, err error) {
107 - // Request structure.
108 - request := interface{}(nil)
109 - // BEGIN Marshal arguments into request.
110 -
111 - // END Marshal arguments into request.
112 -
113 - // Response structure.
114 - response := &struct {
115 - NewDHCPServerConfigurable string
116 - }{}
117 -
118 - // Perform the SOAP call.
119 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPServerConfigurable", request, response); err != nil {
120 - return
121 - }
122 -
123 - // BEGIN Unmarshal arguments from response.
124 -
125 - if NewDHCPServerConfigurable, err = soap.UnmarshalBoolean(response.NewDHCPServerConfigurable); err != nil {
126 - return
127 - }
128 - // END Unmarshal arguments from response.
129 - return
130 -}
131 -
132 -// Arguments:
133 -//
134 -// * NewDHCPRelay:
135 -//
136 -//
137 -func (client *LANHostConfigManagement1) SetDHCPRelay(NewDHCPRelay bool) (err error) {
138 - // Request structure.
139 - request := &struct {
140 - NewDHCPRelay string
141 - }{}
142 - // BEGIN Marshal arguments into request.
143 -
144 - if request.NewDHCPRelay, err = soap.MarshalBoolean(NewDHCPRelay); err != nil {
145 - return
146 - }
147 - // END Marshal arguments into request.
148 -
149 - // Response structure.
150 - response := interface{}(nil)
151 -
152 - // Perform the SOAP call.
153 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDHCPRelay", request, response); err != nil {
154 - return
155 - }
156 -
157 - // BEGIN Unmarshal arguments from response.
158 -
159 - // END Unmarshal arguments from response.
160 - return
161 -}
162 -
163 -//
164 -//
165 -// Return values:
166 -//
167 -// * NewDHCPRelay:
168 -func (client *LANHostConfigManagement1) GetDHCPRelay() (NewDHCPRelay bool, err error) {
169 - // Request structure.
170 - request := interface{}(nil)
171 - // BEGIN Marshal arguments into request.
172 -
173 - // END Marshal arguments into request.
174 -
175 - // Response structure.
176 - response := &struct {
177 - NewDHCPRelay string
178 - }{}
179 -
180 - // Perform the SOAP call.
181 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDHCPRelay", request, response); err != nil {
182 - return
183 - }
184 -
185 - // BEGIN Unmarshal arguments from response.
186 -
187 - if NewDHCPRelay, err = soap.UnmarshalBoolean(response.NewDHCPRelay); err != nil {
188 - return
189 - }
190 - // END Unmarshal arguments from response.
191 - return
192 -}
193 -
194 -// Arguments:
195 -//
196 -// * NewSubnetMask:
197 -//
198 -//
199 -func (client *LANHostConfigManagement1) SetSubnetMask(NewSubnetMask string) (err error) {
200 - // Request structure.
201 - request := &struct {
202 - NewSubnetMask string
203 - }{}
204 - // BEGIN Marshal arguments into request.
205 -
206 - if request.NewSubnetMask, err = soap.MarshalString(NewSubnetMask); err != nil {
207 - return
208 - }
209 - // END Marshal arguments into request.
210 -
211 - // Response structure.
212 - response := interface{}(nil)
213 -
214 - // Perform the SOAP call.
215 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetSubnetMask", request, response); err != nil {
216 - return
217 - }
218 -
219 - // BEGIN Unmarshal arguments from response.
220 -
221 - // END Unmarshal arguments from response.
222 - return
223 -}
224 -
225 -//
226 -//
227 -// Return values:
228 -//
229 -// * NewSubnetMask:
230 -func (client *LANHostConfigManagement1) GetSubnetMask() (NewSubnetMask string, err error) {
231 - // Request structure.
232 - request := interface{}(nil)
233 - // BEGIN Marshal arguments into request.
234 -
235 - // END Marshal arguments into request.
236 -
237 - // Response structure.
238 - response := &struct {
239 - NewSubnetMask string
240 - }{}
241 -
242 - // Perform the SOAP call.
243 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetSubnetMask", request, response); err != nil {
244 - return
245 - }
246 -
247 - // BEGIN Unmarshal arguments from response.
248 -
249 - if NewSubnetMask, err = soap.UnmarshalString(response.NewSubnetMask); err != nil {
250 - return
251 - }
252 - // END Unmarshal arguments from response.
253 - return
254 -}
255 -
256 -// Arguments:
257 -//
258 -// * NewIPRouters:
259 -//
260 -//
261 -func (client *LANHostConfigManagement1) SetIPRouter(NewIPRouters string) (err error) {
262 - // Request structure.
263 - request := &struct {
264 - NewIPRouters string
265 - }{}
266 - // BEGIN Marshal arguments into request.
267 -
268 - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil {
269 - return
270 - }
271 - // END Marshal arguments into request.
272 -
273 - // Response structure.
274 - response := interface{}(nil)
275 -
276 - // Perform the SOAP call.
277 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetIPRouter", request, response); err != nil {
278 - return
279 - }
280 -
281 - // BEGIN Unmarshal arguments from response.
282 -
283 - // END Unmarshal arguments from response.
284 - return
285 -}
286 -
287 -// Arguments:
288 -//
289 -// * NewIPRouters:
290 -//
291 -//
292 -func (client *LANHostConfigManagement1) DeleteIPRouter(NewIPRouters string) (err error) {
293 - // Request structure.
294 - request := &struct {
295 - NewIPRouters string
296 - }{}
297 - // BEGIN Marshal arguments into request.
298 -
299 - if request.NewIPRouters, err = soap.MarshalString(NewIPRouters); err != nil {
300 - return
301 - }
302 - // END Marshal arguments into request.
303 -
304 - // Response structure.
305 - response := interface{}(nil)
306 -
307 - // Perform the SOAP call.
308 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteIPRouter", request, response); err != nil {
309 - return
310 - }
311 -
312 - // BEGIN Unmarshal arguments from response.
313 -
314 - // END Unmarshal arguments from response.
315 - return
316 -}
317 -
318 -//
319 -//
320 -// Return values:
321 -//
322 -// * NewIPRouters:
323 -func (client *LANHostConfigManagement1) GetIPRoutersList() (NewIPRouters string, err error) {
324 - // Request structure.
325 - request := interface{}(nil)
326 - // BEGIN Marshal arguments into request.
327 -
328 - // END Marshal arguments into request.
329 -
330 - // Response structure.
331 - response := &struct {
332 - NewIPRouters string
333 - }{}
334 -
335 - // Perform the SOAP call.
336 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetIPRoutersList", request, response); err != nil {
337 - return
338 - }
339 -
340 - // BEGIN Unmarshal arguments from response.
341 -
342 - if NewIPRouters, err = soap.UnmarshalString(response.NewIPRouters); err != nil {
343 - return
344 - }
345 - // END Unmarshal arguments from response.
346 - return
347 -}
348 -
349 -// Arguments:
350 -//
351 -// * NewDomainName:
352 -//
353 -//
354 -func (client *LANHostConfigManagement1) SetDomainName(NewDomainName string) (err error) {
355 - // Request structure.
356 - request := &struct {
357 - NewDomainName string
358 - }{}
359 - // BEGIN Marshal arguments into request.
360 -
361 - if request.NewDomainName, err = soap.MarshalString(NewDomainName); err != nil {
362 - return
363 - }
364 - // END Marshal arguments into request.
365 -
366 - // Response structure.
367 - response := interface{}(nil)
368 -
369 - // Perform the SOAP call.
370 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDomainName", request, response); err != nil {
371 - return
372 - }
373 -
374 - // BEGIN Unmarshal arguments from response.
375 -
376 - // END Unmarshal arguments from response.
377 - return
378 -}
379 -
380 -//
381 -//
382 -// Return values:
383 -//
384 -// * NewDomainName:
385 -func (client *LANHostConfigManagement1) GetDomainName() (NewDomainName string, err error) {
386 - // Request structure.
387 - request := interface{}(nil)
388 - // BEGIN Marshal arguments into request.
389 -
390 - // END Marshal arguments into request.
391 -
392 - // Response structure.
393 - response := &struct {
394 - NewDomainName string
395 - }{}
396 -
397 - // Perform the SOAP call.
398 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDomainName", request, response); err != nil {
399 - return
400 - }
401 -
402 - // BEGIN Unmarshal arguments from response.
403 -
404 - if NewDomainName, err = soap.UnmarshalString(response.NewDomainName); err != nil {
405 - return
406 - }
407 - // END Unmarshal arguments from response.
408 - return
409 -}
410 -
411 -// Arguments:
412 -//
413 -// * NewMinAddress:
414 -//
415 -// * NewMaxAddress:
416 -//
417 -//
418 -func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, NewMaxAddress string) (err error) {
419 - // Request structure.
420 - request := &struct {
421 - NewMinAddress string
422 -
423 - NewMaxAddress string
424 - }{}
425 - // BEGIN Marshal arguments into request.
426 -
427 - if request.NewMinAddress, err = soap.MarshalString(NewMinAddress); err != nil {
428 - return
429 - }
430 - if request.NewMaxAddress, err = soap.MarshalString(NewMaxAddress); err != nil {
431 - return
432 - }
433 - // END Marshal arguments into request.
434 -
435 - // Response structure.
436 - response := interface{}(nil)
437 -
438 - // Perform the SOAP call.
439 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetAddressRange", request, response); err != nil {
440 - return
441 - }
442 -
443 - // BEGIN Unmarshal arguments from response.
444 -
445 - // END Unmarshal arguments from response.
446 - return
447 -}
448 -
449 -//
450 -//
451 -// Return values:
452 -//
453 -// * NewMinAddress:
454 -//
455 -// * NewMaxAddress:
456 -func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, NewMaxAddress string, err error) {
457 - // Request structure.
458 - request := interface{}(nil)
459 - // BEGIN Marshal arguments into request.
460 -
461 - // END Marshal arguments into request.
462 -
463 - // Response structure.
464 - response := &struct {
465 - NewMinAddress string
466 -
467 - NewMaxAddress string
468 - }{}
469 -
470 - // Perform the SOAP call.
471 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetAddressRange", request, response); err != nil {
472 - return
473 - }
474 -
475 - // BEGIN Unmarshal arguments from response.
476 -
477 - if NewMinAddress, err = soap.UnmarshalString(response.NewMinAddress); err != nil {
478 - return
479 - }
480 - if NewMaxAddress, err = soap.UnmarshalString(response.NewMaxAddress); err != nil {
481 - return
482 - }
483 - // END Unmarshal arguments from response.
484 - return
485 -}
486 -
487 -// Arguments:
488 -//
489 -// * NewReservedAddresses:
490 -//
491 -//
492 -func (client *LANHostConfigManagement1) SetReservedAddress(NewReservedAddresses string) (err error) {
493 - // Request structure.
494 - request := &struct {
495 - NewReservedAddresses string
496 - }{}
497 - // BEGIN Marshal arguments into request.
498 -
499 - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil {
500 - return
501 - }
502 - // END Marshal arguments into request.
503 -
504 - // Response structure.
505 - response := interface{}(nil)
506 -
507 - // Perform the SOAP call.
508 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetReservedAddress", request, response); err != nil {
509 - return
510 - }
511 -
512 - // BEGIN Unmarshal arguments from response.
513 -
514 - // END Unmarshal arguments from response.
515 - return
516 -}
517 -
518 -// Arguments:
519 -//
520 -// * NewReservedAddresses:
521 -//
522 -//
523 -func (client *LANHostConfigManagement1) DeleteReservedAddress(NewReservedAddresses string) (err error) {
524 - // Request structure.
525 - request := &struct {
526 - NewReservedAddresses string
527 - }{}
528 - // BEGIN Marshal arguments into request.
529 -
530 - if request.NewReservedAddresses, err = soap.MarshalString(NewReservedAddresses); err != nil {
531 - return
532 - }
533 - // END Marshal arguments into request.
534 -
535 - // Response structure.
536 - response := interface{}(nil)
537 -
538 - // Perform the SOAP call.
539 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteReservedAddress", request, response); err != nil {
540 - return
541 - }
542 -
543 - // BEGIN Unmarshal arguments from response.
544 -
545 - // END Unmarshal arguments from response.
546 - return
547 -}
548 -
549 -//
550 -//
551 -// Return values:
552 -//
553 -// * NewReservedAddresses:
554 -func (client *LANHostConfigManagement1) GetReservedAddresses() (NewReservedAddresses string, err error) {
555 - // Request structure.
556 - request := interface{}(nil)
557 - // BEGIN Marshal arguments into request.
558 -
559 - // END Marshal arguments into request.
560 -
561 - // Response structure.
562 - response := &struct {
563 - NewReservedAddresses string
564 - }{}
565 -
566 - // Perform the SOAP call.
567 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetReservedAddresses", request, response); err != nil {
568 - return
569 - }
570 -
571 - // BEGIN Unmarshal arguments from response.
572 -
573 - if NewReservedAddresses, err = soap.UnmarshalString(response.NewReservedAddresses); err != nil {
574 - return
575 - }
576 - // END Unmarshal arguments from response.
577 - return
578 -}
579 -
580 -// Arguments:
581 -//
582 -// * NewDNSServers:
583 -//
584 -//
585 -func (client *LANHostConfigManagement1) SetDNSServer(NewDNSServers string) (err error) {
586 - // Request structure.
587 - request := &struct {
588 - NewDNSServers string
589 - }{}
590 - // BEGIN Marshal arguments into request.
591 -
592 - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil {
593 - return
594 - }
595 - // END Marshal arguments into request.
596 -
597 - // Response structure.
598 - response := interface{}(nil)
599 -
600 - // Perform the SOAP call.
601 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "SetDNSServer", request, response); err != nil {
602 - return
603 - }
604 -
605 - // BEGIN Unmarshal arguments from response.
606 -
607 - // END Unmarshal arguments from response.
608 - return
609 -}
610 -
611 -// Arguments:
612 -//
613 -// * NewDNSServers:
614 -//
615 -//
616 -func (client *LANHostConfigManagement1) DeleteDNSServer(NewDNSServers string) (err error) {
617 - // Request structure.
618 - request := &struct {
619 - NewDNSServers string
620 - }{}
621 - // BEGIN Marshal arguments into request.
622 -
623 - if request.NewDNSServers, err = soap.MarshalString(NewDNSServers); err != nil {
624 - return
625 - }
626 - // END Marshal arguments into request.
627 -
628 - // Response structure.
629 - response := interface{}(nil)
630 -
631 - // Perform the SOAP call.
632 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "DeleteDNSServer", request, response); err != nil {
633 - return
634 - }
635 -
636 - // BEGIN Unmarshal arguments from response.
637 -
638 - // END Unmarshal arguments from response.
639 - return
640 -}
641 -
642 -//
643 -//
644 -// Return values:
645 -//
646 -// * NewDNSServers:
647 -func (client *LANHostConfigManagement1) GetDNSServers() (NewDNSServers string, err error) {
648 - // Request structure.
649 - request := interface{}(nil)
650 - // BEGIN Marshal arguments into request.
651 -
652 - // END Marshal arguments into request.
653 -
654 - // Response structure.
655 - response := &struct {
656 - NewDNSServers string
657 - }{}
658 -
659 - // Perform the SOAP call.
660 - if err = client.SOAPClient.PerformAction(URN_LANHostConfigManagement_1, "GetDNSServers", request, response); err != nil {
661 - return
662 - }
663 -
664 - // BEGIN Unmarshal arguments from response.
665 -
666 - if NewDNSServers, err = soap.UnmarshalString(response.NewDNSServers); err != nil {
667 - return
668 - }
669 - // END Unmarshal arguments from response.
670 - return
671 -}
672 -
673 -// Layer3Forwarding1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:Layer3Forwarding:1". See
674 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
675 -// are provided for informational value.
676 -type Layer3Forwarding1 struct {
677 - goupnp.ServiceClient
678 -}
679 -
680 -// NewLayer3Forwarding1Clients discovers instances of the service on the network,
681 -// and returns clients to any that are found. errors will contain an error for
682 -// any devices that replied but which could not be queried, and err will be set
683 -// if the discovery process failed outright.
684 -//
685 -// This is a typical entry calling point into this package.
686 -func NewLayer3Forwarding1Clients() (clients []*Layer3Forwarding1, errors []error, err error) {
687 - var genericClients []goupnp.ServiceClient
688 - if genericClients, errors, err = goupnp.NewServiceClients(URN_Layer3Forwarding_1); err != nil {
689 - return
690 - }
691 - clients = make([]*Layer3Forwarding1, len(genericClients))
692 - for i := range genericClients {
693 - clients[i] = &Layer3Forwarding1{genericClients[i]}
694 - }
695 - return
696 -}
697 -
698 -// Arguments:
699 -//
700 -// * NewDefaultConnectionService:
701 -//
702 -//
703 -func (client *Layer3Forwarding1) SetDefaultConnectionService(NewDefaultConnectionService string) (err error) {
704 - // Request structure.
705 - request := &struct {
706 - NewDefaultConnectionService string
707 - }{}
708 - // BEGIN Marshal arguments into request.
709 -
710 - if request.NewDefaultConnectionService, err = soap.MarshalString(NewDefaultConnectionService); err != nil {
711 - return
712 - }
713 - // END Marshal arguments into request.
714 -
715 - // Response structure.
716 - response := interface{}(nil)
717 -
718 - // Perform the SOAP call.
719 - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "SetDefaultConnectionService", request, response); err != nil {
720 - return
721 - }
722 -
723 - // BEGIN Unmarshal arguments from response.
724 -
725 - // END Unmarshal arguments from response.
726 - return
727 -}
728 -
729 -//
730 -//
731 -// Return values:
732 -//
733 -// * NewDefaultConnectionService:
734 -func (client *Layer3Forwarding1) GetDefaultConnectionService() (NewDefaultConnectionService string, err error) {
735 - // Request structure.
736 - request := interface{}(nil)
737 - // BEGIN Marshal arguments into request.
738 -
739 - // END Marshal arguments into request.
740 -
741 - // Response structure.
742 - response := &struct {
743 - NewDefaultConnectionService string
744 - }{}
745 -
746 - // Perform the SOAP call.
747 - if err = client.SOAPClient.PerformAction(URN_Layer3Forwarding_1, "GetDefaultConnectionService", request, response); err != nil {
748 - return
749 - }
750 -
751 - // BEGIN Unmarshal arguments from response.
752 -
753 - if NewDefaultConnectionService, err = soap.UnmarshalString(response.NewDefaultConnectionService); err != nil {
754 - return
755 - }
756 - // END Unmarshal arguments from response.
757 - return
758 -}
759 -
760 -// WANCableLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCableLinkConfig:1". See
761 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
762 -// are provided for informational value.
763 -type WANCableLinkConfig1 struct {
764 - goupnp.ServiceClient
765 -}
766 -
767 -// NewWANCableLinkConfig1Clients discovers instances of the service on the network,
768 -// and returns clients to any that are found. errors will contain an error for
769 -// any devices that replied but which could not be queried, and err will be set
770 -// if the discovery process failed outright.
771 -//
772 -// This is a typical entry calling point into this package.
773 -func NewWANCableLinkConfig1Clients() (clients []*WANCableLinkConfig1, errors []error, err error) {
774 - var genericClients []goupnp.ServiceClient
775 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCableLinkConfig_1); err != nil {
776 - return
777 - }
778 - clients = make([]*WANCableLinkConfig1, len(genericClients))
779 - for i := range genericClients {
780 - clients[i] = &WANCableLinkConfig1{genericClients[i]}
781 - }
782 - return
783 -}
784 -
785 -//
786 -//
787 -// Return values:
788 -//
789 -// * NewCableLinkConfigState: allowed values: notReady, dsSyncComplete, usParamAcquired, rangingComplete, ipComplete, todEstablished, paramTransferComplete, registrationComplete, operational, accessDenied
790 -//
791 -// * NewLinkType: allowed values: Ethernet
792 -func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigState string, NewLinkType string, err error) {
793 - // Request structure.
794 - request := interface{}(nil)
795 - // BEGIN Marshal arguments into request.
796 -
797 - // END Marshal arguments into request.
798 -
799 - // Response structure.
800 - response := &struct {
801 - NewCableLinkConfigState string
802 -
803 - NewLinkType string
804 - }{}
805 -
806 - // Perform the SOAP call.
807 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetCableLinkConfigInfo", request, response); err != nil {
808 - return
809 - }
810 -
811 - // BEGIN Unmarshal arguments from response.
812 -
813 - if NewCableLinkConfigState, err = soap.UnmarshalString(response.NewCableLinkConfigState); err != nil {
814 - return
815 - }
816 - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil {
817 - return
818 - }
819 - // END Unmarshal arguments from response.
820 - return
821 -}
822 -
823 -//
824 -//
825 -// Return values:
826 -//
827 -// * NewDownstreamFrequency:
828 -func (client *WANCableLinkConfig1) GetDownstreamFrequency() (NewDownstreamFrequency uint32, err error) {
829 - // Request structure.
830 - request := interface{}(nil)
831 - // BEGIN Marshal arguments into request.
832 -
833 - // END Marshal arguments into request.
834 -
835 - // Response structure.
836 - response := &struct {
837 - NewDownstreamFrequency string
838 - }{}
839 -
840 - // Perform the SOAP call.
841 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamFrequency", request, response); err != nil {
842 - return
843 - }
844 -
845 - // BEGIN Unmarshal arguments from response.
846 -
847 - if NewDownstreamFrequency, err = soap.UnmarshalUi4(response.NewDownstreamFrequency); err != nil {
848 - return
849 - }
850 - // END Unmarshal arguments from response.
851 - return
852 -}
853 -
854 -//
855 -//
856 -// Return values:
857 -//
858 -// * NewDownstreamModulation: allowed values: 64QAM, 256QAM
859 -func (client *WANCableLinkConfig1) GetDownstreamModulation() (NewDownstreamModulation string, err error) {
860 - // Request structure.
861 - request := interface{}(nil)
862 - // BEGIN Marshal arguments into request.
863 -
864 - // END Marshal arguments into request.
865 -
866 - // Response structure.
867 - response := &struct {
868 - NewDownstreamModulation string
869 - }{}
870 -
871 - // Perform the SOAP call.
872 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetDownstreamModulation", request, response); err != nil {
873 - return
874 - }
875 -
876 - // BEGIN Unmarshal arguments from response.
877 -
878 - if NewDownstreamModulation, err = soap.UnmarshalString(response.NewDownstreamModulation); err != nil {
879 - return
880 - }
881 - // END Unmarshal arguments from response.
882 - return
883 -}
884 -
885 -//
886 -//
887 -// Return values:
888 -//
889 -// * NewUpstreamFrequency:
890 -func (client *WANCableLinkConfig1) GetUpstreamFrequency() (NewUpstreamFrequency uint32, err error) {
891 - // Request structure.
892 - request := interface{}(nil)
893 - // BEGIN Marshal arguments into request.
894 -
895 - // END Marshal arguments into request.
896 -
897 - // Response structure.
898 - response := &struct {
899 - NewUpstreamFrequency string
900 - }{}
901 -
902 - // Perform the SOAP call.
903 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamFrequency", request, response); err != nil {
904 - return
905 - }
906 -
907 - // BEGIN Unmarshal arguments from response.
908 -
909 - if NewUpstreamFrequency, err = soap.UnmarshalUi4(response.NewUpstreamFrequency); err != nil {
910 - return
911 - }
912 - // END Unmarshal arguments from response.
913 - return
914 -}
915 -
916 -//
917 -//
918 -// Return values:
919 -//
920 -// * NewUpstreamModulation: allowed values: QPSK, 16QAM
921 -func (client *WANCableLinkConfig1) GetUpstreamModulation() (NewUpstreamModulation string, err error) {
922 - // Request structure.
923 - request := interface{}(nil)
924 - // BEGIN Marshal arguments into request.
925 -
926 - // END Marshal arguments into request.
927 -
928 - // Response structure.
929 - response := &struct {
930 - NewUpstreamModulation string
931 - }{}
932 -
933 - // Perform the SOAP call.
934 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamModulation", request, response); err != nil {
935 - return
936 - }
937 -
938 - // BEGIN Unmarshal arguments from response.
939 -
940 - if NewUpstreamModulation, err = soap.UnmarshalString(response.NewUpstreamModulation); err != nil {
941 - return
942 - }
943 - // END Unmarshal arguments from response.
944 - return
945 -}
946 -
947 -//
948 -//
949 -// Return values:
950 -//
951 -// * NewUpstreamChannelID:
952 -func (client *WANCableLinkConfig1) GetUpstreamChannelID() (NewUpstreamChannelID uint32, err error) {
953 - // Request structure.
954 - request := interface{}(nil)
955 - // BEGIN Marshal arguments into request.
956 -
957 - // END Marshal arguments into request.
958 -
959 - // Response structure.
960 - response := &struct {
961 - NewUpstreamChannelID string
962 - }{}
963 -
964 - // Perform the SOAP call.
965 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamChannelID", request, response); err != nil {
966 - return
967 - }
968 -
969 - // BEGIN Unmarshal arguments from response.
970 -
971 - if NewUpstreamChannelID, err = soap.UnmarshalUi4(response.NewUpstreamChannelID); err != nil {
972 - return
973 - }
974 - // END Unmarshal arguments from response.
975 - return
976 -}
977 -
978 -//
979 -//
980 -// Return values:
981 -//
982 -// * NewUpstreamPowerLevel:
983 -func (client *WANCableLinkConfig1) GetUpstreamPowerLevel() (NewUpstreamPowerLevel uint32, err error) {
984 - // Request structure.
985 - request := interface{}(nil)
986 - // BEGIN Marshal arguments into request.
987 -
988 - // END Marshal arguments into request.
989 -
990 - // Response structure.
991 - response := &struct {
992 - NewUpstreamPowerLevel string
993 - }{}
994 -
995 - // Perform the SOAP call.
996 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetUpstreamPowerLevel", request, response); err != nil {
997 - return
998 - }
999 -
1000 - // BEGIN Unmarshal arguments from response.
1001 -
1002 - if NewUpstreamPowerLevel, err = soap.UnmarshalUi4(response.NewUpstreamPowerLevel); err != nil {
1003 - return
1004 - }
1005 - // END Unmarshal arguments from response.
1006 - return
1007 -}
1008 -
1009 -//
1010 -//
1011 -// Return values:
1012 -//
1013 -// * NewBPIEncryptionEnabled:
1014 -func (client *WANCableLinkConfig1) GetBPIEncryptionEnabled() (NewBPIEncryptionEnabled bool, err error) {
1015 - // Request structure.
1016 - request := interface{}(nil)
1017 - // BEGIN Marshal arguments into request.
1018 -
1019 - // END Marshal arguments into request.
1020 -
1021 - // Response structure.
1022 - response := &struct {
1023 - NewBPIEncryptionEnabled string
1024 - }{}
1025 -
1026 - // Perform the SOAP call.
1027 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetBPIEncryptionEnabled", request, response); err != nil {
1028 - return
1029 - }
1030 -
1031 - // BEGIN Unmarshal arguments from response.
1032 -
1033 - if NewBPIEncryptionEnabled, err = soap.UnmarshalBoolean(response.NewBPIEncryptionEnabled); err != nil {
1034 - return
1035 - }
1036 - // END Unmarshal arguments from response.
1037 - return
1038 -}
1039 -
1040 -//
1041 -//
1042 -// Return values:
1043 -//
1044 -// * NewConfigFile:
1045 -func (client *WANCableLinkConfig1) GetConfigFile() (NewConfigFile string, err error) {
1046 - // Request structure.
1047 - request := interface{}(nil)
1048 - // BEGIN Marshal arguments into request.
1049 -
1050 - // END Marshal arguments into request.
1051 -
1052 - // Response structure.
1053 - response := &struct {
1054 - NewConfigFile string
1055 - }{}
1056 -
1057 - // Perform the SOAP call.
1058 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetConfigFile", request, response); err != nil {
1059 - return
1060 - }
1061 -
1062 - // BEGIN Unmarshal arguments from response.
1063 -
1064 - if NewConfigFile, err = soap.UnmarshalString(response.NewConfigFile); err != nil {
1065 - return
1066 - }
1067 - // END Unmarshal arguments from response.
1068 - return
1069 -}
1070 -
1071 -//
1072 -//
1073 -// Return values:
1074 -//
1075 -// * NewTFTPServer:
1076 -func (client *WANCableLinkConfig1) GetTFTPServer() (NewTFTPServer string, err error) {
1077 - // Request structure.
1078 - request := interface{}(nil)
1079 - // BEGIN Marshal arguments into request.
1080 -
1081 - // END Marshal arguments into request.
1082 -
1083 - // Response structure.
1084 - response := &struct {
1085 - NewTFTPServer string
1086 - }{}
1087 -
1088 - // Perform the SOAP call.
1089 - if err = client.SOAPClient.PerformAction(URN_WANCableLinkConfig_1, "GetTFTPServer", request, response); err != nil {
1090 - return
1091 - }
1092 -
1093 - // BEGIN Unmarshal arguments from response.
1094 -
1095 - if NewTFTPServer, err = soap.UnmarshalString(response.NewTFTPServer); err != nil {
1096 - return
1097 - }
1098 - // END Unmarshal arguments from response.
1099 - return
1100 -}
1101 -
1102 -// WANCommonInterfaceConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1". See
1103 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1104 -// are provided for informational value.
1105 -type WANCommonInterfaceConfig1 struct {
1106 - goupnp.ServiceClient
1107 -}
1108 -
1109 -// NewWANCommonInterfaceConfig1Clients discovers instances of the service on the network,
1110 -// and returns clients to any that are found. errors will contain an error for
1111 -// any devices that replied but which could not be queried, and err will be set
1112 -// if the discovery process failed outright.
1113 -//
1114 -// This is a typical entry calling point into this package.
1115 -func NewWANCommonInterfaceConfig1Clients() (clients []*WANCommonInterfaceConfig1, errors []error, err error) {
1116 - var genericClients []goupnp.ServiceClient
1117 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANCommonInterfaceConfig_1); err != nil {
1118 - return
1119 - }
1120 - clients = make([]*WANCommonInterfaceConfig1, len(genericClients))
1121 - for i := range genericClients {
1122 - clients[i] = &WANCommonInterfaceConfig1{genericClients[i]}
1123 - }
1124 - return
1125 -}
1126 -
1127 -// Arguments:
1128 -//
1129 -// * NewEnabledForInternet:
1130 -//
1131 -//
1132 -func (client *WANCommonInterfaceConfig1) SetEnabledForInternet(NewEnabledForInternet bool) (err error) {
1133 - // Request structure.
1134 - request := &struct {
1135 - NewEnabledForInternet string
1136 - }{}
1137 - // BEGIN Marshal arguments into request.
1138 -
1139 - if request.NewEnabledForInternet, err = soap.MarshalBoolean(NewEnabledForInternet); err != nil {
1140 - return
1141 - }
1142 - // END Marshal arguments into request.
1143 -
1144 - // Response structure.
1145 - response := interface{}(nil)
1146 -
1147 - // Perform the SOAP call.
1148 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "SetEnabledForInternet", request, response); err != nil {
1149 - return
1150 - }
1151 -
1152 - // BEGIN Unmarshal arguments from response.
1153 -
1154 - // END Unmarshal arguments from response.
1155 - return
1156 -}
1157 -
1158 -//
1159 -//
1160 -// Return values:
1161 -//
1162 -// * NewEnabledForInternet:
1163 -func (client *WANCommonInterfaceConfig1) GetEnabledForInternet() (NewEnabledForInternet bool, err error) {
1164 - // Request structure.
1165 - request := interface{}(nil)
1166 - // BEGIN Marshal arguments into request.
1167 -
1168 - // END Marshal arguments into request.
1169 -
1170 - // Response structure.
1171 - response := &struct {
1172 - NewEnabledForInternet string
1173 - }{}
1174 -
1175 - // Perform the SOAP call.
1176 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetEnabledForInternet", request, response); err != nil {
1177 - return
1178 - }
1179 -
1180 - // BEGIN Unmarshal arguments from response.
1181 -
1182 - if NewEnabledForInternet, err = soap.UnmarshalBoolean(response.NewEnabledForInternet); err != nil {
1183 - return
1184 - }
1185 - // END Unmarshal arguments from response.
1186 - return
1187 -}
1188 -
1189 -//
1190 -//
1191 -// Return values:
1192 -//
1193 -// * NewWANAccessType: allowed values: DSL, POTS, Cable, Ethernet
1194 -//
1195 -// * NewLayer1UpstreamMaxBitRate:
1196 -//
1197 -// * NewLayer1DownstreamMaxBitRate:
1198 -//
1199 -// * NewPhysicalLinkStatus: allowed values: Up, Down
1200 -func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccessType string, NewLayer1UpstreamMaxBitRate uint32, NewLayer1DownstreamMaxBitRate uint32, NewPhysicalLinkStatus string, err error) {
1201 - // Request structure.
1202 - request := interface{}(nil)
1203 - // BEGIN Marshal arguments into request.
1204 -
1205 - // END Marshal arguments into request.
1206 -
1207 - // Response structure.
1208 - response := &struct {
1209 - NewWANAccessType string
1210 -
1211 - NewLayer1UpstreamMaxBitRate string
1212 -
1213 - NewLayer1DownstreamMaxBitRate string
1214 -
1215 - NewPhysicalLinkStatus string
1216 - }{}
1217 -
1218 - // Perform the SOAP call.
1219 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetCommonLinkProperties", request, response); err != nil {
1220 - return
1221 - }
1222 -
1223 - // BEGIN Unmarshal arguments from response.
1224 -
1225 - if NewWANAccessType, err = soap.UnmarshalString(response.NewWANAccessType); err != nil {
1226 - return
1227 - }
1228 - if NewLayer1UpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1UpstreamMaxBitRate); err != nil {
1229 - return
1230 - }
1231 - if NewLayer1DownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewLayer1DownstreamMaxBitRate); err != nil {
1232 - return
1233 - }
1234 - if NewPhysicalLinkStatus, err = soap.UnmarshalString(response.NewPhysicalLinkStatus); err != nil {
1235 - return
1236 - }
1237 - // END Unmarshal arguments from response.
1238 - return
1239 -}
1240 -
1241 -//
1242 -//
1243 -// Return values:
1244 -//
1245 -// * NewWANAccessProvider:
1246 -func (client *WANCommonInterfaceConfig1) GetWANAccessProvider() (NewWANAccessProvider string, err error) {
1247 - // Request structure.
1248 - request := interface{}(nil)
1249 - // BEGIN Marshal arguments into request.
1250 -
1251 - // END Marshal arguments into request.
1252 -
1253 - // Response structure.
1254 - response := &struct {
1255 - NewWANAccessProvider string
1256 - }{}
1257 -
1258 - // Perform the SOAP call.
1259 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetWANAccessProvider", request, response); err != nil {
1260 - return
1261 - }
1262 -
1263 - // BEGIN Unmarshal arguments from response.
1264 -
1265 - if NewWANAccessProvider, err = soap.UnmarshalString(response.NewWANAccessProvider); err != nil {
1266 - return
1267 - }
1268 - // END Unmarshal arguments from response.
1269 - return
1270 -}
1271 -
1272 -//
1273 -//
1274 -// Return values:
1275 -//
1276 -// * NewMaximumActiveConnections: allowed value range: minimum=1, step=1
1277 -func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaximumActiveConnections uint16, err error) {
1278 - // Request structure.
1279 - request := interface{}(nil)
1280 - // BEGIN Marshal arguments into request.
1281 -
1282 - // END Marshal arguments into request.
1283 -
1284 - // Response structure.
1285 - response := &struct {
1286 - NewMaximumActiveConnections string
1287 - }{}
1288 -
1289 - // Perform the SOAP call.
1290 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetMaximumActiveConnections", request, response); err != nil {
1291 - return
1292 - }
1293 -
1294 - // BEGIN Unmarshal arguments from response.
1295 -
1296 - if NewMaximumActiveConnections, err = soap.UnmarshalUi2(response.NewMaximumActiveConnections); err != nil {
1297 - return
1298 - }
1299 - // END Unmarshal arguments from response.
1300 - return
1301 -}
1302 -
1303 -//
1304 -//
1305 -// Return values:
1306 -//
1307 -// * NewTotalBytesSent:
1308 -func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) {
1309 - // Request structure.
1310 - request := interface{}(nil)
1311 - // BEGIN Marshal arguments into request.
1312 -
1313 - // END Marshal arguments into request.
1314 -
1315 - // Response structure.
1316 - response := &struct {
1317 - NewTotalBytesSent string
1318 - }{}
1319 -
1320 - // Perform the SOAP call.
1321 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesSent", request, response); err != nil {
1322 - return
1323 - }
1324 -
1325 - // BEGIN Unmarshal arguments from response.
1326 -
1327 - if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil {
1328 - return
1329 - }
1330 - // END Unmarshal arguments from response.
1331 - return
1332 -}
1333 -
1334 -//
1335 -//
1336 -// Return values:
1337 -//
1338 -// * NewTotalBytesReceived:
1339 -func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) {
1340 - // Request structure.
1341 - request := interface{}(nil)
1342 - // BEGIN Marshal arguments into request.
1343 -
1344 - // END Marshal arguments into request.
1345 -
1346 - // Response structure.
1347 - response := &struct {
1348 - NewTotalBytesReceived string
1349 - }{}
1350 -
1351 - // Perform the SOAP call.
1352 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalBytesReceived", request, response); err != nil {
1353 - return
1354 - }
1355 -
1356 - // BEGIN Unmarshal arguments from response.
1357 -
1358 - if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil {
1359 - return
1360 - }
1361 - // END Unmarshal arguments from response.
1362 - return
1363 -}
1364 -
1365 -//
1366 -//
1367 -// Return values:
1368 -//
1369 -// * NewTotalPacketsSent:
1370 -func (client *WANCommonInterfaceConfig1) GetTotalPacketsSent() (NewTotalPacketsSent uint32, err error) {
1371 - // Request structure.
1372 - request := interface{}(nil)
1373 - // BEGIN Marshal arguments into request.
1374 -
1375 - // END Marshal arguments into request.
1376 -
1377 - // Response structure.
1378 - response := &struct {
1379 - NewTotalPacketsSent string
1380 - }{}
1381 -
1382 - // Perform the SOAP call.
1383 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsSent", request, response); err != nil {
1384 - return
1385 - }
1386 -
1387 - // BEGIN Unmarshal arguments from response.
1388 -
1389 - if NewTotalPacketsSent, err = soap.UnmarshalUi4(response.NewTotalPacketsSent); err != nil {
1390 - return
1391 - }
1392 - // END Unmarshal arguments from response.
1393 - return
1394 -}
1395 -
1396 -//
1397 -//
1398 -// Return values:
1399 -//
1400 -// * NewTotalPacketsReceived:
1401 -func (client *WANCommonInterfaceConfig1) GetTotalPacketsReceived() (NewTotalPacketsReceived uint32, err error) {
1402 - // Request structure.
1403 - request := interface{}(nil)
1404 - // BEGIN Marshal arguments into request.
1405 -
1406 - // END Marshal arguments into request.
1407 -
1408 - // Response structure.
1409 - response := &struct {
1410 - NewTotalPacketsReceived string
1411 - }{}
1412 -
1413 - // Perform the SOAP call.
1414 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetTotalPacketsReceived", request, response); err != nil {
1415 - return
1416 - }
1417 -
1418 - // BEGIN Unmarshal arguments from response.
1419 -
1420 - if NewTotalPacketsReceived, err = soap.UnmarshalUi4(response.NewTotalPacketsReceived); err != nil {
1421 - return
1422 - }
1423 - // END Unmarshal arguments from response.
1424 - return
1425 -}
1426 -
1427 -// Arguments:
1428 -//
1429 -// * NewActiveConnectionIndex:
1430 -//
1431 -// Return values:
1432 -//
1433 -// * NewActiveConnDeviceContainer:
1434 -//
1435 -// * NewActiveConnectionServiceID:
1436 -func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnectionIndex uint16) (NewActiveConnDeviceContainer string, NewActiveConnectionServiceID string, err error) {
1437 - // Request structure.
1438 - request := &struct {
1439 - NewActiveConnectionIndex string
1440 - }{}
1441 - // BEGIN Marshal arguments into request.
1442 -
1443 - if request.NewActiveConnectionIndex, err = soap.MarshalUi2(NewActiveConnectionIndex); err != nil {
1444 - return
1445 - }
1446 - // END Marshal arguments into request.
1447 -
1448 - // Response structure.
1449 - response := &struct {
1450 - NewActiveConnDeviceContainer string
1451 -
1452 - NewActiveConnectionServiceID string
1453 - }{}
1454 -
1455 - // Perform the SOAP call.
1456 - if err = client.SOAPClient.PerformAction(URN_WANCommonInterfaceConfig_1, "GetActiveConnection", request, response); err != nil {
1457 - return
1458 - }
1459 -
1460 - // BEGIN Unmarshal arguments from response.
1461 -
1462 - if NewActiveConnDeviceContainer, err = soap.UnmarshalString(response.NewActiveConnDeviceContainer); err != nil {
1463 - return
1464 - }
1465 - if NewActiveConnectionServiceID, err = soap.UnmarshalString(response.NewActiveConnectionServiceID); err != nil {
1466 - return
1467 - }
1468 - // END Unmarshal arguments from response.
1469 - return
1470 -}
1471 -
1472 -// WANDSLLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANDSLLinkConfig:1". See
1473 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1474 -// are provided for informational value.
1475 -type WANDSLLinkConfig1 struct {
1476 - goupnp.ServiceClient
1477 -}
1478 -
1479 -// NewWANDSLLinkConfig1Clients discovers instances of the service on the network,
1480 -// and returns clients to any that are found. errors will contain an error for
1481 -// any devices that replied but which could not be queried, and err will be set
1482 -// if the discovery process failed outright.
1483 -//
1484 -// This is a typical entry calling point into this package.
1485 -func NewWANDSLLinkConfig1Clients() (clients []*WANDSLLinkConfig1, errors []error, err error) {
1486 - var genericClients []goupnp.ServiceClient
1487 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANDSLLinkConfig_1); err != nil {
1488 - return
1489 - }
1490 - clients = make([]*WANDSLLinkConfig1, len(genericClients))
1491 - for i := range genericClients {
1492 - clients[i] = &WANDSLLinkConfig1{genericClients[i]}
1493 - }
1494 - return
1495 -}
1496 -
1497 -// Arguments:
1498 -//
1499 -// * NewLinkType:
1500 -//
1501 -//
1502 -func (client *WANDSLLinkConfig1) SetDSLLinkType(NewLinkType string) (err error) {
1503 - // Request structure.
1504 - request := &struct {
1505 - NewLinkType string
1506 - }{}
1507 - // BEGIN Marshal arguments into request.
1508 -
1509 - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil {
1510 - return
1511 - }
1512 - // END Marshal arguments into request.
1513 -
1514 - // Response structure.
1515 - response := interface{}(nil)
1516 -
1517 - // Perform the SOAP call.
1518 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDSLLinkType", request, response); err != nil {
1519 - return
1520 - }
1521 -
1522 - // BEGIN Unmarshal arguments from response.
1523 -
1524 - // END Unmarshal arguments from response.
1525 - return
1526 -}
1527 -
1528 -//
1529 -//
1530 -// Return values:
1531 -//
1532 -// * NewLinkType:
1533 -//
1534 -// * NewLinkStatus: allowed values: Up, Down
1535 -func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkStatus string, err error) {
1536 - // Request structure.
1537 - request := interface{}(nil)
1538 - // BEGIN Marshal arguments into request.
1539 -
1540 - // END Marshal arguments into request.
1541 -
1542 - // Response structure.
1543 - response := &struct {
1544 - NewLinkType string
1545 -
1546 - NewLinkStatus string
1547 - }{}
1548 -
1549 - // Perform the SOAP call.
1550 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDSLLinkInfo", request, response); err != nil {
1551 - return
1552 - }
1553 -
1554 - // BEGIN Unmarshal arguments from response.
1555 -
1556 - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil {
1557 - return
1558 - }
1559 - if NewLinkStatus, err = soap.UnmarshalString(response.NewLinkStatus); err != nil {
1560 - return
1561 - }
1562 - // END Unmarshal arguments from response.
1563 - return
1564 -}
1565 -
1566 -//
1567 -//
1568 -// Return values:
1569 -//
1570 -// * NewAutoConfig:
1571 -func (client *WANDSLLinkConfig1) GetAutoConfig() (NewAutoConfig bool, err error) {
1572 - // Request structure.
1573 - request := interface{}(nil)
1574 - // BEGIN Marshal arguments into request.
1575 -
1576 - // END Marshal arguments into request.
1577 -
1578 - // Response structure.
1579 - response := &struct {
1580 - NewAutoConfig string
1581 - }{}
1582 -
1583 - // Perform the SOAP call.
1584 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetAutoConfig", request, response); err != nil {
1585 - return
1586 - }
1587 -
1588 - // BEGIN Unmarshal arguments from response.
1589 -
1590 - if NewAutoConfig, err = soap.UnmarshalBoolean(response.NewAutoConfig); err != nil {
1591 - return
1592 - }
1593 - // END Unmarshal arguments from response.
1594 - return
1595 -}
1596 -
1597 -//
1598 -//
1599 -// Return values:
1600 -//
1601 -// * NewModulationType:
1602 -func (client *WANDSLLinkConfig1) GetModulationType() (NewModulationType string, err error) {
1603 - // Request structure.
1604 - request := interface{}(nil)
1605 - // BEGIN Marshal arguments into request.
1606 -
1607 - // END Marshal arguments into request.
1608 -
1609 - // Response structure.
1610 - response := &struct {
1611 - NewModulationType string
1612 - }{}
1613 -
1614 - // Perform the SOAP call.
1615 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetModulationType", request, response); err != nil {
1616 - return
1617 - }
1618 -
1619 - // BEGIN Unmarshal arguments from response.
1620 -
1621 - if NewModulationType, err = soap.UnmarshalString(response.NewModulationType); err != nil {
1622 - return
1623 - }
1624 - // END Unmarshal arguments from response.
1625 - return
1626 -}
1627 -
1628 -// Arguments:
1629 -//
1630 -// * NewDestinationAddress:
1631 -//
1632 -//
1633 -func (client *WANDSLLinkConfig1) SetDestinationAddress(NewDestinationAddress string) (err error) {
1634 - // Request structure.
1635 - request := &struct {
1636 - NewDestinationAddress string
1637 - }{}
1638 - // BEGIN Marshal arguments into request.
1639 -
1640 - if request.NewDestinationAddress, err = soap.MarshalString(NewDestinationAddress); err != nil {
1641 - return
1642 - }
1643 - // END Marshal arguments into request.
1644 -
1645 - // Response structure.
1646 - response := interface{}(nil)
1647 -
1648 - // Perform the SOAP call.
1649 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetDestinationAddress", request, response); err != nil {
1650 - return
1651 - }
1652 -
1653 - // BEGIN Unmarshal arguments from response.
1654 -
1655 - // END Unmarshal arguments from response.
1656 - return
1657 -}
1658 -
1659 -//
1660 -//
1661 -// Return values:
1662 -//
1663 -// * NewDestinationAddress:
1664 -func (client *WANDSLLinkConfig1) GetDestinationAddress() (NewDestinationAddress string, err error) {
1665 - // Request structure.
1666 - request := interface{}(nil)
1667 - // BEGIN Marshal arguments into request.
1668 -
1669 - // END Marshal arguments into request.
1670 -
1671 - // Response structure.
1672 - response := &struct {
1673 - NewDestinationAddress string
1674 - }{}
1675 -
1676 - // Perform the SOAP call.
1677 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetDestinationAddress", request, response); err != nil {
1678 - return
1679 - }
1680 -
1681 - // BEGIN Unmarshal arguments from response.
1682 -
1683 - if NewDestinationAddress, err = soap.UnmarshalString(response.NewDestinationAddress); err != nil {
1684 - return
1685 - }
1686 - // END Unmarshal arguments from response.
1687 - return
1688 -}
1689 -
1690 -// Arguments:
1691 -//
1692 -// * NewATMEncapsulation:
1693 -//
1694 -//
1695 -func (client *WANDSLLinkConfig1) SetATMEncapsulation(NewATMEncapsulation string) (err error) {
1696 - // Request structure.
1697 - request := &struct {
1698 - NewATMEncapsulation string
1699 - }{}
1700 - // BEGIN Marshal arguments into request.
1701 -
1702 - if request.NewATMEncapsulation, err = soap.MarshalString(NewATMEncapsulation); err != nil {
1703 - return
1704 - }
1705 - // END Marshal arguments into request.
1706 -
1707 - // Response structure.
1708 - response := interface{}(nil)
1709 -
1710 - // Perform the SOAP call.
1711 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetATMEncapsulation", request, response); err != nil {
1712 - return
1713 - }
1714 -
1715 - // BEGIN Unmarshal arguments from response.
1716 -
1717 - // END Unmarshal arguments from response.
1718 - return
1719 -}
1720 -
1721 -//
1722 -//
1723 -// Return values:
1724 -//
1725 -// * NewATMEncapsulation:
1726 -func (client *WANDSLLinkConfig1) GetATMEncapsulation() (NewATMEncapsulation string, err error) {
1727 - // Request structure.
1728 - request := interface{}(nil)
1729 - // BEGIN Marshal arguments into request.
1730 -
1731 - // END Marshal arguments into request.
1732 -
1733 - // Response structure.
1734 - response := &struct {
1735 - NewATMEncapsulation string
1736 - }{}
1737 -
1738 - // Perform the SOAP call.
1739 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetATMEncapsulation", request, response); err != nil {
1740 - return
1741 - }
1742 -
1743 - // BEGIN Unmarshal arguments from response.
1744 -
1745 - if NewATMEncapsulation, err = soap.UnmarshalString(response.NewATMEncapsulation); err != nil {
1746 - return
1747 - }
1748 - // END Unmarshal arguments from response.
1749 - return
1750 -}
1751 -
1752 -// Arguments:
1753 -//
1754 -// * NewFCSPreserved:
1755 -//
1756 -//
1757 -func (client *WANDSLLinkConfig1) SetFCSPreserved(NewFCSPreserved bool) (err error) {
1758 - // Request structure.
1759 - request := &struct {
1760 - NewFCSPreserved string
1761 - }{}
1762 - // BEGIN Marshal arguments into request.
1763 -
1764 - if request.NewFCSPreserved, err = soap.MarshalBoolean(NewFCSPreserved); err != nil {
1765 - return
1766 - }
1767 - // END Marshal arguments into request.
1768 -
1769 - // Response structure.
1770 - response := interface{}(nil)
1771 -
1772 - // Perform the SOAP call.
1773 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "SetFCSPreserved", request, response); err != nil {
1774 - return
1775 - }
1776 -
1777 - // BEGIN Unmarshal arguments from response.
1778 -
1779 - // END Unmarshal arguments from response.
1780 - return
1781 -}
1782 -
1783 -//
1784 -//
1785 -// Return values:
1786 -//
1787 -// * NewFCSPreserved:
1788 -func (client *WANDSLLinkConfig1) GetFCSPreserved() (NewFCSPreserved bool, err error) {
1789 - // Request structure.
1790 - request := interface{}(nil)
1791 - // BEGIN Marshal arguments into request.
1792 -
1793 - // END Marshal arguments into request.
1794 -
1795 - // Response structure.
1796 - response := &struct {
1797 - NewFCSPreserved string
1798 - }{}
1799 -
1800 - // Perform the SOAP call.
1801 - if err = client.SOAPClient.PerformAction(URN_WANDSLLinkConfig_1, "GetFCSPreserved", request, response); err != nil {
1802 - return
1803 - }
1804 -
1805 - // BEGIN Unmarshal arguments from response.
1806 -
1807 - if NewFCSPreserved, err = soap.UnmarshalBoolean(response.NewFCSPreserved); err != nil {
1808 - return
1809 - }
1810 - // END Unmarshal arguments from response.
1811 - return
1812 -}
1813 -
1814 -// WANEthernetLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANEthernetLinkConfig:1". See
1815 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1816 -// are provided for informational value.
1817 -type WANEthernetLinkConfig1 struct {
1818 - goupnp.ServiceClient
1819 -}
1820 -
1821 -// NewWANEthernetLinkConfig1Clients discovers instances of the service on the network,
1822 -// and returns clients to any that are found. errors will contain an error for
1823 -// any devices that replied but which could not be queried, and err will be set
1824 -// if the discovery process failed outright.
1825 -//
1826 -// This is a typical entry calling point into this package.
1827 -func NewWANEthernetLinkConfig1Clients() (clients []*WANEthernetLinkConfig1, errors []error, err error) {
1828 - var genericClients []goupnp.ServiceClient
1829 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANEthernetLinkConfig_1); err != nil {
1830 - return
1831 - }
1832 - clients = make([]*WANEthernetLinkConfig1, len(genericClients))
1833 - for i := range genericClients {
1834 - clients[i] = &WANEthernetLinkConfig1{genericClients[i]}
1835 - }
1836 - return
1837 -}
1838 -
1839 -//
1840 -//
1841 -// Return values:
1842 -//
1843 -// * NewEthernetLinkStatus: allowed values: Up, Down
1844 -func (client *WANEthernetLinkConfig1) GetEthernetLinkStatus() (NewEthernetLinkStatus string, err error) {
1845 - // Request structure.
1846 - request := interface{}(nil)
1847 - // BEGIN Marshal arguments into request.
1848 -
1849 - // END Marshal arguments into request.
1850 -
1851 - // Response structure.
1852 - response := &struct {
1853 - NewEthernetLinkStatus string
1854 - }{}
1855 -
1856 - // Perform the SOAP call.
1857 - if err = client.SOAPClient.PerformAction(URN_WANEthernetLinkConfig_1, "GetEthernetLinkStatus", request, response); err != nil {
1858 - return
1859 - }
1860 -
1861 - // BEGIN Unmarshal arguments from response.
1862 -
1863 - if NewEthernetLinkStatus, err = soap.UnmarshalString(response.NewEthernetLinkStatus); err != nil {
1864 - return
1865 - }
1866 - // END Unmarshal arguments from response.
1867 - return
1868 -}
1869 -
1870 -// WANIPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:1". See
1871 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
1872 -// are provided for informational value.
1873 -type WANIPConnection1 struct {
1874 - goupnp.ServiceClient
1875 -}
1876 -
1877 -// NewWANIPConnection1Clients discovers instances of the service on the network,
1878 -// and returns clients to any that are found. errors will contain an error for
1879 -// any devices that replied but which could not be queried, and err will be set
1880 -// if the discovery process failed outright.
1881 -//
1882 -// This is a typical entry calling point into this package.
1883 -func NewWANIPConnection1Clients() (clients []*WANIPConnection1, errors []error, err error) {
1884 - var genericClients []goupnp.ServiceClient
1885 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_1); err != nil {
1886 - return
1887 - }
1888 - clients = make([]*WANIPConnection1, len(genericClients))
1889 - for i := range genericClients {
1890 - clients[i] = &WANIPConnection1{genericClients[i]}
1891 - }
1892 - return
1893 -}
1894 -
1895 -// Arguments:
1896 -//
1897 -// * NewConnectionType:
1898 -//
1899 -//
1900 -func (client *WANIPConnection1) SetConnectionType(NewConnectionType string) (err error) {
1901 - // Request structure.
1902 - request := &struct {
1903 - NewConnectionType string
1904 - }{}
1905 - // BEGIN Marshal arguments into request.
1906 -
1907 - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil {
1908 - return
1909 - }
1910 - // END Marshal arguments into request.
1911 -
1912 - // Response structure.
1913 - response := interface{}(nil)
1914 -
1915 - // Perform the SOAP call.
1916 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetConnectionType", request, response); err != nil {
1917 - return
1918 - }
1919 -
1920 - // BEGIN Unmarshal arguments from response.
1921 -
1922 - // END Unmarshal arguments from response.
1923 - return
1924 -}
1925 -
1926 -//
1927 -//
1928 -// Return values:
1929 -//
1930 -// * NewConnectionType:
1931 -//
1932 -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, IP_Bridged
1933 -func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) {
1934 - // Request structure.
1935 - request := interface{}(nil)
1936 - // BEGIN Marshal arguments into request.
1937 -
1938 - // END Marshal arguments into request.
1939 -
1940 - // Response structure.
1941 - response := &struct {
1942 - NewConnectionType string
1943 -
1944 - NewPossibleConnectionTypes string
1945 - }{}
1946 -
1947 - // Perform the SOAP call.
1948 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetConnectionTypeInfo", request, response); err != nil {
1949 - return
1950 - }
1951 -
1952 - // BEGIN Unmarshal arguments from response.
1953 -
1954 - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil {
1955 - return
1956 - }
1957 - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil {
1958 - return
1959 - }
1960 - // END Unmarshal arguments from response.
1961 - return
1962 -}
1963 -
1964 -//
1965 -//
1966 -//
1967 -func (client *WANIPConnection1) RequestConnection() (err error) {
1968 - // Request structure.
1969 - request := interface{}(nil)
1970 - // BEGIN Marshal arguments into request.
1971 -
1972 - // END Marshal arguments into request.
1973 -
1974 - // Response structure.
1975 - response := interface{}(nil)
1976 -
1977 - // Perform the SOAP call.
1978 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestConnection", request, response); err != nil {
1979 - return
1980 - }
1981 -
1982 - // BEGIN Unmarshal arguments from response.
1983 -
1984 - // END Unmarshal arguments from response.
1985 - return
1986 -}
1987 -
1988 -//
1989 -//
1990 -//
1991 -func (client *WANIPConnection1) RequestTermination() (err error) {
1992 - // Request structure.
1993 - request := interface{}(nil)
1994 - // BEGIN Marshal arguments into request.
1995 -
1996 - // END Marshal arguments into request.
1997 -
1998 - // Response structure.
1999 - response := interface{}(nil)
2000 -
2001 - // Perform the SOAP call.
2002 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "RequestTermination", request, response); err != nil {
2003 - return
2004 - }
2005 -
2006 - // BEGIN Unmarshal arguments from response.
2007 -
2008 - // END Unmarshal arguments from response.
2009 - return
2010 -}
2011 -
2012 -//
2013 -//
2014 -//
2015 -func (client *WANIPConnection1) ForceTermination() (err error) {
2016 - // Request structure.
2017 - request := interface{}(nil)
2018 - // BEGIN Marshal arguments into request.
2019 -
2020 - // END Marshal arguments into request.
2021 -
2022 - // Response structure.
2023 - response := interface{}(nil)
2024 -
2025 - // Perform the SOAP call.
2026 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "ForceTermination", request, response); err != nil {
2027 - return
2028 - }
2029 -
2030 - // BEGIN Unmarshal arguments from response.
2031 -
2032 - // END Unmarshal arguments from response.
2033 - return
2034 -}
2035 -
2036 -// Arguments:
2037 -//
2038 -// * NewAutoDisconnectTime:
2039 -//
2040 -//
2041 -func (client *WANIPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) {
2042 - // Request structure.
2043 - request := &struct {
2044 - NewAutoDisconnectTime string
2045 - }{}
2046 - // BEGIN Marshal arguments into request.
2047 -
2048 - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil {
2049 - return
2050 - }
2051 - // END Marshal arguments into request.
2052 -
2053 - // Response structure.
2054 - response := interface{}(nil)
2055 -
2056 - // Perform the SOAP call.
2057 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetAutoDisconnectTime", request, response); err != nil {
2058 - return
2059 - }
2060 -
2061 - // BEGIN Unmarshal arguments from response.
2062 -
2063 - // END Unmarshal arguments from response.
2064 - return
2065 -}
2066 -
2067 -// Arguments:
2068 -//
2069 -// * NewIdleDisconnectTime:
2070 -//
2071 -//
2072 -func (client *WANIPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) {
2073 - // Request structure.
2074 - request := &struct {
2075 - NewIdleDisconnectTime string
2076 - }{}
2077 - // BEGIN Marshal arguments into request.
2078 -
2079 - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil {
2080 - return
2081 - }
2082 - // END Marshal arguments into request.
2083 -
2084 - // Response structure.
2085 - response := interface{}(nil)
2086 -
2087 - // Perform the SOAP call.
2088 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetIdleDisconnectTime", request, response); err != nil {
2089 - return
2090 - }
2091 -
2092 - // BEGIN Unmarshal arguments from response.
2093 -
2094 - // END Unmarshal arguments from response.
2095 - return
2096 -}
2097 -
2098 -// Arguments:
2099 -//
2100 -// * NewWarnDisconnectDelay:
2101 -//
2102 -//
2103 -func (client *WANIPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) {
2104 - // Request structure.
2105 - request := &struct {
2106 - NewWarnDisconnectDelay string
2107 - }{}
2108 - // BEGIN Marshal arguments into request.
2109 -
2110 - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil {
2111 - return
2112 - }
2113 - // END Marshal arguments into request.
2114 -
2115 - // Response structure.
2116 - response := interface{}(nil)
2117 -
2118 - // Perform the SOAP call.
2119 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil {
2120 - return
2121 - }
2122 -
2123 - // BEGIN Unmarshal arguments from response.
2124 -
2125 - // END Unmarshal arguments from response.
2126 - return
2127 -}
2128 -
2129 -//
2130 -//
2131 -// Return values:
2132 -//
2133 -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
2134 -//
2135 -// * NewLastConnectionError: allowed values: ERROR_NONE
2136 -//
2137 -// * NewUptime:
2138 -func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) {
2139 - // Request structure.
2140 - request := interface{}(nil)
2141 - // BEGIN Marshal arguments into request.
2142 -
2143 - // END Marshal arguments into request.
2144 -
2145 - // Response structure.
2146 - response := &struct {
2147 - NewConnectionStatus string
2148 -
2149 - NewLastConnectionError string
2150 -
2151 - NewUptime string
2152 - }{}
2153 -
2154 - // Perform the SOAP call.
2155 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetStatusInfo", request, response); err != nil {
2156 - return
2157 - }
2158 -
2159 - // BEGIN Unmarshal arguments from response.
2160 -
2161 - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil {
2162 - return
2163 - }
2164 - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil {
2165 - return
2166 - }
2167 - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil {
2168 - return
2169 - }
2170 - // END Unmarshal arguments from response.
2171 - return
2172 -}
2173 -
2174 -//
2175 -//
2176 -// Return values:
2177 -//
2178 -// * NewAutoDisconnectTime:
2179 -func (client *WANIPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) {
2180 - // Request structure.
2181 - request := interface{}(nil)
2182 - // BEGIN Marshal arguments into request.
2183 -
2184 - // END Marshal arguments into request.
2185 -
2186 - // Response structure.
2187 - response := &struct {
2188 - NewAutoDisconnectTime string
2189 - }{}
2190 -
2191 - // Perform the SOAP call.
2192 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetAutoDisconnectTime", request, response); err != nil {
2193 - return
2194 - }
2195 -
2196 - // BEGIN Unmarshal arguments from response.
2197 -
2198 - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil {
2199 - return
2200 - }
2201 - // END Unmarshal arguments from response.
2202 - return
2203 -}
2204 -
2205 -//
2206 -//
2207 -// Return values:
2208 -//
2209 -// * NewIdleDisconnectTime:
2210 -func (client *WANIPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) {
2211 - // Request structure.
2212 - request := interface{}(nil)
2213 - // BEGIN Marshal arguments into request.
2214 -
2215 - // END Marshal arguments into request.
2216 -
2217 - // Response structure.
2218 - response := &struct {
2219 - NewIdleDisconnectTime string
2220 - }{}
2221 -
2222 - // Perform the SOAP call.
2223 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetIdleDisconnectTime", request, response); err != nil {
2224 - return
2225 - }
2226 -
2227 - // BEGIN Unmarshal arguments from response.
2228 -
2229 - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil {
2230 - return
2231 - }
2232 - // END Unmarshal arguments from response.
2233 - return
2234 -}
2235 -
2236 -//
2237 -//
2238 -// Return values:
2239 -//
2240 -// * NewWarnDisconnectDelay:
2241 -func (client *WANIPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) {
2242 - // Request structure.
2243 - request := interface{}(nil)
2244 - // BEGIN Marshal arguments into request.
2245 -
2246 - // END Marshal arguments into request.
2247 -
2248 - // Response structure.
2249 - response := &struct {
2250 - NewWarnDisconnectDelay string
2251 - }{}
2252 -
2253 - // Perform the SOAP call.
2254 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil {
2255 - return
2256 - }
2257 -
2258 - // BEGIN Unmarshal arguments from response.
2259 -
2260 - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil {
2261 - return
2262 - }
2263 - // END Unmarshal arguments from response.
2264 - return
2265 -}
2266 -
2267 -//
2268 -//
2269 -// Return values:
2270 -//
2271 -// * NewRSIPAvailable:
2272 -//
2273 -// * NewNATEnabled:
2274 -func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) {
2275 - // Request structure.
2276 - request := interface{}(nil)
2277 - // BEGIN Marshal arguments into request.
2278 -
2279 - // END Marshal arguments into request.
2280 -
2281 - // Response structure.
2282 - response := &struct {
2283 - NewRSIPAvailable string
2284 -
2285 - NewNATEnabled string
2286 - }{}
2287 -
2288 - // Perform the SOAP call.
2289 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetNATRSIPStatus", request, response); err != nil {
2290 - return
2291 - }
2292 -
2293 - // BEGIN Unmarshal arguments from response.
2294 -
2295 - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil {
2296 - return
2297 - }
2298 - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil {
2299 - return
2300 - }
2301 - // END Unmarshal arguments from response.
2302 - return
2303 -}
2304 -
2305 -// Arguments:
2306 -//
2307 -// * NewPortMappingIndex:
2308 -//
2309 -// Return values:
2310 -//
2311 -// * NewRemoteHost:
2312 -//
2313 -// * NewExternalPort:
2314 -//
2315 -// * NewProtocol: allowed values: TCP, UDP
2316 -//
2317 -// * NewInternalPort:
2318 -//
2319 -// * NewInternalClient:
2320 -//
2321 -// * NewEnabled:
2322 -//
2323 -// * NewPortMappingDescription:
2324 -//
2325 -// * NewLeaseDuration:
2326 -func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
2327 - // Request structure.
2328 - request := &struct {
2329 - NewPortMappingIndex string
2330 - }{}
2331 - // BEGIN Marshal arguments into request.
2332 -
2333 - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil {
2334 - return
2335 - }
2336 - // END Marshal arguments into request.
2337 -
2338 - // Response structure.
2339 - response := &struct {
2340 - NewRemoteHost string
2341 -
2342 - NewExternalPort string
2343 -
2344 - NewProtocol string
2345 -
2346 - NewInternalPort string
2347 -
2348 - NewInternalClient string
2349 -
2350 - NewEnabled string
2351 -
2352 - NewPortMappingDescription string
2353 -
2354 - NewLeaseDuration string
2355 - }{}
2356 -
2357 - // Perform the SOAP call.
2358 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetGenericPortMappingEntry", request, response); err != nil {
2359 - return
2360 - }
2361 -
2362 - // BEGIN Unmarshal arguments from response.
2363 -
2364 - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil {
2365 - return
2366 - }
2367 - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil {
2368 - return
2369 - }
2370 - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil {
2371 - return
2372 - }
2373 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
2374 - return
2375 - }
2376 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
2377 - return
2378 - }
2379 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
2380 - return
2381 - }
2382 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
2383 - return
2384 - }
2385 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
2386 - return
2387 - }
2388 - // END Unmarshal arguments from response.
2389 - return
2390 -}
2391 -
2392 -// Arguments:
2393 -//
2394 -// * NewRemoteHost:
2395 -//
2396 -// * NewExternalPort:
2397 -//
2398 -// * NewProtocol: allowed values: TCP, UDP
2399 -//
2400 -// Return values:
2401 -//
2402 -// * NewInternalPort:
2403 -//
2404 -// * NewInternalClient:
2405 -//
2406 -// * NewEnabled:
2407 -//
2408 -// * NewPortMappingDescription:
2409 -//
2410 -// * NewLeaseDuration:
2411 -func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
2412 - // Request structure.
2413 - request := &struct {
2414 - NewRemoteHost string
2415 -
2416 - NewExternalPort string
2417 -
2418 - NewProtocol string
2419 - }{}
2420 - // BEGIN Marshal arguments into request.
2421 -
2422 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
2423 - return
2424 - }
2425 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
2426 - return
2427 - }
2428 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
2429 - return
2430 - }
2431 - // END Marshal arguments into request.
2432 -
2433 - // Response structure.
2434 - response := &struct {
2435 - NewInternalPort string
2436 -
2437 - NewInternalClient string
2438 -
2439 - NewEnabled string
2440 -
2441 - NewPortMappingDescription string
2442 -
2443 - NewLeaseDuration string
2444 - }{}
2445 -
2446 - // Perform the SOAP call.
2447 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetSpecificPortMappingEntry", request, response); err != nil {
2448 - return
2449 - }
2450 -
2451 - // BEGIN Unmarshal arguments from response.
2452 -
2453 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
2454 - return
2455 - }
2456 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
2457 - return
2458 - }
2459 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
2460 - return
2461 - }
2462 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
2463 - return
2464 - }
2465 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
2466 - return
2467 - }
2468 - // END Unmarshal arguments from response.
2469 - return
2470 -}
2471 -
2472 -// Arguments:
2473 -//
2474 -// * NewRemoteHost:
2475 -//
2476 -// * NewExternalPort:
2477 -//
2478 -// * NewProtocol: allowed values: TCP, UDP
2479 -//
2480 -// * NewInternalPort:
2481 -//
2482 -// * NewInternalClient:
2483 -//
2484 -// * NewEnabled:
2485 -//
2486 -// * NewPortMappingDescription:
2487 -//
2488 -// * NewLeaseDuration:
2489 -//
2490 -//
2491 -func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) {
2492 - // Request structure.
2493 - request := &struct {
2494 - NewRemoteHost string
2495 -
2496 - NewExternalPort string
2497 -
2498 - NewProtocol string
2499 -
2500 - NewInternalPort string
2501 -
2502 - NewInternalClient string
2503 -
2504 - NewEnabled string
2505 -
2506 - NewPortMappingDescription string
2507 -
2508 - NewLeaseDuration string
2509 - }{}
2510 - // BEGIN Marshal arguments into request.
2511 -
2512 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
2513 - return
2514 - }
2515 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
2516 - return
2517 - }
2518 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
2519 - return
2520 - }
2521 - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil {
2522 - return
2523 - }
2524 - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil {
2525 - return
2526 - }
2527 - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil {
2528 - return
2529 - }
2530 - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil {
2531 - return
2532 - }
2533 - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil {
2534 - return
2535 - }
2536 - // END Marshal arguments into request.
2537 -
2538 - // Response structure.
2539 - response := interface{}(nil)
2540 -
2541 - // Perform the SOAP call.
2542 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "AddPortMapping", request, response); err != nil {
2543 - return
2544 - }
2545 -
2546 - // BEGIN Unmarshal arguments from response.
2547 -
2548 - // END Unmarshal arguments from response.
2549 - return
2550 -}
2551 -
2552 -// Arguments:
2553 -//
2554 -// * NewRemoteHost:
2555 -//
2556 -// * NewExternalPort:
2557 -//
2558 -// * NewProtocol: allowed values: TCP, UDP
2559 -//
2560 -//
2561 -func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) {
2562 - // Request structure.
2563 - request := &struct {
2564 - NewRemoteHost string
2565 -
2566 - NewExternalPort string
2567 -
2568 - NewProtocol string
2569 - }{}
2570 - // BEGIN Marshal arguments into request.
2571 -
2572 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
2573 - return
2574 - }
2575 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
2576 - return
2577 - }
2578 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
2579 - return
2580 - }
2581 - // END Marshal arguments into request.
2582 -
2583 - // Response structure.
2584 - response := interface{}(nil)
2585 -
2586 - // Perform the SOAP call.
2587 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "DeletePortMapping", request, response); err != nil {
2588 - return
2589 - }
2590 -
2591 - // BEGIN Unmarshal arguments from response.
2592 -
2593 - // END Unmarshal arguments from response.
2594 - return
2595 -}
2596 -
2597 -//
2598 -//
2599 -// Return values:
2600 -//
2601 -// * NewExternalIPAddress:
2602 -func (client *WANIPConnection1) GetExternalIPAddress() (NewExternalIPAddress string, err error) {
2603 - // Request structure.
2604 - request := interface{}(nil)
2605 - // BEGIN Marshal arguments into request.
2606 -
2607 - // END Marshal arguments into request.
2608 -
2609 - // Response structure.
2610 - response := &struct {
2611 - NewExternalIPAddress string
2612 - }{}
2613 -
2614 - // Perform the SOAP call.
2615 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_1, "GetExternalIPAddress", request, response); err != nil {
2616 - return
2617 - }
2618 -
2619 - // BEGIN Unmarshal arguments from response.
2620 -
2621 - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil {
2622 - return
2623 - }
2624 - // END Unmarshal arguments from response.
2625 - return
2626 -}
2627 -
2628 -// WANIPConnection2 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPConnection:2". See
2629 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
2630 -// are provided for informational value.
2631 -type WANIPConnection2 struct {
2632 - goupnp.ServiceClient
2633 -}
2634 -
2635 -// NewWANIPConnection2Clients discovers instances of the service on the network,
2636 -// and returns clients to any that are found. errors will contain an error for
2637 -// any devices that replied but which could not be queried, and err will be set
2638 -// if the discovery process failed outright.
2639 -//
2640 -// This is a typical entry calling point into this package.
2641 -func NewWANIPConnection2Clients() (clients []*WANIPConnection2, errors []error, err error) {
2642 - var genericClients []goupnp.ServiceClient
2643 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPConnection_2); err != nil {
2644 - return
2645 - }
2646 - clients = make([]*WANIPConnection2, len(genericClients))
2647 - for i := range genericClients {
2648 - clients[i] = &WANIPConnection2{genericClients[i]}
2649 - }
2650 - return
2651 -}
2652 -
2653 -// Arguments:
2654 -//
2655 -// * NewConnectionType: allowed values: Unconfigured, IP_Routed, IP_Bridged
2656 -//
2657 -//
2658 -func (client *WANIPConnection2) SetConnectionType(NewConnectionType string) (err error) {
2659 - // Request structure.
2660 - request := &struct {
2661 - NewConnectionType string
2662 - }{}
2663 - // BEGIN Marshal arguments into request.
2664 -
2665 - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil {
2666 - return
2667 - }
2668 - // END Marshal arguments into request.
2669 -
2670 - // Response structure.
2671 - response := interface{}(nil)
2672 -
2673 - // Perform the SOAP call.
2674 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetConnectionType", request, response); err != nil {
2675 - return
2676 - }
2677 -
2678 - // BEGIN Unmarshal arguments from response.
2679 -
2680 - // END Unmarshal arguments from response.
2681 - return
2682 -}
2683 -
2684 -//
2685 -//
2686 -// Return values:
2687 -//
2688 -// * NewConnectionType: allowed values: Unconfigured, IP_Routed, IP_Bridged
2689 -//
2690 -// * NewPossibleConnectionTypes:
2691 -func (client *WANIPConnection2) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) {
2692 - // Request structure.
2693 - request := interface{}(nil)
2694 - // BEGIN Marshal arguments into request.
2695 -
2696 - // END Marshal arguments into request.
2697 -
2698 - // Response structure.
2699 - response := &struct {
2700 - NewConnectionType string
2701 -
2702 - NewPossibleConnectionTypes string
2703 - }{}
2704 -
2705 - // Perform the SOAP call.
2706 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetConnectionTypeInfo", request, response); err != nil {
2707 - return
2708 - }
2709 -
2710 - // BEGIN Unmarshal arguments from response.
2711 -
2712 - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil {
2713 - return
2714 - }
2715 - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil {
2716 - return
2717 - }
2718 - // END Unmarshal arguments from response.
2719 - return
2720 -}
2721 -
2722 -//
2723 -//
2724 -//
2725 -func (client *WANIPConnection2) RequestConnection() (err error) {
2726 - // Request structure.
2727 - request := interface{}(nil)
2728 - // BEGIN Marshal arguments into request.
2729 -
2730 - // END Marshal arguments into request.
2731 -
2732 - // Response structure.
2733 - response := interface{}(nil)
2734 -
2735 - // Perform the SOAP call.
2736 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "RequestConnection", request, response); err != nil {
2737 - return
2738 - }
2739 -
2740 - // BEGIN Unmarshal arguments from response.
2741 -
2742 - // END Unmarshal arguments from response.
2743 - return
2744 -}
2745 -
2746 -//
2747 -//
2748 -//
2749 -func (client *WANIPConnection2) RequestTermination() (err error) {
2750 - // Request structure.
2751 - request := interface{}(nil)
2752 - // BEGIN Marshal arguments into request.
2753 -
2754 - // END Marshal arguments into request.
2755 -
2756 - // Response structure.
2757 - response := interface{}(nil)
2758 -
2759 - // Perform the SOAP call.
2760 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "RequestTermination", request, response); err != nil {
2761 - return
2762 - }
2763 -
2764 - // BEGIN Unmarshal arguments from response.
2765 -
2766 - // END Unmarshal arguments from response.
2767 - return
2768 -}
2769 -
2770 -//
2771 -//
2772 -//
2773 -func (client *WANIPConnection2) ForceTermination() (err error) {
2774 - // Request structure.
2775 - request := interface{}(nil)
2776 - // BEGIN Marshal arguments into request.
2777 -
2778 - // END Marshal arguments into request.
2779 -
2780 - // Response structure.
2781 - response := interface{}(nil)
2782 -
2783 - // Perform the SOAP call.
2784 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "ForceTermination", request, response); err != nil {
2785 - return
2786 - }
2787 -
2788 - // BEGIN Unmarshal arguments from response.
2789 -
2790 - // END Unmarshal arguments from response.
2791 - return
2792 -}
2793 -
2794 -// Arguments:
2795 -//
2796 -// * NewAutoDisconnectTime:
2797 -//
2798 -//
2799 -func (client *WANIPConnection2) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) {
2800 - // Request structure.
2801 - request := &struct {
2802 - NewAutoDisconnectTime string
2803 - }{}
2804 - // BEGIN Marshal arguments into request.
2805 -
2806 - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil {
2807 - return
2808 - }
2809 - // END Marshal arguments into request.
2810 -
2811 - // Response structure.
2812 - response := interface{}(nil)
2813 -
2814 - // Perform the SOAP call.
2815 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetAutoDisconnectTime", request, response); err != nil {
2816 - return
2817 - }
2818 -
2819 - // BEGIN Unmarshal arguments from response.
2820 -
2821 - // END Unmarshal arguments from response.
2822 - return
2823 -}
2824 -
2825 -// Arguments:
2826 -//
2827 -// * NewIdleDisconnectTime:
2828 -//
2829 -//
2830 -func (client *WANIPConnection2) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) {
2831 - // Request structure.
2832 - request := &struct {
2833 - NewIdleDisconnectTime string
2834 - }{}
2835 - // BEGIN Marshal arguments into request.
2836 -
2837 - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil {
2838 - return
2839 - }
2840 - // END Marshal arguments into request.
2841 -
2842 - // Response structure.
2843 - response := interface{}(nil)
2844 -
2845 - // Perform the SOAP call.
2846 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetIdleDisconnectTime", request, response); err != nil {
2847 - return
2848 - }
2849 -
2850 - // BEGIN Unmarshal arguments from response.
2851 -
2852 - // END Unmarshal arguments from response.
2853 - return
2854 -}
2855 -
2856 -// Arguments:
2857 -//
2858 -// * NewWarnDisconnectDelay:
2859 -//
2860 -//
2861 -func (client *WANIPConnection2) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) {
2862 - // Request structure.
2863 - request := &struct {
2864 - NewWarnDisconnectDelay string
2865 - }{}
2866 - // BEGIN Marshal arguments into request.
2867 -
2868 - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil {
2869 - return
2870 - }
2871 - // END Marshal arguments into request.
2872 -
2873 - // Response structure.
2874 - response := interface{}(nil)
2875 -
2876 - // Perform the SOAP call.
2877 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "SetWarnDisconnectDelay", request, response); err != nil {
2878 - return
2879 - }
2880 -
2881 - // BEGIN Unmarshal arguments from response.
2882 -
2883 - // END Unmarshal arguments from response.
2884 - return
2885 -}
2886 -
2887 -//
2888 -//
2889 -// Return values:
2890 -//
2891 -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
2892 -//
2893 -// * NewLastConnectionError: allowed values: ERROR_NONE
2894 -//
2895 -// * NewUptime:
2896 -func (client *WANIPConnection2) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) {
2897 - // Request structure.
2898 - request := interface{}(nil)
2899 - // BEGIN Marshal arguments into request.
2900 -
2901 - // END Marshal arguments into request.
2902 -
2903 - // Response structure.
2904 - response := &struct {
2905 - NewConnectionStatus string
2906 -
2907 - NewLastConnectionError string
2908 -
2909 - NewUptime string
2910 - }{}
2911 -
2912 - // Perform the SOAP call.
2913 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetStatusInfo", request, response); err != nil {
2914 - return
2915 - }
2916 -
2917 - // BEGIN Unmarshal arguments from response.
2918 -
2919 - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil {
2920 - return
2921 - }
2922 - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil {
2923 - return
2924 - }
2925 - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil {
2926 - return
2927 - }
2928 - // END Unmarshal arguments from response.
2929 - return
2930 -}
2931 -
2932 -//
2933 -//
2934 -// Return values:
2935 -//
2936 -// * NewAutoDisconnectTime:
2937 -func (client *WANIPConnection2) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) {
2938 - // Request structure.
2939 - request := interface{}(nil)
2940 - // BEGIN Marshal arguments into request.
2941 -
2942 - // END Marshal arguments into request.
2943 -
2944 - // Response structure.
2945 - response := &struct {
2946 - NewAutoDisconnectTime string
2947 - }{}
2948 -
2949 - // Perform the SOAP call.
2950 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetAutoDisconnectTime", request, response); err != nil {
2951 - return
2952 - }
2953 -
2954 - // BEGIN Unmarshal arguments from response.
2955 -
2956 - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil {
2957 - return
2958 - }
2959 - // END Unmarshal arguments from response.
2960 - return
2961 -}
2962 -
2963 -//
2964 -//
2965 -// Return values:
2966 -//
2967 -// * NewIdleDisconnectTime:
2968 -func (client *WANIPConnection2) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) {
2969 - // Request structure.
2970 - request := interface{}(nil)
2971 - // BEGIN Marshal arguments into request.
2972 -
2973 - // END Marshal arguments into request.
2974 -
2975 - // Response structure.
2976 - response := &struct {
2977 - NewIdleDisconnectTime string
2978 - }{}
2979 -
2980 - // Perform the SOAP call.
2981 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetIdleDisconnectTime", request, response); err != nil {
2982 - return
2983 - }
2984 -
2985 - // BEGIN Unmarshal arguments from response.
2986 -
2987 - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil {
2988 - return
2989 - }
2990 - // END Unmarshal arguments from response.
2991 - return
2992 -}
2993 -
2994 -//
2995 -//
2996 -// Return values:
2997 -//
2998 -// * NewWarnDisconnectDelay:
2999 -func (client *WANIPConnection2) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) {
3000 - // Request structure.
3001 - request := interface{}(nil)
3002 - // BEGIN Marshal arguments into request.
3003 -
3004 - // END Marshal arguments into request.
3005 -
3006 - // Response structure.
3007 - response := &struct {
3008 - NewWarnDisconnectDelay string
3009 - }{}
3010 -
3011 - // Perform the SOAP call.
3012 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetWarnDisconnectDelay", request, response); err != nil {
3013 - return
3014 - }
3015 -
3016 - // BEGIN Unmarshal arguments from response.
3017 -
3018 - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil {
3019 - return
3020 - }
3021 - // END Unmarshal arguments from response.
3022 - return
3023 -}
3024 -
3025 -//
3026 -//
3027 -// Return values:
3028 -//
3029 -// * NewRSIPAvailable:
3030 -//
3031 -// * NewNATEnabled:
3032 -func (client *WANIPConnection2) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) {
3033 - // Request structure.
3034 - request := interface{}(nil)
3035 - // BEGIN Marshal arguments into request.
3036 -
3037 - // END Marshal arguments into request.
3038 -
3039 - // Response structure.
3040 - response := &struct {
3041 - NewRSIPAvailable string
3042 -
3043 - NewNATEnabled string
3044 - }{}
3045 -
3046 - // Perform the SOAP call.
3047 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetNATRSIPStatus", request, response); err != nil {
3048 - return
3049 - }
3050 -
3051 - // BEGIN Unmarshal arguments from response.
3052 -
3053 - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil {
3054 - return
3055 - }
3056 - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil {
3057 - return
3058 - }
3059 - // END Unmarshal arguments from response.
3060 - return
3061 -}
3062 -
3063 -// Arguments:
3064 -//
3065 -// * NewPortMappingIndex:
3066 -//
3067 -// Return values:
3068 -//
3069 -// * NewRemoteHost:
3070 -//
3071 -// * NewExternalPort:
3072 -//
3073 -// * NewProtocol: allowed values: TCP, UDP
3074 -//
3075 -// * NewInternalPort: allowed value range: minimum=1, maximum=65535
3076 -//
3077 -// * NewInternalClient:
3078 -//
3079 -// * NewEnabled:
3080 -//
3081 -// * NewPortMappingDescription:
3082 -//
3083 -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800
3084 -func (client *WANIPConnection2) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
3085 - // Request structure.
3086 - request := &struct {
3087 - NewPortMappingIndex string
3088 - }{}
3089 - // BEGIN Marshal arguments into request.
3090 -
3091 - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil {
3092 - return
3093 - }
3094 - // END Marshal arguments into request.
3095 -
3096 - // Response structure.
3097 - response := &struct {
3098 - NewRemoteHost string
3099 -
3100 - NewExternalPort string
3101 -
3102 - NewProtocol string
3103 -
3104 - NewInternalPort string
3105 -
3106 - NewInternalClient string
3107 -
3108 - NewEnabled string
3109 -
3110 - NewPortMappingDescription string
3111 -
3112 - NewLeaseDuration string
3113 - }{}
3114 -
3115 - // Perform the SOAP call.
3116 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetGenericPortMappingEntry", request, response); err != nil {
3117 - return
3118 - }
3119 -
3120 - // BEGIN Unmarshal arguments from response.
3121 -
3122 - if NewRemoteHost, err = soap.UnmarshalString(response.NewRemoteHost); err != nil {
3123 - return
3124 - }
3125 - if NewExternalPort, err = soap.UnmarshalUi2(response.NewExternalPort); err != nil {
3126 - return
3127 - }
3128 - if NewProtocol, err = soap.UnmarshalString(response.NewProtocol); err != nil {
3129 - return
3130 - }
3131 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
3132 - return
3133 - }
3134 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
3135 - return
3136 - }
3137 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
3138 - return
3139 - }
3140 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
3141 - return
3142 - }
3143 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
3144 - return
3145 - }
3146 - // END Unmarshal arguments from response.
3147 - return
3148 -}
3149 -
3150 -// Arguments:
3151 -//
3152 -// * NewRemoteHost:
3153 -//
3154 -// * NewExternalPort:
3155 -//
3156 -// * NewProtocol: allowed values: TCP, UDP
3157 -//
3158 -// Return values:
3159 -//
3160 -// * NewInternalPort: allowed value range: minimum=1, maximum=65535
3161 -//
3162 -// * NewInternalClient:
3163 -//
3164 -// * NewEnabled:
3165 -//
3166 -// * NewPortMappingDescription:
3167 -//
3168 -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800
3169 -func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
3170 - // Request structure.
3171 - request := &struct {
3172 - NewRemoteHost string
3173 -
3174 - NewExternalPort string
3175 -
3176 - NewProtocol string
3177 - }{}
3178 - // BEGIN Marshal arguments into request.
3179 -
3180 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
3181 - return
3182 - }
3183 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
3184 - return
3185 - }
3186 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3187 - return
3188 - }
3189 - // END Marshal arguments into request.
3190 -
3191 - // Response structure.
3192 - response := &struct {
3193 - NewInternalPort string
3194 -
3195 - NewInternalClient string
3196 -
3197 - NewEnabled string
3198 -
3199 - NewPortMappingDescription string
3200 -
3201 - NewLeaseDuration string
3202 - }{}
3203 -
3204 - // Perform the SOAP call.
3205 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetSpecificPortMappingEntry", request, response); err != nil {
3206 - return
3207 - }
3208 -
3209 - // BEGIN Unmarshal arguments from response.
3210 -
3211 - if NewInternalPort, err = soap.UnmarshalUi2(response.NewInternalPort); err != nil {
3212 - return
3213 - }
3214 - if NewInternalClient, err = soap.UnmarshalString(response.NewInternalClient); err != nil {
3215 - return
3216 - }
3217 - if NewEnabled, err = soap.UnmarshalBoolean(response.NewEnabled); err != nil {
3218 - return
3219 - }
3220 - if NewPortMappingDescription, err = soap.UnmarshalString(response.NewPortMappingDescription); err != nil {
3221 - return
3222 - }
3223 - if NewLeaseDuration, err = soap.UnmarshalUi4(response.NewLeaseDuration); err != nil {
3224 - return
3225 - }
3226 - // END Unmarshal arguments from response.
3227 - return
3228 -}
3229 -
3230 -// Arguments:
3231 -//
3232 -// * NewRemoteHost:
3233 -//
3234 -// * NewExternalPort:
3235 -//
3236 -// * NewProtocol: allowed values: TCP, UDP
3237 -//
3238 -// * NewInternalPort: allowed value range: minimum=1, maximum=65535
3239 -//
3240 -// * NewInternalClient:
3241 -//
3242 -// * NewEnabled:
3243 -//
3244 -// * NewPortMappingDescription:
3245 -//
3246 -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800
3247 -//
3248 -//
3249 -func (client *WANIPConnection2) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) {
3250 - // Request structure.
3251 - request := &struct {
3252 - NewRemoteHost string
3253 -
3254 - NewExternalPort string
3255 -
3256 - NewProtocol string
3257 -
3258 - NewInternalPort string
3259 -
3260 - NewInternalClient string
3261 -
3262 - NewEnabled string
3263 -
3264 - NewPortMappingDescription string
3265 -
3266 - NewLeaseDuration string
3267 - }{}
3268 - // BEGIN Marshal arguments into request.
3269 -
3270 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
3271 - return
3272 - }
3273 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
3274 - return
3275 - }
3276 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3277 - return
3278 - }
3279 - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil {
3280 - return
3281 - }
3282 - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil {
3283 - return
3284 - }
3285 - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil {
3286 - return
3287 - }
3288 - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil {
3289 - return
3290 - }
3291 - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil {
3292 - return
3293 - }
3294 - // END Marshal arguments into request.
3295 -
3296 - // Response structure.
3297 - response := interface{}(nil)
3298 -
3299 - // Perform the SOAP call.
3300 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "AddPortMapping", request, response); err != nil {
3301 - return
3302 - }
3303 -
3304 - // BEGIN Unmarshal arguments from response.
3305 -
3306 - // END Unmarshal arguments from response.
3307 - return
3308 -}
3309 -
3310 -// Arguments:
3311 -//
3312 -// * NewRemoteHost:
3313 -//
3314 -// * NewExternalPort:
3315 -//
3316 -// * NewProtocol: allowed values: TCP, UDP
3317 -//
3318 -//
3319 -func (client *WANIPConnection2) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) {
3320 - // Request structure.
3321 - request := &struct {
3322 - NewRemoteHost string
3323 -
3324 - NewExternalPort string
3325 -
3326 - NewProtocol string
3327 - }{}
3328 - // BEGIN Marshal arguments into request.
3329 -
3330 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
3331 - return
3332 - }
3333 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
3334 - return
3335 - }
3336 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3337 - return
3338 - }
3339 - // END Marshal arguments into request.
3340 -
3341 - // Response structure.
3342 - response := interface{}(nil)
3343 -
3344 - // Perform the SOAP call.
3345 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "DeletePortMapping", request, response); err != nil {
3346 - return
3347 - }
3348 -
3349 - // BEGIN Unmarshal arguments from response.
3350 -
3351 - // END Unmarshal arguments from response.
3352 - return
3353 -}
3354 -
3355 -// Arguments:
3356 -//
3357 -// * NewStartPort:
3358 -//
3359 -// * NewEndPort:
3360 -//
3361 -// * NewProtocol: allowed values: TCP, UDP
3362 -//
3363 -// * NewManage:
3364 -//
3365 -//
3366 -func (client *WANIPConnection2) DeletePortMappingRange(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool) (err error) {
3367 - // Request structure.
3368 - request := &struct {
3369 - NewStartPort string
3370 -
3371 - NewEndPort string
3372 -
3373 - NewProtocol string
3374 -
3375 - NewManage string
3376 - }{}
3377 - // BEGIN Marshal arguments into request.
3378 -
3379 - if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil {
3380 - return
3381 - }
3382 - if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil {
3383 - return
3384 - }
3385 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3386 - return
3387 - }
3388 - if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil {
3389 - return
3390 - }
3391 - // END Marshal arguments into request.
3392 -
3393 - // Response structure.
3394 - response := interface{}(nil)
3395 -
3396 - // Perform the SOAP call.
3397 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "DeletePortMappingRange", request, response); err != nil {
3398 - return
3399 - }
3400 -
3401 - // BEGIN Unmarshal arguments from response.
3402 -
3403 - // END Unmarshal arguments from response.
3404 - return
3405 -}
3406 -
3407 -//
3408 -//
3409 -// Return values:
3410 -//
3411 -// * NewExternalIPAddress:
3412 -func (client *WANIPConnection2) GetExternalIPAddress() (NewExternalIPAddress string, err error) {
3413 - // Request structure.
3414 - request := interface{}(nil)
3415 - // BEGIN Marshal arguments into request.
3416 -
3417 - // END Marshal arguments into request.
3418 -
3419 - // Response structure.
3420 - response := &struct {
3421 - NewExternalIPAddress string
3422 - }{}
3423 -
3424 - // Perform the SOAP call.
3425 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetExternalIPAddress", request, response); err != nil {
3426 - return
3427 - }
3428 -
3429 - // BEGIN Unmarshal arguments from response.
3430 -
3431 - if NewExternalIPAddress, err = soap.UnmarshalString(response.NewExternalIPAddress); err != nil {
3432 - return
3433 - }
3434 - // END Unmarshal arguments from response.
3435 - return
3436 -}
3437 -
3438 -// Arguments:
3439 -//
3440 -// * NewStartPort:
3441 -//
3442 -// * NewEndPort:
3443 -//
3444 -// * NewProtocol: allowed values: TCP, UDP
3445 -//
3446 -// * NewManage:
3447 -//
3448 -// * NewNumberOfPorts:
3449 -//
3450 -// Return values:
3451 -//
3452 -// * NewPortListing:
3453 -func (client *WANIPConnection2) GetListOfPortMappings(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool, NewNumberOfPorts uint16) (NewPortListing string, err error) {
3454 - // Request structure.
3455 - request := &struct {
3456 - NewStartPort string
3457 -
3458 - NewEndPort string
3459 -
3460 - NewProtocol string
3461 -
3462 - NewManage string
3463 -
3464 - NewNumberOfPorts string
3465 - }{}
3466 - // BEGIN Marshal arguments into request.
3467 -
3468 - if request.NewStartPort, err = soap.MarshalUi2(NewStartPort); err != nil {
3469 - return
3470 - }
3471 - if request.NewEndPort, err = soap.MarshalUi2(NewEndPort); err != nil {
3472 - return
3473 - }
3474 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3475 - return
3476 - }
3477 - if request.NewManage, err = soap.MarshalBoolean(NewManage); err != nil {
3478 - return
3479 - }
3480 - if request.NewNumberOfPorts, err = soap.MarshalUi2(NewNumberOfPorts); err != nil {
3481 - return
3482 - }
3483 - // END Marshal arguments into request.
3484 -
3485 - // Response structure.
3486 - response := &struct {
3487 - NewPortListing string
3488 - }{}
3489 -
3490 - // Perform the SOAP call.
3491 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "GetListOfPortMappings", request, response); err != nil {
3492 - return
3493 - }
3494 -
3495 - // BEGIN Unmarshal arguments from response.
3496 -
3497 - if NewPortListing, err = soap.UnmarshalString(response.NewPortListing); err != nil {
3498 - return
3499 - }
3500 - // END Unmarshal arguments from response.
3501 - return
3502 -}
3503 -
3504 -// Arguments:
3505 -//
3506 -// * NewRemoteHost:
3507 -//
3508 -// * NewExternalPort:
3509 -//
3510 -// * NewProtocol: allowed values: TCP, UDP
3511 -//
3512 -// * NewInternalPort: allowed value range: minimum=1, maximum=65535
3513 -//
3514 -// * NewInternalClient:
3515 -//
3516 -// * NewEnabled:
3517 -//
3518 -// * NewPortMappingDescription:
3519 -//
3520 -// * NewLeaseDuration: allowed value range: minimum=0, maximum=604800
3521 -//
3522 -// Return values:
3523 -//
3524 -// * NewReservedPort:
3525 -func (client *WANIPConnection2) AddAnyPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (NewReservedPort uint16, err error) {
3526 - // Request structure.
3527 - request := &struct {
3528 - NewRemoteHost string
3529 -
3530 - NewExternalPort string
3531 -
3532 - NewProtocol string
3533 -
3534 - NewInternalPort string
3535 -
3536 - NewInternalClient string
3537 -
3538 - NewEnabled string
3539 -
3540 - NewPortMappingDescription string
3541 -
3542 - NewLeaseDuration string
3543 - }{}
3544 - // BEGIN Marshal arguments into request.
3545 -
3546 - if request.NewRemoteHost, err = soap.MarshalString(NewRemoteHost); err != nil {
3547 - return
3548 - }
3549 - if request.NewExternalPort, err = soap.MarshalUi2(NewExternalPort); err != nil {
3550 - return
3551 - }
3552 - if request.NewProtocol, err = soap.MarshalString(NewProtocol); err != nil {
3553 - return
3554 - }
3555 - if request.NewInternalPort, err = soap.MarshalUi2(NewInternalPort); err != nil {
3556 - return
3557 - }
3558 - if request.NewInternalClient, err = soap.MarshalString(NewInternalClient); err != nil {
3559 - return
3560 - }
3561 - if request.NewEnabled, err = soap.MarshalBoolean(NewEnabled); err != nil {
3562 - return
3563 - }
3564 - if request.NewPortMappingDescription, err = soap.MarshalString(NewPortMappingDescription); err != nil {
3565 - return
3566 - }
3567 - if request.NewLeaseDuration, err = soap.MarshalUi4(NewLeaseDuration); err != nil {
3568 - return
3569 - }
3570 - // END Marshal arguments into request.
3571 -
3572 - // Response structure.
3573 - response := &struct {
3574 - NewReservedPort string
3575 - }{}
3576 -
3577 - // Perform the SOAP call.
3578 - if err = client.SOAPClient.PerformAction(URN_WANIPConnection_2, "AddAnyPortMapping", request, response); err != nil {
3579 - return
3580 - }
3581 -
3582 - // BEGIN Unmarshal arguments from response.
3583 -
3584 - if NewReservedPort, err = soap.UnmarshalUi2(response.NewReservedPort); err != nil {
3585 - return
3586 - }
3587 - // END Unmarshal arguments from response.
3588 - return
3589 -}
3590 -
3591 -// WANIPv6FirewallControl1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1". See
3592 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
3593 -// are provided for informational value.
3594 -type WANIPv6FirewallControl1 struct {
3595 - goupnp.ServiceClient
3596 -}
3597 -
3598 -// NewWANIPv6FirewallControl1Clients discovers instances of the service on the network,
3599 -// and returns clients to any that are found. errors will contain an error for
3600 -// any devices that replied but which could not be queried, and err will be set
3601 -// if the discovery process failed outright.
3602 -//
3603 -// This is a typical entry calling point into this package.
3604 -func NewWANIPv6FirewallControl1Clients() (clients []*WANIPv6FirewallControl1, errors []error, err error) {
3605 - var genericClients []goupnp.ServiceClient
3606 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANIPv6FirewallControl_1); err != nil {
3607 - return
3608 - }
3609 - clients = make([]*WANIPv6FirewallControl1, len(genericClients))
3610 - for i := range genericClients {
3611 - clients[i] = &WANIPv6FirewallControl1{genericClients[i]}
3612 - }
3613 - return
3614 -}
3615 -
3616 -//
3617 -//
3618 -// Return values:
3619 -//
3620 -// * FirewallEnabled:
3621 -//
3622 -// * InboundPinholeAllowed:
3623 -func (client *WANIPv6FirewallControl1) GetFirewallStatus() (FirewallEnabled bool, InboundPinholeAllowed bool, err error) {
3624 - // Request structure.
3625 - request := interface{}(nil)
3626 - // BEGIN Marshal arguments into request.
3627 -
3628 - // END Marshal arguments into request.
3629 -
3630 - // Response structure.
3631 - response := &struct {
3632 - FirewallEnabled string
3633 -
3634 - InboundPinholeAllowed string
3635 - }{}
3636 -
3637 - // Perform the SOAP call.
3638 - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetFirewallStatus", request, response); err != nil {
3639 - return
3640 - }
3641 -
3642 - // BEGIN Unmarshal arguments from response.
3643 -
3644 - if FirewallEnabled, err = soap.UnmarshalBoolean(response.FirewallEnabled); err != nil {
3645 - return
3646 - }
3647 - if InboundPinholeAllowed, err = soap.UnmarshalBoolean(response.InboundPinholeAllowed); err != nil {
3648 - return
3649 - }
3650 - // END Unmarshal arguments from response.
3651 - return
3652 -}
3653 -
3654 -// Arguments:
3655 -//
3656 -// * RemoteHost:
3657 -//
3658 -// * RemotePort:
3659 -//
3660 -// * InternalClient:
3661 -//
3662 -// * InternalPort:
3663 -//
3664 -// * Protocol:
3665 -//
3666 -// Return values:
3667 -//
3668 -// * OutboundPinholeTimeout:
3669 -func (client *WANIPv6FirewallControl1) GetOutboundPinholeTimeout(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16) (OutboundPinholeTimeout uint32, err error) {
3670 - // Request structure.
3671 - request := &struct {
3672 - RemoteHost string
3673 -
3674 - RemotePort string
3675 -
3676 - InternalClient string
3677 -
3678 - InternalPort string
3679 -
3680 - Protocol string
3681 - }{}
3682 - // BEGIN Marshal arguments into request.
3683 -
3684 - if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil {
3685 - return
3686 - }
3687 - if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil {
3688 - return
3689 - }
3690 - if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil {
3691 - return
3692 - }
3693 - if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil {
3694 - return
3695 - }
3696 - if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil {
3697 - return
3698 - }
3699 - // END Marshal arguments into request.
3700 -
3701 - // Response structure.
3702 - response := &struct {
3703 - OutboundPinholeTimeout string
3704 - }{}
3705 -
3706 - // Perform the SOAP call.
3707 - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetOutboundPinholeTimeout", request, response); err != nil {
3708 - return
3709 - }
3710 -
3711 - // BEGIN Unmarshal arguments from response.
3712 -
3713 - if OutboundPinholeTimeout, err = soap.UnmarshalUi4(response.OutboundPinholeTimeout); err != nil {
3714 - return
3715 - }
3716 - // END Unmarshal arguments from response.
3717 - return
3718 -}
3719 -
3720 -// Arguments:
3721 -//
3722 -// * RemoteHost:
3723 -//
3724 -// * RemotePort:
3725 -//
3726 -// * InternalClient:
3727 -//
3728 -// * InternalPort:
3729 -//
3730 -// * Protocol:
3731 -//
3732 -// * LeaseTime: allowed value range: minimum=1, maximum=86400
3733 -//
3734 -// Return values:
3735 -//
3736 -// * UniqueID:
3737 -func (client *WANIPv6FirewallControl1) AddPinhole(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16, LeaseTime uint32) (UniqueID uint16, err error) {
3738 - // Request structure.
3739 - request := &struct {
3740 - RemoteHost string
3741 -
3742 - RemotePort string
3743 -
3744 - InternalClient string
3745 -
3746 - InternalPort string
3747 -
3748 - Protocol string
3749 -
3750 - LeaseTime string
3751 - }{}
3752 - // BEGIN Marshal arguments into request.
3753 -
3754 - if request.RemoteHost, err = soap.MarshalString(RemoteHost); err != nil {
3755 - return
3756 - }
3757 - if request.RemotePort, err = soap.MarshalUi2(RemotePort); err != nil {
3758 - return
3759 - }
3760 - if request.InternalClient, err = soap.MarshalString(InternalClient); err != nil {
3761 - return
3762 - }
3763 - if request.InternalPort, err = soap.MarshalUi2(InternalPort); err != nil {
3764 - return
3765 - }
3766 - if request.Protocol, err = soap.MarshalUi2(Protocol); err != nil {
3767 - return
3768 - }
3769 - if request.LeaseTime, err = soap.MarshalUi4(LeaseTime); err != nil {
3770 - return
3771 - }
3772 - // END Marshal arguments into request.
3773 -
3774 - // Response structure.
3775 - response := &struct {
3776 - UniqueID string
3777 - }{}
3778 -
3779 - // Perform the SOAP call.
3780 - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "AddPinhole", request, response); err != nil {
3781 - return
3782 - }
3783 -
3784 - // BEGIN Unmarshal arguments from response.
3785 -
3786 - if UniqueID, err = soap.UnmarshalUi2(response.UniqueID); err != nil {
3787 - return
3788 - }
3789 - // END Unmarshal arguments from response.
3790 - return
3791 -}
3792 -
3793 -// Arguments:
3794 -//
3795 -// * UniqueID:
3796 -//
3797 -// * NewLeaseTime: allowed value range: minimum=1, maximum=86400
3798 -//
3799 -//
3800 -func (client *WANIPv6FirewallControl1) UpdatePinhole(UniqueID uint16, NewLeaseTime uint32) (err error) {
3801 - // Request structure.
3802 - request := &struct {
3803 - UniqueID string
3804 -
3805 - NewLeaseTime string
3806 - }{}
3807 - // BEGIN Marshal arguments into request.
3808 -
3809 - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil {
3810 - return
3811 - }
3812 - if request.NewLeaseTime, err = soap.MarshalUi4(NewLeaseTime); err != nil {
3813 - return
3814 - }
3815 - // END Marshal arguments into request.
3816 -
3817 - // Response structure.
3818 - response := interface{}(nil)
3819 -
3820 - // Perform the SOAP call.
3821 - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "UpdatePinhole", request, response); err != nil {
3822 - return
3823 - }
3824 -
3825 - // BEGIN Unmarshal arguments from response.
3826 -
3827 - // END Unmarshal arguments from response.
3828 - return
3829 -}
3830 -
3831 -// Arguments:
3832 -//
3833 -// * UniqueID:
3834 -//
3835 -//
3836 -func (client *WANIPv6FirewallControl1) DeletePinhole(UniqueID uint16) (err error) {
3837 - // Request structure.
3838 - request := &struct {
3839 - UniqueID string
3840 - }{}
3841 - // BEGIN Marshal arguments into request.
3842 -
3843 - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil {
3844 - return
3845 - }
3846 - // END Marshal arguments into request.
3847 -
3848 - // Response structure.
3849 - response := interface{}(nil)
3850 -
3851 - // Perform the SOAP call.
3852 - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "DeletePinhole", request, response); err != nil {
3853 - return
3854 - }
3855 -
3856 - // BEGIN Unmarshal arguments from response.
3857 -
3858 - // END Unmarshal arguments from response.
3859 - return
3860 -}
3861 -
3862 -// Arguments:
3863 -//
3864 -// * UniqueID:
3865 -//
3866 -// Return values:
3867 -//
3868 -// * PinholePackets:
3869 -func (client *WANIPv6FirewallControl1) GetPinholePackets(UniqueID uint16) (PinholePackets uint32, err error) {
3870 - // Request structure.
3871 - request := &struct {
3872 - UniqueID string
3873 - }{}
3874 - // BEGIN Marshal arguments into request.
3875 -
3876 - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil {
3877 - return
3878 - }
3879 - // END Marshal arguments into request.
3880 -
3881 - // Response structure.
3882 - response := &struct {
3883 - PinholePackets string
3884 - }{}
3885 -
3886 - // Perform the SOAP call.
3887 - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "GetPinholePackets", request, response); err != nil {
3888 - return
3889 - }
3890 -
3891 - // BEGIN Unmarshal arguments from response.
3892 -
3893 - if PinholePackets, err = soap.UnmarshalUi4(response.PinholePackets); err != nil {
3894 - return
3895 - }
3896 - // END Unmarshal arguments from response.
3897 - return
3898 -}
3899 -
3900 -// Arguments:
3901 -//
3902 -// * UniqueID:
3903 -//
3904 -// Return values:
3905 -//
3906 -// * IsWorking:
3907 -func (client *WANIPv6FirewallControl1) CheckPinholeWorking(UniqueID uint16) (IsWorking bool, err error) {
3908 - // Request structure.
3909 - request := &struct {
3910 - UniqueID string
3911 - }{}
3912 - // BEGIN Marshal arguments into request.
3913 -
3914 - if request.UniqueID, err = soap.MarshalUi2(UniqueID); err != nil {
3915 - return
3916 - }
3917 - // END Marshal arguments into request.
3918 -
3919 - // Response structure.
3920 - response := &struct {
3921 - IsWorking string
3922 - }{}
3923 -
3924 - // Perform the SOAP call.
3925 - if err = client.SOAPClient.PerformAction(URN_WANIPv6FirewallControl_1, "CheckPinholeWorking", request, response); err != nil {
3926 - return
3927 - }
3928 -
3929 - // BEGIN Unmarshal arguments from response.
3930 -
3931 - if IsWorking, err = soap.UnmarshalBoolean(response.IsWorking); err != nil {
3932 - return
3933 - }
3934 - // END Unmarshal arguments from response.
3935 - return
3936 -}
3937 -
3938 -// WANPOTSLinkConfig1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPOTSLinkConfig:1". See
3939 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
3940 -// are provided for informational value.
3941 -type WANPOTSLinkConfig1 struct {
3942 - goupnp.ServiceClient
3943 -}
3944 -
3945 -// NewWANPOTSLinkConfig1Clients discovers instances of the service on the network,
3946 -// and returns clients to any that are found. errors will contain an error for
3947 -// any devices that replied but which could not be queried, and err will be set
3948 -// if the discovery process failed outright.
3949 -//
3950 -// This is a typical entry calling point into this package.
3951 -func NewWANPOTSLinkConfig1Clients() (clients []*WANPOTSLinkConfig1, errors []error, err error) {
3952 - var genericClients []goupnp.ServiceClient
3953 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPOTSLinkConfig_1); err != nil {
3954 - return
3955 - }
3956 - clients = make([]*WANPOTSLinkConfig1, len(genericClients))
3957 - for i := range genericClients {
3958 - clients[i] = &WANPOTSLinkConfig1{genericClients[i]}
3959 - }
3960 - return
3961 -}
3962 -
3963 -// Arguments:
3964 -//
3965 -// * NewISPPhoneNumber:
3966 -//
3967 -// * NewISPInfo:
3968 -//
3969 -// * NewLinkType: allowed values: PPP_Dialup
3970 -//
3971 -//
3972 -func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInfo string, NewLinkType string) (err error) {
3973 - // Request structure.
3974 - request := &struct {
3975 - NewISPPhoneNumber string
3976 -
3977 - NewISPInfo string
3978 -
3979 - NewLinkType string
3980 - }{}
3981 - // BEGIN Marshal arguments into request.
3982 -
3983 - if request.NewISPPhoneNumber, err = soap.MarshalString(NewISPPhoneNumber); err != nil {
3984 - return
3985 - }
3986 - if request.NewISPInfo, err = soap.MarshalString(NewISPInfo); err != nil {
3987 - return
3988 - }
3989 - if request.NewLinkType, err = soap.MarshalString(NewLinkType); err != nil {
3990 - return
3991 - }
3992 - // END Marshal arguments into request.
3993 -
3994 - // Response structure.
3995 - response := interface{}(nil)
3996 -
3997 - // Perform the SOAP call.
3998 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetISPInfo", request, response); err != nil {
3999 - return
4000 - }
4001 -
4002 - // BEGIN Unmarshal arguments from response.
4003 -
4004 - // END Unmarshal arguments from response.
4005 - return
4006 -}
4007 -
4008 -// Arguments:
4009 -//
4010 -// * NewNumberOfRetries:
4011 -//
4012 -// * NewDelayBetweenRetries:
4013 -//
4014 -//
4015 -func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) {
4016 - // Request structure.
4017 - request := &struct {
4018 - NewNumberOfRetries string
4019 -
4020 - NewDelayBetweenRetries string
4021 - }{}
4022 - // BEGIN Marshal arguments into request.
4023 -
4024 - if request.NewNumberOfRetries, err = soap.MarshalUi4(NewNumberOfRetries); err != nil {
4025 - return
4026 - }
4027 - if request.NewDelayBetweenRetries, err = soap.MarshalUi4(NewDelayBetweenRetries); err != nil {
4028 - return
4029 - }
4030 - // END Marshal arguments into request.
4031 -
4032 - // Response structure.
4033 - response := interface{}(nil)
4034 -
4035 - // Perform the SOAP call.
4036 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "SetCallRetryInfo", request, response); err != nil {
4037 - return
4038 - }
4039 -
4040 - // BEGIN Unmarshal arguments from response.
4041 -
4042 - // END Unmarshal arguments from response.
4043 - return
4044 -}
4045 -
4046 -//
4047 -//
4048 -// Return values:
4049 -//
4050 -// * NewISPPhoneNumber:
4051 -//
4052 -// * NewISPInfo:
4053 -//
4054 -// * NewLinkType: allowed values: PPP_Dialup
4055 -func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISPInfo string, NewLinkType string, err error) {
4056 - // Request structure.
4057 - request := interface{}(nil)
4058 - // BEGIN Marshal arguments into request.
4059 -
4060 - // END Marshal arguments into request.
4061 -
4062 - // Response structure.
4063 - response := &struct {
4064 - NewISPPhoneNumber string
4065 -
4066 - NewISPInfo string
4067 -
4068 - NewLinkType string
4069 - }{}
4070 -
4071 - // Perform the SOAP call.
4072 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetISPInfo", request, response); err != nil {
4073 - return
4074 - }
4075 -
4076 - // BEGIN Unmarshal arguments from response.
4077 -
4078 - if NewISPPhoneNumber, err = soap.UnmarshalString(response.NewISPPhoneNumber); err != nil {
4079 - return
4080 - }
4081 - if NewISPInfo, err = soap.UnmarshalString(response.NewISPInfo); err != nil {
4082 - return
4083 - }
4084 - if NewLinkType, err = soap.UnmarshalString(response.NewLinkType); err != nil {
4085 - return
4086 - }
4087 - // END Unmarshal arguments from response.
4088 - return
4089 -}
4090 -
4091 -//
4092 -//
4093 -// Return values:
4094 -//
4095 -// * NewNumberOfRetries:
4096 -//
4097 -// * NewDelayBetweenRetries:
4098 -func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, NewDelayBetweenRetries uint32, err error) {
4099 - // Request structure.
4100 - request := interface{}(nil)
4101 - // BEGIN Marshal arguments into request.
4102 -
4103 - // END Marshal arguments into request.
4104 -
4105 - // Response structure.
4106 - response := &struct {
4107 - NewNumberOfRetries string
4108 -
4109 - NewDelayBetweenRetries string
4110 - }{}
4111 -
4112 - // Perform the SOAP call.
4113 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetCallRetryInfo", request, response); err != nil {
4114 - return
4115 - }
4116 -
4117 - // BEGIN Unmarshal arguments from response.
4118 -
4119 - if NewNumberOfRetries, err = soap.UnmarshalUi4(response.NewNumberOfRetries); err != nil {
4120 - return
4121 - }
4122 - if NewDelayBetweenRetries, err = soap.UnmarshalUi4(response.NewDelayBetweenRetries); err != nil {
4123 - return
4124 - }
4125 - // END Unmarshal arguments from response.
4126 - return
4127 -}
4128 -
4129 -//
4130 -//
4131 -// Return values:
4132 -//
4133 -// * NewFclass:
4134 -func (client *WANPOTSLinkConfig1) GetFclass() (NewFclass string, err error) {
4135 - // Request structure.
4136 - request := interface{}(nil)
4137 - // BEGIN Marshal arguments into request.
4138 -
4139 - // END Marshal arguments into request.
4140 -
4141 - // Response structure.
4142 - response := &struct {
4143 - NewFclass string
4144 - }{}
4145 -
4146 - // Perform the SOAP call.
4147 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetFclass", request, response); err != nil {
4148 - return
4149 - }
4150 -
4151 - // BEGIN Unmarshal arguments from response.
4152 -
4153 - if NewFclass, err = soap.UnmarshalString(response.NewFclass); err != nil {
4154 - return
4155 - }
4156 - // END Unmarshal arguments from response.
4157 - return
4158 -}
4159 -
4160 -//
4161 -//
4162 -// Return values:
4163 -//
4164 -// * NewDataModulationSupported:
4165 -func (client *WANPOTSLinkConfig1) GetDataModulationSupported() (NewDataModulationSupported string, err error) {
4166 - // Request structure.
4167 - request := interface{}(nil)
4168 - // BEGIN Marshal arguments into request.
4169 -
4170 - // END Marshal arguments into request.
4171 -
4172 - // Response structure.
4173 - response := &struct {
4174 - NewDataModulationSupported string
4175 - }{}
4176 -
4177 - // Perform the SOAP call.
4178 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataModulationSupported", request, response); err != nil {
4179 - return
4180 - }
4181 -
4182 - // BEGIN Unmarshal arguments from response.
4183 -
4184 - if NewDataModulationSupported, err = soap.UnmarshalString(response.NewDataModulationSupported); err != nil {
4185 - return
4186 - }
4187 - // END Unmarshal arguments from response.
4188 - return
4189 -}
4190 -
4191 -//
4192 -//
4193 -// Return values:
4194 -//
4195 -// * NewDataProtocol:
4196 -func (client *WANPOTSLinkConfig1) GetDataProtocol() (NewDataProtocol string, err error) {
4197 - // Request structure.
4198 - request := interface{}(nil)
4199 - // BEGIN Marshal arguments into request.
4200 -
4201 - // END Marshal arguments into request.
4202 -
4203 - // Response structure.
4204 - response := &struct {
4205 - NewDataProtocol string
4206 - }{}
4207 -
4208 - // Perform the SOAP call.
4209 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataProtocol", request, response); err != nil {
4210 - return
4211 - }
4212 -
4213 - // BEGIN Unmarshal arguments from response.
4214 -
4215 - if NewDataProtocol, err = soap.UnmarshalString(response.NewDataProtocol); err != nil {
4216 - return
4217 - }
4218 - // END Unmarshal arguments from response.
4219 - return
4220 -}
4221 -
4222 -//
4223 -//
4224 -// Return values:
4225 -//
4226 -// * NewDataCompression:
4227 -func (client *WANPOTSLinkConfig1) GetDataCompression() (NewDataCompression string, err error) {
4228 - // Request structure.
4229 - request := interface{}(nil)
4230 - // BEGIN Marshal arguments into request.
4231 -
4232 - // END Marshal arguments into request.
4233 -
4234 - // Response structure.
4235 - response := &struct {
4236 - NewDataCompression string
4237 - }{}
4238 -
4239 - // Perform the SOAP call.
4240 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetDataCompression", request, response); err != nil {
4241 - return
4242 - }
4243 -
4244 - // BEGIN Unmarshal arguments from response.
4245 -
4246 - if NewDataCompression, err = soap.UnmarshalString(response.NewDataCompression); err != nil {
4247 - return
4248 - }
4249 - // END Unmarshal arguments from response.
4250 - return
4251 -}
4252 -
4253 -//
4254 -//
4255 -// Return values:
4256 -//
4257 -// * NewPlusVTRCommandSupported:
4258 -func (client *WANPOTSLinkConfig1) GetPlusVTRCommandSupported() (NewPlusVTRCommandSupported bool, err error) {
4259 - // Request structure.
4260 - request := interface{}(nil)
4261 - // BEGIN Marshal arguments into request.
4262 -
4263 - // END Marshal arguments into request.
4264 -
4265 - // Response structure.
4266 - response := &struct {
4267 - NewPlusVTRCommandSupported string
4268 - }{}
4269 -
4270 - // Perform the SOAP call.
4271 - if err = client.SOAPClient.PerformAction(URN_WANPOTSLinkConfig_1, "GetPlusVTRCommandSupported", request, response); err != nil {
4272 - return
4273 - }
4274 -
4275 - // BEGIN Unmarshal arguments from response.
4276 -
4277 - if NewPlusVTRCommandSupported, err = soap.UnmarshalBoolean(response.NewPlusVTRCommandSupported); err != nil {
4278 - return
4279 - }
4280 - // END Unmarshal arguments from response.
4281 - return
4282 -}
4283 -
4284 -// WANPPPConnection1 is a client for UPnP SOAP service with URN "urn:schemas-upnp-org:service:WANPPPConnection:1". See
4285 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
4286 -// are provided for informational value.
4287 -type WANPPPConnection1 struct {
4288 - goupnp.ServiceClient
4289 -}
4290 -
4291 -// NewWANPPPConnection1Clients discovers instances of the service on the network,
4292 -// and returns clients to any that are found. errors will contain an error for
4293 -// any devices that replied but which could not be queried, and err will be set
4294 -// if the discovery process failed outright.
4295 -//
4296 -// This is a typical entry calling point into this package.
4297 -func NewWANPPPConnection1Clients() (clients []*WANPPPConnection1, errors []error, err error) {
4298 - var genericClients []goupnp.ServiceClient
4299 - if genericClients, errors, err = goupnp.NewServiceClients(URN_WANPPPConnection_1); err != nil {
4300 - return
4301 - }
4302 - clients = make([]*WANPPPConnection1, len(genericClients))
4303 - for i := range genericClients {
4304 - clients[i] = &WANPPPConnection1{genericClients[i]}
4305 - }
4306 - return
4307 -}
4308 -
4309 -// Arguments:
4310 -//
4311 -// * NewConnectionType:
4312 -//
4313 -//
4314 -func (client *WANPPPConnection1) SetConnectionType(NewConnectionType string) (err error) {
4315 - // Request structure.
4316 - request := &struct {
4317 - NewConnectionType string
4318 - }{}
4319 - // BEGIN Marshal arguments into request.
4320 -
4321 - if request.NewConnectionType, err = soap.MarshalString(NewConnectionType); err != nil {
4322 - return
4323 - }
4324 - // END Marshal arguments into request.
4325 -
4326 - // Response structure.
4327 - response := interface{}(nil)
4328 -
4329 - // Perform the SOAP call.
4330 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetConnectionType", request, response); err != nil {
4331 - return
4332 - }
4333 -
4334 - // BEGIN Unmarshal arguments from response.
4335 -
4336 - // END Unmarshal arguments from response.
4337 - return
4338 -}
4339 -
4340 -//
4341 -//
4342 -// Return values:
4343 -//
4344 -// * NewConnectionType:
4345 -//
4346 -// * NewPossibleConnectionTypes: allowed values: Unconfigured, IP_Routed, DHCP_Spoofed, PPPoE_Bridged, PPTP_Relay, L2TP_Relay, PPPoE_Relay
4347 -func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType string, NewPossibleConnectionTypes string, err error) {
4348 - // Request structure.
4349 - request := interface{}(nil)
4350 - // BEGIN Marshal arguments into request.
4351 -
4352 - // END Marshal arguments into request.
4353 -
4354 - // Response structure.
4355 - response := &struct {
4356 - NewConnectionType string
4357 -
4358 - NewPossibleConnectionTypes string
4359 - }{}
4360 -
4361 - // Perform the SOAP call.
4362 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetConnectionTypeInfo", request, response); err != nil {
4363 - return
4364 - }
4365 -
4366 - // BEGIN Unmarshal arguments from response.
4367 -
4368 - if NewConnectionType, err = soap.UnmarshalString(response.NewConnectionType); err != nil {
4369 - return
4370 - }
4371 - if NewPossibleConnectionTypes, err = soap.UnmarshalString(response.NewPossibleConnectionTypes); err != nil {
4372 - return
4373 - }
4374 - // END Unmarshal arguments from response.
4375 - return
4376 -}
4377 -
4378 -// Arguments:
4379 -//
4380 -// * NewUserName:
4381 -//
4382 -// * NewPassword:
4383 -//
4384 -//
4385 -func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPassword string) (err error) {
4386 - // Request structure.
4387 - request := &struct {
4388 - NewUserName string
4389 -
4390 - NewPassword string
4391 - }{}
4392 - // BEGIN Marshal arguments into request.
4393 -
4394 - if request.NewUserName, err = soap.MarshalString(NewUserName); err != nil {
4395 - return
4396 - }
4397 - if request.NewPassword, err = soap.MarshalString(NewPassword); err != nil {
4398 - return
4399 - }
4400 - // END Marshal arguments into request.
4401 -
4402 - // Response structure.
4403 - response := interface{}(nil)
4404 -
4405 - // Perform the SOAP call.
4406 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ConfigureConnection", request, response); err != nil {
4407 - return
4408 - }
4409 -
4410 - // BEGIN Unmarshal arguments from response.
4411 -
4412 - // END Unmarshal arguments from response.
4413 - return
4414 -}
4415 -
4416 -//
4417 -//
4418 -//
4419 -func (client *WANPPPConnection1) RequestConnection() (err error) {
4420 - // Request structure.
4421 - request := interface{}(nil)
4422 - // BEGIN Marshal arguments into request.
4423 -
4424 - // END Marshal arguments into request.
4425 -
4426 - // Response structure.
4427 - response := interface{}(nil)
4428 -
4429 - // Perform the SOAP call.
4430 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestConnection", request, response); err != nil {
4431 - return
4432 - }
4433 -
4434 - // BEGIN Unmarshal arguments from response.
4435 -
4436 - // END Unmarshal arguments from response.
4437 - return
4438 -}
4439 -
4440 -//
4441 -//
4442 -//
4443 -func (client *WANPPPConnection1) RequestTermination() (err error) {
4444 - // Request structure.
4445 - request := interface{}(nil)
4446 - // BEGIN Marshal arguments into request.
4447 -
4448 - // END Marshal arguments into request.
4449 -
4450 - // Response structure.
4451 - response := interface{}(nil)
4452 -
4453 - // Perform the SOAP call.
4454 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "RequestTermination", request, response); err != nil {
4455 - return
4456 - }
4457 -
4458 - // BEGIN Unmarshal arguments from response.
4459 -
4460 - // END Unmarshal arguments from response.
4461 - return
4462 -}
4463 -
4464 -//
4465 -//
4466 -//
4467 -func (client *WANPPPConnection1) ForceTermination() (err error) {
4468 - // Request structure.
4469 - request := interface{}(nil)
4470 - // BEGIN Marshal arguments into request.
4471 -
4472 - // END Marshal arguments into request.
4473 -
4474 - // Response structure.
4475 - response := interface{}(nil)
4476 -
4477 - // Perform the SOAP call.
4478 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "ForceTermination", request, response); err != nil {
4479 - return
4480 - }
4481 -
4482 - // BEGIN Unmarshal arguments from response.
4483 -
4484 - // END Unmarshal arguments from response.
4485 - return
4486 -}
4487 -
4488 -// Arguments:
4489 -//
4490 -// * NewAutoDisconnectTime:
4491 -//
4492 -//
4493 -func (client *WANPPPConnection1) SetAutoDisconnectTime(NewAutoDisconnectTime uint32) (err error) {
4494 - // Request structure.
4495 - request := &struct {
4496 - NewAutoDisconnectTime string
4497 - }{}
4498 - // BEGIN Marshal arguments into request.
4499 -
4500 - if request.NewAutoDisconnectTime, err = soap.MarshalUi4(NewAutoDisconnectTime); err != nil {
4501 - return
4502 - }
4503 - // END Marshal arguments into request.
4504 -
4505 - // Response structure.
4506 - response := interface{}(nil)
4507 -
4508 - // Perform the SOAP call.
4509 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetAutoDisconnectTime", request, response); err != nil {
4510 - return
4511 - }
4512 -
4513 - // BEGIN Unmarshal arguments from response.
4514 -
4515 - // END Unmarshal arguments from response.
4516 - return
4517 -}
4518 -
4519 -// Arguments:
4520 -//
4521 -// * NewIdleDisconnectTime:
4522 -//
4523 -//
4524 -func (client *WANPPPConnection1) SetIdleDisconnectTime(NewIdleDisconnectTime uint32) (err error) {
4525 - // Request structure.
4526 - request := &struct {
4527 - NewIdleDisconnectTime string
4528 - }{}
4529 - // BEGIN Marshal arguments into request.
4530 -
4531 - if request.NewIdleDisconnectTime, err = soap.MarshalUi4(NewIdleDisconnectTime); err != nil {
4532 - return
4533 - }
4534 - // END Marshal arguments into request.
4535 -
4536 - // Response structure.
4537 - response := interface{}(nil)
4538 -
4539 - // Perform the SOAP call.
4540 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetIdleDisconnectTime", request, response); err != nil {
4541 - return
4542 - }
4543 -
4544 - // BEGIN Unmarshal arguments from response.
4545 -
4546 - // END Unmarshal arguments from response.
4547 - return
4548 -}
4549 -
4550 -// Arguments:
4551 -//
4552 -// * NewWarnDisconnectDelay:
4553 -//
4554 -//
4555 -func (client *WANPPPConnection1) SetWarnDisconnectDelay(NewWarnDisconnectDelay uint32) (err error) {
4556 - // Request structure.
4557 - request := &struct {
4558 - NewWarnDisconnectDelay string
4559 - }{}
4560 - // BEGIN Marshal arguments into request.
4561 -
4562 - if request.NewWarnDisconnectDelay, err = soap.MarshalUi4(NewWarnDisconnectDelay); err != nil {
4563 - return
4564 - }
4565 - // END Marshal arguments into request.
4566 -
4567 - // Response structure.
4568 - response := interface{}(nil)
4569 -
4570 - // Perform the SOAP call.
4571 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "SetWarnDisconnectDelay", request, response); err != nil {
4572 - return
4573 - }
4574 -
4575 - // BEGIN Unmarshal arguments from response.
4576 -
4577 - // END Unmarshal arguments from response.
4578 - return
4579 -}
4580 -
4581 -//
4582 -//
4583 -// Return values:
4584 -//
4585 -// * NewConnectionStatus: allowed values: Unconfigured, Connected, Disconnected
4586 -//
4587 -// * NewLastConnectionError: allowed values: ERROR_NONE
4588 -//
4589 -// * NewUptime:
4590 -func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, NewLastConnectionError string, NewUptime uint32, err error) {
4591 - // Request structure.
4592 - request := interface{}(nil)
4593 - // BEGIN Marshal arguments into request.
4594 -
4595 - // END Marshal arguments into request.
4596 -
4597 - // Response structure.
4598 - response := &struct {
4599 - NewConnectionStatus string
4600 -
4601 - NewLastConnectionError string
4602 -
4603 - NewUptime string
4604 - }{}
4605 -
4606 - // Perform the SOAP call.
4607 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetStatusInfo", request, response); err != nil {
4608 - return
4609 - }
4610 -
4611 - // BEGIN Unmarshal arguments from response.
4612 -
4613 - if NewConnectionStatus, err = soap.UnmarshalString(response.NewConnectionStatus); err != nil {
4614 - return
4615 - }
4616 - if NewLastConnectionError, err = soap.UnmarshalString(response.NewLastConnectionError); err != nil {
4617 - return
4618 - }
4619 - if NewUptime, err = soap.UnmarshalUi4(response.NewUptime); err != nil {
4620 - return
4621 - }
4622 - // END Unmarshal arguments from response.
4623 - return
4624 -}
4625 -
4626 -//
4627 -//
4628 -// Return values:
4629 -//
4630 -// * NewUpstreamMaxBitRate:
4631 -//
4632 -// * NewDownstreamMaxBitRate:
4633 -func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRate uint32, NewDownstreamMaxBitRate uint32, err error) {
4634 - // Request structure.
4635 - request := interface{}(nil)
4636 - // BEGIN Marshal arguments into request.
4637 -
4638 - // END Marshal arguments into request.
4639 -
4640 - // Response structure.
4641 - response := &struct {
4642 - NewUpstreamMaxBitRate string
4643 -
4644 - NewDownstreamMaxBitRate string
4645 - }{}
4646 -
4647 - // Perform the SOAP call.
4648 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetLinkLayerMaxBitRates", request, response); err != nil {
4649 - return
4650 - }
4651 -
4652 - // BEGIN Unmarshal arguments from response.
4653 -
4654 - if NewUpstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewUpstreamMaxBitRate); err != nil {
4655 - return
4656 - }
4657 - if NewDownstreamMaxBitRate, err = soap.UnmarshalUi4(response.NewDownstreamMaxBitRate); err != nil {
4658 - return
4659 - }
4660 - // END Unmarshal arguments from response.
4661 - return
4662 -}
4663 -
4664 -//
4665 -//
4666 -// Return values:
4667 -//
4668 -// * NewPPPEncryptionProtocol:
4669 -func (client *WANPPPConnection1) GetPPPEncryptionProtocol() (NewPPPEncryptionProtocol string, err error) {
4670 - // Request structure.
4671 - request := interface{}(nil)
4672 - // BEGIN Marshal arguments into request.
4673 -
4674 - // END Marshal arguments into request.
4675 -
4676 - // Response structure.
4677 - response := &struct {
4678 - NewPPPEncryptionProtocol string
4679 - }{}
4680 -
4681 - // Perform the SOAP call.
4682 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPEncryptionProtocol", request, response); err != nil {
4683 - return
4684 - }
4685 -
4686 - // BEGIN Unmarshal arguments from response.
4687 -
4688 - if NewPPPEncryptionProtocol, err = soap.UnmarshalString(response.NewPPPEncryptionProtocol); err != nil {
4689 - return
4690 - }
4691 - // END Unmarshal arguments from response.
4692 - return
4693 -}
4694 -
4695 -//
4696 -//
4697 -// Return values:
4698 -//
4699 -// * NewPPPCompressionProtocol:
4700 -func (client *WANPPPConnection1) GetPPPCompressionProtocol() (NewPPPCompressionProtocol string, err error) {
4701 - // Request structure.
4702 - request := interface{}(nil)
4703 - // BEGIN Marshal arguments into request.
4704 -
4705 - // END Marshal arguments into request.
4706 -
4707 - // Response structure.
4708 - response := &struct {
4709 - NewPPPCompressionProtocol string
4710 - }{}
4711 -
4712 - // Perform the SOAP call.
4713 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPCompressionProtocol", request, response); err != nil {
4714 - return
4715 - }
4716 -
4717 - // BEGIN Unmarshal arguments from response.
4718 -
4719 - if NewPPPCompressionProtocol, err = soap.UnmarshalString(response.NewPPPCompressionProtocol); err != nil {
4720 - return
4721 - }
4722 - // END Unmarshal arguments from response.
4723 - return
4724 -}
4725 -
4726 -//
4727 -//
4728 -// Return values:
4729 -//
4730 -// * NewPPPAuthenticationProtocol:
4731 -func (client *WANPPPConnection1) GetPPPAuthenticationProtocol() (NewPPPAuthenticationProtocol string, err error) {
4732 - // Request structure.
4733 - request := interface{}(nil)
4734 - // BEGIN Marshal arguments into request.
4735 -
4736 - // END Marshal arguments into request.
4737 -
4738 - // Response structure.
4739 - response := &struct {
4740 - NewPPPAuthenticationProtocol string
4741 - }{}
4742 -
4743 - // Perform the SOAP call.
4744 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPPPAuthenticationProtocol", request, response); err != nil {
4745 - return
4746 - }
4747 -
4748 - // BEGIN Unmarshal arguments from response.
4749 -
4750 - if NewPPPAuthenticationProtocol, err = soap.UnmarshalString(response.NewPPPAuthenticationProtocol); err != nil {
4751 - return
4752 - }
4753 - // END Unmarshal arguments from response.
4754 - return
4755 -}
4756 -
4757 -//
4758 -//
4759 -// Return values:
4760 -//
4761 -// * NewUserName:
4762 -func (client *WANPPPConnection1) GetUserName() (NewUserName string, err error) {
4763 - // Request structure.
4764 - request := interface{}(nil)
4765 - // BEGIN Marshal arguments into request.
4766 -
4767 - // END Marshal arguments into request.
4768 -
4769 - // Response structure.
4770 - response := &struct {
4771 - NewUserName string
4772 - }{}
4773 -
4774 - // Perform the SOAP call.
4775 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetUserName", request, response); err != nil {
4776 - return
4777 - }
4778 -
4779 - // BEGIN Unmarshal arguments from response.
4780 -
4781 - if NewUserName, err = soap.UnmarshalString(response.NewUserName); err != nil {
4782 - return
4783 - }
4784 - // END Unmarshal arguments from response.
4785 - return
4786 -}
4787 -
4788 -//
4789 -//
4790 -// Return values:
4791 -//
4792 -// * NewPassword:
4793 -func (client *WANPPPConnection1) GetPassword() (NewPassword string, err error) {
4794 - // Request structure.
4795 - request := interface{}(nil)
4796 - // BEGIN Marshal arguments into request.
4797 -
4798 - // END Marshal arguments into request.
4799 -
4800 - // Response structure.
4801 - response := &struct {
4802 - NewPassword string
4803 - }{}
4804 -
4805 - // Perform the SOAP call.
4806 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetPassword", request, response); err != nil {
4807 - return
4808 - }
4809 -
4810 - // BEGIN Unmarshal arguments from response.
4811 -
4812 - if NewPassword, err = soap.UnmarshalString(response.NewPassword); err != nil {
4813 - return
4814 - }
4815 - // END Unmarshal arguments from response.
4816 - return
4817 -}
4818 -
4819 -//
4820 -//
4821 -// Return values:
4822 -//
4823 -// * NewAutoDisconnectTime:
4824 -func (client *WANPPPConnection1) GetAutoDisconnectTime() (NewAutoDisconnectTime uint32, err error) {
4825 - // Request structure.
4826 - request := interface{}(nil)
4827 - // BEGIN Marshal arguments into request.
4828 -
4829 - // END Marshal arguments into request.
4830 -
4831 - // Response structure.
4832 - response := &struct {
4833 - NewAutoDisconnectTime string
4834 - }{}
4835 -
4836 - // Perform the SOAP call.
4837 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetAutoDisconnectTime", request, response); err != nil {
4838 - return
4839 - }
4840 -
4841 - // BEGIN Unmarshal arguments from response.
4842 -
4843 - if NewAutoDisconnectTime, err = soap.UnmarshalUi4(response.NewAutoDisconnectTime); err != nil {
4844 - return
4845 - }
4846 - // END Unmarshal arguments from response.
4847 - return
4848 -}
4849 -
4850 -//
4851 -//
4852 -// Return values:
4853 -//
4854 -// * NewIdleDisconnectTime:
4855 -func (client *WANPPPConnection1) GetIdleDisconnectTime() (NewIdleDisconnectTime uint32, err error) {
4856 - // Request structure.
4857 - request := interface{}(nil)
4858 - // BEGIN Marshal arguments into request.
4859 -
4860 - // END Marshal arguments into request.
4861 -
4862 - // Response structure.
4863 - response := &struct {
4864 - NewIdleDisconnectTime string
4865 - }{}
4866 -
4867 - // Perform the SOAP call.
4868 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetIdleDisconnectTime", request, response); err != nil {
4869 - return
4870 - }
4871 -
4872 - // BEGIN Unmarshal arguments from response.
4873 -
4874 - if NewIdleDisconnectTime, err = soap.UnmarshalUi4(response.NewIdleDisconnectTime); err != nil {
4875 - return
4876 - }
4877 - // END Unmarshal arguments from response.
4878 - return
4879 -}
4880 -
4881 -//
4882 -//
4883 -// Return values:
4884 -//
4885 -// * NewWarnDisconnectDelay:
4886 -func (client *WANPPPConnection1) GetWarnDisconnectDelay() (NewWarnDisconnectDelay uint32, err error) {
4887 - // Request structure.
4888 - request := interface{}(nil)
4889 - // BEGIN Marshal arguments into request.
4890 -
4891 - // END Marshal arguments into request.
4892 -
4893 - // Response structure.
4894 - response := &struct {
4895 - NewWarnDisconnectDelay string
4896 - }{}
4897 -
4898 - // Perform the SOAP call.
4899 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetWarnDisconnectDelay", request, response); err != nil {
4900 - return
4901 - }
4902 -
4903 - // BEGIN Unmarshal arguments from response.
4904 -
4905 - if NewWarnDisconnectDelay, err = soap.UnmarshalUi4(response.NewWarnDisconnectDelay); err != nil {
4906 - return
4907 - }
4908 - // END Unmarshal arguments from response.
4909 - return
4910 -}
4911 -
4912 -//
4913 -//
4914 -// Return values:
4915 -//
4916 -// * NewRSIPAvailable:
4917 -//
4918 -// * NewNATEnabled:
4919 -func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNATEnabled bool, err error) {
4920 - // Request structure.
4921 - request := interface{}(nil)
4922 - // BEGIN Marshal arguments into request.
4923 -
4924 - // END Marshal arguments into request.
4925 -
4926 - // Response structure.
4927 - response := &struct {
4928 - NewRSIPAvailable string
4929 -
4930 - NewNATEnabled string
4931 - }{}
4932 -
4933 - // Perform the SOAP call.
4934 - if err = client.SOAPClient.PerformAction(URN_WANPPPConnection_1, "GetNATRSIPStatus", request, response); err != nil {
4935 - return
4936 - }
4937 -
4938 - // BEGIN Unmarshal arguments from response.
4939 -
4940 - if NewRSIPAvailable, err = soap.UnmarshalBoolean(response.NewRSIPAvailable); err != nil {
4941 - return
4942 - }
4943 - if NewNATEnabled, err = soap.UnmarshalBoolean(response.NewNATEnabled); err != nil {
4944 - return
4945 - }
4946 - // END Unmarshal arguments from response.
4947 - return
4948 -}
4949 -
4950 -// Arguments:
4951 -//
4952 -// * NewPortMappingIndex:
4953 -//
4954 -// Return values:
4955 -//
4956 -// * NewRemoteHost:
4957 -//
4958 -// * NewExternalPort:
4959 -//
4960 -// * NewProtocol: allowed values: TCP, UDP
4961 -//
4962 -// * NewInternalPort:
4963 -//
4964 -// * NewInternalClient:
4965 -//
4966 -// * NewEnabled:
4967 -//
4968 -// * NewPortMappingDescription:
4969 -//
4970 -// * NewLeaseDuration:
4971 -func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex uint16) (NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) {
4972 - // Request structure.
4973 - request := &struct {
4974 - NewPortMappingIndex string
4975 - }{}
4976 - // BEGIN Marshal arguments into request.
4977 -
4978 - if request.NewPortMappingIndex, err = soap.MarshalUi2(NewPortMappingIndex); err != nil {
4979 - return
4980 - }
4981 - // END Marshal arguments into request.
4982 -
4983 - // Response structure.
4984 - response := &struct {
4985 - NewRemoteHost string
4986 -
4987 - NewExternalPort string
4988 -
4989 - NewProtocol string
4990 -
4991 - NewInternalPort string
4992 -
4993 - NewInternalClient string
4994 -
4995 - NewEnabled string
4996 -
4997 - NewPortMappingDescription string
4998 -
4999 - NewLeaseDuration string

This file is too large to show in full.

Godeps/_workspace/src/github.com/huin/goupnp/device.go deleted
-184
@@ -1,184 +0,0 @@
1 -// This file contains XML structures for communicating with UPnP devices.
2 -
3 -package goupnp
4 -
5 -import (
6 - "encoding/xml"
7 - "errors"
8 - "fmt"
9 - "net/url"
10 -
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/scpd"
12 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/soap"
13 -)
14 -
15 -const (
16 - DeviceXMLNamespace = "urn:schemas-upnp-org:device-1-0"
17 -)
18 -
19 -// RootDevice is the device description as described by section 2.3 "Device
20 -// description" in
21 -// http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf
22 -type RootDevice struct {
23 - XMLName xml.Name `xml:"root"`
24 - SpecVersion SpecVersion `xml:"specVersion"`
25 - URLBase url.URL `xml:"-"`
26 - URLBaseStr string `xml:"URLBase"`
27 - Device Device `xml:"device"`
28 -}
29 -
30 -// SetURLBase sets the URLBase for the RootDevice and its underlying components.
31 -func (root *RootDevice) SetURLBase(urlBase *url.URL) {
32 - root.URLBase = *urlBase
33 - root.URLBaseStr = urlBase.String()
34 - root.Device.SetURLBase(urlBase)
35 -}
36 -
37 -// SpecVersion is part of a RootDevice, describes the version of the
38 -// specification that the data adheres to.
39 -type SpecVersion struct {
40 - Major int32 `xml:"major"`
41 - Minor int32 `xml:"minor"`
42 -}
43 -
44 -// Device is a UPnP device. It can have child devices.
45 -type Device struct {
46 - DeviceType string `xml:"deviceType"`
47 - FriendlyName string `xml:"friendlyName"`
48 - Manufacturer string `xml:"manufacturer"`
49 - ManufacturerURL URLField `xml:"manufacturerURL"`
50 - ModelDescription string `xml:"modelDescription"`
51 - ModelName string `xml:"modelName"`
52 - ModelNumber string `xml:"modelNumber"`
53 - ModelURL URLField `xml:"modelURL"`
54 - SerialNumber string `xml:"serialNumber"`
55 - UDN string `xml:"UDN"`
56 - UPC string `xml:"UPC,omitempty"`
57 - Icons []Icon `xml:"iconList>icon,omitempty"`
58 - Services []Service `xml:"serviceList>service,omitempty"`
59 - Devices []Device `xml:"deviceList>device,omitempty"`
60 -
61 - // Extra observed elements:
62 - PresentationURL URLField `xml:"presentationURL"`
63 -}
64 -
65 -// VisitDevices calls visitor for the device, and all its descendent devices.
66 -func (device *Device) VisitDevices(visitor func(*Device)) {
67 - visitor(device)
68 - for i := range device.Devices {
69 - device.Devices[i].VisitDevices(visitor)
70 - }
71 -}
72 -
73 -// VisitServices calls visitor for all Services under the device and all its
74 -// descendent devices.
75 -func (device *Device) VisitServices(visitor func(*Service)) {
76 - device.VisitDevices(func(d *Device) {
77 - for i := range d.Services {
78 - visitor(&d.Services[i])
79 - }
80 - })
81 -}
82 -
83 -// FindService finds all (if any) Services under the device and its descendents
84 -// that have the given ServiceType.
85 -func (device *Device) FindService(serviceType string) []*Service {
86 - var services []*Service
87 - device.VisitServices(func(s *Service) {
88 - if s.ServiceType == serviceType {
89 - services = append(services, s)
90 - }
91 - })
92 - return services
93 -}
94 -
95 -// SetURLBase sets the URLBase for the Device and its underlying components.
96 -func (device *Device) SetURLBase(urlBase *url.URL) {
97 - device.ManufacturerURL.SetURLBase(urlBase)
98 - device.ModelURL.SetURLBase(urlBase)
99 - device.PresentationURL.SetURLBase(urlBase)
100 - for i := range device.Icons {
101 - device.Icons[i].SetURLBase(urlBase)
102 - }
103 - for i := range device.Services {
104 - device.Services[i].SetURLBase(urlBase)
105 - }
106 - for i := range device.Devices {
107 - device.Devices[i].SetURLBase(urlBase)
108 - }
109 -}
110 -
111 -func (device *Device) String() string {
112 - return fmt.Sprintf("Device ID %s : %s (%s)", device.UDN, device.DeviceType, device.FriendlyName)
113 -}
114 -
115 -// Icon is a representative image that a device might include in its
116 -// description.
117 -type Icon struct {
118 - Mimetype string `xml:"mimetype"`
119 - Width int32 `xml:"width"`
120 - Height int32 `xml:"height"`
121 - Depth int32 `xml:"depth"`
122 - URL URLField `xml:"url"`
123 -}
124 -
125 -// SetURLBase sets the URLBase for the Icon.
126 -func (icon *Icon) SetURLBase(url *url.URL) {
127 - icon.URL.SetURLBase(url)
128 -}
129 -
130 -// Service is a service provided by a UPnP Device.
131 -type Service struct {
132 - ServiceType string `xml:"serviceType"`
133 - ServiceId string `xml:"serviceId"`
134 - SCPDURL URLField `xml:"SCPDURL"`
135 - ControlURL URLField `xml:"controlURL"`
136 - EventSubURL URLField `xml:"eventSubURL"`
137 -}
138 -
139 -// SetURLBase sets the URLBase for the Service.
140 -func (srv *Service) SetURLBase(urlBase *url.URL) {
141 - srv.SCPDURL.SetURLBase(urlBase)
142 - srv.ControlURL.SetURLBase(urlBase)
143 - srv.EventSubURL.SetURLBase(urlBase)
144 -}
145 -
146 -func (srv *Service) String() string {
147 - return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType)
148 -}
149 -
150 -// RequestSCDP requests the SCPD (soap actions and state variables description)
151 -// for the service.
152 -func (srv *Service) RequestSCDP() (*scpd.SCPD, error) {
153 - if !srv.SCPDURL.Ok {
154 - return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set")
155 - }
156 - s := new(scpd.SCPD)
157 - if err := requestXml(srv.SCPDURL.URL.String(), scpd.SCPDXMLNamespace, s); err != nil {
158 - return nil, err
159 - }
160 - return s, nil
161 -}
162 -
163 -func (srv *Service) NewSOAPClient() *soap.SOAPClient {
164 - return soap.NewSOAPClient(srv.ControlURL.URL)
165 -}
166 -
167 -// URLField is a URL that is part of a device description.
168 -type URLField struct {
169 - URL url.URL `xml:"-"`
170 - Ok bool `xml:"-"`
171 - Str string `xml:",chardata"`
172 -}
173 -
174 -func (uf *URLField) SetURLBase(urlBase *url.URL) {
175 - refUrl, err := url.Parse(uf.Str)
176 - if err != nil {
177 - uf.URL = url.URL{}
178 - uf.Ok = false
179 - return
180 - }
181 -
182 - uf.URL = *urlBase.ResolveReference(refUrl)
183 - uf.Ok = true
184 -}
Godeps/_workspace/src/github.com/huin/goupnp/example/example.go deleted
-6
@@ -1,6 +0,0 @@
1 -// Serves as examples of using the goupnp library.
2 -//
3 -// To run examples and see the output for your local network, run the following
4 -// command (specifically including the -v flag):
5 -// go test -v github.com/huin/goupnp/example
6 -package example
Godeps/_workspace/src/github.com/huin/goupnp/example/example_test.go deleted
-62
@@ -1,62 +0,0 @@
1 -package example_test
2 -
3 -import (
4 - "fmt"
5 - "os"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp"
8 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/dcps/internetgateway1"
9 -)
10 -
11 -// Use discovered WANPPPConnection1 services to find external IP addresses.
12 -func Example_WANPPPConnection1_GetExternalIPAddress() {
13 - clients, errors, err := internetgateway1.NewWANPPPConnection1Clients()
14 - extIPClients := make([]GetExternalIPAddresser, len(clients))
15 - for i, client := range clients {
16 - extIPClients[i] = client
17 - }
18 - DisplayExternalIPResults(extIPClients, errors, err)
19 - // Output:
20 -}
21 -
22 -// Use discovered WANIPConnection services to find external IP addresses.
23 -func Example_WANIPConnection_GetExternalIPAddress() {
24 - clients, errors, err := internetgateway1.NewWANIPConnection1Clients()
25 - extIPClients := make([]GetExternalIPAddresser, len(clients))
26 - for i, client := range clients {
27 - extIPClients[i] = client
28 - }
29 - DisplayExternalIPResults(extIPClients, errors, err)
30 - // Output:
31 -}
32 -
33 -type GetExternalIPAddresser interface {
34 - GetExternalIPAddress() (NewExternalIPAddress string, err error)
35 - GetServiceClient() *goupnp.ServiceClient
36 -}
37 -
38 -func DisplayExternalIPResults(clients []GetExternalIPAddresser, errors []error, err error) {
39 - if err != nil {
40 - fmt.Fprintln(os.Stderr, "Error discovering service with UPnP: ", err)
41 - return
42 - }
43 -
44 - if len(errors) > 0 {
45 - fmt.Fprintf(os.Stderr, "Error discovering %d services:\n", len(errors))
46 - for _, err := range errors {
47 - fmt.Println(" ", err)
48 - }
49 - }
50 -
51 - fmt.Fprintf(os.Stderr, "Successfully discovered %d services:\n", len(clients))
52 - for _, client := range clients {
53 - device := &client.GetServiceClient().RootDevice.Device
54 -
55 - fmt.Fprintln(os.Stderr, " Device:", device.FriendlyName)
56 - if addr, err := client.GetExternalIPAddress(); err != nil {
57 - fmt.Fprintf(os.Stderr, " Failed to get external IP address: %v\n", err)
58 - } else {
59 - fmt.Fprintf(os.Stderr, " External IP address: %v\n", addr)
60 - }
61 - }
62 -}
Godeps/_workspace/src/github.com/huin/goupnp/gotasks/specgen_task.go deleted
-539
@@ -1,539 +0,0 @@
1 -// +build gotask
2 -
3 -package gotasks
4 -
5 -import (
6 - "archive/zip"
7 - "bytes"
8 - "encoding/xml"
9 - "fmt"
10 - "io"
11 - "io/ioutil"
12 - "log"
13 - "os"
14 - "path"
15 - "path/filepath"
16 - "regexp"
17 - "strings"
18 - "text/template"
19 -
20 - "github.com/huin/goutil/codegen"
21 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp"
22 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/scpd"
23 - "github.com/jingweno/gotask/tasking"
24 -)
25 -
26 -var (
27 - deviceURNPrefix = "urn:schemas-upnp-org:device:"
28 - serviceURNPrefix = "urn:schemas-upnp-org:service:"
29 -)
30 -
31 -// NAME
32 -// specgen - generates Go code from the UPnP specification files.
33 -//
34 -// DESCRIPTION
35 -// The specification is available for download from:
36 -//
37 -// OPTIONS
38 -// -s, --spec_filename=<upnpresources.zip>
39 -// Path to the specification file, available from http://upnp.org/resources/upnpresources.zip
40 -// -o, --out_dir=<output directory>
41 -// Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/huin/goupnp/dcps
42 -// --nogofmt
43 -// Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt.
44 -func TaskSpecgen(t *tasking.T) {
45 - specFilename := t.Flags.String("spec-filename")
46 - if specFilename == "" {
47 - specFilename = t.Flags.String("s")
48 - }
49 - if specFilename == "" {
50 - t.Fatal("--spec_filename is required")
51 - }
52 - outDir := t.Flags.String("out-dir")
53 - if outDir == "" {
54 - outDir = t.Flags.String("o")
55 - }
56 - if outDir == "" {
57 - log.Fatal("--out_dir is required")
58 - }
59 - useGofmt := !t.Flags.Bool("nogofmt")
60 -
61 - specArchive, err := openZipfile(specFilename)
62 - if err != nil {
63 - t.Fatalf("Error opening spec file: %v", err)
64 - }
65 - defer specArchive.Close()
66 -
67 - dcpCol := newDcpsCollection()
68 - for _, f := range globFiles("standardizeddcps/*/*.zip", specArchive.Reader) {
69 - dirName := strings.TrimPrefix(f.Name, "standardizeddcps/")
70 - slashIndex := strings.Index(dirName, "/")
71 - if slashIndex == -1 {
72 - // Should not happen.
73 - t.Logf("Could not find / in %q", dirName)
74 - return
75 - }
76 - dirName = dirName[:slashIndex]
77 -
78 - dcp := dcpCol.dcpForDir(dirName)
79 - if dcp == nil {
80 - t.Logf("No alias defined for directory %q: skipping %s\n", dirName, f.Name)
81 - continue
82 - } else {
83 - t.Logf("Alias found for directory %q: processing %s\n", dirName, f.Name)
84 - }
85 -
86 - dcp.processZipFile(f)
87 - }
88 -
89 - for _, dcp := range dcpCol.dcpByAlias {
90 - if err := dcp.writePackage(outDir, useGofmt); err != nil {
91 - log.Printf("Error writing package %q: %v", dcp.Metadata.Name, err)
92 - }
93 - }
94 -}
95 -
96 -// DCP contains extra metadata to use when generating DCP source files.
97 -type DCPMetadata struct {
98 - Name string // What to name the Go DCP package.
99 - OfficialName string // Official name for the DCP.
100 - DocURL string // Optional - URL for futher documentation about the DCP.
101 -}
102 -
103 -var dcpMetadataByDir = map[string]DCPMetadata{
104 - "Internet Gateway_1": {
105 - Name: "internetgateway1",
106 - OfficialName: "Internet Gateway Device v1",
107 - DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf",
108 - },
109 - "Internet Gateway_2": {
110 - Name: "internetgateway2",
111 - OfficialName: "Internet Gateway Device v2",
112 - DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf",
113 - },
114 -}
115 -
116 -type dcpCollection struct {
117 - dcpByAlias map[string]*DCP
118 -}
119 -
120 -func newDcpsCollection() *dcpCollection {
121 - c := &dcpCollection{
122 - dcpByAlias: make(map[string]*DCP),
123 - }
124 - for _, metadata := range dcpMetadataByDir {
125 - c.dcpByAlias[metadata.Name] = newDCP(metadata)
126 - }
127 - return c
128 -}
129 -
130 -func (c *dcpCollection) dcpForDir(dirName string) *DCP {
131 - metadata, ok := dcpMetadataByDir[dirName]
132 - if !ok {
133 - return nil
134 - }
135 - return c.dcpByAlias[metadata.Name]
136 -}
137 -
138 -// DCP collects together information about a UPnP Device Control Protocol.
139 -type DCP struct {
140 - Metadata DCPMetadata
141 - DeviceTypes map[string]*URNParts
142 - ServiceTypes map[string]*URNParts
143 - Services []SCPDWithURN
144 -}
145 -
146 -func newDCP(metadata DCPMetadata) *DCP {
147 - return &DCP{
148 - Metadata: metadata,
149 - DeviceTypes: make(map[string]*URNParts),
150 - ServiceTypes: make(map[string]*URNParts),
151 - }
152 -}
153 -
154 -func (dcp *DCP) processZipFile(file *zip.File) {
155 - archive, err := openChildZip(file)
156 - if err != nil {
157 - log.Println("Error reading child zip file:", err)
158 - return
159 - }
160 - for _, deviceFile := range globFiles("*/device/*.xml", archive) {
161 - dcp.processDeviceFile(deviceFile)
162 - }
163 - for _, scpdFile := range globFiles("*/service/*.xml", archive) {
164 - dcp.processSCPDFile(scpdFile)
165 - }
166 -}
167 -
168 -func (dcp *DCP) processDeviceFile(file *zip.File) {
169 - var device goupnp.Device
170 - if err := unmarshalXmlFile(file, &device); err != nil {
171 - log.Printf("Error decoding device XML from file %q: %v", file.Name, err)
172 - return
173 - }
174 - device.VisitDevices(func(d *goupnp.Device) {
175 - t := strings.TrimSpace(d.DeviceType)
176 - if t != "" {
177 - u, err := extractURNParts(t, deviceURNPrefix)
178 - if err != nil {
179 - log.Println(err)
180 - return
181 - }
182 - dcp.DeviceTypes[t] = u
183 - }
184 - })
185 - device.VisitServices(func(s *goupnp.Service) {
186 - u, err := extractURNParts(s.ServiceType, serviceURNPrefix)
187 - if err != nil {
188 - log.Println(err)
189 - return
190 - }
191 - dcp.ServiceTypes[s.ServiceType] = u
192 - })
193 -}
194 -
195 -func (dcp *DCP) writePackage(outDir string, useGofmt bool) error {
196 - packageDirname := filepath.Join(outDir, dcp.Metadata.Name)
197 - err := os.MkdirAll(packageDirname, os.ModePerm)
198 - if err != nil && !os.IsExist(err) {
199 - return err
200 - }
201 - packageFilename := filepath.Join(packageDirname, dcp.Metadata.Name+".go")
202 - packageFile, err := os.Create(packageFilename)
203 - if err != nil {
204 - return err
205 - }
206 - var output io.WriteCloser = packageFile
207 - if useGofmt {
208 - if output, err = codegen.NewGofmtWriteCloser(output); err != nil {
209 - packageFile.Close()
210 - return err
211 - }
212 - }
213 - if err = packageTmpl.Execute(output, dcp); err != nil {
214 - output.Close()
215 - return err
216 - }
217 - return output.Close()
218 -}
219 -
220 -func (dcp *DCP) processSCPDFile(file *zip.File) {
221 - scpd := new(scpd.SCPD)
222 - if err := unmarshalXmlFile(file, scpd); err != nil {
223 - log.Printf("Error decoding SCPD XML from file %q: %v", file.Name, err)
224 - return
225 - }
226 - scpd.Clean()
227 - urnParts, err := urnPartsFromSCPDFilename(file.Name)
228 - if err != nil {
229 - log.Printf("Could not recognize SCPD filename %q: %v", file.Name, err)
230 - return
231 - }
232 - dcp.Services = append(dcp.Services, SCPDWithURN{
233 - URNParts: urnParts,
234 - SCPD: scpd,
235 - })
236 -}
237 -
238 -type SCPDWithURN struct {
239 - *URNParts
240 - SCPD *scpd.SCPD
241 -}
242 -
243 -func (s *SCPDWithURN) WrapArgument(arg scpd.Argument) (*argumentWrapper, error) {
244 - relVar := s.SCPD.GetStateVariable(arg.RelatedStateVariable)
245 - if relVar == nil {
246 - return nil, fmt.Errorf("no such state variable: %q, for argument %q", arg.RelatedStateVariable, arg.Name)
247 - }
248 - cnv, ok := typeConvs[relVar.DataType.Name]
249 - if !ok {
250 - return nil, fmt.Errorf("unknown data type: %q, for state variable %q, for argument %q", relVar.DataType.Type, arg.RelatedStateVariable, arg.Name)
251 - }
252 - return &argumentWrapper{
253 - Argument: arg,
254 - relVar: relVar,
255 - conv: cnv,
256 - }, nil
257 -}
258 -
259 -type argumentWrapper struct {
260 - scpd.Argument
261 - relVar *scpd.StateVariable
262 - conv conv
263 -}
264 -
265 -func (arg *argumentWrapper) AsParameter() string {
266 - return fmt.Sprintf("%s %s", arg.Name, arg.conv.ExtType)
267 -}
268 -
269 -func (arg *argumentWrapper) Document() string {
270 - relVar := arg.relVar
271 - if rng := relVar.AllowedValueRange; rng != nil {
272 - var parts []string
273 - if rng.Minimum != "" {
274 - parts = append(parts, fmt.Sprintf("minimum=%s", rng.Minimum))
275 - }
276 - if rng.Maximum != "" {
277 - parts = append(parts, fmt.Sprintf("maximum=%s", rng.Maximum))
278 - }
279 - if rng.Step != "" {
280 - parts = append(parts, fmt.Sprintf("step=%s", rng.Step))
281 - }
282 - return "allowed value range: " + strings.Join(parts, ", ")
283 - }
284 - if len(relVar.AllowedValues) != 0 {
285 - return "allowed values: " + strings.Join(relVar.AllowedValues, ", ")
286 - }
287 - return ""
288 -}
289 -
290 -func (arg *argumentWrapper) Marshal() string {
291 - return fmt.Sprintf("soap.Marshal%s(%s)", arg.conv.FuncSuffix, arg.Name)
292 -}
293 -
294 -func (arg *argumentWrapper) Unmarshal(objVar string) string {
295 - return fmt.Sprintf("soap.Unmarshal%s(%s.%s)", arg.conv.FuncSuffix, objVar, arg.Name)
296 -}
297 -
298 -type conv struct {
299 - FuncSuffix string
300 - ExtType string
301 -}
302 -
303 -// typeConvs maps from a SOAP type (e.g "fixed.14.4") to the function name
304 -// suffix inside the soap module (e.g "Fixed14_4") and the Go type.
305 -var typeConvs = map[string]conv{
306 - "ui1": conv{"Ui1", "uint8"},
307 - "ui2": conv{"Ui2", "uint16"},
308 - "ui4": conv{"Ui4", "uint32"},
309 - "i1": conv{"I1", "int8"},
310 - "i2": conv{"I2", "int16"},
311 - "i4": conv{"I4", "int32"},
312 - "int": conv{"Int", "int64"},
313 - "r4": conv{"R4", "float32"},
314 - "r8": conv{"R8", "float64"},
315 - "number": conv{"R8", "float64"}, // Alias for r8.
316 - "fixed.14.4": conv{"Fixed14_4", "float64"},
317 - "float": conv{"R8", "float64"},
318 - "char": conv{"Char", "rune"},
319 - "string": conv{"String", "string"},
320 - "date": conv{"Date", "time.Time"},
321 - "dateTime": conv{"DateTime", "time.Time"},
322 - "dateTime.tz": conv{"DateTimeTz", "time.Time"},
323 - "time": conv{"TimeOfDay", "soap.TimeOfDay"},
324 - "time.tz": conv{"TimeOfDayTz", "soap.TimeOfDay"},
325 - "boolean": conv{"Boolean", "bool"},
326 - "bin.base64": conv{"BinBase64", "[]byte"},
327 - "bin.hex": conv{"BinHex", "[]byte"},
328 -}
329 -
330 -type closeableZipReader struct {
331 - io.Closer
332 - *zip.Reader
333 -}
334 -
335 -func openZipfile(filename string) (*closeableZipReader, error) {
336 - file, err := os.Open(filename)
337 - if err != nil {
338 - return nil, err
339 - }
340 - fi, err := file.Stat()
341 - if err != nil {
342 - return nil, err
343 - }
344 - archive, err := zip.NewReader(file, fi.Size())
345 - if err != nil {
346 - return nil, err
347 - }
348 - return &closeableZipReader{
349 - Closer: file,
350 - Reader: archive,
351 - }, nil
352 -}
353 -
354 -// openChildZip opens a zip file within another zip file.
355 -func openChildZip(file *zip.File) (*zip.Reader, error) {
356 - zipFile, err := file.Open()
357 - if err != nil {
358 - return nil, err
359 - }
360 - defer zipFile.Close()
361 -
362 - zipBytes, err := ioutil.ReadAll(zipFile)
363 - if err != nil {
364 - return nil, err
365 - }
366 -
367 - return zip.NewReader(bytes.NewReader(zipBytes), int64(len(zipBytes)))
368 -}
369 -
370 -func globFiles(pattern string, archive *zip.Reader) []*zip.File {
371 - var files []*zip.File
372 - for _, f := range archive.File {
373 - if matched, err := path.Match(pattern, f.Name); err != nil {
374 - // This shouldn't happen - all patterns are hard-coded, errors in them
375 - // are a programming error.
376 - panic(err)
377 - } else if matched {
378 - files = append(files, f)
379 - }
380 - }
381 - return files
382 -}
383 -
384 -func unmarshalXmlFile(file *zip.File, data interface{}) error {
385 - r, err := file.Open()
386 - if err != nil {
387 - return err
388 - }
389 - decoder := xml.NewDecoder(r)
390 - r.Close()
391 - return decoder.Decode(data)
392 -}
393 -
394 -type URNParts struct {
395 - URN string
396 - Name string
397 - Version string
398 -}
399 -
400 -func (u *URNParts) Const() string {
401 - return fmt.Sprintf("URN_%s_%s", u.Name, u.Version)
402 -}
403 -
404 -// extractURNParts extracts the name and version from a URN string.
405 -func extractURNParts(urn, expectedPrefix string) (*URNParts, error) {
406 - if !strings.HasPrefix(urn, expectedPrefix) {
407 - return nil, fmt.Errorf("%q does not have expected prefix %q", urn, expectedPrefix)
408 - }
409 - parts := strings.SplitN(strings.TrimPrefix(urn, expectedPrefix), ":", 2)
410 - if len(parts) != 2 {
411 - return nil, fmt.Errorf("%q does not have a name and version", urn)
412 - }
413 - name, version := parts[0], parts[1]
414 - return &URNParts{urn, name, version}, nil
415 -}
416 -
417 -var scpdFilenameRe = regexp.MustCompile(
418 - `.*/([a-zA-Z0-9]+)([0-9]+)\.xml`)
419 -
420 -func urnPartsFromSCPDFilename(filename string) (*URNParts, error) {
421 - parts := scpdFilenameRe.FindStringSubmatch(filename)
422 - if len(parts) != 3 {
423 - return nil, fmt.Errorf("SCPD filename %q does not have expected number of parts", filename)
424 - }
425 - name, version := parts[1], parts[2]
426 - return &URNParts{
427 - URN: serviceURNPrefix + name + ":" + version,
428 - Name: name,
429 - Version: version,
430 - }, nil
431 -}
432 -
433 -var packageTmpl = template.Must(template.New("package").Parse(`{{$name := .Metadata.Name}}
434 -// Client for UPnP Device Control Protocol {{.Metadata.OfficialName}}.
435 -// {{if .Metadata.DocURL}}
436 -// This DCP is documented in detail at: {{.Metadata.DocURL}}{{end}}
437 -//
438 -// Typically, use one of the New* functions to discover services on the local
439 -// network.
440 -package {{$name}}
441 -
442 -// Generated file - do not edit by hand. See README.md
443 -
444 -
445 -import (
446 - "time"
447 -
448 - "github.com/huin/goupnp"
449 - "github.com/huin/goupnp/soap"
450 -)
451 -
452 -// Hack to avoid Go complaining if time isn't used.
453 -var _ time.Time
454 -
455 -// Device URNs:
456 -const ({{range .DeviceTypes}}
457 - {{.Const}} = "{{.URN}}"{{end}}
458 -)
459 -
460 -// Service URNs:
461 -const ({{range .ServiceTypes}}
462 - {{.Const}} = "{{.URN}}"{{end}}
463 -)
464 -
465 -{{range .Services}}
466 -{{$srv := .}}
467 -{{$srvIdent := printf "%s%s" .Name .Version}}
468 -
469 -// {{$srvIdent}} is a client for UPnP SOAP service with URN "{{.URN}}". See
470 -// goupnp.ServiceClient, which contains RootDevice and Service attributes which
471 -// are provided for informational value.
472 -type {{$srvIdent}} struct {
473 - goupnp.ServiceClient
474 -}
475 -
476 -// New{{$srvIdent}}Clients discovers instances of the service on the network,
477 -// and returns clients to any that are found. errors will contain an error for
478 -// any devices that replied but which could not be queried, and err will be set
479 -// if the discovery process failed outright.
480 -//
481 -// This is a typical entry calling point into this package.
482 -func New{{$srvIdent}}Clients() (clients []*{{$srvIdent}}, errors []error, err error) {
483 - var genericClients []goupnp.ServiceClient
484 - if genericClients, errors, err = goupnp.NewServiceClients({{$srv.Const}}); err != nil {
485 - return
486 - }
487 - clients = make([]*{{$srvIdent}}, len(genericClients))
488 - for i := range genericClients {
489 - clients[i] = &{{$srvIdent}}{genericClients[i]}
490 - }
491 - return
492 -}
493 -
494 -{{range .SCPD.Actions}}{{/* loops over *SCPDWithURN values */}}
495 -
496 -{{$inargs := .InputArguments}}{{$outargs := .OutputArguments}}
497 -// {{if $inargs}}Arguments:{{range $inargs}}{{$argWrap := $srv.WrapArgument .}}
498 -//
499 -// * {{.Name}}: {{$argWrap.Document}}{{end}}{{end}}
500 -//
501 -// {{if $outargs}}Return values:{{range $outargs}}{{$argWrap := $srv.WrapArgument .}}
502 -//
503 -// * {{.Name}}: {{$argWrap.Document}}{{end}}{{end}}
504 -func (client *{{$srvIdent}}) {{.Name}}({{range $inargs}}{{/*
505 -*/}}{{$argWrap := $srv.WrapArgument .}}{{$argWrap.AsParameter}}, {{end}}{{/*
506 -*/}}) ({{range $outargs}}{{/*
507 -*/}}{{$argWrap := $srv.WrapArgument .}}{{$argWrap.AsParameter}}, {{end}} err error) {
508 - // Request structure.
509 - request := {{if $inargs}}&{{template "argstruct" $inargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}}
510 - // BEGIN Marshal arguments into request.
511 -{{range $inargs}}{{$argWrap := $srv.WrapArgument .}}
512 - if request.{{.Name}}, err = {{$argWrap.Marshal}}; err != nil {
513 - return
514 - }{{end}}
515 - // END Marshal arguments into request.
516 -
517 - // Response structure.
518 - response := {{if $outargs}}&{{template "argstruct" $outargs}}{{"{}"}}{{else}}{{"interface{}(nil)"}}{{end}}
519 -
520 - // Perform the SOAP call.
521 - if err = client.SOAPClient.PerformAction({{$srv.URNParts.Const}}, "{{.Name}}", request, response); err != nil {
522 - return
523 - }
524 -
525 - // BEGIN Unmarshal arguments from response.
526 -{{range $outargs}}{{$argWrap := $srv.WrapArgument .}}
527 - if {{.Name}}, err = {{$argWrap.Unmarshal "response"}}; err != nil {
528 - return
529 - }{{end}}
530 - // END Unmarshal arguments from response.
531 - return
532 -}
533 -{{end}}{{/* range .SCPD.Actions */}}
534 -{{end}}{{/* range .Services */}}
535 -
536 -{{define "argstruct"}}struct {{"{"}}{{range .}}
537 -{{.Name}} string
538 -{{end}}{{"}"}}{{end}}
539 -`))
Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go deleted
-109
@@ -1,109 +0,0 @@
1 -// goupnp is an implementation of a client for various UPnP services.
2 -//
3 -// For most uses, it is recommended to use the code-generated packages under
4 -// github.com/huin/goupnp/dcps. Example use is shown at
5 -// http://godoc.org/github.com/huin/goupnp/example
6 -//
7 -// A commonly used client is internetgateway1.WANPPPConnection1:
8 -// http://godoc.org/github.com/huin/goupnp/dcps/internetgateway1#WANPPPConnection1
9 -//
10 -// Currently only a couple of schemas have code generated for them from the
11 -// UPnP example XML specifications. Not all methods will work on these clients,
12 -// because the generated stubs contain the full set of specified methods from
13 -// the XML specifications, and the discovered services will likely support a
14 -// subset of those methods.
15 -package goupnp
16 -
17 -import (
18 - "encoding/xml"
19 - "fmt"
20 - "net/http"
21 - "net/url"
22 -
23 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/httpu"
24 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/ssdp"
25 -)
26 -
27 -// ContextError is an error that wraps an error with some context information.
28 -type ContextError struct {
29 - Context string
30 - Err error
31 -}
32 -
33 -func (err ContextError) Error() string {
34 - return fmt.Sprintf("%s: %v", err.Context, err.Err)
35 -}
36 -
37 -// MaybeRootDevice contains either a RootDevice or an error.
38 -type MaybeRootDevice struct {
39 - Root *RootDevice
40 - Err error
41 -}
42 -
43 -// DiscoverDevices attempts to find targets of the given type. This is
44 -// typically the entry-point for this package. searchTarget is typically a URN
45 -// in the form "urn:schemas-upnp-org:device:..." or
46 -// "urn:schemas-upnp-org:service:...". A single error is returned for errors
47 -// while attempting to send the query. An error or RootDevice is returned for
48 -// each discovered RootDevice.
49 -func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
50 - httpu, err := httpu.NewHTTPUClient()
51 - if err != nil {
52 - return nil, err
53 - }
54 - defer httpu.Close()
55 - responses, err := ssdp.SSDPRawSearch(httpu, string(searchTarget), 2, 3)
56 - if err != nil {
57 - return nil, err
58 - }
59 -
60 - results := make([]MaybeRootDevice, len(responses))
61 - for i, response := range responses {
62 - maybe := &results[i]
63 - loc, err := response.Location()
64 - if err != nil {
65 -
66 - maybe.Err = ContextError{"unexpected bad location from search", err}
67 - continue
68 - }
69 - locStr := loc.String()
70 - root := new(RootDevice)
71 - if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil {
72 - maybe.Err = ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err}
73 - continue
74 - }
75 - var urlBaseStr string
76 - if root.URLBaseStr != "" {
77 - urlBaseStr = root.URLBaseStr
78 - } else {
79 - urlBaseStr = locStr
80 - }
81 - urlBase, err := url.Parse(urlBaseStr)
82 - if err != nil {
83 - maybe.Err = ContextError{fmt.Sprintf("error parsing location URL %q", locStr), err}
84 - continue
85 - }
86 - root.SetURLBase(urlBase)
87 - maybe.Root = root
88 - }
89 -
90 - return results, nil
91 -}
92 -
93 -func requestXml(url string, defaultSpace string, doc interface{}) error {
94 - resp, err := http.Get(url)
95 - if err != nil {
96 - return err
97 - }
98 - defer resp.Body.Close()
99 -
100 - if resp.StatusCode != 200 {
101 - return fmt.Errorf("goupnp: got response status %s from %q",
102 - resp.Status, url)
103 - }
104 -
105 - decoder := xml.NewDecoder(resp.Body)
106 - decoder.DefaultSpace = defaultSpace
107 -
108 - return decoder.Decode(doc)
109 -}
Godeps/_workspace/src/github.com/huin/goupnp/httpu/httpu.go deleted
-117
@@ -1,117 +0,0 @@
1 -package httpu
2 -
3 -import (
4 - "bufio"
5 - "bytes"
6 - "fmt"
7 - "log"
8 - "net"
9 - "net/http"
10 - "sync"
11 - "time"
12 -)
13 -
14 -// HTTPUClient is a client for dealing with HTTPU (HTTP over UDP). Its typical
15 -// function is for HTTPMU, and particularly SSDP.
16 -type HTTPUClient struct {
17 - connLock sync.Mutex // Protects use of conn.
18 - conn net.PacketConn
19 -}
20 -
21 -// NewHTTPUClient creates a new HTTPUClient, opening up a new UDP socket for the
22 -// purpose.
23 -func NewHTTPUClient() (*HTTPUClient, error) {
24 - conn, err := net.ListenPacket("udp", ":0")
25 - if err != nil {
26 - return nil, err
27 - }
28 - return &HTTPUClient{conn: conn}, nil
29 -}
30 -
31 -// Close shuts down the client. The client will no longer be useful following
32 -// this.
33 -func (httpu *HTTPUClient) Close() error {
34 - httpu.connLock.Lock()
35 - defer httpu.connLock.Unlock()
36 - return httpu.conn.Close()
37 -}
38 -
39 -// Do performs a request. The timeout is how long to wait for before returning
40 -// the responses that were received. An error is only returned for failing to
41 -// send the request. Failures in receipt simply do not add to the resulting
42 -// responses.
43 -//
44 -// Note that at present only one concurrent connection will happen per
45 -// HTTPUClient.
46 -func (httpu *HTTPUClient) Do(req *http.Request, timeout time.Duration, numSends int) ([]*http.Response, error) {
47 - httpu.connLock.Lock()
48 - defer httpu.connLock.Unlock()
49 -
50 - // Create the request. This is a subset of what http.Request.Write does
51 - // deliberately to avoid creating extra fields which may confuse some
52 - // devices.
53 - var requestBuf bytes.Buffer
54 - method := req.Method
55 - if method == "" {
56 - method = "GET"
57 - }
58 - if _, err := fmt.Fprintf(&requestBuf, "%s %s HTTP/1.1\r\n", method, req.URL.RequestURI()); err != nil {
59 - return nil, err
60 - }
61 - if err := req.Header.Write(&requestBuf); err != nil {
62 - return nil, err
63 - }
64 - if _, err := requestBuf.Write([]byte{'\r', '\n'}); err != nil {
65 - return nil, err
66 - }
67 -
68 - destAddr, err := net.ResolveUDPAddr("udp", req.Host)
69 - if err != nil {
70 - return nil, err
71 - }
72 - if err = httpu.conn.SetDeadline(time.Now().Add(timeout)); err != nil {
73 - return nil, err
74 - }
75 -
76 - // Send request.
77 - for i := 0; i < numSends; i++ {
78 - if n, err := httpu.conn.WriteTo(requestBuf.Bytes(), destAddr); err != nil {
79 - return nil, err
80 - } else if n < len(requestBuf.Bytes()) {
81 - return nil, fmt.Errorf("httpu: wrote %d bytes rather than full %d in request",
82 - n, len(requestBuf.Bytes()))
83 - }
84 - time.Sleep(5 * time.Millisecond)
85 - }
86 -
87 - // Await responses until timeout.
88 - var responses []*http.Response
89 - responseBytes := make([]byte, 2048)
90 - for {
91 - // 2048 bytes should be sufficient for most networks.
92 - n, _, err := httpu.conn.ReadFrom(responseBytes)
93 - if err != nil {
94 - if err, ok := err.(net.Error); ok {
95 - if err.Timeout() {
96 - break
97 - }
98 - if err.Temporary() {
99 - // Sleep in case this is a persistent error to avoid pegging CPU until deadline.
100 - time.Sleep(10 * time.Millisecond)
101 - continue
102 - }
103 - }
104 - return nil, err
105 - }
106 -
107 - // Parse response.
108 - response, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(responseBytes[:n])), req)
109 - if err != nil {
110 - log.Print("httpu: error while parsing response: %v", err)
111 - continue
112 - }
113 -
114 - responses = append(responses, response)
115 - }
116 - return responses, err
117 -}
Godeps/_workspace/src/github.com/huin/goupnp/httpu/serve.go deleted
-108
@@ -1,108 +0,0 @@
1 -package httpu
2 -
3 -import (
4 - "bufio"
5 - "bytes"
6 - "log"
7 - "net"
8 - "net/http"
9 - "regexp"
10 -)
11 -
12 -const (
13 - DefaultMaxMessageBytes = 2048
14 -)
15 -
16 -var (
17 - trailingWhitespaceRx = regexp.MustCompile(" +\r\n")
18 - crlf = []byte("\r\n")
19 -)
20 -
21 -// Handler is the interface by which received HTTPU messages are passed to
22 -// handling code.
23 -type Handler interface {
24 - // ServeMessage is called for each HTTPU message received. peerAddr contains
25 - // the address that the message was received from.
26 - ServeMessage(r *http.Request)
27 -}
28 -
29 -// HandlerFunc is a function-to-Handler adapter.
30 -type HandlerFunc func(r *http.Request)
31 -
32 -func (f HandlerFunc) ServeMessage(r *http.Request) {
33 - f(r)
34 -}
35 -
36 -// A Server defines parameters for running an HTTPU server.
37 -type Server struct {
38 - Addr string // UDP address to listen on
39 - Multicast bool // Should listen for multicast?
40 - Interface *net.Interface // Network interface to listen on for multicast, nil for default multicast interface
41 - Handler Handler // handler to invoke
42 - MaxMessageBytes int // maximum number of bytes to read from a packet, DefaultMaxMessageBytes if 0
43 -}
44 -
45 -// ListenAndServe listens on the UDP network address srv.Addr. If srv.Multicast
46 -// is true, then a multicast UDP listener will be used on srv.Interface (or
47 -// default interface if nil).
48 -func (srv *Server) ListenAndServe() error {
49 - var err error
50 -
51 - var addr *net.UDPAddr
52 - if addr, err = net.ResolveUDPAddr("udp", srv.Addr); err != nil {
53 - log.Fatal(err)
54 - }
55 -
56 - var conn net.PacketConn
57 - if srv.Multicast {
58 - if conn, err = net.ListenMulticastUDP("udp", srv.Interface, addr); err != nil {
59 - return err
60 - }
61 - } else {
62 - if conn, err = net.ListenUDP("udp", addr); err != nil {
63 - return err
64 - }
65 - }
66 -
67 - return srv.Serve(conn)
68 -}
69 -
70 -// Serve messages received on the given packet listener to the srv.Handler.
71 -func (srv *Server) Serve(l net.PacketConn) error {
72 - maxMessageBytes := DefaultMaxMessageBytes
73 - if srv.MaxMessageBytes != 0 {
74 - maxMessageBytes = srv.MaxMessageBytes
75 - }
76 - for {
77 - buf := make([]byte, maxMessageBytes)
78 - n, peerAddr, err := l.ReadFrom(buf)
79 - if err != nil {
80 - return err
81 - }
82 - buf = buf[:n]
83 -
84 - go func(buf []byte, peerAddr net.Addr) {
85 - // At least one router's UPnP implementation has added a trailing space
86 - // after "HTTP/1.1" - trim it.
87 - buf = trailingWhitespaceRx.ReplaceAllLiteral(buf, crlf)
88 -
89 - req, err := http.ReadRequest(bufio.NewReader(bytes.NewBuffer(buf)))
90 - if err != nil {
91 - log.Printf("httpu: Failed to parse request: %v", err)
92 - return
93 - }
94 - req.RemoteAddr = peerAddr.String()
95 - srv.Handler.ServeMessage(req)
96 - // No need to call req.Body.Close - underlying reader is bytes.Buffer.
97 - }(buf, peerAddr)
98 - }
99 -}
100 -
101 -// Serve messages received on the given packet listener to the given handler.
102 -func Serve(l net.PacketConn, handler Handler) error {
103 - srv := Server{
104 - Handler: handler,
105 - MaxMessageBytes: DefaultMaxMessageBytes,
106 - }
107 - return srv.Serve(l)
108 -}
Godeps/_workspace/src/github.com/huin/goupnp/scpd/scpd.go deleted
-167
@@ -1,167 +0,0 @@
1 -package scpd
2 -
3 -import (
4 - "encoding/xml"
5 - "strings"
6 -)
7 -
8 -const (
9 - SCPDXMLNamespace = "urn:schemas-upnp-org:service-1-0"
10 -)
11 -
12 -func cleanWhitespace(s *string) {
13 - *s = strings.TrimSpace(*s)
14 -}
15 -
16 -// SCPD is the service description as described by section 2.5 "Service
17 -// description" in
18 -// http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf
19 -type SCPD struct {
20 - XMLName xml.Name `xml:"scpd"`
21 - ConfigId string `xml:"configId,attr"`
22 - SpecVersion SpecVersion `xml:"specVersion"`
23 - Actions []Action `xml:"actionList>action"`
24 - StateVariables []StateVariable `xml:"serviceStateTable>stateVariable"`
25 -}
26 -
27 -// Clean attempts to remove stray whitespace etc. in the structure. It seems
28 -// unfortunately common for stray whitespace to be present in SCPD documents,
29 -// this method attempts to make it easy to clean them out.
30 -func (scpd *SCPD) Clean() {
31 - cleanWhitespace(&scpd.ConfigId)
32 - for i := range scpd.Actions {
33 - scpd.Actions[i].clean()
34 - }
35 - for i := range scpd.StateVariables {
36 - scpd.StateVariables[i].clean()
37 - }
38 -}
39 -
40 -func (scpd *SCPD) GetStateVariable(variable string) *StateVariable {
41 - for i := range scpd.StateVariables {
42 - v := &scpd.StateVariables[i]
43 - if v.Name == variable {
44 - return v
45 - }
46 - }
47 - return nil
48 -}
49 -
50 -func (scpd *SCPD) GetAction(action string) *Action {
51 - for i := range scpd.Actions {
52 - a := &scpd.Actions[i]
53 - if a.Name == action {
54 - return a
55 - }
56 - }
57 - return nil
58 -}
59 -
60 -// SpecVersion is part of a SCPD document, describes the version of the
61 -// specification that the data adheres to.
62 -type SpecVersion struct {
63 - Major int32 `xml:"major"`
64 - Minor int32 `xml:"minor"`
65 -}
66 -
67 -type Action struct {
68 - Name string `xml:"name"`
69 - Arguments []Argument `xml:"argumentList>argument"`
70 -}
71 -
72 -func (action *Action) clean() {
73 - cleanWhitespace(&action.Name)
74 - for i := range action.Arguments {
75 - action.Arguments[i].clean()
76 - }
77 -}
78 -
79 -func (action *Action) InputArguments() []*Argument {
80 - var result []*Argument
81 - for i := range action.Arguments {
82 - arg := &action.Arguments[i]
83 - if arg.IsInput() {
84 - result = append(result, arg)
85 - }
86 - }
87 - return result
88 -}
89 -
90 -func (action *Action) OutputArguments() []*Argument {
91 - var result []*Argument
92 - for i := range action.Arguments {
93 - arg := &action.Arguments[i]
94 - if arg.IsOutput() {
95 - result = append(result, arg)
96 - }
97 - }
98 - return result
99 -}
100 -
101 -type Argument struct {
102 - Name string `xml:"name"`
103 - Direction string `xml:"direction"` // in|out
104 - RelatedStateVariable string `xml:"relatedStateVariable"` // ?
105 - Retval string `xml:"retval"` // ?
106 -}
107 -
108 -func (arg *Argument) clean() {
109 - cleanWhitespace(&arg.Name)
110 - cleanWhitespace(&arg.Direction)
111 - cleanWhitespace(&arg.RelatedStateVariable)
112 - cleanWhitespace(&arg.Retval)
113 -}
114 -
115 -func (arg *Argument) IsInput() bool {
116 - return arg.Direction == "in"
117 -}
118 -
119 -func (arg *Argument) IsOutput() bool {
120 - return arg.Direction == "out"
121 -}
122 -
123 -type StateVariable struct {
124 - Name string `xml:"name"`
125 - SendEvents string `xml:"sendEvents,attr"` // yes|no
126 - Multicast string `xml:"multicast,attr"` // yes|no
127 - DataType DataType `xml:"dataType"`
128 - DefaultValue string `xml:"defaultValue"`
129 - AllowedValueRange *AllowedValueRange `xml:"allowedValueRange"`
130 - AllowedValues []string `xml:"allowedValueList>allowedValue"`
131 -}
132 -
133 -func (v *StateVariable) clean() {
134 - cleanWhitespace(&v.Name)
135 - cleanWhitespace(&v.SendEvents)
136 - cleanWhitespace(&v.Multicast)
137 - v.DataType.clean()
138 - cleanWhitespace(&v.DefaultValue)
139 - if v.AllowedValueRange != nil {
140 - v.AllowedValueRange.clean()
141 - }
142 - for i := range v.AllowedValues {
143 - cleanWhitespace(&v.AllowedValues[i])
144 - }
145 -}
146 -
147 -type AllowedValueRange struct {
148 - Minimum string `xml:"minimum"`
149 - Maximum string `xml:"maximum"`
150 - Step string `xml:"step"`
151 -}
152 -
153 -func (r *AllowedValueRange) clean() {
154 - cleanWhitespace(&r.Minimum)
155 - cleanWhitespace(&r.Maximum)
156 - cleanWhitespace(&r.Step)
157 -}
158 -
159 -type DataType struct {
160 - Name string `xml:",chardata"`
161 - Type string `xml:"type,attr"`
162 -}
163 -
164 -func (dt *DataType) clean() {
165 - cleanWhitespace(&dt.Name)
166 - cleanWhitespace(&dt.Type)
167 -}
Godeps/_workspace/src/github.com/huin/goupnp/service_client.go deleted
-56
@@ -1,56 +0,0 @@
1 -package goupnp
2 -
3 -import (
4 - "fmt"
5 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/soap"
6 -)
7 -
8 -// ServiceClient is a SOAP client, root device and the service for the SOAP
9 -// client rolled into one value. The root device and service are intended to be
10 -// informational.
11 -type ServiceClient struct {
12 - SOAPClient *soap.SOAPClient
13 - RootDevice *RootDevice
14 - Service *Service
15 -}
16 -
17 -func NewServiceClients(searchTarget string) (clients []ServiceClient, errors []error, err error) {
18 - var maybeRootDevices []MaybeRootDevice
19 - if maybeRootDevices, err = DiscoverDevices(searchTarget); err != nil {
20 - return
21 - }
22 -
23 - clients = make([]ServiceClient, 0, len(maybeRootDevices))
24 -
25 - for _, maybeRootDevice := range maybeRootDevices {
26 - if maybeRootDevice.Err != nil {
27 - errors = append(errors, maybeRootDevice.Err)
28 - continue
29 - }
30 -
31 - device := &maybeRootDevice.Root.Device
32 - srvs := device.FindService(searchTarget)
33 - if len(srvs) == 0 {
34 - errors = append(errors, fmt.Errorf("goupnp: service %q not found within device %q (UDN=%q)",
35 - searchTarget, device.FriendlyName, device.UDN))
36 - continue
37 - }
38 -
39 - for _, srv := range srvs {
40 - clients = append(clients, ServiceClient{
41 - SOAPClient: srv.NewSOAPClient(),
42 - RootDevice: maybeRootDevice.Root,
43 - Service: srv,
44 - })
45 - }
46 - }
47 -
48 - return
49 -}
50 -
51 -// GetServiceClient returns the ServiceClient itself. This is provided so that the
52 -// service client attributes can be accessed via an interface method on a
53 -// wrapping type.
54 -func (client *ServiceClient) GetServiceClient() *ServiceClient {
55 - return client
56 -}
Godeps/_workspace/src/github.com/huin/goupnp/soap/soap.go deleted
-157
@@ -1,157 +0,0 @@
1 -// Definition for the SOAP structure required for UPnP's SOAP usage.
2 -
3 -package soap
4 -
5 -import (
6 - "bytes"
7 - "encoding/xml"
8 - "fmt"
9 - "io/ioutil"
10 - "net/http"
11 - "net/url"
12 - "reflect"
13 -)
14 -
15 -const (
16 - soapEncodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"
17 - soapPrefix = xml.Header + `<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body>`
18 - soapSuffix = `</s:Body></s:Envelope>`
19 -)
20 -
21 -type SOAPClient struct {
22 - EndpointURL url.URL
23 - HTTPClient http.Client
24 -}
25 -
26 -func NewSOAPClient(endpointURL url.URL) *SOAPClient {
27 - return &SOAPClient{
28 - EndpointURL: endpointURL,
29 - }
30 -}
31 -
32 -// PerformSOAPAction makes a SOAP request, with the given action.
33 -// inAction and outAction must both be pointers to structs with string fields
34 -// only.
35 -func (client *SOAPClient) PerformAction(actionNamespace, actionName string, inAction interface{}, outAction interface{}) error {
36 - requestBytes, err := encodeRequestAction(actionNamespace, actionName, inAction)
37 - if err != nil {
38 - return err
39 - }
40 -
41 - response, err := client.HTTPClient.Do(&http.Request{
42 - Method: "POST",
43 - URL: &client.EndpointURL,
44 - Header: http.Header{
45 - "SOAPACTION": []string{actionNamespace + "#" + actionName},
46 - "CONTENT-TYPE": []string{"text/xml; charset=\"utf-8\""},
47 - },
48 - Body: ioutil.NopCloser(bytes.NewBuffer(requestBytes)),
49 - // Set ContentLength to avoid chunked encoding - some servers might not support it.
50 - ContentLength: int64(len(requestBytes)),
51 - })
52 - if err != nil {
53 - return fmt.Errorf("goupnp: error performing SOAP HTTP request: %v", err)
54 - }
55 - defer response.Body.Close()
56 - if response.StatusCode != 200 {
57 - return fmt.Errorf("goupnp: SOAP request got HTTP %s", response.Status)
58 - }
59 -
60 - responseEnv := newSOAPEnvelope()
61 - decoder := xml.NewDecoder(response.Body)
62 - if err := decoder.Decode(responseEnv); err != nil {
63 - return fmt.Errorf("goupnp: error decoding response body: %v", err)
64 - }
65 -
66 - if responseEnv.Body.Fault != nil {
67 - return responseEnv.Body.Fault
68 - }
69 -
70 - if outAction != nil {
71 - if err := xml.Unmarshal(responseEnv.Body.RawAction, outAction); err != nil {
72 - return fmt.Errorf("goupnp: error unmarshalling out action: %v, %v", err, responseEnv.Body.RawAction)
73 - }
74 - }
75 -
76 - return nil
77 -}
78 -
79 -// newSOAPAction creates a soapEnvelope with the given action and arguments.
80 -func newSOAPEnvelope() *soapEnvelope {
81 - return &soapEnvelope{
82 - EncodingStyle: soapEncodingStyle,
83 - }
84 -}
85 -
86 -// encodeRequestAction is a hacky way to create an encoded SOAP envelope
87 -// containing the given action. Experiments with one router have shown that it
88 -// 500s for requests where the outer default xmlns is set to the SOAP
89 -// namespace, and then reassigning the default namespace within that to the
90 -// service namespace. Hand-coding the outer XML to work-around this.
91 -func encodeRequestAction(actionNamespace, actionName string, inAction interface{}) ([]byte, error) {
92 - requestBuf := new(bytes.Buffer)
93 - requestBuf.WriteString(soapPrefix)
94 - requestBuf.WriteString(`<u:`)
95 - xml.EscapeText(requestBuf, []byte(actionName))
96 - requestBuf.WriteString(` xmlns:u="`)
97 - xml.EscapeText(requestBuf, []byte(actionNamespace))
98 - requestBuf.WriteString(`">`)
99 - if inAction != nil {
100 - if err := encodeRequestArgs(requestBuf, inAction); err != nil {
101 - return nil, err
102 - }
103 - }
104 - requestBuf.WriteString(`</u:`)
105 - xml.EscapeText(requestBuf, []byte(actionName))
106 - requestBuf.WriteString(`>`)
107 - requestBuf.WriteString(soapSuffix)
108 - return requestBuf.Bytes(), nil
109 -}
110 -
111 -func encodeRequestArgs(w *bytes.Buffer, inAction interface{}) error {
112 - in := reflect.Indirect(reflect.ValueOf(inAction))
113 - if in.Kind() != reflect.Struct {
114 - return fmt.Errorf("goupnp: SOAP inAction is not a struct but of type %v", in.Type())
115 - }
116 - enc := xml.NewEncoder(w)
117 - nFields := in.NumField()
118 - inType := in.Type()
119 - for i := 0; i < nFields; i++ {
120 - field := inType.Field(i)
121 - argName := field.Name
122 - if nameOverride := field.Tag.Get("soap"); nameOverride != "" {
123 - argName = nameOverride
124 - }
125 - value := in.Field(i)
126 - if value.Kind() != reflect.String {
127 - return fmt.Errorf("goupnp: SOAP arg %q is not of type string, but of type %v", argName, value.Type())
128 - }
129 - if err := enc.EncodeElement(value.Interface(), xml.StartElement{xml.Name{"", argName}, nil}); err != nil {
130 - return fmt.Errorf("goupnp: error encoding SOAP arg %q: %v", argName, err)
131 - }
132 - }
133 - enc.Flush()
134 - return nil
135 -}
136 -
137 -type soapEnvelope struct {
138 - XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
139 - EncodingStyle string `xml:"http://schemas.xmlsoap.org/soap/envelope/ encodingStyle,attr"`
140 - Body soapBody `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
141 -}
142 -
143 -type soapBody struct {
144 - Fault *SOAPFaultError `xml:"Fault"`
145 - RawAction []byte `xml:",innerxml"`
146 -}
147 -
148 -// SOAPFaultError implements error, and contains SOAP fault information.
149 -type SOAPFaultError struct {
150 - FaultCode string `xml:"faultcode"`
151 - FaultString string `xml:"faultstring"`
152 - Detail string `xml:"detail"`
153 -}
154 -
155 -func (err *SOAPFaultError) Error() string {
156 - return fmt.Sprintf("SOAP fault: %s", err.FaultString)
157 -}
Godeps/_workspace/src/github.com/huin/goupnp/soap/soap_test.go deleted
-85
@@ -1,85 +0,0 @@
1 -package soap
2 -
3 -import (
4 - "bytes"
5 - "io/ioutil"
6 - "net/http"
7 - "net/url"
8 - "reflect"
9 - "testing"
10 -)
11 -
12 -type capturingRoundTripper struct {
13 - err error
14 - resp *http.Response
15 - capturedReq *http.Request
16 -}
17 -
18 -func (rt *capturingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
19 - rt.capturedReq = req
20 - return rt.resp, rt.err
21 -}
22 -
23 -func TestActionInputs(t *testing.T) {
24 - url, err := url.Parse("http://example.com/soap")
25 - if err != nil {
26 - t.Fatal(err)
27 - }
28 - rt := &capturingRoundTripper{
29 - err: nil,
30 - resp: &http.Response{
31 - StatusCode: 200,
32 - Body: ioutil.NopCloser(bytes.NewBufferString(`
33 - <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
34 - <s:Body>
35 - <u:myactionResponse xmlns:u="mynamespace">
36 - <A>valueA</A>
37 - <B>valueB</B>
38 - </u:myactionResponse>
39 - </s:Body>
40 - </s:Envelope>
41 - `)),
42 - },
43 - }
44 - client := SOAPClient{
45 - EndpointURL: *url,
46 - HTTPClient: http.Client{
47 - Transport: rt,
48 - },
49 - }
50 -
51 - type In struct {
52 - Foo string
53 - Bar string `soap:"bar"`
54 - }
55 - type Out struct {
56 - A string
57 - B string
58 - }
59 - in := In{"foo", "bar"}
60 - gotOut := Out{}
61 - err = client.PerformAction("mynamespace", "myaction", &in, &gotOut)
62 - if err != nil {
63 - t.Fatal(err)
64 - }
65 -
66 - wantBody := (soapPrefix +
67 - `<u:myaction xmlns:u="mynamespace">` +
68 - `<Foo>foo</Foo>` +
69 - `<bar>bar</bar>` +
70 - `</u:myaction>` +
71 - soapSuffix)
72 - body, err := ioutil.ReadAll(rt.capturedReq.Body)
73 - if err != nil {
74 - t.Fatal(err)
75 - }
76 - gotBody := string(body)
77 - if wantBody != gotBody {
78 - t.Errorf("Bad request body\nwant: %q\n got: %q", wantBody, gotBody)
79 - }
80 -
81 - wantOut := Out{"valueA", "valueB"}
82 - if !reflect.DeepEqual(wantOut, gotOut) {
83 - t.Errorf("Bad output\nwant: %+v\n got: %+v", wantOut, gotOut)
84 - }
85 -}
Godeps/_workspace/src/github.com/huin/goupnp/soap/types.go deleted
-508
@@ -1,508 +0,0 @@
1 -package soap
2 -
3 -import (
4 - "encoding/base64"
5 - "encoding/hex"
6 - "errors"
7 - "fmt"
8 - "regexp"
9 - "strconv"
10 - "strings"
11 - "time"
12 - "unicode/utf8"
13 -)
14 -
15 -var (
16 - // localLoc acts like time.Local for this package, but is faked out by the
17 - // unit tests to ensure that things stay constant (especially when running
18 - // this test in a place where local time is UTC which might mask bugs).
19 - localLoc = time.Local
20 -)
21 -
22 -func MarshalUi1(v uint8) (string, error) {
23 - return strconv.FormatUint(uint64(v), 10), nil
24 -}
25 -
26 -func UnmarshalUi1(s string) (uint8, error) {
27 - v, err := strconv.ParseUint(s, 10, 8)
28 - return uint8(v), err
29 -}
30 -
31 -func MarshalUi2(v uint16) (string, error) {
32 - return strconv.FormatUint(uint64(v), 10), nil
33 -}
34 -
35 -func UnmarshalUi2(s string) (uint16, error) {
36 - v, err := strconv.ParseUint(s, 10, 16)
37 - return uint16(v), err
38 -}
39 -
40 -func MarshalUi4(v uint32) (string, error) {
41 - return strconv.FormatUint(uint64(v), 10), nil
42 -}
43 -
44 -func UnmarshalUi4(s string) (uint32, error) {
45 - v, err := strconv.ParseUint(s, 10, 32)
46 - return uint32(v), err
47 -}
48 -
49 -func MarshalI1(v int8) (string, error) {
50 - return strconv.FormatInt(int64(v), 10), nil
51 -}
52 -
53 -func UnmarshalI1(s string) (int8, error) {
54 - v, err := strconv.ParseInt(s, 10, 8)
55 - return int8(v), err
56 -}
57 -
58 -func MarshalI2(v int16) (string, error) {
59 - return strconv.FormatInt(int64(v), 10), nil
60 -}
61 -
62 -func UnmarshalI2(s string) (int16, error) {
63 - v, err := strconv.ParseInt(s, 10, 16)
64 - return int16(v), err
65 -}
66 -
67 -func MarshalI4(v int32) (string, error) {
68 - return strconv.FormatInt(int64(v), 10), nil
69 -}
70 -
71 -func UnmarshalI4(s string) (int32, error) {
72 - v, err := strconv.ParseInt(s, 10, 32)
73 - return int32(v), err
74 -}
75 -
76 -func MarshalInt(v int64) (string, error) {
77 - return strconv.FormatInt(v, 10), nil
78 -}
79 -
80 -func UnmarshalInt(s string) (int64, error) {
81 - return strconv.ParseInt(s, 10, 64)
82 -}
83 -
84 -func MarshalR4(v float32) (string, error) {
85 - return strconv.FormatFloat(float64(v), 'G', -1, 32), nil
86 -}
87 -
88 -func UnmarshalR4(s string) (float32, error) {
89 - v, err := strconv.ParseFloat(s, 32)
90 - return float32(v), err
91 -}
92 -
93 -func MarshalR8(v float64) (string, error) {
94 - return strconv.FormatFloat(v, 'G', -1, 64), nil
95 -}
96 -
97 -func UnmarshalR8(s string) (float64, error) {
98 - v, err := strconv.ParseFloat(s, 64)
99 - return float64(v), err
100 -}
101 -
102 -// MarshalFixed14_4 marshals float64 to SOAP "fixed.14.4" type.
103 -func MarshalFixed14_4(v float64) (string, error) {
104 - if v >= 1e14 || v <= -1e14 {
105 - return "", fmt.Errorf("soap fixed14.4: value %v out of bounds", v)
106 - }
107 - return strconv.FormatFloat(v, 'f', 4, 64), nil
108 -}
109 -
110 -// UnmarshalFixed14_4 unmarshals float64 from SOAP "fixed.14.4" type.
111 -func UnmarshalFixed14_4(s string) (float64, error) {
112 - v, err := strconv.ParseFloat(s, 64)
113 - if err != nil {
114 - return 0, err
115 - }
116 - if v >= 1e14 || v <= -1e14 {
117 - return 0, fmt.Errorf("soap fixed14.4: value %q out of bounds", s)
118 - }
119 - return v, nil
120 -}
121 -
122 -// MarshalChar marshals rune to SOAP "char" type.
123 -func MarshalChar(v rune) (string, error) {
124 - if v == 0 {
125 - return "", errors.New("soap char: rune 0 is not allowed")
126 - }
127 - return string(v), nil
128 -}
129 -
130 -// UnmarshalChar unmarshals rune from SOAP "char" type.
131 -func UnmarshalChar(s string) (rune, error) {
132 - if len(s) == 0 {
133 - return 0, errors.New("soap char: got empty string")
134 - }
135 - r, n := utf8.DecodeRune([]byte(s))
136 - if n != len(s) {
137 - return 0, fmt.Errorf("soap char: value %q is not a single rune", s)
138 - }
139 - return r, nil
140 -}
141 -
142 -func MarshalString(v string) (string, error) {
143 - return v, nil
144 -}
145 -
146 -func UnmarshalString(v string) (string, error) {
147 - return v, nil
148 -}
149 -
150 -func parseInt(s string, err *error) int {
151 - v, parseErr := strconv.ParseInt(s, 10, 64)
152 - if parseErr != nil {
153 - *err = parseErr
154 - }
155 - return int(v)
156 -}
157 -
158 -var dateRegexps = []*regexp.Regexp{
159 - // yyyy[-mm[-dd]]
160 - regexp.MustCompile(`^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?$`),
161 - // yyyy[mm[dd]]
162 - regexp.MustCompile(`^(\d{4})(?:(\d{2})(?:(\d{2}))?)?$`),
163 -}
164 -
165 -func parseDateParts(s string) (year, month, day int, err error) {
166 - var parts []string
167 - for _, re := range dateRegexps {
168 - parts = re.FindStringSubmatch(s)
169 - if parts != nil {
170 - break
171 - }
172 - }
173 - if parts == nil {
174 - err = fmt.Errorf("soap date: value %q is not in a recognized ISO8601 date format", s)
175 - return
176 - }
177 -
178 - year = parseInt(parts[1], &err)
179 - month = 1
180 - day = 1
181 - if len(parts[2]) != 0 {
182 - month = parseInt(parts[2], &err)
183 - if len(parts[3]) != 0 {
184 - day = parseInt(parts[3], &err)
185 - }
186 - }
187 -
188 - if err != nil {
189 - err = fmt.Errorf("soap date: %q: %v", s, err)
190 - }
191 -
192 - return
193 -}
194 -
195 -var timeRegexps = []*regexp.Regexp{
196 - // hh[:mm[:ss]]
197 - regexp.MustCompile(`^(\d{2})(?::(\d{2})(?::(\d{2}))?)?$`),
198 - // hh[mm[ss]]
199 - regexp.MustCompile(`^(\d{2})(?:(\d{2})(?:(\d{2}))?)?$`),
200 -}
201 -
202 -func parseTimeParts(s string) (hour, minute, second int, err error) {
203 - var parts []string
204 - for _, re := range timeRegexps {
205 - parts = re.FindStringSubmatch(s)
206 - if parts != nil {
207 - break
208 - }
209 - }
210 - if parts == nil {
211 - err = fmt.Errorf("soap time: value %q is not in ISO8601 time format", s)
212 - return
213 - }
214 -
215 - hour = parseInt(parts[1], &err)
216 - if len(parts[2]) != 0 {
217 - minute = parseInt(parts[2], &err)
218 - if len(parts[3]) != 0 {
219 - second = parseInt(parts[3], &err)
220 - }
221 - }
222 -
223 - if err != nil {
224 - err = fmt.Errorf("soap time: %q: %v", s, err)
225 - }
226 -
227 - return
228 -}
229 -
230 -// (+|-)hh[[:]mm]
231 -var timezoneRegexp = regexp.MustCompile(`^([+-])(\d{2})(?::?(\d{2}))?$`)
232 -
233 -func parseTimezone(s string) (offset int, err error) {
234 - if s == "Z" {
235 - return 0, nil
236 - }
237 - parts := timezoneRegexp.FindStringSubmatch(s)
238 - if parts == nil {
239 - err = fmt.Errorf("soap timezone: value %q is not in ISO8601 timezone format", s)
240 - return
241 - }
242 -
243 - offset = parseInt(parts[2], &err) * 3600
244 - if len(parts[3]) != 0 {
245 - offset += parseInt(parts[3], &err) * 60
246 - }
247 - if parts[1] == "-" {
248 - offset = -offset
249 - }
250 -
251 - if err != nil {
252 - err = fmt.Errorf("soap timezone: %q: %v", s, err)
253 - }
254 -
255 - return
256 -}
257 -
258 -var completeDateTimeZoneRegexp = regexp.MustCompile(`^([^T]+)(?:T([^-+Z]+)(.+)?)?$`)
259 -
260 -// splitCompleteDateTimeZone splits date, time and timezone apart from an
261 -// ISO8601 string. It does not ensure that the contents of each part are
262 -// correct, it merely splits on certain delimiters.
263 -// e.g "2010-09-08T12:15:10+0700" => "2010-09-08", "12:15:10", "+0700".
264 -// Timezone can only be present if time is also present.
265 -func splitCompleteDateTimeZone(s string) (dateStr, timeStr, zoneStr string, err error) {
266 - parts := completeDateTimeZoneRegexp.FindStringSubmatch(s)
267 - if parts == nil {
268 - err = fmt.Errorf("soap date/time/zone: value %q is not in ISO8601 datetime format", s)
269 - return
270 - }
271 - dateStr = parts[1]
272 - timeStr = parts[2]
273 - zoneStr = parts[3]
274 - return
275 -}
276 -
277 -// MarshalDate marshals time.Time to SOAP "date" type. Note that this converts
278 -// to local time, and discards the time-of-day components.
279 -func MarshalDate(v time.Time) (string, error) {
280 - return v.In(localLoc).Format("2006-01-02"), nil
281 -}
282 -
283 -var dateFmts = []string{"2006-01-02", "20060102"}
284 -
285 -// UnmarshalDate unmarshals time.Time from SOAP "date" type. This outputs the
286 -// date as midnight in the local time zone.
287 -func UnmarshalDate(s string) (time.Time, error) {
288 - year, month, day, err := parseDateParts(s)
289 - if err != nil {
290 - return time.Time{}, err
291 - }
292 - return time.Date(year, time.Month(month), day, 0, 0, 0, 0, localLoc), nil
293 -}
294 -
295 -// TimeOfDay is used in cases where SOAP "time" or "time.tz" is used.
296 -type TimeOfDay struct {
297 - // Duration of time since midnight.
298 - FromMidnight time.Duration
299 -
300 - // Set to true if Offset is specified. If false, then the timezone is
301 - // unspecified (and by ISO8601 - implies some "local" time).
302 - HasOffset bool
303 -
304 - // Offset is non-zero only if time.tz is used. It is otherwise ignored. If
305 - // non-zero, then it is regarded as a UTC offset in seconds. Note that the
306 - // sub-minutes is ignored by the marshal function.
307 - Offset int
308 -}
309 -
310 -// MarshalTimeOfDay marshals TimeOfDay to the "time" type.
311 -func MarshalTimeOfDay(v TimeOfDay) (string, error) {
312 - d := int64(v.FromMidnight / time.Second)
313 - hour := d / 3600
314 - d = d % 3600
315 - minute := d / 60
316 - second := d % 60
317 -
318 - return fmt.Sprintf("%02d:%02d:%02d", hour, minute, second), nil
319 -}
320 -
321 -// UnmarshalTimeOfDay unmarshals TimeOfDay from the "time" type.
322 -func UnmarshalTimeOfDay(s string) (TimeOfDay, error) {
323 - t, err := UnmarshalTimeOfDayTz(s)
324 - if err != nil {
325 - return TimeOfDay{}, err
326 - } else if t.HasOffset {
327 - return TimeOfDay{}, fmt.Errorf("soap time: value %q contains unexpected timezone")
328 - }
329 - return t, nil
330 -}
331 -
332 -// MarshalTimeOfDayTz marshals TimeOfDay to the "time.tz" type.
333 -func MarshalTimeOfDayTz(v TimeOfDay) (string, error) {
334 - d := int64(v.FromMidnight / time.Second)
335 - hour := d / 3600
336 - d = d % 3600
337 - minute := d / 60
338 - second := d % 60
339 -
340 - tz := ""
341 - if v.HasOffset {
342 - if v.Offset == 0 {
343 - tz = "Z"
344 - } else {
345 - offsetMins := v.Offset / 60
346 - sign := '+'
347 - if offsetMins < 1 {
348 - offsetMins = -offsetMins
349 - sign = '-'
350 - }
351 - tz = fmt.Sprintf("%c%02d:%02d", sign, offsetMins/60, offsetMins%60)
352 - }
353 - }
354 -
355 - return fmt.Sprintf("%02d:%02d:%02d%s", hour, minute, second, tz), nil
356 -}
357 -
358 -// UnmarshalTimeOfDayTz unmarshals TimeOfDay from the "time.tz" type.
359 -func UnmarshalTimeOfDayTz(s string) (tod TimeOfDay, err error) {
360 - zoneIndex := strings.IndexAny(s, "Z+-")
361 - var timePart string
362 - var hasOffset bool
363 - var offset int
364 - if zoneIndex == -1 {
365 - hasOffset = false
366 - timePart = s
367 - } else {
368 - hasOffset = true
369 - timePart = s[:zoneIndex]
370 - if offset, err = parseTimezone(s[zoneIndex:]); err != nil {
371 - return
372 - }
373 - }
374 -
375 - hour, minute, second, err := parseTimeParts(timePart)
376 - if err != nil {
377 - return
378 - }
379 -
380 - fromMidnight := time.Duration(hour*3600+minute*60+second) * time.Second
381 -
382 - // ISO8601 special case - values up to 24:00:00 are allowed, so using
383 - // strictly greater-than for the maximum value.
384 - if fromMidnight > 24*time.Hour || minute >= 60 || second >= 60 {
385 - return TimeOfDay{}, fmt.Errorf("soap time.tz: value %q has value(s) out of range", s)
386 - }
387 -
388 - return TimeOfDay{
389 - FromMidnight: time.Duration(hour*3600+minute*60+second) * time.Second,
390 - HasOffset: hasOffset,
391 - Offset: offset,
392 - }, nil
393 -}
394 -
395 -// MarshalDateTime marshals time.Time to SOAP "dateTime" type. Note that this
396 -// converts to local time.
397 -func MarshalDateTime(v time.Time) (string, error) {
398 - return v.In(localLoc).Format("2006-01-02T15:04:05"), nil
399 -}
400 -
401 -// UnmarshalDateTime unmarshals time.Time from the SOAP "dateTime" type. This
402 -// returns a value in the local timezone.
403 -func UnmarshalDateTime(s string) (result time.Time, err error) {
404 - dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s)
405 - if err != nil {
406 - return
407 - }
408 -
409 - if len(zoneStr) != 0 {
410 - err = fmt.Errorf("soap datetime: unexpected timezone in %q", s)
411 - return
412 - }
413 -
414 - year, month, day, err := parseDateParts(dateStr)
415 - if err != nil {
416 - return
417 - }
418 -
419 - var hour, minute, second int
420 - if len(timeStr) != 0 {
421 - hour, minute, second, err = parseTimeParts(timeStr)
422 - if err != nil {
423 - return
424 - }
425 - }
426 -
427 - result = time.Date(year, time.Month(month), day, hour, minute, second, 0, localLoc)
428 - return
429 -}
430 -
431 -// MarshalDateTimeTz marshals time.Time to SOAP "dateTime.tz" type.
432 -func MarshalDateTimeTz(v time.Time) (string, error) {
433 - return v.Format("2006-01-02T15:04:05-07:00"), nil
434 -}
435 -
436 -// UnmarshalDateTimeTz unmarshals time.Time from the SOAP "dateTime.tz" type.
437 -// This returns a value in the local timezone when the timezone is unspecified.
438 -func UnmarshalDateTimeTz(s string) (result time.Time, err error) {
439 - dateStr, timeStr, zoneStr, err := splitCompleteDateTimeZone(s)
440 - if err != nil {
441 - return
442 - }
443 -
444 - year, month, day, err := parseDateParts(dateStr)
445 - if err != nil {
446 - return
447 - }
448 -
449 - var hour, minute, second int
450 - var location *time.Location = localLoc
451 - if len(timeStr) != 0 {
452 - hour, minute, second, err = parseTimeParts(timeStr)
453 - if err != nil {
454 - return
455 - }
456 - if len(zoneStr) != 0 {
457 - var offset int
458 - offset, err = parseTimezone(zoneStr)
459 - if offset == 0 {
460 - location = time.UTC
461 - } else {
462 - location = time.FixedZone("", offset)
463 - }
464 - }
465 - }
466 -
467 - result = time.Date(year, time.Month(month), day, hour, minute, second, 0, location)
468 - return
469 -}
470 -
471 -// MarshalBoolean marshals bool to SOAP "boolean" type.
472 -func MarshalBoolean(v bool) (string, error) {
473 - if v {
474 - return "1", nil
475 - }
476 - return "0", nil
477 -}
478 -
479 -// UnmarshalBoolean unmarshals bool from the SOAP "boolean" type.
480 -func UnmarshalBoolean(s string) (bool, error) {
481 - switch s {
482 - case "0", "false", "no":
483 - return false, nil
484 - case "1", "true", "yes":
485 - return true, nil
486 - }
487 - return false, fmt.Errorf("soap boolean: %q is not a valid boolean value", s)
488 -}
489 -
490 -// MarshalBinBase64 marshals []byte to SOAP "bin.base64" type.
491 -func MarshalBinBase64(v []byte) (string, error) {
492 - return base64.StdEncoding.EncodeToString(v), nil
493 -}
494 -
495 -// UnmarshalBinBase64 unmarshals []byte from the SOAP "bin.base64" type.
496 -func UnmarshalBinBase64(s string) ([]byte, error) {
497 - return base64.StdEncoding.DecodeString(s)
498 -}
499 -
500 -// MarshalBinHex marshals []byte to SOAP "bin.hex" type.
501 -func MarshalBinHex(v []byte) (string, error) {
502 - return hex.EncodeToString(v), nil
503 -}
504 -
505 -// UnmarshalBinHex unmarshals []byte from the SOAP "bin.hex" type.
506 -func UnmarshalBinHex(s string) ([]byte, error) {
507 - return hex.DecodeString(s)
508 -}
Godeps/_workspace/src/github.com/huin/goupnp/soap/types_test.go deleted
-481
@@ -1,481 +0,0 @@
1 -package soap
2 -
3 -import (
4 - "bytes"
5 - "math"
6 - "testing"
7 - "time"
8 -)
9 -
10 -type convTest interface {
11 - Marshal() (string, error)
12 - Unmarshal(string) (interface{}, error)
13 - Equal(result interface{}) bool
14 -}
15 -
16 -// duper is an interface that convTest values may optionally also implement to
17 -// generate another convTest for a value in an otherwise identical testCase.
18 -type duper interface {
19 - Dupe(tag string) []convTest
20 -}
21 -
22 -type testCase struct {
23 - value convTest
24 - str string
25 - wantMarshalErr bool
26 - wantUnmarshalErr bool
27 - noMarshal bool
28 - noUnMarshal bool
29 - tag string
30 -}
31 -
32 -type Ui1Test uint8
33 -
34 -func (v Ui1Test) Marshal() (string, error) {
35 - return MarshalUi1(uint8(v))
36 -}
37 -func (v Ui1Test) Unmarshal(s string) (interface{}, error) {
38 - return UnmarshalUi1(s)
39 -}
40 -func (v Ui1Test) Equal(result interface{}) bool {
41 - return uint8(v) == result.(uint8)
42 -}
43 -func (v Ui1Test) Dupe(tag string) []convTest {
44 - if tag == "dupe" {
45 - return []convTest{
46 - Ui2Test(v),
47 - Ui4Test(v),
48 - }
49 - }
50 - return nil
51 -}
52 -
53 -type Ui2Test uint16
54 -
55 -func (v Ui2Test) Marshal() (string, error) {
56 - return MarshalUi2(uint16(v))
57 -}
58 -func (v Ui2Test) Unmarshal(s string) (interface{}, error) {
59 - return UnmarshalUi2(s)
60 -}
61 -func (v Ui2Test) Equal(result interface{}) bool {
62 - return uint16(v) == result.(uint16)
63 -}
64 -
65 -type Ui4Test uint32
66 -
67 -func (v Ui4Test) Marshal() (string, error) {
68 - return MarshalUi4(uint32(v))
69 -}
70 -func (v Ui4Test) Unmarshal(s string) (interface{}, error) {
71 - return UnmarshalUi4(s)
72 -}
73 -func (v Ui4Test) Equal(result interface{}) bool {
74 - return uint32(v) == result.(uint32)
75 -}
76 -
77 -type I1Test int8
78 -
79 -func (v I1Test) Marshal() (string, error) {
80 - return MarshalI1(int8(v))
81 -}
82 -func (v I1Test) Unmarshal(s string) (interface{}, error) {
83 - return UnmarshalI1(s)
84 -}
85 -func (v I1Test) Equal(result interface{}) bool {
86 - return int8(v) == result.(int8)
87 -}
88 -func (v I1Test) Dupe(tag string) []convTest {
89 - if tag == "dupe" {
90 - return []convTest{
91 - I2Test(v),
92 - I4Test(v),
93 - }
94 - }
95 - return nil
96 -}
97 -
98 -type I2Test int16
99 -
100 -func (v I2Test) Marshal() (string, error) {
101 - return MarshalI2(int16(v))
102 -}
103 -func (v I2Test) Unmarshal(s string) (interface{}, error) {
104 - return UnmarshalI2(s)
105 -}
106 -func (v I2Test) Equal(result interface{}) bool {
107 - return int16(v) == result.(int16)
108 -}
109 -
110 -type I4Test int32
111 -
112 -func (v I4Test) Marshal() (string, error) {
113 - return MarshalI4(int32(v))
114 -}
115 -func (v I4Test) Unmarshal(s string) (interface{}, error) {
116 - return UnmarshalI4(s)
117 -}
118 -func (v I4Test) Equal(result interface{}) bool {
119 - return int32(v) == result.(int32)
120 -}
121 -
122 -type IntTest int64
123 -
124 -func (v IntTest) Marshal() (string, error) {
125 - return MarshalInt(int64(v))
126 -}
127 -func (v IntTest) Unmarshal(s string) (interface{}, error) {
128 - return UnmarshalInt(s)
129 -}
130 -func (v IntTest) Equal(result interface{}) bool {
131 - return int64(v) == result.(int64)
132 -}
133 -
134 -type Fixed14_4Test float64
135 -
136 -func (v Fixed14_4Test) Marshal() (string, error) {
137 - return MarshalFixed14_4(float64(v))
138 -}
139 -func (v Fixed14_4Test) Unmarshal(s string) (interface{}, error) {
140 - return UnmarshalFixed14_4(s)
141 -}
142 -func (v Fixed14_4Test) Equal(result interface{}) bool {
143 - return math.Abs(float64(v)-result.(float64)) < 0.001
144 -}
145 -
146 -type CharTest rune
147 -
148 -func (v CharTest) Marshal() (string, error) {
149 - return MarshalChar(rune(v))
150 -}
151 -func (v CharTest) Unmarshal(s string) (interface{}, error) {
152 - return UnmarshalChar(s)
153 -}
154 -func (v CharTest) Equal(result interface{}) bool {
155 - return rune(v) == result.(rune)
156 -}
157 -
158 -type DateTest struct{ time.Time }
159 -
160 -func (v DateTest) Marshal() (string, error) {
161 - return MarshalDate(time.Time(v.Time))
162 -}
163 -func (v DateTest) Unmarshal(s string) (interface{}, error) {
164 - return UnmarshalDate(s)
165 -}
166 -func (v DateTest) Equal(result interface{}) bool {
167 - return v.Time.Equal(result.(time.Time))
168 -}
169 -func (v DateTest) Dupe(tag string) []convTest {
170 - if tag != "no:dateTime" {
171 - return []convTest{DateTimeTest{v.Time}}
172 - }
173 - return nil
174 -}
175 -
176 -type TimeOfDayTest struct {
177 - TimeOfDay
178 -}
179 -
180 -func (v TimeOfDayTest) Marshal() (string, error) {
181 - return MarshalTimeOfDay(v.TimeOfDay)
182 -}
183 -func (v TimeOfDayTest) Unmarshal(s string) (interface{}, error) {
184 - return UnmarshalTimeOfDay(s)
185 -}
186 -func (v TimeOfDayTest) Equal(result interface{}) bool {
187 - return v.TimeOfDay == result.(TimeOfDay)
188 -}
189 -func (v TimeOfDayTest) Dupe(tag string) []convTest {
190 - if tag != "no:time.tz" {
191 - return []convTest{TimeOfDayTzTest{v.TimeOfDay}}
192 - }
193 - return nil
194 -}
195 -
196 -type TimeOfDayTzTest struct {
197 - TimeOfDay
198 -}
199 -
200 -func (v TimeOfDayTzTest) Marshal() (string, error) {
201 - return MarshalTimeOfDayTz(v.TimeOfDay)
202 -}
203 -func (v TimeOfDayTzTest) Unmarshal(s string) (interface{}, error) {
204 - return UnmarshalTimeOfDayTz(s)
205 -}
206 -func (v TimeOfDayTzTest) Equal(result interface{}) bool {
207 - return v.TimeOfDay == result.(TimeOfDay)
208 -}
209 -
210 -type DateTimeTest struct{ time.Time }
211 -
212 -func (v DateTimeTest) Marshal() (string, error) {
213 - return MarshalDateTime(time.Time(v.Time))
214 -}
215 -func (v DateTimeTest) Unmarshal(s string) (interface{}, error) {
216 - return UnmarshalDateTime(s)
217 -}
218 -func (v DateTimeTest) Equal(result interface{}) bool {
219 - return v.Time.Equal(result.(time.Time))
220 -}
221 -func (v DateTimeTest) Dupe(tag string) []convTest {
222 - if tag != "no:dateTime.tz" {
223 - return []convTest{DateTimeTzTest{v.Time}}
224 - }
225 - return nil
226 -}
227 -
228 -type DateTimeTzTest struct{ time.Time }
229 -
230 -func (v DateTimeTzTest) Marshal() (string, error) {
231 - return MarshalDateTimeTz(time.Time(v.Time))
232 -}
233 -func (v DateTimeTzTest) Unmarshal(s string) (interface{}, error) {
234 - return UnmarshalDateTimeTz(s)
235 -}
236 -func (v DateTimeTzTest) Equal(result interface{}) bool {
237 - return v.Time.Equal(result.(time.Time))
238 -}
239 -
240 -type BooleanTest bool
241 -
242 -func (v BooleanTest) Marshal() (string, error) {
243 - return MarshalBoolean(bool(v))
244 -}
245 -func (v BooleanTest) Unmarshal(s string) (interface{}, error) {
246 - return UnmarshalBoolean(s)
247 -}
248 -func (v BooleanTest) Equal(result interface{}) bool {
249 - return bool(v) == result.(bool)
250 -}
251 -
252 -type BinBase64Test []byte
253 -
254 -func (v BinBase64Test) Marshal() (string, error) {
255 - return MarshalBinBase64([]byte(v))
256 -}
257 -func (v BinBase64Test) Unmarshal(s string) (interface{}, error) {
258 - return UnmarshalBinBase64(s)
259 -}
260 -func (v BinBase64Test) Equal(result interface{}) bool {
261 - return bytes.Equal([]byte(v), result.([]byte))
262 -}
263 -
264 -type BinHexTest []byte
265 -
266 -func (v BinHexTest) Marshal() (string, error) {
267 - return MarshalBinHex([]byte(v))
268 -}
269 -func (v BinHexTest) Unmarshal(s string) (interface{}, error) {
270 - return UnmarshalBinHex(s)
271 -}
272 -func (v BinHexTest) Equal(result interface{}) bool {
273 - return bytes.Equal([]byte(v), result.([]byte))
274 -}
275 -
276 -func Test(t *testing.T) {
277 - const time010203 time.Duration = (1*3600 + 2*60 + 3) * time.Second
278 - const time0102 time.Duration = (1*3600 + 2*60) * time.Second
279 - const time01 time.Duration = (1 * 3600) * time.Second
280 - const time235959 time.Duration = (23*3600 + 59*60 + 59) * time.Second
281 -
282 - // Fake out the local time for the implementation.
283 - localLoc = time.FixedZone("Fake/Local", 6*3600)
284 - defer func() {
285 - localLoc = time.Local
286 - }()
287 -
288 - tests := []testCase{
289 - // ui1
290 - {str: "", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"},
291 - {str: " ", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"},
292 - {str: "abc", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"},
293 - {str: "-1", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"},
294 - {str: "0", value: Ui1Test(0), tag: "dupe"},
295 - {str: "1", value: Ui1Test(1), tag: "dupe"},
296 - {str: "255", value: Ui1Test(255), tag: "dupe"},
297 - {str: "256", value: Ui1Test(0), wantUnmarshalErr: true, noMarshal: true},
298 -
299 - // ui2
300 - {str: "65535", value: Ui2Test(65535)},
301 - {str: "65536", value: Ui2Test(0), wantUnmarshalErr: true, noMarshal: true},
302 -
303 - // ui4
304 - {str: "4294967295", value: Ui4Test(4294967295)},
305 - {str: "4294967296", value: Ui4Test(0), wantUnmarshalErr: true, noMarshal: true},
306 -
307 - // i1
308 - {str: "", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"},
309 - {str: " ", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"},
310 - {str: "abc", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true, tag: "dupe"},
311 - {str: "0", value: I1Test(0), tag: "dupe"},
312 - {str: "-1", value: I1Test(-1), tag: "dupe"},
313 - {str: "127", value: I1Test(127), tag: "dupe"},
314 - {str: "-128", value: I1Test(-128), tag: "dupe"},
315 - {str: "128", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true},
316 - {str: "-129", value: I1Test(0), wantUnmarshalErr: true, noMarshal: true},
317 -
318 - // i2
319 - {str: "32767", value: I2Test(32767)},
320 - {str: "-32768", value: I2Test(-32768)},
321 - {str: "32768", value: I2Test(0), wantUnmarshalErr: true, noMarshal: true},
322 - {str: "-32769", value: I2Test(0), wantUnmarshalErr: true, noMarshal: true},
323 -
324 - // i4
325 - {str: "2147483647", value: I4Test(2147483647)},
326 - {str: "-2147483648", value: I4Test(-2147483648)},
327 - {str: "2147483648", value: I4Test(0), wantUnmarshalErr: true, noMarshal: true},
328 - {str: "-2147483649", value: I4Test(0), wantUnmarshalErr: true, noMarshal: true},
329 -
330 - // int
331 - {str: "9223372036854775807", value: IntTest(9223372036854775807)},
332 - {str: "-9223372036854775808", value: IntTest(-9223372036854775808)},
333 - {str: "9223372036854775808", value: IntTest(0), wantUnmarshalErr: true, noMarshal: true},
334 - {str: "-9223372036854775809", value: IntTest(0), wantUnmarshalErr: true, noMarshal: true},
335 -
336 - // fixed.14.4
337 - {str: "0.0000", value: Fixed14_4Test(0)},
338 - {str: "1.0000", value: Fixed14_4Test(1)},
339 - {str: "1.2346", value: Fixed14_4Test(1.23456)},
340 - {str: "-1.0000", value: Fixed14_4Test(-1)},
341 - {str: "-1.2346", value: Fixed14_4Test(-1.23456)},
342 - {str: "10000000000000.0000", value: Fixed14_4Test(1e13)},
343 - {str: "100000000000000.0000", value: Fixed14_4Test(1e14), wantMarshalErr: true, wantUnmarshalErr: true},
344 - {str: "-10000000000000.0000", value: Fixed14_4Test(-1e13)},
345 - {str: "-100000000000000.0000", value: Fixed14_4Test(-1e14), wantMarshalErr: true, wantUnmarshalErr: true},
346 -
347 - // char
348 - {str: "a", value: CharTest('a')},
349 - {str: "z", value: CharTest('z')},
350 - {str: "\u1234", value: CharTest(0x1234)},
351 - {str: "aa", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true},
352 - {str: "", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true},
353 -
354 - // date
355 - {str: "2013-10-08", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, tag: "no:dateTime"},
356 - {str: "20131008", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, noMarshal: true, tag: "no:dateTime"},
357 - {str: "2013-10-08T10:30:50", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime"},
358 - {str: "2013-10-08T10:30:50Z", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime"},
359 - {str: "", value: DateTest{}, wantMarshalErr: true, wantUnmarshalErr: true, noMarshal: true},
360 - {str: "-1", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true},
361 -
362 - // time
363 - {str: "00:00:00", value: TimeOfDayTest{TimeOfDay{FromMidnight: 0}}},
364 - {str: "000000", value: TimeOfDayTest{TimeOfDay{FromMidnight: 0}}, noMarshal: true},
365 - {str: "24:00:00", value: TimeOfDayTest{TimeOfDay{FromMidnight: 24 * time.Hour}}, noMarshal: true}, // ISO8601 special case
366 - {str: "24:01:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
367 - {str: "24:00:01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
368 - {str: "25:00:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
369 - {str: "00:60:00", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
370 - {str: "00:00:60", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
371 - {str: "01:02:03", value: TimeOfDayTest{TimeOfDay{FromMidnight: time010203}}},
372 - {str: "010203", value: TimeOfDayTest{TimeOfDay{FromMidnight: time010203}}, noMarshal: true},
373 - {str: "23:59:59", value: TimeOfDayTest{TimeOfDay{FromMidnight: time235959}}},
374 - {str: "235959", value: TimeOfDayTest{TimeOfDay{FromMidnight: time235959}}, noMarshal: true},
375 - {str: "01:02", value: TimeOfDayTest{TimeOfDay{FromMidnight: time0102}}, noMarshal: true},
376 - {str: "0102", value: TimeOfDayTest{TimeOfDay{FromMidnight: time0102}}, noMarshal: true},
377 - {str: "01", value: TimeOfDayTest{TimeOfDay{FromMidnight: time01}}, noMarshal: true},
378 - {str: "foo 01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
379 - {str: "foo\n01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
380 - {str: "01:02:03 foo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
381 - {str: "01:02:03\nfoo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
382 - {str: "01:02:03Z", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
383 - {str: "01:02:03+01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
384 - {str: "01:02:03+01:23", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
385 - {str: "01:02:03+0123", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
386 - {str: "01:02:03-01", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
387 - {str: "01:02:03-01:23", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
388 - {str: "01:02:03-0123", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:time.tz"},
389 -
390 - // time.tz
391 - {str: "24:00:01", value: TimeOfDayTzTest{}, wantUnmarshalErr: true, noMarshal: true},
392 - {str: "01Z", value: TimeOfDayTzTest{TimeOfDay{time01, true, 0}}, noMarshal: true},
393 - {str: "01:02:03Z", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 0}}},
394 - {str: "01+01", value: TimeOfDayTzTest{TimeOfDay{time01, true, 3600}}, noMarshal: true},
395 - {str: "01:02:03+01", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600}}, noMarshal: true},
396 - {str: "01:02:03+01:23", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600 + 23*60}}},
397 - {str: "01:02:03+0123", value: TimeOfDayTzTest{TimeOfDay{time010203, true, 3600 + 23*60}}, noMarshal: true},
398 - {str: "01:02:03-01", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -3600}}, noMarshal: true},
399 - {str: "01:02:03-01:23", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -(3600 + 23*60)}}},
400 - {str: "01:02:03-0123", value: TimeOfDayTzTest{TimeOfDay{time010203, true, -(3600 + 23*60)}}, noMarshal: true},
401 -
402 - // dateTime
403 - {str: "2013-10-08T00:00:00", value: DateTimeTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, tag: "no:dateTime.tz"},
404 - {str: "20131008", value: DateTimeTest{time.Date(2013, 10, 8, 0, 0, 0, 0, localLoc)}, noMarshal: true},
405 - {str: "2013-10-08T10:30:50", value: DateTimeTest{time.Date(2013, 10, 8, 10, 30, 50, 0, localLoc)}, tag: "no:dateTime.tz"},
406 - {str: "2013-10-08T10:30:50T", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true},
407 - {str: "2013-10-08T10:30:50+01", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"},
408 - {str: "2013-10-08T10:30:50+01:23", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"},
409 - {str: "2013-10-08T10:30:50+0123", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"},
410 - {str: "2013-10-08T10:30:50-01", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"},
411 - {str: "2013-10-08T10:30:50-01:23", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"},
412 - {str: "2013-10-08T10:30:50-0123", value: DateTimeTest{}, wantUnmarshalErr: true, noMarshal: true, tag: "no:dateTime.tz"},
413 -
414 - // dateTime.tz
415 - {str: "2013-10-08T10:30:50", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, localLoc)}, noMarshal: true},
416 - {str: "2013-10-08T10:30:50+01", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:00", 3600))}, noMarshal: true},
417 - {str: "2013-10-08T10:30:50+01:23", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:23", 3600+23*60))}},
418 - {str: "2013-10-08T10:30:50+0123", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("+01:23", 3600+23*60))}, noMarshal: true},
419 - {str: "2013-10-08T10:30:50-01", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:00", -3600))}, noMarshal: true},
420 - {str: "2013-10-08T10:30:50-01:23", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:23", -(3600+23*60)))}},
421 - {str: "2013-10-08T10:30:50-0123", value: DateTimeTzTest{time.Date(2013, 10, 8, 10, 30, 50, 0, time.FixedZone("-01:23", -(3600+23*60)))}, noMarshal: true},
422 -
423 - // boolean
424 - {str: "0", value: BooleanTest(false)},
425 - {str: "1", value: BooleanTest(true)},
426 - {str: "false", value: BooleanTest(false), noMarshal: true},
427 - {str: "true", value: BooleanTest(true), noMarshal: true},
428 - {str: "no", value: BooleanTest(false), noMarshal: true},
429 - {str: "yes", value: BooleanTest(true), noMarshal: true},
430 - {str: "", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true},
431 - {str: "other", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true},
432 - {str: "2", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true},
433 - {str: "-1", value: BooleanTest(false), noMarshal: true, wantUnmarshalErr: true},
434 -
435 - // bin.base64
436 - {str: "", value: BinBase64Test{}},
437 - {str: "YQ==", value: BinBase64Test("a")},
438 - {str: "TG9uZ2VyIFN0cmluZy4=", value: BinBase64Test("Longer String.")},
439 - {str: "TG9uZ2VyIEFsaWduZWQu", value: BinBase64Test("Longer Aligned.")},
440 -
441 - // bin.hex
442 - {str: "", value: BinHexTest{}},
443 - {str: "61", value: BinHexTest("a")},
444 - {str: "4c6f6e67657220537472696e672e", value: BinHexTest("Longer String.")},
445 - {str: "4C6F6E67657220537472696E672E", value: BinHexTest("Longer String."), noMarshal: true},
446 - }
447 -
448 - // Generate extra test cases from convTests that implement duper.
449 - var extras []testCase
450 - for i := range tests {
451 - if duper, ok := tests[i].value.(duper); ok {
452 - dupes := duper.Dupe(tests[i].tag)
453 - for _, duped := range dupes {
454 - dupedCase := testCase(tests[i])
455 - dupedCase.value = duped
456 - extras = append(extras, dupedCase)
457 - }
458 - }
459 - }
460 - tests = append(tests, extras...)
461 -
462 - for _, test := range tests {
463 - if test.noMarshal {
464 - } else if resultStr, err := test.value.Marshal(); err != nil && !test.wantMarshalErr {
465 - t.Errorf("For %T marshal %v, want %q, got error: %v", test.value, test.value, test.str, err)
466 - } else if err == nil && test.wantMarshalErr {
467 - t.Errorf("For %T marshal %v, want error, got %q", test.value, test.value, resultStr)
468 - } else if err == nil && resultStr != test.str {
469 - t.Errorf("For %T marshal %v, want %q, got %q", test.value, test.value, test.str, resultStr)
470 - }
471 -
472 - if test.noUnMarshal {
473 - } else if resultValue, err := test.value.Unmarshal(test.str); err != nil && !test.wantUnmarshalErr {
474 - t.Errorf("For %T unmarshal %q, want %v, got error: %v", test.value, test.str, test.value, err)
475 - } else if err == nil && test.wantUnmarshalErr {
476 - t.Errorf("For %T unmarshal %q, want error, got %v", test.value, test.str, resultValue)
477 - } else if err == nil && !test.value.Equal(resultValue) {
478 - t.Errorf("For %T unmarshal %q, want %v, got %v", test.value, test.str, test.value, resultValue)
479 - }
480 - }
481 -}
Godeps/_workspace/src/github.com/huin/goupnp/ssdp/registry.go deleted
-202
@@ -1,202 +0,0 @@
1 -package ssdp
2 -
3 -import (
4 - "fmt"
5 - "log"
6 - "net/http"
7 - "net/url"
8 - "regexp"
9 - "strconv"
10 - "sync"
11 - "time"
12 -
13 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/httpu"
14 -)
15 -
16 -const (
17 - maxExpiryTimeSeconds = 24 * 60 * 60
18 -)
19 -
20 -var (
21 - maxAgeRx = regexp.MustCompile("max-age=([0-9]+)")
22 -)
23 -
24 -type Entry struct {
25 - // The address that the entry data was actually received from.
26 - RemoteAddr string
27 - // Unique Service Name. Identifies a unique instance of a device or service.
28 - USN string
29 - // Notfication Type. The type of device or service being announced.
30 - NT string
31 - // Server's self-identifying string.
32 - Server string
33 - Host string
34 - // Location of the UPnP root device description.
35 - Location *url.URL
36 -
37 - // Despite BOOTID,CONFIGID being required fields, apparently they are not
38 - // always set by devices. Set to -1 if not present.
39 -
40 - BootID int32
41 - ConfigID int32
42 -
43 - SearchPort uint16
44 -
45 - // When the last update was received for this entry identified by this USN.
46 - LastUpdate time.Time
47 - // When the last update's cached values are advised to expire.
48 - CacheExpiry time.Time
49 -}
50 -
51 -func newEntryFromRequest(r *http.Request) (*Entry, error) {
52 - now := time.Now()
53 - expiryDuration, err := parseCacheControlMaxAge(r.Header.Get("CACHE-CONTROL"))
54 - if err != nil {
55 - return nil, fmt.Errorf("ssdp: error parsing CACHE-CONTROL max age: %v", err)
56 - }
57 -
58 - loc, err := url.Parse(r.Header.Get("LOCATION"))
59 - if err != nil {
60 - return nil, fmt.Errorf("ssdp: error parsing entry Location URL: %v", err)
61 - }
62 -
63 - bootID, err := parseUpnpIntHeader(r.Header, "BOOTID.UPNP.ORG", -1)
64 - if err != nil {
65 - return nil, err
66 - }
67 - configID, err := parseUpnpIntHeader(r.Header, "CONFIGID.UPNP.ORG", -1)
68 - if err != nil {
69 - return nil, err
70 - }
71 - searchPort, err := parseUpnpIntHeader(r.Header, "SEARCHPORT.UPNP.ORG", ssdpSearchPort)
72 - if err != nil {
73 - return nil, err
74 - }
75 -
76 - if searchPort < 1 || searchPort > 65535 {
77 - return nil, fmt.Errorf("ssdp: search port %d is out of range", searchPort)
78 - }
79 -
80 - return &Entry{
81 - RemoteAddr: r.RemoteAddr,
82 - USN: r.Header.Get("USN"),
83 - NT: r.Header.Get("NT"),
84 - Server: r.Header.Get("SERVER"),
85 - Host: r.Header.Get("HOST"),
86 - Location: loc,
87 - BootID: bootID,
88 - ConfigID: configID,
89 - SearchPort: uint16(searchPort),
90 - LastUpdate: now,
91 - CacheExpiry: now.Add(expiryDuration),
92 - }, nil
93 -}
94 -
95 -func parseCacheControlMaxAge(cc string) (time.Duration, error) {
96 - matches := maxAgeRx.FindStringSubmatch(cc)
97 - if len(matches) != 2 {
98 - return 0, fmt.Errorf("did not find exactly one max-age in cache control header: %q", cc)
99 - }
100 - expirySeconds, err := strconv.ParseInt(matches[1], 10, 16)
101 - if err != nil {
102 - return 0, err
103 - }
104 - if expirySeconds < 1 || expirySeconds > maxExpiryTimeSeconds {
105 - return 0, fmt.Errorf("rejecting bad expiry time of %d seconds", expirySeconds)
106 - }
107 - return time.Duration(expirySeconds) * time.Second, nil
108 -}
109 -
110 -// parseUpnpIntHeader is intended to parse the
111 -// {BOOT,CONFIGID,SEARCHPORT}.UPNP.ORG header fields. It returns the def if
112 -// the head is empty or missing.
113 -func parseUpnpIntHeader(headers http.Header, headerName string, def int32) (int32, error) {
114 - s := headers.Get(headerName)
115 - if s == "" {
116 - return def, nil
117 - }
118 - v, err := strconv.ParseInt(s, 10, 32)
119 - if err != nil {
120 - return 0, fmt.Errorf("ssdp: could not parse header %s: %v", headerName, err)
121 - }
122 - return int32(v), nil
123 -}
124 -
125 -var _ httpu.Handler = new(Registry)
126 -
127 -// Registry maintains knowledge of discovered devices and services.
128 -type Registry struct {
129 - lock sync.Mutex
130 - byUSN map[string]*Entry
131 -}
132 -
133 -func NewRegistry() *Registry {
134 - return &Registry{
135 - byUSN: make(map[string]*Entry),
136 - }
137 -}
138 -
139 -// ServeMessage implements httpu.Handler, and uses SSDP NOTIFY requests to
140 -// maintain the registry of devices and services.
141 -func (reg *Registry) ServeMessage(r *http.Request) {
142 - if r.Method != methodNotify {
143 - return
144 - }
145 -
146 - nts := r.Header.Get("nts")
147 -
148 - var err error
149 - switch nts {
150 - case ntsAlive:
151 - err = reg.handleNTSAlive(r)
152 - case ntsUpdate:
153 - err = reg.handleNTSUpdate(r)
154 - case ntsByebye:
155 - err = reg.handleNTSByebye(r)
156 - default:
157 - err = fmt.Errorf("unknown NTS value: %q", nts)
158 - }
159 - log.Printf("In %s request from %s: %v", nts, r.RemoteAddr, err)
160 -}
161 -
162 -func (reg *Registry) handleNTSAlive(r *http.Request) error {
163 - entry, err := newEntryFromRequest(r)
164 - if err != nil {
165 - return err
166 - }
167 -
168 - reg.lock.Lock()
169 - defer reg.lock.Unlock()
170 -
171 - reg.byUSN[entry.USN] = entry
172 -
173 - return nil
174 -}
175 -
176 -func (reg *Registry) handleNTSUpdate(r *http.Request) error {
177 - entry, err := newEntryFromRequest(r)
178 - if err != nil {
179 - return err
180 - }
181 - nextBootID, err := parseUpnpIntHeader(r.Header, "NEXTBOOTID.UPNP.ORG", -1)
182 - if err != nil {
183 - return err
184 - }
185 - entry.BootID = nextBootID
186 -
187 - reg.lock.Lock()
188 - defer reg.lock.Unlock()
189 -
190 - reg.byUSN[entry.USN] = entry
191 -
192 - return nil
193 -}
194 -
195 -func (reg *Registry) handleNTSByebye(r *http.Request) error {
196 - reg.lock.Lock()
197 - defer reg.lock.Unlock()
198 -
199 - delete(reg.byUSN, r.Header.Get("USN"))
200 -
201 - return nil
202 -}
Godeps/_workspace/src/github.com/huin/goupnp/ssdp/ssdp.go deleted
-83
@@ -1,83 +0,0 @@
1 -package ssdp
2 -
3 -import (
4 - "errors"
5 - "log"
6 - "net/http"
7 - "net/url"
8 - "strconv"
9 - "time"
10 -
11 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/huin/goupnp/httpu"
12 -)
13 -
14 -const (
15 - ssdpDiscover = `"ssdp:discover"`
16 - ntsAlive = `ssdp:alive`
17 - ntsByebye = `ssdp:byebye`
18 - ntsUpdate = `ssdp:update`
19 - ssdpUDP4Addr = "239.255.255.250:1900"
20 - ssdpSearchPort = 1900
21 - methodSearch = "M-SEARCH"
22 - methodNotify = "NOTIFY"
23 -)
24 -
25 -// SSDPRawSearch performs a fairly raw SSDP search request, and returns the
26 -// unique response(s) that it receives. Each response has the requested
27 -// searchTarget, a USN, and a valid location. maxWaitSeconds states how long to
28 -// wait for responses in seconds, and must be a minimum of 1 (the
29 -// implementation waits an additional 100ms for responses to arrive), 2 is a
30 -// reasonable value for this. numSends is the number of requests to send - 3 is
31 -// a reasonable value for this.
32 -func SSDPRawSearch(httpu *httpu.HTTPUClient, searchTarget string, maxWaitSeconds int, numSends int) ([]*http.Response, error) {
33 - if maxWaitSeconds < 1 {
34 - return nil, errors.New("ssdp: maxWaitSeconds must be >= 1")
35 - }
36 -
37 - seenUsns := make(map[string]bool)
38 - var responses []*http.Response
39 - req := http.Request{
40 - Method: methodSearch,
41 - // TODO: Support both IPv4 and IPv6.
42 - Host: ssdpUDP4Addr,
43 - URL: &url.URL{Opaque: "*"},
44 - Header: http.Header{
45 - // Putting headers in here avoids them being title-cased.
46 - // (The UPnP discovery protocol uses case-sensitive headers)
47 - "HOST": []string{ssdpUDP4Addr},
48 - "MX": []string{strconv.FormatInt(int64(maxWaitSeconds), 10)},
49 - "MAN": []string{ssdpDiscover},
50 - "ST": []string{searchTarget},
51 - },
52 - }
53 - allResponses, err := httpu.Do(&req, time.Duration(maxWaitSeconds)*time.Second+100*time.Millisecond, numSends)
54 - if err != nil {
55 - return nil, err
56 - }
57 - for _, response := range allResponses {
58 - if response.StatusCode != 200 {
59 - log.Printf("ssdp: got response status code %q in search response", response.Status)
60 - continue
61 - }
62 - if st := response.Header.Get("ST"); st != searchTarget {
63 - log.Printf("ssdp: got unexpected search target result %q", st)
64 - continue
65 - }
66 - location, err := response.Location()
67 - if err != nil {
68 - log.Printf("ssdp: no usable location in search response (discarding): %v", err)
69 - continue
70 - }
71 - usn := response.Header.Get("USN")
72 - if usn == "" {
73 - log.Printf("ssdp: empty/missing USN in search response (using location instead): %v", err)
74 - usn = location.String()
75 - }
76 - if _, alreadySeen := seenUsns[usn]; !alreadySeen {
77 - seenUsns[usn] = true
78 - responses = append(responses, response)
79 - }
80 - }
81 -
82 - return responses, nil
83 -}
Godeps/_workspace/src/github.com/jackpal/go-nat-pmp/LICENSE deleted
-13
@@ -1,13 +0,0 @@
1 - Copyright 2013 John Howard Palevich
2 -
3 - Licensed under the Apache License, Version 2.0 (the "License");
4 - you may not use this file except in compliance with the License.
5 - You may obtain a copy of the License at
6 -
7 - http://www.apache.org/licenses/LICENSE-2.0
8 -
9 - Unless required by applicable law or agreed to in writing, software
10 - distributed under the License is distributed on an "AS IS" BASIS,
11 - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 - See the License for the specific language governing permissions and
13 - limitations under the License.
Godeps/_workspace/src/github.com/jackpal/go-nat-pmp/README.md deleted
-48
@@ -1,48 +0,0 @@
1 -go-nat-pmp
2 -==========
3 -
4 -A Go language client for the NAT-PMP internet protocol for port mapping and discovering the external
5 -IP address of a firewall.
6 -
7 -NAT-PMP is supported by Apple brand routers and open source routers like Tomato and DD-WRT.
8 -
9 -See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
10 -
11 -Get the package
12 ----------------
13 -
14 - go get -u github.com/jackpal/go-nat-pmp
15 -
16 -Usage
17 ------
18 -
19 - import natpmp "github.com/jackpal/go-nat-pmp"
20 -
21 - client := natpmp.NewClient(gatewayIP)
22 - response, err := client.GetExternalAddress()
23 - if err != nil {
24 - return
25 - }
26 - print("External IP address:", response.ExternalIPAddress)
27 -
28 -Notes
29 ------
30 -
31 -There doesn't seem to be an easy way to programmatically determine the address of the default gateway.
32 -(Linux and OSX have a "routes" kernel API that can be examined to get this information, but there is
33 -no Go package for getting this information.)
34 -
35 -Clients
36 --------
37 -
38 -This library is used in the Taipei Torrent BitTorrent client http://github.com/jackpal/Taipei-Torrent
39 -
40 -Complete documentation
41 -----------------------
42 -
43 - http://godoc.org/github.com/jackpal/go-nat-pmp
44 -
45 -License
46 --------
47 -
48 -This project is licensed under the Apache License 2.0.
Godeps/_workspace/src/github.com/jackpal/go-nat-pmp/natpmp.go deleted
-184
@@ -1,184 +0,0 @@
1 -package natpmp
2 -
3 -import (
4 - "fmt"
5 - "log"
6 - "net"
7 - "time"
8 -)
9 -
10 -// Implement the NAT-PMP protocol, typically supported by Apple routers and open source
11 -// routers such as DD-WRT and Tomato.
12 -//
13 -// See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
14 -//
15 -// Usage:
16 -//
17 -// client := natpmp.NewClient(gatewayIP)
18 -// response, err := client.GetExternalAddress()
19 -
20 -const nAT_PMP_PORT = 5351
21 -
22 -const nAT_TRIES = 9
23 -
24 -const nAT_INITIAL_MS = 250
25 -
26 -// The recommended mapping lifetime for AddPortMapping
27 -const RECOMMENDED_MAPPING_LIFETIME_SECONDS = 3600
28 -
29 -// Client is a NAT-PMP protocol client.
30 -type Client struct {
31 - gateway net.IP
32 -}
33 -
34 -// Create a NAT-PMP client for the NAT-PMP server at the gateway.
35 -func NewClient(gateway net.IP) (nat *Client) {
36 - return &Client{gateway}
37 -}
38 -
39 -// Results of the NAT-PMP GetExternalAddress operation
40 -type GetExternalAddressResult struct {
41 - SecondsSinceStartOfEpoc uint32
42 - ExternalIPAddress [4]byte
43 -}
44 -
45 -// Get the external address of the router.
46 -func (n *Client) GetExternalAddress() (result *GetExternalAddressResult, err error) {
47 - msg := make([]byte, 2)
48 - msg[0] = 0 // Version 0
49 - msg[1] = 0 // OP Code 0
50 - response, err := n.rpc(msg, 12)
51 - if err != nil {
52 - return
53 - }
54 - result = &GetExternalAddressResult{}
55 - result.SecondsSinceStartOfEpoc = readNetworkOrderUint32(response[4:8])
56 - copy(result.ExternalIPAddress[:], response[8:12])
57 - return
58 -}
59 -
60 -// Results of the NAT-PMP AddPortMapping operation
61 -type AddPortMappingResult struct {
62 - SecondsSinceStartOfEpoc uint32
63 - InternalPort uint16
64 - MappedExternalPort uint16
65 - PortMappingLifetimeInSeconds uint32
66 -}
67 -
68 -// Add (or delete) a port mapping. To delete a mapping, set the requestedExternalPort and lifetime to 0
69 -func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternalPort int, lifetime int) (result *AddPortMappingResult, err error) {
70 - var opcode byte
71 - if protocol == "udp" {
72 - opcode = 1
73 - } else if protocol == "tcp" {
74 - opcode = 2
75 - } else {
76 - err = fmt.Errorf("unknown protocol %v", protocol)
77 - return
78 - }
79 - msg := make([]byte, 12)
80 - msg[0] = 0 // Version 0
81 - msg[1] = opcode
82 - writeNetworkOrderUint16(msg[4:6], uint16(internalPort))
83 - writeNetworkOrderUint16(msg[6:8], uint16(requestedExternalPort))
84 - writeNetworkOrderUint32(msg[8:12], uint32(lifetime))
85 - response, err := n.rpc(msg, 16)
86 - if err != nil {
87 - return
88 - }
89 - result = &AddPortMappingResult{}
90 - result.SecondsSinceStartOfEpoc = readNetworkOrderUint32(response[4:8])
91 - result.InternalPort = readNetworkOrderUint16(response[8:10])
92 - result.MappedExternalPort = readNetworkOrderUint16(response[10:12])
93 - result.PortMappingLifetimeInSeconds = readNetworkOrderUint32(response[12:16])
94 - return
95 -}
96 -
97 -func (n *Client) rpc(msg []byte, resultSize int) (result []byte, err error) {
98 - var server net.UDPAddr
99 - server.IP = n.gateway
100 - server.Port = nAT_PMP_PORT
101 - conn, err := net.DialUDP("udp", nil, &server)
102 - if err != nil {
103 - return
104 - }
105 - defer conn.Close()
106 -
107 - result = make([]byte, resultSize)
108 -
109 - needNewDeadline := true
110 -
111 - var tries uint
112 - for tries = 0; tries < nAT_TRIES; {
113 - if needNewDeadline {
114 - err = conn.SetDeadline(time.Now().Add((nAT_INITIAL_MS << tries) * time.Millisecond))
115 - if err != nil {
116 - return
117 - }
118 - needNewDeadline = false
119 - }
120 - _, err = conn.Write(msg)
121 - if err != nil {
122 - return
123 - }
124 - var bytesRead int
125 - var remoteAddr *net.UDPAddr
126 - bytesRead, remoteAddr, err = conn.ReadFromUDP(result)
127 - if err != nil {
128 - if err.(net.Error).Timeout() {
129 - tries++
130 - needNewDeadline = true
131 - continue
132 - }
133 - return
134 - }
135 - if !remoteAddr.IP.Equal(n.gateway) {
136 - log.Printf("Ignoring packet because IPs differ:", remoteAddr, n.gateway)
137 - // Ignore this packet.
138 - // Continue without increasing retransmission timeout or deadline.
139 - continue
140 - }
141 - if bytesRead != resultSize {
142 - err = fmt.Errorf("unexpected result size %d, expected %d", bytesRead, resultSize)
143 - return
144 - }
145 - if result[0] != 0 {
146 - err = fmt.Errorf("unknown protocol version %d", result[0])
147 - return
148 - }
149 - expectedOp := msg[1] | 0x80
150 - if result[1] != expectedOp {
151 - err = fmt.Errorf("Unexpected opcode %d. Expected %d", result[1], expectedOp)
152 - return
153 - }
154 - resultCode := readNetworkOrderUint16(result[2:4])
155 - if resultCode != 0 {
156 - err = fmt.Errorf("Non-zero result code %d", resultCode)
157 - return
158 - }
159 - // If we got here the RPC is good.
160 - return
161 - }
162 - err = fmt.Errorf("Timed out trying to contact gateway")
163 - return
164 -}
165 -
166 -func writeNetworkOrderUint16(buf []byte, d uint16) {
167 - buf[0] = byte(d >> 8)
168 - buf[1] = byte(d)
169 -}
170 -
171 -func writeNetworkOrderUint32(buf []byte, d uint32) {
172 - buf[0] = byte(d >> 24)
173 - buf[1] = byte(d >> 16)
174 - buf[2] = byte(d >> 8)
175 - buf[3] = byte(d)
176 -}
177 -
178 -func readNetworkOrderUint16(buf []byte) uint16 {
179 - return (uint16(buf[0]) << 8) | uint16(buf[1])
180 -}
181 -
182 -func readNetworkOrderUint32(buf []byte) uint32 {
183 - return (uint32(buf[0]) << 24) | (uint32(buf[1]) << 16) | (uint32(buf[2]) << 8) | uint32(buf[3])
184 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/.gitignore deleted
-1
@@ -1 +0,0 @@
1 -example/closer
Godeps/_workspace/src/github.com/jbenet/go-peerstream/.travis.yml deleted
-11
@@ -1,11 +0,0 @@
1 -language: go
2 -
3 -go:
4 - - 1.3
5 - - 1.4
6 - - release
7 - - tip
8 -
9 -script:
10 - - go test -v ./...
11 - # - go test -race -cpu=5 ./...
Godeps/_workspace/src/github.com/jbenet/go-peerstream/Godeps/Godeps.json deleted
-37
@@ -1,37 +0,0 @@
1 -{
2 - "ImportPath": "github.com/jbenet/go-peerstream",
3 - "GoVersion": "go1.4.2",
4 - "Packages": [
5 - "./..."
6 - ],
7 - "Deps": [
8 - {
9 - "ImportPath": "github.com/docker/spdystream",
10 - "Rev": "b2c3287865f3ad6aa22821ddb7b4692b896ac207"
11 - },
12 - {
13 - "ImportPath": "github.com/hashicorp/yamux",
14 - "Rev": "b2e55852ddaf823a85c67f798080eb7d08acd71d"
15 - },
16 - {
17 - "ImportPath": "github.com/inconshreveable/muxado",
18 - "Rev": "f693c7e88ba316d1a0ae3e205e22a01aa3ec2848"
19 - },
20 - {
21 - "ImportPath": "github.com/jbenet/go-stream-muxer",
22 - "Rev": "e2e261765847234749629e0190fef193a4548303"
23 - },
24 - {
25 - "ImportPath": "github.com/jbenet/go-temp-err-catcher",
26 - "Rev": "aac704a3f4f27190b4ccc05f303a4931fd1241ff"
27 - },
28 - {
29 - "ImportPath": "github.com/whyrusleeping/go-multiplex",
30 - "Rev": "474b9aebeb391746f304ddf7c764a5da12319857"
31 - },
32 - {
33 - "ImportPath": "github.com/whyrusleeping/go-multistream",
34 - "Rev": "08e8f9c9f5665ed0c63ffde4fa5ef1d5fb3d516d"
35 - }
36 - ]
37 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/Godeps/Readme deleted
-5
@@ -1,5 +0,0 @@
1 -This directory tree is generated automatically by godep.
2 -
3 -Please do not edit.
4 -
5 -See https://github.com/tools/godep for more information.
Godeps/_workspace/src/github.com/jbenet/go-peerstream/LICENSE deleted
-21
@@ -1,21 +0,0 @@
1 -The MIT License (MIT)
2 -
3 -Copyright (c) 2014 Juan Batiz-Benet
4 -
5 -Permission is hereby granted, free of charge, to any person obtaining a copy
6 -of this software and associated documentation files (the "Software"), to deal
7 -in the Software without restriction, including without limitation the rights
8 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 -copies of the Software, and to permit persons to whom the Software is
10 -furnished to do so, subject to the following conditions:
11 -
12 -The above copyright notice and this permission notice shall be included in
13 -all copies or substantial portions of the Software.
14 -
15 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 -THE SOFTWARE.
Godeps/_workspace/src/github.com/jbenet/go-peerstream/Makefile deleted
-15
@@ -1,15 +0,0 @@
1 -
2 -godep:
3 - go get github.com/tools/godep
4 -
5 -vendor: godep
6 - godep save -r ./...
7 -
8 -build:
9 - go build ./...
10 -
11 -test:
12 - go test ./...
13 -
14 -test_race:
15 - go test -race -cpu 5 ./...
Godeps/_workspace/src/github.com/jbenet/go-peerstream/README.md deleted
-148
@@ -1,148 +0,0 @@
1 -# go-peerstream p2p multi-multixplexing
2 -
3 -Package peerstream is a peer-to-peer networking library that multiplexes
4 -connections to many hosts. It tried to simplify the complexity of:
5 -
6 -* accepting incoming connections over **multiple** listeners
7 -* dialing outgoing connections over **multiple** transports
8 -* multiplexing **multiple** connections per-peer
9 -* multiplexing **multiple** different servers or protocols
10 -* handling backpressure correctly
11 -* handling stream multiplexing (we use SPDY, but maybe QUIC some day)
12 -* providing a **simple** interface to the user
13 -
14 -### Godoc: https://godoc.org/github.com/jbenet/go-peerstream
15 -
16 ----
17 -
18 -See this working [example/example.go](example/example):
19 -
20 -```Go
21 -package main
22 -
23 -import (
24 - "fmt"
25 - "io"
26 - "net"
27 - "os"
28 -
29 - ps "github.com/jbenet/go-peerstream"
30 -)
31 -
32 -func main() {
33 - // create a new Swarm
34 - swarm := ps.NewSwarm()
35 - defer swarm.Close()
36 -
37 - // tell swarm what to do with a new incoming streams.
38 - // EchoHandler just echos back anything they write.
39 - swarm.SetStreamHandler(ps.EchoHandler)
40 -
41 - // Okay, let's try listening on some transports
42 - l1, err := net.Listen("tcp", "localhost:8001")
43 - if err != nil {
44 - panic(err)
45 - }
46 -
47 - l2, err := net.Listen("tcp", "localhost:8002")
48 - if err != nil {
49 - panic(err)
50 - }
51 -
52 - // tell swarm to accept incoming connections on these
53 - // listeners. Swarm will start accepting new connections.
54 - if err := swarm.AddListener(l1); err != nil {
55 - panic(err)
56 - }
57 - if err := swarm.AddListener(l2); err != nil {
58 - panic(err)
59 - }
60 -
61 - // ok, let's try some outgoing connections
62 - nc1, err := net.Dial("tcp", "localhost:8001")
63 - if err != nil {
64 - panic(err)
65 - }
66 -
67 - nc2, err := net.Dial("tcp", "localhost:8002")
68 - if err != nil {
69 - panic(err)
70 - }
71 -
72 - // add them to the swarm
73 - c1, err := swarm.AddConn(nc1)
74 - if err != nil {
75 - panic(err)
76 - }
77 - c2, err := swarm.AddConn(nc2)
78 - if err != nil {
79 - panic(err)
80 - }
81 -
82 - // Swarm treats listeners as sources of new connections and does
83 - // not distinguish between outgoing or incoming connections.
84 - // It provides the net.Conn to the StreamHandler so you can
85 - // distinguish between them however you wish.
86 -
87 - // now let's try opening some streams!
88 - // You can specify what connection you want to use
89 - s1, err := swarm.NewStreamWithConn(c1)
90 - if err != nil {
91 - panic(err)
92 - }
93 -
94 - // Or, you can specify a SelectConn function that picks between all
95 - // (it calls NewStreamWithConn underneath the hood)
96 - s2, err := swarm.NewStreamSelectConn(func(conns []*ps.Conn) *ps.Conn {
97 - if len(conns) > 0 {
98 - return conns[0]
99 - }
100 - return nil
101 - })
102 - if err != nil {
103 - panic(err)
104 - }
105 -
106 - // Or, you can bind connections to ConnGroup ids. You can bind a conn to
107 - // multiple groups. And, if conn wasn't in swarm, it calls swarm.AddConn.
108 - // You can use any Go `KeyType` as a group A `KeyType` as in maps...)
109 - swarm.AddConnToGroup(c2, 1)
110 -
111 - // And then use that group to select a connection. Swarm will use any
112 - // connection it finds in that group, using a SelectConn you can rebind:
113 - // swarm.SetGroupSelectConn(1, SelectConn)
114 - // swarm.SetDegaultGroupSelectConn(SelectConn)
115 - s3, err := swarm.NewStreamWithGroup(1)
116 - if err != nil {
117 - panic(err)
118 - }
119 -
120 - // Why groups? It's because with many connections, and many transports,
121 - // and many Servers (or Protocols), we can use the Swarm to associate
122 - // a different StreamHandlers per group, and to let us create NewStreams
123 - // on a given group.
124 -
125 - // Ok, we have streams. now what. Use them! Our Streams are basically
126 - // streams from github.com/docker/spdystream, so they work the same
127 - // way:
128 -
129 - for i, stream := range []ps.Stream{s1, s2, s3} {
130 - stream.Wait()
131 - str := "stream %d ready:"
132 - fmt.Fprintf(stream, str, i)
133 -
134 - buf := make([]byte, len(str))
135 - stream.Read(buf)
136 - fmt.Println(string(buf))
137 - }
138 -
139 - go io.Copy(os.Stdout, s1)
140 - go io.Copy(os.Stdout, s2)
141 - go io.Copy(os.Stdout, s3)
142 - io.Copy(io.MultiWriter(s1, s2, s3), os.Stdin)
143 -}
144 -
145 -func log(s string) {
146 - fmt.Fprintf(os.Stderr, s+"\n")
147 -}
148 -```
Godeps/_workspace/src/github.com/jbenet/go-peerstream/conn.go deleted
-311
@@ -1,311 +0,0 @@
1 -package peerstream
2 -
3 -import (
4 - "errors"
5 - "fmt"
6 - "net"
7 - "sync"
8 -
9 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
10 -)
11 -
12 -// ConnHandler is a function which receives a Conn. It allows
13 -// clients to set a function to receive newly accepted
14 -// connections. It works like StreamHandler, but is usually
15 -// less useful than usual as most services will only use
16 -// Streams. It is safe to pass or store the *Conn elsewhere.
17 -// Note: the ConnHandler is called sequentially, so spawn
18 -// goroutines or pass the Conn. See EchoHandler.
19 -type ConnHandler func(s *Conn)
20 -
21 -// SelectConn selects a connection out of list. It allows
22 -// delegation of decision making to clients. Clients can
23 -// make SelectConn functons that check things connection
24 -// qualities -- like latency andbandwidth -- or pick from
25 -// a logical set of connections.
26 -type SelectConn func([]*Conn) *Conn
27 -
28 -// ErrInvalidConnSelected signals that a connection selected
29 -// with a SelectConn function is invalid. This may be due to
30 -// the Conn not being part of the original set given to the
31 -// function, or the value being nil.
32 -var ErrInvalidConnSelected = errors.New("invalid selected connection")
33 -
34 -// ErrNoConnections signals that no connections are available
35 -var ErrNoConnections = errors.New("no connections")
36 -
37 -// Conn is a Swarm-associated connection.
38 -type Conn struct {
39 - smuxConn smux.Conn
40 - netConn net.Conn // underlying connection
41 -
42 - swarm *Swarm
43 - groups groupSet
44 -
45 - streams map[*Stream]struct{}
46 - streamLock sync.RWMutex
47 -
48 - closed bool
49 - closeLock sync.Mutex
50 -
51 - closing bool
52 - closingLock sync.Mutex
53 -}
54 -
55 -func newConn(nconn net.Conn, tconn smux.Conn, s *Swarm) *Conn {
56 - return &Conn{
57 - netConn: nconn,
58 - smuxConn: tconn,
59 - swarm: s,
60 - groups: groupSet{m: make(map[Group]struct{})},
61 - streams: make(map[*Stream]struct{}),
62 - }
63 -}
64 -
65 -// String returns a string representation of the Conn
66 -func (c *Conn) String() string {
67 - c.streamLock.RLock()
68 - ls := len(c.streams)
69 - c.streamLock.RUnlock()
70 - f := "<peerstream.Conn %d streams %s <--> %s>"
71 - return fmt.Sprintf(f, ls, c.netConn.LocalAddr(), c.netConn.RemoteAddr())
72 -}
73 -
74 -// Swarm returns the Swarm associated with this Conn
75 -func (c *Conn) Swarm() *Swarm {
76 - return c.swarm
77 -}
78 -
79 -// NetConn returns the underlying net.Conn
80 -func (c *Conn) NetConn() net.Conn {
81 - return c.netConn
82 -}
83 -
84 -// Conn returns the underlying transport Connection we use
85 -// Warning: modifying this object is undefined.
86 -func (c *Conn) Conn() smux.Conn {
87 - return c.smuxConn
88 -}
89 -
90 -// Groups returns the Groups this Conn belongs to
91 -func (c *Conn) Groups() []Group {
92 - return c.groups.Groups()
93 -}
94 -
95 -// InGroup returns whether this Conn belongs to a Group
96 -func (c *Conn) InGroup(g Group) bool {
97 - return c.groups.Has(g)
98 -}
99 -
100 -// AddGroup assigns given Group to Conn
101 -func (c *Conn) AddGroup(g Group) {
102 - c.groups.Add(g)
103 -}
104 -
105 -// Stream returns a stream associated with this Conn
106 -func (c *Conn) NewStream() (*Stream, error) {
107 - return c.swarm.NewStreamWithConn(c)
108 -}
109 -
110 -func (c *Conn) Streams() []*Stream {
111 - c.streamLock.RLock()
112 - defer c.streamLock.RUnlock()
113 -
114 - streams := make([]*Stream, 0, len(c.streams))
115 - for s := range c.streams {
116 - streams = append(streams, s)
117 - }
118 - return streams
119 -}
120 -
121 -// GoClose spawns off a goroutine to close the connection iff the connection is
122 -// not already being closed and returns immediately
123 -func (c *Conn) GoClose() {
124 - c.closingLock.Lock()
125 - defer c.closingLock.Unlock()
126 - if c.closing {
127 - return
128 - }
129 - c.closing = true
130 -
131 - go c.Close()
132 -}
133 -
134 -// Close closes this connection
135 -func (c *Conn) Close() error {
136 - c.closeLock.Lock()
137 - defer c.closeLock.Unlock()
138 - if c.closed == true {
139 - return nil
140 - }
141 -
142 - c.closingLock.Lock()
143 - c.closing = true
144 - c.closingLock.Unlock()
145 -
146 - c.closed = true
147 -
148 - // close streams
149 - streams := c.Streams()
150 - for _, s := range streams {
151 - s.Close()
152 - }
153 -
154 - // close underlying connection
155 - c.swarm.removeConn(c)
156 - err := c.smuxConn.Close()
157 - c.swarm.notifyAll(func(n Notifiee) {
158 - n.Disconnected(c)
159 - })
160 - return err
161 -}
162 -
163 -// ConnsWithGroup narrows down a set of connections to those in a given group.
164 -func ConnsWithGroup(g Group, conns []*Conn) []*Conn {
165 - var out []*Conn
166 - for _, c := range conns {
167 - if c.InGroup(g) {
168 - out = append(out, c)
169 - }
170 - }
171 - return out
172 -}
173 -
174 -func ConnInConns(c1 *Conn, conns []*Conn) bool {
175 - for _, c2 := range conns {
176 - if c2 == c1 {
177 - return true
178 - }
179 - }
180 - return false
181 -}
182 -
183 -// ------------------------------------------------------------------
184 -// All the connection setup logic here, in one place.
185 -// these are mostly *Swarm methods, but i wanted a less-crowded place
186 -// for them.
187 -// ------------------------------------------------------------------
188 -
189 -// addConn is the internal version of AddConn. we need the server bool
190 -// as spdystream requires it.
191 -func (s *Swarm) addConn(netConn net.Conn, isServer bool) (*Conn, error) {
192 - c, err := s.setupConn(netConn, isServer)
193 - if err != nil {
194 - return nil, err
195 - }
196 -
197 - s.ConnHandler()(c)
198 -
199 - // go listen for incoming streams on this connection
200 - go c.smuxConn.Serve(func(ss smux.Stream) {
201 - // log.Printf("accepted stream %d from %s\n", ssS.Identifier(), netConn.RemoteAddr())
202 - stream := s.setupStream(ss, c)
203 - s.StreamHandler()(stream) // call our handler
204 - })
205 -
206 - s.notifyAll(func(n Notifiee) {
207 - n.Connected(c)
208 - })
209 - return c, nil
210 -}
211 -
212 -// setupConn adds the relevant connection to the map, first checking if it
213 -// was already there.
214 -func (s *Swarm) setupConn(netConn net.Conn, isServer bool) (*Conn, error) {
215 - if netConn == nil {
216 - return nil, errors.New("nil conn")
217 - }
218 -
219 - // first, check if we already have it, to avoid constructing it
220 - // if it is already there
221 - s.connLock.Lock()
222 - for c := range s.conns {
223 - if c.netConn == netConn {
224 - s.connLock.Unlock()
225 - return c, nil
226 - }
227 - }
228 - s.connLock.Unlock()
229 - // construct the connection without hanging onto the lock
230 - // (as there could be deadlock if so.)
231 -
232 - // create a new spdystream connection
233 - ssConn, err := s.transport.NewConn(netConn, isServer)
234 - if err != nil {
235 - return nil, err
236 - }
237 -
238 - // take the lock to add it to the map.
239 - s.connLock.Lock()
240 - defer s.connLock.Unlock()
241 -
242 - // check for it again as it may have been added already. (TOCTTOU)
243 - for c := range s.conns {
244 - if c.netConn == netConn {
245 - return c, nil
246 - }
247 - }
248 -
249 - // add the connection
250 - c := newConn(netConn, ssConn, s)
251 - s.conns[c] = struct{}{}
252 - return c, nil
253 -}
254 -
255 -// createStream is the internal function that creates a new stream. assumes
256 -// all validation has happened.
257 -func (s *Swarm) createStream(c *Conn) (*Stream, error) {
258 -
259 - // Create a new smux.Stream
260 - smuxStream, err := c.smuxConn.OpenStream()
261 - if err != nil {
262 - return nil, err
263 - }
264 -
265 - return s.setupStream(smuxStream, c), nil
266 -}
267 -
268 -// newStream is the internal function that creates a new stream. assumes
269 -// all validation has happened.
270 -func (s *Swarm) setupStream(smuxStream smux.Stream, c *Conn) *Stream {
271 -
272 - // create a new stream
273 - stream := newStream(smuxStream, c)
274 -
275 - // add it to our streams maps
276 - s.streamLock.Lock()
277 - c.streamLock.Lock()
278 - s.streams[stream] = struct{}{}
279 - c.streams[stream] = struct{}{}
280 - s.streamLock.Unlock()
281 - c.streamLock.Unlock()
282 -
283 - s.notifyAll(func(n Notifiee) {
284 - n.OpenedStream(stream)
285 - })
286 - return stream
287 -}
288 -
289 -func (s *Swarm) removeStream(stream *Stream) error {
290 -
291 - // remove from our maps
292 - s.streamLock.Lock()
293 - stream.conn.streamLock.Lock()
294 - delete(s.streams, stream)
295 - delete(stream.conn.streams, stream)
296 - s.streamLock.Unlock()
297 - stream.conn.streamLock.Unlock()
298 -
299 - err := stream.smuxStream.Close()
300 - s.notifyAll(func(n Notifiee) {
301 - n.ClosedStream(stream)
302 - })
303 - return err
304 -}
305 -
306 -func (s *Swarm) removeConn(conn *Conn) {
307 - // remove from our maps
308 - s.connLock.Lock()
309 - delete(s.conns, conn)
310 - s.connLock.Unlock()
311 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/doc.go deleted
-12
@@ -1,12 +0,0 @@
1 -// Package peerstream is a peer-to-peer networking library that multiplexes
2 -// connections to many hosts. It tried to simplify the complexity of:
3 -//
4 -// * accepting incoming connections over **multiple** listeners
5 -// * dialing outgoing connections over **multiple** transports
6 -// * multiplexing **multiple** connections per-peer
7 -// * multiplexing **multiple** different servers or protocols
8 -// * handling backpressure correctly
9 -// * handling stream multiplexing (we use SPDY, but maybe QUIC some day)
10 -// * providing a **simple** interface to the user
11 -//
12 -package peerstream
Godeps/_workspace/src/github.com/jbenet/go-peerstream/example/.gitignore deleted
-1
@@ -1 +0,0 @@
1 -example
Godeps/_workspace/src/github.com/jbenet/go-peerstream/example/blockhandler/blockhandler.go deleted
-77
@@ -1,77 +0,0 @@
1 -package main
2 -
3 -import (
4 - "bufio"
5 - "fmt"
6 - "net"
7 - "os"
8 - "time"
9 -
10 - ps "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
11 - spdy "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/spdystream"
12 -)
13 -
14 -func die(err error) {
15 - fmt.Fprintf(os.Stderr, "error: %s\n")
16 - os.Exit(1)
17 -}
18 -
19 -func main() {
20 - // create a new Swarm
21 - swarm := ps.NewSwarm(spdy.Transport)
22 - defer swarm.Close()
23 -
24 - // tell swarm what to do with a new incoming streams.
25 - // EchoHandler just echos back anything they write.
26 - swarm.SetStreamHandler(ps.EchoHandler)
27 -
28 - l, err := net.Listen("tcp", "localhost:8001")
29 - if err != nil {
30 - die(err)
31 - }
32 -
33 - if _, err := swarm.AddListener(l); err != nil {
34 - die(err)
35 - }
36 -
37 - nc, err := net.Dial("tcp", "localhost:8001")
38 - if err != nil {
39 - die(err)
40 - }
41 -
42 - c, err := swarm.AddConn(nc)
43 - if err != nil {
44 - die(err)
45 - }
46 -
47 - nRcvStream := 0
48 - bio := bufio.NewReader(os.Stdin)
49 - swarm.SetStreamHandler(func(s *ps.Stream) {
50 - log("handling new stream %d", nRcvStream)
51 - nRcvStream++
52 -
53 - line, err := bio.ReadString('\n')
54 - if err != nil {
55 - die(err)
56 - }
57 - _ = line
58 - // line = "read: " + line
59 - // s.Write([]byte(line))
60 - s.Close()
61 - })
62 -
63 - nSndStream := 0
64 - for {
65 - <-time.After(200 * time.Millisecond)
66 - _, err := swarm.NewStreamWithConn(c)
67 - if err != nil {
68 - die(err)
69 - }
70 - log("sender got new stream %d", nSndStream)
71 - nSndStream++
72 - }
73 -}
74 -
75 -func log(s string, ifs ...interface{}) {
76 - fmt.Fprintf(os.Stderr, s+"\n", ifs...)
77 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/example/example.go deleted
-140
@@ -1,140 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 - "io"
6 - "net"
7 - "os"
8 -
9 - ps "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
10 - spdy "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/spdystream"
11 -)
12 -
13 -func main() {
14 -
15 - log("creating a new swarm with spdystream transport") // create a new Swarm
16 - swarm := ps.NewSwarm(spdy.Transport)
17 - defer swarm.Close()
18 -
19 - // tell swarm what to do with a new incoming streams.
20 - // EchoHandler just echos back anything they write.
21 - log("setup EchoHandler")
22 - swarm.SetStreamHandler(ps.EchoHandler)
23 -
24 - // Okay, let's try listening on some transports
25 - log("listening at localhost:8001")
26 - l1, err := net.Listen("tcp", "localhost:8001")
27 - if err != nil {
28 - panic(err)
29 - }
30 -
31 - log("listening at localhost:8002")
32 - l2, err := net.Listen("tcp", "localhost:8002")
33 - if err != nil {
34 - panic(err)
35 - }
36 -
37 - // tell swarm to accept incoming connections on these
38 - // listeners. Swarm will start accepting new connections.
39 - if _, err := swarm.AddListener(l1); err != nil {
40 - panic(err)
41 - }
42 - if _, err := swarm.AddListener(l2); err != nil {
43 - panic(err)
44 - }
45 -
46 - // ok, let's try some outgoing connections
47 - log("dialing localhost:8001")
48 - nc1, err := net.Dial("tcp", "localhost:8001")
49 - if err != nil {
50 - panic(err)
51 - }
52 -
53 - log("dialing localhost:8002")
54 - nc2, err := net.Dial("tcp", "localhost:8002")
55 - if err != nil {
56 - panic(err)
57 - }
58 -
59 - // add them to the swarm
60 - c1, err := swarm.AddConn(nc1)
61 - if err != nil {
62 - panic(err)
63 - }
64 - c2, err := swarm.AddConn(nc2)
65 - if err != nil {
66 - panic(err)
67 - }
68 -
69 - // Swarm treats listeners as sources of new connections and does
70 - // not distinguish between outgoing or incoming connections.
71 - // It provides the net.Conn to the StreamHandler so you can
72 - // distinguish between them however you wish.
73 -
74 - // now let's try opening some streams!
75 - // You can specify what connection you want to use
76 - log("opening stream with NewStreamWithConn(c1)")
77 - s1, err := swarm.NewStreamWithConn(c1)
78 - if err != nil {
79 - panic(err)
80 - }
81 -
82 - // Or, you can specify a SelectConn function that picks between all
83 - // (it calls NewStreamWithConn underneath the hood)
84 - log("opening stream with NewStreamSelectConn(.)")
85 - s2, err := swarm.NewStreamSelectConn(func(conns []*ps.Conn) *ps.Conn {
86 - if len(conns) > 0 {
87 - return conns[0]
88 - }
89 - return nil
90 - })
91 - if err != nil {
92 - panic(err)
93 - }
94 -
95 - // Or, you can bind connections to ConnGroup ids. You can bind a conn to
96 - // multiple groups. And, if conn wasn't in swarm, it calls swarm.AddConn.
97 - // You can use any Go `KeyType` as a group A `KeyType` as in maps...)
98 - swarm.AddConnToGroup(c2, 1)
99 -
100 - // And then use that group to select a connection. Swarm will use any
101 - // connection it finds in that group, using a SelectConn you can rebind:
102 - // swarm.SetGroupSelectConn(1, SelectConn)
103 - // swarm.SetDegaultGroupSelectConn(SelectConn)
104 - log("opening stream with NewStreamWithGroup(1)")
105 - s3, err := swarm.NewStreamWithGroup(1)
106 - if err != nil {
107 - panic(err)
108 - }
109 -
110 - // Why groups? It's because with many connections, and many transports,
111 - // and many Servers (or Protocols), we can use the Swarm to associate
112 - // a different StreamHandlers per group, and to let us create NewStreams
113 - // on a given group.
114 -
115 - // Ok, we have streams. now what. Use them! Our Streams are basically
116 - // streams from github.com/docker/spdystream, so they work the same
117 - // way:
118 -
119 - log("preparing the streams")
120 - for i, stream := range []*ps.Stream{s1, s2, s3} {
121 - str := "stream %d ready:"
122 - fmt.Fprintf(stream, str, i)
123 -
124 - buf := make([]byte, len(str))
125 - log(fmt.Sprintf("reading from stream %d", i))
126 - stream.Read(buf)
127 - fmt.Println(string(buf))
128 - }
129 -
130 - log("let's test the streams")
131 - log("enter some text below:\n")
132 - go io.Copy(os.Stdout, s1)
133 - go io.Copy(os.Stdout, s2)
134 - go io.Copy(os.Stdout, s3)
135 - io.Copy(io.MultiWriter(s1, s2, s3), os.Stdin)
136 -}
137 -
138 -func log(s string) {
139 - fmt.Fprintf(os.Stderr, s+"\n")
140 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/group.go deleted
-92
@@ -1,92 +0,0 @@
1 -package peerstream
2 -
3 -import (
4 - "errors"
5 - "sync"
6 - "unsafe"
7 -)
8 -
9 -// ErrGroupNotFound signals no such group exists
10 -var ErrGroupNotFound = errors.New("group not found")
11 -
12 -// Group is an object used to associate a group of
13 -// Streams, Connections, and Listeners. It can be anything,
14 -// it is meant to work like a KeyType in maps
15 -type Group interface{}
16 -
17 -// Groupable is an interface for a set of objects that can
18 -// be assigned groups: Streams, Connections, and Listeners.
19 -// Objects inherit groups (e.g. a Stream inherits the groups
20 -// of its parent Connection, and in turn that of its Listener).
21 -type Groupable interface {
22 - // Groups returns the groups this object belongs to
23 - Groups() []Group
24 -
25 - // InGroup returns whether this object belongs to a Group
26 - InGroup(g Group) bool
27 -
28 - // AddGroup adds this object to a group
29 - AddGroup(g Group)
30 -}
31 -
32 -// groupSet is a struct designed to be embedded and
33 -// give things group memebership
34 -type groupSet struct {
35 - m map[Group]struct{}
36 - sync.RWMutex
37 -}
38 -
39 -func (gs *groupSet) Add(g Group) {
40 - gs.Lock()
41 - defer gs.Unlock()
42 - gs.m[g] = struct{}{}
43 -}
44 -
45 -func (gs *groupSet) Remove(g Group) {
46 - gs.Lock()
47 - defer gs.Unlock()
48 - delete(gs.m, g)
49 -}
50 -
51 -func (gs *groupSet) Has(g Group) bool {
52 - gs.RLock()
53 - defer gs.RUnlock()
54 - _, ok := gs.m[g]
55 - return ok
56 -}
57 -
58 -func (gs *groupSet) Groups() []Group {
59 - gs.RLock()
60 - defer gs.RUnlock()
61 -
62 - out := make([]Group, 0, len(gs.m))
63 - for k := range gs.m {
64 - out = append(out, k)
65 - }
66 - return out
67 -}
68 -
69 -// AddSet adds all elements in another set.
70 -func (gs *groupSet) AddSet(gs2 *groupSet) {
71 - // acquire locks in order
72 - p1 := uintptr(unsafe.Pointer(gs))
73 - p2 := uintptr(unsafe.Pointer(gs2))
74 - switch {
75 - case p1 < p2:
76 - gs.Lock()
77 - gs2.RLock()
78 - defer gs.Unlock()
79 - defer gs2.RUnlock()
80 - case p1 > p2:
81 - gs2.Lock()
82 - gs.Lock()
83 - defer gs2.Unlock()
84 - defer gs.Unlock()
85 - default:
86 - return // they're the same!
87 - }
88 -
89 - for g := range gs2.m {
90 - gs.m[g] = struct{}{}
91 - }
92 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/handlers.go deleted
-29
@@ -1,29 +0,0 @@
1 -package peerstream
2 -
3 -import (
4 - "io"
5 - "math/rand"
6 -)
7 -
8 -var SelectRandomConn = func(conns []*Conn) *Conn {
9 - if len(conns) == 0 {
10 - return nil
11 - }
12 -
13 - return conns[rand.Intn(len(conns))]
14 -}
15 -
16 -func EchoHandler(s *Stream) {
17 - go func() {
18 - io.Copy(s, s)
19 - s.Close()
20 - }()
21 -}
22 -
23 -func CloseHandler(s *Stream) {
24 - s.Close()
25 -}
26 -
27 -func NoOpStreamHandler(s *Stream) {}
28 -
29 -func NoOpConnHandler(c *Conn) {}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/listener.go deleted
-163
@@ -1,163 +0,0 @@
1 -package peerstream
2 -
3 -import (
4 - "errors"
5 - "fmt"
6 - "net"
7 - "sync"
8 -
9 - tec "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher"
10 -)
11 -
12 -// AcceptConcurrency is how many connections can simultaneously be
13 -// in process of being accepted. Handshakes can sometimes occur as
14 -// part of this process, so it may take some time. It is imporant to
15 -// rate limit lest a malicious influx of connections would cause our
16 -// node to consume all its resources accepting new connections.
17 -var AcceptConcurrency = 200
18 -
19 -type Listener struct {
20 - netList net.Listener
21 - groups groupSet
22 - swarm *Swarm
23 -
24 - acceptErr chan error
25 -}
26 -
27 -func newListener(nl net.Listener, s *Swarm) *Listener {
28 - return &Listener{
29 - netList: nl,
30 - swarm: s,
31 - acceptErr: make(chan error, 10),
32 - }
33 -}
34 -
35 -// String returns a string representation of the Listener
36 -func (l *Listener) String() string {
37 - f := "<peerstream.Listener %s>"
38 - return fmt.Sprintf(f, l.netList.Addr())
39 -}
40 -
41 -// NetListener is the underlying net.Listener
42 -func (l *Listener) NetListener() net.Listener {
43 - return l.netList
44 -}
45 -
46 -// Groups returns the groups this Listener belongs to
47 -func (l *Listener) Groups() []Group {
48 - return l.groups.Groups()
49 -}
50 -
51 -// InGroup returns whether this Listener belongs to a Group
52 -func (l *Listener) InGroup(g Group) bool {
53 - return l.groups.Has(g)
54 -}
55 -
56 -// AddGroup assigns given Group to Listener
57 -func (l *Listener) AddGroup(g Group) {
58 - l.groups.Add(g)
59 -}
60 -
61 -// ListenersWithGroup narrows down a set of listeners to those in given group.
62 -func ListenersWithGroup(g Group, ls []*Listener) []*Listener {
63 - var out []*Listener
64 - for _, l := range ls {
65 - if l.InGroup(g) {
66 - out = append(out, l)
67 - }
68 - }
69 - return out
70 -}
71 -
72 -// accept continously accepts incoming connections and
73 -// adds them to the listener's Swarm. is is meant to be
74 -// run in a goroutine.
75 -// TODO: add rate limiting
76 -func (l *Listener) accept() {
77 - var wg sync.WaitGroup
78 - defer func() {
79 - wg.Wait() // must happen before teardown
80 - l.teardown()
81 - }()
82 -
83 - // catching the error here is odd. doing what net/http does:
84 - // http://golang.org/src/net/http/server.go?s=51504:51550#L1728
85 - // Using the lib: https://godoc.org/github.com/jbenet/go-temp-err-catcher
86 - var catcher tec.TempErrCatcher
87 -
88 - // rate limit concurrency
89 - limit := make(chan struct{}, AcceptConcurrency)
90 -
91 - // loop forever accepting connections
92 - for {
93 - conn, err := l.netList.Accept()
94 - if err != nil {
95 - if catcher.IsTemporary(err) {
96 - continue
97 - }
98 - l.acceptErr <- fmt.Errorf("peerstream listener failed: %s", err)
99 - return // ok, problems. bail.
100 - }
101 -
102 - // add conn to swarm and listen for incoming streams
103 - // do this in a goroutine to avoid blocking the Accept loop.
104 - // note that this does not rate limit accepts.
105 - limit <- struct{}{} // sema down
106 - wg.Add(1)
107 - go func(conn net.Conn) {
108 - defer func() { <-limit }() // sema up
109 - defer wg.Done()
110 -
111 - conn2, err := l.swarm.addConn(conn, true)
112 - if err != nil {
113 - l.acceptErr <- err
114 - return
115 - }
116 - conn2.groups.AddSet(&l.groups) // add out groups
117 - }(conn)
118 - }
119 -}
120 -
121 -// AcceptError returns the error that we **might** on listener close
122 -func (l *Listener) AcceptErrors() <-chan error {
123 - return l.acceptErr
124 -}
125 -
126 -func (l *Listener) teardown() {
127 - // in case we exit from network errors (accept fails) but
128 - // (a) client doesn't call Close, and (b) listener remains open)
129 - l.netList.Close()
130 -
131 - close(l.acceptErr)
132 -
133 - // remove self from swarm
134 - l.swarm.listenerLock.Lock()
135 - delete(l.swarm.listeners, l)
136 - l.swarm.listenerLock.Unlock()
137 -}
138 -
139 -func (l *Listener) Close() error {
140 - return l.netList.Close()
141 -}
142 -
143 -// addListener is the internal version of AddListener.
144 -func (s *Swarm) addListener(nl net.Listener) (*Listener, error) {
145 - if nl == nil {
146 - return nil, errors.New("nil listener")
147 - }
148 -
149 - s.listenerLock.Lock()
150 - defer s.listenerLock.Unlock()
151 -
152 - // first, check if we already have it...
153 - for l := range s.listeners {
154 - if l.netList == nl {
155 - return l, nil
156 - }
157 - }
158 -
159 - l := newListener(nl, s)
160 - s.listeners[l] = struct{}{}
161 - go l.accept()
162 - return l, nil
163 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/muxtest/hack.go deleted
-15
@@ -1,15 +0,0 @@
1 -package muxtest
2 -
3 -import (
4 - multiplex "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multiplex"
5 - multistream "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multistream"
6 - muxado "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/muxado"
7 - spdy "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/spdystream"
8 - yamux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/yamux"
9 -)
10 -
11 -var _ = multiplex.DefaultTransport
12 -var _ = multistream.NewTransport
13 -var _ = muxado.Transport
14 -var _ = spdy.Transport
15 -var _ = yamux.DefaultTransport
Godeps/_workspace/src/github.com/jbenet/go-peerstream/muxtest/mux_test.go deleted
-31
@@ -1,31 +0,0 @@
1 -package muxtest
2 -
3 -import (
4 - "testing"
5 -
6 - multiplex "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multiplex"
7 - multistream "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multistream"
8 - muxado "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/muxado"
9 - spdy "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/spdystream"
10 - yamux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/yamux"
11 -)
12 -
13 -func TestYamuxTransport(t *testing.T) {
14 - SubtestAll(t, yamux.DefaultTransport)
15 -}
16 -
17 -func TestSpdyStreamTransport(t *testing.T) {
18 - SubtestAll(t, spdy.Transport)
19 -}
20 -
21 -func TestMultiplexTransport(t *testing.T) {
22 - SubtestAll(t, multiplex.DefaultTransport)
23 -}
24 -
25 -func TestMuxadoTransport(t *testing.T) {
26 - SubtestAll(t, muxado.Transport)
27 -}
28 -
29 -func TestMultistreamTransport(t *testing.T) {
30 - SubtestAll(t, multistream.NewTransport())
31 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/muxtest/muxt.go deleted
-422
@@ -1,422 +0,0 @@
1 -package muxtest
2 -
3 -import (
4 - "bytes"
5 - crand "crypto/rand"
6 - "fmt"
7 - "io"
8 - mrand "math/rand"
9 - "net"
10 - "os"
11 - "reflect"
12 - "runtime"
13 - "sync"
14 - "testing"
15 -
16 - ps "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-peerstream"
17 -
18 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
19 -)
20 -
21 -var randomness []byte
22 -var nextPort = 20000
23 -var verbose = false
24 -
25 -func init() {
26 - // read 1MB of randomness
27 - randomness = make([]byte, 1<<20)
28 - if _, err := crand.Read(randomness); err != nil {
29 - panic(err)
30 - }
31 -}
32 -
33 -func randBuf(size int) []byte {
34 - n := len(randomness) - size
35 - if size < 1 {
36 - panic(fmt.Errorf("requested too large buffer (%d). max is %d", size, len(randomness)))
37 - }
38 -
39 - start := mrand.Intn(n)
40 - return randomness[start : start+size]
41 -}
42 -
43 -func checkErr(t *testing.T, err error) {
44 - if err != nil {
45 - t.Fatal(err)
46 - }
47 -}
48 -
49 -func log(s string, v ...interface{}) {
50 - if verbose {
51 - fmt.Fprintf(os.Stderr, "> "+s+"\n", v...)
52 - }
53 -}
54 -
55 -type echoSetup struct {
56 - swarm *ps.Swarm
57 - conns []*ps.Conn
58 -}
59 -
60 -func singleConn(t *testing.T, tr smux.Transport) echoSetup {
61 - swarm := ps.NewSwarm(tr)
62 - swarm.SetStreamHandler(func(s *ps.Stream) {
63 - defer s.Close()
64 - log("accepted stream")
65 - io.Copy(s, s) // echo everything
66 - log("closing stream")
67 - })
68 -
69 - log("listening at %s", "localhost:0")
70 - l, err := net.Listen("tcp", "localhost:0")
71 - checkErr(t, err)
72 -
73 - _, err = swarm.AddListener(l)
74 - checkErr(t, err)
75 -
76 - log("dialing to %s", l.Addr())
77 - nc1, err := net.Dial("tcp", l.Addr().String())
78 - checkErr(t, err)
79 -
80 - c1, err := swarm.AddConn(nc1)
81 - checkErr(t, err)
82 -
83 - return echoSetup{
84 - swarm: swarm,
85 - conns: []*ps.Conn{c1},
86 - }
87 -}
88 -
89 -func makeSwarm(t *testing.T, tr smux.Transport, nListeners int) *ps.Swarm {
90 - swarm := ps.NewSwarm(tr)
91 - swarm.SetStreamHandler(func(s *ps.Stream) {
92 - defer s.Close()
93 - log("accepted stream")
94 - io.Copy(s, s) // echo everything
95 - log("closing stream")
96 - })
97 -
98 - for i := 0; i < nListeners; i++ {
99 - log("%p listening at %s", swarm, "localhost:0")
100 - l, err := net.Listen("tcp", "localhost:0")
101 - checkErr(t, err)
102 - _, err = swarm.AddListener(l)
103 - checkErr(t, err)
104 - }
105 -
106 - return swarm
107 -}
108 -
109 -func makeSwarms(t *testing.T, tr smux.Transport, nSwarms, nListeners int) []*ps.Swarm {
110 - swarms := make([]*ps.Swarm, nSwarms)
111 - for i := 0; i < nSwarms; i++ {
112 - swarms[i] = makeSwarm(t, tr, nListeners)
113 - }
114 - return swarms
115 -}
116 -
117 -func SubtestConstructSwarm(t *testing.T, tr smux.Transport) {
118 - ps.NewSwarm(tr)
119 -}
120 -
121 -func SubtestSimpleWrite(t *testing.T, tr smux.Transport) {
122 - swarm := ps.NewSwarm(tr)
123 - defer swarm.Close()
124 -
125 - piper, pipew := io.Pipe()
126 - swarm.SetStreamHandler(func(s *ps.Stream) {
127 - defer s.Close()
128 - log("accepted stream")
129 - w := io.MultiWriter(s, pipew)
130 - io.Copy(w, s) // echo everything and write it to pipew
131 - log("closing stream")
132 - })
133 -
134 - log("listening at %s", "localhost:0")
135 - l, err := net.Listen("tcp", "localhost:0")
136 - checkErr(t, err)
137 -
138 - _, err = swarm.AddListener(l)
139 - checkErr(t, err)
140 -
141 - log("dialing to %s", l.Addr().String())
142 - nc1, err := net.Dial("tcp", l.Addr().String())
143 - checkErr(t, err)
144 -
145 - c1, err := swarm.AddConn(nc1)
146 - checkErr(t, err)
147 - defer c1.Close()
148 -
149 - log("creating stream")
150 - s1, err := c1.NewStream()
151 - checkErr(t, err)
152 - defer s1.Close()
153 -
154 - buf1 := randBuf(4096)
155 - log("writing %d bytes to stream", len(buf1))
156 - _, err = s1.Write(buf1)
157 - checkErr(t, err)
158 -
159 - buf2 := make([]byte, len(buf1))
160 - log("reading %d bytes from stream (echoed)", len(buf2))
161 - _, err = s1.Read(buf2)
162 - checkErr(t, err)
163 - if string(buf2) != string(buf1) {
164 - t.Error("buf1 and buf2 not equal: %s != %s", string(buf1), string(buf2))
165 - }
166 -
167 - buf3 := make([]byte, len(buf1))
168 - log("reading %d bytes from pipe (tee)", len(buf3))
169 - _, err = piper.Read(buf3)
170 - checkErr(t, err)
171 - if string(buf3) != string(buf1) {
172 - t.Error("buf1 and buf3 not equal: %s != %s", string(buf1), string(buf3))
173 - }
174 -}
175 -
176 -func SubtestSimpleWrite100msgs(t *testing.T, tr smux.Transport) {
177 -
178 - msgs := 100
179 - msgsize := 1 << 19
180 - es := singleConn(t, tr)
181 - defer es.swarm.Close()
182 -
183 - log("creating stream")
184 - stream, err := es.conns[0].NewStream()
185 - checkErr(t, err)
186 -
187 - bufs := make(chan []byte, msgs)
188 - var wg sync.WaitGroup
189 -
190 - wg.Add(1)
191 - go func() {
192 - defer wg.Done()
193 -
194 - for i := 0; i < msgs; i++ {
195 - buf := randBuf(msgsize)
196 - bufs <- buf
197 - log("writing %d bytes (message %d/%d #%x)", len(buf), i, msgs, buf[:3])
198 - if _, err := stream.Write(buf); err != nil {
199 - t.Error(fmt.Errorf("stream.Write(buf): %s", err))
200 - continue
201 - }
202 - }
203 - close(bufs)
204 - }()
205 -
206 - wg.Add(1)
207 - go func() {
208 - defer wg.Done()
209 -
210 - buf2 := make([]byte, msgsize)
211 - i := 0
212 - for buf1 := range bufs {
213 - log("reading %d bytes (message %d/%d #%x)", len(buf1), i, msgs, buf1[:3])
214 - i++
215 -
216 - if _, err := io.ReadFull(stream, buf2); err != nil {
217 - t.Error(fmt.Errorf("readFull(stream, buf2): %s", err))
218 - continue
219 - }
220 - if !bytes.Equal(buf1, buf2) {
221 - t.Error(fmt.Errorf("buffers not equal (%x != %x)", buf1[:3], buf2[:3]))
222 - }
223 - }
224 - }()
225 -
226 - wg.Wait()
227 -}
228 -
229 -func SubtestStressNSwarmNConnNStreamNMsg(t *testing.T, tr smux.Transport, nSwarm, nConn, nStream, nMsg int) {
230 -
231 - msgsize := 1 << 11
232 -
233 - rateLimitN := 5000
234 - rateLimitChan := make(chan struct{}, rateLimitN) // max of 5k funcs.
235 - for i := 0; i < rateLimitN; i++ {
236 - rateLimitChan <- struct{}{}
237 - }
238 -
239 - rateLimit := func(f func()) {
240 - <-rateLimitChan
241 - f()
242 - rateLimitChan <- struct{}{}
243 - }
244 -
245 - writeStream := func(s *ps.Stream, bufs chan<- []byte) {
246 - log("writeStream %p, %d nMsg", s, nMsg)
247 -
248 - for i := 0; i < nMsg; i++ {
249 - buf := randBuf(msgsize)
250 - bufs <- buf
251 - log("%p writing %d bytes (message %d/%d #%x)", s, len(buf), i, nMsg, buf[:3])
252 - if _, err := s.Write(buf); err != nil {
253 - t.Error(fmt.Errorf("s.Write(buf): %s", err))
254 - continue
255 - }
256 - }
257 - }
258 -
259 - readStream := func(s *ps.Stream, bufs <-chan []byte) {
260 - log("readStream %p, %d nMsg", s, nMsg)
261 -
262 - buf2 := make([]byte, msgsize)
263 - i := 0
264 - for buf1 := range bufs {
265 - i++
266 - log("%p reading %d bytes (message %d/%d #%x)", s, len(buf1), i-1, nMsg, buf1[:3])
267 -
268 - if _, err := io.ReadFull(s, buf2); err != nil {
269 - log("%p failed to read %d bytes (message %d/%d #%x)", s, len(buf1), i-1, nMsg, buf1[:3])
270 - t.Error(fmt.Errorf("io.ReadFull(s, buf2): %s", err))
271 - continue
272 - }
273 - if !bytes.Equal(buf1, buf2) {
274 - t.Error(fmt.Errorf("buffers not equal (%x != %x)", buf1[:3], buf2[:3]))
275 - }
276 - }
277 - }
278 -
279 - openStreamAndRW := func(c *ps.Conn) {
280 - log("openStreamAndRW %p, %d nMsg", c, nMsg)
281 -
282 - s, err := c.NewStream()
283 - if err != nil {
284 - t.Error(fmt.Errorf("Failed to create NewStream: %s", err))
285 - return
286 - }
287 -
288 - bufs := make(chan []byte, nMsg)
289 - go func() {
290 - writeStream(s, bufs)
291 - close(bufs)
292 - }()
293 -
294 - readStream(s, bufs)
295 - s.Close()
296 - }
297 -
298 - openConnAndRW := func(a, b *ps.Swarm) {
299 - log("openConnAndRW %p -> %p, %d nStream", a, b, nConn)
300 -
301 - ls := b.Listeners()
302 - l := ls[mrand.Intn(len(ls))]
303 - nl := l.NetListener()
304 - nla := nl.Addr()
305 -
306 - nc, err := net.Dial(nla.Network(), nla.String())
307 - if err != nil {
308 - t.Fatal(fmt.Errorf("net.Dial(%s, %s): %s", nla.Network(), nla.String(), err))
309 - return
310 - }
311 -
312 - c, err := a.AddConn(nc)
313 - if err != nil {
314 - t.Fatal(fmt.Errorf("a.AddConn(%s <--> %s): %s", nc.LocalAddr(), nc.RemoteAddr(), err))
315 - return
316 - }
317 -
318 - var wg sync.WaitGroup
319 - for i := 0; i < nStream; i++ {
320 - wg.Add(1)
321 - go rateLimit(func() {
322 - defer wg.Done()
323 - openStreamAndRW(c)
324 - })
325 - }
326 - wg.Wait()
327 - c.Close()
328 - }
329 -
330 - openConnsAndRW := func(a, b *ps.Swarm) {
331 - log("openConnsAndRW %p -> %p, %d conns", a, b, nConn)
332 -
333 - var wg sync.WaitGroup
334 - for i := 0; i < nConn; i++ {
335 - wg.Add(1)
336 - go rateLimit(func() {
337 - defer wg.Done()
338 - openConnAndRW(a, b)
339 - })
340 - }
341 - wg.Wait()
342 - }
343 -
344 - connectSwarmsAndRW := func(swarms []*ps.Swarm) {
345 - log("connectSwarmsAndRW %d swarms", len(swarms))
346 -
347 - var wg sync.WaitGroup
348 - for _, a := range swarms {
349 - for _, b := range swarms {
350 - wg.Add(1)
351 - a := a // race
352 - b := b // race
353 - go rateLimit(func() {
354 - defer wg.Done()
355 - openConnsAndRW(a, b)
356 - })
357 - }
358 - }
359 - wg.Wait()
360 - }
361 -
362 - swarms := makeSwarms(t, tr, nSwarm, 3) // 3 listeners per swarm.
363 - connectSwarmsAndRW(swarms)
364 - for _, s := range swarms {
365 - s.Close()
366 - }
367 -
368 -}
369 -
370 -func SubtestStress1Swarm1Conn1Stream1Msg(t *testing.T, tr smux.Transport) {
371 - SubtestStressNSwarmNConnNStreamNMsg(t, tr, 1, 1, 1, 1)
372 -}
373 -
374 -func SubtestStress1Swarm1Conn1Stream100Msg(t *testing.T, tr smux.Transport) {
375 - SubtestStressNSwarmNConnNStreamNMsg(t, tr, 1, 1, 1, 100)
376 -}
377 -
378 -func SubtestStress1Swarm1Conn100Stream100Msg(t *testing.T, tr smux.Transport) {
379 - SubtestStressNSwarmNConnNStreamNMsg(t, tr, 1, 1, 100, 100)
380 -}
381 -
382 -func SubtestStress1Swarm10Conn50Stream50Msg(t *testing.T, tr smux.Transport) {
383 - SubtestStressNSwarmNConnNStreamNMsg(t, tr, 1, 10, 50, 50)
384 -}
385 -
386 -func SubtestStress5Swarm2Conn20Stream20Msg(t *testing.T, tr smux.Transport) {
387 - SubtestStressNSwarmNConnNStreamNMsg(t, tr, 5, 2, 20, 20)
388 -}
389 -
390 -func SubtestStress10Swarm2Conn100Stream100Msg(t *testing.T, tr smux.Transport) {
391 - SubtestStressNSwarmNConnNStreamNMsg(t, tr, 10, 2, 100, 100)
392 -}
393 -
394 -func SubtestAll(t *testing.T, tr smux.Transport) {
395 -
396 - tests := []TransportTest{
397 - SubtestConstructSwarm,
398 - SubtestSimpleWrite,
399 - SubtestSimpleWrite100msgs,
400 - SubtestStress1Swarm1Conn1Stream1Msg,
401 - SubtestStress1Swarm1Conn1Stream100Msg,
402 - SubtestStress1Swarm1Conn100Stream100Msg,
403 - SubtestStress1Swarm10Conn50Stream50Msg,
404 - SubtestStress5Swarm2Conn20Stream20Msg,
405 - // SubtestStress10Swarm2Conn100Stream100Msg, <-- this hoses the osx network stack...
406 - }
407 -
408 - for _, f := range tests {
409 - if testing.Verbose() {
410 - fmt.Fprintf(os.Stderr, "==== RUN %s\n", GetFunctionName(f))
411 - }
412 - f(t, tr)
413 - }
414 -}
415 -
416 -type TransportTest func(t *testing.T, tr smux.Transport)
417 -
418 -func TestNoOp(t *testing.T) {}
419 -
420 -func GetFunctionName(i interface{}) string {
421 - return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
422 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/stream.go deleted
-93
@@ -1,93 +0,0 @@
1 -package peerstream
2 -
3 -import (
4 - "fmt"
5 -
6 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
7 -)
8 -
9 -// StreamHandler is a function which receives a Stream. It
10 -// allows clients to set a function to receive newly created
11 -// streams, and decide whether to continue adding them.
12 -// It works sort of like a http.HandleFunc.
13 -// Note: the StreamHandler is called sequentially, so spawn
14 -// goroutines or pass the Stream. See EchoHandler.
15 -type StreamHandler func(s *Stream)
16 -
17 -// Stream is an io.{Read,Write,Close}r to a remote counterpart.
18 -// It wraps a spdystream.Stream, and links it to a Conn and groups
19 -type Stream struct {
20 - smuxStream smux.Stream
21 -
22 - conn *Conn
23 - groups groupSet
24 -}
25 -
26 -func newStream(ss smux.Stream, c *Conn) *Stream {
27 - s := &Stream{
28 - conn: c,
29 - smuxStream: ss,
30 - groups: groupSet{m: make(map[Group]struct{})},
31 - }
32 - s.groups.AddSet(&c.groups) // inherit groups
33 - return s
34 -}
35 -
36 -// String returns a string representation of the Stream
37 -func (s *Stream) String() string {
38 - f := "<peerstream.Stream %s <--> %s>"
39 - return fmt.Sprintf(f, s.conn.NetConn().LocalAddr(), s.conn.NetConn().RemoteAddr())
40 -}
41 -
42 -// SPDYStream returns the underlying *spdystream.Stream
43 -func (s *Stream) Stream() smux.Stream {
44 - return s.smuxStream
45 -}
46 -
47 -// Conn returns the Conn associated with this Stream
48 -func (s *Stream) Conn() *Conn {
49 - return s.conn
50 -}
51 -
52 -// Swarm returns the Swarm asociated with this Stream
53 -func (s *Stream) Swarm() *Swarm {
54 - return s.conn.swarm
55 -}
56 -
57 -// Groups returns the Groups this Stream belongs to
58 -func (s *Stream) Groups() []Group {
59 - return s.groups.Groups()
60 -}
61 -
62 -// InGroup returns whether this stream belongs to a Group
63 -func (s *Stream) InGroup(g Group) bool {
64 - return s.groups.Has(g)
65 -}
66 -
67 -// AddGroup assigns given Group to Stream
68 -func (s *Stream) AddGroup(g Group) {
69 - s.groups.Add(g)
70 -}
71 -
72 -func (s *Stream) Read(p []byte) (n int, err error) {
73 - return s.smuxStream.Read(p)
74 -}
75 -
76 -func (s *Stream) Write(p []byte) (n int, err error) {
77 - return s.smuxStream.Write(p)
78 -}
79 -
80 -func (s *Stream) Close() error {
81 - return s.conn.swarm.removeStream(s)
82 -}
83 -
84 -// StreamsWithGroup narrows down a set of streams to those in given group.
85 -func StreamsWithGroup(g Group, streams []*Stream) []*Stream {
86 - var out []*Stream
87 - for _, s := range streams {
88 - if s.InGroup(g) {
89 - out = append(out, s)
90 - }
91 - }
92 - return out
93 -}
Godeps/_workspace/src/github.com/jbenet/go-peerstream/swarm.go deleted
-404
@@ -1,404 +0,0 @@
1 -package peerstream
2 -
3 -import (
4 - "errors"
5 - "fmt"
6 - "net"
7 - "sync"
8 - "time"
9 -
10 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
11 -)
12 -
13 -// fd is a (file) descriptor, unix style
14 -type fd uint32
15 -
16 -// GarbageCollectTimeout governs the periodic connection closer.
17 -var GarbageCollectTimeout = 5 * time.Second
18 -
19 -type Swarm struct {
20 - // the transport we'll use.
21 - transport smux.Transport
22 -
23 - // active streams.
24 - streams map[*Stream]struct{}
25 - streamLock sync.RWMutex
26 -
27 - // active connections. generate new Streams
28 - conns map[*Conn]struct{}
29 - connLock sync.RWMutex
30 -
31 - // active listeners. generate new Listeners
32 - listeners map[*Listener]struct{}
33 - listenerLock sync.RWMutex
34 -
35 - // these handlers should be accessed with their getter/setter
36 - // as this pointer may be changed at any time.
37 - handlerLock sync.RWMutex // protects the functions below
38 - connHandler ConnHandler // receives Conns intiated remotely
39 - streamHandler StreamHandler // receives Streams initiated remotely
40 - selectConn SelectConn // default SelectConn function
41 -
42 - // notification listeners
43 - notifiees map[Notifiee]struct{}
44 - notifieeLock sync.RWMutex
45 -
46 - closed chan struct{}
47 -}
48 -
49 -func NewSwarm(t smux.Transport) *Swarm {
50 - s := &Swarm{
51 - transport: t,
52 - streams: make(map[*Stream]struct{}),
53 - conns: make(map[*Conn]struct{}),
54 - listeners: make(map[*Listener]struct{}),
55 - notifiees: make(map[Notifiee]struct{}),
56 - selectConn: SelectRandomConn,
57 - streamHandler: NoOpStreamHandler,
58 - connHandler: NoOpConnHandler,
59 - closed: make(chan struct{}),
60 - }
61 - go s.connGarbageCollect()
62 - return s
63 -}
64 -
65 -// String returns a string with various internal stats
66 -func (s *Swarm) String() string {
67 - s.listenerLock.Lock()
68 - ls := len(s.listeners)
69 - s.listenerLock.Unlock()
70 -
71 - s.connLock.Lock()
72 - cs := len(s.conns)
73 - s.connLock.Unlock()
74 -
75 - s.streamLock.Lock()
76 - ss := len(s.streams)
77 - s.streamLock.Unlock()
78 -
79 - str := "<peerstream.Swarm %d listeners %d conns %d streams>"
80 - return fmt.Sprintf(str, ls, cs, ss)
81 -}
82 -
83 -// Dump returns a string with all the internal state
84 -func (s *Swarm) Dump() string {
85 - str := s.String() + "\n"
86 -
87 - s.listenerLock.Lock()
88 - for l, _ := range s.listeners {
89 - str += fmt.Sprintf("\t%s %v\n", l, l.Groups())
90 - }
91 - s.listenerLock.Unlock()
92 -
93 - s.connLock.Lock()
94 - for c, _ := range s.conns {
95 - str += fmt.Sprintf("\t%s %v\n", c, c.Groups())
96 - }
97 - s.connLock.Unlock()
98 -
99 - s.streamLock.Lock()
100 - for ss, _ := range s.streams {
101 - str += fmt.Sprintf("\t%s %v\n", ss, ss.Groups())
102 - }
103 - s.streamLock.Unlock()
104 -
105 - return str
106 -}
107 -
108 -// SetStreamHandler assigns the stream handler in the swarm.
109 -// The handler assumes responsibility for closing the stream.
110 -// This need not happen at the end of the handler, leaving the
111 -// stream open (to be used and closed later) is fine.
112 -// It is also fine to keep a pointer to the Stream.
113 -// This is a threadsafe (atomic) operation
114 -func (s *Swarm) SetStreamHandler(sh StreamHandler) {
115 - s.handlerLock.Lock()
116 - defer s.handlerLock.Unlock()
117 - s.streamHandler = sh
118 -}
119 -
120 -// StreamHandler returns the Swarm's current StreamHandler.
121 -// This is a threadsafe (atomic) operation
122 -func (s *Swarm) StreamHandler() StreamHandler {
123 - s.handlerLock.RLock()
124 - defer s.handlerLock.RUnlock()
125 - if s.streamHandler == nil {
126 - return NoOpStreamHandler
127 - }
128 - return s.streamHandler
129 -}
130 -
131 -// SetConnHandler assigns the conn handler in the swarm.
132 -// Unlike the StreamHandler, the ConnHandler has less respon-
133 -// ibility for the Connection. The Swarm is still its client.
134 -// This handler is only a notification.
135 -// This is a threadsafe (atomic) operation
136 -func (s *Swarm) SetConnHandler(ch ConnHandler) {
137 - s.handlerLock.Lock()
138 - defer s.handlerLock.Unlock()
139 - s.connHandler = ch
140 -}
141 -
142 -// ConnHandler returns the Swarm's current ConnHandler.
143 -// This is a threadsafe (atomic) operation
144 -func (s *Swarm) ConnHandler() ConnHandler {
145 - s.handlerLock.RLock()
146 - defer s.handlerLock.RUnlock()
147 - if s.connHandler == nil {
148 - return NoOpConnHandler
149 - }
150 - return s.connHandler
151 -}
152 -
153 -// SetConnSelect assigns the connection selector in the swarm.
154 -// If cs is nil, will use SelectRandomConn
155 -// This is a threadsafe (atomic) operation
156 -func (s *Swarm) SetSelectConn(cs SelectConn) {
157 - s.handlerLock.Lock()
158 - defer s.handlerLock.Unlock()
159 - s.selectConn = cs
160 -}
161 -
162 -// ConnSelect returns the Swarm's current connection selector.
163 -// ConnSelect is used in order to select the best of a set of
164 -// possible connections. The default chooses one at random.
165 -// This is a threadsafe (atomic) operation
166 -func (s *Swarm) SelectConn() SelectConn {
167 - s.handlerLock.RLock()
168 - defer s.handlerLock.RUnlock()
169 - if s.selectConn == nil {
170 - return SelectRandomConn
171 - }
172 - return s.selectConn
173 -}
174 -
175 -// Conns returns all the connections associated with this Swarm.
176 -func (s *Swarm) Conns() []*Conn {
177 - s.connLock.RLock()
178 - conns := make([]*Conn, 0, len(s.conns))
179 - for c := range s.conns {
180 - conns = append(conns, c)
181 - }
182 - s.connLock.RUnlock()
183 -
184 - open := make([]*Conn, 0, len(conns))
185 - for _, c := range conns {
186 - if c.smuxConn.IsClosed() {
187 - c.GoClose()
188 - } else {
189 - open = append(open, c)
190 - }
191 - }
192 - return open
193 -}
194 -
195 -// Listeners returns all the listeners associated with this Swarm.
196 -func (s *Swarm) Listeners() []*Listener {
197 - s.listenerLock.RLock()
198 - out := make([]*Listener, 0, len(s.listeners))
199 - for c := range s.listeners {
200 - out = append(out, c)
201 - }
202 - s.listenerLock.RUnlock()
203 - return out
204 -}
205 -
206 -// Streams returns all the streams associated with this Swarm.
207 -func (s *Swarm) Streams() []*Stream {
208 - s.streamLock.RLock()
209 - out := make([]*Stream, 0, len(s.streams))
210 - for c := range s.streams {
211 - out = append(out, c)
212 - }
213 - s.streamLock.RUnlock()
214 - return out
215 -}
216 -
217 -// AddListener adds net.Listener to the Swarm, and immediately begins
218 -// accepting incoming connections.
219 -func (s *Swarm) AddListener(l net.Listener) (*Listener, error) {
220 - return s.addListener(l)
221 -}
222 -
223 -// AddListenerWithRateLimit adds Listener to the Swarm, and immediately
224 -// begins accepting incoming connections. The rate of connection acceptance
225 -// depends on the RateLimit option
226 -// func (s *Swarm) AddListenerWithRateLimit(net.Listner, RateLimit) // TODO
227 -
228 -// AddConn gives the Swarm ownership of net.Conn. The Swarm will open a
229 -// SPDY session and begin listening for Streams.
230 -// Returns the resulting Swarm-associated peerstream.Conn.
231 -// Idempotent: if the Connection has already been added, this is a no-op.
232 -func (s *Swarm) AddConn(netConn net.Conn) (*Conn, error) {
233 - return s.addConn(netConn, false)
234 -}
235 -
236 -// NewStream opens a new Stream on the best available connection,
237 -// as selected by current swarm.SelectConn.
238 -func (s *Swarm) NewStream() (*Stream, error) {
239 - return s.NewStreamSelectConn(s.SelectConn())
240 -}
241 -
242 -func (s *Swarm) newStreamSelectConn(selConn SelectConn, conns []*Conn) (*Stream, error) {
243 - if selConn == nil {
244 - return nil, errors.New("nil SelectConn")
245 - }
246 -
247 - best := selConn(conns)
248 - if best == nil || !ConnInConns(best, conns) {
249 - return nil, ErrInvalidConnSelected
250 - }
251 - return s.NewStreamWithConn(best)
252 -}
253 -
254 -// NewStreamWithSelectConn opens a new Stream on a connection selected
255 -// by selConn.
256 -func (s *Swarm) NewStreamSelectConn(selConn SelectConn) (*Stream, error) {
257 - if selConn == nil {
258 - return nil, errors.New("nil SelectConn")
259 - }
260 -
261 - conns := s.Conns()
262 - if len(conns) == 0 {
263 - return nil, ErrNoConnections
264 - }
265 - return s.newStreamSelectConn(selConn, conns)
266 -}
267 -
268 -// NewStreamWithGroup opens a new Stream on an available connection in
269 -// the given group. Uses the current swarm.SelectConn to pick between
270 -// multiple connections.
271 -func (s *Swarm) NewStreamWithGroup(group Group) (*Stream, error) {
272 - conns := s.ConnsWithGroup(group)
273 - return s.newStreamSelectConn(s.SelectConn(), conns)
274 -}
275 -
276 -// NewStreamWithNetConn opens a new Stream on given net.Conn.
277 -// Calls s.AddConn(netConn).
278 -func (s *Swarm) NewStreamWithNetConn(netConn net.Conn) (*Stream, error) {
279 - c, err := s.AddConn(netConn)
280 - if err != nil {
281 - return nil, err
282 - }
283 - return s.NewStreamWithConn(c)
284 -}
285 -
286 -// NewStreamWithConnection opens a new Stream on given connection.
287 -func (s *Swarm) NewStreamWithConn(conn *Conn) (*Stream, error) {
288 - if conn == nil {
289 - return nil, errors.New("nil Conn")
290 - }
291 - if conn.Swarm() != s {
292 - return nil, errors.New("connection not associated with swarm")
293 - }
294 -
295 - if conn.smuxConn.IsClosed() {
296 - go conn.Close()
297 - return nil, errors.New("conn is closed")
298 - }
299 -
300 - s.connLock.RLock()
301 - if _, found := s.conns[conn]; !found {
302 - s.connLock.RUnlock()
303 - return nil, errors.New("connection not associated with swarm")
304 - }
305 - s.connLock.RUnlock()
306 - return s.createStream(conn)
307 -}
308 -
309 -// AddConnToGroup assigns given Group to conn
310 -func (s *Swarm) AddConnToGroup(conn *Conn, g Group) {
311 - conn.groups.Add(g)
312 -}
313 -
314 -// ConnsWithGroup returns all the connections with a given Group
315 -func (s *Swarm) ConnsWithGroup(g Group) []*Conn {
316 - return ConnsWithGroup(g, s.Conns())
317 -}
318 -
319 -// StreamsWithGroup returns all the streams with a given Group
320 -func (s *Swarm) StreamsWithGroup(g Group) []*Stream {
321 - return StreamsWithGroup(g, s.Streams())
322 -}
323 -
324 -// Close shuts down the Swarm, and it's listeners.
325 -func (s *Swarm) Close() error {
326 - defer close(s.closed)
327 -
328 - // automatically close everything new we get.
329 - s.SetConnHandler(func(c *Conn) { c.Close() })
330 - s.SetStreamHandler(func(s *Stream) { s.Close() })
331 -
332 - var wgl sync.WaitGroup
333 - for _, l := range s.Listeners() {
334 - wgl.Add(1)
335 - go func(list *Listener) {
336 - list.Close()
337 - wgl.Done()
338 - }(l)
339 - }
340 - wgl.Wait()
341 -
342 - var wgc sync.WaitGroup
343 - for _, c := range s.Conns() {
344 - wgc.Add(1)
345 - go func(conn *Conn) {
346 - conn.Close()
347 - wgc.Done()
348 - }(c)
349 - }
350 - wgc.Wait()
351 - return nil
352 -}
353 -
354 -// connGarbageCollect periodically sweeps conns to make sure
355 -// they're still alive. if any are closed, remvoes them.
356 -func (s *Swarm) connGarbageCollect() {
357 - for {
358 - select {
359 - case <-s.closed:
360 - return
361 - case <-time.After(GarbageCollectTimeout):
362 - }
363 -
364 - for _, c := range s.Conns() {
365 - if c.smuxConn.IsClosed() {
366 - go c.Close()
367 - }
368 - }
369 - }
370 -}
371 -
372 -// Notify signs up Notifiee to receive signals when events happen
373 -func (s *Swarm) Notify(n Notifiee) {
374 - s.notifieeLock.Lock()
375 - s.notifiees[n] = struct{}{}
376 - s.notifieeLock.Unlock()
377 -}
378 -
379 -// StopNotify unregisters Notifiee fromr receiving signals
380 -func (s *Swarm) StopNotify(n Notifiee) {
381 - s.notifieeLock.Lock()
382 - delete(s.notifiees, n)
383 - s.notifieeLock.Unlock()
384 -}
385 -
386 -// notifyAll runs the notification function on all Notifiees
387 -func (s *Swarm) notifyAll(notification func(n Notifiee)) {
388 - s.notifieeLock.RLock()
389 - for n := range s.notifiees {
390 - // make sure we dont block
391 - // and they dont block each other.
392 - go notification(n)
393 - }
394 - s.notifieeLock.RUnlock()
395 -}
396 -
397 -// Notifiee is an interface for an object wishing to receive
398 -// notifications from a Swarm
399 -type Notifiee interface {
400 - Connected(*Conn) // called when a connection opened
401 - Disconnected(*Conn) // called when a connection closed
402 - OpenedStream(*Stream) // called when a stream opened
403 - ClosedStream(*Stream) // called when a stream closed
404 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/.travis.yml deleted
-10
@@ -1,10 +0,0 @@
1 -language: go
2 -
3 -go:
4 - - 1.3
5 - - 1.4
6 - - release
7 - - tip
8 -
9 -script:
10 - - go test -race -cpu=5 -v ./...
Godeps/_workspace/src/github.com/jbenet/go-reuseport/LICENSE deleted
-13
@@ -1,13 +0,0 @@
1 -Copyright (c) 2013 Conformal Systems LLC.
2 -
3 -Permission to use, copy, modify, and distribute this software for any
4 -purpose with or without fee is hereby granted, provided that the above
5 -copyright notice and this permission notice appear in all copies.
6 -
7 -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
\ No newline at end of file
Godeps/_workspace/src/github.com/jbenet/go-reuseport/README.md deleted
-42
@@ -1,42 +0,0 @@
1 -# go-reuseport
2 -
3 -[![travisbadge](https://travis-ci.org/jbenet/go-reuseport.svg)](https://travis-ci.org/jbenet/go-reuseport)
4 -
5 -This package enables listening and dialing from _the same_ TCP or UDP port.
6 -This means that the following sockopts are set:
7 -
8 -```
9 -SO_REUSEADDR
10 -SO_REUSEPORT
11 -```
12 -
13 -- godoc: https://godoc.org/github.com/jbenet/go-reuseport
14 -
15 -This is a simple package to get around the problem of reusing addresses.
16 -The go `net` package (to my knowledge) does not allow setting socket options.
17 -This is particularly problematic when attempting to do TCP NAT holepunching,
18 -which requires a process to both Listen and Dial on the same TCP port.
19 -This package makes this possible for me. It is a pretty narrow use case, but
20 -perhaps this package can grow to be more general over time.
21 -
22 -## Examples
23 -
24 -
25 -```Go
26 -// listen on the same port. oh yeah.
27 -l1, _ := reuse.Listen("tcp", "127.0.0.1:1234")
28 -l2, _ := reuse.Listen("tcp", "127.0.0.1:1234")
29 -```
30 -
31 -```Go
32 -// dial from the same port. oh yeah.
33 -l1, _ := reuse.Listen("tcp", "127.0.0.1:1234")
34 -l2, _ := reuse.Listen("tcp", "127.0.0.1:1235")
35 -c, _ := reuse.Dial("tcp", "127.0.0.1:1234", "127.0.0.1:1235")
36 -```
37 -
38 -**Note: cant dial self because tcp/ip stacks use 4-tuples to identify connections, and doing so would clash.**
39 -
40 -## Tested
41 -
42 -Tested on `darwin` and `linux`.
Godeps/_workspace/src/github.com/jbenet/go-reuseport/addr.go deleted
-20
@@ -1,20 +0,0 @@
1 -package reuseport
2 -
3 -import (
4 - "net"
5 -)
6 -
7 -func ResolveAddr(network, address string) (net.Addr, error) {
8 - switch network {
9 - default:
10 - return nil, net.UnknownNetworkError(network)
11 - case "ip", "ip4", "ip6":
12 - return net.ResolveIPAddr(network, address)
13 - case "tcp", "tcp4", "tcp6":
14 - return net.ResolveTCPAddr(network, address)
15 - case "udp", "udp4", "udp6":
16 - return net.ResolveUDPAddr(network, address)
17 - case "unix", "unixgram", "unixpacket":
18 - return net.ResolveUnixAddr(network, address)
19 - }
20 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/available_unix.go deleted
-91
@@ -1,91 +0,0 @@
1 -// +build darwin freebsd dragonfly netbsd openbsd linux
2 -
3 -package reuseport
4 -
5 -import (
6 - "sync"
7 - "sync/atomic"
8 - "syscall"
9 - "time"
10 -)
11 -
12 -// checker is a struct to gather the availability check fields + funcs.
13 -// we use atomic ints because this is potentially a really hot function call.
14 -type checkerT struct {
15 - avail int32 // atomic int managed by set/isAvailable()
16 - check int32 // atomic int managed by has/checked()
17 - mu sync.Mutex // synchonizes the actual check
18 -}
19 -
20 -// the static location of the vars.
21 -var checker checkerT
22 -
23 -func (c *checkerT) isAvailable() bool {
24 - return atomic.LoadInt32(&c.avail) != 0
25 -}
26 -
27 -func (c *checkerT) setIsAvailable(b bool) {
28 - if b {
29 - atomic.StoreInt32(&c.avail, 1)
30 - } else {
31 - atomic.StoreInt32(&c.avail, 0)
32 - }
33 -}
34 -
35 -func (c *checkerT) hasChecked() bool {
36 - return atomic.LoadInt32(&c.check) != 0
37 -}
38 -
39 -func (c *checkerT) setHasChecked(b bool) {
40 - if b {
41 - atomic.StoreInt32(&c.check, 1)
42 - } else {
43 - atomic.StoreInt32(&c.check, 0)
44 - }
45 -}
46 -
47 -// Available returns whether or not SO_REUSEPORT is available in the OS.
48 -// It does so by attepting to open a tcp listener, setting the option, and
49 -// checking ENOPROTOOPT on error. After checking, the decision is cached
50 -// for the rest of the process run.
51 -func available() bool {
52 - if checker.hasChecked() {
53 - return checker.isAvailable()
54 - }
55 -
56 - // synchronize, only one should check
57 - checker.mu.Lock()
58 - defer checker.mu.Unlock()
59 -
60 - // we blocked. someone may have been gotten this.
61 - if checker.hasChecked() {
62 - return checker.isAvailable()
63 - }
64 -
65 - // there may be fluke reasons to fail to add a listener.
66 - // so we give it 5 shots. if not, give up and call it not avail.
67 - for i := 0; i < 5; i++ {
68 - // try to listen at tcp port 0.
69 - l, err := listenStream("tcp", "127.0.0.1:0")
70 - if err == nil {
71 - // no error? available.
72 - checker.setIsAvailable(true)
73 - checker.setHasChecked(true)
74 - l.Close() // Go back to the Shadow!
75 - return true
76 - }
77 -
78 - if errno, ok := err.(syscall.Errno); ok {
79 - if errno == syscall.ENOPROTOOPT {
80 - break // :( that's all folks.
81 - }
82 - }
83 -
84 - // not an errno? or not ENOPROTOOPT? retry.
85 - <-time.After(20 * time.Millisecond) // wait a bit
86 - }
87 -
88 - checker.setIsAvailable(false)
89 - checker.setHasChecked(true)
90 - return false
91 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/const_bsd.go deleted
-10
@@ -1,10 +0,0 @@
1 -// +build darwin freebsd dragonfly netbsd openbsd
2 -
3 -package reuseport
4 -
5 -import (
6 - "syscall"
7 -)
8 -
9 -var soReusePort = syscall.SO_REUSEPORT
10 -var soReuseAddr = syscall.SO_REUSEADDR
Godeps/_workspace/src/github.com/jbenet/go-reuseport/const_linux.go deleted
-10
@@ -1,10 +0,0 @@
1 -// +build linux
2 -
3 -package reuseport
4 -
5 -import (
6 - "syscall"
7 -)
8 -
9 -var soReusePort = 15 // this is not defined in unix go pkg.
10 -var soReuseAddr = syscall.SO_REUSEADDR
Godeps/_workspace/src/github.com/jbenet/go-reuseport/impl_unix.go deleted
-362
@@ -1,362 +0,0 @@
1 -// +build darwin freebsd dragonfly netbsd openbsd linux
2 -
3 -package reuseport
4 -
5 -import (
6 - "net"
7 - "os"
8 - "strconv"
9 - "syscall"
10 - "time"
11 -
12 - poll "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-reuseport/poll"
13 - sockaddrnet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-sockaddr/net"
14 -)
15 -
16 -const (
17 - filePrefix = "port."
18 -)
19 -
20 -// Wrapper around the socket system call that marks the returned file
21 -// descriptor as nonblocking and close-on-exec.
22 -func socket(family, socktype, protocol int) (fd int, err error) {
23 - syscall.ForkLock.RLock()
24 - fd, err = syscall.Socket(family, socktype, protocol)
25 - if err == nil {
26 - syscall.CloseOnExec(fd)
27 - }
28 - syscall.ForkLock.RUnlock()
29 -
30 - if err != nil {
31 - return -1, err
32 - }
33 -
34 - // cant set it until after connect
35 - // if err = syscall.SetNonblock(fd, true); err != nil {
36 - // syscall.Close(fd)
37 - // return -1, err
38 - // }
39 -
40 - if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReuseAddr, 1); err != nil {
41 - syscall.Close(fd)
42 - return -1, err
43 - }
44 -
45 - if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReusePort, 1); err != nil {
46 - syscall.Close(fd)
47 - return -1, err
48 - }
49 -
50 - // set setLinger to 5 as reusing exact same (srcip:srcport, dstip:dstport)
51 - // will otherwise fail on connect.
52 - if err = setLinger(fd, 5); err != nil {
53 - syscall.Close(fd)
54 - return -1, err
55 - }
56 -
57 - return fd, nil
58 -}
59 -
60 -func dial(dialer net.Dialer, netw, addr string) (c net.Conn, err error) {
61 - var (
62 - fd int
63 - lfamily int
64 - rfamily int
65 - socktype int
66 - lprotocol int
67 - rprotocol int
68 - file *os.File
69 - deadline time.Time
70 - remoteSockaddr syscall.Sockaddr
71 - localSockaddr syscall.Sockaddr
72 - )
73 -
74 - netAddr, err := ResolveAddr(netw, addr)
75 - if err != nil {
76 - return nil, err
77 - }
78 -
79 - switch netAddr.(type) {
80 - case *net.TCPAddr, *net.UDPAddr:
81 - default:
82 - return nil, ErrUnsupportedProtocol
83 - }
84 -
85 - switch {
86 - case !dialer.Deadline.IsZero():
87 - deadline = dialer.Deadline
88 - case dialer.Timeout != 0:
89 - deadline = time.Now().Add(dialer.Timeout)
90 - }
91 -
92 - localSockaddr = sockaddrnet.NetAddrToSockaddr(dialer.LocalAddr)
93 - remoteSockaddr = sockaddrnet.NetAddrToSockaddr(netAddr)
94 -
95 - rfamily = sockaddrnet.NetAddrAF(netAddr)
96 - rprotocol = sockaddrnet.NetAddrIPPROTO(netAddr)
97 - socktype = sockaddrnet.NetAddrSOCK(netAddr)
98 -
99 - if dialer.LocalAddr != nil {
100 - switch dialer.LocalAddr.(type) {
101 - case *net.TCPAddr, *net.UDPAddr:
102 - default:
103 - return nil, ErrUnsupportedProtocol
104 - }
105 -
106 - // check family and protocols match.
107 - lfamily = sockaddrnet.NetAddrAF(dialer.LocalAddr)
108 - lprotocol = sockaddrnet.NetAddrIPPROTO(dialer.LocalAddr)
109 - if lfamily != rfamily && lprotocol != rfamily {
110 - return nil, &net.AddrError{Err: "unexpected address type", Addr: netAddr.String()}
111 - }
112 - }
113 -
114 - // look at dialTCP in http://golang.org/src/net/tcpsock_posix.go .... !
115 - // here we just try again 3 times.
116 - for i := 0; i < 3; i++ {
117 - if !deadline.IsZero() && deadline.Before(time.Now()) {
118 - if err == nil {
119 - err = errTimeout
120 - }
121 - break
122 - }
123 -
124 - if fd, err = socket(rfamily, socktype, rprotocol); err != nil {
125 - return nil, err
126 - }
127 -
128 - if localSockaddr != nil {
129 - if err = syscall.Bind(fd, localSockaddr); err != nil {
130 - syscall.Close(fd)
131 - return nil, err
132 - }
133 - }
134 -
135 - if err = syscall.SetNonblock(fd, true); err != nil {
136 - syscall.Close(fd)
137 - return nil, err
138 - }
139 -
140 - if err = connect(fd, remoteSockaddr, deadline); err != nil {
141 - syscall.Close(fd)
142 - continue // try again.
143 - }
144 -
145 - break
146 - }
147 - if err != nil {
148 - return nil, err
149 - }
150 -
151 - if rprotocol == syscall.IPPROTO_TCP {
152 - // by default golang/net sets TCP no delay to true.
153 - if err = setNoDelay(fd, true); err != nil {
154 - syscall.Close(fd)
155 - return nil, err
156 - }
157 - }
158 -
159 - // File Name get be nil
160 - file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
161 - if c, err = net.FileConn(file); err != nil {
162 - syscall.Close(fd)
163 - return nil, err
164 - }
165 -
166 - if err = file.Close(); err != nil {
167 - syscall.Close(fd)
168 - c.Close()
169 - return nil, err
170 - }
171 -
172 - // c = wrapConnWithRemoteAddr(c, netAddr)
173 - return c, err
174 -}
175 -
176 -func listen(netw, addr string) (fd int, err error) {
177 - var (
178 - family int
179 - socktype int
180 - protocol int
181 - sockaddr syscall.Sockaddr
182 - )
183 -
184 - netAddr, err := ResolveAddr(netw, addr)
185 - if err != nil {
186 - return -1, err
187 - }
188 -
189 - switch netAddr.(type) {
190 - case *net.TCPAddr, *net.UDPAddr:
191 - default:
192 - return -1, ErrUnsupportedProtocol
193 - }
194 -
195 - family = sockaddrnet.NetAddrAF(netAddr)
196 - protocol = sockaddrnet.NetAddrIPPROTO(netAddr)
197 - sockaddr = sockaddrnet.NetAddrToSockaddr(netAddr)
198 - socktype = sockaddrnet.NetAddrSOCK(netAddr)
199 -
200 - if fd, err = socket(family, socktype, protocol); err != nil {
201 - return -1, err
202 - }
203 -
204 - if err = syscall.Bind(fd, sockaddr); err != nil {
205 - syscall.Close(fd)
206 - return -1, err
207 - }
208 -
209 - if protocol == syscall.IPPROTO_TCP {
210 - // by default golang/net sets TCP no delay to true.
211 - if err = setNoDelay(fd, true); err != nil {
212 - syscall.Close(fd)
213 - return -1, err
214 - }
215 - }
216 -
217 - if err = syscall.SetNonblock(fd, true); err != nil {
218 - syscall.Close(fd)
219 - return -1, err
220 - }
221 -
222 - return fd, nil
223 -}
224 -
225 -func listenStream(netw, addr string) (l net.Listener, err error) {
226 - var (
227 - file *os.File
228 - )
229 -
230 - fd, err := listen(netw, addr)
231 - if err != nil {
232 - return nil, err
233 - }
234 -
235 - // Set backlog size to the maximum
236 - if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
237 - syscall.Close(fd)
238 - return nil, err
239 - }
240 -
241 - file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
242 - if l, err = net.FileListener(file); err != nil {
243 - syscall.Close(fd)
244 - return nil, err
245 - }
246 -
247 - if err = file.Close(); err != nil {
248 - syscall.Close(fd)
249 - l.Close()
250 - return nil, err
251 - }
252 -
253 - return l, err
254 -}
255 -
256 -func listenPacket(netw, addr string) (p net.PacketConn, err error) {
257 - var (
258 - file *os.File
259 - )
260 -
261 - fd, err := listen(netw, addr)
262 - if err != nil {
263 - return nil, err
264 - }
265 -
266 - file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
267 - if p, err = net.FilePacketConn(file); err != nil {
268 - syscall.Close(fd)
269 - return nil, err
270 - }
271 -
272 - if err = file.Close(); err != nil {
273 - syscall.Close(fd)
274 - p.Close()
275 - return nil, err
276 - }
277 -
278 - return p, err
279 -}
280 -
281 -func listenUDP(netw, addr string) (c net.Conn, err error) {
282 - var (
283 - file *os.File
284 - )
285 -
286 - fd, err := listen(netw, addr)
287 - if err != nil {
288 - return nil, err
289 - }
290 -
291 - file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
292 - if c, err = net.FileConn(file); err != nil {
293 - syscall.Close(fd)
294 - return nil, err
295 - }
296 -
297 - if err = file.Close(); err != nil {
298 - syscall.Close(fd)
299 - return nil, err
300 - }
301 -
302 - return c, err
303 -}
304 -
305 -// this is close to the connect() function inside stdlib/net
306 -func connect(fd int, ra syscall.Sockaddr, deadline time.Time) error {
307 - switch err := syscall.Connect(fd, ra); err {
308 - case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
309 - case nil, syscall.EISCONN:
310 - if !deadline.IsZero() && deadline.Before(time.Now()) {
311 - return errTimeout
312 - }
313 - return nil
314 - default:
315 - return err
316 - }
317 -
318 - poller, err := poll.New(fd)
319 - if err != nil {
320 - return err
321 - }
322 - defer poller.Close()
323 -
324 - for {
325 - if err = poller.WaitWrite(deadline); err != nil {
326 - return err
327 - }
328 -
329 - // if err := fd.pd.WaitWrite(); err != nil {
330 - // return err
331 - // }
332 - // i'd use the above fd.pd.WaitWrite to poll io correctly, just like net sockets...
333 - // but of course, it uses the damn runtime_* functions that _cannot_ be used by
334 - // non-go-stdlib source... seriously guys, this is not nice.
335 - // we're relegated to using syscall.Select (what nightmare that is) or using
336 - // a simple but totally bogus time-based wait. such garbage.
337 - var nerr int
338 - nerr, err = syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ERROR)
339 - if err != nil {
340 - return err
341 - }
342 - switch err = syscall.Errno(nerr); err {
343 - case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
344 - continue
345 - case syscall.Errno(0), syscall.EISCONN:
346 - if !deadline.IsZero() && deadline.Before(time.Now()) {
347 - return errTimeout
348 - }
349 - return nil
350 - default:
351 - return err
352 - }
353 - }
354 -}
355 -
356 -var errTimeout = &timeoutError{}
357 -
358 -type timeoutError struct{}
359 -
360 -func (e *timeoutError) Error() string { return "i/o timeout (reuseport)" }
361 -func (e *timeoutError) Timeout() bool { return true }
362 -func (e *timeoutError) Temporary() bool { return true }
Godeps/_workspace/src/github.com/jbenet/go-reuseport/impl_windows.go deleted
-28
@@ -1,28 +0,0 @@
1 -package reuseport
2 -
3 -import "net"
4 -
5 -// TODO. for now, just pass it over to net.Listen/net.Dial
6 -
7 -func listen(network, address string) (net.Listener, error) {
8 - return net.Listen(network, address)
9 -}
10 -
11 -func listenPacket(netw, laddr string) (net.PacketConn, error) {
12 - return net.ListenPacket(netw, laddr)
13 -}
14 -
15 -func listenStream(netw, addr string) (net.Listener, error) {
16 - return listen(netw, addr)
17 -}
18 -
19 -func dial(dialer net.Dialer, network, address string) (net.Conn, error) {
20 - return dialer.Dial(network, address)
21 -}
22 -
23 -// on windows, we just use the regular functions. sources
24 -// vary on this-- some claim port reuse behavior is on by default
25 -// on some windows systems. So we try. may the force be with you.
26 -func available() bool {
27 - return true
28 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/interface.go deleted
-110
@@ -1,110 +0,0 @@
1 -// Package reuseport provides Listen and Dial functions that set socket options
2 -// in order to be able to reuse ports. You should only use this package if you
3 -// know what SO_REUSEADDR and SO_REUSEPORT are.
4 -//
5 -// For example:
6 -//
7 -// // listen on the same port. oh yeah.
8 -// l1, _ := reuse.Listen("tcp", "127.0.0.1:1234")
9 -// l2, _ := reuse.Listen("tcp", "127.0.0.1:1234")
10 -//
11 -// // dial from the same port. oh yeah.
12 -// l1, _ := reuse.Listen("tcp", "127.0.0.1:1234")
13 -// l2, _ := reuse.Listen("tcp", "127.0.0.1:1235")
14 -// c, _ := reuse.Dial("tcp", "127.0.0.1:1234", "127.0.0.1:1235")
15 -//
16 -// Note: cant dial self because tcp/ip stacks use 4-tuples to identify connections,
17 -// and doing so would clash.
18 -package reuseport
19 -
20 -import (
21 - "errors"
22 - "net"
23 - "syscall"
24 - "time"
25 -)
26 -
27 -// Available returns whether or not SO_REUSEPORT is available in the OS.
28 -// It does so by attepting to open a tcp listener, setting the option, and
29 -// checking ENOPROTOOPT on error. After checking, the decision is cached
30 -// for the rest of the process run.
31 -func Available() bool {
32 - return available()
33 -}
34 -
35 -// ErrUnsuportedProtocol signals that the protocol is not currently
36 -// supported by this package. This package currently only supports TCP.
37 -var ErrUnsupportedProtocol = errors.New("protocol not yet supported")
38 -
39 -// ErrReuseFailed is returned if a reuse attempt was unsuccessful.
40 -var ErrReuseFailed = errors.New("reuse failed")
41 -
42 -// Listen listens at the given network and address. see net.Listen
43 -// Returns a net.Listener created from a file discriptor for a socket
44 -// with SO_REUSEPORT and SO_REUSEADDR option set.
45 -func Listen(network, address string) (net.Listener, error) {
46 - if !available() {
47 - return nil, syscall.Errno(syscall.ENOPROTOOPT)
48 - }
49 -
50 - return listenStream(network, address)
51 -}
52 -
53 -// ListenPacket listens at the given network and address. see net.ListenPacket
54 -// Returns a net.Listener created from a file discriptor for a socket
55 -// with SO_REUSEPORT and SO_REUSEADDR option set.
56 -func ListenPacket(network, address string) (net.PacketConn, error) {
57 - if !available() {
58 - return nil, syscall.Errno(syscall.ENOPROTOOPT)
59 - }
60 -
61 - return listenPacket(network, address)
62 -}
63 -
64 -// Dial dials the given network and address. see net.Dialer.Dial
65 -// Returns a net.Conn created from a file discriptor for a socket
66 -// with SO_REUSEPORT and SO_REUSEADDR option set.
67 -func Dial(network, laddr, raddr string) (net.Conn, error) {
68 - if !available() {
69 - return nil, syscall.Errno(syscall.ENOPROTOOPT)
70 - }
71 -
72 - var d Dialer
73 - if laddr != "" {
74 - netladdr, err := ResolveAddr(network, laddr)
75 - if err != nil {
76 - return nil, err
77 - }
78 - d.D.LocalAddr = netladdr
79 - }
80 -
81 - return d.Dial(network, raddr)
82 -}
83 -
84 -// Dialer is used to specify the Dial options, much like net.Dialer.
85 -// We simply wrap a net.Dialer.
86 -type Dialer struct {
87 - D net.Dialer
88 -}
89 -
90 -// Dial dials the given network and address. see net.Dialer.Dial
91 -// Returns a net.Conn created from a file discriptor for a socket
92 -// with SO_REUSEPORT and SO_REUSEADDR option set.
93 -func (d *Dialer) Dial(network, address string) (net.Conn, error) {
94 - if !available() {
95 - return nil, syscall.Errno(syscall.ENOPROTOOPT)
96 - }
97 -
98 - return dial(d.D, network, address)
99 -}
100 -
101 -func (d *Dialer) deadline(def time.Duration) time.Time {
102 - switch {
103 - case !d.D.Deadline.IsZero():
104 - return d.D.Deadline
105 - case d.D.Timeout != 0:
106 - return time.Now().Add(d.D.Timeout)
107 - default:
108 - return time.Now().Add(def)
109 - }
110 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/opts_posix.go deleted
-35
@@ -1,35 +0,0 @@
1 -// Copyright 2009 The Go Authors. All rights reserved.
2 -// Use of this source code is governed by a BSD-style
3 -// license that can be found in the LICENSE file.
4 -
5 -// +build darwin dragonfly freebsd linux netbsd openbsd solaris
6 -
7 -package reuseport
8 -
9 -import (
10 - "os"
11 - "syscall"
12 -)
13 -
14 -func boolint(b bool) int {
15 - if b {
16 - return 1
17 - }
18 - return 0
19 -}
20 -
21 -func setNoDelay(fd int, noDelay bool) error {
22 - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay)))
23 -}
24 -
25 -func setLinger(fd int, sec int) error {
26 - var l syscall.Linger
27 - if sec >= 0 {
28 - l.Onoff = 1
29 - l.Linger = int32(sec)
30 - } else {
31 - l.Onoff = 0
32 - l.Linger = 0
33 - }
34 - return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l))
35 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/poll/error.go deleted
-9
@@ -1,9 +0,0 @@
1 -package poll
2 -
3 -var errTimeout = &timeoutError{}
4 -
5 -type timeoutError struct{}
6 -
7 -func (e *timeoutError) Error() string { return "i/o timeout (reuseport poll)" }
8 -func (e *timeoutError) Timeout() bool { return true }
9 -func (e *timeoutError) Temporary() bool { return true }
Godeps/_workspace/src/github.com/jbenet/go-reuseport/poll/poll_bsd.go deleted
-59
@@ -1,59 +0,0 @@
1 -// +build darwin,amd64 darwin,arm64 freebsd dragonfly netbsd openbsd
2 -
3 -package poll
4 -
5 -import (
6 - "syscall"
7 - "time"
8 -)
9 -
10 -type Poller struct {
11 - kqfd int
12 - event syscall.Kevent_t
13 -}
14 -
15 -func New(fd int) (p *Poller, err error) {
16 - p = &Poller{}
17 -
18 - p.kqfd, err = syscall.Kqueue()
19 - if p.kqfd == -1 || err != nil {
20 - return nil, err
21 - }
22 -
23 - p.event = syscall.Kevent_t{
24 - Ident: uint64(fd),
25 - Filter: syscall.EVFILT_WRITE,
26 - Flags: syscall.EV_ADD | syscall.EV_ENABLE | syscall.EV_ONESHOT,
27 - Fflags: 0,
28 - Data: 0,
29 - Udata: nil,
30 - }
31 - return p, nil
32 -}
33 -
34 -func (p *Poller) Close() error {
35 - return syscall.Close(p.kqfd)
36 -}
37 -
38 -func (p *Poller) WaitWrite(deadline time.Time) error {
39 -
40 - // setup timeout
41 - var timeout *syscall.Timespec
42 - if !deadline.IsZero() {
43 - d := deadline.Sub(time.Now())
44 - t := syscall.NsecToTimespec(d.Nanoseconds())
45 - timeout = &t
46 - }
47 -
48 - // wait on kevent
49 - events := make([]syscall.Kevent_t, 1)
50 - n, err := syscall.Kevent(p.kqfd, []syscall.Kevent_t{p.event}, events, timeout)
51 - if err != nil {
52 - return err
53 - }
54 -
55 - if n < 1 {
56 - return errTimeout
57 - }
58 - return nil
59 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/poll/poll_darwin_386.go deleted
-57
@@ -1,57 +0,0 @@
1 -package poll
2 -
3 -import (
4 - "syscall"
5 - "time"
6 -)
7 -
8 -type Poller struct {
9 - kqfd int
10 - event syscall.Kevent_t
11 -}
12 -
13 -func New(fd int) (p *Poller, err error) {
14 - p = &Poller{}
15 -
16 - p.kqfd, err = syscall.Kqueue()
17 - if p.kqfd == -1 || err != nil {
18 - return nil, err
19 - }
20 -
21 - p.event = syscall.Kevent_t{
22 - Ident: uint32(fd),
23 - Filter: syscall.EVFILT_WRITE,
24 - Flags: syscall.EV_ADD | syscall.EV_ENABLE | syscall.EV_ONESHOT,
25 - Fflags: 0,
26 - Data: 0,
27 - Udata: nil,
28 - }
29 - return p, nil
30 -}
31 -
32 -func (p *Poller) Close() error {
33 - return syscall.Close(p.kqfd)
34 -}
35 -
36 -func (p *Poller) WaitWrite(deadline time.Time) error {
37 -
38 - // setup timeout
39 - var timeout *syscall.Timespec
40 - if !deadline.IsZero() {
41 - d := deadline.Sub(time.Now())
42 - t := syscall.NsecToTimespec(d.Nanoseconds())
43 - timeout = &t
44 - }
45 -
46 - // wait on kevent
47 - events := make([]syscall.Kevent_t, 1)
48 - n, err := syscall.Kevent(p.kqfd, []syscall.Kevent_t{p.event}, events, timeout)
49 - if err != nil {
50 - return err
51 - }
52 -
53 - if n < 1 {
54 - return errTimeout
55 - }
56 - return nil
57 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/poll/poll_linux.go deleted
-51
@@ -1,51 +0,0 @@
1 -// +build linux
2 -
3 -package poll
4 -
5 -import (
6 - "syscall"
7 - "time"
8 -)
9 -
10 -type Poller struct {
11 - epfd int
12 - event syscall.EpollEvent
13 - events [32]syscall.EpollEvent
14 -}
15 -
16 -func New(fd int) (p *Poller, err error) {
17 - p = &Poller{}
18 - if p.epfd, err = syscall.EpollCreate1(0); err != nil {
19 - return nil, err
20 - }
21 -
22 - p.event.Events = syscall.EPOLLOUT
23 - p.event.Fd = int32(fd)
24 - if err = syscall.EpollCtl(p.epfd, syscall.EPOLL_CTL_ADD, fd, &p.event); err != nil {
25 - p.Close()
26 - return nil, err
27 - }
28 -
29 - return p, nil
30 -}
31 -
32 -func (p *Poller) Close() error {
33 - return syscall.Close(p.epfd)
34 -}
35 -
36 -func (p *Poller) WaitWrite(deadline time.Time) error {
37 - msec := -1
38 - if !deadline.IsZero() {
39 - d := deadline.Sub(time.Now())
40 - msec = int(d.Nanoseconds() / 1000000) // ms!? omg...
41 - }
42 -
43 - n, err := syscall.EpollWait(p.epfd, p.events[:], msec)
44 - if err != nil {
45 - return err
46 - }
47 - if n < 1 {
48 - return errTimeout
49 - }
50 - return nil
51 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/poll/poll_unsupported.go deleted
-11
@@ -1,11 +0,0 @@
1 -// +build windows plan9
2 -
3 -package poll
4 -
5 -import (
6 - "errors"
7 -)
8 -
9 -func WaitWrite(fd int) error {
10 - return errors.New("platform not supported")
11 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/reuse_test.go deleted
-579
@@ -1,579 +0,0 @@
1 -package reuseport
2 -
3 -import (
4 - "bytes"
5 - "errors"
6 - "fmt"
7 - "io"
8 - "net"
9 - "os"
10 - "os/exec"
11 - "strings"
12 - "sync"
13 - "testing"
14 - "time"
15 -)
16 -
17 -func echo(c net.Conn) {
18 - io.Copy(c, c)
19 - c.Close()
20 -}
21 -
22 -func packetEcho(c net.PacketConn) {
23 - defer c.Close()
24 - buf := make([]byte, 65536)
25 - for {
26 - n, addr, err := c.ReadFrom(buf)
27 - if err != nil {
28 - return
29 - }
30 - if _, err := c.WriteTo(buf[:n], addr); err != nil {
31 - return
32 - }
33 - }
34 -}
35 -
36 -func acceptAndEcho(l net.Listener) {
37 - for {
38 - c, err := l.Accept()
39 - if err != nil {
40 - return
41 - }
42 - go echo(c)
43 - }
44 -}
45 -
46 -func CI() bool {
47 - return os.Getenv("TRAVIS") == "true"
48 -}
49 -
50 -func TestStreamListenSamePort(t *testing.T) {
51 -
52 - // any ports
53 - any := [][]string{
54 - []string{"tcp", "0.0.0.0:0"},
55 - []string{"tcp4", "0.0.0.0:0"},
56 - []string{"tcp6", "[::]:0"},
57 -
58 - []string{"tcp", "127.0.0.1:0"},
59 - []string{"tcp", "[::1]:0"},
60 - []string{"tcp4", "127.0.0.1:0"},
61 - []string{"tcp6", "[::1]:0"},
62 - }
63 -
64 - // specific ports. off in CI
65 - specific := [][]string{
66 - []string{"tcp", "127.0.0.1:5556"},
67 - []string{"tcp", "[::1]:5557"},
68 - []string{"tcp4", "127.0.0.1:5558"},
69 - []string{"tcp6", "[::1]:5559"},
70 - }
71 -
72 - testCases := any
73 - if !CI() {
74 - testCases = append(testCases, specific...)
75 - }
76 -
77 - for _, tcase := range testCases {
78 - network := tcase[0]
79 - addr := tcase[1]
80 - t.Log("testing", network, addr)
81 -
82 - l1, err := Listen(network, addr)
83 - if err != nil {
84 - t.Fatal(err)
85 - continue
86 - }
87 - defer l1.Close()
88 - t.Log("listening", l1.Addr())
89 -
90 - l2, err := Listen(l1.Addr().Network(), l1.Addr().String())
91 - if err != nil {
92 - t.Fatal(err)
93 - continue
94 - }
95 - defer l2.Close()
96 - t.Log("listening", l2.Addr())
97 -
98 - l3, err := Listen(l2.Addr().Network(), l2.Addr().String())
99 - if err != nil {
100 - t.Fatal(err)
101 - continue
102 - }
103 - defer l3.Close()
104 - t.Log("listening", l3.Addr())
105 -
106 - if l1.Addr().String() != l2.Addr().String() {
107 - t.Fatal("addrs should match", l1.Addr(), l2.Addr())
108 - }
109 -
110 - if l1.Addr().String() != l3.Addr().String() {
111 - t.Fatal("addrs should match", l1.Addr(), l3.Addr())
112 - }
113 - }
114 -}
115 -
116 -func TestPacketListenSamePort(t *testing.T) {
117 -
118 - // any ports
119 - any := [][]string{
120 - []string{"udp", "0.0.0.0:0"},
121 - []string{"udp4", "0.0.0.0:0"},
122 - []string{"udp6", "[::]:0"},
123 -
124 - []string{"udp", "127.0.0.1:0"},
125 - []string{"udp", "[::1]:0"},
126 - []string{"udp4", "127.0.0.1:0"},
127 - []string{"udp6", "[::1]:0"},
128 - }
129 -
130 - // specific ports. off in CI
131 - specific := [][]string{
132 - []string{"udp", "127.0.0.1:5560"},
133 - []string{"udp", "[::1]:5561"},
134 - []string{"udp4", "127.0.0.1:5562"},
135 - []string{"udp6", "[::1]:5563"},
136 - }
137 -
138 - testCases := any
139 - if !CI() {
140 - testCases = append(testCases, specific...)
141 - }
142 -
143 - for _, tcase := range testCases {
144 - network := tcase[0]
145 - addr := tcase[1]
146 - t.Log("testing", network, addr)
147 -
148 - l1, err := ListenPacket(network, addr)
149 - if err != nil {
150 - t.Fatal(err)
151 - continue
152 - }
153 - defer l1.Close()
154 - t.Log("listening", l1.LocalAddr())
155 -
156 - l2, err := ListenPacket(l1.LocalAddr().Network(), l1.LocalAddr().String())
157 - if err != nil {
158 - t.Fatal(err)
159 - continue
160 - }
161 - defer l2.Close()
162 - t.Log("listening", l2.LocalAddr())
163 -
164 - l3, err := ListenPacket(l2.LocalAddr().Network(), l2.LocalAddr().String())
165 - if err != nil {
166 - t.Fatal(err)
167 - continue
168 - }
169 - defer l3.Close()
170 - t.Log("listening", l3.LocalAddr())
171 -
172 - if l1.LocalAddr().String() != l2.LocalAddr().String() {
173 - t.Fatal("addrs should match", l1.LocalAddr(), l2.LocalAddr())
174 - }
175 -
176 - if l1.LocalAddr().String() != l3.LocalAddr().String() {
177 - t.Fatal("addrs should match", l1.LocalAddr(), l3.LocalAddr())
178 - }
179 - }
180 -}
181 -
182 -func TestStreamListenDialSamePort(t *testing.T) {
183 -
184 - any := [][]string{
185 - []string{"tcp", "0.0.0.0:0", "0.0.0.0:0"},
186 - []string{"tcp4", "0.0.0.0:0", "0.0.0.0:0"},
187 - []string{"tcp6", "[::]:0", "[::]:0"},
188 -
189 - []string{"tcp", "127.0.0.1:0", "127.0.0.1:0"},
190 - []string{"tcp4", "127.0.0.1:0", "127.0.0.1:0"},
191 - []string{"tcp6", "[::1]:0", "[::1]:0"},
192 - }
193 -
194 - specific := [][]string{
195 - []string{"tcp", "127.0.0.1:0", "127.0.0.1:5571"},
196 - []string{"tcp4", "127.0.0.1:0", "127.0.0.1:5573"},
197 - []string{"tcp6", "[::1]:0", "[::1]:5574"},
198 - []string{"tcp", "127.0.0.1:5570", "127.0.0.1:0"},
199 - []string{"tcp4", "127.0.0.1:5572", "127.0.0.1:0"},
200 - []string{"tcp6", "[::1]:5573", "[::1]:0"},
201 - }
202 -
203 - testCases := any
204 - if !CI() {
205 - testCases = append(testCases, specific...)
206 - }
207 -
208 - for _, tcase := range testCases {
209 - t.Log("testing", tcase)
210 - network := tcase[0]
211 - addr1 := tcase[1]
212 - addr2 := tcase[2]
213 -
214 - l1, err := Listen(network, addr1)
215 - if err != nil {
216 - t.Fatal(err)
217 - continue
218 - }
219 - defer l1.Close()
220 - t.Log("listening", l1.Addr())
221 -
222 - l2, err := Listen(network, addr2)
223 - if err != nil {
224 - t.Fatal(err)
225 - continue
226 - }
227 - defer l2.Close()
228 - t.Log("listening", l2.Addr())
229 -
230 - go acceptAndEcho(l1)
231 - go acceptAndEcho(l2)
232 -
233 - c1, err := Dial(network, l1.Addr().String(), l2.Addr().String())
234 - if err != nil {
235 - t.Fatal(err, network, l1.Addr().String(), l2.Addr().String())
236 - continue
237 - }
238 - defer c1.Close()
239 - t.Log("dialed", c1, c1.LocalAddr(), c1.RemoteAddr())
240 -
241 - if getPort(l1.Addr()) != getPort(c1.LocalAddr()) {
242 - t.Fatal("addrs should match", l1.Addr(), c1.LocalAddr())
243 - }
244 -
245 - if getPort(l2.Addr()) != getPort(c1.RemoteAddr()) {
246 - t.Fatal("addrs should match", l2.Addr(), c1.RemoteAddr())
247 - }
248 -
249 - hello1 := []byte("hello world")
250 - hello2 := make([]byte, len(hello1))
251 - if _, err := c1.Write(hello1); err != nil {
252 - t.Fatal(err)
253 - continue
254 - }
255 -
256 - if _, err := c1.Read(hello2); err != nil {
257 - t.Fatal(err)
258 - continue
259 - }
260 -
261 - if !bytes.Equal(hello1, hello2) {
262 - t.Fatal("echo failed", string(hello1), "!=", string(hello2))
263 - }
264 - t.Log("echoed", string(hello2))
265 - c1.Close()
266 - }
267 -}
268 -
269 -func TestStreamListenDialSamePortStressManyMsgs(t *testing.T) {
270 - testCases := [][]string{
271 - []string{"tcp", "127.0.0.1:0"},
272 - []string{"tcp4", "127.0.0.1:0"},
273 - []string{"tcp6", "[::]:0"},
274 - }
275 -
276 - for _, tcase := range testCases {
277 - subestStreamListenDialSamePortStress(t, tcase[0], tcase[1], 2, 1000)
278 - }
279 -}
280 -
281 -func TestStreamListenDialSamePortStressManyNodes(t *testing.T) {
282 - testCases := [][]string{
283 - []string{"tcp", "127.0.0.1:0"},
284 - []string{"tcp4", "127.0.0.1:0"},
285 - []string{"tcp6", "[::]:0"},
286 - }
287 -
288 - for _, tcase := range testCases {
289 - subestStreamListenDialSamePortStress(t, tcase[0], tcase[1], 50, 1)
290 - }
291 -}
292 -
293 -func TestStreamListenDialSamePortStressManyMsgsManyNodes(t *testing.T) {
294 - testCases := [][]string{
295 - []string{"tcp", "127.0.0.1:0"},
296 - []string{"tcp4", "127.0.0.1:0"},
297 - []string{"tcp6", "[::]:0"},
298 - }
299 -
300 - for _, tcase := range testCases {
301 - subestStreamListenDialSamePortStress(t, tcase[0], tcase[1], 50, 100)
302 - }
303 -}
304 -
305 -func subestStreamListenDialSamePortStress(t *testing.T, network, addr string, nodes int, msgs int) {
306 - t.Logf("testing %s:%s %d nodes %d msgs", network, addr, nodes, msgs)
307 -
308 - var ls []net.Listener
309 - for i := 0; i < nodes; i++ {
310 - l, err := Listen(network, addr)
311 - if err != nil {
312 - t.Fatal(err)
313 - }
314 - defer l.Close()
315 - go acceptAndEcho(l)
316 - ls = append(ls, l)
317 - t.Logf("listening %s", l.Addr())
318 - }
319 -
320 - // connect them all
321 - var cs []net.Conn
322 - for i := 0; i < nodes; i++ {
323 - for j := 0; j < i; j++ {
324 - if i == j {
325 - continue // cannot do self.
326 - }
327 -
328 - ia := ls[i].Addr().String()
329 - ja := ls[j].Addr().String()
330 - c, err := Dial(network, ia, ja)
331 - if err != nil {
332 - t.Fatal(network, ia, ja, err)
333 - }
334 - defer c.Close()
335 - cs = append(cs, c)
336 - t.Logf("dialed %s --> %s", c.LocalAddr(), c.RemoteAddr())
337 - }
338 - }
339 -
340 - errs := make(chan error)
341 -
342 - send := func(c net.Conn, buf []byte) {
343 - if _, err := c.Write(buf); err != nil {
344 - errs <- err
345 - }
346 - }
347 -
348 - recv := func(c net.Conn, buf []byte) {
349 - buf2 := make([]byte, len(buf))
350 - if _, err := c.Read(buf2); err != nil {
351 - errs <- err
352 - }
353 - if !bytes.Equal(buf, buf2) {
354 - errs <- fmt.Errorf("recv failure: %s <--> %s -- %s %s", c.RemoteAddr(), c.LocalAddr(), buf, buf2)
355 - }
356 - }
357 -
358 - t.Logf("sending %d msgs per conn", msgs)
359 - go func() {
360 - var wg sync.WaitGroup
361 - for _, c := range cs {
362 - wg.Add(1)
363 - go func(c net.Conn) {
364 - defer wg.Done()
365 - for i := 0; i < msgs; i++ {
366 - msg := []byte(fmt.Sprintf("message %d", i))
367 - send(c, msg)
368 - recv(c, msg)
369 - }
370 - }(c)
371 - }
372 - wg.Wait()
373 - close(errs)
374 - }()
375 -
376 - for err := range errs {
377 - if err != nil {
378 - t.Error(err)
379 - }
380 - }
381 -}
382 -
383 -func TestPacketListenDialSamePort(t *testing.T) {
384 -
385 - any := [][]string{
386 - []string{"udp", "0.0.0.0:0", "0.0.0.0:0"},
387 - []string{"udp4", "0.0.0.0:0", "0.0.0.0:0"},
388 - []string{"udp6", "[::]:0", "[::]:0"},
389 -
390 - []string{"udp", "127.0.0.1:0", "127.0.0.1:0"},
391 - []string{"udp4", "127.0.0.1:0", "127.0.0.1:0"},
392 - []string{"udp6", "[::1]:0", "[::1]:0"},
393 - }
394 -
395 - specific := [][]string{
396 - []string{"udp", "127.0.0.1:5670", "127.0.0.1:5671"},
397 - []string{"udp4", "127.0.0.1:5672", "127.0.0.1:5673"},
398 - []string{"udp6", "[::1]:5673", "[::1]:5674"},
399 - }
400 -
401 - testCases := any
402 - if !CI() {
403 - testCases = append(testCases, specific...)
404 - }
405 -
406 - for _, tcase := range testCases {
407 - t.Log("testing", tcase)
408 - network := tcase[0]
409 - addr1 := tcase[1]
410 - addr2 := tcase[2]
411 -
412 - l1, err := ListenPacket(network, addr1)
413 - if err != nil {
414 - t.Fatal(err)
415 - continue
416 - }
417 - defer l1.Close()
418 - t.Log("listening", l1.LocalAddr())
419 -
420 - l2, err := ListenPacket(network, addr2)
421 - if err != nil {
422 - t.Fatal(err)
423 - continue
424 - }
425 - defer l2.Close()
426 - t.Log("listening", l2.LocalAddr())
427 -
428 - go packetEcho(l1)
429 - go packetEcho(l2)
430 -
431 - c1, err := Dial(network, l1.LocalAddr().String(), l2.LocalAddr().String())
432 - if err != nil {
433 - t.Fatal(err)
434 - continue
435 - }
436 - defer c1.Close()
437 - t.Log("dialed", c1.LocalAddr(), c1.RemoteAddr())
438 -
439 - if getPort(l1.LocalAddr()) != getPort(c1.LocalAddr()) {
440 - t.Fatal("addrs should match", l1.LocalAddr(), c1.LocalAddr())
441 - }
442 -
443 - if getPort(l2.LocalAddr()) != getPort(c1.RemoteAddr()) {
444 - t.Fatal("addrs should match", l2.LocalAddr(), c1.RemoteAddr())
445 - }
446 -
447 - hello1 := []byte("hello world")
448 - hello2 := make([]byte, len(hello1))
449 - if _, err := c1.Write(hello1); err != nil {
450 - t.Fatal(err)
451 - continue
452 - }
453 -
454 - if _, err := c1.Read(hello2); err != nil {
455 - t.Fatal(err)
456 - continue
457 - }
458 -
459 - if !bytes.Equal(hello1, hello2) {
460 - t.Fatal("echo failed", string(hello1), "!=", string(hello2))
461 - }
462 - t.Log("echoed", string(hello2))
463 - }
464 -}
465 -
466 -func TestDialRespectsTimeout(t *testing.T) {
467 -
468 - testCases := [][]string{
469 - []string{"tcp", "127.0.0.1:6780", "1.2.3.4:6781"},
470 - []string{"tcp4", "127.0.0.1:6782", "1.2.3.4:6783"},
471 - []string{"tcp6", "[::1]:6784", "[::2]:6785"},
472 - }
473 -
474 - timeout := 50 * time.Millisecond
475 -
476 - for _, tcase := range testCases {
477 - network := tcase[0]
478 - laddr := tcase[1]
479 - raddr := tcase[2]
480 -
481 - // l, err := Listen(network, raddr)
482 - // if err != nil {
483 - // t.Error("without a listener it wont work")
484 - // continue
485 - // }
486 - // defer l.Close()
487 -
488 - nladdr, err := ResolveAddr(network, laddr)
489 - if err != nil {
490 - t.Error("failed to resolve addr", network, laddr, err)
491 - continue
492 - }
493 - t.Log("testing", network, nladdr, raddr)
494 -
495 - d := Dialer{
496 - D: net.Dialer{
497 - LocalAddr: nil,
498 - Timeout: timeout,
499 - },
500 - }
501 -
502 - errs := make(chan error)
503 - go func() {
504 - c, err := d.Dial(network, raddr)
505 - if err == nil {
506 - c.Close()
507 - errs <- errors.New("should've not connected")
508 - return
509 - }
510 - close(errs) // success!
511 - }()
512 -
513 - ErrDrain:
514 - select {
515 - case <-time.After(5 * time.Second):
516 - t.Fatal("took too long")
517 - case err, more := <-errs:
518 - if !more {
519 - break
520 - }
521 - t.Error(err)
522 - goto ErrDrain
523 - }
524 -
525 - }
526 -}
527 -
528 -func TestUnixNotSupported(t *testing.T) {
529 -
530 - testCases := [][]string{
531 - []string{"unix", "/tmp/foo"},
532 - }
533 -
534 - for _, tcase := range testCases {
535 - network := tcase[0]
536 - addr := tcase[1]
537 - t.Log("testing", network, addr)
538 -
539 - l, err := Listen(network, addr)
540 - if err == nil {
541 - l.Close()
542 - t.Fatal("unix supported")
543 - continue
544 - }
545 - }
546 -}
547 -
548 -func TestOpenFDs(t *testing.T) {
549 - // this is a totally ad-hoc limit. test harnesses may add fds.
550 - // but if this is really much higher than 20, there's obviously leaks.
551 - limit := 20
552 - start := time.Now()
553 - for countOpenFiles(t) > limit {
554 - <-time.After(time.Second)
555 - t.Log("open fds:", countOpenFiles(t))
556 - if time.Now().Sub(start) > (time.Second * 15) {
557 - t.Error("fd leak!")
558 - }
559 - }
560 -}
561 -
562 -func countOpenFiles(t *testing.T) int {
563 - out, err := exec.Command("/bin/sh", "-c", fmt.Sprintf("lsof -p %v", os.Getpid())).Output()
564 - if err != nil {
565 - t.Fatal(err)
566 - }
567 - return bytes.Count(out, []byte("\n"))
568 -}
569 -
570 -func getPort(a net.Addr) string {
571 - if a == nil {
572 - return ""
573 - }
574 - s := strings.Split(a.String(), ":")
575 - if len(s) > 1 {
576 - return s[1]
577 - }
578 - return ""
579 -}
Godeps/_workspace/src/github.com/jbenet/go-reuseport/test/.gitignore deleted
-1
@@ -1 +0,0 @@
1 -test
Godeps/_workspace/src/github.com/jbenet/go-reuseport/test/main.go deleted
-71
@@ -1,71 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 - "io"
6 - "net"
7 - "os"
8 -
9 - reuse "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-reuseport"
10 - resolve "gx/ipfs/Qma73Sqt13DzHzveZ667BBfraM7MuMrPepUXjmv812JhRS/go-net-resolve-addr"
11 -)
12 -
13 -func main() {
14 -
15 - l1, err := reuse.Listen("tcp", "0.0.0.0:11111")
16 - maybeDie(err)
17 - fmt.Printf("listening on %s\n", l1.Addr())
18 -
19 - l2, err := reuse.Listen("tcp", "0.0.0.0:22222")
20 - maybeDie(err)
21 - fmt.Printf("listening on %s\n", l2.Addr())
22 -
23 - a1, err := resolve.ResolveAddr("dial", "tcp", "127.0.0.1:11111")
24 - maybeDie(err)
25 -
26 - a3, err := resolve.ResolveAddr("dial", "tcp", "127.0.0.1:33333")
27 - maybeDie(err)
28 -
29 - d1 := reuse.Dialer{net.Dialer{LocalAddr: a1}}
30 - d2 := reuse.Dialer{net.Dialer{LocalAddr: a3}}
31 -
32 - go func() {
33 - l2to1foo, err := l2.Accept()
34 - maybeDie(err)
35 - fmt.Printf("%s accepted conn from %s\n", addrStr(l2.Addr()), addrStr(l2to1foo.RemoteAddr()))
36 -
37 - fmt.Println("safe")
38 -
39 - l1to2bar, err := l1.Accept()
40 - maybeDie(err)
41 - fmt.Printf("%s accepted conn from %s\n", addrStr(l1.Addr()), addrStr(l1to2bar.RemoteAddr()))
42 -
43 - io.Copy(l1to2bar, l2to1foo)
44 - }()
45 -
46 - d1to2foo, err := d1.Dial("tcp4", "127.0.0.1:22222")
47 - maybeDie(err)
48 - fmt.Printf("dialing from %s to %s\n", d1.D.LocalAddr, "127.0.0.1:22222")
49 -
50 - d2to1bar, err := d2.Dial("tcp4", "127.0.0.1:11111")
51 - maybeDie(err)
52 - fmt.Printf("dialing from %s to %s\n", d2.D.LocalAddr, "127.0.0.1:11111")
53 -
54 - go io.Copy(d1to2foo, os.Stdin)
55 - io.Copy(os.Stdout, d2to1bar)
56 -}
57 -
58 -func die(err error) {
59 - fmt.Fprintf(os.Stderr, "%s\n", err)
60 - os.Exit(-1)
61 -}
62 -
63 -func maybeDie(err error) {
64 - if err != nil {
65 - die(err)
66 - }
67 -}
68 -
69 -func addrStr(a net.Addr) string {
70 - return fmt.Sprintf("%s/%s", a.Network(), a)
71 -}
Godeps/_workspace/src/github.com/jbenet/go-sockaddr/net/net.go deleted
-341
@@ -1,341 +0,0 @@
1 -// package sockaddrnet provides conversions between net.Addr and syscall.Sockaddr
2 -package sockaddrnet
3 -
4 -import (
5 - "net"
6 - "syscall"
7 -)
8 -
9 -// NetAddrAF returns the syscall AF_* type for a given net.Addr
10 -// returns AF_UNSPEC if unknown
11 -func NetAddrAF(addr net.Addr) int {
12 - switch addr := addr.(type) {
13 - case *net.IPAddr:
14 - return IPAF(addr.IP)
15 -
16 - case *net.TCPAddr:
17 - return IPAF(addr.IP)
18 -
19 - case *net.UDPAddr:
20 - return IPAF(addr.IP)
21 -
22 - case *net.UnixAddr:
23 - return AF_UNIX
24 -
25 - default:
26 - return AF_UNSPEC
27 - }
28 -}
29 -
30 -// IPAF returns the syscall AF_* type for a given IP address
31 -// returns AF_UNSPEC if unknown
32 -func IPAF(ip net.IP) int {
33 - switch {
34 - case ip.To4() != nil:
35 - return AF_INET
36 -
37 - case ip.To16() != nil:
38 - return AF_INET6
39 -
40 - default:
41 - return AF_UNSPEC
42 - }
43 -}
44 -
45 -// NetAddrIPPROTO returns the syscall IPPROTO_* type for a given net.Addr
46 -// returns -1 if protocol unknown
47 -func NetAddrIPPROTO(addr net.Addr) int {
48 - switch addr := addr.(type) {
49 - case *net.IPAddr:
50 - switch {
51 - default:
52 - return IPPROTO_IP
53 -
54 - case addr.IP.To4() != nil:
55 - return IPPROTO_IPV4
56 -
57 - case addr.IP.To16() != nil:
58 - return IPPROTO_IPV6
59 - }
60 -
61 - case *net.TCPAddr:
62 - return IPPROTO_TCP
63 -
64 - case *net.UDPAddr:
65 - return IPPROTO_UDP
66 -
67 - default:
68 - return -1
69 - }
70 -}
71 -
72 -// NetAddrSOCK returns the syscall SOCK_* type for a given net.Addr
73 -// returns 0 if type unknown
74 -func NetAddrSOCK(addr net.Addr) int {
75 - switch addr := addr.(type) {
76 - case *net.IPAddr:
77 - return SOCK_DGRAM
78 - case *net.TCPAddr:
79 - return SOCK_STREAM
80 - case *net.UDPAddr:
81 - return SOCK_DGRAM
82 - case *net.UnixAddr:
83 - switch addr.Net {
84 - default:
85 - return 0
86 - case "unix":
87 - return SOCK_STREAM
88 - case "unixgram":
89 - return SOCK_DGRAM
90 - case "unixpacket":
91 - return SOCK_SEQPACKET
92 - }
93 - default:
94 - return 0
95 - }
96 -}
97 -
98 -// NetAddrToSockaddr converts a net.Addr to a syscall.Sockaddr.
99 -// Returns nil if the input is invalid or conversion is not possible.
100 -func NetAddrToSockaddr(addr net.Addr) syscall.Sockaddr {
101 - switch addr := addr.(type) {
102 - case *net.IPAddr:
103 - return IPAddrToSockaddr(addr)
104 - case *net.TCPAddr:
105 - return TCPAddrToSockaddr(addr)
106 - case *net.UDPAddr:
107 - return UDPAddrToSockaddr(addr)
108 - case *net.UnixAddr:
109 - sa, _ := UnixAddrToSockaddr(addr)
110 - return sa
111 - default:
112 - return nil
113 - }
114 -}
115 -
116 -// IPAndZoneToSockaddr converts a net.IP (with optional IPv6 Zone) to a syscall.Sockaddr
117 -// Returns nil if conversion fails.
118 -func IPAndZoneToSockaddr(ip net.IP, zone string) syscall.Sockaddr {
119 - switch {
120 - case len(ip) < net.IPv4len: // default to IPv4
121 - buf := [4]byte{0, 0, 0, 0}
122 - return &syscall.SockaddrInet4{Addr: buf}
123 -
124 - case ip.To4() != nil:
125 - var buf [4]byte
126 - copy(buf[:], ip[12:16]) // last 4 bytes
127 - return &syscall.SockaddrInet4{Addr: buf}
128 -
129 - case ip.To16() != nil:
130 - var buf [16]byte
131 - copy(buf[:], ip)
132 - return &syscall.SockaddrInet6{Addr: buf, ZoneId: uint32(IP6ZoneToInt(zone))}
133 - }
134 - panic("should be unreachable")
135 -}
136 -
137 -// IPAddrToSockaddr converts a net.IPAddr to a syscall.Sockaddr.
138 -// Returns nil if conversion fails.
139 -func IPAddrToSockaddr(addr *net.IPAddr) syscall.Sockaddr {
140 - return IPAndZoneToSockaddr(addr.IP, addr.Zone)
141 -}
142 -
143 -// TCPAddrToSockaddr converts a net.TCPAddr to a syscall.Sockaddr.
144 -// Returns nil if conversion fails.
145 -func TCPAddrToSockaddr(addr *net.TCPAddr) syscall.Sockaddr {
146 - sa := IPAndZoneToSockaddr(addr.IP, addr.Zone)
147 - switch sa := sa.(type) {
148 - case *syscall.SockaddrInet4:
149 - sa.Port = addr.Port
150 - return sa
151 - case *syscall.SockaddrInet6:
152 - sa.Port = addr.Port
153 - return sa
154 - default:
155 - return nil
156 - }
157 -}
158 -
159 -// UDPAddrToSockaddr converts a net.UDPAddr to a syscall.Sockaddr.
160 -// Returns nil if conversion fails.
161 -func UDPAddrToSockaddr(addr *net.UDPAddr) syscall.Sockaddr {
162 - sa := IPAndZoneToSockaddr(addr.IP, addr.Zone)
163 - switch sa := sa.(type) {
164 - case *syscall.SockaddrInet4:
165 - sa.Port = addr.Port
166 - return sa
167 - case *syscall.SockaddrInet6:
168 - sa.Port = addr.Port
169 - return sa
170 - default:
171 - return nil
172 - }
173 -}
174 -
175 -// UnixAddrToSockaddr converts a net.UnixAddr to a syscall.Sockaddr, and returns
176 -// the type (syscall.SOCK_STREAM, syscall.SOCK_DGRAM, syscall.SOCK_SEQPACKET)
177 -// Returns (nil, 0) if conversion fails.
178 -func UnixAddrToSockaddr(addr *net.UnixAddr) (syscall.Sockaddr, int) {
179 - t := 0
180 - switch addr.Net {
181 - case "unix":
182 - t = syscall.SOCK_STREAM
183 - case "unixgram":
184 - t = syscall.SOCK_DGRAM
185 - case "unixpacket":
186 - t = syscall.SOCK_SEQPACKET
187 - default:
188 - return nil, 0
189 - }
190 - return &syscall.SockaddrUnix{Name: addr.Name}, t
191 -}
192 -
193 -// IPAndZoneToSockaddr converts a net.IP (with optional IPv6 Zone) to a syscall.Sockaddr
194 -// Returns nil if conversion fails.
195 -func SockaddrToIPAndZone(sa syscall.Sockaddr) (net.IP, string) {
196 - switch sa := sa.(type) {
197 - case *syscall.SockaddrInet4:
198 - ip := make([]byte, 16)
199 - copy(ip[12:16], sa.Addr[:])
200 - return ip, ""
201 -
202 - case *syscall.SockaddrInet6:
203 - ip := make([]byte, 16)
204 - copy(ip, sa.Addr[:])
205 - return ip, IP6ZoneToString(int(sa.ZoneId))
206 - }
207 - return nil, ""
208 -}
209 -
210 -// SockaddrToIPAddr converts a syscall.Sockaddr to a net.IPAddr
211 -// Returns nil if conversion fails.
212 -func SockaddrToIPAddr(sa syscall.Sockaddr) *net.IPAddr {
213 - ip, zone := SockaddrToIPAndZone(sa)
214 - switch sa.(type) {
215 - case *syscall.SockaddrInet4:
216 - return &net.IPAddr{IP: ip}
217 - case *syscall.SockaddrInet6:
218 - return &net.IPAddr{IP: ip, Zone: zone}
219 - }
220 - return nil
221 -}
222 -
223 -// SockaddrToTCPAddr converts a syscall.Sockaddr to a net.TCPAddr
224 -// Returns nil if conversion fails.
225 -func SockaddrToTCPAddr(sa syscall.Sockaddr) *net.TCPAddr {
226 - ip, zone := SockaddrToIPAndZone(sa)
227 - switch sa := sa.(type) {
228 - case *syscall.SockaddrInet4:
229 - return &net.TCPAddr{IP: ip, Port: sa.Port}
230 - case *syscall.SockaddrInet6:
231 - return &net.TCPAddr{IP: ip, Port: sa.Port, Zone: zone}
232 - }
233 - return nil
234 -}
235 -
236 -// SockaddrToUDPAddr converts a syscall.Sockaddr to a net.UDPAddr
237 -// Returns nil if conversion fails.
238 -func SockaddrToUDPAddr(sa syscall.Sockaddr) *net.UDPAddr {
239 - ip, zone := SockaddrToIPAndZone(sa)
240 - switch sa := sa.(type) {
241 - case *syscall.SockaddrInet4:
242 - return &net.UDPAddr{IP: ip, Port: sa.Port}
243 - case *syscall.SockaddrInet6:
244 - return &net.UDPAddr{IP: ip, Port: sa.Port, Zone: zone}
245 - }
246 - return nil
247 -}
248 -
249 -// from: go/src/pkg/net/unixsock_posix.go
250 -
251 -// SockaddrToUnixAddr converts a syscall.Sockaddr to a net.UnixAddr
252 -// Returns nil if conversion fails.
253 -func SockaddrToUnixAddr(sa syscall.Sockaddr) *net.UnixAddr {
254 - if s, ok := sa.(*syscall.SockaddrUnix); ok {
255 - return &net.UnixAddr{Name: s.Name, Net: "unix"}
256 - }
257 - return nil
258 -}
259 -
260 -// SockaddrToUnixgramAddr converts a syscall.Sockaddr to a net.UnixAddr
261 -// Returns nil if conversion fails.
262 -func SockaddrToUnixgramAddr(sa syscall.Sockaddr) *net.UnixAddr {
263 - if s, ok := sa.(*syscall.SockaddrUnix); ok {
264 - return &net.UnixAddr{Name: s.Name, Net: "unixgram"}
265 - }
266 - return nil
267 -}
268 -
269 -// SockaddrToUnixpacketAddr converts a syscall.Sockaddr to a net.UnixAddr
270 -// Returns nil if conversion fails.
271 -func SockaddrToUnixpacketAddr(sa syscall.Sockaddr) *net.UnixAddr {
272 - if s, ok := sa.(*syscall.SockaddrUnix); ok {
273 - return &net.UnixAddr{Name: s.Name, Net: "unixpacket"}
274 - }
275 - return nil
276 -}
277 -
278 -// from: go/src/pkg/net/ipsock.go
279 -
280 -// IP6ZoneToString converts an IP6 Zone syscall int to a net string
281 -// returns "" if zone is 0
282 -func IP6ZoneToString(zone int) string {
283 - if zone == 0 {
284 - return ""
285 - }
286 - if ifi, err := net.InterfaceByIndex(zone); err == nil {
287 - return ifi.Name
288 - }
289 - return itod(uint(zone))
290 -}
291 -
292 -// IP6ZoneToInt converts an IP6 Zone net string to a syscall int
293 -// returns 0 if zone is ""
294 -func IP6ZoneToInt(zone string) int {
295 - if zone == "" {
296 - return 0
297 - }
298 - if ifi, err := net.InterfaceByName(zone); err == nil {
299 - return ifi.Index
300 - }
301 - n, _, _ := dtoi(zone, 0)
302 - return n
303 -}
304 -
305 -// from: go/src/pkg/net/parse.go
306 -
307 -// Convert i to decimal string.
308 -func itod(i uint) string {
309 - if i == 0 {
310 - return "0"
311 - }
312 -
313 - // Assemble decimal in reverse order.
314 - var b [32]byte
315 - bp := len(b)
316 - for ; i > 0; i /= 10 {
317 - bp--
318 - b[bp] = byte(i%10) + '0'
319 - }
320 -
321 - return string(b[bp:])
322 -}
323 -
324 -// Bigger than we need, not too big to worry about overflow
325 -const big = 0xFFFFFF
326 -
327 -// Decimal to integer starting at &s[i0].
328 -// Returns number, new offset, success.
329 -func dtoi(s string, i0 int) (n int, i int, ok bool) {
330 - n = 0
331 - for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
332 - n = n*10 + int(s[i]-'0')
333 - if n >= big {
334 - return 0, i, false
335 - }
336 - }
337 - if i == i0 {
338 - return 0, i, false
339 - }
340 - return n, i, true
341 -}
Godeps/_workspace/src/github.com/jbenet/go-sockaddr/net/net_bsd.go deleted
-24
@@ -1,24 +0,0 @@
1 -// +build darwin dragonfly freebsd netbsd openbsd
2 -
3 -package sockaddrnet
4 -
5 -import (
6 - "syscall"
7 -)
8 -
9 -const (
10 - AF_INET = syscall.AF_INET
11 - AF_INET6 = syscall.AF_INET6
12 - AF_UNIX = syscall.AF_UNIX
13 - AF_UNSPEC = syscall.AF_UNSPEC
14 -
15 - IPPROTO_IP = syscall.IPPROTO_IP
16 - IPPROTO_IPV4 = syscall.IPPROTO_IPV4
17 - IPPROTO_IPV6 = syscall.IPPROTO_IPV6
18 - IPPROTO_TCP = syscall.IPPROTO_TCP
19 - IPPROTO_UDP = syscall.IPPROTO_UDP
20 -
21 - SOCK_DGRAM = syscall.SOCK_DGRAM
22 - SOCK_STREAM = syscall.SOCK_STREAM
23 - SOCK_SEQPACKET = syscall.SOCK_SEQPACKET
24 -)
Godeps/_workspace/src/github.com/jbenet/go-sockaddr/net/net_linux.go deleted
-22
@@ -1,22 +0,0 @@
1 -package sockaddrnet
2 -
3 -import (
4 - "syscall"
5 -)
6 -
7 -const (
8 - AF_INET = syscall.AF_INET
9 - AF_INET6 = syscall.AF_INET6
10 - AF_UNIX = syscall.AF_UNIX
11 - AF_UNSPEC = syscall.AF_UNSPEC
12 -
13 - IPPROTO_IP = syscall.IPPROTO_IP
14 - IPPROTO_IPV4 = syscall.IPPROTO_IPIP
15 - IPPROTO_IPV6 = syscall.IPPROTO_IPV6
16 - IPPROTO_TCP = syscall.IPPROTO_TCP
17 - IPPROTO_UDP = syscall.IPPROTO_UDP
18 -
19 - SOCK_DGRAM = syscall.SOCK_DGRAM
20 - SOCK_STREAM = syscall.SOCK_STREAM
21 - SOCK_SEQPACKET = syscall.SOCK_SEQPACKET
22 -)
Godeps/_workspace/src/github.com/jbenet/go-sockaddr/net/net_windows.go deleted
-22
@@ -1,22 +0,0 @@
1 -package sockaddrnet
2 -
3 -import (
4 - "syscall"
5 -)
6 -
7 -const (
8 - AF_INET = syscall.AF_INET
9 - AF_INET6 = syscall.AF_INET6
10 - AF_UNIX = syscall.AF_UNIX
11 - AF_UNSPEC = syscall.AF_UNSPEC
12 -
13 - IPPROTO_IP = syscall.IPPROTO_IP
14 - IPPROTO_IPV4 = syscall.IPPROTO_IPV4
15 - IPPROTO_IPV6 = syscall.IPPROTO_IPV6
16 - IPPROTO_TCP = syscall.IPPROTO_TCP
17 - IPPROTO_UDP = syscall.IPPROTO_UDP
18 -
19 - SOCK_DGRAM = syscall.SOCK_DGRAM
20 - SOCK_STREAM = syscall.SOCK_STREAM
21 - SOCK_SEQPACKET = syscall.SOCK_SEQPACKET
22 -)
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/.travis.yml deleted
-11
@@ -1,11 +0,0 @@
1 -language: go
2 -
3 -go:
4 - - 1.3
5 - - 1.4
6 - - release
7 - - tip
8 -
9 -script:
10 - - go test ./...
11 - # - go test -race -cpu=5 ./...
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/Godeps/Godeps.json deleted
-29
@@ -1,29 +0,0 @@
1 -{
2 - "ImportPath": "github.com/jbenet/go-stream-muxer",
3 - "GoVersion": "go1.4.2",
4 - "Packages": [
5 - "./..."
6 - ],
7 - "Deps": [
8 - {
9 - "ImportPath": "github.com/docker/spdystream",
10 - "Rev": "b2c3287865f3ad6aa22821ddb7b4692b896ac207"
11 - },
12 - {
13 - "ImportPath": "github.com/hashicorp/yamux",
14 - "Rev": "b2e55852ddaf823a85c67f798080eb7d08acd71d"
15 - },
16 - {
17 - "ImportPath": "github.com/inconshreveable/muxado",
18 - "Rev": "f693c7e88ba316d1a0ae3e205e22a01aa3ec2848"
19 - },
20 - {
21 - "ImportPath": "github.com/whyrusleeping/go-multiplex",
22 - "Rev": "474b9aebeb391746f304ddf7c764a5da12319857"
23 - },
24 - {
25 - "ImportPath": "github.com/whyrusleeping/go-multistream",
26 - "Rev": "31bb014803a6eba2261bda5593e42c016a5f33bb"
27 - }
28 - ]
29 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/Godeps/Readme deleted
-5
@@ -1,5 +0,0 @@
1 -This directory tree is generated automatically by godep.
2 -
3 -Please do not edit.
4 -
5 -See https://github.com/tools/godep for more information.
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/LICENSE deleted
-21
@@ -1,21 +0,0 @@
1 -The MIT License (MIT)
2 -
3 -Copyright (c) 2014 Juan Batiz-Benet
4 -
5 -Permission is hereby granted, free of charge, to any person obtaining a copy
6 -of this software and associated documentation files (the "Software"), to deal
7 -in the Software without restriction, including without limitation the rights
8 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 -copies of the Software, and to permit persons to whom the Software is
10 -furnished to do so, subject to the following conditions:
11 -
12 -The above copyright notice and this permission notice shall be included in
13 -all copies or substantial portions of the Software.
14 -
15 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 -THE SOFTWARE.
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/Makefile deleted
-15
@@ -1,15 +0,0 @@
1 -
2 -godep:
3 - go get github.com/tools/godep
4 -
5 -vendor: godep
6 - godep save -r ./...
7 -
8 -build:
9 - go build ./...
10 -
11 -test:
12 - go test ./...
13 -
14 -test_race:
15 - go test -race -cpu 5 ./...
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/README.md deleted
-98
@@ -1,98 +0,0 @@
1 -# go-stream-muxer - generalized stream multiplexing
2 -
3 -
4 -go-stream-muxer is a common interface for stream muxers, with common tests. It wraps other stream muxers (like [muxado](https://github.com/inconshreveable/muxado), [spdystream](https://github.com/docker/spdystream) and [yamux](https://github.com/hashicorp/yamux)).
5 -
6 -[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) [![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
7 -
8 -> A test suite and interface you can use to implement a stream muxer.
9 -
10 -### Godoc: https://godoc.org/github.com/jbenet/go-stream-muxer
11 -
12 -## Implementations
13 -
14 -* [yamux](yamux)
15 -* [muxado](muxado)
16 -* [multiplex](multiplex)
17 -* [spdystream](spdystream)
18 -
19 -## Badge
20 -
21 -Include this badge in your readme if you make a new module that uses abstract-stream-muxer API.
22 -
23 -![](img/badge.png)
24 -
25 -## Client example
26 -
27 -```go
28 -import (
29 - "net"
30 - "fmt"
31 - "io"
32 - ymux "github.com/jbenet/go-stream-muxer/yamux"
33 - smux "github.com/jbenet/go-stream-muxer"
34 -)
35 -
36 -func dial() {
37 - nconn, _ := net.Dial("tcp", "localhost:1234")
38 - sconn, _ := ymux.DefaultTransport.NewConn(nconn, false) // false == client
39 -
40 - go sconn.Serve(func(smux.Stream) {}) // no-op
41 -
42 - s1, _ := sconn.OpenStream()
43 - s1.Write([]byte("hello"))
44 -
45 - s2, _ := sconn.OpenStream()
46 - s2.Write([]byte("world"))
47 -
48 - length := 20
49 - buf2 := make([]byte, length)
50 - fmt.Printf("reading %d bytes from stream (echoed)\n", length)
51 -
52 - s1.Read(buf2)
53 -
54 - fmt.Printf("received %s as a response\n", string(buf2))
55 -
56 - s3, _ := sconn.OpenStream()
57 - io.Copy(s3, os.Stdin)
58 -}
59 -```
60 -
61 -## Server example
62 -
63 -```go
64 -import (
65 - "net"
66 - "fmt"
67 - "io"
68 - ymux "github.com/jbenet/go-stream-muxer/yamux"
69 - smux "github.com/jbenet/go-stream-muxer"
70 -)
71 -
72 -func listen() {
73 - tr := ymux.DefaultTransport
74 - l, _ := net.Listen("tcp", "localhost:1234")
75 -
76 - go func() {
77 - for {
78 - c, _ := l.Accept()
79 -
80 - fmt.Println("accepted connection")
81 - sc, _ := tr.NewConn(c, true)
82 -
83 - go sc.Serve(func(s smux.Stream) {
84 - fmt.Println("serving connection")
85 - echoStream(s)
86 - })
87 - }
88 - }()
89 -}
90 -
91 -func echoStream(s smux.Stream) {
92 - defer s.Close()
93 -
94 - fmt.Println("accepted stream")
95 - io.Copy(s, s) // echo everything
96 - fmt.Println("closing stream")
97 -}
98 -```
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/img/badge.png
Binary files a/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/img/badge.png and /dev/null differ
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multiplex/multiplex.go deleted
-56
@@ -1,56 +0,0 @@
1 -package peerstream_multiplex
2 -
3 -import (
4 - "errors"
5 - "net"
6 -
7 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
8 - mp "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-multiplex" // Conn is a connection to a remote peer.
9 -)
10 -
11 -var ErrUseServe = errors.New("not implemented, use Serve")
12 -
13 -type conn struct {
14 - *mp.Multiplex
15 -}
16 -
17 -func (c *conn) Close() error {
18 - return c.Multiplex.Close()
19 -}
20 -
21 -func (c *conn) IsClosed() bool {
22 - return c.Multiplex.IsClosed()
23 -}
24 -
25 -// OpenStream creates a new stream.
26 -func (c *conn) OpenStream() (smux.Stream, error) {
27 - return c.Multiplex.NewStream(), nil
28 -}
29 -
30 -// AcceptStream accepts a stream opened by the other side.
31 -func (c *conn) AcceptStream() (smux.Stream, error) {
32 - return c.Multiplex.Accept()
33 -}
34 -
35 -// Serve starts listening for incoming requests and handles them
36 -// using given StreamHandler
37 -func (c *conn) Serve(handler smux.StreamHandler) {
38 - for {
39 - s, err := c.AcceptStream()
40 - if err != nil {
41 - return
42 - }
43 - go handler(s)
44 - }
45 -}
46 -
47 -// Transport is a go-peerstream transport that constructs
48 -// multiplex-backed connections.
49 -type Transport struct{}
50 -
51 -// DefaultTransport has default settings for multiplex
52 -var DefaultTransport = &Transport{}
53 -
54 -func (t *Transport) NewConn(nc net.Conn, isServer bool) (smux.Conn, error) {
55 - return &conn{mp.NewMultiplex(nc, isServer)}, nil
56 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multiplex/multiplex_test.go deleted
-11
@@ -1,11 +0,0 @@
1 -package peerstream_multiplex
2 -
3 -import (
4 - "testing"
5 -
6 - test "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/test"
7 -)
8 -
9 -func TestMultiplexTransport(t *testing.T) {
10 - test.SubtestAll(t, DefaultTransport)
11 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multistream/multistream.go deleted
-60
@@ -1,60 +0,0 @@
1 -// package multistream implements a peerstream transport using
2 -// go-multistream to select the underlying stream muxer
3 -package multistream
4 -
5 -import (
6 - "net"
7 -
8 - mss "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-multistream"
9 -
10 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
11 - multiplex "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multiplex"
12 - spdy "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/spdystream"
13 - yamux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/yamux"
14 -)
15 -
16 -type transport struct {
17 - mux *mss.MultistreamMuxer
18 -
19 - tpts map[string]smux.Transport
20 -}
21 -
22 -func NewTransport() smux.Transport {
23 - mux := mss.NewMultistreamMuxer()
24 - mux.AddHandler("/multiplex", nil)
25 - mux.AddHandler("/spdystream", nil)
26 - mux.AddHandler("/yamux", nil)
27 -
28 - tpts := map[string]smux.Transport{
29 - "/multiplex": multiplex.DefaultTransport,
30 - "/spdystream": spdy.Transport,
31 - "/yamux": yamux.DefaultTransport,
32 - }
33 -
34 - return &transport{
35 - mux: mux,
36 - tpts: tpts,
37 - }
38 -}
39 -
40 -func (t *transport) NewConn(nc net.Conn, isServer bool) (smux.Conn, error) {
41 - var proto string
42 - if isServer {
43 - selected, _, err := t.mux.Negotiate(nc)
44 - if err != nil {
45 - return nil, err
46 - }
47 - proto = selected
48 - } else {
49 - // prefer yamux
50 - selected, err := mss.SelectOneOf([]string{"/yamux", "/spdystream", "/multiplex"}, nc)
51 - if err != nil {
52 - return nil, err
53 - }
54 - proto = selected
55 - }
56 -
57 - tpt := t.tpts[proto]
58 -
59 - return tpt.NewConn(nc, isServer)
60 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/multistream/multistream_test.go deleted
-11
@@ -1,11 +0,0 @@
1 -package multistream
2 -
3 -import (
4 - "testing"
5 -
6 - test "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/test"
7 -)
8 -
9 -func TestMultiStreamTransport(t *testing.T) {
10 - test.SubtestAll(t, NewTransport())
11 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/muxado/muxado.go deleted
-105
@@ -1,105 +0,0 @@
1 -package peerstream_muxado
2 -
3 -import (
4 - "net"
5 -
6 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
7 - muxado "gx/ipfs/QmaZ9WavcC9EKocNHof8onR8JHci2Qt8AuybkFaxJdr51Q/muxado"
8 -)
9 -
10 -// stream implements smux.Stream using a ss.Stream
11 -type stream struct {
12 - ms muxado.Stream
13 -}
14 -
15 -func (s *stream) muxadoStream() muxado.Stream {
16 - return s.ms
17 -}
18 -
19 -func (s *stream) Read(buf []byte) (int, error) {
20 - return s.ms.Read(buf)
21 -}
22 -
23 -func (s *stream) Write(buf []byte) (int, error) {
24 - return s.ms.Write(buf)
25 -}
26 -
27 -func (s *stream) Close() error {
28 - return s.ms.Close()
29 -}
30 -
31 -// Conn is a connection to a remote peer.
32 -type conn struct {
33 - ms muxado.Session
34 -
35 - closed chan struct{}
36 -}
37 -
38 -func (c *conn) muxadoSession() muxado.Session {
39 - return c.ms
40 -}
41 -
42 -func (c *conn) Close() error {
43 - return c.ms.Close()
44 -}
45 -
46 -func (c *conn) IsClosed() bool {
47 - select {
48 - case <-c.closed:
49 - return true
50 - default:
51 - return false
52 - }
53 -}
54 -
55 -// OpenStream creates a new stream.
56 -func (c *conn) OpenStream() (smux.Stream, error) {
57 - s, err := c.ms.Open()
58 - if err != nil {
59 - return nil, err
60 - }
61 -
62 - return &stream{ms: s}, nil
63 -}
64 -
65 -// AcceptStream accepts a stream opened by the other side.
66 -func (c *conn) AcceptStream() (smux.Stream, error) {
67 - s, err := c.ms.Accept()
68 - if err != nil {
69 - return nil, err
70 - }
71 - return &stream{ms: s}, nil
72 -}
73 -
74 -// Serve starts listening for incoming requests and handles them
75 -// using given StreamHandler
76 -func (c *conn) Serve(handler smux.StreamHandler) {
77 - for { // accept loop
78 - s, err := c.AcceptStream()
79 - if err != nil {
80 - return // err always means closed.
81 - }
82 - go handler(s)
83 - }
84 -}
85 -
86 -type transport struct{}
87 -
88 -// Transport is a go-peerstream transport that constructs
89 -// spdystream-backed connections.
90 -var Transport = transport{}
91 -
92 -func (t transport) NewConn(nc net.Conn, isServer bool) (smux.Conn, error) {
93 - var s muxado.Session
94 - if isServer {
95 - s = muxado.Server(nc)
96 - } else {
97 - s = muxado.Client(nc)
98 - }
99 - cl := make(chan struct{})
100 - go func() {
101 - s.Wait()
102 - close(cl)
103 - }()
104 - return &conn{ms: s, closed: cl}, nil
105 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/muxado/muxado_test.go deleted
-11
@@ -1,11 +0,0 @@
1 -package peerstream_muxado
2 -
3 -import (
4 - "testing"
5 -
6 - test "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/test"
7 -)
8 -
9 -func TestMuxadoTransport(t *testing.T) {
10 - test.SubtestAll(t, Transport)
11 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/muxer.go deleted
-46
@@ -1,46 +0,0 @@
1 -package streammux
2 -
3 -import (
4 - "io"
5 - "net"
6 -)
7 -
8 -// Stream is a bidirectional io pipe within a connection
9 -type Stream interface {
10 - io.Reader
11 - io.Writer
12 - io.Closer
13 -}
14 -
15 -// StreamHandler is a function that handles streams
16 -// (usually those opened by the remote side)
17 -type StreamHandler func(Stream)
18 -
19 -// NoOpHandler do nothing. close streams as soon as they are opened.
20 -var NoOpHandler = func(s Stream) { s.Close() }
21 -
22 -// Conn is a stream-multiplexing connection to a remote peer.
23 -type Conn interface {
24 - io.Closer
25 -
26 - // IsClosed returns whether a connection is fully closed, so it can
27 - // be garbage collected.
28 - IsClosed() bool
29 -
30 - // OpenStream creates a new stream.
31 - OpenStream() (Stream, error)
32 -
33 - // AcceptStream accepts a stream opened by the other side.
34 - AcceptStream() (Stream, error)
35 -
36 - // Serve starts a loop, accepting incoming requests and calling
37 - // `StreamHandler with them. (Use _instead of_ accept. not both.)
38 - Serve(StreamHandler)
39 -}
40 -
41 -// Transport constructs go-stream-muxer compatible connections.
42 -type Transport interface {
43 -
44 - // NewConn constructs a new connection
45 - NewConn(c net.Conn, isServer bool) (Conn, error)
46 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/spdystream/spdystream.go deleted
-123
@@ -1,123 +0,0 @@
1 -package peerstream_spdystream
2 -
3 -import (
4 - "errors"
5 - "net"
6 - "net/http"
7 -
8 - ss "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/docker/spdystream"
9 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
10 -)
11 -
12 -var ErrUseServe = errors.New("not implemented, use Serve")
13 -
14 -// stream implements smux.Stream using a ss.Stream
15 -type stream ss.Stream
16 -
17 -func (s *stream) spdyStream() *ss.Stream {
18 - return (*ss.Stream)(s)
19 -}
20 -
21 -func (s *stream) Read(buf []byte) (int, error) {
22 - return s.spdyStream().Read(buf)
23 -}
24 -
25 -func (s *stream) Write(buf []byte) (int, error) {
26 - return s.spdyStream().Write(buf)
27 -}
28 -
29 -func (s *stream) Close() error {
30 - // Reset is spdystream's full bidirectional close.
31 - // We expose bidirectional close as our `Close`.
32 - // To close only half of the connection, and use other
33 - // spdystream options, just get the stream with:
34 - // ssStream := (*ss.Stream)(stream)
35 - return s.spdyStream().Reset()
36 -}
37 -
38 -// Conn is a connection to a remote peer.
39 -type conn struct {
40 - sc *ss.Connection
41 -
42 - closed chan struct{}
43 -}
44 -
45 -func (c *conn) spdyConn() *ss.Connection {
46 - return c.sc
47 -}
48 -
49 -func (c *conn) Close() error {
50 - err := c.spdyConn().CloseWait()
51 - if !c.IsClosed() {
52 - close(c.closed)
53 - }
54 - return err
55 -}
56 -
57 -func (c *conn) IsClosed() bool {
58 - select {
59 - case <-c.closed:
60 - return true
61 - case <-c.sc.CloseChan():
62 - return true
63 - default:
64 - return false
65 - }
66 -}
67 -
68 -// OpenStream creates a new stream.
69 -func (c *conn) OpenStream() (smux.Stream, error) {
70 - s, err := c.spdyConn().CreateStream(http.Header{
71 - ":method": []string{"GET"}, // this is here for HTTP/SPDY interop
72 - ":path": []string{"/"}, // this is here for HTTP/SPDY interop
73 - }, nil, false)
74 - if err != nil {
75 - return nil, err
76 - }
77 -
78 - // wait for a response before writing. for some reason
79 - // spdystream does not make forward progress unless you do this.
80 - s.Wait()
81 - return (*stream)(s), nil
82 -}
83 -
84 -// AcceptStream accepts a stream opened by the other side.
85 -func (c *conn) AcceptStream() (smux.Stream, error) {
86 - return nil, ErrUseServe
87 -}
88 -
89 -// Serve starts listening for incoming requests and handles them
90 -// using given StreamHandler
91 -func (c *conn) Serve(handler smux.StreamHandler) {
92 - c.spdyConn().Serve(func(s *ss.Stream) {
93 -
94 - // Flow control and backpressure of Opening streams is broken.
95 - // I believe that spdystream has one set of workers that both send
96 - // data AND accept new streams (as it's just more data). there
97 - // is a problem where if the new stream handlers want to throttle,
98 - // they also eliminate the ability to read/write data, which makes
99 - // forward-progress impossible. Thus, throttling this function is
100 - // -- at this moment -- not the solution. Either spdystream must
101 - // change, or we must throttle another way. go-peerstream handles
102 - // every new stream in its own goroutine.
103 - err := s.SendReply(http.Header{}, false)
104 - if err != nil {
105 - // this _could_ error out. not sure how to handle this failure.
106 - // don't return, and let the caller handle a broken stream.
107 - // better than _hiding_ an error.
108 - // return
109 - }
110 - go handler((*stream)(s))
111 - })
112 -}
113 -
114 -type transport struct{}
115 -
116 -// Transport is a go-peerstream transport that constructs
117 -// spdystream-backed connections.
118 -var Transport = transport{}
119 -
120 -func (t transport) NewConn(nc net.Conn, isServer bool) (smux.Conn, error) {
121 - sc, err := ss.NewConnection(nc, isServer)
122 - return &conn{sc: sc, closed: make(chan struct{})}, err
123 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/spdystream/spdystream_test.go deleted
-11
@@ -1,11 +0,0 @@
1 -package peerstream_spdystream
2 -
3 -import (
4 - "testing"
5 -
6 - test "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/test"
7 -)
8 -
9 -func TestSpdyStreamTransport(t *testing.T) {
10 - test.SubtestAll(t, Transport)
11 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/test/ttest.go deleted
-378
@@ -1,378 +0,0 @@
1 -package sm_test
2 -
3 -import (
4 - "bytes"
5 - crand "crypto/rand"
6 - "fmt"
7 - "io"
8 - mrand "math/rand"
9 - "net"
10 - "os"
11 - "reflect"
12 - "runtime"
13 - "runtime/debug"
14 - "sync"
15 - "testing"
16 -
17 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
18 -)
19 -
20 -var randomness []byte
21 -
22 -func init() {
23 - // read 1MB of randomness
24 - randomness = make([]byte, 1<<20)
25 - if _, err := crand.Read(randomness); err != nil {
26 - panic(err)
27 - }
28 -}
29 -
30 -type Options struct {
31 - tr smux.Transport
32 - connNum int
33 - streamNum int
34 - msgNum int
35 - msgMin int
36 - msgMax int
37 -}
38 -
39 -func randBuf(size int) []byte {
40 - n := len(randomness) - size
41 - if size < 1 {
42 - panic(fmt.Errorf("requested too large buffer (%d). max is %d", size, len(randomness)))
43 - }
44 -
45 - start := mrand.Intn(n)
46 - return randomness[start : start+size]
47 -}
48 -
49 -func checkErr(t *testing.T, err error) {
50 - if err != nil {
51 - debug.PrintStack()
52 - t.Fatal(err)
53 - }
54 -}
55 -
56 -func log(s string, v ...interface{}) {
57 - if testing.Verbose() {
58 - fmt.Fprintf(os.Stderr, "> "+s+"\n", v...)
59 - }
60 -}
61 -
62 -func echoStream(s smux.Stream) {
63 - defer s.Close()
64 - log("accepted stream")
65 - io.Copy(&LogWriter{s}, s) // echo everything
66 - log("closing stream")
67 -}
68 -
69 -type LogWriter struct {
70 - W io.Writer
71 -}
72 -
73 -func (lw *LogWriter) Write(buf []byte) (int, error) {
74 - if testing.Verbose() {
75 - log("logwriter: writing %d bytes", len(buf))
76 - }
77 - return lw.W.Write(buf)
78 -}
79 -
80 -func GoServe(t *testing.T, tr smux.Transport, l net.Listener) (done func()) {
81 - closed := make(chan struct{}, 1)
82 -
83 - go func() {
84 - for {
85 - c1, err := l.Accept()
86 - if err != nil {
87 - select {
88 - case <-closed:
89 - return // closed naturally.
90 - default:
91 - checkErr(t, err)
92 - }
93 - }
94 -
95 - log("accepted connection")
96 - sc1, err := tr.NewConn(c1, true)
97 - checkErr(t, err)
98 - go sc1.Serve(echoStream)
99 - }
100 - }()
101 -
102 - return func() {
103 - closed <- struct{}{}
104 - }
105 -}
106 -
107 -func SubtestSimpleWrite(t *testing.T, tr smux.Transport) {
108 - l, err := net.Listen("tcp", "localhost:0")
109 - checkErr(t, err)
110 - log("listening at %s", l.Addr().String())
111 - done := GoServe(t, tr, l)
112 - defer done()
113 -
114 - log("dialing to %s", l.Addr().String())
115 - nc1, err := net.Dial("tcp", l.Addr().String())
116 - checkErr(t, err)
117 - defer nc1.Close()
118 -
119 - log("wrapping conn")
120 - c1, err := tr.NewConn(nc1, false)
121 - checkErr(t, err)
122 - defer c1.Close()
123 -
124 - // serve the outgoing conn, because some muxers assume
125 - // that we _always_ call serve. (this is an error?)
126 - go c1.Serve(smux.NoOpHandler)
127 -
128 - log("creating stream")
129 - s1, err := c1.OpenStream()
130 - checkErr(t, err)
131 - defer s1.Close()
132 -
133 - buf1 := randBuf(4096)
134 - log("writing %d bytes to stream", len(buf1))
135 - _, err = s1.Write(buf1)
136 - checkErr(t, err)
137 -
138 - buf2 := make([]byte, len(buf1))
139 - log("reading %d bytes from stream (echoed)", len(buf2))
140 - _, err = s1.Read(buf2)
141 - checkErr(t, err)
142 -
143 - if string(buf2) != string(buf1) {
144 - t.Error("buf1 and buf2 not equal: %s != %s", string(buf1), string(buf2))
145 - }
146 - log("done")
147 -}
148 -
149 -func SubtestStress(t *testing.T, opt Options) {
150 -
151 - msgsize := 1 << 11
152 - errs := make(chan error, 0) // dont block anything.
153 -
154 - rateLimitN := 5000 // max of 5k funcs, because -race has 8k max.
155 - rateLimitChan := make(chan struct{}, rateLimitN)
156 - for i := 0; i < rateLimitN; i++ {
157 - rateLimitChan <- struct{}{}
158 - }
159 -
160 - rateLimit := func(f func()) {
161 - <-rateLimitChan
162 - f()
163 - rateLimitChan <- struct{}{}
164 - }
165 -
166 - writeStream := func(s smux.Stream, bufs chan<- []byte) {
167 - log("writeStream %p, %d msgNum", s, opt.msgNum)
168 -
169 - for i := 0; i < opt.msgNum; i++ {
170 - buf := randBuf(msgsize)
171 - bufs <- buf
172 - log("%p writing %d bytes (message %d/%d #%x)", s, len(buf), i, opt.msgNum, buf[:3])
173 - if _, err := s.Write(buf); err != nil {
174 - errs <- fmt.Errorf("s.Write(buf): %s", err)
175 - continue
176 - }
177 - }
178 - }
179 -
180 - readStream := func(s smux.Stream, bufs <-chan []byte) {
181 - log("readStream %p, %d msgNum", s, opt.msgNum)
182 -
183 - buf2 := make([]byte, msgsize)
184 - i := 0
185 - for buf1 := range bufs {
186 - i++
187 - log("%p reading %d bytes (message %d/%d #%x)", s, len(buf1), i-1, opt.msgNum, buf1[:3])
188 -
189 - if _, err := io.ReadFull(s, buf2); err != nil {
190 - errs <- fmt.Errorf("io.ReadFull(s, buf2): %s", err)
191 - log("%p failed to read %d bytes (message %d/%d #%x)", s, len(buf1), i-1, opt.msgNum, buf1[:3])
192 - continue
193 - }
194 - if !bytes.Equal(buf1, buf2) {
195 - errs <- fmt.Errorf("buffers not equal (%x != %x)", buf1[:3], buf2[:3])
196 - }
197 - }
198 - }
199 -
200 - openStreamAndRW := func(c smux.Conn) {
201 - log("openStreamAndRW %p, %d opt.msgNum", c, opt.msgNum)
202 -
203 - s, err := c.OpenStream()
204 - if err != nil {
205 - errs <- fmt.Errorf("Failed to create NewStream: %s", err)
206 - return
207 - }
208 -
209 - bufs := make(chan []byte, opt.msgNum)
210 - go func() {
211 - writeStream(s, bufs)
212 - close(bufs)
213 - }()
214 -
215 - readStream(s, bufs)
216 - s.Close()
217 - }
218 -
219 - openConnAndRW := func() {
220 - log("openConnAndRW")
221 -
222 - l, err := net.Listen("tcp", "localhost:0")
223 - checkErr(t, err)
224 - done := GoServe(t, opt.tr, l)
225 - defer done()
226 -
227 - nla := l.Addr()
228 - nc, err := net.Dial(nla.Network(), nla.String())
229 - checkErr(t, err)
230 - if err != nil {
231 - t.Fatal(fmt.Errorf("net.Dial(%s, %s): %s", nla.Network(), nla.String(), err))
232 - return
233 - }
234 -
235 - c, err := opt.tr.NewConn(nc, false)
236 - if err != nil {
237 - t.Fatal(fmt.Errorf("a.AddConn(%s <--> %s): %s", nc.LocalAddr(), nc.RemoteAddr(), err))
238 - return
239 - }
240 -
241 - // serve the outgoing conn, because some muxers assume
242 - // that we _always_ call serve. (this is an error?)
243 - go c.Serve(func(s smux.Stream) {
244 - log("serving connection")
245 - echoStream(s)
246 - s.Close()
247 - })
248 -
249 - var wg sync.WaitGroup
250 - for i := 0; i < opt.streamNum; i++ {
251 - wg.Add(1)
252 - go rateLimit(func() {
253 - defer wg.Done()
254 - openStreamAndRW(c)
255 - })
256 - }
257 - wg.Wait()
258 - c.Close()
259 - }
260 -
261 - openConnsAndRW := func() {
262 - log("openConnsAndRW, %d conns", opt.connNum)
263 -
264 - var wg sync.WaitGroup
265 - for i := 0; i < opt.connNum; i++ {
266 - wg.Add(1)
267 - go rateLimit(func() {
268 - defer wg.Done()
269 - openConnAndRW()
270 - })
271 - }
272 - wg.Wait()
273 - }
274 -
275 - go func() {
276 - openConnsAndRW()
277 - close(errs) // done
278 - }()
279 -
280 - for err := range errs {
281 - t.Error(err)
282 - }
283 -
284 -}
285 -
286 -func SubtestStress1Conn1Stream1Msg(t *testing.T, tr smux.Transport) {
287 - SubtestStress(t, Options{
288 - tr: tr,
289 - connNum: 1,
290 - streamNum: 1,
291 - msgNum: 1,
292 - msgMax: 100,
293 - msgMin: 100,
294 - })
295 -}
296 -
297 -func SubtestStress1Conn1Stream100Msg(t *testing.T, tr smux.Transport) {
298 - SubtestStress(t, Options{
299 - tr: tr,
300 - connNum: 1,
301 - streamNum: 1,
302 - msgNum: 100,
303 - msgMax: 100,
304 - msgMin: 100,
305 - })
306 -}
307 -
308 -func SubtestStress1Conn100Stream100Msg(t *testing.T, tr smux.Transport) {
309 - SubtestStress(t, Options{
310 - tr: tr,
311 - connNum: 1,
312 - streamNum: 100,
313 - msgNum: 100,
314 - msgMax: 100,
315 - msgMin: 100,
316 - })
317 -}
318 -
319 -func SubtestStress50Conn10Stream50Msg(t *testing.T, tr smux.Transport) {
320 - SubtestStress(t, Options{
321 - tr: tr,
322 - connNum: 50,
323 - streamNum: 10,
324 - msgNum: 50,
325 - msgMax: 100,
326 - msgMin: 100,
327 - })
328 -}
329 -
330 -func SubtestStress1Conn1000Stream10Msg(t *testing.T, tr smux.Transport) {
331 - SubtestStress(t, Options{
332 - tr: tr,
333 - connNum: 1,
334 - streamNum: 1000,
335 - msgNum: 10,
336 - msgMax: 100,
337 - msgMin: 100,
338 - })
339 -}
340 -
341 -func SubtestStress1Conn100Stream100Msg10MB(t *testing.T, tr smux.Transport) {
342 - SubtestStress(t, Options{
343 - tr: tr,
344 - connNum: 1,
345 - streamNum: 100,
346 - msgNum: 100,
347 - msgMax: 10000,
348 - msgMin: 1000,
349 - })
350 -}
351 -
352 -func SubtestAll(t *testing.T, tr smux.Transport) {
353 -
354 - tests := []TransportTest{
355 - SubtestSimpleWrite,
356 - SubtestStress1Conn1Stream1Msg,
357 - SubtestStress1Conn1Stream100Msg,
358 - SubtestStress1Conn100Stream100Msg,
359 - SubtestStress50Conn10Stream50Msg,
360 - SubtestStress1Conn1000Stream10Msg,
361 - SubtestStress1Conn100Stream100Msg10MB,
362 - }
363 -
364 - for _, f := range tests {
365 - if testing.Verbose() {
366 - fmt.Fprintf(os.Stderr, "==== RUN %s\n", GetFunctionName(f))
367 - }
368 - f(t, tr)
369 - }
370 -}
371 -
372 -type TransportTest func(t *testing.T, tr smux.Transport)
373 -
374 -func TestNoOp(t *testing.T) {}
375 -
376 -func GetFunctionName(i interface{}) string {
377 - return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
378 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/yamux/yamux.go deleted
-100
@@ -1,100 +0,0 @@
1 -package sm_yamux
2 -
3 -import (
4 - "io/ioutil"
5 - "net"
6 - "time"
7 -
8 - yamux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/hashicorp/yamux"
9 - smux "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer"
10 -)
11 -
12 -// stream implements smux.Stream using a ss.Stream
13 -type stream yamux.Stream
14 -
15 -func (s *stream) yamuxStream() *yamux.Stream {
16 - return (*yamux.Stream)(s)
17 -}
18 -
19 -func (s *stream) Read(buf []byte) (int, error) {
20 - return s.yamuxStream().Read(buf)
21 -}
22 -
23 -func (s *stream) Write(buf []byte) (int, error) {
24 - return s.yamuxStream().Write(buf)
25 -}
26 -
27 -func (s *stream) Close() error {
28 - return s.yamuxStream().Close()
29 -}
30 -
31 -// Conn is a connection to a remote peer.
32 -type conn yamux.Session
33 -
34 -func (c *conn) yamuxSession() *yamux.Session {
35 - return (*yamux.Session)(c)
36 -}
37 -
38 -func (c *conn) Close() error {
39 - return c.yamuxSession().Close()
40 -}
41 -
42 -func (c *conn) IsClosed() bool {
43 - return c.yamuxSession().IsClosed()
44 -}
45 -
46 -// OpenStream creates a new stream.
47 -func (c *conn) OpenStream() (smux.Stream, error) {
48 - s, err := c.yamuxSession().OpenStream()
49 - if err != nil {
50 - return nil, err
51 - }
52 -
53 - return (*stream)(s), nil
54 -}
55 -
56 -// AcceptStream accepts a stream opened by the other side.
57 -func (c *conn) AcceptStream() (smux.Stream, error) {
58 - s, err := c.yamuxSession().AcceptStream()
59 - return (*stream)(s), err
60 -}
61 -
62 -// Serve starts listening for incoming requests and handles them
63 -// using given StreamHandler
64 -func (c *conn) Serve(handler smux.StreamHandler) {
65 - for { // accept loop
66 - s, err := c.AcceptStream()
67 - if err != nil {
68 - return // err always means closed.
69 - }
70 - go handler(s)
71 - }
72 -}
73 -
74 -// Transport is a go-peerstream transport that constructs
75 -// yamux-backed connections.
76 -type Transport yamux.Config
77 -
78 -// DefaultTransport has default settings for yamux
79 -var DefaultTransport = (*Transport)(&yamux.Config{
80 - AcceptBacklog: 256, // from yamux.DefaultConfig
81 - EnableKeepAlive: true, // from yamux.DefaultConfig
82 - KeepAliveInterval: 30 * time.Second, // from yamux.DefaultConfig
83 - MaxStreamWindowSize: uint32(256 * 1024), // from yamux.DefaultConfig
84 - LogOutput: ioutil.Discard,
85 -})
86 -
87 -func (t *Transport) NewConn(nc net.Conn, isServer bool) (smux.Conn, error) {
88 - var s *yamux.Session
89 - var err error
90 - if isServer {
91 - s, err = yamux.Server(nc, t.Config())
92 - } else {
93 - s, err = yamux.Client(nc, t.Config())
94 - }
95 - return (*conn)(s), err
96 -}
97 -
98 -func (t *Transport) Config() *yamux.Config {
99 - return (*yamux.Config)(t)
100 -}
Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/yamux/yamux_test.go deleted
-11
@@ -1,11 +0,0 @@
1 -package sm_yamux
2 -
3 -import (
4 - "testing"
5 -
6 - test "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-stream-muxer/test"
7 -)
8 -
9 -func TestYamuxTransport(t *testing.T) {
10 - test.SubtestAll(t, DefaultTransport)
11 -}
Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher/.travis.yml deleted
-9
@@ -1,9 +0,0 @@
1 -language: go
2 -
3 -go:
4 - - 1.3
5 - - release
6 - - tip
7 -
8 -script:
9 - - go test -race -cpu=5 -v ./...
Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher/LICENSE deleted
-21
@@ -1,21 +0,0 @@
1 -The MIT License (MIT)
2 -
3 -Copyright (c) 2014 Juan Batiz-Benet
4 -
5 -Permission is hereby granted, free of charge, to any person obtaining a copy
6 -of this software and associated documentation files (the "Software"), to deal
7 -in the Software without restriction, including without limitation the rights
8 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 -copies of the Software, and to permit persons to whom the Software is
10 -furnished to do so, subject to the following conditions:
11 -
12 -The above copyright notice and this permission notice shall be included in
13 -all copies or substantial portions of the Software.
14 -
15 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 -THE SOFTWARE.
Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher/README.md deleted
-78
@@ -1,78 +0,0 @@
1 -# go-temp-err-catcher
2 -
3 -This is a little package to use with your net.Listeners.
4 -
5 -Docs: https://godoc.org/github.com/jbenet/go-temp-err-catcher
6 -
7 -Get:
8 -
9 - go get github.com/jbenet/go-temp-err-catcher
10 -
11 -## Examples
12 -
13 -It is meant to be used with things like net.Lister.Accept:
14 -
15 -```go
16 -import (
17 - tec "github.com/jbenet/go-temp-err-catcher"
18 -)
19 -
20 -func listen(listener net.Listener) {
21 - var c tec.TempErrCatcher
22 -
23 - for {
24 - conn, err := listener.Accept()
25 - if err != nil && c.IsTemporary(c) {
26 - continue
27 - }
28 - return conn, err
29 - }
30 -}
31 -```
32 -
33 -You can make your errors implement `Temporary`:
34 -
35 -```go
36 -type errTemp struct {
37 - e error
38 -}
39 -
40 -func (e errTemp) Temporary() bool {
41 - return true
42 -}
43 -
44 -func (e errTemp) Error() string {
45 - return e.e.Error()
46 -}
47 -
48 -err := errors.New("beep boop")
49 -var c tec.TempErrCatcher
50 -c.IsTemporary(err) // false
51 -c.IsTemporary(errTemp{err}) // true
52 -```
53 -
54 -Or just use `ErrTemp`:
55 -
56 -```go
57 -err := errors.New("beep boop")
58 -var c tec.TempErrCatcher
59 -c.IsTemporary(err) // false
60 -c.IsTemporary(tec.ErrTemp{err}) // true
61 -```
62 -
63 -
64 -You can also define an `IsTemp` function to classify errors:
65 -
66 -```go
67 -var ErrSkip = errors.New("this should be skipped")
68 -var ErrNotSkip = errors.New("this should not be skipped")
69 -
70 -var c tec.TempErrCatcher
71 -c.IsTemp = func(e error) bool {
72 - return e == ErrSkip
73 -}
74 -
75 -c.IsTemporary(ErrSkip) // true
76 -c.IsTemporary(ErrNotSkip) // false
77 -c.IsTemporary(ErrTemp) // false! no longer accepts Temporary()
78 -```
Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher/doc.go deleted
-62
@@ -1,62 +0,0 @@
1 -// Package temperrcatcher provides a TempErrCatcher object,
2 -// which implements simple error-retrying functionality.
3 -// It is meant to be used with things like net.Lister.Accept:
4 -//
5 -// import (
6 -// tec "github.com/jbenet/go-temp-err-catcher"
7 -// )
8 -//
9 -// func listen(listener net.Listener) {
10 -// var c tec.TempErrCatcher
11 -//
12 -// for {
13 -// conn, err := listener.Accept()
14 -// if err != nil && c.IsTemporary(c) {
15 -// continue
16 -// }
17 -// return conn, err
18 -// }
19 -// }
20 -//
21 -// You can make your errors implement `Temporary`:
22 -//
23 -// type errTemp struct {
24 -// e error
25 -// }
26 -//
27 -// func (e errTemp) Temporary() bool {
28 -// return true
29 -// }
30 -//
31 -// func (e errTemp) Error() string {
32 -// return e.e.Error()
33 -// }
34 -//
35 -// err := errors.New("beep boop")
36 -// var c tec.TempErrCatcher
37 -// c.IsTemporary(err) // false
38 -// c.IsTemporary(errTemp{err}) // true
39 -//
40 -// Or just use `ErrTemp`:
41 -//
42 -// err := errors.New("beep boop")
43 -// var c tec.TempErrCatcher
44 -// c.IsTemporary(err) // false
45 -// c.IsTemporary(tec.ErrTemp{err}) // true
46 -//
47 -//
48 -// You can also define an `IsTemp` function to classify errors:
49 -//
50 -// var ErrSkip = errors.New("this should be skipped")
51 -// var ErrNotSkip = errors.New("this should not be skipped")
52 -//
53 -// var c tec.TempErrCatcher
54 -// c.IsTemp = func(e error) bool {
55 -// return e == ErrSkip
56 -// }
57 -//
58 -// c.IsTemporary(ErrSkip) // true
59 -// c.IsTemporary(ErrNotSkip) // false
60 -// c.IsTemporary(ErrTemp) // false! no longer accepts Temporary()
61 -//
62 -package temperrcatcher
Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher/example/example.go deleted
-47
@@ -1,47 +0,0 @@
1 -package main
2 -
3 -import (
4 - "fmt"
5 -
6 - tec "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher"
7 -)
8 -
9 -var (
10 - ErrTemp = tec.ErrTemporary{fmt.Errorf("ErrTemp")}
11 - ErrSkip = fmt.Errorf("ErrSkip")
12 - ErrOther = fmt.Errorf("ErrOther")
13 -)
14 -
15 -func main() {
16 - var normal tec.TempErrCatcher
17 - var skipper tec.TempErrCatcher
18 - skipper.IsTemp = func(e error) bool {
19 - return e == ErrSkip
20 - }
21 -
22 - fmt.Println("trying normal (uses Temporary interface)")
23 - tryTec(normal)
24 - fmt.Println("")
25 - fmt.Println("trying skipper (uses our IsTemp function)")
26 - tryTec(skipper)
27 -}
28 -
29 -func tryTec(c tec.TempErrCatcher) {
30 - errs := []error{
31 - ErrTemp,
32 - ErrSkip,
33 - ErrOther,
34 - ErrTemp,
35 - ErrSkip,
36 - ErrOther,
37 - }
38 -
39 - for _, e := range errs {
40 - if c.IsTemporary(e) {
41 - fmt.Printf("\tIsTemporary: true - skipped %s\n", e)
42 - continue
43 - }
44 -
45 - fmt.Printf("\tIsTemporary: false - not skipped %s\n", e)
46 - }
47 -}
Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher/tec_test.go deleted
-172
@@ -1,172 +0,0 @@
1 -package temperrcatcher
2 -
3 -import (
4 - "fmt"
5 - "testing"
6 - "time"
7 -)
8 -
9 -var (
10 - ErrTemp = ErrTemporary{fmt.Errorf("ErrTemp")}
11 - ErrSkip = fmt.Errorf("ErrSkip")
12 - ErrOther = fmt.Errorf("ErrOther")
13 -)
14 -
15 -func testTec(t *testing.T, c TempErrCatcher, errs map[error]bool) {
16 - for e, expected := range errs {
17 - if c.IsTemporary(e) != expected {
18 - t.Error("expected %s to be %v", e, expected)
19 - }
20 - }
21 -}
22 -
23 -func TestNil(t *testing.T) {
24 - var c TempErrCatcher
25 - testTec(t, c, map[error]bool{
26 - ErrTemp: true,
27 - ErrSkip: false,
28 - ErrOther: false,
29 - })
30 -}
31 -
32 -func TestWait(t *testing.T) {
33 - var c TempErrCatcher
34 - worked := make(chan time.Duration, 3)
35 - c.Wait = func(t time.Duration) {
36 - worked <- t
37 - }
38 - testTec(t, c, map[error]bool{
39 - ErrTemp: true,
40 - ErrSkip: false,
41 - ErrOther: false,
42 - })
43 -
44 - // should've called it once
45 - select {
46 - case <-worked:
47 - default:
48 - t.Error("did not call our Wait func")
49 - }
50 -
51 - // should've called it ONLY once
52 - select {
53 - case <-worked:
54 - t.Error("called our Wait func more than once")
55 - default:
56 - }
57 -}
58 -
59 -func TestTemporary(t *testing.T) {
60 - var c TempErrCatcher
61 - testTec(t, c, map[error]bool{
62 - ErrTemp: true,
63 - ErrSkip: false,
64 - ErrOther: false,
65 - })
66 -}
67 -
68 -func TestDoubles(t *testing.T) {
69 - last := time.Now()
70 - diff := func() time.Duration {
71 - now := time.Now()
72 - diff := now.Sub(last)
73 - last = now
74 - return diff
75 - }
76 -
77 - testDiff := func(low, hi time.Duration) {
78 - d := diff()
79 - grace := time.Duration(50 * time.Microsecond)
80 - if (d + grace) < low {
81 - t.Error("time difference is smaller than", low, d)
82 - }
83 - if (d - grace) > hi {
84 - t.Error("time difference is greater than", hi, d)
85 - }
86 - }
87 -
88 - var c TempErrCatcher
89 - testDiff(0, c.Start)
90 - c.IsTemporary(ErrTemp)
91 - testDiff(c.Start, 2*c.Start) // first time.
92 - c.IsTemporary(ErrTemp)
93 - testDiff(2*c.Start, 4*c.Start) // second time.
94 - c.IsTemporary(ErrTemp)
95 - testDiff(4*c.Start, 8*c.Start) // third time.
96 -}
97 -
98 -func TestDifferentStart(t *testing.T) {
99 - last := time.Now()
100 - diff := func() time.Duration {
101 - now := time.Now()
102 - diff := now.Sub(last)
103 - last = now
104 - return diff
105 - }
106 -
107 - testDiff := func(low, hi time.Duration) {
108 - d := diff()
109 - grace := time.Duration(50 * time.Microsecond)
110 - if (d + grace) < low {
111 - t.Error("time difference is smaller than", low, d)
112 - }
113 - if (d - grace) > hi {
114 - t.Error("time difference is greater than", hi, d)
115 - }
116 - }
117 -
118 - var c TempErrCatcher
119 - f := time.Millisecond
120 - testDiff(0, f)
121 - c.IsTemporary(ErrTemp)
122 - testDiff(f, 2*f) // first time.
123 - c.IsTemporary(ErrTemp)
124 - testDiff(2*f, 4*f) // second time.
125 - c.IsTemporary(ErrTemp)
126 - testDiff(4*f, 8*f) // third time.
127 -
128 - c.Reset()
129 - c.Start = 10 * time.Millisecond
130 - f = c.Start
131 - testDiff(0, f)
132 - c.IsTemporary(ErrTemp)
133 - testDiff(f, 2*f) // first time.
134 - c.IsTemporary(ErrTemp)
135 - testDiff(2*f, 4*f) // second time.
136 - c.IsTemporary(ErrTemp)
137 - testDiff(4*f, 8*f) // third time.
138 -}
139 -
140 -func TestDifferentStreaks(t *testing.T) {
141 - var c TempErrCatcher
142 - // one streak
143 - c.IsTemporary(ErrTemp) // 1
144 - c.IsTemporary(ErrTemp) // 2
145 - c.IsTemporary(ErrTemp) // 4
146 - expect := 4 * time.Millisecond
147 - if c.delay != expect {
148 - t.Error("delay should be:", expect, c.delay)
149 - }
150 -
151 - <-time.After(c.delay * 10)
152 -
153 - // a different streak
154 - c.IsTemporary(ErrTemp) // 1
155 - c.IsTemporary(ErrTemp) // 2
156 - c.IsTemporary(ErrTemp) // 4
157 - if c.delay != expect {
158 - t.Error("delay should be:", expect, c.delay)
159 - }
160 -}
161 -
162 -func TestFunc(t *testing.T) {
163 - var c TempErrCatcher
164 - c.IsTemp = func(e error) bool {
165 - return e == ErrSkip
166 - }
167 - testTec(t, c, map[error]bool{
168 - ErrTemp: false,
169 - ErrSkip: true,
170 - ErrOther: false,
171 - })
172 -}
Godeps/_workspace/src/github.com/jbenet/go-temp-err-catcher/temp_err_catcher.go deleted
-124
@@ -1,124 +0,0 @@
1 -// Package temperrcatcher provides a TempErrCatcher object,
2 -// which implements simple error-retrying functionality.
3 -package temperrcatcher
4 -
5 -import (
6 - "time"
7 -)
8 -
9 -// InitialDelay governs how long to wait the first time.
10 -// This is defaulted to time.Millisecond, which makes sense
11 -// for network listener failures. You may want a much smaller
12 -// delay. You can configure this package wide, or in each
13 -// TempErrCatcher
14 -var InitialDelay = time.Millisecond
15 -
16 -// Temporary is an interface errors can implement to
17 -// ensure they are correctly classified by the default
18 -// TempErrCatcher classifier
19 -type Temporary interface {
20 - Temporary() bool
21 -}
22 -
23 -// ErrIsTemporary returns whether an error is Temporary(),
24 -// iff it implements the Temporary interface.
25 -func ErrIsTemporary(e error) bool {
26 - te, ok := e.(Temporary)
27 - return ok && te.Temporary()
28 -}
29 -
30 -// TempErrCatcher catches temporary errors for you. It then sleeps
31 -// for a bit before returning (you should then try again). This may
32 -// seem odd, but it's exactly what net/http does:
33 -// http://golang.org/src/net/http/server.go?s=51504:51550#L1728
34 -//
35 -// You can set a few options in TempErrCatcher. They all have defaults
36 -// so a zero TempErrCatcher is ready to be used:
37 -//
38 -// var c tec.TempErrCatcher
39 -// c.IsTemporary(tempErr)
40 -//
41 -type TempErrCatcher struct {
42 - IsTemp func(error) bool // the classifier to use. default: ErrIsTemporary
43 - Wait func(time.Duration) // the wait func to call. default: time.Sleep
44 - Max time.Duration // the maximum time to wait. default: time.Second
45 - Start time.Duration // the delay to start with. default: InitialDelay
46 - delay time.Duration
47 - last time.Time
48 -}
49 -
50 -func (tec *TempErrCatcher) init() {
51 - if tec.Max == 0 {
52 - tec.Max = time.Second
53 - }
54 - if tec.IsTemp == nil {
55 - tec.IsTemp = ErrIsTemporary
56 - }
57 - if tec.Wait == nil {
58 - tec.Wait = time.Sleep
59 - }
60 - if tec.Start == 0 {
61 - tec.Start = InitialDelay
62 - }
63 -}
64 -
65 -// IsTemporary checks whether an error is temporary. It will call
66 -// tec.Wait before returning, with a delay. The delay is also
67 -// doubled, so we do not constantly spin. This is the strategy
68 -// net.Listener uses.
69 -//
70 -// Note: you will want to call Reset() if you get a success,
71 -// so that the stored delay is brough back to 0.
72 -func (tec *TempErrCatcher) IsTemporary(e error) bool {
73 - tec.init()
74 - if tec.IsTemp(e) {
75 - now := time.Now()
76 - if now.Sub(tec.last) > (tec.delay * 5) {
77 - // this is a "new streak" of temp failures. reset.
78 - tec.Reset()
79 - }
80 -
81 - if tec.delay == 0 { // init case.
82 - tec.delay = tec.Start
83 - } else {
84 - tec.delay *= 2
85 - }
86 -
87 - if tec.delay > tec.Max {
88 - tec.delay = tec.Max
89 - }
90 - tec.Wait(tec.delay)
91 - tec.last = now
92 - return true
93 - }
94 - tec.Reset() // different failure. call reset
95 - return false
96 -}
97 -
98 -// Reset sets the internal delay counter to 0
99 -func (tec *TempErrCatcher) Reset() {
100 - tec.delay = 0
101 -}
102 -
103 -// ErrTemporary wraps any error and implements Temporary function.
104 -//
105 -// err := errors.New("beep boop")
106 -// var c tec.TempErrCatcher
107 -// c.IsTemporary(err) // false
108 -// c.IsTemporary(tec.ErrTemp{err}) // true
109 -//
110 -type ErrTemporary struct {
111 - Err error
112 -}
113 -
114 -func (e ErrTemporary) Temporary() bool {
115 - return true
116 -}
117 -
118 -func (e ErrTemporary) Error() string {
119 - return e.Err.Error()
120 -}
121 -
122 -func (e ErrTemporary) String() string {
123 - return e.Error()
124 -}
Godeps/_workspace/src/github.com/miekg/dns/.gitignore deleted
-4
@@ -1,4 +0,0 @@
1 -*.6
2 -tags
3 -test.out
4 -a.out
Godeps/_workspace/src/github.com/miekg/dns/.travis.yml deleted
-6
@@ -1,6 +0,0 @@
1 -language: go
2 -go:
3 - - 1.3
4 - - 1.4
5 -script:
6 - - go test -short -bench=.
Godeps/_workspace/src/github.com/miekg/dns/AUTHORS deleted
-1
@@ -1 +0,0 @@
1 -Miek Gieben <miek@miek.nl>
Godeps/_workspace/src/github.com/miekg/dns/CONTRIBUTORS deleted
-9
@@ -1,9 +0,0 @@
1 -Alex A. Skinner
2 -Andrew Tunnell-Jones
3 -Ask Bjørn Hansen
4 -Dave Cheney
5 -Dusty Wilson
6 -Marek Majkowski
7 -Peter van Dijk
8 -Omri Bahumi
9 -Alex Sergeyev
Godeps/_workspace/src/github.com/miekg/dns/COPYRIGHT deleted
-9
@@ -1,9 +0,0 @@
1 -Copyright 2009 The Go Authors. All rights reserved. Use of this source code
2 -is governed by a BSD-style license that can be found in the LICENSE file.
3 -Extensions of the original work are copyright (c) 2011 Miek Gieben
4 -
5 -Copyright 2011 Miek Gieben. All rights reserved. Use of this source code is
6 -governed by a BSD-style license that can be found in the LICENSE file.
7 -
8 -Copyright 2014 CloudFlare. All rights reserved. Use of this source code is
9 -governed by a BSD-style license that can be found in the LICENSE file.
Godeps/_workspace/src/github.com/miekg/dns/LICENSE deleted
-32
@@ -1,32 +0,0 @@
1 -Extensions of the original work are copyright (c) 2011 Miek Gieben
2 -
3 -As this is fork of the official Go code the same license applies:
4 -
5 -Copyright (c) 2009 The Go Authors. All rights reserved.
6 -
7 -Redistribution and use in source and binary forms, with or without
8 -modification, are permitted provided that the following conditions are
9 -met:
10 -
11 - * Redistributions of source code must retain the above copyright
12 -notice, this list of conditions and the following disclaimer.
13 - * Redistributions in binary form must reproduce the above
14 -copyright notice, this list of conditions and the following disclaimer
15 -in the documentation and/or other materials provided with the
16 -distribution.
17 - * Neither the name of Google Inc. nor the names of its
18 -contributors may be used to endorse or promote products derived from
19 -this software without specific prior written permission.
20 -
21 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 -
Godeps/_workspace/src/github.com/miekg/dns/README.md deleted
-143
@@ -1,143 +0,0 @@
1 -[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)
2 -
3 -# Alternative (more granular) approach to a DNS library
4 -
5 -> Less is more.
6 -
7 -Complete and usable DNS library. All widely used Resource Records are
8 -supported, including the DNSSEC types. It follows a lean and mean philosophy.
9 -If there is stuff you should know as a DNS programmer there isn't a convenience
10 -function for it. Server side and client side programming is supported, i.e. you
11 -can build servers and resolvers with it.
12 -
13 -If you like this, you may also be interested in:
14 -
15 -* https://github.com/miekg/unbound -- Go wrapper for the Unbound resolver.
16 -
17 -# Goals
18 -
19 -* KISS;
20 -* Fast;
21 -* Small API, if its easy to code in Go, don't make a function for it.
22 -
23 -# Users
24 -
25 -A not-so-up-to-date-list-that-may-be-actually-current:
26 -
27 -* https://github.com/abh/geodns
28 -* http://www.statdns.com/
29 -* http://www.dnsinspect.com/
30 -* https://github.com/chuangbo/jianbing-dictionary-dns
31 -* http://www.dns-lg.com/
32 -* https://github.com/fcambus/rrda
33 -* https://github.com/kenshinx/godns
34 -* https://github.com/skynetservices/skydns
35 -* https://github.com/DevelopersPL/godnsagent
36 -* https://github.com/duedil-ltd/discodns
37 -* https://github.com/StalkR/dns-reverse-proxy
38 -* https://github.com/tianon/rawdns
39 -* https://mesosphere.github.io/mesos-dns/
40 -
41 -Send pull request if you want to be listed here.
42 -
43 -# Features
44 -
45 -* UDP/TCP queries, IPv4 and IPv6;
46 -* RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported;
47 -* Fast:
48 - * Reply speed around ~ 80K qps (faster hardware results in more qps);
49 - * Parsing RRs ~ 100K RR/s, that's 5M records in about 50 seconds;
50 -* Server side programming (mimicking the net/http package);
51 -* Client side programming;
52 -* DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA;
53 -* EDNS0, NSID;
54 -* AXFR/IXFR;
55 -* TSIG, SIG(0);
56 -* DNS name compression;
57 -* Depends only on the standard library.
58 -
59 -Have fun!
60 -
61 -Miek Gieben - 2010-2012 - <miek@miek.nl>
62 -
63 -# Building
64 -
65 -Building is done with the `go` tool. If you have setup your GOPATH
66 -correctly, the following should work:
67 -
68 - go get github.com/miekg/dns
69 - go build github.com/miekg/dns
70 -
71 -## Examples
72 -
73 -A short "how to use the API" is at the beginning of doc.go (this also will show
74 -when you call `godoc github.com/miekg/dns`).
75 -
76 -Example programs can be found in the `github.com/miekg/exdns` repository.
77 -
78 -## Supported RFCs
79 -
80 -*all of them*
81 -
82 -* 103{4,5} - DNS standard
83 -* 1348 - NSAP record
84 -* 1982 - Serial Arithmetic
85 -* 1876 - LOC record
86 -* 1995 - IXFR
87 -* 1996 - DNS notify
88 -* 2136 - DNS Update (dynamic updates)
89 -* 2181 - RRset definition - there is no RRset type though, just []RR
90 -* 2537 - RSAMD5 DNS keys
91 -* 2065 - DNSSEC (updated in later RFCs)
92 -* 2671 - EDNS record
93 -* 2782 - SRV record
94 -* 2845 - TSIG record
95 -* 2915 - NAPTR record
96 -* 2929 - DNS IANA Considerations
97 -* 3110 - RSASHA1 DNS keys
98 -* 3225 - DO bit (DNSSEC OK)
99 -* 340{1,2,3} - NAPTR record
100 -* 3445 - Limiting the scope of (DNS)KEY
101 -* 3597 - Unknown RRs
102 -* 4025 - IPSECKEY
103 -* 403{3,4,5} - DNSSEC + validation functions
104 -* 4255 - SSHFP record
105 -* 4343 - Case insensitivity
106 -* 4408 - SPF record
107 -* 4509 - SHA256 Hash in DS
108 -* 4592 - Wildcards in the DNS
109 -* 4635 - HMAC SHA TSIG
110 -* 4701 - DHCID
111 -* 4892 - id.server
112 -* 5001 - NSID
113 -* 5155 - NSEC3 record
114 -* 5205 - HIP record
115 -* 5702 - SHA2 in the DNS
116 -* 5936 - AXFR
117 -* 5966 - TCP implementation recommendations
118 -* 6605 - ECDSA
119 -* 6725 - IANA Registry Update
120 -* 6742 - ILNP DNS
121 -* 6891 - EDNS0 update
122 -* 6895 - DNS IANA considerations
123 -* 6975 - Algorithm Understanding in DNSSEC
124 -* 7043 - EUI48/EUI64 records
125 -* 7314 - DNS (EDNS) EXPIRE Option
126 -* xxxx - URI record (draft)
127 -* xxxx - EDNS0 DNS Update Lease (draft)
128 -
129 -## Loosely based upon
130 -
131 -* `ldns`
132 -* `NSD`
133 -* `Net::DNS`
134 -* `GRONG`
135 -
136 -## TODO
137 -
138 -* privatekey.Precompute() when signing?
139 -* Last remaining RRs: APL, ATMA, A6 and NXT and IPSECKEY;
140 -* Missing in parsing: ISDN, UNSPEC, ATMA;
141 -* CAA parsing is broken;
142 -* NSEC(3) cover/match/closest enclose;
143 -* Replies with TC bit are not parsed to the end;
Godeps/_workspace/src/github.com/miekg/dns/client.go deleted
-326
@@ -1,326 +0,0 @@
1 -package dns
2 -
3 -// A client implementation.
4 -
5 -import (
6 - "bytes"
7 - "io"
8 - "net"
9 - "time"
10 -)
11 -
12 -const dnsTimeout time.Duration = 2 * time.Second
13 -const tcpIdleTimeout time.Duration = 8 * time.Second
14 -
15 -// A Conn represents a connection to a DNS server.
16 -type Conn struct {
17 - net.Conn // a net.Conn holding the connection
18 - UDPSize uint16 // minimum receive buffer for UDP messages
19 - TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
20 - rtt time.Duration
21 - t time.Time
22 - tsigRequestMAC string
23 -}
24 -
25 -// A Client defines parameters for a DNS client.
26 -type Client struct {
27 - Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one (default is "" for UDP)
28 - UDPSize uint16 // minimum receive buffer for UDP messages
29 - DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
30 - ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
31 - WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
32 - TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
33 - SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
34 - group singleflight
35 -}
36 -
37 -// Exchange performs a synchronous UDP query. It sends the message m to the address
38 -// contained in a and waits for an reply. Exchange does not retry a failed query, nor
39 -// will it fall back to TCP in case of truncation.
40 -// If you need to send a DNS message on an already existing connection, you can use the
41 -// following:
42 -//
43 -// co := &dns.Conn{Conn: c} // c is your net.Conn
44 -// co.WriteMsg(m)
45 -// in, err := co.ReadMsg()
46 -// co.Close()
47 -//
48 -func Exchange(m *Msg, a string) (r *Msg, err error) {
49 - var co *Conn
50 - co, err = DialTimeout("udp", a, dnsTimeout)
51 - if err != nil {
52 - return nil, err
53 - }
54 -
55 - defer co.Close()
56 - co.SetReadDeadline(time.Now().Add(dnsTimeout))
57 - co.SetWriteDeadline(time.Now().Add(dnsTimeout))
58 -
59 - opt := m.IsEdns0()
60 - // If EDNS0 is used use that for size.
61 - if opt != nil && opt.UDPSize() >= MinMsgSize {
62 - co.UDPSize = opt.UDPSize()
63 - }
64 -
65 - if err = co.WriteMsg(m); err != nil {
66 - return nil, err
67 - }
68 - r, err = co.ReadMsg()
69 - return r, err
70 -}
71 -
72 -// ExchangeConn performs a synchronous query. It sends the message m via the connection
73 -// c and waits for a reply. The connection c is not closed by ExchangeConn.
74 -// This function is going away, but can easily be mimicked:
75 -//
76 -// co := &dns.Conn{Conn: c} // c is your net.Conn
77 -// co.WriteMsg(m)
78 -// in, _ := co.ReadMsg()
79 -// co.Close()
80 -//
81 -func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
82 - println("dns: this function is deprecated")
83 - co := new(Conn)
84 - co.Conn = c
85 - if err = co.WriteMsg(m); err != nil {
86 - return nil, err
87 - }
88 - r, err = co.ReadMsg()
89 - return r, err
90 -}
91 -
92 -// Exchange performs an synchronous query. It sends the message m to the address
93 -// contained in a and waits for an reply. Basic use pattern with a *dns.Client:
94 -//
95 -// c := new(dns.Client)
96 -// in, rtt, err := c.Exchange(message, "127.0.0.1:53")
97 -//
98 -// Exchange does not retry a failed query, nor will it fall back to TCP in
99 -// case of truncation.
100 -func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
101 - if !c.SingleInflight {
102 - return c.exchange(m, a)
103 - }
104 - // This adds a bunch of garbage, TODO(miek).
105 - t := "nop"
106 - if t1, ok := TypeToString[m.Question[0].Qtype]; ok {
107 - t = t1
108 - }
109 - cl := "nop"
110 - if cl1, ok := ClassToString[m.Question[0].Qclass]; ok {
111 - cl = cl1
112 - }
113 - r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
114 - return c.exchange(m, a)
115 - })
116 - if err != nil {
117 - return r, rtt, err
118 - }
119 - if shared {
120 - return r.Copy(), rtt, nil
121 - }
122 - return r, rtt, nil
123 -}
124 -
125 -func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
126 - timeout := dnsTimeout
127 - var co *Conn
128 - if c.DialTimeout != 0 {
129 - timeout = c.DialTimeout
130 - }
131 - if c.Net == "" {
132 - co, err = DialTimeout("udp", a, timeout)
133 - } else {
134 - co, err = DialTimeout(c.Net, a, timeout)
135 - }
136 - if err != nil {
137 - return nil, 0, err
138 - }
139 - timeout = dnsTimeout
140 - if c.ReadTimeout != 0 {
141 - timeout = c.ReadTimeout
142 - }
143 - co.SetReadDeadline(time.Now().Add(timeout))
144 - timeout = dnsTimeout
145 - if c.WriteTimeout != 0 {
146 - timeout = c.WriteTimeout
147 - }
148 - co.SetWriteDeadline(time.Now().Add(timeout))
149 - defer co.Close()
150 - opt := m.IsEdns0()
151 - // If EDNS0 is used use that for size.
152 - if opt != nil && opt.UDPSize() >= MinMsgSize {
153 - co.UDPSize = opt.UDPSize()
154 - }
155 - // Otherwise use the client's configured UDP size.
156 - if opt == nil && c.UDPSize >= MinMsgSize {
157 - co.UDPSize = c.UDPSize
158 - }
159 - co.TsigSecret = c.TsigSecret
160 - if err = co.WriteMsg(m); err != nil {
161 - return nil, 0, err
162 - }
163 - r, err = co.ReadMsg()
164 - return r, co.rtt, err
165 -}
166 -
167 -// ReadMsg reads a message from the connection co.
168 -// If the received message contains a TSIG record the transaction
169 -// signature is verified.
170 -func (co *Conn) ReadMsg() (*Msg, error) {
171 - var p []byte
172 - m := new(Msg)
173 - if _, ok := co.Conn.(*net.TCPConn); ok {
174 - p = make([]byte, MaxMsgSize)
175 - } else {
176 - if co.UDPSize >= 512 {
177 - p = make([]byte, co.UDPSize)
178 - } else {
179 - p = make([]byte, MinMsgSize)
180 - }
181 - }
182 - n, err := co.Read(p)
183 - if err != nil && n == 0 {
184 - return nil, err
185 - }
186 - p = p[:n]
187 - if err := m.Unpack(p); err != nil {
188 - return nil, err
189 - }
190 - co.rtt = time.Since(co.t)
191 - if t := m.IsTsig(); t != nil {
192 - if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
193 - return m, ErrSecret
194 - }
195 - // Need to work on the original message p, as that was used to calculate the tsig.
196 - err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
197 - }
198 - return m, err
199 -}
200 -
201 -// Read implements the net.Conn read method.
202 -func (co *Conn) Read(p []byte) (n int, err error) {
203 - if co.Conn == nil {
204 - return 0, ErrConnEmpty
205 - }
206 - if len(p) < 2 {
207 - return 0, io.ErrShortBuffer
208 - }
209 - if t, ok := co.Conn.(*net.TCPConn); ok {
210 - n, err = t.Read(p[0:2])
211 - if err != nil || n != 2 {
212 - return n, err
213 - }
214 - l, _ := unpackUint16(p[0:2], 0)
215 - if l == 0 {
216 - return 0, ErrShortRead
217 - }
218 - if int(l) > len(p) {
219 - return int(l), io.ErrShortBuffer
220 - }
221 - n, err = t.Read(p[:l])
222 - if err != nil {
223 - return n, err
224 - }
225 - i := n
226 - for i < int(l) {
227 - j, err := t.Read(p[i:int(l)])
228 - if err != nil {
229 - return i, err
230 - }
231 - i += j
232 - }
233 - n = i
234 - return n, err
235 - }
236 - // UDP connection
237 - n, err = co.Conn.Read(p)
238 - if err != nil {
239 - return n, err
240 - }
241 - return n, err
242 -}
243 -
244 -// WriteMsg sends a message throught the connection co.
245 -// If the message m contains a TSIG record the transaction
246 -// signature is calculated.
247 -func (co *Conn) WriteMsg(m *Msg) (err error) {
248 - var out []byte
249 - if t := m.IsTsig(); t != nil {
250 - mac := ""
251 - if _, ok := co.TsigSecret[t.Hdr.Name]; !ok {
252 - return ErrSecret
253 - }
254 - out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false)
255 - // Set for the next read, allthough only used in zone transfers
256 - co.tsigRequestMAC = mac
257 - } else {
258 - out, err = m.Pack()
259 - }
260 - if err != nil {
261 - return err
262 - }
263 - co.t = time.Now()
264 - if _, err = co.Write(out); err != nil {
265 - return err
266 - }
267 - return nil
268 -}
269 -
270 -// Write implements the net.Conn Write method.
271 -func (co *Conn) Write(p []byte) (n int, err error) {
272 - if t, ok := co.Conn.(*net.TCPConn); ok {
273 - lp := len(p)
274 - if lp < 2 {
275 - return 0, io.ErrShortBuffer
276 - }
277 - if lp > MaxMsgSize {
278 - return 0, &Error{err: "message too large"}
279 - }
280 - l := make([]byte, 2, lp+2)
281 - l[0], l[1] = packUint16(uint16(lp))
282 - p = append(l, p...)
283 - n, err := io.Copy(t, bytes.NewReader(p))
284 - return int(n), err
285 - }
286 - n, err = co.Conn.(*net.UDPConn).Write(p)
287 - return n, err
288 -}
289 -
290 -// Dial connects to the address on the named network.
291 -func Dial(network, address string) (conn *Conn, err error) {
292 - conn = new(Conn)
293 - conn.Conn, err = net.Dial(network, address)
294 - if err != nil {
295 - return nil, err
296 - }
297 - return conn, nil
298 -}
299 -
300 -// DialTimeout acts like Dial but takes a timeout.
301 -func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) {
302 - conn = new(Conn)
303 - conn.Conn, err = net.DialTimeout(network, address, timeout)
304 - if err != nil {
305 - return nil, err
306 - }
307 - return conn, nil
308 -}
309 -
310 -// Close implements the net.Conn Close method.
311 -func (co *Conn) Close() error { return co.Conn.Close() }
312 -
313 -// LocalAddr implements the net.Conn LocalAddr method.
314 -func (co *Conn) LocalAddr() net.Addr { return co.Conn.LocalAddr() }
315 -
316 -// RemoteAddr implements the net.Conn RemoteAddr method.
317 -func (co *Conn) RemoteAddr() net.Addr { return co.Conn.RemoteAddr() }
318 -
319 -// SetDeadline implements the net.Conn SetDeadline method.
320 -func (co *Conn) SetDeadline(t time.Time) error { return co.Conn.SetDeadline(t) }
321 -
322 -// SetReadDeadline implements the net.Conn SetReadDeadline method.
323 -func (co *Conn) SetReadDeadline(t time.Time) error { return co.Conn.SetReadDeadline(t) }
324 -
325 -// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
326 -func (co *Conn) SetWriteDeadline(t time.Time) error { return co.Conn.SetWriteDeadline(t) }
Godeps/_workspace/src/github.com/miekg/dns/client_test.go deleted
-214
@@ -1,214 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "strconv"
5 - "testing"
6 - "time"
7 -)
8 -
9 -func TestClientSync(t *testing.T) {
10 - HandleFunc("miek.nl.", HelloServer)
11 - defer HandleRemove("miek.nl.")
12 -
13 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
14 - if err != nil {
15 - t.Fatalf("Unable to run test server: %v", err)
16 - }
17 - defer s.Shutdown()
18 -
19 - m := new(Msg)
20 - m.SetQuestion("miek.nl.", TypeSOA)
21 -
22 - c := new(Client)
23 - r, _, err := c.Exchange(m, addrstr)
24 - if err != nil {
25 - t.Errorf("failed to exchange: %v", err)
26 - }
27 - if r != nil && r.Rcode != RcodeSuccess {
28 - t.Errorf("failed to get an valid answer\n%v", r)
29 - }
30 - // And now with plain Exchange().
31 - r, err = Exchange(m, addrstr)
32 - if err != nil {
33 - t.Errorf("failed to exchange: %v", err)
34 - }
35 - if r != nil && r.Rcode != RcodeSuccess {
36 - t.Errorf("failed to get an valid answer\n%v", r)
37 - }
38 -}
39 -
40 -func TestClientEDNS0(t *testing.T) {
41 - HandleFunc("miek.nl.", HelloServer)
42 - defer HandleRemove("miek.nl.")
43 -
44 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
45 - if err != nil {
46 - t.Fatalf("Unable to run test server: %v", err)
47 - }
48 - defer s.Shutdown()
49 -
50 - m := new(Msg)
51 - m.SetQuestion("miek.nl.", TypeDNSKEY)
52 -
53 - m.SetEdns0(2048, true)
54 -
55 - c := new(Client)
56 - r, _, err := c.Exchange(m, addrstr)
57 - if err != nil {
58 - t.Errorf("failed to exchange: %v", err)
59 - }
60 -
61 - if r != nil && r.Rcode != RcodeSuccess {
62 - t.Errorf("failed to get an valid answer\n%v", r)
63 - }
64 -}
65 -
66 -// Validates the transmission and parsing of local EDNS0 options.
67 -func TestClientEDNS0Local(t *testing.T) {
68 -
69 - optStr1 := "1979:0x0707"
70 - optStr2 := strconv.Itoa(EDNS0LOCALSTART) + ":0x0601"
71 -
72 - handler := func(w ResponseWriter, req *Msg) {
73 - m := new(Msg)
74 - m.SetReply(req)
75 -
76 - m.Extra = make([]RR, 1, 2)
77 - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello local edns"}}
78 -
79 - // If the local options are what we expect, then reflect them back.
80 - ec1 := req.Extra[0].(*OPT).Option[0].(*EDNS0_LOCAL).String()
81 - ec2 := req.Extra[0].(*OPT).Option[1].(*EDNS0_LOCAL).String()
82 - if ec1 == optStr1 && ec2 == optStr2 {
83 - m.Extra = append(m.Extra, req.Extra[0])
84 - }
85 -
86 - w.WriteMsg(m)
87 - }
88 -
89 - HandleFunc("miek.nl.", handler)
90 - defer HandleRemove("miek.nl.")
91 -
92 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
93 - if err != nil {
94 - t.Fatalf("Unable to run test server: %s", err)
95 - }
96 - defer s.Shutdown()
97 -
98 - m := new(Msg)
99 - m.SetQuestion("miek.nl.", TypeTXT)
100 -
101 - // Add two local edns options to the query.
102 - ec1 := &EDNS0_LOCAL{Code: 1979, Data: []byte{7, 7}}
103 - ec2 := &EDNS0_LOCAL{Code: EDNS0LOCALSTART, Data: []byte{6, 1}}
104 - o := &OPT{Hdr: RR_Header{Name: ".", Rrtype: TypeOPT}, Option: []EDNS0{ec1, ec2}}
105 - m.Extra = append(m.Extra, o)
106 -
107 - c := new(Client)
108 - r, _, e := c.Exchange(m, addrstr)
109 - if e != nil {
110 - t.Logf("failed to exchange: %s", e.Error())
111 - t.Fail()
112 - }
113 -
114 - if r != nil && r.Rcode != RcodeSuccess {
115 - t.Log("failed to get a valid answer")
116 - t.Fail()
117 - t.Logf("%v\n", r)
118 - }
119 -
120 - txt := r.Extra[0].(*TXT).Txt[0]
121 - if txt != "Hello local edns" {
122 - t.Log("Unexpected result for miek.nl", txt, "!= Hello local edns")
123 - t.Fail()
124 - }
125 -
126 - // Validate the local options in the reply.
127 - got := r.Extra[1].(*OPT).Option[0].(*EDNS0_LOCAL).String()
128 - if got != optStr1 {
129 - t.Log("failed to get local edns0 answer; got %s, expected %s", got, optStr1)
130 - t.Fail()
131 - t.Logf("%v\n", r)
132 - }
133 -
134 - got = r.Extra[1].(*OPT).Option[1].(*EDNS0_LOCAL).String()
135 - if got != optStr2 {
136 - t.Log("failed to get local edns0 answer; got %s, expected %s", got, optStr2)
137 - t.Fail()
138 - t.Logf("%v\n", r)
139 - }
140 -}
141 -
142 -func TestSingleSingleInflight(t *testing.T) {
143 - HandleFunc("miek.nl.", HelloServer)
144 - defer HandleRemove("miek.nl.")
145 -
146 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
147 - if err != nil {
148 - t.Fatalf("Unable to run test server: %v", err)
149 - }
150 - defer s.Shutdown()
151 -
152 - m := new(Msg)
153 - m.SetQuestion("miek.nl.", TypeDNSKEY)
154 -
155 - c := new(Client)
156 - c.SingleInflight = true
157 - nr := 10
158 - ch := make(chan time.Duration)
159 - for i := 0; i < nr; i++ {
160 - go func() {
161 - _, rtt, _ := c.Exchange(m, addrstr)
162 - ch <- rtt
163 - }()
164 - }
165 - i := 0
166 - var first time.Duration
167 - // With inflight *all* rtt are identical, and by doing actual lookups
168 - // the changes that this is a coincidence is small.
169 -Loop:
170 - for {
171 - select {
172 - case rtt := <-ch:
173 - if i == 0 {
174 - first = rtt
175 - } else {
176 - if first != rtt {
177 - t.Errorf("all rtts should be equal. got %d want %d", rtt, first)
178 - }
179 - }
180 - i++
181 - if i == 10 {
182 - break Loop
183 - }
184 - }
185 - }
186 -}
187 -
188 -// ExampleUpdateLeaseTSIG shows how to update a lease signed with TSIG.
189 -func ExampleUpdateLeaseTSIG(t *testing.T) {
190 - m := new(Msg)
191 - m.SetUpdate("t.local.ip6.io.")
192 - rr, _ := NewRR("t.local.ip6.io. 30 A 127.0.0.1")
193 - rrs := make([]RR, 1)
194 - rrs[0] = rr
195 - m.Insert(rrs)
196 -
197 - leaseRr := new(OPT)
198 - leaseRr.Hdr.Name = "."
199 - leaseRr.Hdr.Rrtype = TypeOPT
200 - e := new(EDNS0_UL)
201 - e.Code = EDNS0UL
202 - e.Lease = 120
203 - leaseRr.Option = append(leaseRr.Option, e)
204 - m.Extra = append(m.Extra, leaseRr)
205 -
206 - c := new(Client)
207 - m.SetTsig("polvi.", HmacMD5, 300, time.Now().Unix())
208 - c.TsigSecret = map[string]string{"polvi.": "pRZgBrBvI4NAHZYhxmhs/Q=="}
209 -
210 - _, _, err := c.Exchange(m, "127.0.0.1:53")
211 - if err != nil {
212 - t.Error(err)
213 - }
214 -}
Godeps/_workspace/src/github.com/miekg/dns/clientconfig.go deleted
-99
@@ -1,99 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "bufio"
5 - "os"
6 - "strconv"
7 - "strings"
8 -)
9 -
10 -// ClientConfig wraps the contents of the /etc/resolv.conf file.
11 -type ClientConfig struct {
12 - Servers []string // servers to use
13 - Search []string // suffixes to append to local name
14 - Port string // what port to use
15 - Ndots int // number of dots in name to trigger absolute lookup
16 - Timeout int // seconds before giving up on packet
17 - Attempts int // lost packets before giving up on server, not used in the package dns
18 -}
19 -
20 -// ClientConfigFromFile parses a resolv.conf(5) like file and returns
21 -// a *ClientConfig.
22 -func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
23 - file, err := os.Open(resolvconf)
24 - if err != nil {
25 - return nil, err
26 - }
27 - defer file.Close()
28 - c := new(ClientConfig)
29 - scanner := bufio.NewScanner(file)
30 - c.Servers = make([]string, 0)
31 - c.Search = make([]string, 0)
32 - c.Port = "53"
33 - c.Ndots = 1
34 - c.Timeout = 5
35 - c.Attempts = 2
36 -
37 - for scanner.Scan() {
38 - if err := scanner.Err(); err != nil {
39 - return nil, err
40 - }
41 - line := scanner.Text()
42 - f := strings.Fields(line)
43 - if len(f) < 1 {
44 - continue
45 - }
46 - switch f[0] {
47 - case "nameserver": // add one name server
48 - if len(f) > 1 {
49 - // One more check: make sure server name is
50 - // just an IP address. Otherwise we need DNS
51 - // to look it up.
52 - name := f[1]
53 - c.Servers = append(c.Servers, name)
54 - }
55 -
56 - case "domain": // set search path to just this domain
57 - if len(f) > 1 {
58 - c.Search = make([]string, 1)
59 - c.Search[0] = f[1]
60 - } else {
61 - c.Search = make([]string, 0)
62 - }
63 -
64 - case "search": // set search path to given servers
65 - c.Search = make([]string, len(f)-1)
66 - for i := 0; i < len(c.Search); i++ {
67 - c.Search[i] = f[i+1]
68 - }
69 -
70 - case "options": // magic options
71 - for i := 1; i < len(f); i++ {
72 - s := f[i]
73 - switch {
74 - case len(s) >= 6 && s[:6] == "ndots:":
75 - n, _ := strconv.Atoi(s[6:])
76 - if n < 1 {
77 - n = 1
78 - }
79 - c.Ndots = n
80 - case len(s) >= 8 && s[:8] == "timeout:":
81 - n, _ := strconv.Atoi(s[8:])
82 - if n < 1 {
83 - n = 1
84 - }
85 - c.Timeout = n
86 - case len(s) >= 8 && s[:9] == "attempts:":
87 - n, _ := strconv.Atoi(s[9:])
88 - if n < 1 {
89 - n = 1
90 - }
91 - c.Attempts = n
92 - case s == "rotate":
93 - /* not imp */
94 - }
95 - }
96 - }
97 - }
98 - return c, nil
99 -}
Godeps/_workspace/src/github.com/miekg/dns/clientconfig_test.go deleted
-55
@@ -1,55 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "io/ioutil"
5 - "os"
6 - "path/filepath"
7 - "testing"
8 -)
9 -
10 -const normal string = `
11 -# Comment
12 -domain somedomain.com
13 -nameserver 10.28.10.2
14 -nameserver 11.28.10.1
15 -`
16 -
17 -const missingNewline string = `
18 -domain somedomain.com
19 -nameserver 10.28.10.2
20 -nameserver 11.28.10.1` // <- NOTE: NO newline.
21 -
22 -func testConfig(t *testing.T, data string) {
23 - tempDir, err := ioutil.TempDir("", "")
24 - if err != nil {
25 - t.Fatalf("TempDir: %v", err)
26 - }
27 - defer os.RemoveAll(tempDir)
28 -
29 - path := filepath.Join(tempDir, "resolv.conf")
30 - if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {
31 - t.Fatalf("WriteFile: %v", err)
32 - }
33 - cc, err := ClientConfigFromFile(path)
34 - if err != nil {
35 - t.Errorf("error parsing resolv.conf: %v", err)
36 - }
37 - if l := len(cc.Servers); l != 2 {
38 - t.Errorf("incorrect number of nameservers detected: %d", l)
39 - }
40 - if l := len(cc.Search); l != 1 {
41 - t.Errorf("domain directive not parsed correctly: %v", cc.Search)
42 - } else {
43 - if cc.Search[0] != "somedomain.com" {
44 - t.Errorf("domain is unexpected: %v", cc.Search[0])
45 - }
46 - }
47 -}
48 -
49 -func TestNameserver(t *testing.T) {
50 - testConfig(t, normal)
51 -}
52 -
53 -func TestMissingFinalNewLine(t *testing.T) {
54 - testConfig(t, missingNewline)
55 -}
Godeps/_workspace/src/github.com/miekg/dns/defaults.go deleted
-248
@@ -1,248 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "errors"
5 - "net"
6 - "strconv"
7 -)
8 -
9 -const hexDigit = "0123456789abcdef"
10 -
11 -// Everything is assumed in ClassINET.
12 -
13 -// SetReply creates a reply message from a request message.
14 -func (dns *Msg) SetReply(request *Msg) *Msg {
15 - dns.Id = request.Id
16 - dns.RecursionDesired = request.RecursionDesired // Copy rd bit
17 - dns.Response = true
18 - dns.Opcode = OpcodeQuery
19 - dns.Rcode = RcodeSuccess
20 - if len(request.Question) > 0 {
21 - dns.Question = make([]Question, 1)
22 - dns.Question[0] = request.Question[0]
23 - }
24 - return dns
25 -}
26 -
27 -// SetQuestion creates a question message, it sets the Question
28 -// section, generates an Id and sets the RecursionDesired (RD)
29 -// bit to true.
30 -func (dns *Msg) SetQuestion(z string, t uint16) *Msg {
31 - dns.Id = Id()
32 - dns.RecursionDesired = true
33 - dns.Question = make([]Question, 1)
34 - dns.Question[0] = Question{z, t, ClassINET}
35 - return dns
36 -}
37 -
38 -// SetNotify creates a notify message, it sets the Question
39 -// section, generates an Id and sets the Authoritative (AA)
40 -// bit to true.
41 -func (dns *Msg) SetNotify(z string) *Msg {
42 - dns.Opcode = OpcodeNotify
43 - dns.Authoritative = true
44 - dns.Id = Id()
45 - dns.Question = make([]Question, 1)
46 - dns.Question[0] = Question{z, TypeSOA, ClassINET}
47 - return dns
48 -}
49 -
50 -// SetRcode creates an error message suitable for the request.
51 -func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg {
52 - dns.SetReply(request)
53 - dns.Rcode = rcode
54 - return dns
55 -}
56 -
57 -// SetRcodeFormatError creates a message with FormError set.
58 -func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg {
59 - dns.Rcode = RcodeFormatError
60 - dns.Opcode = OpcodeQuery
61 - dns.Response = true
62 - dns.Authoritative = false
63 - dns.Id = request.Id
64 - return dns
65 -}
66 -
67 -// SetUpdate makes the message a dynamic update message. It
68 -// sets the ZONE section to: z, TypeSOA, ClassINET.
69 -func (dns *Msg) SetUpdate(z string) *Msg {
70 - dns.Id = Id()
71 - dns.Response = false
72 - dns.Opcode = OpcodeUpdate
73 - dns.Compress = false // BIND9 cannot handle compression
74 - dns.Question = make([]Question, 1)
75 - dns.Question[0] = Question{z, TypeSOA, ClassINET}
76 - return dns
77 -}
78 -
79 -// SetIxfr creates message for requesting an IXFR.
80 -func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg {
81 - dns.Id = Id()
82 - dns.Question = make([]Question, 1)
83 - dns.Ns = make([]RR, 1)
84 - s := new(SOA)
85 - s.Hdr = RR_Header{z, TypeSOA, ClassINET, defaultTtl, 0}
86 - s.Serial = serial
87 - s.Ns = ns
88 - s.Mbox = mbox
89 - dns.Question[0] = Question{z, TypeIXFR, ClassINET}
90 - dns.Ns[0] = s
91 - return dns
92 -}
93 -
94 -// SetAxfr creates message for requesting an AXFR.
95 -func (dns *Msg) SetAxfr(z string) *Msg {
96 - dns.Id = Id()
97 - dns.Question = make([]Question, 1)
98 - dns.Question[0] = Question{z, TypeAXFR, ClassINET}
99 - return dns
100 -}
101 -
102 -// SetTsig appends a TSIG RR to the message.
103 -// This is only a skeleton TSIG RR that is added as the last RR in the
104 -// additional section. The Tsig is calculated when the message is being send.
105 -func (dns *Msg) SetTsig(z, algo string, fudge, timesigned int64) *Msg {
106 - t := new(TSIG)
107 - t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
108 - t.Algorithm = algo
109 - t.Fudge = 300
110 - t.TimeSigned = uint64(timesigned)
111 - t.OrigId = dns.Id
112 - dns.Extra = append(dns.Extra, t)
113 - return dns
114 -}
115 -
116 -// SetEdns0 appends a EDNS0 OPT RR to the message.
117 -// TSIG should always the last RR in a message.
118 -func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg {
119 - e := new(OPT)
120 - e.Hdr.Name = "."
121 - e.Hdr.Rrtype = TypeOPT
122 - e.SetUDPSize(udpsize)
123 - if do {
124 - e.SetDo()
125 - }
126 - dns.Extra = append(dns.Extra, e)
127 - return dns
128 -}
129 -
130 -// IsTsig checks if the message has a TSIG record as the last record
131 -// in the additional section. It returns the TSIG record found or nil.
132 -func (dns *Msg) IsTsig() *TSIG {
133 - if len(dns.Extra) > 0 {
134 - if dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG {
135 - return dns.Extra[len(dns.Extra)-1].(*TSIG)
136 - }
137 - }
138 - return nil
139 -}
140 -
141 -// IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0
142 -// record in the additional section will do. It returns the OPT record
143 -// found or nil.
144 -func (dns *Msg) IsEdns0() *OPT {
145 - for _, r := range dns.Extra {
146 - if r.Header().Rrtype == TypeOPT {
147 - return r.(*OPT)
148 - }
149 - }
150 - return nil
151 -}
152 -
153 -// IsDomainName checks if s is a valid domainname, it returns
154 -// the number of labels and true, when a domain name is valid.
155 -// Note that non fully qualified domain name is considered valid, in this case the
156 -// last label is counted in the number of labels.
157 -// When false is returned the number of labels is not defined.
158 -func IsDomainName(s string) (labels int, ok bool) {
159 - _, labels, err := packDomainName(s, nil, 0, nil, false)
160 - return labels, err == nil
161 -}
162 -
163 -// IsSubDomain checks if child is indeed a child of the parent. Both child and
164 -// parent are *not* downcased before doing the comparison.
165 -func IsSubDomain(parent, child string) bool {
166 - // Entire child is contained in parent
167 - return CompareDomainName(parent, child) == CountLabel(parent)
168 -}
169 -
170 -// IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet.
171 -// The checking is performed on the binary payload.
172 -func IsMsg(buf []byte) error {
173 - // Header
174 - if len(buf) < 12 {
175 - return errors.New("dns: bad message header")
176 - }
177 - // Header: Opcode
178 - // TODO(miek): more checks here, e.g. check all header bits.
179 - return nil
180 -}
181 -
182 -// IsFqdn checks if a domain name is fully qualified.
183 -func IsFqdn(s string) bool {
184 - l := len(s)
185 - if l == 0 {
186 - return false
187 - }
188 - return s[l-1] == '.'
189 -}
190 -
191 -// Fqdn return the fully qualified domain name from s.
192 -// If s is already fully qualified, it behaves as the identity function.
193 -func Fqdn(s string) string {
194 - if IsFqdn(s) {
195 - return s
196 - }
197 - return s + "."
198 -}
199 -
200 -// Copied from the official Go code.
201 -
202 -// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
203 -// address suitable for reverse DNS (PTR) record lookups or an error if it fails
204 -// to parse the IP address.
205 -func ReverseAddr(addr string) (arpa string, err error) {
206 - ip := net.ParseIP(addr)
207 - if ip == nil {
208 - return "", &Error{err: "unrecognized address: " + addr}
209 - }
210 - if ip.To4() != nil {
211 - return strconv.Itoa(int(ip[15])) + "." + strconv.Itoa(int(ip[14])) + "." + strconv.Itoa(int(ip[13])) + "." +
212 - strconv.Itoa(int(ip[12])) + ".in-addr.arpa.", nil
213 - }
214 - // Must be IPv6
215 - buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
216 - // Add it, in reverse, to the buffer
217 - for i := len(ip) - 1; i >= 0; i-- {
218 - v := ip[i]
219 - buf = append(buf, hexDigit[v&0xF])
220 - buf = append(buf, '.')
221 - buf = append(buf, hexDigit[v>>4])
222 - buf = append(buf, '.')
223 - }
224 - // Append "ip6.arpa." and return (buf already has the final .)
225 - buf = append(buf, "ip6.arpa."...)
226 - return string(buf), nil
227 -}
228 -
229 -// String returns the string representation for the type t.
230 -func (t Type) String() string {
231 - if t1, ok := TypeToString[uint16(t)]; ok {
232 - return t1
233 - }
234 - return "TYPE" + strconv.Itoa(int(t))
235 -}
236 -
237 -// String returns the string representation for the class c.
238 -func (c Class) String() string {
239 - if c1, ok := ClassToString[uint16(c)]; ok {
240 - return c1
241 - }
242 - return "CLASS" + strconv.Itoa(int(c))
243 -}
244 -
245 -// String returns the string representation for the name n.
246 -func (n Name) String() string {
247 - return sprintName(string(n))
248 -}
Godeps/_workspace/src/github.com/miekg/dns/dns.go deleted
-102
@@ -1,102 +0,0 @@
1 -package dns
2 -
3 -import "strconv"
4 -
5 -const (
6 - year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
7 - // DefaultMsgSize is the standard default for messages larger than 512 bytes.
8 - DefaultMsgSize = 4096
9 - // MinMsgSize is the minimal size of a DNS packet.
10 - MinMsgSize = 512
11 - // MaxMsgSize is the largest possible DNS packet.
12 - MaxMsgSize = 65535
13 - defaultTtl = 3600 // Default internal TTL.
14 -)
15 -
16 -// Error represents a DNS error
17 -type Error struct{ err string }
18 -
19 -func (e *Error) Error() string {
20 - if e == nil {
21 - return "dns: <nil>"
22 - }
23 - return "dns: " + e.err
24 -}
25 -
26 -// An RR represents a resource record.
27 -type RR interface {
28 - // Header returns the header of an resource record. The header contains
29 - // everything up to the rdata.
30 - Header() *RR_Header
31 - // String returns the text representation of the resource record.
32 - String() string
33 - // copy returns a copy of the RR
34 - copy() RR
35 - // len returns the length (in octets) of the uncompressed RR in wire format.
36 - len() int
37 -}
38 -
39 -// DNS resource records.
40 -// There are many types of RRs,
41 -// but they all share the same header.
42 -type RR_Header struct {
43 - Name string `dns:"cdomain-name"`
44 - Rrtype uint16
45 - Class uint16
46 - Ttl uint32
47 - Rdlength uint16 // length of data after header
48 -}
49 -
50 -// Header returns itself. This is here to make RR_Header implement the RR interface.
51 -func (h *RR_Header) Header() *RR_Header { return h }
52 -
53 -// Just to imlement the RR interface.
54 -func (h *RR_Header) copy() RR { return nil }
55 -
56 -func (h *RR_Header) copyHeader() *RR_Header {
57 - r := new(RR_Header)
58 - r.Name = h.Name
59 - r.Rrtype = h.Rrtype
60 - r.Class = h.Class
61 - r.Ttl = h.Ttl
62 - r.Rdlength = h.Rdlength
63 - return r
64 -}
65 -
66 -func (h *RR_Header) String() string {
67 - var s string
68 -
69 - if h.Rrtype == TypeOPT {
70 - s = ";"
71 - // and maybe other things
72 - }
73 -
74 - s += sprintName(h.Name) + "\t"
75 - s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
76 - s += Class(h.Class).String() + "\t"
77 - s += Type(h.Rrtype).String() + "\t"
78 - return s
79 -}
80 -
81 -func (h *RR_Header) len() int {
82 - l := len(h.Name) + 1
83 - l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2)
84 - return l
85 -}
86 -
87 -// ToRFC3597 converts a known RR to the unknown RR representation
88 -// from RFC 3597.
89 -func (rr *RFC3597) ToRFC3597(r RR) error {
90 - buf := make([]byte, r.len()*2)
91 - off, err := PackStruct(r, buf, 0)
92 - if err != nil {
93 - return err
94 - }
95 - buf = buf[:off]
96 - rawSetRdlength(buf, 0, off)
97 - _, err = UnpackStruct(rr, buf, 0)
98 - if err != nil {
99 - return err
100 - }
101 - return nil
102 -}
Godeps/_workspace/src/github.com/miekg/dns/dns_test.go deleted
-581
@@ -1,581 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "encoding/hex"
5 - "net"
6 - "testing"
7 -)
8 -
9 -func TestPackUnpack(t *testing.T) {
10 - out := new(Msg)
11 - out.Answer = make([]RR, 1)
12 - key := new(DNSKEY)
13 - key = &DNSKEY{Flags: 257, Protocol: 3, Algorithm: RSASHA1}
14 - key.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 3600}
15 - key.PublicKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
16 -
17 - out.Answer[0] = key
18 - msg, err := out.Pack()
19 - if err != nil {
20 - t.Error("failed to pack msg with DNSKEY")
21 - }
22 - in := new(Msg)
23 - if in.Unpack(msg) != nil {
24 - t.Error("failed to unpack msg with DNSKEY")
25 - }
26 -
27 - sig := new(RRSIG)
28 - sig = &RRSIG{TypeCovered: TypeDNSKEY, Algorithm: RSASHA1, Labels: 2,
29 - OrigTtl: 3600, Expiration: 4000, Inception: 4000, KeyTag: 34641, SignerName: "miek.nl.",
30 - Signature: "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"}
31 - sig.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeRRSIG, Class: ClassINET, Ttl: 3600}
32 -
33 - out.Answer[0] = sig
34 - msg, err = out.Pack()
35 - if err != nil {
36 - t.Error("failed to pack msg with RRSIG")
37 - }
38 -
39 - if in.Unpack(msg) != nil {
40 - t.Error("failed to unpack msg with RRSIG")
41 - }
42 -}
43 -
44 -func TestPackUnpack2(t *testing.T) {
45 - m := new(Msg)
46 - m.Extra = make([]RR, 1)
47 - m.Answer = make([]RR, 1)
48 - dom := "miek.nl."
49 - rr := new(A)
50 - rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
51 - rr.A = net.IPv4(127, 0, 0, 1)
52 -
53 - x := new(TXT)
54 - x.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
55 - x.Txt = []string{"heelalaollo"}
56 -
57 - m.Extra[0] = x
58 - m.Answer[0] = rr
59 - _, err := m.Pack()
60 - if err != nil {
61 - t.Error("Packing failed: ", err)
62 - return
63 - }
64 -}
65 -
66 -func TestPackUnpack3(t *testing.T) {
67 - m := new(Msg)
68 - m.Extra = make([]RR, 2)
69 - m.Answer = make([]RR, 1)
70 - dom := "miek.nl."
71 - rr := new(A)
72 - rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
73 - rr.A = net.IPv4(127, 0, 0, 1)
74 -
75 - x1 := new(TXT)
76 - x1.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
77 - x1.Txt = []string{}
78 -
79 - x2 := new(TXT)
80 - x2.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
81 - x2.Txt = []string{"heelalaollo"}
82 -
83 - m.Extra[0] = x1
84 - m.Extra[1] = x2
85 - m.Answer[0] = rr
86 - b, err := m.Pack()
87 - if err != nil {
88 - t.Error("packing failed: ", err)
89 - return
90 - }
91 -
92 - var unpackMsg Msg
93 - err = unpackMsg.Unpack(b)
94 - if err != nil {
95 - t.Error("unpacking failed")
96 - return
97 - }
98 -}
99 -
100 -func TestBailiwick(t *testing.T) {
101 - yes := map[string]string{
102 - "miek.nl": "ns.miek.nl",
103 - ".": "miek.nl",
104 - }
105 - for parent, child := range yes {
106 - if !IsSubDomain(parent, child) {
107 - t.Errorf("%s should be child of %s", child, parent)
108 - t.Errorf("comparelabels %d", CompareDomainName(parent, child))
109 - t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
110 - }
111 - }
112 - no := map[string]string{
113 - "www.miek.nl": "ns.miek.nl",
114 - "m\\.iek.nl": "ns.miek.nl",
115 - "w\\.iek.nl": "w.iek.nl",
116 - "p\\\\.iek.nl": "ns.p.iek.nl", // p\\.iek.nl , literal \ in domain name
117 - "miek.nl": ".",
118 - }
119 - for parent, child := range no {
120 - if IsSubDomain(parent, child) {
121 - t.Errorf("%s should not be child of %s", child, parent)
122 - t.Errorf("comparelabels %d", CompareDomainName(parent, child))
123 - t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
124 - }
125 - }
126 -}
127 -
128 -func TestPack(t *testing.T) {
129 - rr := []string{"US. 86400 IN NSEC 0-.us. NS SOA RRSIG NSEC DNSKEY TYPE65534"}
130 - m := new(Msg)
131 - var err error
132 - m.Answer = make([]RR, 1)
133 - for _, r := range rr {
134 - m.Answer[0], err = NewRR(r)
135 - if err != nil {
136 - t.Errorf("failed to create RR: %v", err)
137 - continue
138 - }
139 - if _, err := m.Pack(); err != nil {
140 - t.Errorf("packing failed: %v", err)
141 - }
142 - }
143 - x := new(Msg)
144 - ns, _ := NewRR("pool.ntp.org. 390 IN NS a.ntpns.org")
145 - ns.(*NS).Ns = "a.ntpns.org"
146 - x.Ns = append(m.Ns, ns)
147 - x.Ns = append(m.Ns, ns)
148 - x.Ns = append(m.Ns, ns)
149 - // This crashes due to the fact the a.ntpns.org isn't a FQDN
150 - // How to recover() from a remove panic()?
151 - if _, err := x.Pack(); err == nil {
152 - t.Error("packing should fail")
153 - }
154 - x.Answer = make([]RR, 1)
155 - x.Answer[0], err = NewRR(rr[0])
156 - if _, err := x.Pack(); err == nil {
157 - t.Error("packing should fail")
158 - }
159 - x.Question = make([]Question, 1)
160 - x.Question[0] = Question{";sd#edddds鍛↙赏‘℅∥↙xzztsestxssweewwsssstx@s@Z嵌e@cn.pool.ntp.org.", TypeA, ClassINET}
161 - if _, err := x.Pack(); err == nil {
162 - t.Error("packing should fail")
163 - }
164 -}
165 -
166 -func TestPackNAPTR(t *testing.T) {
167 - for _, n := range []string{
168 - `apple.com. IN NAPTR 100 50 "se" "SIP+D2U" "" _sip._udp.apple.com.`,
169 - `apple.com. IN NAPTR 90 50 "se" "SIP+D2T" "" _sip._tcp.apple.com.`,
170 - `apple.com. IN NAPTR 50 50 "se" "SIPS+D2T" "" _sips._tcp.apple.com.`,
171 - } {
172 - rr, _ := NewRR(n)
173 - msg := make([]byte, rr.len())
174 - if off, err := PackRR(rr, msg, 0, nil, false); err != nil {
175 - t.Errorf("packing failed: %v", err)
176 - t.Errorf("length %d, need more than %d", rr.len(), off)
177 - } else {
178 - t.Logf("buf size needed: %d", off)
179 - }
180 - }
181 -}
182 -
183 -func TestCompressLength(t *testing.T) {
184 - m := new(Msg)
185 - m.SetQuestion("miek.nl", TypeMX)
186 - ul := m.Len()
187 - m.Compress = true
188 - if ul != m.Len() {
189 - t.Fatalf("should be equal")
190 - }
191 -}
192 -
193 -// Does the predicted length match final packed length?
194 -func TestMsgCompressLength(t *testing.T) {
195 - makeMsg := func(question string, ans, ns, e []RR) *Msg {
196 - msg := new(Msg)
197 - msg.SetQuestion(Fqdn(question), TypeANY)
198 - msg.Answer = append(msg.Answer, ans...)
199 - msg.Ns = append(msg.Ns, ns...)
200 - msg.Extra = append(msg.Extra, e...)
201 - msg.Compress = true
202 - return msg
203 - }
204 -
205 - name1 := "12345678901234567890123456789012345.12345678.123."
206 - rrA, _ := NewRR(name1 + " 3600 IN A 192.0.2.1")
207 - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
208 - tests := []*Msg{
209 - makeMsg(name1, []RR{rrA}, nil, nil),
210 - makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)}
211 -
212 - for _, msg := range tests {
213 - predicted := msg.Len()
214 - buf, err := msg.Pack()
215 - if err != nil {
216 - t.Error(err)
217 - }
218 - if predicted < len(buf) {
219 - t.Errorf("predicted compressed length is wrong: predicted %s (len=%d) %d, actual %d",
220 - msg.Question[0].Name, len(msg.Answer), predicted, len(buf))
221 - }
222 - }
223 -}
224 -
225 -func TestMsgLength(t *testing.T) {
226 - makeMsg := func(question string, ans, ns, e []RR) *Msg {
227 - msg := new(Msg)
228 - msg.SetQuestion(Fqdn(question), TypeANY)
229 - msg.Answer = append(msg.Answer, ans...)
230 - msg.Ns = append(msg.Ns, ns...)
231 - msg.Extra = append(msg.Extra, e...)
232 - return msg
233 - }
234 -
235 - name1 := "12345678901234567890123456789012345.12345678.123."
236 - rrA, _ := NewRR(name1 + " 3600 IN A 192.0.2.1")
237 - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
238 - tests := []*Msg{
239 - makeMsg(name1, []RR{rrA}, nil, nil),
240 - makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)}
241 -
242 - for _, msg := range tests {
243 - predicted := msg.Len()
244 - buf, err := msg.Pack()
245 - if err != nil {
246 - t.Error(err)
247 - }
248 - if predicted < len(buf) {
249 - t.Errorf("predicted length is wrong: predicted %s (len=%d), actual %d",
250 - msg.Question[0].Name, predicted, len(buf))
251 - }
252 - }
253 -}
254 -
255 -func TestMsgLength2(t *testing.T) {
256 - // Serialized replies
257 - var testMessages = []string{
258 - // google.com. IN A?
259 - "064e81800001000b0004000506676f6f676c6503636f6d0000010001c00c00010001000000050004adc22986c00c00010001000000050004adc22987c00c00010001000000050004adc22988c00c00010001000000050004adc22989c00c00010001000000050004adc2298ec00c00010001000000050004adc22980c00c00010001000000050004adc22981c00c00010001000000050004adc22982c00c00010001000000050004adc22983c00c00010001000000050004adc22984c00c00010001000000050004adc22985c00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc0d800010001000000050004d8ef200ac0ea00010001000000050004d8ef220ac0fc00010001000000050004d8ef240ac10e00010001000000050004d8ef260a0000290500000000050000",
260 - // amazon.com. IN A? (reply has no EDNS0 record)
261 - // TODO(miek): this one is off-by-one, need to find out why
262 - //"6de1818000010004000a000806616d617a6f6e03636f6d0000010001c00c000100010000000500044815c2d4c00c000100010000000500044815d7e8c00c00010001000000050004b02062a6c00c00010001000000050004cdfbf236c00c000200010000000500140570646e733408756c747261646e73036f726700c00c000200010000000500150570646e733508756c747261646e7304696e666f00c00c000200010000000500160570646e733608756c747261646e7302636f02756b00c00c00020001000000050014036e7331037033310664796e656374036e657400c00c00020001000000050006036e7332c0cfc00c00020001000000050006036e7333c0cfc00c00020001000000050006036e7334c0cfc00c000200010000000500110570646e733108756c747261646e73c0dac00c000200010000000500080570646e7332c127c00c000200010000000500080570646e7333c06ec0cb00010001000000050004d04e461fc0eb00010001000000050004cc0dfa1fc0fd00010001000000050004d04e471fc10f00010001000000050004cc0dfb1fc12100010001000000050004cc4a6c01c121001c000100000005001020010502f3ff00000000000000000001c13e00010001000000050004cc4a6d01c13e001c0001000000050010261000a1101400000000000000000001",
263 - // yahoo.com. IN A?
264 - "fc2d81800001000300070008057961686f6f03636f6d0000010001c00c00010001000000050004628afd6dc00c00010001000000050004628bb718c00c00010001000000050004cebe242dc00c00020001000000050006036e7336c00cc00c00020001000000050006036e7338c00cc00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7335c00cc07b0001000100000005000444b48310c08d00010001000000050004448eff10c09f00010001000000050004cb54dd35c0b100010001000000050004628a0b9dc0c30001000100000005000477a0f77cc05700010001000000050004ca2bdfaac06900010001000000050004caa568160000290500000000050000",
265 - // microsoft.com. IN A?
266 - "f4368180000100020005000b096d6963726f736f667403636f6d0000010001c00c0001000100000005000440040b25c00c0001000100000005000441373ac9c00c0002000100000005000e036e7331046d736674036e657400c00c00020001000000050006036e7332c04fc00c00020001000000050006036e7333c04fc00c00020001000000050006036e7334c04fc00c00020001000000050006036e7335c04fc04b000100010000000500044137253ec04b001c00010000000500102a010111200500000000000000010001c0650001000100000005000440043badc065001c00010000000500102a010111200600060000000000010001c07700010001000000050004d5c7b435c077001c00010000000500102a010111202000000000000000010001c08900010001000000050004cf2e4bfec089001c00010000000500102404f800200300000000000000010001c09b000100010000000500044137e28cc09b001c00010000000500102a010111200f000100000000000100010000290500000000050000",
267 - // google.com. IN MX?
268 - "724b8180000100050004000b06676f6f676c6503636f6d00000f0001c00c000f000100000005000c000a056173706d78016cc00cc00c000f0001000000050009001404616c7431c02ac00c000f0001000000050009001e04616c7432c02ac00c000f0001000000050009002804616c7433c02ac00c000f0001000000050009003204616c7434c02ac00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7331c00cc02a00010001000000050004adc2421bc02a001c00010000000500102a00145040080c01000000000000001bc04200010001000000050004adc2461bc05700010001000000050004adc2451bc06c000100010000000500044a7d8f1bc081000100010000000500044a7d191bc0ca00010001000000050004d8ef200ac09400010001000000050004d8ef220ac0a600010001000000050004d8ef240ac0b800010001000000050004d8ef260a0000290500000000050000",
269 - // reddit.com. IN A?
270 - "12b98180000100080000000c0672656464697403636f6d0000020001c00c0002000100000005000f046175733204616b616d036e657400c00c000200010000000500070475736534c02dc00c000200010000000500070475737733c02dc00c000200010000000500070475737735c02dc00c00020001000000050008056173696131c02dc00c00020001000000050008056173696139c02dc00c00020001000000050008056e73312d31c02dc00c0002000100000005000a076e73312d313935c02dc02800010001000000050004c30a242ec04300010001000000050004451f1d39c05600010001000000050004451f3bc7c0690001000100000005000460073240c07c000100010000000500046007fb81c090000100010000000500047c283484c090001c00010000000500102a0226f0006700000000000000000064c0a400010001000000050004c16c5b01c0a4001c000100000005001026001401000200000000000000000001c0b800010001000000050004c16c5bc3c0b8001c0001000000050010260014010002000000000000000000c30000290500000000050000",
271 - }
272 -
273 - for i, hexData := range testMessages {
274 - // we won't fail the decoding of the hex
275 - input, _ := hex.DecodeString(hexData)
276 - m := new(Msg)
277 - m.Unpack(input)
278 - //println(m.String())
279 - m.Compress = true
280 - lenComp := m.Len()
281 - b, _ := m.Pack()
282 - pacComp := len(b)
283 - m.Compress = false
284 - lenUnComp := m.Len()
285 - b, _ = m.Pack()
286 - pacUnComp := len(b)
287 - if pacComp+1 != lenComp {
288 - t.Errorf("msg.Len(compressed)=%d actual=%d for test %d", lenComp, pacComp, i)
289 - }
290 - if pacUnComp+1 != lenUnComp {
291 - t.Errorf("msg.Len(uncompressed)=%d actual=%d for test %d", lenUnComp, pacUnComp, i)
292 - }
293 - }
294 -}
295 -
296 -func TestMsgLengthCompressionMalformed(t *testing.T) {
297 - // SOA with empty hostmaster, which is illegal
298 - soa := &SOA{Hdr: RR_Header{Name: ".", Rrtype: TypeSOA, Class: ClassINET, Ttl: 12345},
299 - Ns: ".",
300 - Mbox: "",
301 - Serial: 0,
302 - Refresh: 28800,
303 - Retry: 7200,
304 - Expire: 604800,
305 - Minttl: 60}
306 - m := new(Msg)
307 - m.Compress = true
308 - m.Ns = []RR{soa}
309 - m.Len() // Should not crash.
310 -}
311 -
312 -func BenchmarkMsgLength(b *testing.B) {
313 - b.StopTimer()
314 - makeMsg := func(question string, ans, ns, e []RR) *Msg {
315 - msg := new(Msg)
316 - msg.SetQuestion(Fqdn(question), TypeANY)
317 - msg.Answer = append(msg.Answer, ans...)
318 - msg.Ns = append(msg.Ns, ns...)
319 - msg.Extra = append(msg.Extra, e...)
320 - msg.Compress = true
321 - return msg
322 - }
323 - name1 := "12345678901234567890123456789012345.12345678.123."
324 - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
325 - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
326 - b.StartTimer()
327 - for i := 0; i < b.N; i++ {
328 - msg.Len()
329 - }
330 -}
331 -
332 -func BenchmarkMsgLengthPack(b *testing.B) {
333 - makeMsg := func(question string, ans, ns, e []RR) *Msg {
334 - msg := new(Msg)
335 - msg.SetQuestion(Fqdn(question), TypeANY)
336 - msg.Answer = append(msg.Answer, ans...)
337 - msg.Ns = append(msg.Ns, ns...)
338 - msg.Extra = append(msg.Extra, e...)
339 - msg.Compress = true
340 - return msg
341 - }
342 - name1 := "12345678901234567890123456789012345.12345678.123."
343 - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
344 - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
345 - b.ResetTimer()
346 - for i := 0; i < b.N; i++ {
347 - _, _ = msg.Pack()
348 - }
349 -}
350 -
351 -func BenchmarkMsgPackBuffer(b *testing.B) {
352 - makeMsg := func(question string, ans, ns, e []RR) *Msg {
353 - msg := new(Msg)
354 - msg.SetQuestion(Fqdn(question), TypeANY)
355 - msg.Answer = append(msg.Answer, ans...)
356 - msg.Ns = append(msg.Ns, ns...)
357 - msg.Extra = append(msg.Extra, e...)
358 - msg.Compress = true
359 - return msg
360 - }
361 - name1 := "12345678901234567890123456789012345.12345678.123."
362 - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
363 - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
364 - buf := make([]byte, 512)
365 - b.ResetTimer()
366 - for i := 0; i < b.N; i++ {
367 - _, _ = msg.PackBuffer(buf)
368 - }
369 -}
370 -
371 -func BenchmarkMsgUnpack(b *testing.B) {
372 - makeMsg := func(question string, ans, ns, e []RR) *Msg {
373 - msg := new(Msg)
374 - msg.SetQuestion(Fqdn(question), TypeANY)
375 - msg.Answer = append(msg.Answer, ans...)
376 - msg.Ns = append(msg.Ns, ns...)
377 - msg.Extra = append(msg.Extra, e...)
378 - msg.Compress = true
379 - return msg
380 - }
381 - name1 := "12345678901234567890123456789012345.12345678.123."
382 - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1)
383 - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)
384 - msgBuf, _ := msg.Pack()
385 - b.ResetTimer()
386 - for i := 0; i < b.N; i++ {
387 - _ = msg.Unpack(msgBuf)
388 - }
389 -}
390 -
391 -func BenchmarkPackDomainName(b *testing.B) {
392 - name1 := "12345678901234567890123456789012345.12345678.123."
393 - buf := make([]byte, len(name1)+1)
394 - b.ResetTimer()
395 - for i := 0; i < b.N; i++ {
396 - _, _ = PackDomainName(name1, buf, 0, nil, false)
397 - }
398 -}
399 -
400 -func BenchmarkUnpackDomainName(b *testing.B) {
401 - name1 := "12345678901234567890123456789012345.12345678.123."
402 - buf := make([]byte, len(name1)+1)
403 - _, _ = PackDomainName(name1, buf, 0, nil, false)
404 - b.ResetTimer()
405 - for i := 0; i < b.N; i++ {
406 - _, _, _ = UnpackDomainName(buf, 0)
407 - }
408 -}
409 -
410 -func BenchmarkUnpackDomainNameUnprintable(b *testing.B) {
411 - name1 := "\x02\x02\x02\x025\x02\x02\x02\x02.12345678.123."
412 - buf := make([]byte, len(name1)+1)
413 - _, _ = PackDomainName(name1, buf, 0, nil, false)
414 - b.ResetTimer()
415 - for i := 0; i < b.N; i++ {
416 - _, _, _ = UnpackDomainName(buf, 0)
417 - }
418 -}
419 -
420 -func TestToRFC3597(t *testing.T) {
421 - a, _ := NewRR("miek.nl. IN A 10.0.1.1")
422 - x := new(RFC3597)
423 - x.ToRFC3597(a)
424 - if x.String() != `miek.nl. 3600 CLASS1 TYPE1 \# 4 0a000101` {
425 - t.Error("string mismatch")
426 - }
427 -}
428 -
429 -func TestNoRdataPack(t *testing.T) {
430 - data := make([]byte, 1024)
431 - for typ, fn := range typeToRR {
432 - if typ == TypeCAA {
433 - continue // TODO(miek): known omission
434 - }
435 - r := fn()
436 - *r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 3600}
437 - _, err := PackRR(r, data, 0, nil, false)
438 - if err != nil {
439 - t.Errorf("failed to pack RR with zero rdata: %s: %v", TypeToString[typ], err)
440 - }
441 - }
442 -}
443 -
444 -// TODO(miek): fix dns buffer too small errors this throws
445 -func TestNoRdataUnpack(t *testing.T) {
446 - data := make([]byte, 1024)
447 - for typ, fn := range typeToRR {
448 - if typ == TypeSOA || typ == TypeTSIG || typ == TypeWKS {
449 - // SOA, TSIG will not be seen (like this) in dyn. updates?
450 - // WKS is an bug, but...deprecated record.
451 - continue
452 - }
453 - r := fn()
454 - *r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 3600}
455 - off, err := PackRR(r, data, 0, nil, false)
456 - if err != nil {
457 - // Should always works, TestNoDataPack should have caught this
458 - t.Errorf("failed to pack RR: %v", err)
459 - continue
460 - }
461 - rr, _, err := UnpackRR(data[:off], 0)
462 - if err != nil {
463 - t.Errorf("failed to unpack RR with zero rdata: %s: %v", TypeToString[typ], err)
464 - }
465 - t.Log(rr)
466 - }
467 -}
468 -
469 -func TestRdataOverflow(t *testing.T) {
470 - rr := new(RFC3597)
471 - rr.Hdr.Name = "."
472 - rr.Hdr.Class = ClassINET
473 - rr.Hdr.Rrtype = 65280
474 - rr.Rdata = hex.EncodeToString(make([]byte, 0xFFFF))
475 - buf := make([]byte, 0xFFFF*2)
476 - if _, err := PackRR(rr, buf, 0, nil, false); err != nil {
477 - t.Fatalf("maximum size rrdata pack failed: %v", err)
478 - }
479 - rr.Rdata += "00"
480 - if _, err := PackRR(rr, buf, 0, nil, false); err != ErrRdata {
481 - t.Fatalf("oversize rrdata pack didn't return ErrRdata - instead: %v", err)
482 - }
483 -}
484 -
485 -func TestCopy(t *testing.T) {
486 - rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1") // Weird TTL to avoid catching TTL
487 - rr1 := Copy(rr)
488 - if rr.String() != rr1.String() {
489 - t.Fatalf("Copy() failed %s != %s", rr.String(), rr1.String())
490 - }
491 -}
492 -
493 -func TestMsgCopy(t *testing.T) {
494 - m := new(Msg)
495 - m.SetQuestion("miek.nl.", TypeA)
496 - rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1")
497 - m.Answer = []RR{rr}
498 - rr, _ = NewRR("miek.nl. 2311 IN NS 127.0.0.1")
499 - m.Ns = []RR{rr}
500 -
501 - m1 := m.Copy()
502 - if m.String() != m1.String() {
503 - t.Fatalf("Msg.Copy() failed %s != %s", m.String(), m1.String())
504 - }
505 -
506 - m1.Answer[0], _ = NewRR("somethingelse.nl. 2311 IN A 127.0.0.1")
507 - if m.String() == m1.String() {
508 - t.Fatalf("Msg.Copy() failed; change to copy changed template %s", m.String())
509 - }
510 -
511 - rr, _ = NewRR("miek.nl. 2311 IN A 127.0.0.2")
512 - m1.Answer = append(m1.Answer, rr)
513 - if m1.Ns[0].String() == m1.Answer[1].String() {
514 - t.Fatalf("Msg.Copy() failed; append changed underlying array %s", m1.Ns[0].String())
515 - }
516 -}
517 -
518 -func BenchmarkCopy(b *testing.B) {
519 - b.ReportAllocs()
520 - m := new(Msg)
521 - m.SetQuestion("miek.nl.", TypeA)
522 - rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1")
523 - m.Answer = []RR{rr}
524 - rr, _ = NewRR("miek.nl. 2311 IN NS 127.0.0.1")
525 - m.Ns = []RR{rr}
526 - rr, _ = NewRR("miek.nl. 2311 IN A 127.0.0.1")
527 - m.Extra = []RR{rr}
528 -
529 - b.ResetTimer()
530 - for i := 0; i < b.N; i++ {
531 - m.Copy()
532 - }
533 -}
534 -
535 -func TestPackIPSECKEY(t *testing.T) {
536 - tests := []string{
537 - "38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
538 - "38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
539 - "38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
540 - "38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
541 - "0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
542 - }
543 - buf := make([]byte, 1024)
544 - for _, t1 := range tests {
545 - rr, _ := NewRR(t1)
546 - off, err := PackRR(rr, buf, 0, nil, false)
547 - if err != nil {
548 - t.Errorf("failed to pack IPSECKEY %v: %s", err, t1)
549 - continue
550 - }
551 -
552 - rr, _, err = UnpackRR(buf[:off], 0)
553 - if err != nil {
554 - t.Errorf("failed to unpack IPSECKEY %v: %s", err, t1)
555 - }
556 - t.Log(rr)
557 - }
558 -}
559 -
560 -func TestMsgPackBuffer(t *testing.T) {
561 - var testMessages = []string{
562 - // news.ycombinator.com.in.escapemg.com. IN A, response
563 - "586285830001000000010000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001c0210006000100000e10002c036e7332c02103646e730b67726f6f7665736861726bc02d77ed50e600002a3000000e1000093a8000000e10",
564 -
565 - // news.ycombinator.com.in.escapemg.com. IN A, question
566 - "586201000001000000000000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001",
567 -
568 - "398781020001000000000000046e6577730b79636f6d62696e61746f7203636f6d0000010001",
569 - }
570 -
571 - for i, hexData := range testMessages {
572 - // we won't fail the decoding of the hex
573 - input, _ := hex.DecodeString(hexData)
574 - m := new(Msg)
575 - if err := m.Unpack(input); err != nil {
576 - t.Errorf("packet %d failed to unpack", i)
577 - continue
578 - }
579 - t.Logf("packet %d %s", i, m.String())
580 - }
581 -}
Godeps/_workspace/src/github.com/miekg/dns/dnssec.go deleted
-634
@@ -1,634 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "bytes"
5 - "crypto"
6 - "crypto/dsa"
7 - "crypto/ecdsa"
8 - "crypto/elliptic"
9 - "crypto/md5"
10 - "crypto/rsa"
11 - "crypto/sha1"
12 - "crypto/sha256"
13 - "crypto/sha512"
14 - "encoding/hex"
15 - "hash"
16 - "io"
17 - "math/big"
18 - "sort"
19 - "strings"
20 - "time"
21 -)
22 -
23 -// DNSSEC encryption algorithm codes.
24 -const (
25 - _ uint8 = iota
26 - RSAMD5
27 - DH
28 - DSA
29 - _ // Skip 4, RFC 6725, section 2.1
30 - RSASHA1
31 - DSANSEC3SHA1
32 - RSASHA1NSEC3SHA1
33 - RSASHA256
34 - _ // Skip 9, RFC 6725, section 2.1
35 - RSASHA512
36 - _ // Skip 11, RFC 6725, section 2.1
37 - ECCGOST
38 - ECDSAP256SHA256
39 - ECDSAP384SHA384
40 - INDIRECT uint8 = 252
41 - PRIVATEDNS uint8 = 253 // Private (experimental keys)
42 - PRIVATEOID uint8 = 254
43 -)
44 -
45 -// DNSSEC hashing algorithm codes.
46 -const (
47 - _ uint8 = iota
48 - SHA1 // RFC 4034
49 - SHA256 // RFC 4509
50 - GOST94 // RFC 5933
51 - SHA384 // Experimental
52 - SHA512 // Experimental
53 -)
54 -
55 -// DNSKEY flag values.
56 -const (
57 - SEP = 1
58 - REVOKE = 1 << 7
59 - ZONE = 1 << 8
60 -)
61 -
62 -// The RRSIG needs to be converted to wireformat with some of
63 -// the rdata (the signature) missing. Use this struct to easy
64 -// the conversion (and re-use the pack/unpack functions).
65 -type rrsigWireFmt struct {
66 - TypeCovered uint16
67 - Algorithm uint8
68 - Labels uint8
69 - OrigTtl uint32
70 - Expiration uint32
71 - Inception uint32
72 - KeyTag uint16
73 - SignerName string `dns:"domain-name"`
74 - /* No Signature */
75 -}
76 -
77 -// Used for converting DNSKEY's rdata to wirefmt.
78 -type dnskeyWireFmt struct {
79 - Flags uint16
80 - Protocol uint8
81 - Algorithm uint8
82 - PublicKey string `dns:"base64"`
83 - /* Nothing is left out */
84 -}
85 -
86 -func divRoundUp(a, b int) int {
87 - return (a + b - 1) / b
88 -}
89 -
90 -// KeyTag calculates the keytag (or key-id) of the DNSKEY.
91 -func (k *DNSKEY) KeyTag() uint16 {
92 - if k == nil {
93 - return 0
94 - }
95 - var keytag int
96 - switch k.Algorithm {
97 - case RSAMD5:
98 - // Look at the bottom two bytes of the modules, which the last
99 - // item in the pubkey. We could do this faster by looking directly
100 - // at the base64 values. But I'm lazy.
101 - modulus, _ := fromBase64([]byte(k.PublicKey))
102 - if len(modulus) > 1 {
103 - x, _ := unpackUint16(modulus, len(modulus)-2)
104 - keytag = int(x)
105 - }
106 - default:
107 - keywire := new(dnskeyWireFmt)
108 - keywire.Flags = k.Flags
109 - keywire.Protocol = k.Protocol
110 - keywire.Algorithm = k.Algorithm
111 - keywire.PublicKey = k.PublicKey
112 - wire := make([]byte, DefaultMsgSize)
113 - n, err := PackStruct(keywire, wire, 0)
114 - if err != nil {
115 - return 0
116 - }
117 - wire = wire[:n]
118 - for i, v := range wire {
119 - if i&1 != 0 {
120 - keytag += int(v) // must be larger than uint32
121 - } else {
122 - keytag += int(v) << 8
123 - }
124 - }
125 - keytag += (keytag >> 16) & 0xFFFF
126 - keytag &= 0xFFFF
127 - }
128 - return uint16(keytag)
129 -}
130 -
131 -// ToDS converts a DNSKEY record to a DS record.
132 -func (k *DNSKEY) ToDS(h uint8) *DS {
133 - if k == nil {
134 - return nil
135 - }
136 - ds := new(DS)
137 - ds.Hdr.Name = k.Hdr.Name
138 - ds.Hdr.Class = k.Hdr.Class
139 - ds.Hdr.Rrtype = TypeDS
140 - ds.Hdr.Ttl = k.Hdr.Ttl
141 - ds.Algorithm = k.Algorithm
142 - ds.DigestType = h
143 - ds.KeyTag = k.KeyTag()
144 -
145 - keywire := new(dnskeyWireFmt)
146 - keywire.Flags = k.Flags
147 - keywire.Protocol = k.Protocol
148 - keywire.Algorithm = k.Algorithm
149 - keywire.PublicKey = k.PublicKey
150 - wire := make([]byte, DefaultMsgSize)
151 - n, err := PackStruct(keywire, wire, 0)
152 - if err != nil {
153 - return nil
154 - }
155 - wire = wire[:n]
156 -
157 - owner := make([]byte, 255)
158 - off, err1 := PackDomainName(strings.ToLower(k.Hdr.Name), owner, 0, nil, false)
159 - if err1 != nil {
160 - return nil
161 - }
162 - owner = owner[:off]
163 - // RFC4034:
164 - // digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
165 - // "|" denotes concatenation
166 - // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
167 -
168 - // digest buffer
169 - digest := append(owner, wire...) // another copy
170 -
171 - switch h {
172 - case SHA1:
173 - s := sha1.New()
174 - io.WriteString(s, string(digest))
175 - ds.Digest = hex.EncodeToString(s.Sum(nil))
176 - case SHA256:
177 - s := sha256.New()
178 - io.WriteString(s, string(digest))
179 - ds.Digest = hex.EncodeToString(s.Sum(nil))
180 - case SHA384:
181 - s := sha512.New384()
182 - io.WriteString(s, string(digest))
183 - ds.Digest = hex.EncodeToString(s.Sum(nil))
184 - case GOST94:
185 - /* I have no clue */
186 - default:
187 - return nil
188 - }
189 - return ds
190 -}
191 -
192 -// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record.
193 -func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
194 - c := &CDNSKEY{DNSKEY: *k}
195 - c.Hdr = *k.Hdr.copyHeader()
196 - c.Hdr.Rrtype = TypeCDNSKEY
197 - return c
198 -}
199 -
200 -// ToCDS converts a DS record to a CDS record.
201 -func (d *DS) ToCDS() *CDS {
202 - c := &CDS{DS: *d}
203 - c.Hdr = *d.Hdr.copyHeader()
204 - c.Hdr.Rrtype = TypeCDS
205 - return c
206 -}
207 -
208 -// Sign signs an RRSet. The signature needs to be filled in with
209 -// the values: Inception, Expiration, KeyTag, SignerName and Algorithm.
210 -// The rest is copied from the RRset. Sign returns true when the signing went OK,
211 -// otherwise false.
212 -// There is no check if RRSet is a proper (RFC 2181) RRSet.
213 -// If OrigTTL is non zero, it is used as-is, otherwise the TTL of the RRset
214 -// is used as the OrigTTL.
215 -func (rr *RRSIG) Sign(k PrivateKey, rrset []RR) error {
216 - if k == nil {
217 - return ErrPrivKey
218 - }
219 - // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set
220 - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
221 - return ErrKey
222 - }
223 -
224 - rr.Hdr.Rrtype = TypeRRSIG
225 - rr.Hdr.Name = rrset[0].Header().Name
226 - rr.Hdr.Class = rrset[0].Header().Class
227 - if rr.OrigTtl == 0 { // If set don't override
228 - rr.OrigTtl = rrset[0].Header().Ttl
229 - }
230 - rr.TypeCovered = rrset[0].Header().Rrtype
231 - rr.Labels = uint8(CountLabel(rrset[0].Header().Name))
232 -
233 - if strings.HasPrefix(rrset[0].Header().Name, "*") {
234 - rr.Labels-- // wildcard, remove from label count
235 - }
236 -
237 - sigwire := new(rrsigWireFmt)
238 - sigwire.TypeCovered = rr.TypeCovered
239 - sigwire.Algorithm = rr.Algorithm
240 - sigwire.Labels = rr.Labels
241 - sigwire.OrigTtl = rr.OrigTtl
242 - sigwire.Expiration = rr.Expiration
243 - sigwire.Inception = rr.Inception
244 - sigwire.KeyTag = rr.KeyTag
245 - // For signing, lowercase this name
246 - sigwire.SignerName = strings.ToLower(rr.SignerName)
247 -
248 - // Create the desired binary blob
249 - signdata := make([]byte, DefaultMsgSize)
250 - n, err := PackStruct(sigwire, signdata, 0)
251 - if err != nil {
252 - return err
253 - }
254 - signdata = signdata[:n]
255 - wire, err := rawSignatureData(rrset, rr)
256 - if err != nil {
257 - return err
258 - }
259 - signdata = append(signdata, wire...)
260 -
261 - var h hash.Hash
262 - switch rr.Algorithm {
263 - case DSA, DSANSEC3SHA1:
264 - // TODO: this seems bugged, will panic
265 - case RSASHA1, RSASHA1NSEC3SHA1:
266 - h = sha1.New()
267 - case RSASHA256, ECDSAP256SHA256:
268 - h = sha256.New()
269 - case ECDSAP384SHA384:
270 - h = sha512.New384()
271 - case RSASHA512:
272 - h = sha512.New()
273 - case RSAMD5:
274 - fallthrough // Deprecated in RFC 6725
275 - default:
276 - return ErrAlg
277 - }
278 -
279 - _, err = h.Write(signdata)
280 - if err != nil {
281 - return err
282 - }
283 - sighash := h.Sum(nil)
284 -
285 - signature, err := k.Sign(sighash, rr.Algorithm)
286 - if err != nil {
287 - return err
288 - }
289 - rr.Signature = toBase64(signature)
290 -
291 - return nil
292 -}
293 -
294 -// Verify validates an RRSet with the signature and key. This is only the
295 -// cryptographic test, the signature validity period must be checked separately.
296 -// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work.
297 -func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
298 - // First the easy checks
299 - if len(rrset) == 0 {
300 - return ErrRRset
301 - }
302 - if rr.KeyTag != k.KeyTag() {
303 - return ErrKey
304 - }
305 - if rr.Hdr.Class != k.Hdr.Class {
306 - return ErrKey
307 - }
308 - if rr.Algorithm != k.Algorithm {
309 - return ErrKey
310 - }
311 - if strings.ToLower(rr.SignerName) != strings.ToLower(k.Hdr.Name) {
312 - return ErrKey
313 - }
314 - if k.Protocol != 3 {
315 - return ErrKey
316 - }
317 - for _, r := range rrset {
318 - if r.Header().Class != rr.Hdr.Class {
319 - return ErrRRset
320 - }
321 - if r.Header().Rrtype != rr.TypeCovered {
322 - return ErrRRset
323 - }
324 - }
325 - // RFC 4035 5.3.2. Reconstructing the Signed Data
326 - // Copy the sig, except the rrsig data
327 - sigwire := new(rrsigWireFmt)
328 - sigwire.TypeCovered = rr.TypeCovered
329 - sigwire.Algorithm = rr.Algorithm
330 - sigwire.Labels = rr.Labels
331 - sigwire.OrigTtl = rr.OrigTtl
332 - sigwire.Expiration = rr.Expiration
333 - sigwire.Inception = rr.Inception
334 - sigwire.KeyTag = rr.KeyTag
335 - sigwire.SignerName = strings.ToLower(rr.SignerName)
336 - // Create the desired binary blob
337 - signeddata := make([]byte, DefaultMsgSize)
338 - n, err := PackStruct(sigwire, signeddata, 0)
339 - if err != nil {
340 - return err
341 - }
342 - signeddata = signeddata[:n]
343 - wire, err := rawSignatureData(rrset, rr)
344 - if err != nil {
345 - return err
346 - }
347 - signeddata = append(signeddata, wire...)
348 -
349 - sigbuf := rr.sigBuf() // Get the binary signature data
350 - if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
351 - // TODO(mg)
352 - // remove the domain name and assume its our
353 - }
354 -
355 - switch rr.Algorithm {
356 - case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5:
357 - // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere??
358 - pubkey := k.publicKeyRSA() // Get the key
359 - if pubkey == nil {
360 - return ErrKey
361 - }
362 - // Setup the hash as defined for this alg.
363 - var h hash.Hash
364 - var ch crypto.Hash
365 - switch rr.Algorithm {
366 - case RSAMD5:
367 - h = md5.New()
368 - ch = crypto.MD5
369 - case RSASHA1, RSASHA1NSEC3SHA1:
370 - h = sha1.New()
371 - ch = crypto.SHA1
372 - case RSASHA256:
373 - h = sha256.New()
374 - ch = crypto.SHA256
375 - case RSASHA512:
376 - h = sha512.New()
377 - ch = crypto.SHA512
378 - }
379 - io.WriteString(h, string(signeddata))
380 - sighash := h.Sum(nil)
381 - return rsa.VerifyPKCS1v15(pubkey, ch, sighash, sigbuf)
382 - case ECDSAP256SHA256, ECDSAP384SHA384:
383 - pubkey := k.publicKeyECDSA()
384 - if pubkey == nil {
385 - return ErrKey
386 - }
387 - var h hash.Hash
388 - switch rr.Algorithm {
389 - case ECDSAP256SHA256:
390 - h = sha256.New()
391 - case ECDSAP384SHA384:
392 - h = sha512.New384()
393 - }
394 - io.WriteString(h, string(signeddata))
395 - sighash := h.Sum(nil)
396 - // Split sigbuf into the r and s coordinates
397 - r := big.NewInt(0)
398 - r.SetBytes(sigbuf[:len(sigbuf)/2])
399 - s := big.NewInt(0)
400 - s.SetBytes(sigbuf[len(sigbuf)/2:])
401 - if ecdsa.Verify(pubkey, sighash, r, s) {
402 - return nil
403 - }
404 - return ErrSig
405 - }
406 - // Unknown alg
407 - return ErrAlg
408 -}
409 -
410 -// ValidityPeriod uses RFC1982 serial arithmetic to calculate
411 -// if a signature period is valid. If t is the zero time, the
412 -// current time is taken other t is.
413 -func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
414 - var utc int64
415 - if t.IsZero() {
416 - utc = time.Now().UTC().Unix()
417 - } else {
418 - utc = t.UTC().Unix()
419 - }
420 - modi := (int64(rr.Inception) - utc) / year68
421 - mode := (int64(rr.Expiration) - utc) / year68
422 - ti := int64(rr.Inception) + (modi * year68)
423 - te := int64(rr.Expiration) + (mode * year68)
424 - return ti <= utc && utc <= te
425 -}
426 -
427 -// Return the signatures base64 encodedig sigdata as a byte slice.
428 -func (rr *RRSIG) sigBuf() []byte {
429 - sigbuf, err := fromBase64([]byte(rr.Signature))
430 - if err != nil {
431 - return nil
432 - }
433 - return sigbuf
434 -}
435 -
436 -// publicKeyRSA returns the RSA public key from a DNSKEY record.
437 -func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
438 - keybuf, err := fromBase64([]byte(k.PublicKey))
439 - if err != nil {
440 - return nil
441 - }
442 -
443 - // RFC 2537/3110, section 2. RSA Public KEY Resource Records
444 - // Length is in the 0th byte, unless its zero, then it
445 - // it in bytes 1 and 2 and its a 16 bit number
446 - explen := uint16(keybuf[0])
447 - keyoff := 1
448 - if explen == 0 {
449 - explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
450 - keyoff = 3
451 - }
452 - pubkey := new(rsa.PublicKey)
453 -
454 - pubkey.N = big.NewInt(0)
455 - shift := uint64((explen - 1) * 8)
456 - expo := uint64(0)
457 - for i := int(explen - 1); i > 0; i-- {
458 - expo += uint64(keybuf[keyoff+i]) << shift
459 - shift -= 8
460 - }
461 - // Remainder
462 - expo += uint64(keybuf[keyoff])
463 - if expo > 2<<31 {
464 - // Larger expo than supported.
465 - // println("dns: F5 primes (or larger) are not supported")
466 - return nil
467 - }
468 - pubkey.E = int(expo)
469 -
470 - pubkey.N.SetBytes(keybuf[keyoff+int(explen):])
471 - return pubkey
472 -}
473 -
474 -// publicKeyECDSA returns the Curve public key from the DNSKEY record.
475 -func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey {
476 - keybuf, err := fromBase64([]byte(k.PublicKey))
477 - if err != nil {
478 - return nil
479 - }
480 - pubkey := new(ecdsa.PublicKey)
481 - switch k.Algorithm {
482 - case ECDSAP256SHA256:
483 - pubkey.Curve = elliptic.P256()
484 - if len(keybuf) != 64 {
485 - // wrongly encoded key
486 - return nil
487 - }
488 - case ECDSAP384SHA384:
489 - pubkey.Curve = elliptic.P384()
490 - if len(keybuf) != 96 {
491 - // Wrongly encoded key
492 - return nil
493 - }
494 - }
495 - pubkey.X = big.NewInt(0)
496 - pubkey.X.SetBytes(keybuf[:len(keybuf)/2])
497 - pubkey.Y = big.NewInt(0)
498 - pubkey.Y.SetBytes(keybuf[len(keybuf)/2:])
499 - return pubkey
500 -}
501 -
502 -func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey {
503 - keybuf, err := fromBase64([]byte(k.PublicKey))
504 - if err != nil {
505 - return nil
506 - }
507 - if len(keybuf) < 22 {
508 - return nil
509 - }
510 - t, keybuf := int(keybuf[0]), keybuf[1:]
511 - size := 64 + t*8
512 - q, keybuf := keybuf[:20], keybuf[20:]
513 - if len(keybuf) != 3*size {
514 - return nil
515 - }
516 - p, keybuf := keybuf[:size], keybuf[size:]
517 - g, y := keybuf[:size], keybuf[size:]
518 - pubkey := new(dsa.PublicKey)
519 - pubkey.Parameters.Q = big.NewInt(0).SetBytes(q)
520 - pubkey.Parameters.P = big.NewInt(0).SetBytes(p)
521 - pubkey.Parameters.G = big.NewInt(0).SetBytes(g)
522 - pubkey.Y = big.NewInt(0).SetBytes(y)
523 - return pubkey
524 -}
525 -
526 -type wireSlice [][]byte
527 -
528 -func (p wireSlice) Len() int { return len(p) }
529 -func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
530 -func (p wireSlice) Less(i, j int) bool {
531 - _, ioff, _ := UnpackDomainName(p[i], 0)
532 - _, joff, _ := UnpackDomainName(p[j], 0)
533 - return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0
534 -}
535 -
536 -// Return the raw signature data.
537 -func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) {
538 - wires := make(wireSlice, len(rrset))
539 - for i, r := range rrset {
540 - r1 := r.copy()
541 - r1.Header().Ttl = s.OrigTtl
542 - labels := SplitDomainName(r1.Header().Name)
543 - // 6.2. Canonical RR Form. (4) - wildcards
544 - if len(labels) > int(s.Labels) {
545 - // Wildcard
546 - r1.Header().Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "."
547 - }
548 - // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase
549 - r1.Header().Name = strings.ToLower(r1.Header().Name)
550 - // 6.2. Canonical RR Form. (3) - domain rdata to lowercase.
551 - // NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR,
552 - // HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX,
553 - // SRV, DNAME, A6
554 - switch x := r1.(type) {
555 - case *NS:
556 - x.Ns = strings.ToLower(x.Ns)
557 - case *CNAME:
558 - x.Target = strings.ToLower(x.Target)
559 - case *SOA:
560 - x.Ns = strings.ToLower(x.Ns)
561 - x.Mbox = strings.ToLower(x.Mbox)
562 - case *MB:
563 - x.Mb = strings.ToLower(x.Mb)
564 - case *MG:
565 - x.Mg = strings.ToLower(x.Mg)
566 - case *MR:
567 - x.Mr = strings.ToLower(x.Mr)
568 - case *PTR:
569 - x.Ptr = strings.ToLower(x.Ptr)
570 - case *MINFO:
571 - x.Rmail = strings.ToLower(x.Rmail)
572 - x.Email = strings.ToLower(x.Email)
573 - case *MX:
574 - x.Mx = strings.ToLower(x.Mx)
575 - case *NAPTR:
576 - x.Replacement = strings.ToLower(x.Replacement)
577 - case *KX:
578 - x.Exchanger = strings.ToLower(x.Exchanger)
579 - case *SRV:
580 - x.Target = strings.ToLower(x.Target)
581 - case *DNAME:
582 - x.Target = strings.ToLower(x.Target)
583 - }
584 - // 6.2. Canonical RR Form. (5) - origTTL
585 - wire := make([]byte, r1.len()+1) // +1 to be safe(r)
586 - off, err1 := PackRR(r1, wire, 0, nil, false)
587 - if err1 != nil {
588 - return nil, err1
589 - }
590 - wire = wire[:off]
591 - wires[i] = wire
592 - }
593 - sort.Sort(wires)
594 - for i, wire := range wires {
595 - if i > 0 && bytes.Equal(wire, wires[i-1]) {
596 - continue
597 - }
598 - buf = append(buf, wire...)
599 - }
600 - return buf, nil
601 -}
602 -
603 -// Map for algorithm names.
604 -var AlgorithmToString = map[uint8]string{
605 - RSAMD5: "RSAMD5",
606 - DH: "DH",
607 - DSA: "DSA",
608 - RSASHA1: "RSASHA1",
609 - DSANSEC3SHA1: "DSA-NSEC3-SHA1",
610 - RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1",
611 - RSASHA256: "RSASHA256",
612 - RSASHA512: "RSASHA512",
613 - ECCGOST: "ECC-GOST",
614 - ECDSAP256SHA256: "ECDSAP256SHA256",
615 - ECDSAP384SHA384: "ECDSAP384SHA384",
616 - INDIRECT: "INDIRECT",
617 - PRIVATEDNS: "PRIVATEDNS",
618 - PRIVATEOID: "PRIVATEOID",
619 -}
620 -
621 -// Map of algorithm strings.
622 -var StringToAlgorithm = reverseInt8(AlgorithmToString)
623 -
624 -// Map for hash names.
625 -var HashToString = map[uint8]string{
626 - SHA1: "SHA1",
627 - SHA256: "SHA256",
628 - GOST94: "GOST94",
629 - SHA384: "SHA384",
630 - SHA512: "SHA512",
631 -}
632 -
633 -// Map of hash strings.
634 -var StringToHash = reverseInt8(HashToString)
Godeps/_workspace/src/github.com/miekg/dns/dnssec_keygen.go deleted
-155
@@ -1,155 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "crypto/dsa"
5 - "crypto/ecdsa"
6 - "crypto/elliptic"
7 - "crypto/rand"
8 - "crypto/rsa"
9 - "math/big"
10 -)
11 -
12 -// Generate generates a DNSKEY of the given bit size.
13 -// The public part is put inside the DNSKEY record.
14 -// The Algorithm in the key must be set as this will define
15 -// what kind of DNSKEY will be generated.
16 -// The ECDSA algorithms imply a fixed keysize, in that case
17 -// bits should be set to the size of the algorithm.
18 -func (k *DNSKEY) Generate(bits int) (PrivateKey, error) {
19 - switch k.Algorithm {
20 - case DSA, DSANSEC3SHA1:
21 - if bits != 1024 {
22 - return nil, ErrKeySize
23 - }
24 - case RSAMD5, RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
25 - if bits < 512 || bits > 4096 {
26 - return nil, ErrKeySize
27 - }
28 - case RSASHA512:
29 - if bits < 1024 || bits > 4096 {
30 - return nil, ErrKeySize
31 - }
32 - case ECDSAP256SHA256:
33 - if bits != 256 {
34 - return nil, ErrKeySize
35 - }
36 - case ECDSAP384SHA384:
37 - if bits != 384 {
38 - return nil, ErrKeySize
39 - }
40 - }
41 -
42 - switch k.Algorithm {
43 - case DSA, DSANSEC3SHA1:
44 - params := new(dsa.Parameters)
45 - if err := dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160); err != nil {
46 - return nil, err
47 - }
48 - priv := new(dsa.PrivateKey)
49 - priv.PublicKey.Parameters = *params
50 - err := dsa.GenerateKey(priv, rand.Reader)
51 - if err != nil {
52 - return nil, err
53 - }
54 - k.setPublicKeyDSA(params.Q, params.P, params.G, priv.PublicKey.Y)
55 - return (*DSAPrivateKey)(priv), nil
56 - case RSAMD5, RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
57 - priv, err := rsa.GenerateKey(rand.Reader, bits)
58 - if err != nil {
59 - return nil, err
60 - }
61 - k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N)
62 - return (*RSAPrivateKey)(priv), nil
63 - case ECDSAP256SHA256, ECDSAP384SHA384:
64 - var c elliptic.Curve
65 - switch k.Algorithm {
66 - case ECDSAP256SHA256:
67 - c = elliptic.P256()
68 - case ECDSAP384SHA384:
69 - c = elliptic.P384()
70 - }
71 - priv, err := ecdsa.GenerateKey(c, rand.Reader)
72 - if err != nil {
73 - return nil, err
74 - }
75 - k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y)
76 - return (*ECDSAPrivateKey)(priv), nil
77 - default:
78 - return nil, ErrAlg
79 - }
80 -}
81 -
82 -// Set the public key (the value E and N)
83 -func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool {
84 - if _E == 0 || _N == nil {
85 - return false
86 - }
87 - buf := exponentToBuf(_E)
88 - buf = append(buf, _N.Bytes()...)
89 - k.PublicKey = toBase64(buf)
90 - return true
91 -}
92 -
93 -// Set the public key for Elliptic Curves
94 -func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool {
95 - if _X == nil || _Y == nil {
96 - return false
97 - }
98 - var intlen int
99 - switch k.Algorithm {
100 - case ECDSAP256SHA256:
101 - intlen = 32
102 - case ECDSAP384SHA384:
103 - intlen = 48
104 - }
105 - k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen))
106 - return true
107 -}
108 -
109 -// Set the public key for DSA
110 -func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool {
111 - if _Q == nil || _P == nil || _G == nil || _Y == nil {
112 - return false
113 - }
114 - buf := dsaToBuf(_Q, _P, _G, _Y)
115 - k.PublicKey = toBase64(buf)
116 - return true
117 -}
118 -
119 -// Set the public key (the values E and N) for RSA
120 -// RFC 3110: Section 2. RSA Public KEY Resource Records
121 -func exponentToBuf(_E int) []byte {
122 - var buf []byte
123 - i := big.NewInt(int64(_E))
124 - if len(i.Bytes()) < 256 {
125 - buf = make([]byte, 1)
126 - buf[0] = uint8(len(i.Bytes()))
127 - } else {
128 - buf = make([]byte, 3)
129 - buf[0] = 0
130 - buf[1] = uint8(len(i.Bytes()) >> 8)
131 - buf[2] = uint8(len(i.Bytes()))
132 - }
133 - buf = append(buf, i.Bytes()...)
134 - return buf
135 -}
136 -
137 -// Set the public key for X and Y for Curve. The two
138 -// values are just concatenated.
139 -func curveToBuf(_X, _Y *big.Int, intlen int) []byte {
140 - buf := intToBytes(_X, intlen)
141 - buf = append(buf, intToBytes(_Y, intlen)...)
142 - return buf
143 -}
144 -
145 -// Set the public key for X and Y for Curve. The two
146 -// values are just concatenated.
147 -func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte {
148 - t := divRoundUp(divRoundUp(_G.BitLen(), 8)-64, 8)
149 - buf := []byte{byte(t)}
150 - buf = append(buf, intToBytes(_Q, 20)...)
151 - buf = append(buf, intToBytes(_P, 64+t*8)...)
152 - buf = append(buf, intToBytes(_G, 64+t*8)...)
153 - buf = append(buf, intToBytes(_Y, 64+t*8)...)
154 - return buf
155 -}
Godeps/_workspace/src/github.com/miekg/dns/dnssec_keyscan.go deleted
-243
@@ -1,243 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "crypto/dsa"
5 - "crypto/ecdsa"
6 - "crypto/rsa"
7 - "io"
8 - "math/big"
9 - "strings"
10 -)
11 -
12 -// NewPrivateKey returns a PrivateKey by parsing the string s.
13 -// s should be in the same form of the BIND private key files.
14 -func (k *DNSKEY) NewPrivateKey(s string) (PrivateKey, error) {
15 - if s[len(s)-1] != '\n' { // We need a closing newline
16 - return k.ReadPrivateKey(strings.NewReader(s+"\n"), "")
17 - }
18 - return k.ReadPrivateKey(strings.NewReader(s), "")
19 -}
20 -
21 -// ReadPrivateKey reads a private key from the io.Reader q. The string file is
22 -// only used in error reporting.
23 -// The public key must be known, because some cryptographic algorithms embed
24 -// the public inside the privatekey.
25 -func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (PrivateKey, error) {
26 - m, e := parseKey(q, file)
27 - if m == nil {
28 - return nil, e
29 - }
30 - if _, ok := m["private-key-format"]; !ok {
31 - return nil, ErrPrivKey
32 - }
33 - if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" {
34 - return nil, ErrPrivKey
35 - }
36 - // TODO(mg): check if the pubkey matches the private key
37 - switch m["algorithm"] {
38 - case "3 (DSA)":
39 - priv, e := readPrivateKeyDSA(m)
40 - if e != nil {
41 - return nil, e
42 - }
43 - pub := k.publicKeyDSA()
44 - if pub == nil {
45 - return nil, ErrKey
46 - }
47 - priv.PublicKey = *pub
48 - return (*DSAPrivateKey)(priv), e
49 - case "1 (RSAMD5)":
50 - fallthrough
51 - case "5 (RSASHA1)":
52 - fallthrough
53 - case "7 (RSASHA1NSEC3SHA1)":
54 - fallthrough
55 - case "8 (RSASHA256)":
56 - fallthrough
57 - case "10 (RSASHA512)":
58 - priv, e := readPrivateKeyRSA(m)
59 - if e != nil {
60 - return nil, e
61 - }
62 - pub := k.publicKeyRSA()
63 - if pub == nil {
64 - return nil, ErrKey
65 - }
66 - priv.PublicKey = *pub
67 - return (*RSAPrivateKey)(priv), e
68 - case "12 (ECC-GOST)":
69 - return nil, ErrPrivKey
70 - case "13 (ECDSAP256SHA256)":
71 - fallthrough
72 - case "14 (ECDSAP384SHA384)":
73 - priv, e := readPrivateKeyECDSA(m)
74 - if e != nil {
75 - return nil, e
76 - }
77 - pub := k.publicKeyECDSA()
78 - if pub == nil {
79 - return nil, ErrKey
80 - }
81 - priv.PublicKey = *pub
82 - return (*ECDSAPrivateKey)(priv), e
83 - default:
84 - return nil, ErrPrivKey
85 - }
86 -}
87 -
88 -// Read a private key (file) string and create a public key. Return the private key.
89 -func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) {
90 - p := new(rsa.PrivateKey)
91 - p.Primes = []*big.Int{nil, nil}
92 - for k, v := range m {
93 - switch k {
94 - case "modulus", "publicexponent", "privateexponent", "prime1", "prime2":
95 - v1, err := fromBase64([]byte(v))
96 - if err != nil {
97 - return nil, err
98 - }
99 - switch k {
100 - case "modulus":
101 - p.PublicKey.N = big.NewInt(0)
102 - p.PublicKey.N.SetBytes(v1)
103 - case "publicexponent":
104 - i := big.NewInt(0)
105 - i.SetBytes(v1)
106 - p.PublicKey.E = int(i.Int64()) // int64 should be large enough
107 - case "privateexponent":
108 - p.D = big.NewInt(0)
109 - p.D.SetBytes(v1)
110 - case "prime1":
111 - p.Primes[0] = big.NewInt(0)
112 - p.Primes[0].SetBytes(v1)
113 - case "prime2":
114 - p.Primes[1] = big.NewInt(0)
115 - p.Primes[1].SetBytes(v1)
116 - }
117 - case "exponent1", "exponent2", "coefficient":
118 - // not used in Go (yet)
119 - case "created", "publish", "activate":
120 - // not used in Go (yet)
121 - }
122 - }
123 - return p, nil
124 -}
125 -
126 -func readPrivateKeyDSA(m map[string]string) (*dsa.PrivateKey, error) {
127 - p := new(dsa.PrivateKey)
128 - p.X = big.NewInt(0)
129 - for k, v := range m {
130 - switch k {
131 - case "private_value(x)":
132 - v1, err := fromBase64([]byte(v))
133 - if err != nil {
134 - return nil, err
135 - }
136 - p.X.SetBytes(v1)
137 - case "created", "publish", "activate":
138 - /* not used in Go (yet) */
139 - }
140 - }
141 - return p, nil
142 -}
143 -
144 -func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) {
145 - p := new(ecdsa.PrivateKey)
146 - p.D = big.NewInt(0)
147 - // TODO: validate that the required flags are present
148 - for k, v := range m {
149 - switch k {
150 - case "privatekey":
151 - v1, err := fromBase64([]byte(v))
152 - if err != nil {
153 - return nil, err
154 - }
155 - p.D.SetBytes(v1)
156 - case "created", "publish", "activate":
157 - /* not used in Go (yet) */
158 - }
159 - }
160 - return p, nil
161 -}
162 -
163 -// parseKey reads a private key from r. It returns a map[string]string,
164 -// with the key-value pairs, or an error when the file is not correct.
165 -func parseKey(r io.Reader, file string) (map[string]string, error) {
166 - s := scanInit(r)
167 - m := make(map[string]string)
168 - c := make(chan lex)
169 - k := ""
170 - // Start the lexer
171 - go klexer(s, c)
172 - for l := range c {
173 - // It should alternate
174 - switch l.value {
175 - case zKey:
176 - k = l.token
177 - case zValue:
178 - if k == "" {
179 - return nil, &ParseError{file, "no private key seen", l}
180 - }
181 - //println("Setting", strings.ToLower(k), "to", l.token, "b")
182 - m[strings.ToLower(k)] = l.token
183 - k = ""
184 - }
185 - }
186 - return m, nil
187 -}
188 -
189 -// klexer scans the sourcefile and returns tokens on the channel c.
190 -func klexer(s *scan, c chan lex) {
191 - var l lex
192 - str := "" // Hold the current read text
193 - commt := false
194 - key := true
195 - x, err := s.tokenText()
196 - defer close(c)
197 - for err == nil {
198 - l.column = s.position.Column
199 - l.line = s.position.Line
200 - switch x {
201 - case ':':
202 - if commt {
203 - break
204 - }
205 - l.token = str
206 - if key {
207 - l.value = zKey
208 - c <- l
209 - // Next token is a space, eat it
210 - s.tokenText()
211 - key = false
212 - str = ""
213 - } else {
214 - l.value = zValue
215 - }
216 - case ';':
217 - commt = true
218 - case '\n':
219 - if commt {
220 - // Reset a comment
221 - commt = false
222 - }
223 - l.value = zValue
224 - l.token = str
225 - c <- l
226 - str = ""
227 - commt = false
228 - key = true
229 - default:
230 - if commt {
231 - break
232 - }
233 - str += string(x)
234 - }
235 - x, err = s.tokenText()
236 - }
237 - if len(str) > 0 {
238 - // Send remainder
239 - l.token = str
240 - l.value = zValue
241 - c <- l
242 - }
243 -}
Godeps/_workspace/src/github.com/miekg/dns/dnssec_privkey.go deleted
-144
@@ -1,144 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "crypto"
5 - "crypto/dsa"
6 - "crypto/ecdsa"
7 - "crypto/rand"
8 - "crypto/rsa"
9 - "math/big"
10 - "strconv"
11 -)
12 -
13 -const format = "Private-key-format: v1.3\n"
14 -
15 -// PrivateKey ... TODO(miek)
16 -type PrivateKey interface {
17 - Sign([]byte, uint8) ([]byte, error)
18 - String(uint8) string
19 -}
20 -
21 -// PrivateKeyString converts a PrivateKey to a string. This string has the same
22 -// format as the private-key-file of BIND9 (Private-key-format: v1.3).
23 -// It needs some info from the key (the algorithm), so its a method of the
24 -// DNSKEY and calls PrivateKey.String(alg).
25 -func (r *DNSKEY) PrivateKeyString(p PrivateKey) string {
26 - return p.String(r.Algorithm)
27 -}
28 -
29 -type RSAPrivateKey rsa.PrivateKey
30 -
31 -func (p *RSAPrivateKey) Sign(hashed []byte, alg uint8) ([]byte, error) {
32 - var hash crypto.Hash
33 - switch alg {
34 - case RSASHA1, RSASHA1NSEC3SHA1:
35 - hash = crypto.SHA1
36 - case RSASHA256:
37 - hash = crypto.SHA256
38 - case RSASHA512:
39 - hash = crypto.SHA512
40 - default:
41 - return nil, ErrAlg
42 - }
43 - return rsa.SignPKCS1v15(nil, (*rsa.PrivateKey)(p), hash, hashed)
44 -}
45 -
46 -func (p *RSAPrivateKey) String(alg uint8) string {
47 - algorithm := strconv.Itoa(int(alg)) + " (" + AlgorithmToString[alg] + ")"
48 - modulus := toBase64(p.PublicKey.N.Bytes())
49 - e := big.NewInt(int64(p.PublicKey.E))
50 - publicExponent := toBase64(e.Bytes())
51 - privateExponent := toBase64(p.D.Bytes())
52 - prime1 := toBase64(p.Primes[0].Bytes())
53 - prime2 := toBase64(p.Primes[1].Bytes())
54 - // Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm
55 - // and from: http://code.google.com/p/go/issues/detail?id=987
56 - one := big.NewInt(1)
57 - p1 := big.NewInt(0).Sub(p.Primes[0], one)
58 - q1 := big.NewInt(0).Sub(p.Primes[1], one)
59 - exp1 := big.NewInt(0).Mod(p.D, p1)
60 - exp2 := big.NewInt(0).Mod(p.D, q1)
61 - coeff := big.NewInt(0).ModInverse(p.Primes[1], p.Primes[0])
62 -
63 - exponent1 := toBase64(exp1.Bytes())
64 - exponent2 := toBase64(exp2.Bytes())
65 - coefficient := toBase64(coeff.Bytes())
66 -
67 - return format +
68 - "Algorithm: " + algorithm + "\n" +
69 - "Modulus: " + modulus + "\n" +
70 - "PublicExponent: " + publicExponent + "\n" +
71 - "PrivateExponent: " + privateExponent + "\n" +
72 - "Prime1: " + prime1 + "\n" +
73 - "Prime2: " + prime2 + "\n" +
74 - "Exponent1: " + exponent1 + "\n" +
75 - "Exponent2: " + exponent2 + "\n" +
76 - "Coefficient: " + coefficient + "\n"
77 -}
78 -
79 -type ECDSAPrivateKey ecdsa.PrivateKey
80 -
81 -func (p *ECDSAPrivateKey) Sign(hashed []byte, alg uint8) ([]byte, error) {
82 - var intlen int
83 - switch alg {
84 - case ECDSAP256SHA256:
85 - intlen = 32
86 - case ECDSAP384SHA384:
87 - intlen = 48
88 - default:
89 - return nil, ErrAlg
90 - }
91 - r1, s1, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(p), hashed)
92 - if err != nil {
93 - return nil, err
94 - }
95 - signature := intToBytes(r1, intlen)
96 - signature = append(signature, intToBytes(s1, intlen)...)
97 - return signature, nil
98 -}
99 -
100 -func (p *ECDSAPrivateKey) String(alg uint8) string {
101 - algorithm := strconv.Itoa(int(alg)) + " (" + AlgorithmToString[alg] + ")"
102 - var intlen int
103 - switch alg {
104 - case ECDSAP256SHA256:
105 - intlen = 32
106 - case ECDSAP384SHA384:
107 - intlen = 48
108 - }
109 - private := toBase64(intToBytes(p.D, intlen))
110 - return format +
111 - "Algorithm: " + algorithm + "\n" +
112 - "PrivateKey: " + private + "\n"
113 -}
114 -
115 -type DSAPrivateKey dsa.PrivateKey
116 -
117 -func (p *DSAPrivateKey) Sign(hashed []byte, alg uint8) ([]byte, error) {
118 - r1, s1, err := dsa.Sign(rand.Reader, (*dsa.PrivateKey)(p), hashed)
119 - if err != nil {
120 - return nil, err
121 - }
122 - t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8)
123 - signature := []byte{byte(t)}
124 - signature = append(signature, intToBytes(r1, 20)...)
125 - signature = append(signature, intToBytes(s1, 20)...)
126 - return signature, nil
127 -}
128 -
129 -func (p *DSAPrivateKey) String(alg uint8) string {
130 - algorithm := strconv.Itoa(int(alg)) + " (" + AlgorithmToString[alg] + ")"
131 - T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8)
132 - prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8))
133 - subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20))
134 - base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8))
135 - priv := toBase64(intToBytes(p.X, 20))
136 - pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8))
137 - return format +
138 - "Algorithm: " + algorithm + "\n" +
139 - "Prime(p): " + prime + "\n" +
140 - "Subprime(q): " + subprime + "\n" +
141 - "Base(g): " + base + "\n" +
142 - "Private_value(x): " + priv + "\n" +
143 - "Public_value(y): " + pub + "\n"
144 -}
Godeps/_workspace/src/github.com/miekg/dns/dnssec_test.go deleted
-658
@@ -1,658 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "reflect"
5 - "strings"
6 - "testing"
7 - "time"
8 -)
9 -
10 -func getKey() *DNSKEY {
11 - key := new(DNSKEY)
12 - key.Hdr.Name = "miek.nl."
13 - key.Hdr.Class = ClassINET
14 - key.Hdr.Ttl = 14400
15 - key.Flags = 256
16 - key.Protocol = 3
17 - key.Algorithm = RSASHA256
18 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
19 - return key
20 -}
21 -
22 -func getSoa() *SOA {
23 - soa := new(SOA)
24 - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
25 - soa.Ns = "open.nlnetlabs.nl."
26 - soa.Mbox = "miekg.atoom.net."
27 - soa.Serial = 1293945905
28 - soa.Refresh = 14400
29 - soa.Retry = 3600
30 - soa.Expire = 604800
31 - soa.Minttl = 86400
32 - return soa
33 -}
34 -
35 -func TestGenerateEC(t *testing.T) {
36 - if testing.Short() {
37 - t.Skip("skipping test in short mode.")
38 - }
39 - key := new(DNSKEY)
40 - key.Hdr.Rrtype = TypeDNSKEY
41 - key.Hdr.Name = "miek.nl."
42 - key.Hdr.Class = ClassINET
43 - key.Hdr.Ttl = 14400
44 - key.Flags = 256
45 - key.Protocol = 3
46 - key.Algorithm = ECDSAP256SHA256
47 - privkey, _ := key.Generate(256)
48 - t.Log(key.String())
49 - t.Log(key.PrivateKeyString(privkey))
50 -}
51 -
52 -func TestGenerateDSA(t *testing.T) {
53 - if testing.Short() {
54 - t.Skip("skipping test in short mode.")
55 - }
56 - key := new(DNSKEY)
57 - key.Hdr.Rrtype = TypeDNSKEY
58 - key.Hdr.Name = "miek.nl."
59 - key.Hdr.Class = ClassINET
60 - key.Hdr.Ttl = 14400
61 - key.Flags = 256
62 - key.Protocol = 3
63 - key.Algorithm = DSA
64 - privkey, _ := key.Generate(1024)
65 - t.Log(key.String())
66 - t.Log(key.PrivateKeyString(privkey))
67 -}
68 -
69 -func TestGenerateRSA(t *testing.T) {
70 - if testing.Short() {
71 - t.Skip("skipping test in short mode.")
72 - }
73 - key := new(DNSKEY)
74 - key.Hdr.Rrtype = TypeDNSKEY
75 - key.Hdr.Name = "miek.nl."
76 - key.Hdr.Class = ClassINET
77 - key.Hdr.Ttl = 14400
78 - key.Flags = 256
79 - key.Protocol = 3
80 - key.Algorithm = RSASHA256
81 - privkey, _ := key.Generate(1024)
82 - t.Log(key.String())
83 - t.Log(key.PrivateKeyString(privkey))
84 -}
85 -
86 -func TestSecure(t *testing.T) {
87 - soa := getSoa()
88 -
89 - sig := new(RRSIG)
90 - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
91 - sig.TypeCovered = TypeSOA
92 - sig.Algorithm = RSASHA256
93 - sig.Labels = 2
94 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
95 - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
96 - sig.OrigTtl = 14400
97 - sig.KeyTag = 12051
98 - sig.SignerName = "miek.nl."
99 - sig.Signature = "oMCbslaAVIp/8kVtLSms3tDABpcPRUgHLrOR48OOplkYo+8TeEGWwkSwaz/MRo2fB4FxW0qj/hTlIjUGuACSd+b1wKdH5GvzRJc2pFmxtCbm55ygAh4EUL0F6U5cKtGJGSXxxg6UFCQ0doJCmiGFa78LolaUOXImJrk6AFrGa0M="
100 -
101 - key := new(DNSKEY)
102 - key.Hdr.Name = "miek.nl."
103 - key.Hdr.Class = ClassINET
104 - key.Hdr.Ttl = 14400
105 - key.Flags = 256
106 - key.Protocol = 3
107 - key.Algorithm = RSASHA256
108 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
109 -
110 - // It should validate. Period is checked separately, so this will keep on working
111 - if sig.Verify(key, []RR{soa}) != nil {
112 - t.Error("failure to validate")
113 - }
114 -}
115 -
116 -func TestSignature(t *testing.T) {
117 - sig := new(RRSIG)
118 - sig.Hdr.Name = "miek.nl."
119 - sig.Hdr.Class = ClassINET
120 - sig.Hdr.Ttl = 3600
121 - sig.TypeCovered = TypeDNSKEY
122 - sig.Algorithm = RSASHA1
123 - sig.Labels = 2
124 - sig.OrigTtl = 4000
125 - sig.Expiration = 1000 //Thu Jan 1 02:06:40 CET 1970
126 - sig.Inception = 800 //Thu Jan 1 01:13:20 CET 1970
127 - sig.KeyTag = 34641
128 - sig.SignerName = "miek.nl."
129 - sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
130 -
131 - // Should not be valid
132 - if sig.ValidityPeriod(time.Now()) {
133 - t.Error("should not be valid")
134 - }
135 -
136 - sig.Inception = 315565800 //Tue Jan 1 10:10:00 CET 1980
137 - sig.Expiration = 4102477800 //Fri Jan 1 10:10:00 CET 2100
138 - if !sig.ValidityPeriod(time.Now()) {
139 - t.Error("should be valid")
140 - }
141 -}
142 -
143 -func TestSignVerify(t *testing.T) {
144 - // The record we want to sign
145 - soa := new(SOA)
146 - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
147 - soa.Ns = "open.nlnetlabs.nl."
148 - soa.Mbox = "miekg.atoom.net."
149 - soa.Serial = 1293945905
150 - soa.Refresh = 14400
151 - soa.Retry = 3600
152 - soa.Expire = 604800
153 - soa.Minttl = 86400
154 -
155 - soa1 := new(SOA)
156 - soa1.Hdr = RR_Header{"*.miek.nl.", TypeSOA, ClassINET, 14400, 0}
157 - soa1.Ns = "open.nlnetlabs.nl."
158 - soa1.Mbox = "miekg.atoom.net."
159 - soa1.Serial = 1293945905
160 - soa1.Refresh = 14400
161 - soa1.Retry = 3600
162 - soa1.Expire = 604800
163 - soa1.Minttl = 86400
164 -
165 - srv := new(SRV)
166 - srv.Hdr = RR_Header{"srv.miek.nl.", TypeSRV, ClassINET, 14400, 0}
167 - srv.Port = 1000
168 - srv.Weight = 800
169 - srv.Target = "web1.miek.nl."
170 -
171 - // With this key
172 - key := new(DNSKEY)
173 - key.Hdr.Rrtype = TypeDNSKEY
174 - key.Hdr.Name = "miek.nl."
175 - key.Hdr.Class = ClassINET
176 - key.Hdr.Ttl = 14400
177 - key.Flags = 256
178 - key.Protocol = 3
179 - key.Algorithm = RSASHA256
180 - privkey, _ := key.Generate(512)
181 -
182 - // Fill in the values of the Sig, before signing
183 - sig := new(RRSIG)
184 - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
185 - sig.TypeCovered = soa.Hdr.Rrtype
186 - sig.Labels = uint8(CountLabel(soa.Hdr.Name)) // works for all 3
187 - sig.OrigTtl = soa.Hdr.Ttl
188 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
189 - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
190 - sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
191 - sig.SignerName = key.Hdr.Name
192 - sig.Algorithm = RSASHA256
193 -
194 - for _, r := range []RR{soa, soa1, srv} {
195 - if sig.Sign(privkey, []RR{r}) != nil {
196 - t.Error("failure to sign the record")
197 - continue
198 - }
199 - if sig.Verify(key, []RR{r}) != nil {
200 - t.Error("failure to validate")
201 - continue
202 - }
203 - t.Logf("validated: %s", r.Header().Name)
204 - }
205 -}
206 -
207 -func Test65534(t *testing.T) {
208 - t6 := new(RFC3597)
209 - t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0}
210 - t6.Rdata = "505D870001"
211 - key := new(DNSKEY)
212 - key.Hdr.Name = "miek.nl."
213 - key.Hdr.Rrtype = TypeDNSKEY
214 - key.Hdr.Class = ClassINET
215 - key.Hdr.Ttl = 14400
216 - key.Flags = 256
217 - key.Protocol = 3
218 - key.Algorithm = RSASHA256
219 - privkey, _ := key.Generate(1024)
220 -
221 - sig := new(RRSIG)
222 - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
223 - sig.TypeCovered = t6.Hdr.Rrtype
224 - sig.Labels = uint8(CountLabel(t6.Hdr.Name))
225 - sig.OrigTtl = t6.Hdr.Ttl
226 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
227 - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
228 - sig.KeyTag = key.KeyTag()
229 - sig.SignerName = key.Hdr.Name
230 - sig.Algorithm = RSASHA256
231 - if err := sig.Sign(privkey, []RR{t6}); err != nil {
232 - t.Error(err)
233 - t.Error("failure to sign the TYPE65534 record")
234 - }
235 - if err := sig.Verify(key, []RR{t6}); err != nil {
236 - t.Error(err)
237 - t.Error("failure to validate")
238 - } else {
239 - t.Logf("validated: %s", t6.Header().Name)
240 - }
241 -}
242 -
243 -func TestDnskey(t *testing.T) {
244 - pubkey, err := ReadRR(strings.NewReader(`
245 -miek.nl. IN DNSKEY 256 3 10 AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL ;{id = 5240 (zsk), size = 1024b}
246 -`), "Kmiek.nl.+010+05240.key")
247 - if err != nil {
248 - t.Fatal(err)
249 - }
250 - privStr := `Private-key-format: v1.3
251 -Algorithm: 10 (RSASHA512)
252 -Modulus: m4wK7YV26AeROtdiCXmqLG9wPDVoMOW8vjr/EkpscEAdjXp81RvZvrlzCSjYmz9onFRgltmTl3AINnFh+t9tlW0M9C5zejxBoKFXELv8ljPYAdz2oe+pDWPhWsfvVFYg2VCjpViPM38EakyE5mhk4TDOnUd+w4TeU1hyhZTWyYs=
253 -PublicExponent: AQAB
254 -PrivateExponent: UfCoIQ/Z38l8vB6SSqOI/feGjHEl/fxIPX4euKf0D/32k30fHbSaNFrFOuIFmWMB3LimWVEs6u3dpbB9CQeCVg7hwU5puG7OtuiZJgDAhNeOnxvo5btp4XzPZrJSxR4WNQnwIiYWbl0aFlL1VGgHC/3By89ENZyWaZcMLW4KGWE=
255 -Prime1: yxwC6ogAu8aVcDx2wg1V0b5M5P6jP8qkRFVMxWNTw60Vkn+ECvw6YAZZBHZPaMyRYZLzPgUlyYRd0cjupy4+fQ==
256 -Prime2: xA1bF8M0RTIQ6+A11AoVG6GIR/aPGg5sogRkIZ7ID/sF6g9HMVU/CM2TqVEBJLRPp73cv6ZeC3bcqOCqZhz+pw==
257 -Exponent1: xzkblyZ96bGYxTVZm2/vHMOXswod4KWIyMoOepK6B/ZPcZoIT6omLCgtypWtwHLfqyCz3MK51Nc0G2EGzg8rFQ==
258 -Exponent2: Pu5+mCEb7T5F+kFNZhQadHUklt0JUHbi3hsEvVoHpEGSw3BGDQrtIflDde0/rbWHgDPM4WQY+hscd8UuTXrvLw==
259 -Coefficient: UuRoNqe7YHnKmQzE6iDWKTMIWTuoqqrFAmXPmKQnC+Y+BQzOVEHUo9bXdDnoI9hzXP1gf8zENMYwYLeWpuYlFQ==
260 -`
261 - privkey, err := pubkey.(*DNSKEY).ReadPrivateKey(strings.NewReader(privStr),
262 - "Kmiek.nl.+010+05240.private")
263 - if err != nil {
264 - t.Fatal(err)
265 - }
266 - if pubkey.(*DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" {
267 - t.Error("pubkey is not what we've read")
268 - }
269 - if pubkey.(*DNSKEY).PrivateKeyString(privkey) != privStr {
270 - t.Error("privkey is not what we've read")
271 - t.Errorf("%v", pubkey.(*DNSKEY).PrivateKeyString(privkey))
272 - }
273 -}
274 -
275 -func TestTag(t *testing.T) {
276 - key := new(DNSKEY)
277 - key.Hdr.Name = "miek.nl."
278 - key.Hdr.Rrtype = TypeDNSKEY
279 - key.Hdr.Class = ClassINET
280 - key.Hdr.Ttl = 3600
281 - key.Flags = 256
282 - key.Protocol = 3
283 - key.Algorithm = RSASHA256
284 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
285 -
286 - tag := key.KeyTag()
287 - if tag != 12051 {
288 - t.Errorf("wrong key tag: %d for key %v", tag, key)
289 - }
290 -}
291 -
292 -func TestKeyRSA(t *testing.T) {
293 - if testing.Short() {
294 - t.Skip("skipping test in short mode.")
295 - }
296 - key := new(DNSKEY)
297 - key.Hdr.Name = "miek.nl."
298 - key.Hdr.Rrtype = TypeDNSKEY
299 - key.Hdr.Class = ClassINET
300 - key.Hdr.Ttl = 3600
301 - key.Flags = 256
302 - key.Protocol = 3
303 - key.Algorithm = RSASHA256
304 - priv, _ := key.Generate(2048)
305 -
306 - soa := new(SOA)
307 - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
308 - soa.Ns = "open.nlnetlabs.nl."
309 - soa.Mbox = "miekg.atoom.net."
310 - soa.Serial = 1293945905
311 - soa.Refresh = 14400
312 - soa.Retry = 3600
313 - soa.Expire = 604800
314 - soa.Minttl = 86400
315 -
316 - sig := new(RRSIG)
317 - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
318 - sig.TypeCovered = TypeSOA
319 - sig.Algorithm = RSASHA256
320 - sig.Labels = 2
321 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
322 - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
323 - sig.OrigTtl = soa.Hdr.Ttl
324 - sig.KeyTag = key.KeyTag()
325 - sig.SignerName = key.Hdr.Name
326 -
327 - if err := sig.Sign(priv, []RR{soa}); err != nil {
328 - t.Error("failed to sign")
329 - return
330 - }
331 - if err := sig.Verify(key, []RR{soa}); err != nil {
332 - t.Error("failed to verify")
333 - }
334 -}
335 -
336 -func TestKeyToDS(t *testing.T) {
337 - key := new(DNSKEY)
338 - key.Hdr.Name = "miek.nl."
339 - key.Hdr.Rrtype = TypeDNSKEY
340 - key.Hdr.Class = ClassINET
341 - key.Hdr.Ttl = 3600
342 - key.Flags = 256
343 - key.Protocol = 3
344 - key.Algorithm = RSASHA256
345 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz"
346 -
347 - ds := key.ToDS(SHA1)
348 - if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" {
349 - t.Errorf("wrong DS digest for SHA1\n%v", ds)
350 - }
351 -}
352 -
353 -func TestSignRSA(t *testing.T) {
354 - pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ"
355 -
356 - priv := `Private-key-format: v1.3
357 -Algorithm: 5 (RSASHA1)
358 -Modulus: v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8/FCczL25wLKUD4W4f1xKMhw9/g+ol926keT1foQFiPGsItjinX/IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k=
359 -PublicExponent: AQAB
360 -PrivateExponent: YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66/EN/GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV+YDyEu7Hp/rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV/1wRDK1A5NxsHPDMYi2SoK63Enm/1ptk=
361 -Prime1: /wjOG+fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx/x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw==
362 -Prime2: wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA+t+iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw==
363 -Exponent1: N0A7FsSRIg+IAN8YPQqlawoTtG1t1OkJ+nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ==
364 -Exponent2: SvuYRaGyvo0zemE3oS+WRm2scxR8eiA8WJGeOc+obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW/vwMA46lpLzJNw==
365 -Coefficient: 8+7ZN/JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs+hGw==
366 -Created: 20110302104537
367 -Publish: 20110302104537
368 -Activate: 20110302104537`
369 -
370 - xk, _ := NewRR(pub)
371 - k := xk.(*DNSKEY)
372 - p, err := k.NewPrivateKey(priv)
373 - if err != nil {
374 - t.Error(err)
375 - }
376 - switch priv := p.(type) {
377 - case *RSAPrivateKey:
378 - if 65537 != priv.PublicKey.E {
379 - t.Error("exponenent should be 65537")
380 - }
381 - default:
382 - t.Errorf("we should have read an RSA key: %v", priv)
383 - }
384 - if k.KeyTag() != 37350 {
385 - t.Errorf("keytag should be 37350, got %d %v", k.KeyTag(), k)
386 - }
387 -
388 - soa := new(SOA)
389 - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0}
390 - soa.Ns = "open.nlnetlabs.nl."
391 - soa.Mbox = "miekg.atoom.net."
392 - soa.Serial = 1293945905
393 - soa.Refresh = 14400
394 - soa.Retry = 3600
395 - soa.Expire = 604800
396 - soa.Minttl = 86400
397 -
398 - sig := new(RRSIG)
399 - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
400 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
401 - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
402 - sig.KeyTag = k.KeyTag()
403 - sig.SignerName = k.Hdr.Name
404 - sig.Algorithm = k.Algorithm
405 -
406 - sig.Sign(p, []RR{soa})
407 - if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" {
408 - t.Errorf("signature is not correct: %v", sig)
409 - }
410 -}
411 -
412 -func TestSignVerifyECDSA(t *testing.T) {
413 - pub := `example.net. 3600 IN DNSKEY 257 3 14 (
414 - xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
415 - w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
416 - /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
417 - priv := `Private-key-format: v1.2
418 -Algorithm: 14 (ECDSAP384SHA384)
419 -PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
420 -
421 - eckey, err := NewRR(pub)
422 - if err != nil {
423 - t.Fatal(err)
424 - }
425 - privkey, err := eckey.(*DNSKEY).NewPrivateKey(priv)
426 - if err != nil {
427 - t.Fatal(err)
428 - }
429 - // TODO: Create separate test for this
430 - ds := eckey.(*DNSKEY).ToDS(SHA384)
431 - if ds.KeyTag != 10771 {
432 - t.Fatal("wrong keytag on DS")
433 - }
434 - if ds.Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" {
435 - t.Fatal("wrong DS Digest")
436 - }
437 - a, _ := NewRR("www.example.net. 3600 IN A 192.0.2.1")
438 - sig := new(RRSIG)
439 - sig.Hdr = RR_Header{"example.net.", TypeRRSIG, ClassINET, 14400, 0}
440 - sig.Expiration, _ = StringToTime("20100909102025")
441 - sig.Inception, _ = StringToTime("20100812102025")
442 - sig.KeyTag = eckey.(*DNSKEY).KeyTag()
443 - sig.SignerName = eckey.(*DNSKEY).Hdr.Name
444 - sig.Algorithm = eckey.(*DNSKEY).Algorithm
445 -
446 - if sig.Sign(privkey, []RR{a}) != nil {
447 - t.Fatal("failure to sign the record")
448 - }
449 -
450 - if err := sig.Verify(eckey.(*DNSKEY), []RR{a}); err != nil {
451 - t.Fatalf("Failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
452 - eckey.(*DNSKEY).String(),
453 - a.String(),
454 - sig.String(),
455 - eckey.(*DNSKEY).PrivateKeyString(privkey),
456 - err,
457 - )
458 - }
459 -}
460 -
461 -func TestSignVerifyECDSA2(t *testing.T) {
462 - srv1, err := NewRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.")
463 - if err != nil {
464 - t.Fatal(err)
465 - }
466 - srv := srv1.(*SRV)
467 -
468 - // With this key
469 - key := new(DNSKEY)
470 - key.Hdr.Rrtype = TypeDNSKEY
471 - key.Hdr.Name = "miek.nl."
472 - key.Hdr.Class = ClassINET
473 - key.Hdr.Ttl = 14400
474 - key.Flags = 256
475 - key.Protocol = 3
476 - key.Algorithm = ECDSAP256SHA256
477 - privkey, err := key.Generate(256)
478 - if err != nil {
479 - t.Fatal("failure to generate key")
480 - }
481 -
482 - // Fill in the values of the Sig, before signing
483 - sig := new(RRSIG)
484 - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0}
485 - sig.TypeCovered = srv.Hdr.Rrtype
486 - sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3
487 - sig.OrigTtl = srv.Hdr.Ttl
488 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05"
489 - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05"
490 - sig.KeyTag = key.KeyTag() // Get the keyfrom the Key
491 - sig.SignerName = key.Hdr.Name
492 - sig.Algorithm = ECDSAP256SHA256
493 -
494 - if sig.Sign(privkey, []RR{srv}) != nil {
495 - t.Fatal("failure to sign the record")
496 - }
497 -
498 - err = sig.Verify(key, []RR{srv})
499 - if err != nil {
500 - t.Logf("Failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v",
501 - key.String(),
502 - srv.String(),
503 - sig.String(),
504 - key.PrivateKeyString(privkey),
505 - err,
506 - )
507 - }
508 -}
509 -
510 -// Here the test vectors from the relevant RFCs are checked.
511 -// rfc6605 6.1
512 -func TestRFC6605P256(t *testing.T) {
513 - exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 13 (
514 - GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb
515 - krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )`
516 - exPriv := `Private-key-format: v1.2
517 -Algorithm: 13 (ECDSAP256SHA256)
518 -PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=`
519 - rrDNSKEY, err := NewRR(exDNSKEY)
520 - if err != nil {
521 - t.Fatal(err)
522 - }
523 - priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
524 - if err != nil {
525 - t.Fatal(err)
526 - }
527 -
528 - exDS := `example.net. 3600 IN DS 55648 13 2 (
529 - b4c8c1fe2e7477127b27115656ad6256f424625bf5c1
530 - e2770ce6d6e37df61d17 )`
531 - rrDS, err := NewRR(exDS)
532 - if err != nil {
533 - t.Fatal(err)
534 - }
535 - ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256)
536 - if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
537 - t.Errorf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
538 - }
539 -
540 - exA := `www.example.net. 3600 IN A 192.0.2.1`
541 - exRRSIG := `www.example.net. 3600 IN RRSIG A 13 3 3600 (
542 - 20100909100439 20100812100439 55648 example.net.
543 - qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA
544 - yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )`
545 - rrA, err := NewRR(exA)
546 - if err != nil {
547 - t.Fatal(err)
548 - }
549 - rrRRSIG, err := NewRR(exRRSIG)
550 - if err != nil {
551 - t.Fatal(err)
552 - }
553 - if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
554 - t.Errorf("Failure to validate the spec RRSIG: %v", err)
555 - }
556 -
557 - ourRRSIG := &RRSIG{
558 - Hdr: RR_Header{
559 - Ttl: rrA.Header().Ttl,
560 - },
561 - KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
562 - SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
563 - Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
564 - }
565 - ourRRSIG.Expiration, _ = StringToTime("20100909100439")
566 - ourRRSIG.Inception, _ = StringToTime("20100812100439")
567 - err = ourRRSIG.Sign(priv, []RR{rrA})
568 - if err != nil {
569 - t.Fatal(err)
570 - }
571 -
572 - if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
573 - t.Errorf("Failure to validate our RRSIG: %v", err)
574 - }
575 -
576 - // Signatures are randomized
577 - rrRRSIG.(*RRSIG).Signature = ""
578 - ourRRSIG.Signature = ""
579 - if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
580 - t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
581 - }
582 -}
583 -
584 -// rfc6605 6.2
585 -func TestRFC6605P384(t *testing.T) {
586 - exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 14 (
587 - xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1
588 - w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8
589 - /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )`
590 - exPriv := `Private-key-format: v1.2
591 -Algorithm: 14 (ECDSAP384SHA384)
592 -PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR`
593 - rrDNSKEY, err := NewRR(exDNSKEY)
594 - if err != nil {
595 - t.Fatal(err)
596 - }
597 - priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv)
598 - if err != nil {
599 - t.Fatal(err)
600 - }
601 -
602 - exDS := `example.net. 3600 IN DS 10771 14 4 (
603 - 72d7b62976ce06438e9c0bf319013cf801f09ecc84b8
604 - d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94
605 - 6df983d6 )`
606 - rrDS, err := NewRR(exDS)
607 - if err != nil {
608 - t.Fatal(err)
609 - }
610 - ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA384)
611 - if !reflect.DeepEqual(ourDS, rrDS.(*DS)) {
612 - t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS))
613 - }
614 -
615 - exA := `www.example.net. 3600 IN A 192.0.2.1`
616 - exRRSIG := `www.example.net. 3600 IN RRSIG A 14 3 3600 (
617 - 20100909102025 20100812102025 10771 example.net.
618 - /L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP
619 - 95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz
620 - WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )`
621 - rrA, err := NewRR(exA)
622 - if err != nil {
623 - t.Fatal(err)
624 - }
625 - rrRRSIG, err := NewRR(exRRSIG)
626 - if err != nil {
627 - t.Fatal(err)
628 - }
629 - if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
630 - t.Errorf("Failure to validate the spec RRSIG: %v", err)
631 - }
632 -
633 - ourRRSIG := &RRSIG{
634 - Hdr: RR_Header{
635 - Ttl: rrA.Header().Ttl,
636 - },
637 - KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(),
638 - SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name,
639 - Algorithm: rrDNSKEY.(*DNSKEY).Algorithm,
640 - }
641 - ourRRSIG.Expiration, _ = StringToTime("20100909102025")
642 - ourRRSIG.Inception, _ = StringToTime("20100812102025")
643 - err = ourRRSIG.Sign(priv, []RR{rrA})
644 - if err != nil {
645 - t.Fatal(err)
646 - }
647 -
648 - if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil {
649 - t.Errorf("Failure to validate our RRSIG: %v", err)
650 - }
651 -
652 - // Signatures are randomized
653 - rrRRSIG.(*RRSIG).Signature = ""
654 - ourRRSIG.Signature = ""
655 - if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) {
656 - t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG))
657 - }
658 -}
Godeps/_workspace/src/github.com/miekg/dns/doc.go deleted
-247
@@ -1,247 +0,0 @@
1 -/*
2 -Package dns implements a full featured interface to the Domain Name System.
3 -Server- and client-side programming is supported.
4 -The package allows complete control over what is send out to the DNS. The package
5 -API follows the less-is-more principle, by presenting a small, clean interface.
6 -
7 -The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
8 -TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.
9 -Note that domain names MUST be fully qualified, before sending them, unqualified
10 -names in a message will result in a packing failure.
11 -
12 -Resource records are native types. They are not stored in wire format.
13 -Basic usage pattern for creating a new resource record:
14 -
15 - r := new(dns.MX)
16 - r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
17 - r.Preference = 10
18 - r.Mx = "mx.miek.nl."
19 -
20 -Or directly from a string:
21 -
22 - mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
23 -
24 -Or when the default TTL (3600) and class (IN) suit you:
25 -
26 - mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.")
27 -
28 -Or even:
29 -
30 - mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
31 -
32 -In the DNS messages are exchanged, these messages contain resource
33 -records (sets). Use pattern for creating a message:
34 -
35 - m := new(dns.Msg)
36 - m.SetQuestion("miek.nl.", dns.TypeMX)
37 -
38 -Or when not certain if the domain name is fully qualified:
39 -
40 - m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)
41 -
42 -The message m is now a message with the question section set to ask
43 -the MX records for the miek.nl. zone.
44 -
45 -The following is slightly more verbose, but more flexible:
46 -
47 - m1 := new(dns.Msg)
48 - m1.Id = dns.Id()
49 - m1.RecursionDesired = true
50 - m1.Question = make([]dns.Question, 1)
51 - m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
52 -
53 -After creating a message it can be send.
54 -Basic use pattern for synchronous querying the DNS at a
55 -server configured on 127.0.0.1 and port 53:
56 -
57 - c := new(dns.Client)
58 - in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
59 -
60 -Suppressing
61 -multiple outstanding queries (with the same question, type and class) is as easy as setting:
62 -
63 - c.SingleInflight = true
64 -
65 -If these "advanced" features are not needed, a simple UDP query can be send,
66 -with:
67 -
68 - in, err := dns.Exchange(m1, "127.0.0.1:53")
69 -
70 -When this functions returns you will get dns message. A dns message consists
71 -out of four sections.
72 -The question section: in.Question, the answer section: in.Answer,
73 -the authority section: in.Ns and the additional section: in.Extra.
74 -
75 -Each of these sections (except the Question section) contain a []RR. Basic
76 -use pattern for accessing the rdata of a TXT RR as the first RR in
77 -the Answer section:
78 -
79 - if t, ok := in.Answer[0].(*dns.TXT); ok {
80 - // do something with t.Txt
81 - }
82 -
83 -Domain Name and TXT Character String Representations
84 -
85 -Both domain names and TXT character strings are converted to presentation
86 -form both when unpacked and when converted to strings.
87 -
88 -For TXT character strings, tabs, carriage returns and line feeds will be
89 -converted to \t, \r and \n respectively. Back slashes and quotations marks
90 -will be escaped. Bytes below 32 and above 127 will be converted to \DDD
91 -form.
92 -
93 -For domain names, in addition to the above rules brackets, periods,
94 -spaces, semicolons and the at symbol are escaped.
95 -
96 -DNSSEC
97 -
98 -DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It
99 -uses public key cryptography to sign resource records. The
100 -public keys are stored in DNSKEY records and the signatures in RRSIG records.
101 -
102 -Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit
103 -to an request.
104 -
105 - m := new(dns.Msg)
106 - m.SetEdns0(4096, true)
107 -
108 -Signature generation, signature verification and key generation are all supported.
109 -
110 -DYNAMIC UPDATES
111 -
112 -Dynamic updates reuses the DNS message format, but renames three of
113 -the sections. Question is Zone, Answer is Prerequisite, Authority is
114 -Update, only the Additional is not renamed. See RFC 2136 for the gory details.
115 -
116 -You can set a rather complex set of rules for the existence of absence of
117 -certain resource records or names in a zone to specify if resource records
118 -should be added or removed. The table from RFC 2136 supplemented with the Go
119 -DNS function shows which functions exist to specify the prerequisites.
120 -
121 -3.2.4 - Table Of Metavalues Used In Prerequisite Section
122 -
123 - CLASS TYPE RDATA Meaning Function
124 - --------------------------------------------------------------
125 - ANY ANY empty Name is in use dns.NameUsed
126 - ANY rrset empty RRset exists (value indep) dns.RRsetUsed
127 - NONE ANY empty Name is not in use dns.NameNotUsed
128 - NONE rrset empty RRset does not exist dns.RRsetNotUsed
129 - zone rrset rr RRset exists (value dep) dns.Used
130 -
131 -The prerequisite section can also be left empty.
132 -If you have decided on the prerequisites you can tell what RRs should
133 -be added or deleted. The next table shows the options you have and
134 -what functions to call.
135 -
136 -3.4.2.6 - Table Of Metavalues Used In Update Section
137 -
138 - CLASS TYPE RDATA Meaning Function
139 - ---------------------------------------------------------------
140 - ANY ANY empty Delete all RRsets from name dns.RemoveName
141 - ANY rrset empty Delete an RRset dns.RemoveRRset
142 - NONE rrset rr Delete an RR from RRset dns.Remove
143 - zone rrset rr Add to an RRset dns.Insert
144 -
145 -TRANSACTION SIGNATURE
146 -
147 -An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
148 -The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512.
149 -
150 -Basic use pattern when querying with a TSIG name "axfr." (note that these key names
151 -must be fully qualified - as they are domain names) and the base64 secret
152 -"so6ZGir4GPAqINNh9U5c3A==":
153 -
154 - c := new(dns.Client)
155 - c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
156 - m := new(dns.Msg)
157 - m.SetQuestion("miek.nl.", dns.TypeMX)
158 - m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
159 - ...
160 - // When sending the TSIG RR is calculated and filled in before sending
161 -
162 -When requesting an zone transfer (almost all TSIG usage is when requesting zone transfers), with
163 -TSIG, this is the basic use pattern. In this example we request an AXFR for
164 -miek.nl. with TSIG key named "axfr." and secret "so6ZGir4GPAqINNh9U5c3A=="
165 -and using the server 176.58.119.54:
166 -
167 - t := new(dns.Transfer)
168 - m := new(dns.Msg)
169 - t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
170 - m.SetAxfr("miek.nl.")
171 - m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
172 - c, err := t.In(m, "176.58.119.54:53")
173 - for r := range c { ... }
174 -
175 -You can now read the records from the transfer as they come in. Each envelope is checked with TSIG.
176 -If something is not correct an error is returned.
177 -
178 -Basic use pattern validating and replying to a message that has TSIG set.
179 -
180 - server := &dns.Server{Addr: ":53", Net: "udp"}
181 - server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
182 - go server.ListenAndServe()
183 - dns.HandleFunc(".", handleRequest)
184 -
185 - func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
186 - m := new(Msg)
187 - m.SetReply(r)
188 - if r.IsTsig() {
189 - if w.TsigStatus() == nil {
190 - // *Msg r has an TSIG record and it was validated
191 - m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
192 - } else {
193 - // *Msg r has an TSIG records and it was not valided
194 - }
195 - }
196 - w.WriteMsg(m)
197 - }
198 -
199 -PRIVATE RRS
200 -
201 -RFC 6895 sets aside a range of type codes for private use. This range
202 -is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
203 -can be used, before requesting an official type code from IANA.
204 -
205 -EDNS0
206 -
207 -EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated
208 -by RFC 6891. It defines an new RR type, the OPT RR, which is then completely
209 -abused.
210 -Basic use pattern for creating an (empty) OPT RR:
211 -
212 - o := new(dns.OPT)
213 - o.Hdr.Name = "." // MUST be the root zone, per definition.
214 - o.Hdr.Rrtype = dns.TypeOPT
215 -
216 -The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891)
217 -interfaces. Currently only a few have been standardized: EDNS0_NSID
218 -(RFC 5001) and EDNS0_SUBNET (draft-vandergaast-edns-client-subnet-02). Note
219 -that these options may be combined in an OPT RR.
220 -Basic use pattern for a server to check if (and which) options are set:
221 -
222 - // o is a dns.OPT
223 - for _, s := range o.Option {
224 - switch e := s.(type) {
225 - case *dns.EDNS0_NSID:
226 - // do stuff with e.Nsid
227 - case *dns.EDNS0_SUBNET:
228 - // access e.Family, e.Address, etc.
229 - }
230 - }
231 -
232 -SIG(0)
233 -
234 -From RFC 2931:
235 -
236 - SIG(0) provides protection for DNS transactions and requests ....
237 - ... protection for glue records, DNS requests, protection for message headers
238 - on requests and responses, and protection of the overall integrity of a response.
239 -
240 -It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared
241 -secret approach in TSIG.
242 -Supported algorithms: DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256 and
243 -RSASHA512.
244 -
245 -Signing subsequent messages in multi-message sessions is not implemented.
246 -*/
247 -package dns
Godeps/_workspace/src/github.com/miekg/dns/dyn_test.go deleted
-3
@@ -1,3 +0,0 @@
1 -package dns
2 -
3 -// Find better solution
Godeps/_workspace/src/github.com/miekg/dns/edns.go deleted
-523
@@ -1,523 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "encoding/hex"
5 - "errors"
6 - "net"
7 - "strconv"
8 -)
9 -
10 -// EDNS0 Option codes.
11 -const (
12 - EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
13 - EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
14 - EDNS0NSID = 0x3 // nsid (RFC5001)
15 - EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
16 - EDNS0DHU = 0x6 // DS Hash Understood
17 - EDNS0N3U = 0x7 // NSEC3 Hash Understood
18 - EDNS0SUBNET = 0x8 // client-subnet (RFC6891)
19 - EDNS0EXPIRE = 0x9 // EDNS0 expire
20 - EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
21 - EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
22 - EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891)
23 - _DO = 1 << 15 // dnssec ok
24 -)
25 -
26 -// OPT is the EDNS0 RR appended to messages to convey extra (meta) information.
27 -// See RFC 6891.
28 -type OPT struct {
29 - Hdr RR_Header
30 - Option []EDNS0 `dns:"opt"`
31 -}
32 -
33 -func (rr *OPT) Header() *RR_Header {
34 - return &rr.Hdr
35 -}
36 -
37 -func (rr *OPT) String() string {
38 - s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; "
39 - if rr.Do() {
40 - s += "flags: do; "
41 - } else {
42 - s += "flags: ; "
43 - }
44 - s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
45 -
46 - for _, o := range rr.Option {
47 - switch o.(type) {
48 - case *EDNS0_NSID:
49 - s += "\n; NSID: " + o.String()
50 - h, e := o.pack()
51 - var r string
52 - if e == nil {
53 - for _, c := range h {
54 - r += "(" + string(c) + ")"
55 - }
56 - s += " " + r
57 - }
58 - case *EDNS0_SUBNET:
59 - s += "\n; SUBNET: " + o.String()
60 - if o.(*EDNS0_SUBNET).DraftOption {
61 - s += " (draft)"
62 - }
63 - case *EDNS0_UL:
64 - s += "\n; UPDATE LEASE: " + o.String()
65 - case *EDNS0_LLQ:
66 - s += "\n; LONG LIVED QUERIES: " + o.String()
67 - case *EDNS0_DAU:
68 - s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String()
69 - case *EDNS0_DHU:
70 - s += "\n; DS HASH UNDERSTOOD: " + o.String()
71 - case *EDNS0_N3U:
72 - s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String()
73 - case *EDNS0_LOCAL:
74 - s += "\n; LOCAL OPT: " + o.String()
75 - }
76 - }
77 - return s
78 -}
79 -
80 -func (rr *OPT) len() int {
81 - l := rr.Hdr.len()
82 - for i := 0; i < len(rr.Option); i++ {
83 - l += 4 // Account for 2-byte option code and 2-byte option length.
84 - lo, _ := rr.Option[i].pack()
85 - l += len(lo)
86 - }
87 - return l
88 -}
89 -
90 -func (rr *OPT) copy() RR {
91 - return &OPT{*rr.Hdr.copyHeader(), rr.Option}
92 -}
93 -
94 -// return the old value -> delete SetVersion?
95 -
96 -// Version returns the EDNS version used. Only zero is defined.
97 -func (rr *OPT) Version() uint8 {
98 - return uint8((rr.Hdr.Ttl & 0x00FF0000) >> 16)
99 -}
100 -
101 -// SetVersion sets the version of EDNS. This is usually zero.
102 -func (rr *OPT) SetVersion(v uint8) {
103 - rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | (uint32(v) << 16)
104 -}
105 -
106 -// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
107 -func (rr *OPT) ExtendedRcode() uint8 {
108 - return uint8((rr.Hdr.Ttl & 0xFF000000) >> 24)
109 -}
110 -
111 -// SetExtendedRcode sets the EDNS extended RCODE field.
112 -func (rr *OPT) SetExtendedRcode(v uint8) {
113 - rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v) << 24)
114 -}
115 -
116 -// UDPSize returns the UDP buffer size.
117 -func (rr *OPT) UDPSize() uint16 {
118 - return rr.Hdr.Class
119 -}
120 -
121 -// SetUDPSize sets the UDP buffer size.
122 -func (rr *OPT) SetUDPSize(size uint16) {
123 - rr.Hdr.Class = size
124 -}
125 -
126 -// Do returns the value of the DO (DNSSEC OK) bit.
127 -func (rr *OPT) Do() bool {
128 - return rr.Hdr.Ttl&_DO == _DO
129 -}
130 -
131 -// SetDo sets the DO (DNSSEC OK) bit.
132 -func (rr *OPT) SetDo() {
133 - rr.Hdr.Ttl |= _DO
134 -}
135 -
136 -// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to
137 -// it.
138 -type EDNS0 interface {
139 - // Option returns the option code for the option.
140 - Option() uint16
141 - // pack returns the bytes of the option data.
142 - pack() ([]byte, error)
143 - // unpack sets the data as found in the buffer. Is also sets
144 - // the length of the slice as the length of the option data.
145 - unpack([]byte) error
146 - // String returns the string representation of the option.
147 - String() string
148 -}
149 -
150 -// The nsid EDNS0 option is used to retrieve a nameserver
151 -// identifier. When sending a request Nsid must be set to the empty string
152 -// The identifier is an opaque string encoded as hex.
153 -// Basic use pattern for creating an nsid option:
154 -//
155 -// o := new(dns.OPT)
156 -// o.Hdr.Name = "."
157 -// o.Hdr.Rrtype = dns.TypeOPT
158 -// e := new(dns.EDNS0_NSID)
159 -// e.Code = dns.EDNS0NSID
160 -// e.Nsid = "AA"
161 -// o.Option = append(o.Option, e)
162 -type EDNS0_NSID struct {
163 - Code uint16 // Always EDNS0NSID
164 - Nsid string // This string needs to be hex encoded
165 -}
166 -
167 -func (e *EDNS0_NSID) pack() ([]byte, error) {
168 - h, err := hex.DecodeString(e.Nsid)
169 - if err != nil {
170 - return nil, err
171 - }
172 - return h, nil
173 -}
174 -
175 -func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID }
176 -func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil }
177 -func (e *EDNS0_NSID) String() string { return string(e.Nsid) }
178 -
179 -// The subnet EDNS0 option is used to give the remote nameserver
180 -// an idea of where the client lives. It can then give back a different
181 -// answer depending on the location or network topology.
182 -// Basic use pattern for creating an subnet option:
183 -//
184 -// o := new(dns.OPT)
185 -// o.Hdr.Name = "."
186 -// o.Hdr.Rrtype = dns.TypeOPT
187 -// e := new(dns.EDNS0_SUBNET)
188 -// e.Code = dns.EDNS0SUBNET
189 -// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6
190 -// e.NetMask = 32 // 32 for IPV4, 128 for IPv6
191 -// e.SourceScope = 0
192 -// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4
193 -// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6
194 -// o.Option = append(o.Option, e)
195 -type EDNS0_SUBNET struct {
196 - Code uint16 // Always EDNS0SUBNET
197 - Family uint16 // 1 for IP, 2 for IP6
198 - SourceNetmask uint8
199 - SourceScope uint8
200 - Address net.IP
201 - DraftOption bool // Set to true if using the old (0x50fa) option code
202 -}
203 -
204 -func (e *EDNS0_SUBNET) Option() uint16 {
205 - if e.DraftOption {
206 - return EDNS0SUBNETDRAFT
207 - }
208 - return EDNS0SUBNET
209 -}
210 -
211 -func (e *EDNS0_SUBNET) pack() ([]byte, error) {
212 - b := make([]byte, 4)
213 - b[0], b[1] = packUint16(e.Family)
214 - b[2] = e.SourceNetmask
215 - b[3] = e.SourceScope
216 - switch e.Family {
217 - case 1:
218 - if e.SourceNetmask > net.IPv4len*8 {
219 - return nil, errors.New("dns: bad netmask")
220 - }
221 - ip := make([]byte, net.IPv4len)
222 - a := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8))
223 - for i := 0; i < net.IPv4len; i++ {
224 - if i+1 > len(e.Address) {
225 - break
226 - }
227 - ip[i] = a[i]
228 - }
229 - needLength := e.SourceNetmask / 8
230 - if e.SourceNetmask%8 > 0 {
231 - needLength++
232 - }
233 - ip = ip[:needLength]
234 - b = append(b, ip...)
235 - case 2:
236 - if e.SourceNetmask > net.IPv6len*8 {
237 - return nil, errors.New("dns: bad netmask")
238 - }
239 - ip := make([]byte, net.IPv6len)
240 - a := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8))
241 - for i := 0; i < net.IPv6len; i++ {
242 - if i+1 > len(e.Address) {
243 - break
244 - }
245 - ip[i] = a[i]
246 - }
247 - needLength := e.SourceNetmask / 8
248 - if e.SourceNetmask%8 > 0 {
249 - needLength++
250 - }
251 - ip = ip[:needLength]
252 - b = append(b, ip...)
253 - default:
254 - return nil, errors.New("dns: bad address family")
255 - }
256 - return b, nil
257 -}
258 -
259 -func (e *EDNS0_SUBNET) unpack(b []byte) error {
260 - lb := len(b)
261 - if lb < 4 {
262 - return ErrBuf
263 - }
264 - e.Family, _ = unpackUint16(b, 0)
265 - e.SourceNetmask = b[2]
266 - e.SourceScope = b[3]
267 - switch e.Family {
268 - case 1:
269 - addr := make([]byte, 4)
270 - for i := 0; i < int(e.SourceNetmask/8); i++ {
271 - if i >= len(addr) || 4+i >= len(b) {
272 - return ErrBuf
273 - }
274 - addr[i] = b[4+i]
275 - }
276 - e.Address = net.IPv4(addr[0], addr[1], addr[2], addr[3])
277 - case 2:
278 - addr := make([]byte, 16)
279 - for i := 0; i < int(e.SourceNetmask/8); i++ {
280 - if i >= len(addr) || 4+i >= len(b) {
281 - return ErrBuf
282 - }
283 - addr[i] = b[4+i]
284 - }
285 - e.Address = net.IP{addr[0], addr[1], addr[2], addr[3], addr[4],
286 - addr[5], addr[6], addr[7], addr[8], addr[9], addr[10],
287 - addr[11], addr[12], addr[13], addr[14], addr[15]}
288 - }
289 - return nil
290 -}
291 -
292 -func (e *EDNS0_SUBNET) String() (s string) {
293 - if e.Address == nil {
294 - s = "<nil>"
295 - } else if e.Address.To4() != nil {
296 - s = e.Address.String()
297 - } else {
298 - s = "[" + e.Address.String() + "]"
299 - }
300 - s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope))
301 - return
302 -}
303 -
304 -// The UL (Update Lease) EDNS0 (draft RFC) option is used to tell the server to set
305 -// an expiration on an update RR. This is helpful for clients that cannot clean
306 -// up after themselves. This is a draft RFC and more information can be found at
307 -// http://files.dns-sd.org/draft-sekar-dns-ul.txt
308 -//
309 -// o := new(dns.OPT)
310 -// o.Hdr.Name = "."
311 -// o.Hdr.Rrtype = dns.TypeOPT
312 -// e := new(dns.EDNS0_UL)
313 -// e.Code = dns.EDNS0UL
314 -// e.Lease = 120 // in seconds
315 -// o.Option = append(o.Option, e)
316 -type EDNS0_UL struct {
317 - Code uint16 // Always EDNS0UL
318 - Lease uint32
319 -}
320 -
321 -func (e *EDNS0_UL) Option() uint16 { return EDNS0UL }
322 -func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), 10) }
323 -
324 -// Copied: http://golang.org/src/pkg/net/dnsmsg.go
325 -func (e *EDNS0_UL) pack() ([]byte, error) {
326 - b := make([]byte, 4)
327 - b[0] = byte(e.Lease >> 24)
328 - b[1] = byte(e.Lease >> 16)
329 - b[2] = byte(e.Lease >> 8)
330 - b[3] = byte(e.Lease)
331 - return b, nil
332 -}
333 -
334 -func (e *EDNS0_UL) unpack(b []byte) error {
335 - if len(b) < 4 {
336 - return ErrBuf
337 - }
338 - e.Lease = uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
339 - return nil
340 -}
341 -
342 -// Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01
343 -// Implemented for completeness, as the EDNS0 type code is assigned.
344 -type EDNS0_LLQ struct {
345 - Code uint16 // Always EDNS0LLQ
346 - Version uint16
347 - Opcode uint16
348 - Error uint16
349 - Id uint64
350 - LeaseLife uint32
351 -}
352 -
353 -func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ }
354 -
355 -func (e *EDNS0_LLQ) pack() ([]byte, error) {
356 - b := make([]byte, 18)
357 - b[0], b[1] = packUint16(e.Version)
358 - b[2], b[3] = packUint16(e.Opcode)
359 - b[4], b[5] = packUint16(e.Error)
360 - b[6] = byte(e.Id >> 56)
361 - b[7] = byte(e.Id >> 48)
362 - b[8] = byte(e.Id >> 40)
363 - b[9] = byte(e.Id >> 32)
364 - b[10] = byte(e.Id >> 24)
365 - b[11] = byte(e.Id >> 16)
366 - b[12] = byte(e.Id >> 8)
367 - b[13] = byte(e.Id)
368 - b[14] = byte(e.LeaseLife >> 24)
369 - b[15] = byte(e.LeaseLife >> 16)
370 - b[16] = byte(e.LeaseLife >> 8)
371 - b[17] = byte(e.LeaseLife)
372 - return b, nil
373 -}
374 -
375 -func (e *EDNS0_LLQ) unpack(b []byte) error {
376 - if len(b) < 18 {
377 - return ErrBuf
378 - }
379 - e.Version, _ = unpackUint16(b, 0)
380 - e.Opcode, _ = unpackUint16(b, 2)
381 - e.Error, _ = unpackUint16(b, 4)
382 - e.Id = uint64(b[6])<<56 | uint64(b[6+1])<<48 | uint64(b[6+2])<<40 |
383 - uint64(b[6+3])<<32 | uint64(b[6+4])<<24 | uint64(b[6+5])<<16 | uint64(b[6+6])<<8 | uint64(b[6+7])
384 - e.LeaseLife = uint32(b[14])<<24 | uint32(b[14+1])<<16 | uint32(b[14+2])<<8 | uint32(b[14+3])
385 - return nil
386 -}
387 -
388 -func (e *EDNS0_LLQ) String() string {
389 - s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) +
390 - " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(uint64(e.Id), 10) +
391 - " " + strconv.FormatUint(uint64(e.LeaseLife), 10)
392 - return s
393 -}
394 -
395 -type EDNS0_DAU struct {
396 - Code uint16 // Always EDNS0DAU
397 - AlgCode []uint8
398 -}
399 -
400 -func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU }
401 -func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil }
402 -func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil }
403 -
404 -func (e *EDNS0_DAU) String() string {
405 - s := ""
406 - for i := 0; i < len(e.AlgCode); i++ {
407 - if a, ok := AlgorithmToString[e.AlgCode[i]]; ok {
408 - s += " " + a
409 - } else {
410 - s += " " + strconv.Itoa(int(e.AlgCode[i]))
411 - }
412 - }
413 - return s
414 -}
415 -
416 -type EDNS0_DHU struct {
417 - Code uint16 // Always EDNS0DHU
418 - AlgCode []uint8
419 -}
420 -
421 -func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU }
422 -func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil }
423 -func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil }
424 -
425 -func (e *EDNS0_DHU) String() string {
426 - s := ""
427 - for i := 0; i < len(e.AlgCode); i++ {
428 - if a, ok := HashToString[e.AlgCode[i]]; ok {
429 - s += " " + a
430 - } else {
431 - s += " " + strconv.Itoa(int(e.AlgCode[i]))
432 - }
433 - }
434 - return s
435 -}
436 -
437 -type EDNS0_N3U struct {
438 - Code uint16 // Always EDNS0N3U
439 - AlgCode []uint8
440 -}
441 -
442 -func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U }
443 -func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil }
444 -func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil }
445 -
446 -func (e *EDNS0_N3U) String() string {
447 - // Re-use the hash map
448 - s := ""
449 - for i := 0; i < len(e.AlgCode); i++ {
450 - if a, ok := HashToString[e.AlgCode[i]]; ok {
451 - s += " " + a
452 - } else {
453 - s += " " + strconv.Itoa(int(e.AlgCode[i]))
454 - }
455 - }
456 - return s
457 -}
458 -
459 -type EDNS0_EXPIRE struct {
460 - Code uint16 // Always EDNS0EXPIRE
461 - Expire uint32
462 -}
463 -
464 -func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE }
465 -func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) }
466 -
467 -func (e *EDNS0_EXPIRE) pack() ([]byte, error) {
468 - b := make([]byte, 4)
469 - b[0] = byte(e.Expire >> 24)
470 - b[1] = byte(e.Expire >> 16)
471 - b[2] = byte(e.Expire >> 8)
472 - b[3] = byte(e.Expire)
473 - return b, nil
474 -}
475 -
476 -func (e *EDNS0_EXPIRE) unpack(b []byte) error {
477 - if len(b) < 4 {
478 - return ErrBuf
479 - }
480 - e.Expire = uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3])
481 - return nil
482 -}
483 -
484 -// The local EDNS0 option is used for local/experimental purposes. The option
485 -// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND]
486 -// (RFC6891), although any unassigned code can actually be used. The content of
487 -// the option is made available in Data, unaltered.
488 -// Basic use pattern for creating a local option:
489 -//
490 -// o := new(dns.OPT)
491 -// o.Hdr.Name = "."
492 -// o.Hdr.Rrtype = dns.TypeOPT
493 -// e := new(dns.EDNS0_LOCAL)
494 -// e.Code = dns.EDNS0LOCALSTART
495 -// e.Data = []byte{72, 82, 74}
496 -// o.Option = append(o.Option, e)
497 -type EDNS0_LOCAL struct {
498 - Code uint16
499 - Data []byte
500 -}
501 -
502 -func (e *EDNS0_LOCAL) Option() uint16 { return e.Code }
503 -func (e *EDNS0_LOCAL) String() string {
504 - return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data)
505 -}
506 -
507 -func (e *EDNS0_LOCAL) pack() ([]byte, error) {
508 - b := make([]byte, len(e.Data))
509 - copied := copy(b, e.Data)
510 - if copied != len(e.Data) {
511 - return nil, ErrBuf
512 - }
513 - return b, nil
514 -}
515 -
516 -func (e *EDNS0_LOCAL) unpack(b []byte) error {
517 - e.Data = make([]byte, len(b))
518 - copied := copy(e.Data, b)
519 - if copied != len(b) {
520 - return ErrBuf
521 - }
522 - return nil
523 -}
Godeps/_workspace/src/github.com/miekg/dns/edns_test.go deleted
-48
@@ -1,48 +0,0 @@
1 -package dns
2 -
3 -import "testing"
4 -
5 -func TestOPTTtl(t *testing.T) {
6 - e := &OPT{}
7 - e.Hdr.Name = "."
8 - e.Hdr.Rrtype = TypeOPT
9 -
10 - if e.Do() {
11 - t.Fail()
12 - }
13 -
14 - e.SetDo()
15 - if !e.Do() {
16 - t.Fail()
17 - }
18 -
19 - oldTtl := e.Hdr.Ttl
20 -
21 - if e.Version() != 0 {
22 - t.Fail()
23 - }
24 -
25 - e.SetVersion(42)
26 - if e.Version() != 42 {
27 - t.Fail()
28 - }
29 -
30 - e.SetVersion(0)
31 - if e.Hdr.Ttl != oldTtl {
32 - t.Fail()
33 - }
34 -
35 - if e.ExtendedRcode() != 0 {
36 - t.Fail()
37 - }
38 -
39 - e.SetExtendedRcode(42)
40 - if e.ExtendedRcode() != 42 {
41 - t.Fail()
42 - }
43 -
44 - e.SetExtendedRcode(0)
45 - if e.Hdr.Ttl != oldTtl {
46 - t.Fail()
47 - }
48 -}
Godeps/_workspace/src/github.com/miekg/dns/example_test.go deleted
-147
@@ -1,147 +0,0 @@
1 -package dns_test
2 -
3 -import (
4 - "errors"
5 - "fmt"
6 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/miekg/dns"
7 - "log"
8 - "net"
9 -)
10 -
11 -// Retrieve the MX records for miek.nl.
12 -func ExampleMX() {
13 - config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
14 - c := new(dns.Client)
15 - m := new(dns.Msg)
16 - m.SetQuestion("miek.nl.", dns.TypeMX)
17 - m.RecursionDesired = true
18 - r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
19 - if err != nil {
20 - return
21 - }
22 - if r.Rcode != dns.RcodeSuccess {
23 - return
24 - }
25 - for _, a := range r.Answer {
26 - if mx, ok := a.(*dns.MX); ok {
27 - fmt.Printf("%s\n", mx.String())
28 - }
29 - }
30 -}
31 -
32 -// Retrieve the DNSKEY records of a zone and convert them
33 -// to DS records for SHA1, SHA256 and SHA384.
34 -func ExampleDS(zone string) {
35 - config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
36 - c := new(dns.Client)
37 - m := new(dns.Msg)
38 - if zone == "" {
39 - zone = "miek.nl"
40 - }
41 - m.SetQuestion(dns.Fqdn(zone), dns.TypeDNSKEY)
42 - m.SetEdns0(4096, true)
43 - r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
44 - if err != nil {
45 - return
46 - }
47 - if r.Rcode != dns.RcodeSuccess {
48 - return
49 - }
50 - for _, k := range r.Answer {
51 - if key, ok := k.(*dns.DNSKEY); ok {
52 - for _, alg := range []uint8{dns.SHA1, dns.SHA256, dns.SHA384} {
53 - fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags)
54 - }
55 - }
56 - }
57 -}
58 -
59 -const TypeAPAIR = 0x0F99
60 -
61 -type APAIR struct {
62 - addr [2]net.IP
63 -}
64 -
65 -func NewAPAIR() dns.PrivateRdata { return new(APAIR) }
66 -
67 -func (rd *APAIR) String() string { return rd.addr[0].String() + " " + rd.addr[1].String() }
68 -func (rd *APAIR) Parse(txt []string) error {
69 - if len(txt) != 2 {
70 - return errors.New("two addresses required for APAIR")
71 - }
72 - for i, s := range txt {
73 - ip := net.ParseIP(s)
74 - if ip == nil {
75 - return errors.New("invalid IP in APAIR text representation")
76 - }
77 - rd.addr[i] = ip
78 - }
79 - return nil
80 -}
81 -
82 -func (rd *APAIR) Pack(buf []byte) (int, error) {
83 - b := append([]byte(rd.addr[0]), []byte(rd.addr[1])...)
84 - n := copy(buf, b)
85 - if n != len(b) {
86 - return n, dns.ErrBuf
87 - }
88 - return n, nil
89 -}
90 -
91 -func (rd *APAIR) Unpack(buf []byte) (int, error) {
92 - ln := net.IPv4len * 2
93 - if len(buf) != ln {
94 - return 0, errors.New("invalid length of APAIR rdata")
95 - }
96 - cp := make([]byte, ln)
97 - copy(cp, buf) // clone bytes to use them in IPs
98 -
99 - rd.addr[0] = net.IP(cp[:3])
100 - rd.addr[1] = net.IP(cp[4:])
101 -
102 - return len(buf), nil
103 -}
104 -
105 -func (rd *APAIR) Copy(dest dns.PrivateRdata) error {
106 - cp := make([]byte, rd.Len())
107 - _, err := rd.Pack(cp)
108 - if err != nil {
109 - return err
110 - }
111 -
112 - d := dest.(*APAIR)
113 - d.addr[0] = net.IP(cp[:3])
114 - d.addr[1] = net.IP(cp[4:])
115 - return nil
116 -}
117 -
118 -func (rd *APAIR) Len() int {
119 - return net.IPv4len * 2
120 -}
121 -
122 -func ExamplePrivateHandle() {
123 - dns.PrivateHandle("APAIR", TypeAPAIR, NewAPAIR)
124 - defer dns.PrivateHandleRemove(TypeAPAIR)
125 -
126 - rr, err := dns.NewRR("miek.nl. APAIR (1.2.3.4 1.2.3.5)")
127 - if err != nil {
128 - log.Fatal("could not parse APAIR record: ", err)
129 - }
130 - fmt.Println(rr)
131 - // Output: miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5
132 -
133 - m := new(dns.Msg)
134 - m.Id = 12345
135 - m.SetQuestion("miek.nl.", TypeAPAIR)
136 - m.Answer = append(m.Answer, rr)
137 -
138 - fmt.Println(m)
139 - // ;; opcode: QUERY, status: NOERROR, id: 12345
140 - // ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
141 - //
142 - // ;; QUESTION SECTION:
143 - // ;miek.nl. IN APAIR
144 - //
145 - // ;; ANSWER SECTION:
146 - // miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5
147 -}
Godeps/_workspace/src/github.com/miekg/dns/format.go deleted
-96
@@ -1,96 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "net"
5 - "reflect"
6 - "strconv"
7 -)
8 -
9 -// NumField returns the number of rdata fields r has.
10 -func NumField(r RR) int {
11 - return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header
12 -}
13 -
14 -// Field returns the rdata field i as a string. Fields are indexed starting from 1.
15 -// RR types that holds slice data, for instance the NSEC type bitmap will return a single
16 -// string where the types are concatenated using a space.
17 -// Accessing non existing fields will cause a panic.
18 -func Field(r RR, i int) string {
19 - if i == 0 {
20 - return ""
21 - }
22 - d := reflect.ValueOf(r).Elem().Field(i)
23 - switch k := d.Kind(); k {
24 - case reflect.String:
25 - return d.String()
26 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
27 - return strconv.FormatInt(d.Int(), 10)
28 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
29 - return strconv.FormatUint(d.Uint(), 10)
30 - case reflect.Slice:
31 - switch reflect.ValueOf(r).Elem().Type().Field(i).Tag {
32 - case `dns:"a"`:
33 - // TODO(miek): Hmm store this as 16 bytes
34 - if d.Len() < net.IPv6len {
35 - return net.IPv4(byte(d.Index(0).Uint()),
36 - byte(d.Index(1).Uint()),
37 - byte(d.Index(2).Uint()),
38 - byte(d.Index(3).Uint())).String()
39 - }
40 - return net.IPv4(byte(d.Index(12).Uint()),
41 - byte(d.Index(13).Uint()),
42 - byte(d.Index(14).Uint()),
43 - byte(d.Index(15).Uint())).String()
44 - case `dns:"aaaa"`:
45 - return net.IP{
46 - byte(d.Index(0).Uint()),
47 - byte(d.Index(1).Uint()),
48 - byte(d.Index(2).Uint()),
49 - byte(d.Index(3).Uint()),
50 - byte(d.Index(4).Uint()),
51 - byte(d.Index(5).Uint()),
52 - byte(d.Index(6).Uint()),
53 - byte(d.Index(7).Uint()),
54 - byte(d.Index(8).Uint()),
55 - byte(d.Index(9).Uint()),
56 - byte(d.Index(10).Uint()),
57 - byte(d.Index(11).Uint()),
58 - byte(d.Index(12).Uint()),
59 - byte(d.Index(13).Uint()),
60 - byte(d.Index(14).Uint()),
61 - byte(d.Index(15).Uint()),
62 - }.String()
63 - case `dns:"nsec"`:
64 - if d.Len() == 0 {
65 - return ""
66 - }
67 - s := Type(d.Index(0).Uint()).String()
68 - for i := 1; i < d.Len(); i++ {
69 - s += " " + Type(d.Index(i).Uint()).String()
70 - }
71 - return s
72 - case `dns:"wks"`:
73 - if d.Len() == 0 {
74 - return ""
75 - }
76 - s := strconv.Itoa(int(d.Index(0).Uint()))
77 - for i := 0; i < d.Len(); i++ {
78 - s += " " + strconv.Itoa(int(d.Index(i).Uint()))
79 - }
80 - return s
81 - default:
82 - // if it does not have a tag its a string slice
83 - fallthrough
84 - case `dns:"txt"`:
85 - if d.Len() == 0 {
86 - return ""
87 - }
88 - s := d.Index(0).String()
89 - for i := 1; i < d.Len(); i++ {
90 - s += " " + d.Index(i).String()
91 - }
92 - return s
93 - }
94 - }
95 - return ""
96 -}
Godeps/_workspace/src/github.com/miekg/dns/idn/example_test.go deleted
-18
@@ -1,18 +0,0 @@
1 -package idn_test
2 -
3 -import (
4 - "fmt"
5 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/miekg/dns/idn"
6 -)
7 -
8 -func ExampleToPunycode() {
9 - name := "インターネット.テスト"
10 - fmt.Printf("%s -> %s", name, idn.ToPunycode(name))
11 - // Output: インターネット.テスト -> xn--eckucmux0ukc.xn--zckzah
12 -}
13 -
14 -func ExampleFromPunycode() {
15 - name := "xn--mgbaja8a1hpac.xn--mgbachtv"
16 - fmt.Printf("%s -> %s", name, idn.FromPunycode(name))
17 - // Output: xn--mgbaja8a1hpac.xn--mgbachtv -> الانترنت.اختبار
18 -}
Godeps/_workspace/src/github.com/miekg/dns/idn/punycode.go deleted
-269
@@ -1,269 +0,0 @@
1 -// Package idn implements encoding from and to punycode as speficied by RFC 3492.
2 -package idn
3 -
4 -import (
5 - "bytes"
6 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/miekg/dns"
7 - "strings"
8 - "unicode"
9 -)
10 -
11 -// Implementation idea from RFC itself and from from IDNA::Punycode created by
12 -// Tatsuhiko Miyagawa <miyagawa@bulknews.net> and released under Perl Artistic
13 -// License in 2002.
14 -
15 -const (
16 - _MIN rune = 1
17 - _MAX rune = 26
18 - _SKEW rune = 38
19 - _BASE rune = 36
20 - _BIAS rune = 72
21 - _N rune = 128
22 - _DAMP rune = 700
23 -
24 - _DELIMITER = '-'
25 - _PREFIX = "xn--"
26 -)
27 -
28 -// ToPunycode converts unicode domain names to DNS-appropriate punycode names.
29 -// This function would return incorrect result for strings for non-canonical
30 -// unicode strings.
31 -func ToPunycode(s string) string {
32 - tokens := dns.SplitDomainName(s)
33 - switch {
34 - case s == "":
35 - return ""
36 - case tokens == nil: // s == .
37 - return "."
38 - case s[len(s)-1] == '.':
39 - tokens = append(tokens, "")
40 - }
41 -
42 - for i := range tokens {
43 - tokens[i] = string(encode([]byte(tokens[i])))
44 - }
45 - return strings.Join(tokens, ".")
46 -}
47 -
48 -// FromPunycode returns unicode domain name from provided punycode string.
49 -func FromPunycode(s string) string {
50 - tokens := dns.SplitDomainName(s)
51 - switch {
52 - case s == "":
53 - return ""
54 - case tokens == nil: // s == .
55 - return "."
56 - case s[len(s)-1] == '.':
57 - tokens = append(tokens, "")
58 - }
59 - for i := range tokens {
60 - tokens[i] = string(decode([]byte(tokens[i])))
61 - }
62 - return strings.Join(tokens, ".")
63 -}
64 -
65 -// digitval converts single byte into meaningful value that's used to calculate decoded unicode character.
66 -const errdigit = 0xffff
67 -
68 -func digitval(code rune) rune {
69 - switch {
70 - case code >= 'A' && code <= 'Z':
71 - return code - 'A'
72 - case code >= 'a' && code <= 'z':
73 - return code - 'a'
74 - case code >= '0' && code <= '9':
75 - return code - '0' + 26
76 - }
77 - return errdigit
78 -}
79 -
80 -// lettercode finds BASE36 byte (a-z0-9) based on calculated number.
81 -func lettercode(digit rune) rune {
82 - switch {
83 - case digit >= 0 && digit <= 25:
84 - return digit + 'a'
85 - case digit >= 26 && digit <= 36:
86 - return digit - 26 + '0'
87 - }
88 - panic("dns: not reached")
89 -}
90 -
91 -// adapt calculates next bias to be used for next iteration delta.
92 -func adapt(delta rune, numpoints int, firsttime bool) rune {
93 - if firsttime {
94 - delta /= _DAMP
95 - } else {
96 - delta /= 2
97 - }
98 -
99 - var k rune
100 - for delta = delta + delta/rune(numpoints); delta > (_BASE-_MIN)*_MAX/2; k += _BASE {
101 - delta /= _BASE - _MIN
102 - }
103 -
104 - return k + ((_BASE-_MIN+1)*delta)/(delta+_SKEW)
105 -}
106 -
107 -// next finds minimal rune (one with lowest codepoint value) that should be equal or above boundary.
108 -func next(b []rune, boundary rune) rune {
109 - if len(b) == 0 {
110 - panic("dns: invalid set of runes to determine next one")
111 - }
112 - m := b[0]
113 - for _, x := range b[1:] {
114 - if x >= boundary && (m < boundary || x < m) {
115 - m = x
116 - }
117 - }
118 - return m
119 -}
120 -
121 -// preprune converts unicode rune to lower case. At this time it's not
122 -// supporting all things described in RFCs
123 -func preprune(r rune) rune {
124 - if unicode.IsUpper(r) {
125 - r = unicode.ToLower(r)
126 - }
127 - return r
128 -}
129 -
130 -// tfunc is a function that helps calculate each character weight
131 -func tfunc(k, bias rune) rune {
132 - switch {
133 - case k <= bias:
134 - return _MIN
135 - case k >= bias+_MAX:
136 - return _MAX
137 - }
138 - return k - bias
139 -}
140 -
141 -// encode transforms Unicode input bytes (that represent DNS label) into punycode bytestream
142 -func encode(input []byte) []byte {
143 - n, bias := _N, _BIAS
144 -
145 - b := bytes.Runes(input)
146 - for i := range b {
147 - b[i] = preprune(b[i])
148 - }
149 -
150 - basic := make([]byte, 0, len(b))
151 - for _, ltr := range b {
152 - if ltr <= 0x7f {
153 - basic = append(basic, byte(ltr))
154 - }
155 - }
156 - basiclen := len(basic)
157 - fulllen := len(b)
158 - if basiclen == fulllen {
159 - return basic
160 - }
161 -
162 - var out bytes.Buffer
163 -
164 - out.WriteString(_PREFIX)
165 - if basiclen > 0 {
166 - out.Write(basic)
167 - out.WriteByte(_DELIMITER)
168 - }
169 -
170 - var (
171 - ltr, nextltr rune
172 - delta, q rune // delta calculation (see rfc)
173 - t, k, cp rune // weight and codepoint calculation
174 - )
175 -
176 - s := &bytes.Buffer{}
177 - for h := basiclen; h < fulllen; n, delta = n+1, delta+1 {
178 - nextltr = next(b, n)
179 - s.Truncate(0)
180 - s.WriteRune(nextltr)
181 - delta, n = delta+(nextltr-n)*rune(h+1), nextltr
182 -
183 - for _, ltr = range b {
184 - if ltr < n {
185 - delta++
186 - }
187 - if ltr == n {
188 - q = delta
189 - for k = _BASE; ; k += _BASE {
190 - t = tfunc(k, bias)
191 - if q < t {
192 - break
193 - }
194 - cp = t + ((q - t) % (_BASE - t))
195 - out.WriteRune(lettercode(cp))
196 - q = (q - t) / (_BASE - t)
197 - }
198 -
199 - out.WriteRune(lettercode(q))
200 -
201 - bias = adapt(delta, h+1, h == basiclen)
202 - h, delta = h+1, 0
203 - }
204 - }
205 - }
206 - return out.Bytes()
207 -}
208 -
209 -// decode transforms punycode input bytes (that represent DNS label) into Unicode bytestream
210 -func decode(b []byte) []byte {
211 - src := b // b would move and we need to keep it
212 -
213 - n, bias := _N, _BIAS
214 - if !bytes.HasPrefix(b, []byte(_PREFIX)) {
215 - return b
216 - }
217 - out := make([]rune, 0, len(b))
218 - b = b[len(_PREFIX):]
219 - for pos := len(b) - 1; pos >= 0; pos-- {
220 - // only last delimiter is our interest
221 - if b[pos] == _DELIMITER {
222 - out = append(out, bytes.Runes(b[:pos])...)
223 - b = b[pos+1:] // trim source string
224 - break
225 - }
226 - }
227 - if len(b) == 0 {
228 - return src
229 - }
230 - var (
231 - i, oldi, w rune
232 - ch byte
233 - t, digit rune
234 - ln int
235 - )
236 -
237 - for i = 0; len(b) > 0; i++ {
238 - oldi, w = i, 1
239 - for k := _BASE; len(b) > 0; k += _BASE {
240 - ch, b = b[0], b[1:]
241 - digit = digitval(rune(ch))
242 - if digit == errdigit {
243 - return src
244 - }
245 - i += digit * w
246 -
247 - t = tfunc(k, bias)
248 - if digit < t {
249 - break
250 - }
251 -
252 - w *= _BASE - t
253 - }
254 - ln = len(out) + 1
255 - bias = adapt(i-oldi, ln, oldi == 0)
256 - n += i / rune(ln)
257 - i = i % rune(ln)
258 - // insert
259 - out = append(out, 0)
260 - copy(out[i+1:], out[i:])
261 - out[i] = n
262 - }
263 -
264 - var ret bytes.Buffer
265 - for _, r := range out {
266 - ret.WriteRune(r)
267 - }
268 - return ret.Bytes()
269 -}
Godeps/_workspace/src/github.com/miekg/dns/idn/punycode_test.go deleted
-97
@@ -1,97 +0,0 @@
1 -package idn
2 -
3 -import (
4 - "strings"
5 - "testing"
6 -)
7 -
8 -var testcases = [][2]string{
9 - {"", ""},
10 - {"a", "a"},
11 - {"A-B", "a-b"},
12 - {"A-B-C", "a-b-c"},
13 - {"AbC", "abc"},
14 - {"я", "xn--41a"},
15 - {"zя", "xn--z-0ub"},
16 - {"ЯZ", "xn--z-zub"},
17 - {"а-я", "xn----7sb8g"},
18 - {"إختبار", "xn--kgbechtv"},
19 - {"آزمایشی", "xn--hgbk6aj7f53bba"},
20 - {"测试", "xn--0zwm56d"},
21 - {"測試", "xn--g6w251d"},
22 - {"Испытание", "xn--80akhbyknj4f"},
23 - {"परीक्षा", "xn--11b5bs3a9aj6g"},
24 - {"δοκιμή", "xn--jxalpdlp"},
25 - {"테스트", "xn--9t4b11yi5a"},
26 - {"טעסט", "xn--deba0ad"},
27 - {"テスト", "xn--zckzah"},
28 - {"பரிட்சை", "xn--hlcj6aya9esc7a"},
29 - {"mamão-com-açúcar", "xn--mamo-com-acar-yeb1e6q"},
30 -}
31 -
32 -func TestEncodeDecodePunycode(t *testing.T) {
33 - for _, tst := range testcases {
34 - enc := encode([]byte(tst[0]))
35 - if string(enc) != tst[1] {
36 - t.Errorf("%s encodeded as %s but should be %s", tst[0], enc, tst[1])
37 - }
38 - dec := decode([]byte(tst[1]))
39 - if string(dec) != strings.ToLower(tst[0]) {
40 - t.Errorf("%s decoded as %s but should be %s", tst[1], dec, strings.ToLower(tst[0]))
41 - }
42 - }
43 -}
44 -
45 -func TestToFromPunycode(t *testing.T) {
46 - for _, tst := range testcases {
47 - // assert unicode.com == punycode.com
48 - full := ToPunycode(tst[0] + ".com")
49 - if full != tst[1]+".com" {
50 - t.Errorf("invalid result from string conversion to punycode, %s and should be %s.com", full, tst[1])
51 - }
52 - // assert punycode.punycode == unicode.unicode
53 - decoded := FromPunycode(tst[1] + "." + tst[1])
54 - if decoded != strings.ToLower(tst[0]+"."+tst[0]) {
55 - t.Errorf("invalid result from string conversion to punycode, %s and should be %s.%s", decoded, tst[0], tst[0])
56 - }
57 - }
58 -}
59 -
60 -func TestEncodeDecodeFinalPeriod(t *testing.T) {
61 - for _, tst := range testcases {
62 - // assert unicode.com. == punycode.com.
63 - full := ToPunycode(tst[0] + ".")
64 - if full != tst[1]+"." {
65 - t.Errorf("invalid result from string conversion to punycode when period added at the end, %#v and should be %#v", full, tst[1]+".")
66 - }
67 - // assert punycode.com. == unicode.com.
68 - decoded := FromPunycode(tst[1] + ".")
69 - if decoded != strings.ToLower(tst[0]+".") {
70 - t.Errorf("invalid result from string conversion to punycode when period added, %#v and should be %#v", decoded, tst[0]+".")
71 - }
72 - full = ToPunycode(tst[0])
73 - if full != tst[1] {
74 - t.Errorf("invalid result from string conversion to punycode when no period added at the end, %#v and should be %#v", full, tst[1]+".")
75 - }
76 - // assert punycode.com. == unicode.com.
77 - decoded = FromPunycode(tst[1])
78 - if decoded != strings.ToLower(tst[0]) {
79 - t.Errorf("invalid result from string conversion to punycode when no period added, %#v and should be %#v", decoded, tst[0]+".")
80 - }
81 - }
82 -}
83 -
84 -var invalid = []string{
85 - "xn--*",
86 - "xn--",
87 - "xn---",
88 -}
89 -
90 -func TestInvalidPunycode(t *testing.T) {
91 - for _, d := range invalid {
92 - s := FromPunycode(d)
93 - if s != d {
94 - t.Errorf("Changed invalid name %s to %#v", d, s)
95 - }
96 - }
97 -}
Godeps/_workspace/src/github.com/miekg/dns/labels.go deleted
-162
@@ -1,162 +0,0 @@
1 -package dns
2 -
3 -// Holds a bunch of helper functions for dealing with labels.
4 -
5 -// SplitDomainName splits a name string into it's labels.
6 -// www.miek.nl. returns []string{"www", "miek", "nl"}
7 -// The root label (.) returns nil. Note that using
8 -// strings.Split(s) will work in most cases, but does not handle
9 -// escaped dots (\.) for instance.
10 -func SplitDomainName(s string) (labels []string) {
11 - if len(s) == 0 {
12 - return nil
13 - }
14 - fqdnEnd := 0 // offset of the final '.' or the length of the name
15 - idx := Split(s)
16 - begin := 0
17 - if s[len(s)-1] == '.' {
18 - fqdnEnd = len(s) - 1
19 - } else {
20 - fqdnEnd = len(s)
21 - }
22 -
23 - switch len(idx) {
24 - case 0:
25 - return nil
26 - case 1:
27 - // no-op
28 - default:
29 - end := 0
30 - for i := 1; i < len(idx); i++ {
31 - end = idx[i]
32 - labels = append(labels, s[begin:end-1])
33 - begin = end
34 - }
35 - }
36 -
37 - labels = append(labels, s[begin:fqdnEnd])
38 - return labels
39 -}
40 -
41 -// CompareDomainName compares the names s1 and s2 and
42 -// returns how many labels they have in common starting from the *right*.
43 -// The comparison stops at the first inequality. The names are not downcased
44 -// before the comparison.
45 -//
46 -// www.miek.nl. and miek.nl. have two labels in common: miek and nl
47 -// www.miek.nl. and www.bla.nl. have one label in common: nl
48 -func CompareDomainName(s1, s2 string) (n int) {
49 - s1 = Fqdn(s1)
50 - s2 = Fqdn(s2)
51 - l1 := Split(s1)
52 - l2 := Split(s2)
53 -
54 - // the first check: root label
55 - if l1 == nil || l2 == nil {
56 - return
57 - }
58 -
59 - j1 := len(l1) - 1 // end
60 - i1 := len(l1) - 2 // start
61 - j2 := len(l2) - 1
62 - i2 := len(l2) - 2
63 - // the second check can be done here: last/only label
64 - // before we fall through into the for-loop below
65 - if s1[l1[j1]:] == s2[l2[j2]:] {
66 - n++
67 - } else {
68 - return
69 - }
70 - for {
71 - if i1 < 0 || i2 < 0 {
72 - break
73 - }
74 - if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] {
75 - n++
76 - } else {
77 - break
78 - }
79 - j1--
80 - i1--
81 - j2--
82 - i2--
83 - }
84 - return
85 -}
86 -
87 -// CountLabel counts the the number of labels in the string s.
88 -func CountLabel(s string) (labels int) {
89 - if s == "." {
90 - return
91 - }
92 - off := 0
93 - end := false
94 - for {
95 - off, end = NextLabel(s, off)
96 - labels++
97 - if end {
98 - return
99 - }
100 - }
101 - panic("dns: not reached")
102 -}
103 -
104 -// Split splits a name s into its label indexes.
105 -// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}.
106 -// The root name (.) returns nil. Also see dns.SplitDomainName.
107 -func Split(s string) []int {
108 - if s == "." {
109 - return nil
110 - }
111 - idx := make([]int, 1, 3)
112 - off := 0
113 - end := false
114 -
115 - for {
116 - off, end = NextLabel(s, off)
117 - if end {
118 - return idx
119 - }
120 - idx = append(idx, off)
121 - }
122 - panic("dns: not reached")
123 -}
124 -
125 -// NextLabel returns the index of the start of the next label in the
126 -// string s starting at offset.
127 -// The bool end is true when the end of the string has been reached.
128 -func NextLabel(s string, offset int) (i int, end bool) {
129 - quote := false
130 - for i = offset; i < len(s)-1; i++ {
131 - switch s[i] {
132 - case '\\':
133 - quote = !quote
134 - default:
135 - quote = false
136 - case '.':
137 - if quote {
138 - quote = !quote
139 - continue
140 - }
141 - return i + 1, false
142 - }
143 - }
144 - return i + 1, true
145 -}
146 -
147 -// PrevLabel returns the index of the label when starting from the right and
148 -// jumping n labels to the left.
149 -// The bool start is true when the start of the string has been overshot.
150 -func PrevLabel(s string, n int) (i int, start bool) {
151 - if n == 0 {
152 - return len(s), false
153 - }
154 - lab := Split(s)
155 - if lab == nil {
156 - return 0, true
157 - }
158 - if n > len(lab) {
159 - return 0, true
160 - }
161 - return lab[len(lab)-n], false
162 -}
Godeps/_workspace/src/github.com/miekg/dns/labels_test.go deleted
-199
@@ -1,199 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "testing"
5 -)
6 -
7 -func TestCompareDomainName(t *testing.T) {
8 - s1 := "www.miek.nl."
9 - s2 := "miek.nl."
10 - s3 := "www.bla.nl."
11 - s4 := "nl.www.bla."
12 - s5 := "nl"
13 - s6 := "miek.nl"
14 -
15 - if CompareDomainName(s1, s2) != 2 {
16 - t.Errorf("%s with %s should be %d", s1, s2, 2)
17 - }
18 - if CompareDomainName(s1, s3) != 1 {
19 - t.Errorf("%s with %s should be %d", s1, s3, 1)
20 - }
21 - if CompareDomainName(s3, s4) != 0 {
22 - t.Errorf("%s with %s should be %d", s3, s4, 0)
23 - }
24 - // Non qualified tests
25 - if CompareDomainName(s1, s5) != 1 {
26 - t.Errorf("%s with %s should be %d", s1, s5, 1)
27 - }
28 - if CompareDomainName(s1, s6) != 2 {
29 - t.Errorf("%s with %s should be %d", s1, s5, 2)
30 - }
31 -
32 - if CompareDomainName(s1, ".") != 0 {
33 - t.Errorf("%s with %s should be %d", s1, s5, 0)
34 - }
35 - if CompareDomainName(".", ".") != 0 {
36 - t.Errorf("%s with %s should be %d", ".", ".", 0)
37 - }
38 -}
39 -
40 -func TestSplit(t *testing.T) {
41 - splitter := map[string]int{
42 - "www.miek.nl.": 3,
43 - "www.miek.nl": 3,
44 - "www..miek.nl": 4,
45 - `www\.miek.nl.`: 2,
46 - `www\\.miek.nl.`: 3,
47 - ".": 0,
48 - "nl.": 1,
49 - "nl": 1,
50 - "com.": 1,
51 - ".com.": 2,
52 - }
53 - for s, i := range splitter {
54 - if x := len(Split(s)); x != i {
55 - t.Errorf("labels should be %d, got %d: %s %v", i, x, s, Split(s))
56 - } else {
57 - t.Logf("%s %v", s, Split(s))
58 - }
59 - }
60 -}
61 -
62 -func TestSplit2(t *testing.T) {
63 - splitter := map[string][]int{
64 - "www.miek.nl.": []int{0, 4, 9},
65 - "www.miek.nl": []int{0, 4, 9},
66 - "nl": []int{0},
67 - }
68 - for s, i := range splitter {
69 - x := Split(s)
70 - switch len(i) {
71 - case 1:
72 - if x[0] != i[0] {
73 - t.Errorf("labels should be %v, got %v: %s", i, x, s)
74 - }
75 - default:
76 - if x[0] != i[0] || x[1] != i[1] || x[2] != i[2] {
77 - t.Errorf("labels should be %v, got %v: %s", i, x, s)
78 - }
79 - }
80 - }
81 -}
82 -
83 -func TestPrevLabel(t *testing.T) {
84 - type prev struct {
85 - string
86 - int
87 - }
88 - prever := map[prev]int{
89 - prev{"www.miek.nl.", 0}: 12,
90 - prev{"www.miek.nl.", 1}: 9,
91 - prev{"www.miek.nl.", 2}: 4,
92 -
93 - prev{"www.miek.nl", 0}: 11,
94 - prev{"www.miek.nl", 1}: 9,
95 - prev{"www.miek.nl", 2}: 4,
96 -
97 - prev{"www.miek.nl.", 5}: 0,
98 - prev{"www.miek.nl", 5}: 0,
99 -
100 - prev{"www.miek.nl.", 3}: 0,
101 - prev{"www.miek.nl", 3}: 0,
102 - }
103 - for s, i := range prever {
104 - x, ok := PrevLabel(s.string, s.int)
105 - if i != x {
106 - t.Errorf("label should be %d, got %d, %t: preving %d, %s", i, x, ok, s.int, s.string)
107 - }
108 - }
109 -}
110 -
111 -func TestCountLabel(t *testing.T) {
112 - splitter := map[string]int{
113 - "www.miek.nl.": 3,
114 - "www.miek.nl": 3,
115 - "nl": 1,
116 - ".": 0,
117 - }
118 - for s, i := range splitter {
119 - x := CountLabel(s)
120 - if x != i {
121 - t.Errorf("CountLabel should have %d, got %d", i, x)
122 - }
123 - }
124 -}
125 -
126 -func TestSplitDomainName(t *testing.T) {
127 - labels := map[string][]string{
128 - "miek.nl": []string{"miek", "nl"},
129 - ".": nil,
130 - "www.miek.nl.": []string{"www", "miek", "nl"},
131 - "www.miek.nl": []string{"www", "miek", "nl"},
132 - "www..miek.nl": []string{"www", "", "miek", "nl"},
133 - `www\.miek.nl`: []string{`www\.miek`, "nl"},
134 - `www\\.miek.nl`: []string{`www\\`, "miek", "nl"},
135 - }
136 -domainLoop:
137 - for domain, splits := range labels {
138 - parts := SplitDomainName(domain)
139 - if len(parts) != len(splits) {
140 - t.Errorf("SplitDomainName returned %v for %s, expected %v", parts, domain, splits)
141 - continue domainLoop
142 - }
143 - for i := range parts {
144 - if parts[i] != splits[i] {
145 - t.Errorf("SplitDomainName returned %v for %s, expected %v", parts, domain, splits)
146 - continue domainLoop
147 - }
148 - }
149 - }
150 -}
151 -
152 -func TestIsDomainName(t *testing.T) {
153 - type ret struct {
154 - ok bool
155 - lab int
156 - }
157 - names := map[string]*ret{
158 - "..": &ret{false, 1},
159 - "@.": &ret{true, 1},
160 - "www.example.com": &ret{true, 3},
161 - "www.e%ample.com": &ret{true, 3},
162 - "www.example.com.": &ret{true, 3},
163 - "mi\\k.nl.": &ret{true, 2},
164 - "mi\\k.nl": &ret{true, 2},
165 - }
166 - for d, ok := range names {
167 - l, k := IsDomainName(d)
168 - if ok.ok != k || ok.lab != l {
169 - t.Errorf(" got %v %d for %s ", k, l, d)
170 - t.Errorf("have %v %d for %s ", ok.ok, ok.lab, d)
171 - }
172 - }
173 -}
174 -
175 -func BenchmarkSplitLabels(b *testing.B) {
176 - for i := 0; i < b.N; i++ {
177 - Split("www.example.com")
178 - }
179 -}
180 -
181 -func BenchmarkLenLabels(b *testing.B) {
182 - for i := 0; i < b.N; i++ {
183 - CountLabel("www.example.com")
184 - }
185 -}
186 -
187 -func BenchmarkCompareLabels(b *testing.B) {
188 - for i := 0; i < b.N; i++ {
189 - CompareDomainName("www.example.com", "aa.example.com")
190 - }
191 -}
192 -
193 -func BenchmarkIsSubDomain(b *testing.B) {
194 - for i := 0; i < b.N; i++ {
195 - IsSubDomain("www.example.com", "aa.example.com")
196 - IsSubDomain("example.com", "aa.example.com")
197 - IsSubDomain("miek.nl", "aa.example.com")
198 - }
199 -}
Godeps/_workspace/src/github.com/miekg/dns/msg.go deleted
-1967
@@ -1,1967 +0,0 @@
1 -// DNS packet assembly, see RFC 1035. Converting from - Unpack() -
2 -// and to - Pack() - wire format.
3 -// All the packers and unpackers take a (msg []byte, off int)
4 -// and return (off1 int, ok bool). If they return ok==false, they
5 -// also return off1==len(msg), so that the next unpacker will
6 -// also fail. This lets us avoid checks of ok until the end of a
7 -// packing sequence.
8 -
9 -package dns
10 -
11 -import (
12 - "encoding/base32"
13 - "encoding/base64"
14 - "encoding/hex"
15 - "math/big"
16 - "math/rand"
17 - "net"
18 - "reflect"
19 - "strconv"
20 - "time"
21 -)
22 -
23 -const maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
24 -
25 -var (
26 - // ErrAlg indicates an error with the (DNSSEC) algorithm.
27 - ErrAlg error = &Error{err: "bad algorithm"}
28 - // ErrAuth indicates an error in the TSIG authentication.
29 - ErrAuth error = &Error{err: "bad authentication"}
30 - // ErrBuf indicates that the buffer used it too small for the message.
31 - ErrBuf error = &Error{err: "buffer size too small"}
32 - // ErrConn indicates that a connection has both a TCP and UDP socket.
33 - ErrConn error = &Error{err: "conn holds both UDP and TCP connection"}
34 - // ErrConnEmpty indicates a connection is being uses before it is initialized.
35 - ErrConnEmpty error = &Error{err: "conn has no connection"}
36 - // ErrExtendedRcode ...
37 - ErrExtendedRcode error = &Error{err: "bad extended rcode"}
38 - // ErrFqdn indicates that a domain name does not have a closing dot.
39 - ErrFqdn error = &Error{err: "domain must be fully qualified"}
40 - // ErrId indicates there is a mismatch with the message's ID.
41 - ErrId error = &Error{err: "id mismatch"}
42 - ErrKeyAlg error = &Error{err: "bad key algorithm"}
43 - ErrKey error = &Error{err: "bad key"}
44 - ErrKeySize error = &Error{err: "bad key size"}
45 - ErrNoSig error = &Error{err: "no signature found"}
46 - ErrPrivKey error = &Error{err: "bad private key"}
47 - ErrRcode error = &Error{err: "bad rcode"}
48 - ErrRdata error = &Error{err: "bad rdata"}
49 - ErrRRset error = &Error{err: "bad rrset"}
50 - ErrSecret error = &Error{err: "no secrets defined"}
51 - ErrShortRead error = &Error{err: "short read"}
52 - // ErrSig indicates that a signature can not be cryptographically validated.
53 - ErrSig error = &Error{err: "bad signature"}
54 - // ErrSigGen indicates a faulure to generate a signature.
55 - ErrSigGen error = &Error{err: "bad signature generation"}
56 - // ErrSOA indicates that no SOA RR was seen when doing zone transfers.
57 - ErrSoa error = &Error{err: "no SOA"}
58 - // ErrTime indicates a timing error in TSIG authentication.
59 - ErrTime error = &Error{err: "bad time"}
60 -)
61 -
62 -// Id, by default, returns a 16 bits random number to be used as a
63 -// message id. The random provided should be good enough. This being a
64 -// variable the function can be reassigned to a custom function.
65 -// For instance, to make it return a static value:
66 -//
67 -// dns.Id = func() uint16 { return 3 }
68 -var Id func() uint16 = id
69 -
70 -// MsgHdr is a a manually-unpacked version of (id, bits).
71 -type MsgHdr struct {
72 - Id uint16
73 - Response bool
74 - Opcode int
75 - Authoritative bool
76 - Truncated bool
77 - RecursionDesired bool
78 - RecursionAvailable bool
79 - Zero bool
80 - AuthenticatedData bool
81 - CheckingDisabled bool
82 - Rcode int
83 -}
84 -
85 -// Msg contains the layout of a DNS message.
86 -type Msg struct {
87 - MsgHdr
88 - Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format. This not part of the official DNS packet format.
89 - Question []Question // Holds the RR(s) of the question section.
90 - Answer []RR // Holds the RR(s) of the answer section.
91 - Ns []RR // Holds the RR(s) of the authority section.
92 - Extra []RR // Holds the RR(s) of the additional section.
93 -}
94 -
95 -// TypeToString is a map of strings for each RR wire type.
96 -var TypeToString = map[uint16]string{
97 - TypeA: "A",
98 - TypeAAAA: "AAAA",
99 - TypeAFSDB: "AFSDB",
100 - TypeANY: "ANY", // Meta RR
101 - TypeATMA: "ATMA",
102 - TypeAXFR: "AXFR", // Meta RR
103 - TypeCAA: "CAA",
104 - TypeCDNSKEY: "CDNSKEY",
105 - TypeCDS: "CDS",
106 - TypeCERT: "CERT",
107 - TypeCNAME: "CNAME",
108 - TypeDHCID: "DHCID",
109 - TypeDLV: "DLV",
110 - TypeDNAME: "DNAME",
111 - TypeDNSKEY: "DNSKEY",
112 - TypeDS: "DS",
113 - TypeEID: "EID",
114 - TypeEUI48: "EUI48",
115 - TypeEUI64: "EUI64",
116 - TypeGID: "GID",
117 - TypeGPOS: "GPOS",
118 - TypeHINFO: "HINFO",
119 - TypeHIP: "HIP",
120 - TypeIPSECKEY: "IPSECKEY",
121 - TypeISDN: "ISDN",
122 - TypeIXFR: "IXFR", // Meta RR
123 - TypeKEY: "KEY",
124 - TypeKX: "KX",
125 - TypeL32: "L32",
126 - TypeL64: "L64",
127 - TypeLOC: "LOC",
128 - TypeLP: "LP",
129 - TypeMB: "MB",
130 - TypeMD: "MD",
131 - TypeMF: "MF",
132 - TypeMG: "MG",
133 - TypeMINFO: "MINFO",
134 - TypeMR: "MR",
135 - TypeMX: "MX",
136 - TypeNAPTR: "NAPTR",
137 - TypeNID: "NID",
138 - TypeNINFO: "NINFO",
139 - TypeNIMLOC: "NIMLOC",
140 - TypeNS: "NS",
141 - TypeNSAP: "NSAP",
142 - TypeNSAPPTR: "NSAP-PTR",
143 - TypeNSEC3: "NSEC3",
144 - TypeNSEC3PARAM: "NSEC3PARAM",
145 - TypeNSEC: "NSEC",
146 - TypeNULL: "NULL",
147 - TypeOPT: "OPT",
148 - TypeOPENPGPKEY: "OPENPGPKEY",
149 - TypePTR: "PTR",
150 - TypeRKEY: "RKEY",
151 - TypeRP: "RP",
152 - TypeRRSIG: "RRSIG",
153 - TypeRT: "RT",
154 - TypeSIG: "SIG",
155 - TypeSOA: "SOA",
156 - TypeSPF: "SPF",
157 - TypeSRV: "SRV",
158 - TypeSSHFP: "SSHFP",
159 - TypeTA: "TA",
160 - TypeTALINK: "TALINK",
161 - TypeTKEY: "TKEY", // Meta RR
162 - TypeTLSA: "TLSA",
163 - TypeTSIG: "TSIG", // Meta RR
164 - TypeTXT: "TXT",
165 - TypePX: "PX",
166 - TypeUID: "UID",
167 - TypeUINFO: "UINFO",
168 - TypeUNSPEC: "UNSPEC",
169 - TypeURI: "URI",
170 - TypeWKS: "WKS",
171 - TypeX25: "X25",
172 -}
173 -
174 -// StringToType is the reverse of TypeToString, needed for string parsing.
175 -var StringToType = reverseInt16(TypeToString)
176 -
177 -// StringToClass is the reverse of ClassToString, needed for string parsing.
178 -var StringToClass = reverseInt16(ClassToString)
179 -
180 -// Map of opcodes strings.
181 -var StringToOpcode = reverseInt(OpcodeToString)
182 -
183 -// Map of rcodes strings.
184 -var StringToRcode = reverseInt(RcodeToString)
185 -
186 -// ClassToString is a maps Classes to strings for each CLASS wire type.
187 -var ClassToString = map[uint16]string{
188 - ClassINET: "IN",
189 - ClassCSNET: "CS",
190 - ClassCHAOS: "CH",
191 - ClassHESIOD: "HS",
192 - ClassNONE: "NONE",
193 - ClassANY: "ANY",
194 -}
195 -
196 -// OpcodeToString maps Opcodes to strings.
197 -var OpcodeToString = map[int]string{
198 - OpcodeQuery: "QUERY",
199 - OpcodeIQuery: "IQUERY",
200 - OpcodeStatus: "STATUS",
201 - OpcodeNotify: "NOTIFY",
202 - OpcodeUpdate: "UPDATE",
203 -}
204 -
205 -// RcodeToString maps Rcodes to strings.
206 -var RcodeToString = map[int]string{
207 - RcodeSuccess: "NOERROR",
208 - RcodeFormatError: "FORMERR",
209 - RcodeServerFailure: "SERVFAIL",
210 - RcodeNameError: "NXDOMAIN",
211 - RcodeNotImplemented: "NOTIMPL",
212 - RcodeRefused: "REFUSED",
213 - RcodeYXDomain: "YXDOMAIN", // From RFC 2136
214 - RcodeYXRrset: "YXRRSET",
215 - RcodeNXRrset: "NXRRSET",
216 - RcodeNotAuth: "NOTAUTH",
217 - RcodeNotZone: "NOTZONE",
218 - RcodeBadSig: "BADSIG", // Also known as RcodeBadVers, see RFC 6891
219 - // RcodeBadVers: "BADVERS",
220 - RcodeBadKey: "BADKEY",
221 - RcodeBadTime: "BADTIME",
222 - RcodeBadMode: "BADMODE",
223 - RcodeBadName: "BADNAME",
224 - RcodeBadAlg: "BADALG",
225 - RcodeBadTrunc: "BADTRUNC",
226 -}
227 -
228 -// Rather than write the usual handful of routines to pack and
229 -// unpack every message that can appear on the wire, we use
230 -// reflection to write a generic pack/unpack for structs and then
231 -// use it. Thus, if in the future we need to define new message
232 -// structs, no new pack/unpack/printing code needs to be written.
233 -
234 -// Domain names are a sequence of counted strings
235 -// split at the dots. They end with a zero-length string.
236 -
237 -// PackDomainName packs a domain name s into msg[off:].
238 -// If compression is wanted compress must be true and the compression
239 -// map needs to hold a mapping between domain names and offsets
240 -// pointing into msg[].
241 -func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
242 - off1, _, err = packDomainName(s, msg, off, compression, compress)
243 - return
244 -}
245 -
246 -func packDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, labels int, err error) {
247 - // special case if msg == nil
248 - lenmsg := 256
249 - if msg != nil {
250 - lenmsg = len(msg)
251 - }
252 - ls := len(s)
253 - if ls == 0 { // Ok, for instance when dealing with update RR without any rdata.
254 - return off, 0, nil
255 - }
256 - // If not fully qualified, error out, but only if msg == nil #ugly
257 - switch {
258 - case msg == nil:
259 - if s[ls-1] != '.' {
260 - s += "."
261 - ls++
262 - }
263 - case msg != nil:
264 - if s[ls-1] != '.' {
265 - return lenmsg, 0, ErrFqdn
266 - }
267 - }
268 - // Each dot ends a segment of the name.
269 - // We trade each dot byte for a length byte.
270 - // Except for escaped dots (\.), which are normal dots.
271 - // There is also a trailing zero.
272 -
273 - // Compression
274 - nameoffset := -1
275 - pointer := -1
276 - // Emit sequence of counted strings, chopping at dots.
277 - begin := 0
278 - bs := []byte(s)
279 - roBs, bsFresh, escapedDot := s, true, false
280 - for i := 0; i < ls; i++ {
281 - if bs[i] == '\\' {
282 - for j := i; j < ls-1; j++ {
283 - bs[j] = bs[j+1]
284 - }
285 - ls--
286 - if off+1 > lenmsg {
287 - return lenmsg, labels, ErrBuf
288 - }
289 - // check for \DDD
290 - if i+2 < ls && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
291 - bs[i] = dddToByte(bs[i:])
292 - for j := i + 1; j < ls-2; j++ {
293 - bs[j] = bs[j+2]
294 - }
295 - ls -= 2
296 - } else if bs[i] == 't' {
297 - bs[i] = '\t'
298 - } else if bs[i] == 'r' {
299 - bs[i] = '\r'
300 - } else if bs[i] == 'n' {
301 - bs[i] = '\n'
302 - }
303 - escapedDot = bs[i] == '.'
304 - bsFresh = false
305 - continue
306 - }
307 -
308 - if bs[i] == '.' {
309 - if i > 0 && bs[i-1] == '.' && !escapedDot {
310 - // two dots back to back is not legal
311 - return lenmsg, labels, ErrRdata
312 - }
313 - if i-begin >= 1<<6 { // top two bits of length must be clear
314 - return lenmsg, labels, ErrRdata
315 - }
316 - // off can already (we're in a loop) be bigger than len(msg)
317 - // this happens when a name isn't fully qualified
318 - if off+1 > lenmsg {
319 - return lenmsg, labels, ErrBuf
320 - }
321 - if msg != nil {
322 - msg[off] = byte(i - begin)
323 - }
324 - offset := off
325 - off++
326 - for j := begin; j < i; j++ {
327 - if off+1 > lenmsg {
328 - return lenmsg, labels, ErrBuf
329 - }
330 - if msg != nil {
331 - msg[off] = bs[j]
332 - }
333 - off++
334 - }
335 - if compress && !bsFresh {
336 - roBs = string(bs)
337 - bsFresh = true
338 - }
339 - // Dont try to compress '.'
340 - if compress && roBs[begin:] != "." {
341 - if p, ok := compression[roBs[begin:]]; !ok {
342 - // Only offsets smaller than this can be used.
343 - if offset < maxCompressionOffset {
344 - compression[roBs[begin:]] = offset
345 - }
346 - } else {
347 - // The first hit is the longest matching dname
348 - // keep the pointer offset we get back and store
349 - // the offset of the current name, because that's
350 - // where we need to insert the pointer later
351 -
352 - // If compress is true, we're allowed to compress this dname
353 - if pointer == -1 && compress {
354 - pointer = p // Where to point to
355 - nameoffset = offset // Where to point from
356 - break
357 - }
358 - }
359 - }
360 - labels++
361 - begin = i + 1
362 - }
363 - escapedDot = false
364 - }
365 - // Root label is special
366 - if len(bs) == 1 && bs[0] == '.' {
367 - return off, labels, nil
368 - }
369 - // If we did compression and we find something add the pointer here
370 - if pointer != -1 {
371 - // We have two bytes (14 bits) to put the pointer in
372 - // if msg == nil, we will never do compression
373 - msg[nameoffset], msg[nameoffset+1] = packUint16(uint16(pointer ^ 0xC000))
374 - off = nameoffset + 1
375 - goto End
376 - }
377 - if msg != nil {
378 - msg[off] = 0
379 - }
380 -End:
381 - off++
382 - return off, labels, nil
383 -}
384 -
385 -// Unpack a domain name.
386 -// In addition to the simple sequences of counted strings above,
387 -// domain names are allowed to refer to strings elsewhere in the
388 -// packet, to avoid repeating common suffixes when returning
389 -// many entries in a single domain. The pointers are marked
390 -// by a length byte with the top two bits set. Ignoring those
391 -// two bits, that byte and the next give a 14 bit offset from msg[0]
392 -// where we should pick up the trail.
393 -// Note that if we jump elsewhere in the packet,
394 -// we return off1 == the offset after the first pointer we found,
395 -// which is where the next record will start.
396 -// In theory, the pointers are only allowed to jump backward.
397 -// We let them jump anywhere and stop jumping after a while.
398 -
399 -// UnpackDomainName unpacks a domain name into a string.
400 -func UnpackDomainName(msg []byte, off int) (string, int, error) {
401 - s := make([]byte, 0, 64)
402 - off1 := 0
403 - lenmsg := len(msg)
404 - ptr := 0 // number of pointers followed
405 -Loop:
406 - for {
407 - if off >= lenmsg {
408 - return "", lenmsg, ErrBuf
409 - }
410 - c := int(msg[off])
411 - off++
412 - switch c & 0xC0 {
413 - case 0x00:
414 - if c == 0x00 {
415 - // end of name
416 - if len(s) == 0 {
417 - return ".", off, nil
418 - }
419 - break Loop
420 - }
421 - // literal string
422 - if off+c > lenmsg {
423 - return "", lenmsg, ErrBuf
424 - }
425 - for j := off; j < off+c; j++ {
426 - switch b := msg[j]; b {
427 - case '.', '(', ')', ';', ' ', '@':
428 - fallthrough
429 - case '"', '\\':
430 - s = append(s, '\\', b)
431 - case '\t':
432 - s = append(s, '\\', 't')
433 - case '\r':
434 - s = append(s, '\\', 'r')
435 - default:
436 - if b < 32 || b >= 127 { // unprintable use \DDD
437 - var buf [3]byte
438 - bufs := strconv.AppendInt(buf[:0], int64(b), 10)
439 - s = append(s, '\\')
440 - for i := 0; i < 3-len(bufs); i++ {
441 - s = append(s, '0')
442 - }
443 - for _, r := range bufs {
444 - s = append(s, r)
445 - }
446 - } else {
447 - s = append(s, b)
448 - }
449 - }
450 - }
451 - s = append(s, '.')
452 - off += c
453 - case 0xC0:
454 - // pointer to somewhere else in msg.
455 - // remember location after first ptr,
456 - // since that's how many bytes we consumed.
457 - // also, don't follow too many pointers --
458 - // maybe there's a loop.
459 - if off >= lenmsg {
460 - return "", lenmsg, ErrBuf
461 - }
462 - c1 := msg[off]
463 - off++
464 - if ptr == 0 {
465 - off1 = off
466 - }
467 - if ptr++; ptr > 10 {
468 - return "", lenmsg, &Error{err: "too many compression pointers"}
469 - }
470 - off = (c^0xC0)<<8 | int(c1)
471 - default:
472 - // 0x80 and 0x40 are reserved
473 - return "", lenmsg, ErrRdata
474 - }
475 - }
476 - if ptr == 0 {
477 - off1 = off
478 - }
479 - return string(s), off1, nil
480 -}
481 -
482 -func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) {
483 - var err error
484 - if len(txt) == 0 {
485 - if offset >= len(msg) {
486 - return offset, ErrBuf
487 - }
488 - msg[offset] = 0
489 - return offset, nil
490 - }
491 - for i := range txt {
492 - if len(txt[i]) > len(tmp) {
493 - return offset, ErrBuf
494 - }
495 - offset, err = packTxtString(txt[i], msg, offset, tmp)
496 - if err != nil {
497 - return offset, err
498 - }
499 - }
500 - return offset, err
501 -}
502 -
503 -func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) {
504 - lenByteOffset := offset
505 - if offset >= len(msg) {
506 - return offset, ErrBuf
507 - }
508 - offset++
509 - bs := tmp[:len(s)]
510 - copy(bs, s)
511 - for i := 0; i < len(bs); i++ {
512 - if len(msg) <= offset {
513 - return offset, ErrBuf
514 - }
515 - if bs[i] == '\\' {
516 - i++
517 - if i == len(bs) {
518 - break
519 - }
520 - // check for \DDD
521 - if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
522 - msg[offset] = dddToByte(bs[i:])
523 - i += 2
524 - } else if bs[i] == 't' {
525 - msg[offset] = '\t'
526 - } else if bs[i] == 'r' {
527 - msg[offset] = '\r'
528 - } else if bs[i] == 'n' {
529 - msg[offset] = '\n'
530 - } else {
531 - msg[offset] = bs[i]
532 - }
533 - } else {
534 - msg[offset] = bs[i]
535 - }
536 - offset++
537 - }
538 - l := offset - lenByteOffset - 1
539 - if l > 255 {
540 - return offset, &Error{err: "string exceeded 255 bytes in txt"}
541 - }
542 - msg[lenByteOffset] = byte(l)
543 - return offset, nil
544 -}
545 -
546 -func unpackTxt(msg []byte, offset, rdend int) ([]string, int, error) {
547 - var err error
548 - var ss []string
549 - var s string
550 - for offset < rdend && err == nil {
551 - s, offset, err = unpackTxtString(msg, offset)
552 - if err == nil {
553 - ss = append(ss, s)
554 - }
555 - }
556 - return ss, offset, err
557 -}
558 -
559 -func unpackTxtString(msg []byte, offset int) (string, int, error) {
560 - if offset+1 > len(msg) {
561 - return "", offset, &Error{err: "overflow unpacking txt"}
562 - }
563 - l := int(msg[offset])
564 - if offset+l+1 > len(msg) {
565 - return "", offset, &Error{err: "overflow unpacking txt"}
566 - }
567 - s := make([]byte, 0, l)
568 - for _, b := range msg[offset+1 : offset+1+l] {
569 - switch b {
570 - case '"', '\\':
571 - s = append(s, '\\', b)
572 - case '\t':
573 - s = append(s, `\t`...)
574 - case '\r':
575 - s = append(s, `\r`...)
576 - case '\n':
577 - s = append(s, `\n`...)
578 - default:
579 - if b < 32 || b > 127 { // unprintable
580 - var buf [3]byte
581 - bufs := strconv.AppendInt(buf[:0], int64(b), 10)
582 - s = append(s, '\\')
583 - for i := 0; i < 3-len(bufs); i++ {
584 - s = append(s, '0')
585 - }
586 - for _, r := range bufs {
587 - s = append(s, r)
588 - }
589 - } else {
590 - s = append(s, b)
591 - }
592 - }
593 - }
594 - offset += 1 + l
595 - return string(s), offset, nil
596 -}
597 -
598 -// Pack a reflect.StructValue into msg. Struct members can only be uint8, uint16, uint32, string,
599 -// slices and other (often anonymous) structs.
600 -func packStructValue(val reflect.Value, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
601 - var txtTmp []byte
602 - lenmsg := len(msg)
603 - numfield := val.NumField()
604 - for i := 0; i < numfield; i++ {
605 - typefield := val.Type().Field(i)
606 - if typefield.Tag == `dns:"-"` {
607 - continue
608 - }
609 - switch fv := val.Field(i); fv.Kind() {
610 - default:
611 - return lenmsg, &Error{err: "bad kind packing"}
612 - case reflect.Interface:
613 - // PrivateRR is the only RR implementation that has interface field.
614 - // therefore it's expected that this interface would be PrivateRdata
615 - switch data := fv.Interface().(type) {
616 - case PrivateRdata:
617 - n, err := data.Pack(msg[off:])
618 - if err != nil {
619 - return lenmsg, err
620 - }
621 - off += n
622 - default:
623 - return lenmsg, &Error{err: "bad kind interface packing"}
624 - }
625 - case reflect.Slice:
626 - switch typefield.Tag {
627 - default:
628 - return lenmsg, &Error{"bad tag packing slice: " + typefield.Tag.Get("dns")}
629 - case `dns:"domain-name"`:
630 - for j := 0; j < val.Field(i).Len(); j++ {
631 - element := val.Field(i).Index(j).String()
632 - off, err = PackDomainName(element, msg, off, compression, false && compress)
633 - if err != nil {
634 - return lenmsg, err
635 - }
636 - }
637 - case `dns:"txt"`:
638 - if txtTmp == nil {
639 - txtTmp = make([]byte, 256*4+1)
640 - }
641 - off, err = packTxt(fv.Interface().([]string), msg, off, txtTmp)
642 - if err != nil {
643 - return lenmsg, err
644 - }
645 - case `dns:"opt"`: // edns
646 - for j := 0; j < val.Field(i).Len(); j++ {
647 - element := val.Field(i).Index(j).Interface()
648 - b, e := element.(EDNS0).pack()
649 - if e != nil {
650 - return lenmsg, &Error{err: "overflow packing opt"}
651 - }
652 - // Option code
653 - msg[off], msg[off+1] = packUint16(element.(EDNS0).Option())
654 - // Length
655 - msg[off+2], msg[off+3] = packUint16(uint16(len(b)))
656 - off += 4
657 - if off+len(b) > lenmsg {
658 - copy(msg[off:], b)
659 - off = lenmsg
660 - continue
661 - }
662 - // Actual data
663 - copy(msg[off:off+len(b)], b)
664 - off += len(b)
665 - }
666 - case `dns:"a"`:
667 - if val.Type().String() == "dns.IPSECKEY" {
668 - // Field(2) is GatewayType, must be 1
669 - if val.Field(2).Uint() != 1 {
670 - continue
671 - }
672 - }
673 - // It must be a slice of 4, even if it is 16, we encode
674 - // only the first 4
675 - if off+net.IPv4len > lenmsg {
676 - return lenmsg, &Error{err: "overflow packing a"}
677 - }
678 - switch fv.Len() {
679 - case net.IPv6len:
680 - msg[off] = byte(fv.Index(12).Uint())
681 - msg[off+1] = byte(fv.Index(13).Uint())
682 - msg[off+2] = byte(fv.Index(14).Uint())
683 - msg[off+3] = byte(fv.Index(15).Uint())
684 - off += net.IPv4len
685 - case net.IPv4len:
686 - msg[off] = byte(fv.Index(0).Uint())
687 - msg[off+1] = byte(fv.Index(1).Uint())
688 - msg[off+2] = byte(fv.Index(2).Uint())
689 - msg[off+3] = byte(fv.Index(3).Uint())
690 - off += net.IPv4len
691 - case 0:
692 - // Allowed, for dynamic updates
693 - default:
694 - return lenmsg, &Error{err: "overflow packing a"}
695 - }
696 - case `dns:"aaaa"`:
697 - if val.Type().String() == "dns.IPSECKEY" {
698 - // Field(2) is GatewayType, must be 2
699 - if val.Field(2).Uint() != 2 {
700 - continue
701 - }
702 - }
703 - if fv.Len() == 0 {
704 - break
705 - }
706 - if fv.Len() > net.IPv6len || off+fv.Len() > lenmsg {
707 - return lenmsg, &Error{err: "overflow packing aaaa"}
708 - }
709 - for j := 0; j < net.IPv6len; j++ {
710 - msg[off] = byte(fv.Index(j).Uint())
711 - off++
712 - }
713 - case `dns:"wks"`:
714 - // TODO(miek): this is wrong should be lenrd
715 - if off == lenmsg {
716 - break // dyn. updates
717 - }
718 - if val.Field(i).Len() == 0 {
719 - break
720 - }
721 - var bitmapbyte uint16
722 - for j := 0; j < val.Field(i).Len(); j++ {
723 - serv := uint16((fv.Index(j).Uint()))
724 - bitmapbyte = uint16(serv / 8)
725 - if int(bitmapbyte) > lenmsg {
726 - return lenmsg, &Error{err: "overflow packing wks"}
727 - }
728 - bit := uint16(serv) - bitmapbyte*8
729 - msg[bitmapbyte] = byte(1 << (7 - bit))
730 - }
731 - off += int(bitmapbyte)
732 - case `dns:"nsec"`: // NSEC/NSEC3
733 - // This is the uint16 type bitmap
734 - if val.Field(i).Len() == 0 {
735 - // Do absolutely nothing
736 - break
737 - }
738 -
739 - lastwindow := uint16(0)
740 - length := uint16(0)
741 - if off+2 > lenmsg {
742 - return lenmsg, &Error{err: "overflow packing nsecx"}
743 - }
744 - for j := 0; j < val.Field(i).Len(); j++ {
745 - t := uint16((fv.Index(j).Uint()))
746 - window := uint16(t / 256)
747 - if lastwindow != window {
748 - // New window, jump to the new offset
749 - off += int(length) + 3
750 - if off > lenmsg {
751 - return lenmsg, &Error{err: "overflow packing nsecx bitmap"}
752 - }
753 - }
754 - length = (t - window*256) / 8
755 - bit := t - (window * 256) - (length * 8)
756 - if off+2+int(length) > lenmsg {
757 - return lenmsg, &Error{err: "overflow packing nsecx bitmap"}
758 - }
759 -
760 - // Setting the window #
761 - msg[off] = byte(window)
762 - // Setting the octets length
763 - msg[off+1] = byte(length + 1)
764 - // Setting the bit value for the type in the right octet
765 - msg[off+2+int(length)] |= byte(1 << (7 - bit))
766 - lastwindow = window
767 - }
768 - off += 2 + int(length)
769 - off++
770 - if off > lenmsg {
771 - return lenmsg, &Error{err: "overflow packing nsecx bitmap"}
772 - }
773 - }
774 - case reflect.Struct:
775 - off, err = packStructValue(fv, msg, off, compression, compress)
776 - if err != nil {
777 - return lenmsg, err
778 - }
779 - case reflect.Uint8:
780 - if off+1 > lenmsg {
781 - return lenmsg, &Error{err: "overflow packing uint8"}
782 - }
783 - msg[off] = byte(fv.Uint())
784 - off++
785 - case reflect.Uint16:
786 - if off+2 > lenmsg {
787 - return lenmsg, &Error{err: "overflow packing uint16"}
788 - }
789 - i := fv.Uint()
790 - msg[off] = byte(i >> 8)
791 - msg[off+1] = byte(i)
792 - off += 2
793 - case reflect.Uint32:
794 - if off+4 > lenmsg {
795 - return lenmsg, &Error{err: "overflow packing uint32"}
796 - }
797 - i := fv.Uint()
798 - msg[off] = byte(i >> 24)
799 - msg[off+1] = byte(i >> 16)
800 - msg[off+2] = byte(i >> 8)
801 - msg[off+3] = byte(i)
802 - off += 4
803 - case reflect.Uint64:
804 - switch typefield.Tag {
805 - default:
806 - if off+8 > lenmsg {
807 - return lenmsg, &Error{err: "overflow packing uint64"}
808 - }
809 - i := fv.Uint()
810 - msg[off] = byte(i >> 56)
811 - msg[off+1] = byte(i >> 48)
812 - msg[off+2] = byte(i >> 40)
813 - msg[off+3] = byte(i >> 32)
814 - msg[off+4] = byte(i >> 24)
815 - msg[off+5] = byte(i >> 16)
816 - msg[off+6] = byte(i >> 8)
817 - msg[off+7] = byte(i)
818 - off += 8
819 - case `dns:"uint48"`:
820 - // Used in TSIG, where it stops at 48 bits, so we discard the upper 16
821 - if off+6 > lenmsg {
822 - return lenmsg, &Error{err: "overflow packing uint64 as uint48"}
823 - }
824 - i := fv.Uint()
825 - msg[off] = byte(i >> 40)
826 - msg[off+1] = byte(i >> 32)
827 - msg[off+2] = byte(i >> 24)
828 - msg[off+3] = byte(i >> 16)
829 - msg[off+4] = byte(i >> 8)
830 - msg[off+5] = byte(i)
831 - off += 6
832 - }
833 - case reflect.String:
834 - // There are multiple string encodings.
835 - // The tag distinguishes ordinary strings from domain names.
836 - s := fv.String()
837 - switch typefield.Tag {
838 - default:
839 - return lenmsg, &Error{"bad tag packing string: " + typefield.Tag.Get("dns")}
840 - case `dns:"base64"`:
841 - b64, e := fromBase64([]byte(s))
842 - if e != nil {
843 - return lenmsg, e
844 - }
845 - copy(msg[off:off+len(b64)], b64)
846 - off += len(b64)
847 - case `dns:"domain-name"`:
848 - if val.Type().String() == "dns.IPSECKEY" {
849 - // Field(2) is GatewayType, 1 and 2 or used for addresses
850 - x := val.Field(2).Uint()
851 - if x == 1 || x == 2 {
852 - continue
853 - }
854 - }
855 - if off, err = PackDomainName(s, msg, off, compression, false && compress); err != nil {
856 - return lenmsg, err
857 - }
858 - case `dns:"cdomain-name"`:
859 - if off, err = PackDomainName(s, msg, off, compression, true && compress); err != nil {
860 - return lenmsg, err
861 - }
862 - case `dns:"size-base32"`:
863 - // This is purely for NSEC3 atm, the previous byte must
864 - // holds the length of the encoded string. As NSEC3
865 - // is only defined to SHA1, the hashlength is 20 (160 bits)
866 - msg[off-1] = 20
867 - fallthrough
868 - case `dns:"base32"`:
869 - b32, e := fromBase32([]byte(s))
870 - if e != nil {
871 - return lenmsg, e
872 - }
873 - copy(msg[off:off+len(b32)], b32)
874 - off += len(b32)
875 - case `dns:"size-hex"`:
876 - fallthrough
877 - case `dns:"hex"`:
878 - // There is no length encoded here
879 - h, e := hex.DecodeString(s)
880 - if e != nil {
881 - return lenmsg, e
882 - }
883 - if off+hex.DecodedLen(len(s)) > lenmsg {
884 - return lenmsg, &Error{err: "overflow packing hex"}
885 - }
886 - copy(msg[off:off+hex.DecodedLen(len(s))], h)
887 - off += hex.DecodedLen(len(s))
888 - case `dns:"size"`:
889 - // the size is already encoded in the RR, we can safely use the
890 - // length of string. String is RAW (not encoded in hex, nor base64)
891 - copy(msg[off:off+len(s)], s)
892 - off += len(s)
893 - case `dns:"txt"`:
894 - fallthrough
895 - case "":
896 - if txtTmp == nil {
897 - txtTmp = make([]byte, 256*4+1)
898 - }
899 - off, err = packTxtString(fv.String(), msg, off, txtTmp)
900 - if err != nil {
901 - return lenmsg, err
902 - }
903 - }
904 - }
905 - }
906 - return off, nil
907 -}
908 -
909 -func structValue(any interface{}) reflect.Value {
910 - return reflect.ValueOf(any).Elem()
911 -}
912 -
913 -// PackStruct packs any structure to wire format.
914 -func PackStruct(any interface{}, msg []byte, off int) (off1 int, err error) {
915 - off, err = packStructValue(structValue(any), msg, off, nil, false)
916 - return off, err
917 -}
918 -
919 -func packStructCompress(any interface{}, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
920 - off, err = packStructValue(structValue(any), msg, off, compression, compress)
921 - return off, err
922 -}
923 -
924 -// TODO(miek): Fix use of rdlength here
925 -
926 -// Unpack a reflect.StructValue from msg.
927 -// Same restrictions as packStructValue.
928 -func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, err error) {
929 - var lenrd int
930 - lenmsg := len(msg)
931 - for i := 0; i < val.NumField(); i++ {
932 - if lenrd != 0 && lenrd == off {
933 - break
934 - }
935 - if off > lenmsg {
936 - return lenmsg, &Error{"bad offset unpacking"}
937 - }
938 - switch fv := val.Field(i); fv.Kind() {
939 - default:
940 - return lenmsg, &Error{err: "bad kind unpacking"}
941 - case reflect.Interface:
942 - // PrivateRR is the only RR implementation that has interface field.
943 - // therefore it's expected that this interface would be PrivateRdata
944 - switch data := fv.Interface().(type) {
945 - case PrivateRdata:
946 - n, err := data.Unpack(msg[off:lenrd])
947 - if err != nil {
948 - return lenmsg, err
949 - }
950 - off += n
951 - default:
952 - return lenmsg, &Error{err: "bad kind interface unpacking"}
953 - }
954 - case reflect.Slice:
955 - switch val.Type().Field(i).Tag {
956 - default:
957 - return lenmsg, &Error{"bad tag unpacking slice: " + val.Type().Field(i).Tag.Get("dns")}
958 - case `dns:"domain-name"`:
959 - // HIP record slice of name (or none)
960 - var servers []string
961 - var s string
962 - for off < lenrd {
963 - s, off, err = UnpackDomainName(msg, off)
964 - if err != nil {
965 - return lenmsg, err
966 - }
967 - servers = append(servers, s)
968 - }
969 - fv.Set(reflect.ValueOf(servers))
970 - case `dns:"txt"`:
971 - if off == lenmsg || lenrd == off {
972 - break
973 - }
974 - var txt []string
975 - txt, off, err = unpackTxt(msg, off, lenrd)
976 - if err != nil {
977 - return lenmsg, err
978 - }
979 - fv.Set(reflect.ValueOf(txt))
980 - case `dns:"opt"`: // edns0
981 - if off == lenrd {
982 - // This is an EDNS0 (OPT Record) with no rdata
983 - // We can safely return here.
984 - break
985 - }
986 - var edns []EDNS0
987 - Option:
988 - code := uint16(0)
989 - if off+2 > lenmsg {
990 - return lenmsg, &Error{err: "overflow unpacking opt"}
991 - }
992 - code, off = unpackUint16(msg, off)
993 - optlen, off1 := unpackUint16(msg, off)
994 - if off1+int(optlen) > lenrd {
995 - return lenmsg, &Error{err: "overflow unpacking opt"}
996 - }
997 - switch code {
998 - case EDNS0NSID:
999 - e := new(EDNS0_NSID)
1000 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1001 - return lenmsg, err
1002 - }
1003 - edns = append(edns, e)
1004 - off = off1 + int(optlen)
1005 - case EDNS0SUBNET, EDNS0SUBNETDRAFT:
1006 - e := new(EDNS0_SUBNET)
1007 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1008 - return lenmsg, err
1009 - }
1010 - edns = append(edns, e)
1011 - off = off1 + int(optlen)
1012 - if code == EDNS0SUBNETDRAFT {
1013 - e.DraftOption = true
1014 - }
1015 - case EDNS0UL:
1016 - e := new(EDNS0_UL)
1017 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1018 - return lenmsg, err
1019 - }
1020 - edns = append(edns, e)
1021 - off = off1 + int(optlen)
1022 - case EDNS0LLQ:
1023 - e := new(EDNS0_LLQ)
1024 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1025 - return lenmsg, err
1026 - }
1027 - edns = append(edns, e)
1028 - off = off1 + int(optlen)
1029 - case EDNS0DAU:
1030 - e := new(EDNS0_DAU)
1031 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1032 - return lenmsg, err
1033 - }
1034 - edns = append(edns, e)
1035 - off = off1 + int(optlen)
1036 - case EDNS0DHU:
1037 - e := new(EDNS0_DHU)
1038 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1039 - return lenmsg, err
1040 - }
1041 - edns = append(edns, e)
1042 - off = off1 + int(optlen)
1043 - case EDNS0N3U:
1044 - e := new(EDNS0_N3U)
1045 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1046 - return lenmsg, err
1047 - }
1048 - edns = append(edns, e)
1049 - off = off1 + int(optlen)
1050 - default:
1051 - e := new(EDNS0_LOCAL)
1052 - e.Code = code
1053 - if err := e.unpack(msg[off1 : off1+int(optlen)]); err != nil {
1054 - return lenmsg, err
1055 - }
1056 - edns = append(edns, e)
1057 - off = off1 + int(optlen)
1058 - }
1059 - if off < lenrd {
1060 - goto Option
1061 - }
1062 - fv.Set(reflect.ValueOf(edns))
1063 - case `dns:"a"`:
1064 - if val.Type().String() == "dns.IPSECKEY" {
1065 - // Field(2) is GatewayType, must be 1
1066 - if val.Field(2).Uint() != 1 {
1067 - continue
1068 - }
1069 - }
1070 - if off == lenrd {
1071 - break // dyn. update
1072 - }
1073 - if off+net.IPv4len > lenrd || off+net.IPv4len > lenmsg {
1074 - return lenmsg, &Error{err: "overflow unpacking a"}
1075 - }
1076 - fv.Set(reflect.ValueOf(net.IPv4(msg[off], msg[off+1], msg[off+2], msg[off+3])))
1077 - off += net.IPv4len
1078 - case `dns:"aaaa"`:
1079 - if val.Type().String() == "dns.IPSECKEY" {
1080 - // Field(2) is GatewayType, must be 2
1081 - if val.Field(2).Uint() != 2 {
1082 - continue
1083 - }
1084 - }
1085 - if off == lenrd {
1086 - break
1087 - }
1088 - if off+net.IPv6len > lenrd || off+net.IPv6len > lenmsg {
1089 - return lenmsg, &Error{err: "overflow unpacking aaaa"}
1090 - }
1091 - fv.Set(reflect.ValueOf(net.IP{msg[off], msg[off+1], msg[off+2], msg[off+3], msg[off+4],
1092 - msg[off+5], msg[off+6], msg[off+7], msg[off+8], msg[off+9], msg[off+10],
1093 - msg[off+11], msg[off+12], msg[off+13], msg[off+14], msg[off+15]}))
1094 - off += net.IPv6len
1095 - case `dns:"wks"`:
1096 - // Rest of the record is the bitmap
1097 - var serv []uint16
1098 - j := 0
1099 - for off < lenrd {
1100 - if off+1 > lenmsg {
1101 - return lenmsg, &Error{err: "overflow unpacking wks"}
1102 - }
1103 - b := msg[off]
1104 - // Check the bits one by one, and set the type
1105 - if b&0x80 == 0x80 {
1106 - serv = append(serv, uint16(j*8+0))
1107 - }
1108 - if b&0x40 == 0x40 {
1109 - serv = append(serv, uint16(j*8+1))
1110 - }
1111 - if b&0x20 == 0x20 {
1112 - serv = append(serv, uint16(j*8+2))
1113 - }
1114 - if b&0x10 == 0x10 {
1115 - serv = append(serv, uint16(j*8+3))
1116 - }
1117 - if b&0x8 == 0x8 {
1118 - serv = append(serv, uint16(j*8+4))
1119 - }
1120 - if b&0x4 == 0x4 {
1121 - serv = append(serv, uint16(j*8+5))
1122 - }
1123 - if b&0x2 == 0x2 {
1124 - serv = append(serv, uint16(j*8+6))
1125 - }
1126 - if b&0x1 == 0x1 {
1127 - serv = append(serv, uint16(j*8+7))
1128 - }
1129 - j++
1130 - off++
1131 - }
1132 - fv.Set(reflect.ValueOf(serv))
1133 - case `dns:"nsec"`: // NSEC/NSEC3
1134 - if off == lenrd {
1135 - break
1136 - }
1137 - // Rest of the record is the type bitmap
1138 - if off+2 > lenrd || off+2 > lenmsg {
1139 - return lenmsg, &Error{err: "overflow unpacking nsecx"}
1140 - }
1141 - var nsec []uint16
1142 - length := 0
1143 - window := 0
1144 - for off+2 < lenrd {
1145 - window = int(msg[off])
1146 - length = int(msg[off+1])
1147 - //println("off, windows, length, end", off, window, length, endrr)
1148 - if length == 0 {
1149 - // A length window of zero is strange. If there
1150 - // the window should not have been specified. Bail out
1151 - // println("dns: length == 0 when unpacking NSEC")
1152 - return lenmsg, &Error{err: "overflow unpacking nsecx"}
1153 - }
1154 - if length > 32 {
1155 - return lenmsg, &Error{err: "overflow unpacking nsecx"}
1156 - }
1157 -
1158 - // Walk the bytes in the window - and check the bit settings...
1159 - off += 2
1160 - for j := 0; j < length; j++ {
1161 - if off+j+1 > lenmsg {
1162 - return lenmsg, &Error{err: "overflow unpacking nsecx"}
1163 - }
1164 - b := msg[off+j]
1165 - // Check the bits one by one, and set the type
1166 - if b&0x80 == 0x80 {
1167 - nsec = append(nsec, uint16(window*256+j*8+0))
1168 - }
1169 - if b&0x40 == 0x40 {
1170 - nsec = append(nsec, uint16(window*256+j*8+1))
1171 - }
1172 - if b&0x20 == 0x20 {
1173 - nsec = append(nsec, uint16(window*256+j*8+2))
1174 - }
1175 - if b&0x10 == 0x10 {
1176 - nsec = append(nsec, uint16(window*256+j*8+3))
1177 - }
1178 - if b&0x8 == 0x8 {
1179 - nsec = append(nsec, uint16(window*256+j*8+4))
1180 - }
1181 - if b&0x4 == 0x4 {
1182 - nsec = append(nsec, uint16(window*256+j*8+5))
1183 - }
1184 - if b&0x2 == 0x2 {
1185 - nsec = append(nsec, uint16(window*256+j*8+6))
1186 - }
1187 - if b&0x1 == 0x1 {
1188 - nsec = append(nsec, uint16(window*256+j*8+7))
1189 - }
1190 - }
1191 - off += length
1192 - }
1193 - fv.Set(reflect.ValueOf(nsec))
1194 - }
1195 - case reflect.Struct:
1196 - off, err = unpackStructValue(fv, msg, off)
1197 - if err != nil {
1198 - return lenmsg, err
1199 - }
1200 - if val.Type().Field(i).Name == "Hdr" {
1201 - lenrd = off + int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
1202 - }
1203 - case reflect.Uint8:
1204 - if off == lenmsg {
1205 - break
1206 - }
1207 - if off+1 > lenmsg {
1208 - return lenmsg, &Error{err: "overflow unpacking uint8"}
1209 - }
1210 - fv.SetUint(uint64(uint8(msg[off])))
1211 - off++
1212 - case reflect.Uint16:
1213 - if off == lenmsg {
1214 - break
1215 - }
1216 - var i uint16
1217 - if off+2 > lenmsg {
1218 - return lenmsg, &Error{err: "overflow unpacking uint16"}
1219 - }
1220 - i, off = unpackUint16(msg, off)
1221 - fv.SetUint(uint64(i))
1222 - case reflect.Uint32:
1223 - if off == lenmsg {
1224 - break
1225 - }
1226 - if off+4 > lenmsg {
1227 - return lenmsg, &Error{err: "overflow unpacking uint32"}
1228 - }
1229 - fv.SetUint(uint64(uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])))
1230 - off += 4
1231 - case reflect.Uint64:
1232 - switch val.Type().Field(i).Tag {
1233 - default:
1234 - if off+8 > lenmsg {
1235 - return lenmsg, &Error{err: "overflow unpacking uint64"}
1236 - }
1237 - fv.SetUint(uint64(uint64(msg[off])<<56 | uint64(msg[off+1])<<48 | uint64(msg[off+2])<<40 |
1238 - uint64(msg[off+3])<<32 | uint64(msg[off+4])<<24 | uint64(msg[off+5])<<16 | uint64(msg[off+6])<<8 | uint64(msg[off+7])))
1239 - off += 8
1240 - case `dns:"uint48"`:
1241 - // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes)
1242 - if off+6 > lenmsg {
1243 - return lenmsg, &Error{err: "overflow unpacking uint64 as uint48"}
1244 - }
1245 - fv.SetUint(uint64(uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 |
1246 - uint64(msg[off+4])<<8 | uint64(msg[off+5])))
1247 - off += 6
1248 - }
1249 - case reflect.String:
1250 - var s string
1251 - if off == lenmsg {
1252 - break
1253 - }
1254 - switch val.Type().Field(i).Tag {
1255 - default:
1256 - return lenmsg, &Error{"bad tag unpacking string: " + val.Type().Field(i).Tag.Get("dns")}
1257 - case `dns:"hex"`:
1258 - hexend := lenrd
1259 - if val.FieldByName("Hdr").FieldByName("Rrtype").Uint() == uint64(TypeHIP) {
1260 - hexend = off + int(val.FieldByName("HitLength").Uint())
1261 - }
1262 - if hexend > lenrd || hexend > lenmsg {
1263 - return lenmsg, &Error{err: "overflow unpacking hex"}
1264 - }
1265 - s = hex.EncodeToString(msg[off:hexend])
1266 - off = hexend
1267 - case `dns:"base64"`:
1268 - // Rest of the RR is base64 encoded value
1269 - b64end := lenrd
1270 - if val.FieldByName("Hdr").FieldByName("Rrtype").Uint() == uint64(TypeHIP) {
1271 - b64end = off + int(val.FieldByName("PublicKeyLength").Uint())
1272 - }
1273 - if b64end > lenrd || b64end > lenmsg {
1274 - return lenmsg, &Error{err: "overflow unpacking base64"}
1275 - }
1276 - s = toBase64(msg[off:b64end])
1277 - off = b64end
1278 - case `dns:"cdomain-name"`:
1279 - fallthrough
1280 - case `dns:"domain-name"`:
1281 - if val.Type().String() == "dns.IPSECKEY" {
1282 - // Field(2) is GatewayType, 1 and 2 or used for addresses
1283 - x := val.Field(2).Uint()
1284 - if x == 1 || x == 2 {
1285 - continue
1286 - }
1287 - }
1288 - if off == lenmsg {
1289 - // zero rdata foo, OK for dyn. updates
1290 - break
1291 - }
1292 - s, off, err = UnpackDomainName(msg, off)
1293 - if err != nil {
1294 - return lenmsg, err
1295 - }
1296 - case `dns:"size-base32"`:
1297 - var size int
1298 - switch val.Type().Name() {
1299 - case "NSEC3":
1300 - switch val.Type().Field(i).Name {
1301 - case "NextDomain":
1302 - name := val.FieldByName("HashLength")
1303 - size = int(name.Uint())
1304 - }
1305 - }
1306 - if off+size > lenmsg {
1307 - return lenmsg, &Error{err: "overflow unpacking base32"}
1308 - }
1309 - s = toBase32(msg[off : off+size])
1310 - off += size
1311 - case `dns:"size-hex"`:
1312 - // a "size" string, but it must be encoded in hex in the string
1313 - var size int
1314 - switch val.Type().Name() {
1315 - case "NSEC3":
1316 - switch val.Type().Field(i).Name {
1317 - case "Salt":
1318 - name := val.FieldByName("SaltLength")
1319 - size = int(name.Uint())
1320 - case "NextDomain":
1321 - name := val.FieldByName("HashLength")
1322 - size = int(name.Uint())
1323 - }
1324 - case "TSIG":
1325 - switch val.Type().Field(i).Name {
1326 - case "MAC":
1327 - name := val.FieldByName("MACSize")
1328 - size = int(name.Uint())
1329 - case "OtherData":
1330 - name := val.FieldByName("OtherLen")
1331 - size = int(name.Uint())
1332 - }
1333 - }
1334 - if off+size > lenmsg {
1335 - return lenmsg, &Error{err: "overflow unpacking hex"}
1336 - }
1337 - s = hex.EncodeToString(msg[off : off+size])
1338 - off += size
1339 - case `dns:"txt"`:
1340 - fallthrough
1341 - case "":
1342 - s, off, err = unpackTxtString(msg, off)
1343 - }
1344 - fv.SetString(s)
1345 - }
1346 - }
1347 - return off, nil
1348 -}
1349 -
1350 -// Helpers for dealing with escaped bytes
1351 -func isDigit(b byte) bool { return b >= '0' && b <= '9' }
1352 -
1353 -func dddToByte(s []byte) byte {
1354 - return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0'))
1355 -}
1356 -
1357 -// UnpackStruct unpacks a binary message from offset off to the interface
1358 -// value given.
1359 -func UnpackStruct(any interface{}, msg []byte, off int) (int, error) {
1360 - return unpackStructValue(structValue(any), msg, off)
1361 -}
1362 -
1363 -// Helper function for packing and unpacking
1364 -func intToBytes(i *big.Int, length int) []byte {
1365 - buf := i.Bytes()
1366 - if len(buf) < length {
1367 - b := make([]byte, length)
1368 - copy(b[length-len(buf):], buf)
1369 - return b
1370 - }
1371 - return buf
1372 -}
1373 -
1374 -func unpackUint16(msg []byte, off int) (uint16, int) {
1375 - return uint16(msg[off])<<8 | uint16(msg[off+1]), off + 2
1376 -}
1377 -
1378 -func packUint16(i uint16) (byte, byte) {
1379 - return byte(i >> 8), byte(i)
1380 -}
1381 -
1382 -func toBase32(b []byte) string {
1383 - return base32.HexEncoding.EncodeToString(b)
1384 -}
1385 -
1386 -func fromBase32(s []byte) (buf []byte, err error) {
1387 - buflen := base32.HexEncoding.DecodedLen(len(s))
1388 - buf = make([]byte, buflen)
1389 - n, err := base32.HexEncoding.Decode(buf, s)
1390 - buf = buf[:n]
1391 - return
1392 -}
1393 -
1394 -func toBase64(b []byte) string {
1395 - return base64.StdEncoding.EncodeToString(b)
1396 -}
1397 -
1398 -func fromBase64(s []byte) (buf []byte, err error) {
1399 - buflen := base64.StdEncoding.DecodedLen(len(s))
1400 - buf = make([]byte, buflen)
1401 - n, err := base64.StdEncoding.Decode(buf, s)
1402 - buf = buf[:n]
1403 - return
1404 -}
1405 -
1406 -// PackRR packs a resource record rr into msg[off:].
1407 -// See PackDomainName for documentation about the compression.
1408 -func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) {
1409 - if rr == nil {
1410 - return len(msg), &Error{err: "nil rr"}
1411 - }
1412 -
1413 - off1, err = packStructCompress(rr, msg, off, compression, compress)
1414 - if err != nil {
1415 - return len(msg), err
1416 - }
1417 - if rawSetRdlength(msg, off, off1) {
1418 - return off1, nil
1419 - }
1420 - return off, ErrRdata
1421 -}
1422 -
1423 -// UnpackRR unpacks msg[off:] into an RR.
1424 -func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
1425 - // unpack just the header, to find the rr type and length
1426 - var h RR_Header
1427 - off0 := off
1428 - if off, err = UnpackStruct(&h, msg, off); err != nil {
1429 - return nil, len(msg), err
1430 - }
1431 - end := off + int(h.Rdlength)
1432 - // make an rr of that type and re-unpack.
1433 - mk, known := typeToRR[h.Rrtype]
1434 - if !known {
1435 - rr = new(RFC3597)
1436 - } else {
1437 - rr = mk()
1438 - }
1439 - off, err = UnpackStruct(rr, msg, off0)
1440 - if off != end {
1441 - return &h, end, &Error{err: "bad rdlength"}
1442 - }
1443 - return rr, off, err
1444 -}
1445 -
1446 -// Reverse a map
1447 -func reverseInt8(m map[uint8]string) map[string]uint8 {
1448 - n := make(map[string]uint8)
1449 - for u, s := range m {
1450 - n[s] = u
1451 - }
1452 - return n
1453 -}
1454 -
1455 -func reverseInt16(m map[uint16]string) map[string]uint16 {
1456 - n := make(map[string]uint16)
1457 - for u, s := range m {
1458 - n[s] = u
1459 - }
1460 - return n
1461 -}
1462 -
1463 -func reverseInt(m map[int]string) map[string]int {
1464 - n := make(map[string]int)
1465 - for u, s := range m {
1466 - n[s] = u
1467 - }
1468 - return n
1469 -}
1470 -
1471 -// Convert a MsgHdr to a string, with dig-like headers:
1472 -//
1473 -//;; opcode: QUERY, status: NOERROR, id: 48404
1474 -//
1475 -//;; flags: qr aa rd ra;
1476 -func (h *MsgHdr) String() string {
1477 - if h == nil {
1478 - return "<nil> MsgHdr"
1479 - }
1480 -
1481 - s := ";; opcode: " + OpcodeToString[h.Opcode]
1482 - s += ", status: " + RcodeToString[h.Rcode]
1483 - s += ", id: " + strconv.Itoa(int(h.Id)) + "\n"
1484 -
1485 - s += ";; flags:"
1486 - if h.Response {
1487 - s += " qr"
1488 - }
1489 - if h.Authoritative {
1490 - s += " aa"
1491 - }
1492 - if h.Truncated {
1493 - s += " tc"
1494 - }
1495 - if h.RecursionDesired {
1496 - s += " rd"
1497 - }
1498 - if h.RecursionAvailable {
1499 - s += " ra"
1500 - }
1501 - if h.Zero { // Hmm
1502 - s += " z"
1503 - }
1504 - if h.AuthenticatedData {
1505 - s += " ad"
1506 - }
1507 - if h.CheckingDisabled {
1508 - s += " cd"
1509 - }
1510 -
1511 - s += ";"
1512 - return s
1513 -}
1514 -
1515 -// Pack packs a Msg: it is converted to to wire format.
1516 -// If the dns.Compress is true the message will be in compressed wire format.
1517 -func (dns *Msg) Pack() (msg []byte, err error) {
1518 - return dns.PackBuffer(nil)
1519 -}
1520 -
1521 -// PackBuffer packs a Msg, using the given buffer buf. If buf is too small
1522 -// a new buffer is allocated.
1523 -func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
1524 - var dh Header
1525 - var compression map[string]int
1526 - if dns.Compress {
1527 - compression = make(map[string]int) // Compression pointer mappings
1528 - }
1529 -
1530 - if dns.Rcode < 0 || dns.Rcode > 0xFFF {
1531 - return nil, ErrRcode
1532 - }
1533 - if dns.Rcode > 0xF {
1534 - // Regular RCODE field is 4 bits
1535 - opt := dns.IsEdns0()
1536 - if opt == nil {
1537 - return nil, ErrExtendedRcode
1538 - }
1539 - opt.SetExtendedRcode(uint8(dns.Rcode >> 4))
1540 - dns.Rcode &= 0xF
1541 - }
1542 -
1543 - // Convert convenient Msg into wire-like Header.
1544 - dh.Id = dns.Id
1545 - dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode)
1546 - if dns.Response {
1547 - dh.Bits |= _QR
1548 - }
1549 - if dns.Authoritative {
1550 - dh.Bits |= _AA
1551 - }
1552 - if dns.Truncated {
1553 - dh.Bits |= _TC
1554 - }
1555 - if dns.RecursionDesired {
1556 - dh.Bits |= _RD
1557 - }
1558 - if dns.RecursionAvailable {
1559 - dh.Bits |= _RA
1560 - }
1561 - if dns.Zero {
1562 - dh.Bits |= _Z
1563 - }
1564 - if dns.AuthenticatedData {
1565 - dh.Bits |= _AD
1566 - }
1567 - if dns.CheckingDisabled {
1568 - dh.Bits |= _CD
1569 - }
1570 -
1571 - // Prepare variable sized arrays.
1572 - question := dns.Question
1573 - answer := dns.Answer
1574 - ns := dns.Ns
1575 - extra := dns.Extra
1576 -
1577 - dh.Qdcount = uint16(len(question))
1578 - dh.Ancount = uint16(len(answer))
1579 - dh.Nscount = uint16(len(ns))
1580 - dh.Arcount = uint16(len(extra))
1581 -
1582 - // We need the uncompressed length here, because we first pack it and then compress it.
1583 - msg = buf
1584 - compress := dns.Compress
1585 - dns.Compress = false
1586 - if packLen := dns.Len() + 1; len(msg) < packLen {
1587 - msg = make([]byte, packLen)
1588 - }
1589 - dns.Compress = compress
1590 -
1591 - // Pack it in: header and then the pieces.
1592 - off := 0
1593 - off, err = packStructCompress(&dh, msg, off, compression, dns.Compress)
1594 - if err != nil {
1595 - return nil, err
1596 - }
1597 - for i := 0; i < len(question); i++ {
1598 - off, err = packStructCompress(&question[i], msg, off, compression, dns.Compress)
1599 - if err != nil {
1600 - return nil, err
1601 - }
1602 - }
1603 - for i := 0; i < len(answer); i++ {
1604 - off, err = PackRR(answer[i], msg, off, compression, dns.Compress)
1605 - if err != nil {
1606 - return nil, err
1607 - }
1608 - }
1609 - for i := 0; i < len(ns); i++ {
1610 - off, err = PackRR(ns[i], msg, off, compression, dns.Compress)
1611 - if err != nil {
1612 - return nil, err
1613 - }
1614 - }
1615 - for i := 0; i < len(extra); i++ {
1616 - off, err = PackRR(extra[i], msg, off, compression, dns.Compress)
1617 - if err != nil {
1618 - return nil, err
1619 - }
1620 - }
1621 - return msg[:off], nil
1622 -}
1623 -
1624 -// Unpack unpacks a binary message to a Msg structure.
1625 -func (dns *Msg) Unpack(msg []byte) (err error) {
1626 - // Header.
1627 - var dh Header
1628 - off := 0
1629 - if off, err = UnpackStruct(&dh, msg, off); err != nil {
1630 - return err
1631 - }
1632 - dns.Id = dh.Id
1633 - dns.Response = (dh.Bits & _QR) != 0
1634 - dns.Opcode = int(dh.Bits>>11) & 0xF
1635 - dns.Authoritative = (dh.Bits & _AA) != 0
1636 - dns.Truncated = (dh.Bits & _TC) != 0
1637 - dns.RecursionDesired = (dh.Bits & _RD) != 0
1638 - dns.RecursionAvailable = (dh.Bits & _RA) != 0
1639 - dns.Zero = (dh.Bits & _Z) != 0
1640 - dns.AuthenticatedData = (dh.Bits & _AD) != 0
1641 - dns.CheckingDisabled = (dh.Bits & _CD) != 0
1642 - dns.Rcode = int(dh.Bits & 0xF)
1643 -
1644 - // Arrays.
1645 - dns.Question = make([]Question, dh.Qdcount)
1646 - dns.Answer = make([]RR, dh.Ancount)
1647 - dns.Ns = make([]RR, dh.Nscount)
1648 - dns.Extra = make([]RR, dh.Arcount)
1649 -
1650 - for i := 0; i < len(dns.Question); i++ {
1651 - off, err = UnpackStruct(&dns.Question[i], msg, off)
1652 - if err != nil {
1653 - return err
1654 - }
1655 - }
1656 - // If we see a TC bit being set we return here, without
1657 - // an error, because technically it isn't an error. So return
1658 - // without parsing the potentially corrupt packet and hitting an error.
1659 - // TODO(miek): this isn't the best strategy!
1660 - if dns.Truncated {
1661 - dns.Answer = nil
1662 - dns.Ns = nil
1663 - dns.Extra = nil
1664 - return nil
1665 - }
1666 - for i := 0; i < len(dns.Answer); i++ {
1667 - dns.Answer[i], off, err = UnpackRR(msg, off)
1668 - if err != nil {
1669 - return err
1670 - }
1671 - }
1672 - for i := 0; i < len(dns.Ns); i++ {
1673 - dns.Ns[i], off, err = UnpackRR(msg, off)
1674 - if err != nil {
1675 - return err
1676 - }
1677 - }
1678 - for i := 0; i < len(dns.Extra); i++ {
1679 - dns.Extra[i], off, err = UnpackRR(msg, off)
1680 - if err != nil {
1681 - return err
1682 - }
1683 - }
1684 - if off != len(msg) {
1685 - // TODO(miek) make this an error?
1686 - // use PackOpt to let people tell how detailed the error reporting should be?
1687 - // println("dns: extra bytes in dns packet", off, "<", len(msg))
1688 - }
1689 - return nil
1690 -}
1691 -
1692 -// Convert a complete message to a string with dig-like output.
1693 -func (dns *Msg) String() string {
1694 - if dns == nil {
1695 - return "<nil> MsgHdr"
1696 - }
1697 - s := dns.MsgHdr.String() + " "
1698 - s += "QUERY: " + strconv.Itoa(len(dns.Question)) + ", "
1699 - s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", "
1700 - s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", "
1701 - s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n"
1702 - if len(dns.Question) > 0 {
1703 - s += "\n;; QUESTION SECTION:\n"
1704 - for i := 0; i < len(dns.Question); i++ {
1705 - s += dns.Question[i].String() + "\n"
1706 - }
1707 - }
1708 - if len(dns.Answer) > 0 {
1709 - s += "\n;; ANSWER SECTION:\n"
1710 - for i := 0; i < len(dns.Answer); i++ {
1711 - if dns.Answer[i] != nil {
1712 - s += dns.Answer[i].String() + "\n"
1713 - }
1714 - }
1715 - }
1716 - if len(dns.Ns) > 0 {
1717 - s += "\n;; AUTHORITY SECTION:\n"
1718 - for i := 0; i < len(dns.Ns); i++ {
1719 - if dns.Ns[i] != nil {
1720 - s += dns.Ns[i].String() + "\n"
1721 - }
1722 - }
1723 - }
1724 - if len(dns.Extra) > 0 {
1725 - s += "\n;; ADDITIONAL SECTION:\n"
1726 - for i := 0; i < len(dns.Extra); i++ {
1727 - if dns.Extra[i] != nil {
1728 - s += dns.Extra[i].String() + "\n"
1729 - }
1730 - }
1731 - }
1732 - return s
1733 -}
1734 -
1735 -// Len returns the message length when in (un)compressed wire format.
1736 -// If dns.Compress is true compression it is taken into account. Len()
1737 -// is provided to be a faster way to get the size of the resulting packet,
1738 -// than packing it, measuring the size and discarding the buffer.
1739 -func (dns *Msg) Len() int {
1740 - // We always return one more than needed.
1741 - l := 12 // Message header is always 12 bytes
1742 - var compression map[string]int
1743 - if dns.Compress {
1744 - compression = make(map[string]int)
1745 - }
1746 - for i := 0; i < len(dns.Question); i++ {
1747 - l += dns.Question[i].len()
1748 - if dns.Compress {
1749 - compressionLenHelper(compression, dns.Question[i].Name)
1750 - }
1751 - }
1752 - for i := 0; i < len(dns.Answer); i++ {
1753 - l += dns.Answer[i].len()
1754 - if dns.Compress {
1755 - k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name)
1756 - if ok {
1757 - l += 1 - k
1758 - }
1759 - compressionLenHelper(compression, dns.Answer[i].Header().Name)
1760 - k, ok = compressionLenSearchType(compression, dns.Answer[i])
1761 - if ok {
1762 - l += 1 - k
1763 - }
1764 - compressionLenHelperType(compression, dns.Answer[i])
1765 - }
1766 - }
1767 - for i := 0; i < len(dns.Ns); i++ {
1768 - l += dns.Ns[i].len()
1769 - if dns.Compress {
1770 - k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name)
1771 - if ok {
1772 - l += 1 - k
1773 - }
1774 - compressionLenHelper(compression, dns.Ns[i].Header().Name)
1775 - k, ok = compressionLenSearchType(compression, dns.Ns[i])
1776 - if ok {
1777 - l += 1 - k
1778 - }
1779 - compressionLenHelperType(compression, dns.Ns[i])
1780 - }
1781 - }
1782 - for i := 0; i < len(dns.Extra); i++ {
1783 - l += dns.Extra[i].len()
1784 - if dns.Compress {
1785 - k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name)
1786 - if ok {
1787 - l += 1 - k
1788 - }
1789 - compressionLenHelper(compression, dns.Extra[i].Header().Name)
1790 - k, ok = compressionLenSearchType(compression, dns.Extra[i])
1791 - if ok {
1792 - l += 1 - k
1793 - }
1794 - compressionLenHelperType(compression, dns.Extra[i])
1795 - }
1796 - }
1797 - return l
1798 -}
1799 -
1800 -// Put the parts of the name in the compression map.
1801 -func compressionLenHelper(c map[string]int, s string) {
1802 - pref := ""
1803 - lbs := Split(s)
1804 - for j := len(lbs) - 1; j >= 0; j-- {
1805 - pref = s[lbs[j]:]
1806 - if _, ok := c[pref]; !ok {
1807 - c[pref] = len(pref)
1808 - }
1809 - }
1810 -}
1811 -
1812 -// Look for each part in the compression map and returns its length,
1813 -// keep on searching so we get the longest match.
1814 -func compressionLenSearch(c map[string]int, s string) (int, bool) {
1815 - off := 0
1816 - end := false
1817 - if s == "" { // don't bork on bogus data
1818 - return 0, false
1819 - }
1820 - for {
1821 - if _, ok := c[s[off:]]; ok {
1822 - return len(s[off:]), true
1823 - }
1824 - if end {
1825 - break
1826 - }
1827 - off, end = NextLabel(s, off)
1828 - }
1829 - return 0, false
1830 -}
1831 -
1832 -// TODO(miek): should add all types, because the all can be *used* for compression.
1833 -func compressionLenHelperType(c map[string]int, r RR) {
1834 - switch x := r.(type) {
1835 - case *NS:
1836 - compressionLenHelper(c, x.Ns)
1837 - case *MX:
1838 - compressionLenHelper(c, x.Mx)
1839 - case *CNAME:
1840 - compressionLenHelper(c, x.Target)
1841 - case *PTR:
1842 - compressionLenHelper(c, x.Ptr)
1843 - case *SOA:
1844 - compressionLenHelper(c, x.Ns)
1845 - compressionLenHelper(c, x.Mbox)
1846 - case *MB:
1847 - compressionLenHelper(c, x.Mb)
1848 - case *MG:
1849 - compressionLenHelper(c, x.Mg)
1850 - case *MR:
1851 - compressionLenHelper(c, x.Mr)
1852 - case *MF:
1853 - compressionLenHelper(c, x.Mf)
1854 - case *MD:
1855 - compressionLenHelper(c, x.Md)
1856 - case *RT:
1857 - compressionLenHelper(c, x.Host)
1858 - case *MINFO:
1859 - compressionLenHelper(c, x.Rmail)
1860 - compressionLenHelper(c, x.Email)
1861 - case *AFSDB:
1862 - compressionLenHelper(c, x.Hostname)
1863 - }
1864 -}
1865 -
1866 -// Only search on compressing these types.
1867 -func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
1868 - switch x := r.(type) {
1869 - case *NS:
1870 - return compressionLenSearch(c, x.Ns)
1871 - case *MX:
1872 - return compressionLenSearch(c, x.Mx)
1873 - case *CNAME:
1874 - return compressionLenSearch(c, x.Target)
1875 - case *PTR:
1876 - return compressionLenSearch(c, x.Ptr)
1877 - case *SOA:
1878 - k, ok := compressionLenSearch(c, x.Ns)
1879 - k1, ok1 := compressionLenSearch(c, x.Mbox)
1880 - if !ok && !ok1 {
1881 - return 0, false
1882 - }
1883 - return k + k1, true
1884 - case *MB:
1885 - return compressionLenSearch(c, x.Mb)
1886 - case *MG:
1887 - return compressionLenSearch(c, x.Mg)
1888 - case *MR:
1889 - return compressionLenSearch(c, x.Mr)
1890 - case *MF:
1891 - return compressionLenSearch(c, x.Mf)
1892 - case *MD:
1893 - return compressionLenSearch(c, x.Md)
1894 - case *RT:
1895 - return compressionLenSearch(c, x.Host)
1896 - case *MINFO:
1897 - k, ok := compressionLenSearch(c, x.Rmail)
1898 - k1, ok1 := compressionLenSearch(c, x.Email)
1899 - if !ok && !ok1 {
1900 - return 0, false
1901 - }
1902 - return k + k1, true
1903 - case *AFSDB:
1904 - return compressionLenSearch(c, x.Hostname)
1905 - }
1906 - return 0, false
1907 -}
1908 -
1909 -// id returns a 16 bits random number to be used as a
1910 -// message id. The random provided should be good enough.
1911 -func id() uint16 {
1912 - return uint16(rand.Int()) ^ uint16(time.Now().Nanosecond())
1913 -}
1914 -
1915 -// Copy returns a new RR which is a deep-copy of r.
1916 -func Copy(r RR) RR {
1917 - r1 := r.copy()
1918 - return r1
1919 -}
1920 -
1921 -// Copy returns a new *Msg which is a deep-copy of dns.
1922 -func (dns *Msg) Copy() *Msg {
1923 - return dns.CopyTo(new(Msg))
1924 -}
1925 -
1926 -// CopyTo copies the contents to the provided message using a deep-copy and returns the copy.
1927 -func (dns *Msg) CopyTo(r1 *Msg) *Msg {
1928 - r1.MsgHdr = dns.MsgHdr
1929 - r1.Compress = dns.Compress
1930 -
1931 - if len(dns.Question) > 0 {
1932 - r1.Question = make([]Question, len(dns.Question))
1933 - copy(r1.Question, dns.Question) // TODO(miek): Question is an immutable value, ok to do a shallow-copy
1934 - }
1935 -
1936 - rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra))
1937 - var rri int
1938 -
1939 - if len(dns.Answer) > 0 {
1940 - rrbegin := rri
1941 - for i := 0; i < len(dns.Answer); i++ {
1942 - rrArr[rri] = dns.Answer[i].copy()
1943 - rri++
1944 - }
1945 - r1.Answer = rrArr[rrbegin:rri:rri]
1946 - }
1947 -
1948 - if len(dns.Ns) > 0 {
1949 - rrbegin := rri
1950 - for i := 0; i < len(dns.Ns); i++ {
1951 - rrArr[rri] = dns.Ns[i].copy()
1952 - rri++
1953 - }
1954 - r1.Ns = rrArr[rrbegin:rri:rri]
1955 - }
1956 -
1957 - if len(dns.Extra) > 0 {
1958 - rrbegin := rri
1959 - for i := 0; i < len(dns.Extra); i++ {
1960 - rrArr[rri] = dns.Extra[i].copy()
1961 - rri++
1962 - }
1963 - r1.Extra = rrArr[rrbegin:rri:rri]
1964 - }
1965 -
1966 - return r1
1967 -}
Godeps/_workspace/src/github.com/miekg/dns/nsecx.go deleted
-112
@@ -1,112 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "crypto/sha1"
5 - "hash"
6 - "io"
7 - "strings"
8 -)
9 -
10 -type saltWireFmt struct {
11 - Salt string `dns:"size-hex"`
12 -}
13 -
14 -// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in
15 -// uppercase.
16 -func HashName(label string, ha uint8, iter uint16, salt string) string {
17 - saltwire := new(saltWireFmt)
18 - saltwire.Salt = salt
19 - wire := make([]byte, DefaultMsgSize)
20 - n, err := PackStruct(saltwire, wire, 0)
21 - if err != nil {
22 - return ""
23 - }
24 - wire = wire[:n]
25 - name := make([]byte, 255)
26 - off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
27 - if err != nil {
28 - return ""
29 - }
30 - name = name[:off]
31 - var s hash.Hash
32 - switch ha {
33 - case SHA1:
34 - s = sha1.New()
35 - default:
36 - return ""
37 - }
38 -
39 - // k = 0
40 - name = append(name, wire...)
41 - io.WriteString(s, string(name))
42 - nsec3 := s.Sum(nil)
43 - // k > 0
44 - for k := uint16(0); k < iter; k++ {
45 - s.Reset()
46 - nsec3 = append(nsec3, wire...)
47 - io.WriteString(s, string(nsec3))
48 - nsec3 = s.Sum(nil)
49 - }
50 - return toBase32(nsec3)
51 -}
52 -
53 -// Denialer is an interface that should be implemented by types that are used to denial
54 -// answers in DNSSEC.
55 -type Denialer interface {
56 - // Cover will check if the (unhashed) name is being covered by this NSEC or NSEC3.
57 - Cover(name string) bool
58 - // Match will check if the ownername matches the (unhashed) name for this NSEC3 or NSEC3.
59 - Match(name string) bool
60 -}
61 -
62 -// Cover implements the Denialer interface.
63 -func (rr *NSEC) Cover(name string) bool {
64 - return true
65 -}
66 -
67 -// Match implements the Denialer interface.
68 -func (rr *NSEC) Match(name string) bool {
69 - return true
70 -}
71 -
72 -// Cover implements the Denialer interface.
73 -func (rr *NSEC3) Cover(name string) bool {
74 - // FIXME(miek): check if the zones match
75 - // FIXME(miek): check if we're not dealing with parent nsec3
76 - hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
77 - labels := Split(rr.Hdr.Name)
78 - if len(labels) < 2 {
79 - return false
80 - }
81 - hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the dot
82 - if hash == rr.NextDomain {
83 - return false // empty interval
84 - }
85 - if hash > rr.NextDomain { // last name, points to apex
86 - // hname > hash
87 - // hname > rr.NextDomain
88 - // TODO(miek)
89 - }
90 - if hname <= hash {
91 - return false
92 - }
93 - if hname >= rr.NextDomain {
94 - return false
95 - }
96 - return true
97 -}
98 -
99 -// Match implements the Denialer interface.
100 -func (rr *NSEC3) Match(name string) bool {
101 - // FIXME(miek): Check if we are in the same zone
102 - hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
103 - labels := Split(rr.Hdr.Name)
104 - if len(labels) < 2 {
105 - return false
106 - }
107 - hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the .
108 - if hash == hname {
109 - return true
110 - }
111 - return false
112 -}
Godeps/_workspace/src/github.com/miekg/dns/nsecx_test.go deleted
-29
@@ -1,29 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "testing"
5 -)
6 -
7 -func TestPackNsec3(t *testing.T) {
8 - nsec3 := HashName("dnsex.nl.", SHA1, 0, "DEAD")
9 - if nsec3 != "ROCCJAE8BJJU7HN6T7NG3TNM8ACRS87J" {
10 - t.Error(nsec3)
11 - }
12 -
13 - nsec3 = HashName("a.b.c.example.org.", SHA1, 2, "DEAD")
14 - if nsec3 != "6LQ07OAHBTOOEU2R9ANI2AT70K5O0RCG" {
15 - t.Error(nsec3)
16 - }
17 -}
18 -
19 -func TestNsec3(t *testing.T) {
20 - // examples taken from .nl
21 - nsec3, _ := NewRR("39p91242oslggest5e6a7cci4iaeqvnk.nl. IN NSEC3 1 1 5 F10E9F7EA83FC8F3 39P99DCGG0MDLARTCRMCF6OFLLUL7PR6 NS DS RRSIG")
22 - if !nsec3.(*NSEC3).Cover("snasajsksasasa.nl.") { // 39p94jrinub66hnpem8qdpstrec86pg3
23 - t.Error("39p94jrinub66hnpem8qdpstrec86pg3. should be covered by 39p91242oslggest5e6a7cci4iaeqvnk.nl. - 39P99DCGG0MDLARTCRMCF6OFLLUL7PR6")
24 - }
25 - nsec3, _ = NewRR("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. IN NSEC3 1 1 5 F10E9F7EA83FC8F3 SK4F38CQ0ATIEI8MH3RGD0P5I4II6QAN NS SOA TXT RRSIG DNSKEY NSEC3PARAM")
26 - if !nsec3.(*NSEC3).Match("nl.") { // sk4e8fj94u78smusb40o1n0oltbblu2r.nl.
27 - t.Error("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. should match sk4e8fj94u78smusb40o1n0oltbblu2r.nl.")
28 - }
29 -}
Godeps/_workspace/src/github.com/miekg/dns/parse_test.go deleted
-1378
@@ -1,1378 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "bytes"
5 - "crypto/rsa"
6 - "encoding/hex"
7 - "fmt"
8 - "math/rand"
9 - "net"
10 - "reflect"
11 - "strconv"
12 - "strings"
13 - "testing"
14 - "testing/quick"
15 - "time"
16 -)
17 -
18 -func TestDotInName(t *testing.T) {
19 - buf := make([]byte, 20)
20 - PackDomainName("aa\\.bb.nl.", buf, 0, nil, false)
21 - // index 3 must be a real dot
22 - if buf[3] != '.' {
23 - t.Error("dot should be a real dot")
24 - }
25 -
26 - if buf[6] != 2 {
27 - t.Error("this must have the value 2")
28 - }
29 - dom, _, _ := UnpackDomainName(buf, 0)
30 - // printing it should yield the backspace again
31 - if dom != "aa\\.bb.nl." {
32 - t.Error("dot should have been escaped: ", dom)
33 - }
34 -}
35 -
36 -func TestDotLastInLabel(t *testing.T) {
37 - sample := "aa\\..au."
38 - buf := make([]byte, 20)
39 - _, err := PackDomainName(sample, buf, 0, nil, false)
40 - if err != nil {
41 - t.Fatalf("unexpected error packing domain: %v", err)
42 - }
43 - dom, _, _ := UnpackDomainName(buf, 0)
44 - if dom != sample {
45 - t.Fatalf("unpacked domain `%s' doesn't match packed domain", dom)
46 - }
47 -}
48 -
49 -func TestTooLongDomainName(t *testing.T) {
50 - l := "aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt."
51 - dom := l + l + l + l + l + l + l
52 - _, err := NewRR(dom + " IN A 127.0.0.1")
53 - if err == nil {
54 - t.Error("should be too long")
55 - } else {
56 - t.Logf("error is %v", err)
57 - }
58 - _, err = NewRR("..com. IN A 127.0.0.1")
59 - if err == nil {
60 - t.Error("should fail")
61 - } else {
62 - t.Logf("error is %v", err)
63 - }
64 -}
65 -
66 -func TestDomainName(t *testing.T) {
67 - tests := []string{"r\\.gieben.miek.nl.", "www\\.www.miek.nl.",
68 - "www.*.miek.nl.", "www.*.miek.nl.",
69 - }
70 - dbuff := make([]byte, 40)
71 -
72 - for _, ts := range tests {
73 - if _, err := PackDomainName(ts, dbuff, 0, nil, false); err != nil {
74 - t.Error("not a valid domain name")
75 - continue
76 - }
77 - n, _, err := UnpackDomainName(dbuff, 0)
78 - if err != nil {
79 - t.Error("failed to unpack packed domain name")
80 - continue
81 - }
82 - if ts != n {
83 - t.Errorf("must be equal: in: %s, out: %s", ts, n)
84 - }
85 - }
86 -}
87 -
88 -func TestDomainNameAndTXTEscapes(t *testing.T) {
89 - tests := []byte{'.', '(', ')', ';', ' ', '@', '"', '\\', '\t', '\r', '\n', 0, 255}
90 - for _, b := range tests {
91 - rrbytes := []byte{
92 - 1, b, 0, // owner
93 - byte(TypeTXT >> 8), byte(TypeTXT),
94 - byte(ClassINET >> 8), byte(ClassINET),
95 - 0, 0, 0, 1, // TTL
96 - 0, 2, 1, b, // Data
97 - }
98 - rr1, _, err := UnpackRR(rrbytes, 0)
99 - if err != nil {
100 - panic(err)
101 - }
102 - s := rr1.String()
103 - rr2, err := NewRR(s)
104 - if err != nil {
105 - t.Errorf("Error parsing unpacked RR's string: %v", err)
106 - t.Errorf(" Bytes: %v", rrbytes)
107 - t.Errorf("String: %v", s)
108 - }
109 - repacked := make([]byte, len(rrbytes))
110 - if _, err := PackRR(rr2, repacked, 0, nil, false); err != nil {
111 - t.Errorf("error packing parsed RR: %v", err)
112 - t.Errorf(" original Bytes: %v", rrbytes)
113 - t.Errorf("unpacked Struct: %v", rr1)
114 - t.Errorf(" parsed Struct: %v", rr2)
115 - }
116 - if !bytes.Equal(repacked, rrbytes) {
117 - t.Error("packed bytes don't match original bytes")
118 - t.Errorf(" original bytes: %v", rrbytes)
119 - t.Errorf(" packed bytes: %v", repacked)
120 - t.Errorf("unpacked struct: %v", rr1)
121 - t.Errorf(" parsed struct: %v", rr2)
122 - }
123 - }
124 -}
125 -
126 -func TestTXTEscapeParsing(t *testing.T) {
127 - test := [][]string{
128 - {`";"`, `";"`},
129 - {`\;`, `";"`},
130 - {`"\t"`, `"\t"`},
131 - {`"\r"`, `"\r"`},
132 - {`"\ "`, `" "`},
133 - {`"\;"`, `";"`},
134 - {`"\;\""`, `";\""`},
135 - {`"\(a\)"`, `"(a)"`},
136 - {`"\(a)"`, `"(a)"`},
137 - {`"(a\)"`, `"(a)"`},
138 - {`"(a)"`, `"(a)"`},
139 - {`"\048"`, `"0"`},
140 - {`"\` + "\n" + `"`, `"\n"`},
141 - {`"\` + "\r" + `"`, `"\r"`},
142 - {`"\` + "\x11" + `"`, `"\017"`},
143 - {`"\'"`, `"'"`},
144 - }
145 - for _, s := range test {
146 - rr, err := NewRR(fmt.Sprintf("example.com. IN TXT %v", s[0]))
147 - if err != nil {
148 - t.Errorf("Could not parse %v TXT: %s", s[0], err)
149 - continue
150 - }
151 -
152 - txt := sprintTxt(rr.(*TXT).Txt)
153 - if txt != s[1] {
154 - t.Errorf("Mismatch after parsing `%v` TXT record: `%v` != `%v`", s[0], txt, s[1])
155 - }
156 - }
157 -}
158 -
159 -func GenerateDomain(r *rand.Rand, size int) []byte {
160 - dnLen := size % 70 // artificially limit size so there's less to intrepret if a failure occurs
161 - var dn []byte
162 - done := false
163 - for i := 0; i < dnLen && !done; {
164 - max := dnLen - i
165 - if max > 63 {
166 - max = 63
167 - }
168 - lLen := max
169 - if lLen != 0 {
170 - lLen = int(r.Int31()) % max
171 - }
172 - done = lLen == 0
173 - if done {
174 - continue
175 - }
176 - l := make([]byte, lLen+1)
177 - l[0] = byte(lLen)
178 - for j := 0; j < lLen; j++ {
179 - l[j+1] = byte(rand.Int31())
180 - }
181 - dn = append(dn, l...)
182 - i += 1 + lLen
183 - }
184 - return append(dn, 0)
185 -}
186 -
187 -func TestDomainQuick(t *testing.T) {
188 - r := rand.New(rand.NewSource(0))
189 - f := func(l int) bool {
190 - db := GenerateDomain(r, l)
191 - ds, _, err := UnpackDomainName(db, 0)
192 - if err != nil {
193 - panic(err)
194 - }
195 - buf := make([]byte, 255)
196 - off, err := PackDomainName(ds, buf, 0, nil, false)
197 - if err != nil {
198 - t.Errorf("error packing domain: %v", err)
199 - t.Errorf(" bytes: %v", db)
200 - t.Errorf("string: %v", ds)
201 - return false
202 - }
203 - if !bytes.Equal(db, buf[:off]) {
204 - t.Errorf("repacked domain doesn't match original:")
205 - t.Errorf("src bytes: %v", db)
206 - t.Errorf(" string: %v", ds)
207 - t.Errorf("out bytes: %v", buf[:off])
208 - return false
209 - }
210 - return true
211 - }
212 - if err := quick.Check(f, nil); err != nil {
213 - t.Error(err)
214 - }
215 -}
216 -
217 -func GenerateTXT(r *rand.Rand, size int) []byte {
218 - rdLen := size % 300 // artificially limit size so there's less to intrepret if a failure occurs
219 - var rd []byte
220 - for i := 0; i < rdLen; {
221 - max := rdLen - 1
222 - if max > 255 {
223 - max = 255
224 - }
225 - sLen := max
226 - if max != 0 {
227 - sLen = int(r.Int31()) % max
228 - }
229 - s := make([]byte, sLen+1)
230 - s[0] = byte(sLen)
231 - for j := 0; j < sLen; j++ {
232 - s[j+1] = byte(rand.Int31())
233 - }
234 - rd = append(rd, s...)
235 - i += 1 + sLen
236 - }
237 - return rd
238 -}
239 -
240 -// Ok, 2 things. 1) this test breaks with the new functionality of splitting up larger txt
241 -// chunks into 255 byte pieces. 2) I don't like the random nature of this thing, because I can't
242 -// place the quotes where they need to be.
243 -// So either add some code the places the quotes in just the right spots, make this non random
244 -// or do something else.
245 -// Disabled for now. (miek)
246 -func testTXTRRQuick(t *testing.T) {
247 - s := rand.NewSource(0)
248 - r := rand.New(s)
249 - typeAndClass := []byte{
250 - byte(TypeTXT >> 8), byte(TypeTXT),
251 - byte(ClassINET >> 8), byte(ClassINET),
252 - 0, 0, 0, 1, // TTL
253 - }
254 - f := func(l int) bool {
255 - owner := GenerateDomain(r, l)
256 - rdata := GenerateTXT(r, l)
257 - rrbytes := make([]byte, 0, len(owner)+2+2+4+2+len(rdata))
258 - rrbytes = append(rrbytes, owner...)
259 - rrbytes = append(rrbytes, typeAndClass...)
260 - rrbytes = append(rrbytes, byte(len(rdata)>>8))
261 - rrbytes = append(rrbytes, byte(len(rdata)))
262 - rrbytes = append(rrbytes, rdata...)
263 - rr, _, err := UnpackRR(rrbytes, 0)
264 - if err != nil {
265 - panic(err)
266 - }
267 - buf := make([]byte, len(rrbytes)*3)
268 - off, err := PackRR(rr, buf, 0, nil, false)
269 - if err != nil {
270 - t.Errorf("pack Error: %v\nRR: %v", err, rr)
271 - return false
272 - }
273 - buf = buf[:off]
274 - if !bytes.Equal(buf, rrbytes) {
275 - t.Errorf("packed bytes don't match original bytes")
276 - t.Errorf("src bytes: %v", rrbytes)
277 - t.Errorf(" struct: %v", rr)
278 - t.Errorf("out bytes: %v", buf)
279 - return false
280 - }
281 - if len(rdata) == 0 {
282 - // string'ing won't produce any data to parse
283 - return true
284 - }
285 - rrString := rr.String()
286 - rr2, err := NewRR(rrString)
287 - if err != nil {
288 - t.Errorf("error parsing own output: %v", err)
289 - t.Errorf("struct: %v", rr)
290 - t.Errorf("string: %v", rrString)
291 - return false
292 - }
293 - if rr2.String() != rrString {
294 - t.Errorf("parsed rr.String() doesn't match original string")
295 - t.Errorf("original: %v", rrString)
296 - t.Errorf(" parsed: %v", rr2.String())
297 - return false
298 - }
299 -
300 - buf = make([]byte, len(rrbytes)*3)
301 - off, err = PackRR(rr2, buf, 0, nil, false)
302 - if err != nil {
303 - t.Errorf("error packing parsed rr: %v", err)
304 - t.Errorf("unpacked Struct: %v", rr)
305 - t.Errorf(" string: %v", rrString)
306 - t.Errorf(" parsed Struct: %v", rr2)
307 - return false
308 - }
309 - buf = buf[:off]
310 - if !bytes.Equal(buf, rrbytes) {
311 - t.Errorf("parsed packed bytes don't match original bytes")
312 - t.Errorf(" source bytes: %v", rrbytes)
313 - t.Errorf("unpacked struct: %v", rr)
314 - t.Errorf(" string: %v", rrString)
315 - t.Errorf(" parsed struct: %v", rr2)
316 - t.Errorf(" repacked bytes: %v", buf)
317 - return false
318 - }
319 - return true
320 - }
321 - c := &quick.Config{MaxCountScale: 10}
322 - if err := quick.Check(f, c); err != nil {
323 - t.Error(err)
324 - }
325 -}
326 -
327 -func TestParseDirectiveMisc(t *testing.T) {
328 - tests := map[string]string{
329 - "$ORIGIN miek.nl.\na IN NS b": "a.miek.nl.\t3600\tIN\tNS\tb.miek.nl.",
330 - "$TTL 2H\nmiek.nl. IN NS b.": "miek.nl.\t7200\tIN\tNS\tb.",
331 - "miek.nl. 1D IN NS b.": "miek.nl.\t86400\tIN\tNS\tb.",
332 - `name. IN SOA a6.nstld.com. hostmaster.nic.name. (
333 - 203362132 ; serial
334 - 5m ; refresh (5 minutes)
335 - 5m ; retry (5 minutes)
336 - 2w ; expire (2 weeks)
337 - 300 ; minimum (5 minutes)
338 -)`: "name.\t3600\tIN\tSOA\ta6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300",
339 - ". 3600000 IN NS ONE.MY-ROOTS.NET.": ".\t3600000\tIN\tNS\tONE.MY-ROOTS.NET.",
340 - "ONE.MY-ROOTS.NET. 3600000 IN A 192.168.1.1": "ONE.MY-ROOTS.NET.\t3600000\tIN\tA\t192.168.1.1",
341 - }
342 - for i, o := range tests {
343 - rr, err := NewRR(i)
344 - if err != nil {
345 - t.Error("failed to parse RR: ", err)
346 - continue
347 - }
348 - if rr.String() != o {
349 - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
350 - } else {
351 - t.Logf("RR is OK: `%s'", rr.String())
352 - }
353 - }
354 -}
355 -
356 -func TestNSEC(t *testing.T) {
357 - nsectests := map[string]string{
358 - "nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F": "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F",
359 - "p2209hipbpnm681knjnu0m1febshlv4e.nl. IN NSEC3 1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM": "p2209hipbpnm681knjnu0m1febshlv4e.nl.\t3600\tIN\tNSEC3\t1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM",
360 - "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC",
361 - "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC TYPE65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534",
362 - "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSec Type65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534",
363 - }
364 - for i, o := range nsectests {
365 - rr, err := NewRR(i)
366 - if err != nil {
367 - t.Error("failed to parse RR: ", err)
368 - continue
369 - }
370 - if rr.String() != o {
371 - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
372 - } else {
373 - t.Logf("RR is OK: `%s'", rr.String())
374 - }
375 - }
376 -}
377 -
378 -func TestParseLOC(t *testing.T) {
379 - lt := map[string]string{
380 - "SW1A2AA.find.me.uk. LOC 51 30 12.748 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 30 12.748 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m",
381 - "SW1A2AA.find.me.uk. LOC 51 0 0.0 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 00 0.000 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m",
382 - }
383 - for i, o := range lt {
384 - rr, err := NewRR(i)
385 - if err != nil {
386 - t.Error("failed to parse RR: ", err)
387 - continue
388 - }
389 - if rr.String() != o {
390 - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
391 - } else {
392 - t.Logf("RR is OK: `%s'", rr.String())
393 - }
394 - }
395 -}
396 -
397 -func TestParseDS(t *testing.T) {
398 - dt := map[string]string{
399 - "example.net. 3600 IN DS 40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B 2071398F": "example.net.\t3600\tIN\tDS\t40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B2071398F",
400 - }
401 - for i, o := range dt {
402 - rr, err := NewRR(i)
403 - if err != nil {
404 - t.Error("failed to parse RR: ", err)
405 - continue
406 - }
407 - if rr.String() != o {
408 - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
409 - } else {
410 - t.Logf("RR is OK: `%s'", rr.String())
411 - }
412 - }
413 -}
414 -
415 -func TestQuotes(t *testing.T) {
416 - tests := map[string]string{
417 - `t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"",
418 - `t.example.com. IN TXT "a
419 - bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\\n bc\"",
420 - `t.example.com. IN TXT ""`: "t.example.com.\t3600\tIN\tTXT\t\"\"",
421 - `t.example.com. IN TXT "a"`: "t.example.com.\t3600\tIN\tTXT\t\"a\"",
422 - `t.example.com. IN TXT "aa"`: "t.example.com.\t3600\tIN\tTXT\t\"aa\"",
423 - `t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
424 - `t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
425 - `t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"",
426 - `t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa \"",
427 - `t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
428 - `t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa aaa\"",
429 - `t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"",
430 - "cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.",
431 - "cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.",
432 - "cid.urn.arpa. NAPTR 100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.",
433 - "cid.urn.arpa. NAPTR 100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .",
434 - }
435 - for i, o := range tests {
436 - rr, err := NewRR(i)
437 - if err != nil {
438 - t.Error("failed to parse RR: ", err)
439 - continue
440 - }
441 - if rr.String() != o {
442 - t.Errorf("`%s' should be equal to\n`%s', but is\n`%s'", i, o, rr.String())
443 - } else {
444 - t.Logf("RR is OK: `%s'", rr.String())
445 - }
446 - }
447 -}
448 -
449 -func TestParseClass(t *testing.T) {
450 - tests := map[string]string{
451 - "t.example.com. IN A 127.0.0.1": "t.example.com. 3600 IN A 127.0.0.1",
452 - "t.example.com. CS A 127.0.0.1": "t.example.com. 3600 CS A 127.0.0.1",
453 - "t.example.com. CH A 127.0.0.1": "t.example.com. 3600 CH A 127.0.0.1",
454 - // ClassANY can not occur in zone files
455 - // "t.example.com. ANY A 127.0.0.1": "t.example.com. 3600 ANY A 127.0.0.1",
456 - "t.example.com. NONE A 127.0.0.1": "t.example.com. 3600 NONE A 127.0.0.1",
457 - }
458 - for i, o := range tests {
459 - rr, err := NewRR(i)
460 - if err != nil {
461 - t.Error("failed to parse RR: ", err)
462 - continue
463 - }
464 - if rr.String() != o {
465 - t.Errorf("`%s' should be equal to\n`%s', but is\n`%s'", i, o, rr.String())
466 - } else {
467 - t.Logf("RR is OK: `%s'", rr.String())
468 - }
469 - }
470 -}
471 -
472 -func TestBrace(t *testing.T) {
473 - tests := map[string]string{
474 - "(miek.nl.) 3600 IN A 127.0.1.1": "miek.nl.\t3600\tIN\tA\t127.0.1.1",
475 - "miek.nl. (3600) IN MX (10) elektron.atoom.net.": "miek.nl.\t3600\tIN\tMX\t10 elektron.atoom.net.",
476 - `miek.nl. IN (
477 - 3600 A 127.0.0.1)`: "miek.nl.\t3600\tIN\tA\t127.0.0.1",
478 - "(miek.nl.) (A) (127.0.2.1)": "miek.nl.\t3600\tIN\tA\t127.0.2.1",
479 - "miek.nl A 127.0.3.1": "miek.nl.\t3600\tIN\tA\t127.0.3.1",
480 - "_ssh._tcp.local. 60 IN (PTR) stora._ssh._tcp.local.": "_ssh._tcp.local.\t60\tIN\tPTR\tstora._ssh._tcp.local.",
481 - "miek.nl. NS ns.miek.nl": "miek.nl.\t3600\tIN\tNS\tns.miek.nl.",
482 - `(miek.nl.) (
483 - (IN)
484 - (AAAA)
485 - (::1) )`: "miek.nl.\t3600\tIN\tAAAA\t::1",
486 - `(miek.nl.) (
487 - (IN)
488 - (AAAA)
489 - (::1))`: "miek.nl.\t3600\tIN\tAAAA\t::1",
490 - "miek.nl. IN AAAA ::2": "miek.nl.\t3600\tIN\tAAAA\t::2",
491 - `((m)(i)ek.(n)l.) (SOA) (soa.) (soa.) (
492 - 2009032802 ; serial
493 - 21600 ; refresh (6 hours)
494 - 7(2)00 ; retry (2 hours)
495 - 604()800 ; expire (1 week)
496 - 3600 ; minimum (1 hour)
497 - )`: "miek.nl.\t3600\tIN\tSOA\tsoa. soa. 2009032802 21600 7200 604800 3600",
498 - "miek\\.nl. IN A 127.0.0.10": "miek\\.nl.\t3600\tIN\tA\t127.0.0.10",
499 - "miek.nl. IN A 127.0.0.11": "miek.nl.\t3600\tIN\tA\t127.0.0.11",
500 - "miek.nl. A 127.0.0.12": "miek.nl.\t3600\tIN\tA\t127.0.0.12",
501 - `miek.nl. 86400 IN SOA elektron.atoom.net. miekg.atoom.net. (
502 - 2009032802 ; serial
503 - 21600 ; refresh (6 hours)
504 - 7200 ; retry (2 hours)
505 - 604800 ; expire (1 week)
506 - 3600 ; minimum (1 hour)
507 - )`: "miek.nl.\t86400\tIN\tSOA\telektron.atoom.net. miekg.atoom.net. 2009032802 21600 7200 604800 3600",
508 - }
509 - for i, o := range tests {
510 - rr, err := NewRR(i)
511 - if err != nil {
512 - t.Errorf("failed to parse RR: %v\n\t%s", err, i)
513 - continue
514 - }
515 - if rr.String() != o {
516 - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
517 - } else {
518 - t.Logf("RR is OK: `%s'", rr.String())
519 - }
520 - }
521 -}
522 -
523 -func TestParseFailure(t *testing.T) {
524 - tests := []string{"miek.nl. IN A 327.0.0.1",
525 - "miek.nl. IN AAAA ::x",
526 - "miek.nl. IN MX a0 miek.nl.",
527 - "miek.nl aap IN MX mx.miek.nl.",
528 - "miek.nl 200 IN mxx 10 mx.miek.nl.",
529 - "miek.nl. inn MX 10 mx.miek.nl.",
530 - // "miek.nl. IN CNAME ", // actually valid nowadays, zero size rdata
531 - "miek.nl. IN CNAME ..",
532 - "miek.nl. PA MX 10 miek.nl.",
533 - "miek.nl. ) IN MX 10 miek.nl.",
534 - }
535 -
536 - for _, s := range tests {
537 - _, err := NewRR(s)
538 - if err == nil {
539 - t.Errorf("should have triggered an error: \"%s\"", s)
540 - }
541 - }
542 -}
543 -
544 -func TestZoneParsing(t *testing.T) {
545 - // parse_test.db
546 - db := `
547 -a.example.com. IN A 127.0.0.1
548 -8db7._openpgpkey.example.com. IN OPENPGPKEY mQCNAzIG
549 -$ORIGIN a.example.com.
550 -test IN A 127.0.0.1
551 -$ORIGIN b.example.com.
552 -test IN CNAME test.a.example.com.
553 -`
554 - start := time.Now().UnixNano()
555 - to := ParseZone(strings.NewReader(db), "", "parse_test.db")
556 - var i int
557 - for x := range to {
558 - i++
559 - if x.Error != nil {
560 - t.Error(x.Error)
561 - continue
562 - }
563 - t.Log(x.RR)
564 - }
565 - delta := time.Now().UnixNano() - start
566 - t.Logf("%d RRs parsed in %.2f s (%.2f RR/s)", i, float32(delta)/1e9, float32(i)/(float32(delta)/1e9))
567 -}
568 -
569 -func ExampleZone() {
570 - zone := `$ORIGIN .
571 -$TTL 3600 ; 1 hour
572 -name IN SOA a6.nstld.com. hostmaster.nic.name. (
573 - 203362132 ; serial
574 - 300 ; refresh (5 minutes)
575 - 300 ; retry (5 minutes)
576 - 1209600 ; expire (2 weeks)
577 - 300 ; minimum (5 minutes)
578 - )
579 -$TTL 10800 ; 3 hours
580 -name. 10800 IN NS name.
581 - IN NS g6.nstld.com.
582 - 7200 NS h6.nstld.com.
583 - 3600 IN NS j6.nstld.com.
584 - IN 3600 NS k6.nstld.com.
585 - NS l6.nstld.com.
586 - NS a6.nstld.com.
587 - NS c6.nstld.com.
588 - NS d6.nstld.com.
589 - NS f6.nstld.com.
590 - NS m6.nstld.com.
591 -(
592 - NS m7.nstld.com.
593 -)
594 -$ORIGIN name.
595 -0-0onlus NS ns7.ehiweb.it.
596 - NS ns8.ehiweb.it.
597 -0-g MX 10 mx01.nic
598 - MX 10 mx02.nic
599 - MX 10 mx03.nic
600 - MX 10 mx04.nic
601 -$ORIGIN 0-g.name
602 -moutamassey NS ns01.yahoodomains.jp.
603 - NS ns02.yahoodomains.jp.
604 -`
605 - to := ParseZone(strings.NewReader(zone), "", "testzone")
606 - for x := range to {
607 - fmt.Println(x.RR)
608 - }
609 - // Output:
610 - // name. 3600 IN SOA a6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300
611 - // name. 10800 IN NS name.
612 - // name. 10800 IN NS g6.nstld.com.
613 - // name. 7200 IN NS h6.nstld.com.
614 - // name. 3600 IN NS j6.nstld.com.
615 - // name. 3600 IN NS k6.nstld.com.
616 - // name. 10800 IN NS l6.nstld.com.
617 - // name. 10800 IN NS a6.nstld.com.
618 - // name. 10800 IN NS c6.nstld.com.
619 - // name. 10800 IN NS d6.nstld.com.
620 - // name. 10800 IN NS f6.nstld.com.
621 - // name. 10800 IN NS m6.nstld.com.
622 - // name. 10800 IN NS m7.nstld.com.
623 - // 0-0onlus.name. 10800 IN NS ns7.ehiweb.it.
624 - // 0-0onlus.name. 10800 IN NS ns8.ehiweb.it.
625 - // 0-g.name. 10800 IN MX 10 mx01.nic.name.
626 - // 0-g.name. 10800 IN MX 10 mx02.nic.name.
627 - // 0-g.name. 10800 IN MX 10 mx03.nic.name.
628 - // 0-g.name. 10800 IN MX 10 mx04.nic.name.
629 - // moutamassey.0-g.name.name. 10800 IN NS ns01.yahoodomains.jp.
630 - // moutamassey.0-g.name.name. 10800 IN NS ns02.yahoodomains.jp.
631 -}
632 -
633 -func ExampleHIP() {
634 - h := `www.example.com IN HIP ( 2 200100107B1A74DF365639CC39F1D578
635 - AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
636 -9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
637 -b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
638 - rvs.example.com. )`
639 - if hip, err := NewRR(h); err == nil {
640 - fmt.Println(hip.String())
641 - }
642 - // Output:
643 - // www.example.com. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
644 -}
645 -
646 -func TestHIP(t *testing.T) {
647 - h := `www.example.com. IN HIP ( 2 200100107B1A74DF365639CC39F1D578
648 - AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p
649 -9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ
650 -b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
651 - rvs1.example.com.
652 - rvs2.example.com. )`
653 - rr, err := NewRR(h)
654 - if err != nil {
655 - t.Fatalf("failed to parse RR: %v", err)
656 - }
657 - t.Logf("RR: %s", rr)
658 - msg := new(Msg)
659 - msg.Answer = []RR{rr, rr}
660 - bytes, err := msg.Pack()
661 - if err != nil {
662 - t.Fatalf("failed to pack msg: %v", err)
663 - }
664 - if err := msg.Unpack(bytes); err != nil {
665 - t.Fatalf("failed to unpack msg: %v", err)
666 - }
667 - if len(msg.Answer) != 2 {
668 - t.Fatalf("2 answers expected: %v", msg)
669 - }
670 - for i, rr := range msg.Answer {
671 - rr := rr.(*HIP)
672 - t.Logf("RR: %s", rr)
673 - if l := len(rr.RendezvousServers); l != 2 {
674 - t.Fatalf("2 servers expected, only %d in record %d:\n%v", l, i, msg)
675 - }
676 - for j, s := range []string{"rvs1.example.com.", "rvs2.example.com."} {
677 - if rr.RendezvousServers[j] != s {
678 - t.Fatalf("expected server %d of record %d to be %s:\n%v", j, i, s, msg)
679 - }
680 - }
681 - }
682 -}
683 -
684 -func ExampleSOA() {
685 - s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100"
686 - if soa, err := NewRR(s); err == nil {
687 - fmt.Println(soa.String())
688 - }
689 - // Output:
690 - // example.com. 1000 IN SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100
691 -}
692 -
693 -func TestLineNumberError(t *testing.T) {
694 - s := "example.com. 1000 SOA master.example.com. admin.example.com. monkey 4294967294 4294967293 4294967295 100"
695 - if _, err := NewRR(s); err != nil {
696 - if err.Error() != "dns: bad SOA zone parameter: \"monkey\" at line: 1:68" {
697 - t.Error("not expecting this error: ", err)
698 - }
699 - }
700 -}
701 -
702 -// Test with no known RR on the line
703 -func TestLineNumberError2(t *testing.T) {
704 - tests := map[string]string{
705 - "example.com. 1000 SO master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100": "dns: expecting RR type or class, not this...: \"SO\" at line: 1:21",
706 - "example.com 1000 IN TALINK a.example.com. b..example.com.": "dns: bad TALINK NextName: \"b..example.com.\" at line: 1:57",
707 - "example.com 1000 IN TALINK ( a.example.com. b..example.com. )": "dns: bad TALINK NextName: \"b..example.com.\" at line: 1:60",
708 - `example.com 1000 IN TALINK ( a.example.com.
709 - bb..example.com. )`: "dns: bad TALINK NextName: \"bb..example.com.\" at line: 2:18",
710 - // This is a bug, it should report an error on line 1, but the new is already processed.
711 - `example.com 1000 IN TALINK ( a.example.com. b...example.com.
712 - )`: "dns: bad TALINK NextName: \"b...example.com.\" at line: 2:1"}
713 -
714 - for in, errStr := range tests {
715 - _, err := NewRR(in)
716 - if err == nil {
717 - t.Error("err is nil")
718 - } else {
719 - if err.Error() != errStr {
720 - t.Errorf("%s: error should be %s is %v", in, errStr, err)
721 - }
722 - }
723 - }
724 -}
725 -
726 -// Test if the calculations are correct
727 -func TestRfc1982(t *testing.T) {
728 - // If the current time and the timestamp are more than 68 years apart
729 - // it means the date has wrapped. 0 is 1970
730 -
731 - // fall in the current 68 year span
732 - strtests := []string{"20120525134203", "19700101000000", "20380119031408"}
733 - for _, v := range strtests {
734 - if x, _ := StringToTime(v); v != TimeToString(x) {
735 - t.Errorf("1982 arithmetic string failure %s (%s:%d)", v, TimeToString(x), x)
736 - }
737 - }
738 -
739 - inttests := map[uint32]string{0: "19700101000000",
740 - 1 << 31: "20380119031408",
741 - 1<<32 - 1: "21060207062815",
742 - }
743 - for i, v := range inttests {
744 - if TimeToString(i) != v {
745 - t.Errorf("1982 arithmetic int failure %d:%s (%s)", i, v, TimeToString(i))
746 - }
747 - }
748 -
749 - // Future tests, these dates get parsed to a date within the current 136 year span
750 - future := map[string]string{"22680119031408": "20631123173144",
751 - "19010101121212": "20370206184028",
752 - "19210101121212": "20570206184028",
753 - "19500101121212": "20860206184028",
754 - "19700101000000": "19700101000000",
755 - "19690101000000": "21050207062816",
756 - "29210101121212": "21040522212236",
757 - }
758 - for from, to := range future {
759 - x, _ := StringToTime(from)
760 - y := TimeToString(x)
761 - if y != to {
762 - t.Errorf("1982 arithmetic future failure %s:%s (%s)", from, to, y)
763 - }
764 - }
765 -}
766 -
767 -func TestEmpty(t *testing.T) {
768 - for _ = range ParseZone(strings.NewReader(""), "", "") {
769 - t.Errorf("should be empty")
770 - }
771 -}
772 -
773 -func TestLowercaseTokens(t *testing.T) {
774 - var testrecords = []string{
775 - "example.org. 300 IN a 1.2.3.4",
776 - "example.org. 300 in A 1.2.3.4",
777 - "example.org. 300 in a 1.2.3.4",
778 - "example.org. 300 a 1.2.3.4",
779 - "example.org. 300 A 1.2.3.4",
780 - "example.org. IN a 1.2.3.4",
781 - "example.org. in A 1.2.3.4",
782 - "example.org. in a 1.2.3.4",
783 - "example.org. a 1.2.3.4",
784 - "example.org. A 1.2.3.4",
785 - "example.org. a 1.2.3.4",
786 - "$ORIGIN example.org.\n a 1.2.3.4",
787 - "$Origin example.org.\n a 1.2.3.4",
788 - "$origin example.org.\n a 1.2.3.4",
789 - "example.org. Class1 Type1 1.2.3.4",
790 - }
791 - for _, testrr := range testrecords {
792 - _, err := NewRR(testrr)
793 - if err != nil {
794 - t.Errorf("failed to parse %#v, got %v", testrr, err)
795 - }
796 - }
797 -}
798 -
799 -func ExampleGenerate() {
800 - // From the manual: http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761
801 - zone := "$GENERATE 1-2 0 NS SERVER$.EXAMPLE.\n$GENERATE 1-8 $ CNAME $.0"
802 - to := ParseZone(strings.NewReader(zone), "0.0.192.IN-ADDR.ARPA.", "")
803 - for x := range to {
804 - if x.Error == nil {
805 - fmt.Println(x.RR.String())
806 - }
807 - }
808 - // Output:
809 - // 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER1.EXAMPLE.
810 - // 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER2.EXAMPLE.
811 - // 1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA.
812 - // 2.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 2.0.0.0.192.IN-ADDR.ARPA.
813 - // 3.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 3.0.0.0.192.IN-ADDR.ARPA.
814 - // 4.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 4.0.0.0.192.IN-ADDR.ARPA.
815 - // 5.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 5.0.0.0.192.IN-ADDR.ARPA.
816 - // 6.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 6.0.0.0.192.IN-ADDR.ARPA.
817 - // 7.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 7.0.0.0.192.IN-ADDR.ARPA.
818 - // 8.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 8.0.0.0.192.IN-ADDR.ARPA.
819 -}
820 -
821 -func TestSRVPacking(t *testing.T) {
822 - msg := Msg{}
823 -
824 - things := []string{"1.2.3.4:8484",
825 - "45.45.45.45:8484",
826 - "84.84.84.84:8484",
827 - }
828 -
829 - for i, n := range things {
830 - h, p, err := net.SplitHostPort(n)
831 - if err != nil {
832 - continue
833 - }
834 - port := 8484
835 - tmp, err := strconv.Atoi(p)
836 - if err == nil {
837 - port = tmp
838 - }
839 -
840 - rr := &SRV{
841 - Hdr: RR_Header{Name: "somename.",
842 - Rrtype: TypeSRV,
843 - Class: ClassINET,
844 - Ttl: 5},
845 - Priority: uint16(i),
846 - Weight: 5,
847 - Port: uint16(port),
848 - Target: h + ".",
849 - }
850 -
851 - msg.Answer = append(msg.Answer, rr)
852 - }
853 -
854 - _, err := msg.Pack()
855 - if err != nil {
856 - t.Fatalf("couldn't pack %v: %v", msg, err)
857 - }
858 -}
859 -
860 -func TestParseBackslash(t *testing.T) {
861 - if r, err := NewRR("nul\\000gap.test.globnix.net. 600 IN A 192.0.2.10"); err != nil {
862 - t.Errorf("could not create RR with \\000 in it")
863 - } else {
864 - t.Logf("parsed %s", r.String())
865 - }
866 - if r, err := NewRR(`nul\000gap.test.globnix.net. 600 IN TXT "Hello\123"`); err != nil {
867 - t.Errorf("could not create RR with \\000 in it")
868 - } else {
869 - t.Logf("parsed %s", r.String())
870 - }
871 - if r, err := NewRR(`m\ @\ iek.nl. IN 3600 A 127.0.0.1`); err != nil {
872 - t.Errorf("could not create RR with \\ and \\@ in it")
873 - } else {
874 - t.Logf("parsed %s", r.String())
875 - }
876 -}
877 -
878 -func TestILNP(t *testing.T) {
879 - tests := []string{
880 - "host1.example.com.\t3600\tIN\tNID\t10 0014:4fff:ff20:ee64",
881 - "host1.example.com.\t3600\tIN\tNID\t20 0015:5fff:ff21:ee65",
882 - "host2.example.com.\t3600\tIN\tNID\t10 0016:6fff:ff22:ee66",
883 - "host1.example.com.\t3600\tIN\tL32\t10 10.1.2.0",
884 - "host1.example.com.\t3600\tIN\tL32\t20 10.1.4.0",
885 - "host2.example.com.\t3600\tIN\tL32\t10 10.1.8.0",
886 - "host1.example.com.\t3600\tIN\tL64\t10 2001:0DB8:1140:1000",
887 - "host1.example.com.\t3600\tIN\tL64\t20 2001:0DB8:2140:2000",
888 - "host2.example.com.\t3600\tIN\tL64\t10 2001:0DB8:4140:4000",
889 - "host1.example.com.\t3600\tIN\tLP\t10 l64-subnet1.example.com.",
890 - "host1.example.com.\t3600\tIN\tLP\t10 l64-subnet2.example.com.",
891 - "host1.example.com.\t3600\tIN\tLP\t20 l32-subnet1.example.com.",
892 - }
893 - for _, t1 := range tests {
894 - r, err := NewRR(t1)
895 - if err != nil {
896 - t.Fatalf("an error occurred: %v", err)
897 - } else {
898 - if t1 != r.String() {
899 - t.Fatalf("strings should be equal %s %s", t1, r.String())
900 - }
901 - }
902 - }
903 -}
904 -
905 -func TestNsapGposEidNimloc(t *testing.T) {
906 - dt := map[string]string{
907 - "foo.bar.com. IN NSAP 21 47000580ffff000000321099991111222233334444": "foo.bar.com.\t3600\tIN\tNSAP\t21 47000580ffff000000321099991111222233334444",
908 - "host.school.de IN NSAP 17 39276f3100111100002222333344449876": "host.school.de.\t3600\tIN\tNSAP\t17 39276f3100111100002222333344449876",
909 - "444433332222111199990123000000ff. NSAP-PTR foo.bar.com.": "444433332222111199990123000000ff.\t3600\tIN\tNSAP-PTR\tfoo.bar.com.",
910 - "lillee. IN GPOS -32.6882 116.8652 10.0": "lillee.\t3600\tIN\tGPOS\t-32.6882 116.8652 10.0",
911 - "hinault. IN GPOS -22.6882 116.8652 250.0": "hinault.\t3600\tIN\tGPOS\t-22.6882 116.8652 250.0",
912 - "VENERA. IN NIMLOC 75234159EAC457800920": "VENERA.\t3600\tIN\tNIMLOC\t75234159EAC457800920",
913 - "VAXA. IN EID 3141592653589793": "VAXA.\t3600\tIN\tEID\t3141592653589793",
914 - }
915 - for i, o := range dt {
916 - rr, err := NewRR(i)
917 - if err != nil {
918 - t.Error("failed to parse RR: ", err)
919 - continue
920 - }
921 - if rr.String() != o {
922 - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
923 - } else {
924 - t.Logf("RR is OK: `%s'", rr.String())
925 - }
926 - }
927 -}
928 -
929 -func TestPX(t *testing.T) {
930 - dt := map[string]string{
931 - "*.net2.it. IN PX 10 net2.it. PRMD-net2.ADMD-p400.C-it.": "*.net2.it.\t3600\tIN\tPX\t10 net2.it. PRMD-net2.ADMD-p400.C-it.",
932 - "ab.net2.it. IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.": "ab.net2.it.\t3600\tIN\tPX\t10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.",
933 - }
934 - for i, o := range dt {
935 - rr, err := NewRR(i)
936 - if err != nil {
937 - t.Error("failed to parse RR: ", err)
938 - continue
939 - }
940 - if rr.String() != o {
941 - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String())
942 - } else {
943 - t.Logf("RR is OK: `%s'", rr.String())
944 - }
945 - }
946 -}
947 -
948 -func TestComment(t *testing.T) {
949 - // Comments we must see
950 - comments := map[string]bool{"; this is comment 1": true,
951 - "; this is comment 4": true, "; this is comment 6": true,
952 - "; this is comment 7": true, "; this is comment 8": true}
953 - zone := `
954 -foo. IN A 10.0.0.1 ; this is comment 1
955 -foo. IN A (
956 - 10.0.0.2 ; this is comment2
957 -)
958 -; this is comment3
959 -foo. IN A 10.0.0.3
960 -foo. IN A ( 10.0.0.4 ); this is comment 4
961 -
962 -foo. IN A 10.0.0.5
963 -; this is comment5
964 -
965 -foo. IN A 10.0.0.6
966 -
967 -foo. IN DNSKEY 256 3 5 AwEAAb+8l ; this is comment 6
968 -foo. IN NSEC miek.nl. TXT RRSIG NSEC; this is comment 7
969 -foo. IN TXT "THIS IS TEXT MAN"; this is comment 8
970 -`
971 - for x := range ParseZone(strings.NewReader(zone), ".", "") {
972 - if x.Error == nil {
973 - if x.Comment != "" {
974 - if _, ok := comments[x.Comment]; !ok {
975 - t.Errorf("wrong comment %s", x.Comment)
976 - }
977 - }
978 - }
979 - }
980 -}
981 -
982 -func TestEUIxx(t *testing.T) {
983 - tests := map[string]string{
984 - "host.example. IN EUI48 00-00-5e-90-01-2a": "host.example.\t3600\tIN\tEUI48\t00-00-5e-90-01-2a",
985 - "host.example. IN EUI64 00-00-5e-ef-00-00-00-2a": "host.example.\t3600\tIN\tEUI64\t00-00-5e-ef-00-00-00-2a",
986 - }
987 - for i, o := range tests {
988 - r, err := NewRR(i)
989 - if err != nil {
990 - t.Errorf("failed to parse %s: %v", i, err)
991 - }
992 - if r.String() != o {
993 - t.Errorf("want %s, got %s", o, r.String())
994 - }
995 - }
996 -}
997 -
998 -func TestUserRR(t *testing.T) {
999 - tests := map[string]string{
1000 - "host.example. IN UID 1234": "host.example.\t3600\tIN\tUID\t1234",
1001 - "host.example. IN GID 1234556": "host.example.\t3600\tIN\tGID\t1234556",
1002 - "host.example. IN UINFO \"Miek Gieben\"": "host.example.\t3600\tIN\tUINFO\t\"Miek Gieben\"",
1003 - }
1004 - for i, o := range tests {
1005 - r, err := NewRR(i)
1006 - if err != nil {
1007 - t.Errorf("failed to parse %s: %v", i, err)
1008 - }
1009 - if r.String() != o {
1010 - t.Errorf("want %s, got %s", o, r.String())
1011 - }
1012 - }
1013 -}
1014 -
1015 -func TestTXT(t *testing.T) {
1016 - // Test single entry TXT record
1017 - rr, err := NewRR(`_raop._tcp.local. 60 IN TXT "single value"`)
1018 - if err != nil {
1019 - t.Error("failed to parse single value TXT record", err)
1020 - } else if rr, ok := rr.(*TXT); !ok {
1021 - t.Error("wrong type, record should be of type TXT")
1022 - } else {
1023 - if len(rr.Txt) != 1 {
1024 - t.Error("bad size of TXT value:", len(rr.Txt))
1025 - } else if rr.Txt[0] != "single value" {
1026 - t.Error("bad single value")
1027 - }
1028 - if rr.String() != `_raop._tcp.local. 60 IN TXT "single value"` {
1029 - t.Error("bad representation of TXT record:", rr.String())
1030 - }
1031 - if rr.len() != 28+1+12 {
1032 - t.Error("bad size of serialized record:", rr.len())
1033 - }
1034 - }
1035 -
1036 - // Test multi entries TXT record
1037 - rr, err = NewRR(`_raop._tcp.local. 60 IN TXT "a=1" "b=2" "c=3" "d=4"`)
1038 - if err != nil {
1039 - t.Error("failed to parse multi-values TXT record", err)
1040 - } else if rr, ok := rr.(*TXT); !ok {
1041 - t.Error("wrong type, record should be of type TXT")
1042 - } else {
1043 - if len(rr.Txt) != 4 {
1044 - t.Error("bad size of TXT multi-value:", len(rr.Txt))
1045 - } else if rr.Txt[0] != "a=1" || rr.Txt[1] != "b=2" || rr.Txt[2] != "c=3" || rr.Txt[3] != "d=4" {
1046 - t.Error("bad values in TXT records")
1047 - }
1048 - if rr.String() != `_raop._tcp.local. 60 IN TXT "a=1" "b=2" "c=3" "d=4"` {
1049 - t.Error("bad representation of TXT multi value record:", rr.String())
1050 - }
1051 - if rr.len() != 28+1+3+1+3+1+3+1+3 {
1052 - t.Error("bad size of serialized multi value record:", rr.len())
1053 - }
1054 - }
1055 -
1056 - // Test empty-string in TXT record
1057 - rr, err = NewRR(`_raop._tcp.local. 60 IN TXT ""`)
1058 - if err != nil {
1059 - t.Error("failed to parse empty-string TXT record", err)
1060 - } else if rr, ok := rr.(*TXT); !ok {
1061 - t.Error("wrong type, record should be of type TXT")
1062 - } else {
1063 - if len(rr.Txt) != 1 {
1064 - t.Error("bad size of TXT empty-string value:", len(rr.Txt))
1065 - } else if rr.Txt[0] != "" {
1066 - t.Error("bad value for empty-string TXT record")
1067 - }
1068 - if rr.String() != `_raop._tcp.local. 60 IN TXT ""` {
1069 - t.Error("bad representation of empty-string TXT record:", rr.String())
1070 - }
1071 - if rr.len() != 28+1 {
1072 - t.Error("bad size of serialized record:", rr.len())
1073 - }
1074 - }
1075 -
1076 - // Test TXT record with chunk larger than 255 bytes, they should be split up, by the parser
1077 - s := ""
1078 - for i := 0; i < 255; i++ {
1079 - s += "a"
1080 - }
1081 - s += "b"
1082 - rr, err = NewRR(`test.local. 60 IN TXT "` + s + `"`)
1083 - if err != nil {
1084 - t.Error("failed to parse empty-string TXT record", err)
1085 - }
1086 - if rr.(*TXT).Txt[1] != "b" {
1087 - t.Errorf("Txt should have two chunk, last one my be 'b', but is %s", rr.(*TXT).Txt[1])
1088 - }
1089 - t.Log(rr.String())
1090 -}
1091 -
1092 -func TestTypeXXXX(t *testing.T) {
1093 - _, err := NewRR("example.com IN TYPE1234 \\# 4 aabbccdd")
1094 - if err != nil {
1095 - t.Errorf("failed to parse TYPE1234 RR: %v", err)
1096 - }
1097 - _, err = NewRR("example.com IN TYPE655341 \\# 8 aabbccddaabbccdd")
1098 - if err == nil {
1099 - t.Errorf("this should not work, for TYPE655341")
1100 - }
1101 - _, err = NewRR("example.com IN TYPE1 \\# 4 0a000001")
1102 - if err == nil {
1103 - t.Errorf("this should not work")
1104 - }
1105 -}
1106 -
1107 -func TestPTR(t *testing.T) {
1108 - _, err := NewRR("144.2.0.192.in-addr.arpa. 900 IN PTR ilouse03146p0\\(.example.com.")
1109 - if err != nil {
1110 - t.Error("failed to parse ", err)
1111 - }
1112 -}
1113 -
1114 -func TestDigit(t *testing.T) {
1115 - tests := map[string]byte{
1116 - "miek\\000.nl. 100 IN TXT \"A\"": 0,
1117 - "miek\\001.nl. 100 IN TXT \"A\"": 1,
1118 - "miek\\254.nl. 100 IN TXT \"A\"": 254,
1119 - "miek\\255.nl. 100 IN TXT \"A\"": 255,
1120 - "miek\\256.nl. 100 IN TXT \"A\"": 0,
1121 - "miek\\257.nl. 100 IN TXT \"A\"": 1,
1122 - "miek\\004.nl. 100 IN TXT \"A\"": 4,
1123 - }
1124 - for s, i := range tests {
1125 - r, err := NewRR(s)
1126 - buf := make([]byte, 40)
1127 - if err != nil {
1128 - t.Fatalf("failed to parse %v", err)
1129 - }
1130 - PackRR(r, buf, 0, nil, false)
1131 - t.Log(buf)
1132 - if buf[5] != i {
1133 - t.Fatalf("5 pos must be %d, is %d", i, buf[5])
1134 - }
1135 - r1, _, _ := UnpackRR(buf, 0)
1136 - if r1.Header().Ttl != 100 {
1137 - t.Fatalf("TTL should %d, is %d", 100, r1.Header().Ttl)
1138 - }
1139 - }
1140 -}
1141 -
1142 -func TestParseRRSIGTimestamp(t *testing.T) {
1143 - tests := map[string]bool{
1144 - `miek.nl. IN RRSIG SOA 8 2 43200 20140210031301 20140111031301 12051 miek.nl. MVZUyrYwq0iZhMFDDnVXD2BvuNiUJjSYlJAgzyAE6CF875BMvvZa+Sb0 RlSCL7WODQSQHhCx/fegHhVVF+Iz8N8kOLrmXD1+jO3Bm6Prl5UhcsPx WTBsg/kmxbp8sR1kvH4oZJtVfakG3iDerrxNaf0sQwhZzyfJQAqpC7pcBoc=`: true,
1145 - `miek.nl. IN RRSIG SOA 8 2 43200 315565800 4102477800 12051 miek.nl. MVZUyrYwq0iZhMFDDnVXD2BvuNiUJjSYlJAgzyAE6CF875BMvvZa+Sb0 RlSCL7WODQSQHhCx/fegHhVVF+Iz8N8kOLrmXD1+jO3Bm6Prl5UhcsPx WTBsg/kmxbp8sR1kvH4oZJtVfakG3iDerrxNaf0sQwhZzyfJQAqpC7pcBoc=`: true,
1146 - }
1147 - for r := range tests {
1148 - _, err := NewRR(r)
1149 - if err != nil {
1150 - t.Error(err)
1151 - }
1152 - }
1153 -}
1154 -
1155 -func TestTxtEqual(t *testing.T) {
1156 - rr1 := new(TXT)
1157 - rr1.Hdr = RR_Header{Name: ".", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
1158 - rr1.Txt = []string{"a\"a", "\"", "b"}
1159 - rr2, _ := NewRR(rr1.String())
1160 - if rr1.String() != rr2.String() {
1161 - // This is not an error, but keep this test.
1162 - t.Errorf("these two TXT records should match:\n%s\n%s", rr1.String(), rr2.String())
1163 - }
1164 - t.Logf("%s\n%s", rr1.String(), rr2.String())
1165 -}
1166 -
1167 -func TestTxtLong(t *testing.T) {
1168 - rr1 := new(TXT)
1169 - rr1.Hdr = RR_Header{Name: ".", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
1170 - // Make a long txt record, this breaks when sending the packet,
1171 - // but not earlier.
1172 - rr1.Txt = []string{"start-"}
1173 - for i := 0; i < 200; i++ {
1174 - rr1.Txt[0] += "start-"
1175 - }
1176 - str := rr1.String()
1177 - if len(str) < len(rr1.Txt[0]) {
1178 - t.Error("string conversion should work")
1179 - }
1180 -}
1181 -
1182 -// Basically, don't crash.
1183 -func TestMalformedPackets(t *testing.T) {
1184 - var packets = []string{
1185 - "0021641c0000000100000000000078787878787878787878787303636f6d0000100001",
1186 - }
1187 -
1188 - // com = 63 6f 6d
1189 - for _, packet := range packets {
1190 - data, _ := hex.DecodeString(packet)
1191 - // for _, v := range data {
1192 - // t.Log(v)
1193 - // }
1194 - var msg Msg
1195 - msg.Unpack(data)
1196 - // println(msg.String())
1197 - }
1198 -}
1199 -
1200 -type algorithm struct {
1201 - name uint8
1202 - bits int
1203 -}
1204 -
1205 -func TestNewPrivateKey(t *testing.T) {
1206 - if testing.Short() {
1207 - t.Skip("skipping test in short mode.")
1208 - }
1209 - algorithms := []algorithm{
1210 - algorithm{ECDSAP256SHA256, 256},
1211 - algorithm{ECDSAP384SHA384, 384},
1212 - algorithm{RSASHA1, 1024},
1213 - algorithm{RSASHA256, 2048},
1214 - algorithm{DSA, 1024},
1215 - }
1216 -
1217 - for _, algo := range algorithms {
1218 - key := new(DNSKEY)
1219 - key.Hdr.Rrtype = TypeDNSKEY
1220 - key.Hdr.Name = "miek.nl."
1221 - key.Hdr.Class = ClassINET
1222 - key.Hdr.Ttl = 14400
1223 - key.Flags = 256
1224 - key.Protocol = 3
1225 - key.Algorithm = algo.name
1226 - privkey, err := key.Generate(algo.bits)
1227 - if err != nil {
1228 - t.Fatal(err)
1229 - }
1230 -
1231 - newPrivKey, err := key.NewPrivateKey(key.PrivateKeyString(privkey))
1232 - if err != nil {
1233 - t.Error(key.String())
1234 - t.Error(key.PrivateKeyString(privkey))
1235 - t.Fatal(err)
1236 - }
1237 -
1238 - switch newPrivKey := newPrivKey.(type) {
1239 - case *RSAPrivateKey:
1240 - (*rsa.PrivateKey)(newPrivKey).Precompute()
1241 - }
1242 -
1243 - if !reflect.DeepEqual(privkey, newPrivKey) {
1244 - t.Errorf("[%v] Private keys differ:\n%#v\n%#v", AlgorithmToString[algo.name], privkey, newPrivKey)
1245 - }
1246 - }
1247 -}
1248 -
1249 -// special input test
1250 -func TestNewRRSpecial(t *testing.T) {
1251 - var (
1252 - rr RR
1253 - err error
1254 - expect string
1255 - )
1256 -
1257 - rr, err = NewRR("; comment")
1258 - expect = ""
1259 - if err != nil {
1260 - t.Errorf("unexpected err: %v", err)
1261 - }
1262 - if rr != nil {
1263 - t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
1264 - }
1265 -
1266 - rr, err = NewRR("")
1267 - expect = ""
1268 - if err != nil {
1269 - t.Errorf("unexpected err: %v", err)
1270 - }
1271 - if rr != nil {
1272 - t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
1273 - }
1274 -
1275 - rr, err = NewRR("$ORIGIN foo.")
1276 - expect = ""
1277 - if err != nil {
1278 - t.Errorf("unexpected err: %v", err)
1279 - }
1280 - if rr != nil {
1281 - t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
1282 - }
1283 -
1284 - rr, err = NewRR(" ")
1285 - expect = ""
1286 - if err != nil {
1287 - t.Errorf("unexpected err: %v", err)
1288 - }
1289 - if rr != nil {
1290 - t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
1291 - }
1292 -
1293 - rr, err = NewRR("\n")
1294 - expect = ""
1295 - if err != nil {
1296 - t.Errorf("unexpected err: %v", err)
1297 - }
1298 - if rr != nil {
1299 - t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
1300 - }
1301 -
1302 - rr, err = NewRR("foo. A 1.1.1.1\nbar. A 2.2.2.2")
1303 - expect = "foo.\t3600\tIN\tA\t1.1.1.1"
1304 - if err != nil {
1305 - t.Errorf("unexpected err: %v", err)
1306 - }
1307 - if rr == nil || rr.String() != expect {
1308 - t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
1309 - }
1310 -}
1311 -
1312 -func TestPrintfVerbsRdata(t *testing.T) {
1313 - x, _ := NewRR("www.miek.nl. IN MX 20 mx.miek.nl.")
1314 - if Field(x, 1) != "20" {
1315 - t.Errorf("should be 20")
1316 - }
1317 - if Field(x, 2) != "mx.miek.nl." {
1318 - t.Errorf("should be mx.miek.nl.")
1319 - }
1320 -
1321 - x, _ = NewRR("www.miek.nl. IN A 127.0.0.1")
1322 - if Field(x, 1) != "127.0.0.1" {
1323 - t.Errorf("should be 127.0.0.1")
1324 - }
1325 -
1326 - x, _ = NewRR("www.miek.nl. IN AAAA ::1")
1327 - if Field(x, 1) != "::1" {
1328 - t.Errorf("should be ::1")
1329 - }
1330 -
1331 - x, _ = NewRR("www.miek.nl. IN NSEC a.miek.nl. A NS SOA MX AAAA")
1332 - if Field(x, 1) != "a.miek.nl." {
1333 - t.Errorf("should be a.miek.nl.")
1334 - }
1335 - if Field(x, 2) != "A NS SOA MX AAAA" {
1336 - t.Errorf("should be A NS SOA MX AAAA")
1337 - }
1338 -
1339 - x, _ = NewRR("www.miek.nl. IN TXT \"first\" \"second\"")
1340 - if Field(x, 1) != "first second" {
1341 - t.Errorf("should be first second")
1342 - }
1343 - if Field(x, 0) != "" {
1344 - t.Errorf("should be empty")
1345 - }
1346 -}
1347 -
1348 -func TestParseIPSECKEY(t *testing.T) {
1349 - tests := []string{
1350 - "38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
1351 - "38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
1352 -
1353 - "38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
1354 - "38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
1355 -
1356 - "38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
1357 - "38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
1358 -
1359 - "38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
1360 - "38.1.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
1361 -
1362 - "0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
1363 - "0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.\t7200\tIN\tIPSECKEY\t10 2 2 2001:db8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
1364 - }
1365 - for i := 0; i < len(tests)-1; i++ {
1366 - t1 := tests[i]
1367 - e1 := tests[i+1]
1368 - r, err := NewRR(t1)
1369 - if err != nil {
1370 - t.Errorf("failed to parse IPSECKEY %v", err)
1371 - continue
1372 - }
1373 - if r.String() != e1 {
1374 - t.Errorf("these two IPSECKEY records should match:\n%s\n%s", r.String(), e1)
1375 - }
1376 - i++
1377 - }
1378 -}
Godeps/_workspace/src/github.com/miekg/dns/privaterr.go deleted
-115
@@ -1,115 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "fmt"
5 - "strings"
6 -)
7 -
8 -// PrivateRdata is an interface used for implementing "Private Use" RR types, see
9 -// RFC 6895. This allows one to experiment with new RR types, without requesting an
10 -// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
11 -type PrivateRdata interface {
12 - // String returns the text presentaton of the Rdata of the Private RR.
13 - String() string
14 - // Parse parses the Rdata of the private RR.
15 - Parse([]string) error
16 - // Pack is used when packing a private RR into a buffer.
17 - Pack([]byte) (int, error)
18 - // Unpack is used when unpacking a private RR from a buffer.
19 - // TODO(miek): diff. signature than Pack, see edns0.go for instance.
20 - Unpack([]byte) (int, error)
21 - // Copy copies the Rdata.
22 - Copy(PrivateRdata) error
23 - // Len returns the length in octets of the Rdata.
24 - Len() int
25 -}
26 -
27 -// PrivateRR represents an RR that uses a PrivateRdata user-defined type.
28 -// It mocks normal RRs and implements dns.RR interface.
29 -type PrivateRR struct {
30 - Hdr RR_Header
31 - Data PrivateRdata
32 -}
33 -
34 -func mkPrivateRR(rrtype uint16) *PrivateRR {
35 - // Panics if RR is not an instance of PrivateRR.
36 - rrfunc, ok := typeToRR[rrtype]
37 - if !ok {
38 - panic(fmt.Sprintf("dns: invalid operation with Private RR type %d", rrtype))
39 - }
40 -
41 - anyrr := rrfunc()
42 - switch rr := anyrr.(type) {
43 - case *PrivateRR:
44 - return rr
45 - }
46 - panic(fmt.Sprintf("dns: RR is not a PrivateRR, typeToRR[%d] generator returned %T", rrtype, anyrr))
47 -}
48 -
49 -func (r *PrivateRR) Header() *RR_Header { return &r.Hdr }
50 -func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() }
51 -
52 -// Private len and copy parts to satisfy RR interface.
53 -func (r *PrivateRR) len() int { return r.Hdr.len() + r.Data.Len() }
54 -func (r *PrivateRR) copy() RR {
55 - // make new RR like this:
56 - rr := mkPrivateRR(r.Hdr.Rrtype)
57 - newh := r.Hdr.copyHeader()
58 - rr.Hdr = *newh
59 -
60 - err := r.Data.Copy(rr.Data)
61 - if err != nil {
62 - panic("dns: got value that could not be used to copy Private rdata")
63 - }
64 - return rr
65 -}
66 -
67 -// PrivateHandle registers a private resource record type. It requires
68 -// string and numeric representation of private RR type and generator function as argument.
69 -func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) {
70 - rtypestr = strings.ToUpper(rtypestr)
71 -
72 - typeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator()} }
73 - TypeToString[rtype] = rtypestr
74 - StringToType[rtypestr] = rtype
75 -
76 - setPrivateRR := func(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
77 - rr := mkPrivateRR(h.Rrtype)
78 - rr.Hdr = h
79 -
80 - var l lex
81 - text := make([]string, 0, 2) // could be 0..N elements, median is probably 1
82 - FETCH:
83 - for {
84 - // TODO(miek): we could also be returning _QUOTE, this might or might not
85 - // be an issue (basically parsing TXT becomes hard)
86 - switch l = <-c; l.value {
87 - case zNewline, zEOF:
88 - break FETCH
89 - case zString:
90 - text = append(text, l.token)
91 - }
92 - }
93 -
94 - err := rr.Data.Parse(text)
95 - if err != nil {
96 - return nil, &ParseError{f, err.Error(), l}, ""
97 - }
98 -
99 - return rr, nil, ""
100 - }
101 -
102 - typeToparserFunc[rtype] = parserFunc{setPrivateRR, true}
103 -}
104 -
105 -// PrivateHandleRemove removes defenitions required to support private RR type.
106 -func PrivateHandleRemove(rtype uint16) {
107 - rtypestr, ok := TypeToString[rtype]
108 - if ok {
109 - delete(typeToRR, rtype)
110 - delete(TypeToString, rtype)
111 - delete(typeToparserFunc, rtype)
112 - delete(StringToType, rtypestr)
113 - }
114 - return
115 -}
Godeps/_workspace/src/github.com/miekg/dns/privaterr_test.go deleted
-170
@@ -1,170 +0,0 @@
1 -package dns_test
2 -
3 -import (
4 - "strings"
5 - "testing"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/miekg/dns"
8 -)
9 -
10 -const TypeISBN uint16 = 0x0F01
11 -
12 -// A crazy new RR type :)
13 -type ISBN struct {
14 - x string // rdata with 10 or 13 numbers, dashes or spaces allowed
15 -}
16 -
17 -func NewISBN() dns.PrivateRdata { return &ISBN{""} }
18 -
19 -func (rd *ISBN) Len() int { return len([]byte(rd.x)) }
20 -func (rd *ISBN) String() string { return rd.x }
21 -
22 -func (rd *ISBN) Parse(txt []string) error {
23 - rd.x = strings.TrimSpace(strings.Join(txt, " "))
24 - return nil
25 -}
26 -
27 -func (rd *ISBN) Pack(buf []byte) (int, error) {
28 - b := []byte(rd.x)
29 - n := copy(buf, b)
30 - if n != len(b) {
31 - return n, dns.ErrBuf
32 - }
33 - return n, nil
34 -}
35 -
36 -func (rd *ISBN) Unpack(buf []byte) (int, error) {
37 - rd.x = string(buf)
38 - return len(buf), nil
39 -}
40 -
41 -func (rd *ISBN) Copy(dest dns.PrivateRdata) error {
42 - isbn, ok := dest.(*ISBN)
43 - if !ok {
44 - return dns.ErrRdata
45 - }
46 - isbn.x = rd.x
47 - return nil
48 -}
49 -
50 -var testrecord = strings.Join([]string{"example.org.", "3600", "IN", "ISBN", "12-3 456789-0-123"}, "\t")
51 -
52 -func TestPrivateText(t *testing.T) {
53 - dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
54 - defer dns.PrivateHandleRemove(TypeISBN)
55 -
56 - rr, err := dns.NewRR(testrecord)
57 - if err != nil {
58 - t.Fatal(err)
59 - }
60 - if rr.String() != testrecord {
61 - t.Errorf("record string representation did not match original %#v != %#v", rr.String(), testrecord)
62 - } else {
63 - t.Log(rr.String())
64 - }
65 -}
66 -
67 -func TestPrivateByteSlice(t *testing.T) {
68 - dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
69 - defer dns.PrivateHandleRemove(TypeISBN)
70 -
71 - rr, err := dns.NewRR(testrecord)
72 - if err != nil {
73 - t.Fatal(err)
74 - }
75 -
76 - buf := make([]byte, 100)
77 - off, err := dns.PackRR(rr, buf, 0, nil, false)
78 - if err != nil {
79 - t.Errorf("got error packing ISBN: %v", err)
80 - }
81 -
82 - custrr := rr.(*dns.PrivateRR)
83 - if ln := custrr.Data.Len() + len(custrr.Header().Name) + 11; ln != off {
84 - t.Errorf("offset is not matching to length of Private RR: %d!=%d", off, ln)
85 - }
86 -
87 - rr1, off1, err := dns.UnpackRR(buf[:off], 0)
88 - if err != nil {
89 - t.Errorf("got error unpacking ISBN: %v", err)
90 - }
91 -
92 - if off1 != off {
93 - t.Errorf("Offset after unpacking differs: %d != %d", off1, off)
94 - }
95 -
96 - if rr1.String() != testrecord {
97 - t.Errorf("Record string representation did not match original %#v != %#v", rr1.String(), testrecord)
98 - } else {
99 - t.Log(rr1.String())
100 - }
101 -}
102 -
103 -const TypeVERSION uint16 = 0x0F02
104 -
105 -type VERSION struct {
106 - x string
107 -}
108 -
109 -func NewVersion() dns.PrivateRdata { return &VERSION{""} }
110 -
111 -func (rd *VERSION) String() string { return rd.x }
112 -func (rd *VERSION) Parse(txt []string) error {
113 - rd.x = strings.TrimSpace(strings.Join(txt, " "))
114 - return nil
115 -}
116 -
117 -func (rd *VERSION) Pack(buf []byte) (int, error) {
118 - b := []byte(rd.x)
119 - n := copy(buf, b)
120 - if n != len(b) {
121 - return n, dns.ErrBuf
122 - }
123 - return n, nil
124 -}
125 -
126 -func (rd *VERSION) Unpack(buf []byte) (int, error) {
127 - rd.x = string(buf)
128 - return len(buf), nil
129 -}
130 -
131 -func (rd *VERSION) Copy(dest dns.PrivateRdata) error {
132 - isbn, ok := dest.(*VERSION)
133 - if !ok {
134 - return dns.ErrRdata
135 - }
136 - isbn.x = rd.x
137 - return nil
138 -}
139 -
140 -func (rd *VERSION) Len() int {
141 - return len([]byte(rd.x))
142 -}
143 -
144 -var smallzone = `$ORIGIN example.org.
145 -@ SOA sns.dns.icann.org. noc.dns.icann.org. (
146 - 2014091518 7200 3600 1209600 3600
147 -)
148 - A 1.2.3.4
149 -ok ISBN 1231-92110-12
150 -go VERSION (
151 - 1.3.1 ; comment
152 -)
153 -www ISBN 1231-92110-16
154 -* CNAME @
155 -`
156 -
157 -func TestPrivateZoneParser(t *testing.T) {
158 - dns.PrivateHandle("ISBN", TypeISBN, NewISBN)
159 - dns.PrivateHandle("VERSION", TypeVERSION, NewVersion)
160 - defer dns.PrivateHandleRemove(TypeISBN)
161 - defer dns.PrivateHandleRemove(TypeVERSION)
162 -
163 - r := strings.NewReader(smallzone)
164 - for x := range dns.ParseZone(r, ".", "") {
165 - if err := x.Error; err != nil {
166 - t.Fatal(err)
167 - }
168 - t.Log(x.RR)
169 - }
170 -}
Godeps/_workspace/src/github.com/miekg/dns/rawmsg.go deleted
-95
@@ -1,95 +0,0 @@
1 -package dns
2 -
3 -// These raw* functions do not use reflection, they directly set the values
4 -// in the buffer. There are faster than their reflection counterparts.
5 -
6 -// RawSetId sets the message id in buf.
7 -func rawSetId(msg []byte, i uint16) bool {
8 - if len(msg) < 2 {
9 - return false
10 - }
11 - msg[0], msg[1] = packUint16(i)
12 - return true
13 -}
14 -
15 -// rawSetQuestionLen sets the length of the question section.
16 -func rawSetQuestionLen(msg []byte, i uint16) bool {
17 - if len(msg) < 6 {
18 - return false
19 - }
20 - msg[4], msg[5] = packUint16(i)
21 - return true
22 -}
23 -
24 -// rawSetAnswerLen sets the lenght of the answer section.
25 -func rawSetAnswerLen(msg []byte, i uint16) bool {
26 - if len(msg) < 8 {
27 - return false
28 - }
29 - msg[6], msg[7] = packUint16(i)
30 - return true
31 -}
32 -
33 -// rawSetsNsLen sets the lenght of the authority section.
34 -func rawSetNsLen(msg []byte, i uint16) bool {
35 - if len(msg) < 10 {
36 - return false
37 - }
38 - msg[8], msg[9] = packUint16(i)
39 - return true
40 -}
41 -
42 -// rawSetExtraLen sets the lenght of the additional section.
43 -func rawSetExtraLen(msg []byte, i uint16) bool {
44 - if len(msg) < 12 {
45 - return false
46 - }
47 - msg[10], msg[11] = packUint16(i)
48 - return true
49 -}
50 -
51 -// rawSetRdlength sets the rdlength in the header of
52 -// the RR. The offset 'off' must be positioned at the
53 -// start of the header of the RR, 'end' must be the
54 -// end of the RR.
55 -func rawSetRdlength(msg []byte, off, end int) bool {
56 - l := len(msg)
57 -Loop:
58 - for {
59 - if off+1 > l {
60 - return false
61 - }
62 - c := int(msg[off])
63 - off++
64 - switch c & 0xC0 {
65 - case 0x00:
66 - if c == 0x00 {
67 - // End of the domainname
68 - break Loop
69 - }
70 - if off+c > l {
71 - return false
72 - }
73 - off += c
74 -
75 - case 0xC0:
76 - // pointer, next byte included, ends domainname
77 - off++
78 - break Loop
79 - }
80 - }
81 - // The domainname has been seen, we at the start of the fixed part in the header.
82 - // Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length.
83 - off += 2 + 2 + 4
84 - if off+2 > l {
85 - return false
86 - }
87 - //off+1 is the end of the header, 'end' is the end of the rr
88 - //so 'end' - 'off+2' is the length of the rdata
89 - rdatalen := end - (off + 2)
90 - if rdatalen > 0xFFFF {
91 - return false
92 - }
93 - msg[off], msg[off+1] = packUint16(uint16(rdatalen))
94 - return true
95 -}
Godeps/_workspace/src/github.com/miekg/dns/scanner.go deleted
-43
@@ -1,43 +0,0 @@
1 -package dns
2 -
3 -// Implement a simple scanner, return a byte stream from an io reader.
4 -
5 -import (
6 - "bufio"
7 - "io"
8 - "text/scanner"
9 -)
10 -
11 -type scan struct {
12 - src *bufio.Reader
13 - position scanner.Position
14 - eof bool // Have we just seen a eof
15 -}
16 -
17 -func scanInit(r io.Reader) *scan {
18 - s := new(scan)
19 - s.src = bufio.NewReader(r)
20 - s.position.Line = 1
21 - return s
22 -}
23 -
24 -// tokenText returns the next byte from the input
25 -func (s *scan) tokenText() (byte, error) {
26 - c, err := s.src.ReadByte()
27 - if err != nil {
28 - return c, err
29 - }
30 - // delay the newline handling until the next token is delivered,
31 - // fixes off-by-one errors when reporting a parse error.
32 - if s.eof == true {
33 - s.position.Line++
34 - s.position.Column = 0
35 - s.eof = false
36 - }
37 - if c == '\n' {
38 - s.eof = true
39 - return c, nil
40 - }
41 - s.position.Column++
42 - return c, nil
43 -}
Godeps/_workspace/src/github.com/miekg/dns/server.go deleted
-630
@@ -1,630 +0,0 @@
1 -// DNS server implementation.
2 -
3 -package dns
4 -
5 -import (
6 - "bytes"
7 - "io"
8 - "net"
9 - "sync"
10 - "time"
11 -)
12 -
13 -// Handler is implemented by any value that implements ServeDNS.
14 -type Handler interface {
15 - ServeDNS(w ResponseWriter, r *Msg)
16 -}
17 -
18 -// A ResponseWriter interface is used by an DNS handler to
19 -// construct an DNS response.
20 -type ResponseWriter interface {
21 - // LocalAddr returns the net.Addr of the server
22 - LocalAddr() net.Addr
23 - // RemoteAddr returns the net.Addr of the client that sent the current request.
24 - RemoteAddr() net.Addr
25 - // WriteMsg writes a reply back to the client.
26 - WriteMsg(*Msg) error
27 - // Write writes a raw buffer back to the client.
28 - Write([]byte) (int, error)
29 - // Close closes the connection.
30 - Close() error
31 - // TsigStatus returns the status of the Tsig.
32 - TsigStatus() error
33 - // TsigTimersOnly sets the tsig timers only boolean.
34 - TsigTimersOnly(bool)
35 - // Hijack lets the caller take over the connection.
36 - // After a call to Hijack(), the DNS package will not do anything with the connection.
37 - Hijack()
38 -}
39 -
40 -type response struct {
41 - hijacked bool // connection has been hijacked by handler
42 - tsigStatus error
43 - tsigTimersOnly bool
44 - tsigRequestMAC string
45 - tsigSecret map[string]string // the tsig secrets
46 - udp *net.UDPConn // i/o connection if UDP was used
47 - tcp *net.TCPConn // i/o connection if TCP was used
48 - udpSession *SessionUDP // oob data to get egress interface right
49 - remoteAddr net.Addr // address of the client
50 -}
51 -
52 -// ServeMux is an DNS request multiplexer. It matches the
53 -// zone name of each incoming request against a list of
54 -// registered patterns add calls the handler for the pattern
55 -// that most closely matches the zone name. ServeMux is DNSSEC aware, meaning
56 -// that queries for the DS record are redirected to the parent zone (if that
57 -// is also registered), otherwise the child gets the query.
58 -// ServeMux is also safe for concurrent access from multiple goroutines.
59 -type ServeMux struct {
60 - z map[string]Handler
61 - m *sync.RWMutex
62 -}
63 -
64 -// NewServeMux allocates and returns a new ServeMux.
65 -func NewServeMux() *ServeMux { return &ServeMux{z: make(map[string]Handler), m: new(sync.RWMutex)} }
66 -
67 -// DefaultServeMux is the default ServeMux used by Serve.
68 -var DefaultServeMux = NewServeMux()
69 -
70 -// The HandlerFunc type is an adapter to allow the use of
71 -// ordinary functions as DNS handlers. If f is a function
72 -// with the appropriate signature, HandlerFunc(f) is a
73 -// Handler object that calls f.
74 -type HandlerFunc func(ResponseWriter, *Msg)
75 -
76 -// ServeDNS calls f(w, r).
77 -func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
78 - f(w, r)
79 -}
80 -
81 -// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets.
82 -func HandleFailed(w ResponseWriter, r *Msg) {
83 - m := new(Msg)
84 - m.SetRcode(r, RcodeServerFailure)
85 - // does not matter if this write fails
86 - w.WriteMsg(m)
87 -}
88 -
89 -func failedHandler() Handler { return HandlerFunc(HandleFailed) }
90 -
91 -// ListenAndServe Starts a server on addresss and network speficied. Invoke handler
92 -// for incoming queries.
93 -func ListenAndServe(addr string, network string, handler Handler) error {
94 - server := &Server{Addr: addr, Net: network, Handler: handler}
95 - return server.ListenAndServe()
96 -}
97 -
98 -// ActivateAndServe activates a server with a listener from systemd,
99 -// l and p should not both be non-nil.
100 -// If both l and p are not nil only p will be used.
101 -// Invoke handler for incoming queries.
102 -func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error {
103 - server := &Server{Listener: l, PacketConn: p, Handler: handler}
104 - return server.ActivateAndServe()
105 -}
106 -
107 -func (mux *ServeMux) match(q string, t uint16) Handler {
108 - mux.m.RLock()
109 - defer mux.m.RUnlock()
110 - var handler Handler
111 - b := make([]byte, len(q)) // worst case, one label of length q
112 - off := 0
113 - end := false
114 - for {
115 - l := len(q[off:])
116 - for i := 0; i < l; i++ {
117 - b[i] = q[off+i]
118 - if b[i] >= 'A' && b[i] <= 'Z' {
119 - b[i] |= ('a' - 'A')
120 - }
121 - }
122 - if h, ok := mux.z[string(b[:l])]; ok { // 'causes garbage, might want to change the map key
123 - if t != TypeDS {
124 - return h
125 - }
126 - // Continue for DS to see if we have a parent too, if so delegeate to the parent
127 - handler = h
128 - }
129 - off, end = NextLabel(q, off)
130 - if end {
131 - break
132 - }
133 - }
134 - // Wildcard match, if we have found nothing try the root zone as a last resort.
135 - if h, ok := mux.z["."]; ok {
136 - return h
137 - }
138 - return handler
139 -}
140 -
141 -// Handle adds a handler to the ServeMux for pattern.
142 -func (mux *ServeMux) Handle(pattern string, handler Handler) {
143 - if pattern == "" {
144 - panic("dns: invalid pattern " + pattern)
145 - }
146 - mux.m.Lock()
147 - mux.z[Fqdn(pattern)] = handler
148 - mux.m.Unlock()
149 -}
150 -
151 -// HandleFunc adds a handler function to the ServeMux for pattern.
152 -func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
153 - mux.Handle(pattern, HandlerFunc(handler))
154 -}
155 -
156 -// HandleRemove deregistrars the handler specific for pattern from the ServeMux.
157 -func (mux *ServeMux) HandleRemove(pattern string) {
158 - if pattern == "" {
159 - panic("dns: invalid pattern " + pattern)
160 - }
161 - // don't need a mutex here, because deleting is OK, even if the
162 - // entry is note there.
163 - delete(mux.z, Fqdn(pattern))
164 -}
165 -
166 -// ServeDNS dispatches the request to the handler whose
167 -// pattern most closely matches the request message. If DefaultServeMux
168 -// is used the correct thing for DS queries is done: a possible parent
169 -// is sought.
170 -// If no handler is found a standard SERVFAIL message is returned
171 -// If the request message does not have exactly one question in the
172 -// question section a SERVFAIL is returned, unlesss Unsafe is true.
173 -func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) {
174 - var h Handler
175 - if len(request.Question) < 1 { // allow more than one question
176 - h = failedHandler()
177 - } else {
178 - if h = mux.match(request.Question[0].Name, request.Question[0].Qtype); h == nil {
179 - h = failedHandler()
180 - }
181 - }
182 - h.ServeDNS(w, request)
183 -}
184 -
185 -// Handle registers the handler with the given pattern
186 -// in the DefaultServeMux. The documentation for
187 -// ServeMux explains how patterns are matched.
188 -func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
189 -
190 -// HandleRemove deregisters the handle with the given pattern
191 -// in the DefaultServeMux.
192 -func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) }
193 -
194 -// HandleFunc registers the handler function with the given pattern
195 -// in the DefaultServeMux.
196 -func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
197 - DefaultServeMux.HandleFunc(pattern, handler)
198 -}
199 -
200 -// A Server defines parameters for running an DNS server.
201 -type Server struct {
202 - // Address to listen on, ":dns" if empty.
203 - Addr string
204 - // if "tcp" it will invoke a TCP listener, otherwise an UDP one.
205 - Net string
206 - // TCP Listener to use, this is to aid in systemd's socket activation.
207 - Listener net.Listener
208 - // UDP "Listener" to use, this is to aid in systemd's socket activation.
209 - PacketConn net.PacketConn
210 - // Handler to invoke, dns.DefaultServeMux if nil.
211 - Handler Handler
212 - // Default buffer size to use to read incoming UDP messages. If not set
213 - // it defaults to MinMsgSize (512 B).
214 - UDPSize int
215 - // The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second.
216 - ReadTimeout time.Duration
217 - // The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second.
218 - WriteTimeout time.Duration
219 - // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966).
220 - IdleTimeout func() time.Duration
221 - // Secret(s) for Tsig map[<zonename>]<base64 secret>.
222 - TsigSecret map[string]string
223 - // Unsafe instructs the server to disregard any sanity checks and directly hand the message to
224 - // the handler. It will specfically not check if the query has the QR bit not set.
225 - Unsafe bool
226 - // If NotifyStartedFunc is set is is called, once the server has started listening.
227 - NotifyStartedFunc func()
228 -
229 - // For graceful shutdown.
230 - stopUDP chan bool
231 - stopTCP chan bool
232 - wgUDP sync.WaitGroup
233 - wgTCP sync.WaitGroup
234 -
235 - // make start/shutdown not racy
236 - lock sync.Mutex
237 - started bool
238 -}
239 -
240 -// ListenAndServe starts a nameserver on the configured address in *Server.
241 -func (srv *Server) ListenAndServe() error {
242 - srv.lock.Lock()
243 - if srv.started {
244 - srv.lock.Unlock()
245 - return &Error{err: "server already started"}
246 - }
247 - srv.stopUDP, srv.stopTCP = make(chan bool), make(chan bool)
248 - srv.started = true
249 - srv.lock.Unlock()
250 - addr := srv.Addr
251 - if addr == "" {
252 - addr = ":domain"
253 - }
254 - if srv.UDPSize == 0 {
255 - srv.UDPSize = MinMsgSize
256 - }
257 - switch srv.Net {
258 - case "tcp", "tcp4", "tcp6":
259 - a, e := net.ResolveTCPAddr(srv.Net, addr)
260 - if e != nil {
261 - return e
262 - }
263 - l, e := net.ListenTCP(srv.Net, a)
264 - if e != nil {
265 - return e
266 - }
267 - srv.Listener = l
268 - return srv.serveTCP(l)
269 - case "udp", "udp4", "udp6":
270 - a, e := net.ResolveUDPAddr(srv.Net, addr)
271 - if e != nil {
272 - return e
273 - }
274 - l, e := net.ListenUDP(srv.Net, a)
275 - if e != nil {
276 - return e
277 - }
278 - if e := setUDPSocketOptions(l); e != nil {
279 - return e
280 - }
281 - srv.PacketConn = l
282 - return srv.serveUDP(l)
283 - }
284 - return &Error{err: "bad network"}
285 -}
286 -
287 -// ActivateAndServe starts a nameserver with the PacketConn or Listener
288 -// configured in *Server. Its main use is to start a server from systemd.
289 -func (srv *Server) ActivateAndServe() error {
290 - srv.lock.Lock()
291 - if srv.started {
292 - srv.lock.Unlock()
293 - return &Error{err: "server already started"}
294 - }
295 - srv.stopUDP, srv.stopTCP = make(chan bool), make(chan bool)
296 - srv.started = true
297 - srv.lock.Unlock()
298 - if srv.PacketConn != nil {
299 - if srv.UDPSize == 0 {
300 - srv.UDPSize = MinMsgSize
301 - }
302 - if t, ok := srv.PacketConn.(*net.UDPConn); ok {
303 - if e := setUDPSocketOptions(t); e != nil {
304 - return e
305 - }
306 - return srv.serveUDP(t)
307 - }
308 - }
309 - if srv.Listener != nil {
310 - if t, ok := srv.Listener.(*net.TCPListener); ok {
311 - return srv.serveTCP(t)
312 - }
313 - }
314 - return &Error{err: "bad listeners"}
315 -}
316 -
317 -// Shutdown gracefully shuts down a server. After a call to Shutdown, ListenAndServe and
318 -// ActivateAndServe will return. All in progress queries are completed before the server
319 -// is taken down. If the Shutdown is taking longer than the reading timeout and error
320 -// is returned.
321 -func (srv *Server) Shutdown() error {
322 - srv.lock.Lock()
323 - if !srv.started {
324 - srv.lock.Unlock()
325 - return &Error{err: "server not started"}
326 - }
327 - srv.started = false
328 - srv.lock.Unlock()
329 - net, addr := srv.Net, srv.Addr
330 - switch {
331 - case srv.Listener != nil:
332 - a := srv.Listener.Addr()
333 - net, addr = a.Network(), a.String()
334 - case srv.PacketConn != nil:
335 - a := srv.PacketConn.LocalAddr()
336 - net, addr = a.Network(), a.String()
337 - }
338 -
339 - fin := make(chan bool)
340 - switch net {
341 - case "tcp", "tcp4", "tcp6":
342 - go func() {
343 - srv.stopTCP <- true
344 - srv.wgTCP.Wait()
345 - fin <- true
346 - }()
347 -
348 - case "udp", "udp4", "udp6":
349 - go func() {
350 - srv.stopUDP <- true
351 - srv.wgUDP.Wait()
352 - fin <- true
353 - }()
354 - }
355 -
356 - c := &Client{Net: net}
357 - go c.Exchange(new(Msg), addr) // extra query to help ReadXXX loop to pass
358 -
359 - select {
360 - case <-time.After(srv.getReadTimeout()):
361 - return &Error{err: "server shutdown is pending"}
362 - case <-fin:
363 - return nil
364 - }
365 -}
366 -
367 -// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
368 -func (srv *Server) getReadTimeout() time.Duration {
369 - rtimeout := dnsTimeout
370 - if srv.ReadTimeout != 0 {
371 - rtimeout = srv.ReadTimeout
372 - }
373 - return rtimeout
374 -}
375 -
376 -// serveTCP starts a TCP listener for the server.
377 -// Each request is handled in a separate goroutine.
378 -func (srv *Server) serveTCP(l *net.TCPListener) error {
379 - defer l.Close()
380 -
381 - if srv.NotifyStartedFunc != nil {
382 - srv.NotifyStartedFunc()
383 - }
384 -
385 - handler := srv.Handler
386 - if handler == nil {
387 - handler = DefaultServeMux
388 - }
389 - rtimeout := srv.getReadTimeout()
390 - // deadline is not used here
391 - for {
392 - rw, e := l.AcceptTCP()
393 - if e != nil {
394 - continue
395 - }
396 - m, e := srv.readTCP(rw, rtimeout)
397 - select {
398 - case <-srv.stopTCP:
399 - return nil
400 - default:
401 - }
402 - if e != nil {
403 - continue
404 - }
405 - srv.wgTCP.Add(1)
406 - go srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw)
407 - }
408 - panic("dns: not reached")
409 -}
410 -
411 -// serveUDP starts a UDP listener for the server.
412 -// Each request is handled in a separate goroutine.
413 -func (srv *Server) serveUDP(l *net.UDPConn) error {
414 - defer l.Close()
415 -
416 - if srv.NotifyStartedFunc != nil {
417 - srv.NotifyStartedFunc()
418 - }
419 -
420 - handler := srv.Handler
421 - if handler == nil {
422 - handler = DefaultServeMux
423 - }
424 - rtimeout := srv.getReadTimeout()
425 - // deadline is not used here
426 - for {
427 - m, s, e := srv.readUDP(l, rtimeout)
428 - select {
429 - case <-srv.stopUDP:
430 - return nil
431 - default:
432 - }
433 - if e != nil {
434 - continue
435 - }
436 - srv.wgUDP.Add(1)
437 - go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
438 - }
439 - panic("dns: not reached")
440 -}
441 -
442 -// Serve a new connection.
443 -func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, s *SessionUDP, t *net.TCPConn) {
444 - w := &response{tsigSecret: srv.TsigSecret, udp: u, tcp: t, remoteAddr: a, udpSession: s}
445 - q := 0
446 - defer func() {
447 - if u != nil {
448 - srv.wgUDP.Done()
449 - }
450 - if t != nil {
451 - srv.wgTCP.Done()
452 - }
453 - }()
454 -Redo:
455 - req := new(Msg)
456 - err := req.Unpack(m)
457 - if err != nil { // Send a FormatError back
458 - x := new(Msg)
459 - x.SetRcodeFormatError(req)
460 - w.WriteMsg(x)
461 - goto Exit
462 - }
463 - if !srv.Unsafe && req.Response {
464 - goto Exit
465 - }
466 -
467 - w.tsigStatus = nil
468 - if w.tsigSecret != nil {
469 - if t := req.IsTsig(); t != nil {
470 - secret := t.Hdr.Name
471 - if _, ok := w.tsigSecret[secret]; !ok {
472 - w.tsigStatus = ErrKeyAlg
473 - }
474 - w.tsigStatus = TsigVerify(m, w.tsigSecret[secret], "", false)
475 - w.tsigTimersOnly = false
476 - w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC
477 - }
478 - }
479 - h.ServeDNS(w, req) // Writes back to the client
480 -
481 -Exit:
482 - if w.hijacked {
483 - return // client calls Close()
484 - }
485 - if u != nil { // UDP, "close" and return
486 - w.Close()
487 - return
488 - }
489 - idleTimeout := tcpIdleTimeout
490 - if srv.IdleTimeout != nil {
491 - idleTimeout = srv.IdleTimeout()
492 - }
493 - m, e := srv.readTCP(w.tcp, idleTimeout)
494 - if e == nil {
495 - q++
496 - // TODO(miek): make this number configurable?
497 - if q > 128 { // close socket after this many queries
498 - w.Close()
499 - return
500 - }
501 - goto Redo
502 - }
503 - w.Close()
504 - return
505 -}
506 -
507 -func (srv *Server) readTCP(conn *net.TCPConn, timeout time.Duration) ([]byte, error) {
508 - conn.SetReadDeadline(time.Now().Add(timeout))
509 - l := make([]byte, 2)
510 - n, err := conn.Read(l)
511 - if err != nil || n != 2 {
512 - if err != nil {
513 - return nil, err
514 - }
515 - return nil, ErrShortRead
516 - }
517 - length, _ := unpackUint16(l, 0)
518 - if length == 0 {
519 - return nil, ErrShortRead
520 - }
521 - m := make([]byte, int(length))
522 - n, err = conn.Read(m[:int(length)])
523 - if err != nil || n == 0 {
524 - if err != nil {
525 - return nil, err
526 - }
527 - return nil, ErrShortRead
528 - }
529 - i := n
530 - for i < int(length) {
531 - j, err := conn.Read(m[i:int(length)])
532 - if err != nil {
533 - return nil, err
534 - }
535 - i += j
536 - }
537 - n = i
538 - m = m[:n]
539 - return m, nil
540 -}
541 -
542 -func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
543 - conn.SetReadDeadline(time.Now().Add(timeout))
544 - m := make([]byte, srv.UDPSize)
545 - n, s, e := ReadFromSessionUDP(conn, m)
546 - if e != nil || n == 0 {
547 - if e != nil {
548 - return nil, nil, e
549 - }
550 - return nil, nil, ErrShortRead
551 - }
552 - m = m[:n]
553 - return m, s, nil
554 -}
555 -
556 -// WriteMsg implements the ResponseWriter.WriteMsg method.
557 -func (w *response) WriteMsg(m *Msg) (err error) {
558 - var data []byte
559 - if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check)
560 - if t := m.IsTsig(); t != nil {
561 - data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly)
562 - if err != nil {
563 - return err
564 - }
565 - _, err = w.Write(data)
566 - return err
567 - }
568 - }
569 - data, err = m.Pack()
570 - if err != nil {
571 - return err
572 - }
573 - _, err = w.Write(data)
574 - return err
575 -}
576 -
577 -// Write implements the ResponseWriter.Write method.
578 -func (w *response) Write(m []byte) (int, error) {
579 - switch {
580 - case w.udp != nil:
581 - n, err := WriteToSessionUDP(w.udp, m, w.udpSession)
582 - return n, err
583 - case w.tcp != nil:
584 - lm := len(m)
585 - if lm < 2 {
586 - return 0, io.ErrShortBuffer
587 - }
588 - if lm > MaxMsgSize {
589 - return 0, &Error{err: "message too large"}
590 - }
591 - l := make([]byte, 2, 2+lm)
592 - l[0], l[1] = packUint16(uint16(lm))
593 - m = append(l, m...)
594 -
595 - n, err := io.Copy(w.tcp, bytes.NewReader(m))
596 - return int(n), err
597 - }
598 - panic("not reached")
599 -}
600 -
601 -// LocalAddr implements the ResponseWriter.LocalAddr method.
602 -func (w *response) LocalAddr() net.Addr {
603 - if w.tcp != nil {
604 - return w.tcp.LocalAddr()
605 - }
606 - return w.udp.LocalAddr()
607 -}
608 -
609 -// RemoteAddr implements the ResponseWriter.RemoteAddr method.
610 -func (w *response) RemoteAddr() net.Addr { return w.remoteAddr }
611 -
612 -// TsigStatus implements the ResponseWriter.TsigStatus method.
613 -func (w *response) TsigStatus() error { return w.tsigStatus }
614 -
615 -// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method.
616 -func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b }
617 -
618 -// Hijack implements the ResponseWriter.Hijack method.
619 -func (w *response) Hijack() { w.hijacked = true }
620 -
621 -// Close implements the ResponseWriter.Close method
622 -func (w *response) Close() error {
623 - // Can't close the udp conn, as that is actually the listener.
624 - if w.tcp != nil {
625 - e := w.tcp.Close()
626 - w.tcp = nil
627 - return e
628 - }
629 - return nil
630 -}
Godeps/_workspace/src/github.com/miekg/dns/server_test.go deleted
-389
@@ -1,389 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "fmt"
5 - "net"
6 - "runtime"
7 - "sync"
8 - "testing"
9 -)
10 -
11 -func HelloServer(w ResponseWriter, req *Msg) {
12 - m := new(Msg)
13 - m.SetReply(req)
14 -
15 - m.Extra = make([]RR, 1)
16 - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
17 - w.WriteMsg(m)
18 -}
19 -
20 -func AnotherHelloServer(w ResponseWriter, req *Msg) {
21 - m := new(Msg)
22 - m.SetReply(req)
23 -
24 - m.Extra = make([]RR, 1)
25 - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello example"}}
26 - w.WriteMsg(m)
27 -}
28 -
29 -func RunLocalUDPServer(laddr string) (*Server, string, error) {
30 - pc, err := net.ListenPacket("udp", laddr)
31 - if err != nil {
32 - return nil, "", err
33 - }
34 - server := &Server{PacketConn: pc}
35 -
36 - waitLock := sync.Mutex{}
37 - waitLock.Lock()
38 - server.NotifyStartedFunc = waitLock.Unlock
39 -
40 - go func() {
41 - server.ActivateAndServe()
42 - pc.Close()
43 - }()
44 -
45 - waitLock.Lock()
46 - return server, pc.LocalAddr().String(), nil
47 -}
48 -
49 -func RunLocalUDPServerUnsafe(laddr string) (*Server, string, error) {
50 - pc, err := net.ListenPacket("udp", laddr)
51 - if err != nil {
52 - return nil, "", err
53 - }
54 - server := &Server{PacketConn: pc, Unsafe: true}
55 -
56 - waitLock := sync.Mutex{}
57 - waitLock.Lock()
58 - server.NotifyStartedFunc = waitLock.Unlock
59 -
60 - go func() {
61 - server.ActivateAndServe()
62 - pc.Close()
63 - }()
64 -
65 - waitLock.Lock()
66 - return server, pc.LocalAddr().String(), nil
67 -}
68 -
69 -func RunLocalTCPServer(laddr string) (*Server, string, error) {
70 - l, err := net.Listen("tcp", laddr)
71 - if err != nil {
72 - return nil, "", err
73 - }
74 -
75 - server := &Server{Listener: l}
76 -
77 - waitLock := sync.Mutex{}
78 - waitLock.Lock()
79 - server.NotifyStartedFunc = waitLock.Unlock
80 -
81 - go func() {
82 - server.ActivateAndServe()
83 - l.Close()
84 - }()
85 -
86 - waitLock.Lock()
87 - return server, l.Addr().String(), nil
88 -}
89 -
90 -func TestServing(t *testing.T) {
91 - HandleFunc("miek.nl.", HelloServer)
92 - HandleFunc("example.com.", AnotherHelloServer)
93 - defer HandleRemove("miek.nl.")
94 - defer HandleRemove("example.com.")
95 -
96 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
97 - if err != nil {
98 - t.Fatalf("Unable to run test server: %v", err)
99 - }
100 - defer s.Shutdown()
101 -
102 - c := new(Client)
103 - m := new(Msg)
104 - m.SetQuestion("miek.nl.", TypeTXT)
105 - r, _, err := c.Exchange(m, addrstr)
106 - if err != nil || len(r.Extra) == 0 {
107 - t.Fatal("failed to exchange miek.nl", err)
108 - }
109 - txt := r.Extra[0].(*TXT).Txt[0]
110 - if txt != "Hello world" {
111 - t.Error("Unexpected result for miek.nl", txt, "!= Hello world")
112 - }
113 -
114 - m.SetQuestion("example.com.", TypeTXT)
115 - r, _, err = c.Exchange(m, addrstr)
116 - if err != nil {
117 - t.Fatal("failed to exchange example.com", err)
118 - }
119 - txt = r.Extra[0].(*TXT).Txt[0]
120 - if txt != "Hello example" {
121 - t.Error("Unexpected result for example.com", txt, "!= Hello example")
122 - }
123 -
124 - // Test Mixes cased as noticed by Ask.
125 - m.SetQuestion("eXaMplE.cOm.", TypeTXT)
126 - r, _, err = c.Exchange(m, addrstr)
127 - if err != nil {
128 - t.Error("failed to exchange eXaMplE.cOm", err)
129 - }
130 - txt = r.Extra[0].(*TXT).Txt[0]
131 - if txt != "Hello example" {
132 - t.Error("Unexpected result for example.com", txt, "!= Hello example")
133 - }
134 -}
135 -
136 -func BenchmarkServe(b *testing.B) {
137 - b.StopTimer()
138 - HandleFunc("miek.nl.", HelloServer)
139 - defer HandleRemove("miek.nl.")
140 - a := runtime.GOMAXPROCS(4)
141 -
142 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
143 - if err != nil {
144 - b.Fatalf("Unable to run test server: %v", err)
145 - }
146 - defer s.Shutdown()
147 -
148 - c := new(Client)
149 - m := new(Msg)
150 - m.SetQuestion("miek.nl", TypeSOA)
151 -
152 - b.StartTimer()
153 - for i := 0; i < b.N; i++ {
154 - c.Exchange(m, addrstr)
155 - }
156 - runtime.GOMAXPROCS(a)
157 -}
158 -
159 -func benchmarkServe6(b *testing.B) {
160 - b.StopTimer()
161 - HandleFunc("miek.nl.", HelloServer)
162 - defer HandleRemove("miek.nl.")
163 - a := runtime.GOMAXPROCS(4)
164 - s, addrstr, err := RunLocalUDPServer("[::1]:0")
165 - if err != nil {
166 - b.Fatalf("Unable to run test server: %v", err)
167 - }
168 - defer s.Shutdown()
169 -
170 - c := new(Client)
171 - m := new(Msg)
172 - m.SetQuestion("miek.nl", TypeSOA)
173 -
174 - b.StartTimer()
175 - for i := 0; i < b.N; i++ {
176 - c.Exchange(m, addrstr)
177 - }
178 - runtime.GOMAXPROCS(a)
179 -}
180 -
181 -func HelloServerCompress(w ResponseWriter, req *Msg) {
182 - m := new(Msg)
183 - m.SetReply(req)
184 - m.Extra = make([]RR, 1)
185 - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}}
186 - m.Compress = true
187 - w.WriteMsg(m)
188 -}
189 -
190 -func BenchmarkServeCompress(b *testing.B) {
191 - b.StopTimer()
192 - HandleFunc("miek.nl.", HelloServerCompress)
193 - defer HandleRemove("miek.nl.")
194 - a := runtime.GOMAXPROCS(4)
195 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
196 - if err != nil {
197 - b.Fatalf("Unable to run test server: %v", err)
198 - }
199 - defer s.Shutdown()
200 -
201 - c := new(Client)
202 - m := new(Msg)
203 - m.SetQuestion("miek.nl", TypeSOA)
204 - b.StartTimer()
205 - for i := 0; i < b.N; i++ {
206 - c.Exchange(m, addrstr)
207 - }
208 - runtime.GOMAXPROCS(a)
209 -}
210 -
211 -func TestDotAsCatchAllWildcard(t *testing.T) {
212 - mux := NewServeMux()
213 - mux.Handle(".", HandlerFunc(HelloServer))
214 - mux.Handle("example.com.", HandlerFunc(AnotherHelloServer))
215 -
216 - handler := mux.match("www.miek.nl.", TypeTXT)
217 - if handler == nil {
218 - t.Error("wildcard match failed")
219 - }
220 -
221 - handler = mux.match("www.example.com.", TypeTXT)
222 - if handler == nil {
223 - t.Error("example.com match failed")
224 - }
225 -
226 - handler = mux.match("a.www.example.com.", TypeTXT)
227 - if handler == nil {
228 - t.Error("a.www.example.com match failed")
229 - }
230 -
231 - handler = mux.match("boe.", TypeTXT)
232 - if handler == nil {
233 - t.Error("boe. match failed")
234 - }
235 -}
236 -
237 -func TestCaseFolding(t *testing.T) {
238 - mux := NewServeMux()
239 - mux.Handle("_udp.example.com.", HandlerFunc(HelloServer))
240 -
241 - handler := mux.match("_dns._udp.example.com.", TypeSRV)
242 - if handler == nil {
243 - t.Error("case sensitive characters folded")
244 - }
245 -
246 - handler = mux.match("_DNS._UDP.EXAMPLE.COM.", TypeSRV)
247 - if handler == nil {
248 - t.Error("case insensitive characters not folded")
249 - }
250 -}
251 -
252 -func TestRootServer(t *testing.T) {
253 - mux := NewServeMux()
254 - mux.Handle(".", HandlerFunc(HelloServer))
255 -
256 - handler := mux.match(".", TypeNS)
257 - if handler == nil {
258 - t.Error("root match failed")
259 - }
260 -}
261 -
262 -type maxRec struct {
263 - max int
264 - sync.RWMutex
265 -}
266 -
267 -var M = new(maxRec)
268 -
269 -func HelloServerLargeResponse(resp ResponseWriter, req *Msg) {
270 - m := new(Msg)
271 - m.SetReply(req)
272 - m.Authoritative = true
273 - m1 := 0
274 - M.RLock()
275 - m1 = M.max
276 - M.RUnlock()
277 - for i := 0; i < m1; i++ {
278 - aRec := &A{
279 - Hdr: RR_Header{
280 - Name: req.Question[0].Name,
281 - Rrtype: TypeA,
282 - Class: ClassINET,
283 - Ttl: 0,
284 - },
285 - A: net.ParseIP(fmt.Sprintf("127.0.0.%d", i+1)).To4(),
286 - }
287 - m.Answer = append(m.Answer, aRec)
288 - }
289 - resp.WriteMsg(m)
290 -}
291 -
292 -func TestServingLargeResponses(t *testing.T) {
293 - HandleFunc("example.", HelloServerLargeResponse)
294 - defer HandleRemove("example.")
295 -
296 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
297 - if err != nil {
298 - t.Fatalf("Unable to run test server: %v", err)
299 - }
300 - defer s.Shutdown()
301 -
302 - // Create request
303 - m := new(Msg)
304 - m.SetQuestion("web.service.example.", TypeANY)
305 -
306 - c := new(Client)
307 - c.Net = "udp"
308 - M.Lock()
309 - M.max = 2
310 - M.Unlock()
311 - _, _, err = c.Exchange(m, addrstr)
312 - if err != nil {
313 - t.Errorf("failed to exchange: %v", err)
314 - }
315 - // This must fail
316 - M.Lock()
317 - M.max = 20
318 - M.Unlock()
319 - _, _, err = c.Exchange(m, addrstr)
320 - if err == nil {
321 - t.Error("failed to fail exchange, this should generate packet error")
322 - }
323 - // But this must work again
324 - c.UDPSize = 7000
325 - _, _, err = c.Exchange(m, addrstr)
326 - if err != nil {
327 - t.Errorf("failed to exchange: %v", err)
328 - }
329 -}
330 -
331 -func TestServingResponse(t *testing.T) {
332 - if testing.Short() {
333 - t.Skip("skipping test in short mode.")
334 - }
335 - HandleFunc("miek.nl.", HelloServer)
336 - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0")
337 - if err != nil {
338 - t.Fatalf("Unable to run test server: %v", err)
339 - }
340 -
341 - c := new(Client)
342 - m := new(Msg)
343 - m.SetQuestion("miek.nl.", TypeTXT)
344 - m.Response = false
345 - _, _, err = c.Exchange(m, addrstr)
346 - if err != nil {
347 - t.Fatal("failed to exchange", err)
348 - }
349 - m.Response = true
350 - _, _, err = c.Exchange(m, addrstr)
351 - if err == nil {
352 - t.Fatal("exchanged response message")
353 - }
354 -
355 - s.Shutdown()
356 - s, addrstr, err = RunLocalUDPServerUnsafe("127.0.0.1:0")
357 - if err != nil {
358 - t.Fatalf("Unable to run test server: %v", err)
359 - }
360 - defer s.Shutdown()
361 -
362 - m.Response = true
363 - _, _, err = c.Exchange(m, addrstr)
364 - if err != nil {
365 - t.Fatal("could exchanged response message in Unsafe mode")
366 - }
367 -}
368 -
369 -func TestShutdownTCP(t *testing.T) {
370 - s, _, err := RunLocalTCPServer("127.0.0.1:0")
371 - if err != nil {
372 - t.Fatalf("Unable to run test server: %v", err)
373 - }
374 - err = s.Shutdown()
375 - if err != nil {
376 - t.Errorf("Could not shutdown test TCP server, %v", err)
377 - }
378 -}
379 -
380 -func TestShutdownUDP(t *testing.T) {
381 - s, _, err := RunLocalUDPServer("127.0.0.1:0")
382 - if err != nil {
383 - t.Fatalf("Unable to run test server: %v", err)
384 - }
385 - err = s.Shutdown()
386 - if err != nil {
387 - t.Errorf("Could not shutdown test UDP server, %v", err)
388 - }
389 -}
Godeps/_workspace/src/github.com/miekg/dns/sig0.go deleted
-221
@@ -1,221 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "crypto"
5 - "crypto/dsa"
6 - "crypto/ecdsa"
7 - "crypto/rsa"
8 - "math/big"
9 - "strings"
10 - "time"
11 -)
12 -
13 -// Sign signs a dns.Msg. It fills the signature with the appropriate data.
14 -// The SIG record should have the SignerName, KeyTag, Algorithm, Inception
15 -// and Expiration set.
16 -func (rr *SIG) Sign(k PrivateKey, m *Msg) ([]byte, error) {
17 - if k == nil {
18 - return nil, ErrPrivKey
19 - }
20 - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
21 - return nil, ErrKey
22 - }
23 - rr.Header().Rrtype = TypeSIG
24 - rr.Header().Class = ClassANY
25 - rr.Header().Ttl = 0
26 - rr.Header().Name = "."
27 - rr.OrigTtl = 0
28 - rr.TypeCovered = 0
29 - rr.Labels = 0
30 -
31 - buf := make([]byte, m.Len()+rr.len())
32 - mbuf, err := m.PackBuffer(buf)
33 - if err != nil {
34 - return nil, err
35 - }
36 - if &buf[0] != &mbuf[0] {
37 - return nil, ErrBuf
38 - }
39 - off, err := PackRR(rr, buf, len(mbuf), nil, false)
40 - if err != nil {
41 - return nil, err
42 - }
43 - buf = buf[:off:cap(buf)]
44 - var hash crypto.Hash
45 - switch rr.Algorithm {
46 - case DSA, RSASHA1:
47 - hash = crypto.SHA1
48 - case RSASHA256, ECDSAP256SHA256:
49 - hash = crypto.SHA256
50 - case ECDSAP384SHA384:
51 - hash = crypto.SHA384
52 - case RSASHA512:
53 - hash = crypto.SHA512
54 - default:
55 - return nil, ErrAlg
56 - }
57 - hasher := hash.New()
58 - // Write SIG rdata
59 - hasher.Write(buf[len(mbuf)+1+2+2+4+2:])
60 - // Write message
61 - hasher.Write(buf[:len(mbuf)])
62 - hashed := hasher.Sum(nil)
63 -
64 - sig, err := k.Sign(hashed, rr.Algorithm)
65 - if err != nil {
66 - return nil, err
67 - }
68 - rr.Signature = toBase64(sig)
69 - buf = append(buf, sig...)
70 - if len(buf) > int(^uint16(0)) {
71 - return nil, ErrBuf
72 - }
73 - // Adjust sig data length
74 - rdoff := len(mbuf) + 1 + 2 + 2 + 4
75 - rdlen, _ := unpackUint16(buf, rdoff)
76 - rdlen += uint16(len(sig))
77 - buf[rdoff], buf[rdoff+1] = packUint16(rdlen)
78 - // Adjust additional count
79 - adc, _ := unpackUint16(buf, 10)
80 - adc++
81 - buf[10], buf[11] = packUint16(adc)
82 - return buf, nil
83 -}
84 -
85 -// Verify validates the message buf using the key k.
86 -// It's assumed that buf is a valid message from which rr was unpacked.
87 -func (rr *SIG) Verify(k *KEY, buf []byte) error {
88 - if k == nil {
89 - return ErrKey
90 - }
91 - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 {
92 - return ErrKey
93 - }
94 -
95 - var hash crypto.Hash
96 - switch rr.Algorithm {
97 - case DSA, RSASHA1:
98 - hash = crypto.SHA1
99 - case RSASHA256, ECDSAP256SHA256:
100 - hash = crypto.SHA256
101 - case ECDSAP384SHA384:
102 - hash = crypto.SHA384
103 - case RSASHA512:
104 - hash = crypto.SHA512
105 - default:
106 - return ErrAlg
107 - }
108 - hasher := hash.New()
109 -
110 - buflen := len(buf)
111 - qdc, _ := unpackUint16(buf, 4)
112 - anc, _ := unpackUint16(buf, 6)
113 - auc, _ := unpackUint16(buf, 8)
114 - adc, offset := unpackUint16(buf, 10)
115 - var err error
116 - for i := uint16(0); i < qdc && offset < buflen; i++ {
117 - _, offset, err = UnpackDomainName(buf, offset)
118 - if err != nil {
119 - return err
120 - }
121 - // Skip past Type and Class
122 - offset += 2 + 2
123 - }
124 - for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ {
125 - _, offset, err = UnpackDomainName(buf, offset)
126 - if err != nil {
127 - return err
128 - }
129 - // Skip past Type, Class and TTL
130 - offset += 2 + 2 + 4
131 - if offset+1 >= buflen {
132 - continue
133 - }
134 - var rdlen uint16
135 - rdlen, offset = unpackUint16(buf, offset)
136 - offset += int(rdlen)
137 - }
138 - if offset >= buflen {
139 - return &Error{err: "overflowing unpacking signed message"}
140 - }
141 -
142 - // offset should be just prior to SIG
143 - bodyend := offset
144 - // owner name SHOULD be root
145 - _, offset, err = UnpackDomainName(buf, offset)
146 - if err != nil {
147 - return err
148 - }
149 - // Skip Type, Class, TTL, RDLen
150 - offset += 2 + 2 + 4 + 2
151 - sigstart := offset
152 - // Skip Type Covered, Algorithm, Labels, Original TTL
153 - offset += 2 + 1 + 1 + 4
154 - if offset+4+4 >= buflen {
155 - return &Error{err: "overflow unpacking signed message"}
156 - }
157 - expire := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3])
158 - offset += 4
159 - incept := uint32(buf[offset])<<24 | uint32(buf[offset+1])<<16 | uint32(buf[offset+2])<<8 | uint32(buf[offset+3])
160 - offset += 4
161 - now := uint32(time.Now().Unix())
162 - if now < incept || now > expire {
163 - return ErrTime
164 - }
165 - // Skip key tag
166 - offset += 2
167 - var signername string
168 - signername, offset, err = UnpackDomainName(buf, offset)
169 - if err != nil {
170 - return err
171 - }
172 - // If key has come from the DNS name compression might
173 - // have mangled the case of the name
174 - if strings.ToLower(signername) != strings.ToLower(k.Header().Name) {
175 - return &Error{err: "signer name doesn't match key name"}
176 - }
177 - sigend := offset
178 - hasher.Write(buf[sigstart:sigend])
179 - hasher.Write(buf[:10])
180 - hasher.Write([]byte{
181 - byte((adc - 1) << 8),
182 - byte(adc - 1),
183 - })
184 - hasher.Write(buf[12:bodyend])
185 -
186 - hashed := hasher.Sum(nil)
187 - sig := buf[sigend:]
188 - switch k.Algorithm {
189 - case DSA:
190 - pk := k.publicKeyDSA()
191 - sig = sig[1:]
192 - r := big.NewInt(0)
193 - r.SetBytes(sig[:len(sig)/2])
194 - s := big.NewInt(0)
195 - s.SetBytes(sig[len(sig)/2:])
196 - if pk != nil {
197 - if dsa.Verify(pk, hashed, r, s) {
198 - return nil
199 - }
200 - return ErrSig
201 - }
202 - case RSASHA1, RSASHA256, RSASHA512:
203 - pk := k.publicKeyRSA()
204 - if pk != nil {
205 - return rsa.VerifyPKCS1v15(pk, hash, hashed, sig)
206 - }
207 - case ECDSAP256SHA256, ECDSAP384SHA384:
208 - pk := k.publicKeyECDSA()
209 - r := big.NewInt(0)
210 - r.SetBytes(sig[:len(sig)/2])
211 - s := big.NewInt(0)
212 - s.SetBytes(sig[len(sig)/2:])
213 - if pk != nil {
214 - if ecdsa.Verify(pk, hashed, r, s) {
215 - return nil
216 - }
217 - return ErrSig
218 - }
219 - }
220 - return ErrKeyAlg
221 -}
Godeps/_workspace/src/github.com/miekg/dns/sig0_test.go deleted
-88
@@ -1,88 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "testing"
5 - "time"
6 -)
7 -
8 -func TestSIG0(t *testing.T) {
9 - if testing.Short() {
10 - t.Skip("skipping test in short mode.")
11 - }
12 - m := new(Msg)
13 - m.SetQuestion("example.org.", TypeSOA)
14 - for _, alg := range []uint8{DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256, RSASHA512} {
15 - algstr := AlgorithmToString[alg]
16 - keyrr := new(KEY)
17 - keyrr.Hdr.Name = algstr + "."
18 - keyrr.Hdr.Rrtype = TypeKEY
19 - keyrr.Hdr.Class = ClassINET
20 - keyrr.Algorithm = alg
21 - keysize := 1024
22 - switch alg {
23 - case ECDSAP256SHA256:
24 - keysize = 256
25 - case ECDSAP384SHA384:
26 - keysize = 384
27 - }
28 - pk, err := keyrr.Generate(keysize)
29 - if err != nil {
30 - t.Errorf("Failed to generate key for “%s”: %v", algstr, err)
31 - continue
32 - }
33 - now := uint32(time.Now().Unix())
34 - sigrr := new(SIG)
35 - sigrr.Hdr.Name = "."
36 - sigrr.Hdr.Rrtype = TypeSIG
37 - sigrr.Hdr.Class = ClassANY
38 - sigrr.Algorithm = alg
39 - sigrr.Expiration = now + 300
40 - sigrr.Inception = now - 300
41 - sigrr.KeyTag = keyrr.KeyTag()
42 - sigrr.SignerName = keyrr.Hdr.Name
43 - mb, err := sigrr.Sign(pk, m)
44 - if err != nil {
45 - t.Errorf("Failed to sign message using “%s”: %v", algstr, err)
46 - continue
47 - }
48 - m := new(Msg)
49 - if err := m.Unpack(mb); err != nil {
50 - t.Errorf("Failed to unpack message signed using “%s”: %v", algstr, err)
51 - continue
52 - }
53 - if len(m.Extra) != 1 {
54 - t.Errorf("Missing SIG for message signed using “%s”", algstr)
55 - continue
56 - }
57 - var sigrrwire *SIG
58 - switch rr := m.Extra[0].(type) {
59 - case *SIG:
60 - sigrrwire = rr
61 - default:
62 - t.Errorf("Expected SIG RR, instead: %v", rr)
63 - continue
64 - }
65 - for _, rr := range []*SIG{sigrr, sigrrwire} {
66 - id := "sigrr"
67 - if rr == sigrrwire {
68 - id = "sigrrwire"
69 - }
70 - if err := rr.Verify(keyrr, mb); err != nil {
71 - t.Errorf("Failed to verify “%s” signed SIG(%s): %v", algstr, id, err)
72 - continue
73 - }
74 - }
75 - mb[13]++
76 - if err := sigrr.Verify(keyrr, mb); err == nil {
77 - t.Errorf("Verify succeeded on an altered message using “%s”", algstr)
78 - continue
79 - }
80 - sigrr.Expiration = 2
81 - sigrr.Inception = 1
82 - mb, _ = sigrr.Sign(pk, m)
83 - if err := sigrr.Verify(keyrr, mb); err == nil {
84 - t.Errorf("Verify succeeded on an expired message using “%s”", algstr)
85 - continue
86 - }
87 - }
88 -}
Godeps/_workspace/src/github.com/miekg/dns/singleinflight.go deleted
-57
@@ -1,57 +0,0 @@
1 -// Copyright 2013 The Go Authors. All rights reserved.
2 -// Use of this source code is governed by a BSD-style
3 -// license that can be found in the LICENSE file.
4 -
5 -// Adapted for dns package usage by Miek Gieben.
6 -
7 -package dns
8 -
9 -import "sync"
10 -import "time"
11 -
12 -// call is an in-flight or completed singleflight.Do call
13 -type call struct {
14 - wg sync.WaitGroup
15 - val *Msg
16 - rtt time.Duration
17 - err error
18 - dups int
19 -}
20 -
21 -// singleflight represents a class of work and forms a namespace in
22 -// which units of work can be executed with duplicate suppression.
23 -type singleflight struct {
24 - sync.Mutex // protects m
25 - m map[string]*call // lazily initialized
26 -}
27 -
28 -// Do executes and returns the results of the given function, making
29 -// sure that only one execution is in-flight for a given key at a
30 -// time. If a duplicate comes in, the duplicate caller waits for the
31 -// original to complete and receives the same results.
32 -// The return value shared indicates whether v was given to multiple callers.
33 -func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) {
34 - g.Lock()
35 - if g.m == nil {
36 - g.m = make(map[string]*call)
37 - }
38 - if c, ok := g.m[key]; ok {
39 - c.dups++
40 - g.Unlock()
41 - c.wg.Wait()
42 - return c.val, c.rtt, c.err, true
43 - }
44 - c := new(call)
45 - c.wg.Add(1)
46 - g.m[key] = c
47 - g.Unlock()
48 -
49 - c.val, c.rtt, c.err = fn()
50 - c.wg.Done()
51 -
52 - g.Lock()
53 - delete(g.m, key)
54 - g.Unlock()
55 -
56 - return c.val, c.rtt, c.err, c.dups > 0
57 -}
Godeps/_workspace/src/github.com/miekg/dns/tlsa.go deleted
-86
@@ -1,86 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "crypto/sha256"
5 - "crypto/sha512"
6 - "crypto/x509"
7 - "encoding/hex"
8 - "errors"
9 - "io"
10 - "net"
11 - "strconv"
12 -)
13 -
14 -// CertificateToDANE converts a certificate to a hex string as used in the TLSA record.
15 -func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) {
16 - switch matchingType {
17 - case 0:
18 - switch selector {
19 - case 0:
20 - return hex.EncodeToString(cert.Raw), nil
21 - case 1:
22 - return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil
23 - }
24 - case 1:
25 - h := sha256.New()
26 - switch selector {
27 - case 0:
28 - io.WriteString(h, string(cert.Raw))
29 - return hex.EncodeToString(h.Sum(nil)), nil
30 - case 1:
31 - io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
32 - return hex.EncodeToString(h.Sum(nil)), nil
33 - }
34 - case 2:
35 - h := sha512.New()
36 - switch selector {
37 - case 0:
38 - io.WriteString(h, string(cert.Raw))
39 - return hex.EncodeToString(h.Sum(nil)), nil
40 - case 1:
41 - io.WriteString(h, string(cert.RawSubjectPublicKeyInfo))
42 - return hex.EncodeToString(h.Sum(nil)), nil
43 - }
44 - }
45 - return "", errors.New("dns: bad TLSA MatchingType or TLSA Selector")
46 -}
47 -
48 -// Sign creates a TLSA record from an SSL certificate.
49 -func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
50 - r.Hdr.Rrtype = TypeTLSA
51 - r.Usage = uint8(usage)
52 - r.Selector = uint8(selector)
53 - r.MatchingType = uint8(matchingType)
54 -
55 - r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
56 - if err != nil {
57 - return err
58 - }
59 - return nil
60 -}
61 -
62 -// Verify verifies a TLSA record against an SSL certificate. If it is OK
63 -// a nil error is returned.
64 -func (r *TLSA) Verify(cert *x509.Certificate) error {
65 - c, err := CertificateToDANE(r.Selector, r.MatchingType, cert)
66 - if err != nil {
67 - return err // Not also ErrSig?
68 - }
69 - if r.Certificate == c {
70 - return nil
71 - }
72 - return ErrSig // ErrSig, really?
73 -}
74 -
75 -// TLSAName returns the ownername of a TLSA resource record as per the
76 -// rules specified in RFC 6698, Section 3.
77 -func TLSAName(name, service, network string) (string, error) {
78 - if !IsFqdn(name) {
79 - return "", ErrFqdn
80 - }
81 - p, e := net.LookupPort(network, service)
82 - if e != nil {
83 - return "", e
84 - }
85 - return "_" + strconv.Itoa(p) + "_" + network + "." + name, nil
86 -}
Godeps/_workspace/src/github.com/miekg/dns/tsig.go deleted
-333
@@ -1,333 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "crypto/hmac"
5 - "crypto/md5"
6 - "crypto/sha1"
7 - "crypto/sha256"
8 - "crypto/sha512"
9 - "encoding/hex"
10 - "hash"
11 - "io"
12 - "strconv"
13 - "strings"
14 - "time"
15 -)
16 -
17 -// HMAC hashing codes. These are transmitted as domain names.
18 -const (
19 - HmacMD5 = "hmac-md5.sig-alg.reg.int."
20 - HmacSHA1 = "hmac-sha1."
21 - HmacSHA256 = "hmac-sha256."
22 - HmacSHA512 = "hmac-sha512."
23 -)
24 -
25 -// TSIG is the RR the holds the transaction signature of a message.
26 -// See RFC 2845 and RFC 4635.
27 -type TSIG struct {
28 - Hdr RR_Header
29 - Algorithm string `dns:"domain-name"`
30 - TimeSigned uint64 `dns:"uint48"`
31 - Fudge uint16
32 - MACSize uint16
33 - MAC string `dns:"size-hex"`
34 - OrigId uint16
35 - Error uint16
36 - OtherLen uint16
37 - OtherData string `dns:"size-hex"`
38 -}
39 -
40 -func (rr *TSIG) Header() *RR_Header {
41 - return &rr.Hdr
42 -}
43 -
44 -// TSIG has no official presentation format, but this will suffice.
45 -
46 -func (rr *TSIG) String() string {
47 - s := "\n;; TSIG PSEUDOSECTION:\n"
48 - s += rr.Hdr.String() +
49 - " " + rr.Algorithm +
50 - " " + tsigTimeToString(rr.TimeSigned) +
51 - " " + strconv.Itoa(int(rr.Fudge)) +
52 - " " + strconv.Itoa(int(rr.MACSize)) +
53 - " " + strings.ToUpper(rr.MAC) +
54 - " " + strconv.Itoa(int(rr.OrigId)) +
55 - " " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR
56 - " " + strconv.Itoa(int(rr.OtherLen)) +
57 - " " + rr.OtherData
58 - return s
59 -}
60 -
61 -func (rr *TSIG) len() int {
62 - return rr.Hdr.len() + len(rr.Algorithm) + 1 + 6 +
63 - 4 + len(rr.MAC)/2 + 1 + 6 + len(rr.OtherData)/2 + 1
64 -}
65 -
66 -func (rr *TSIG) copy() RR {
67 - return &TSIG{*rr.Hdr.copyHeader(), rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData}
68 -}
69 -
70 -// The following values must be put in wireformat, so that the MAC can be calculated.
71 -// RFC 2845, section 3.4.2. TSIG Variables.
72 -type tsigWireFmt struct {
73 - // From RR_Header
74 - Name string `dns:"domain-name"`
75 - Class uint16
76 - Ttl uint32
77 - // Rdata of the TSIG
78 - Algorithm string `dns:"domain-name"`
79 - TimeSigned uint64 `dns:"uint48"`
80 - Fudge uint16
81 - // MACSize, MAC and OrigId excluded
82 - Error uint16
83 - OtherLen uint16
84 - OtherData string `dns:"size-hex"`
85 -}
86 -
87 -// If we have the MAC use this type to convert it to wiredata.
88 -// Section 3.4.3. Request MAC
89 -type macWireFmt struct {
90 - MACSize uint16
91 - MAC string `dns:"size-hex"`
92 -}
93 -
94 -// 3.3. Time values used in TSIG calculations
95 -type timerWireFmt struct {
96 - TimeSigned uint64 `dns:"uint48"`
97 - Fudge uint16
98 -}
99 -
100 -// TsigGenerate fills out the TSIG record attached to the message.
101 -// The message should contain
102 -// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
103 -// time fudge (defaults to 300 seconds) and the current time
104 -// The TSIG MAC is saved in that Tsig RR.
105 -// When TsigGenerate is called for the first time requestMAC is set to the empty string and
106 -// timersOnly is false.
107 -// If something goes wrong an error is returned, otherwise it is nil.
108 -func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
109 - if m.IsTsig() == nil {
110 - panic("dns: TSIG not last RR in additional")
111 - }
112 - // If we barf here, the caller is to blame
113 - rawsecret, err := fromBase64([]byte(secret))
114 - if err != nil {
115 - return nil, "", err
116 - }
117 -
118 - rr := m.Extra[len(m.Extra)-1].(*TSIG)
119 - m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
120 - mbuf, err := m.Pack()
121 - if err != nil {
122 - return nil, "", err
123 - }
124 - buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
125 -
126 - t := new(TSIG)
127 - var h hash.Hash
128 - switch rr.Algorithm {
129 - case HmacMD5:
130 - h = hmac.New(md5.New, []byte(rawsecret))
131 - case HmacSHA1:
132 - h = hmac.New(sha1.New, []byte(rawsecret))
133 - case HmacSHA256:
134 - h = hmac.New(sha256.New, []byte(rawsecret))
135 - case HmacSHA512:
136 - h = hmac.New(sha512.New, []byte(rawsecret))
137 - default:
138 - return nil, "", ErrKeyAlg
139 - }
140 - io.WriteString(h, string(buf))
141 - t.MAC = hex.EncodeToString(h.Sum(nil))
142 - t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
143 -
144 - t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
145 - t.Fudge = rr.Fudge
146 - t.TimeSigned = rr.TimeSigned
147 - t.Algorithm = rr.Algorithm
148 - t.OrigId = m.Id
149 -
150 - tbuf := make([]byte, t.len())
151 - if off, err := PackRR(t, tbuf, 0, nil, false); err == nil {
152 - tbuf = tbuf[:off] // reset to actual size used
153 - } else {
154 - return nil, "", err
155 - }
156 - mbuf = append(mbuf, tbuf...)
157 - rawSetExtraLen(mbuf, uint16(len(m.Extra)+1))
158 - return mbuf, t.MAC, nil
159 -}
160 -
161 -// TsigVerify verifies the TSIG on a message.
162 -// If the signature does not validate err contains the
163 -// error, otherwise it is nil.
164 -func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
165 - rawsecret, err := fromBase64([]byte(secret))
166 - if err != nil {
167 - return err
168 - }
169 - // Strip the TSIG from the incoming msg
170 - stripped, tsig, err := stripTsig(msg)
171 - if err != nil {
172 - return err
173 - }
174 -
175 - msgMAC, err := hex.DecodeString(tsig.MAC)
176 - if err != nil {
177 - return err
178 - }
179 -
180 - buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
181 -
182 - // Fudge factor works both ways. A message can arrive before it was signed because
183 - // of clock skew.
184 - now := uint64(time.Now().Unix())
185 - ti := now - tsig.TimeSigned
186 - if now < tsig.TimeSigned {
187 - ti = tsig.TimeSigned - now
188 - }
189 - if uint64(tsig.Fudge) < ti {
190 - return ErrTime
191 - }
192 -
193 - var h hash.Hash
194 - switch tsig.Algorithm {
195 - case HmacMD5:
196 - h = hmac.New(md5.New, rawsecret)
197 - case HmacSHA1:
198 - h = hmac.New(sha1.New, rawsecret)
199 - case HmacSHA256:
200 - h = hmac.New(sha256.New, rawsecret)
201 - case HmacSHA512:
202 - h = hmac.New(sha512.New, rawsecret)
203 - default:
204 - return ErrKeyAlg
205 - }
206 - h.Write(buf)
207 - if !hmac.Equal(h.Sum(nil), msgMAC) {
208 - return ErrSig
209 - }
210 - return nil
211 -}
212 -
213 -// Create a wiredata buffer for the MAC calculation.
214 -func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []byte {
215 - var buf []byte
216 - if rr.TimeSigned == 0 {
217 - rr.TimeSigned = uint64(time.Now().Unix())
218 - }
219 - if rr.Fudge == 0 {
220 - rr.Fudge = 300 // Standard (RFC) default.
221 - }
222 -
223 - if requestMAC != "" {
224 - m := new(macWireFmt)
225 - m.MACSize = uint16(len(requestMAC) / 2)
226 - m.MAC = requestMAC
227 - buf = make([]byte, len(requestMAC)) // long enough
228 - n, _ := PackStruct(m, buf, 0)
229 - buf = buf[:n]
230 - }
231 -
232 - tsigvar := make([]byte, DefaultMsgSize)
233 - if timersOnly {
234 - tsig := new(timerWireFmt)
235 - tsig.TimeSigned = rr.TimeSigned
236 - tsig.Fudge = rr.Fudge
237 - n, _ := PackStruct(tsig, tsigvar, 0)
238 - tsigvar = tsigvar[:n]
239 - } else {
240 - tsig := new(tsigWireFmt)
241 - tsig.Name = strings.ToLower(rr.Hdr.Name)
242 - tsig.Class = ClassANY
243 - tsig.Ttl = rr.Hdr.Ttl
244 - tsig.Algorithm = strings.ToLower(rr.Algorithm)
245 - tsig.TimeSigned = rr.TimeSigned
246 - tsig.Fudge = rr.Fudge
247 - tsig.Error = rr.Error
248 - tsig.OtherLen = rr.OtherLen
249 - tsig.OtherData = rr.OtherData
250 - n, _ := PackStruct(tsig, tsigvar, 0)
251 - tsigvar = tsigvar[:n]
252 - }
253 -
254 - if requestMAC != "" {
255 - x := append(buf, msgbuf...)
256 - buf = append(x, tsigvar...)
257 - } else {
258 - buf = append(msgbuf, tsigvar...)
259 - }
260 - return buf
261 -}
262 -
263 -// Strip the TSIG from the raw message.
264 -func stripTsig(msg []byte) ([]byte, *TSIG, error) {
265 - // Copied from msg.go's Unpack()
266 - // Header.
267 - var dh Header
268 - var err error
269 - dns := new(Msg)
270 - rr := new(TSIG)
271 - off := 0
272 - tsigoff := 0
273 - if off, err = UnpackStruct(&dh, msg, off); err != nil {
274 - return nil, nil, err
275 - }
276 - if dh.Arcount == 0 {
277 - return nil, nil, ErrNoSig
278 - }
279 - // Rcode, see msg.go Unpack()
280 - if int(dh.Bits&0xF) == RcodeNotAuth {
281 - return nil, nil, ErrAuth
282 - }
283 -
284 - // Arrays.
285 - dns.Question = make([]Question, dh.Qdcount)
286 - dns.Answer = make([]RR, dh.Ancount)
287 - dns.Ns = make([]RR, dh.Nscount)
288 - dns.Extra = make([]RR, dh.Arcount)
289 -
290 - for i := 0; i < len(dns.Question); i++ {
291 - off, err = UnpackStruct(&dns.Question[i], msg, off)
292 - if err != nil {
293 - return nil, nil, err
294 - }
295 - }
296 - for i := 0; i < len(dns.Answer); i++ {
297 - dns.Answer[i], off, err = UnpackRR(msg, off)
298 - if err != nil {
299 - return nil, nil, err
300 - }
301 - }
302 - for i := 0; i < len(dns.Ns); i++ {
303 - dns.Ns[i], off, err = UnpackRR(msg, off)
304 - if err != nil {
305 - return nil, nil, err
306 - }
307 - }
308 - for i := 0; i < len(dns.Extra); i++ {
309 - tsigoff = off
310 - dns.Extra[i], off, err = UnpackRR(msg, off)
311 - if err != nil {
312 - return nil, nil, err
313 - }
314 - if dns.Extra[i].Header().Rrtype == TypeTSIG {
315 - rr = dns.Extra[i].(*TSIG)
316 - // Adjust Arcount.
317 - arcount, _ := unpackUint16(msg, 10)
318 - msg[10], msg[11] = packUint16(arcount - 1)
319 - break
320 - }
321 - }
322 - if rr == nil {
323 - return nil, nil, ErrNoSig
324 - }
325 - return msg[:tsigoff], rr, nil
326 -}
327 -
328 -// Translate the TSIG time signed into a date. There is no
329 -// need for RFC1982 calculations as this date is 48 bits.
330 -func tsigTimeToString(t uint64) string {
331 - ti := time.Unix(int64(t), 0).UTC()
332 - return ti.Format("20060102150405")
333 -}
Godeps/_workspace/src/github.com/miekg/dns/types.go deleted
-1737
@@ -1,1737 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "encoding/base64"
5 - "fmt"
6 - "net"
7 - "strconv"
8 - "strings"
9 - "time"
10 -)
11 -
12 -type (
13 - // Type is a DNS type.
14 - Type uint16
15 - // Class is a DNS class.
16 - Class uint16
17 - // Name is a DNS domain name.
18 - Name string
19 -)
20 -
21 -// Packet formats
22 -
23 -// Wire constants and supported types.
24 -const (
25 - // valid RR_Header.Rrtype and Question.qtype
26 -
27 - TypeNone uint16 = 0
28 - TypeA uint16 = 1
29 - TypeNS uint16 = 2
30 - TypeMD uint16 = 3
31 - TypeMF uint16 = 4
32 - TypeCNAME uint16 = 5
33 - TypeSOA uint16 = 6
34 - TypeMB uint16 = 7
35 - TypeMG uint16 = 8
36 - TypeMR uint16 = 9
37 - TypeNULL uint16 = 10
38 - TypeWKS uint16 = 11
39 - TypePTR uint16 = 12
40 - TypeHINFO uint16 = 13
41 - TypeMINFO uint16 = 14
42 - TypeMX uint16 = 15
43 - TypeTXT uint16 = 16
44 - TypeRP uint16 = 17
45 - TypeAFSDB uint16 = 18
46 - TypeX25 uint16 = 19
47 - TypeISDN uint16 = 20
48 - TypeRT uint16 = 21
49 - TypeNSAP uint16 = 22
50 - TypeNSAPPTR uint16 = 23
51 - TypeSIG uint16 = 24
52 - TypeKEY uint16 = 25
53 - TypePX uint16 = 26
54 - TypeGPOS uint16 = 27
55 - TypeAAAA uint16 = 28
56 - TypeLOC uint16 = 29
57 - TypeNXT uint16 = 30
58 - TypeEID uint16 = 31
59 - TypeNIMLOC uint16 = 32
60 - TypeSRV uint16 = 33
61 - TypeATMA uint16 = 34
62 - TypeNAPTR uint16 = 35
63 - TypeKX uint16 = 36
64 - TypeCERT uint16 = 37
65 - TypeDNAME uint16 = 39
66 - TypeOPT uint16 = 41 // EDNS
67 - TypeDS uint16 = 43
68 - TypeSSHFP uint16 = 44
69 - TypeIPSECKEY uint16 = 45
70 - TypeRRSIG uint16 = 46
71 - TypeNSEC uint16 = 47
72 - TypeDNSKEY uint16 = 48
73 - TypeDHCID uint16 = 49
74 - TypeNSEC3 uint16 = 50
75 - TypeNSEC3PARAM uint16 = 51
76 - TypeTLSA uint16 = 52
77 - TypeHIP uint16 = 55
78 - TypeNINFO uint16 = 56
79 - TypeRKEY uint16 = 57
80 - TypeTALINK uint16 = 58
81 - TypeCDS uint16 = 59
82 - TypeCDNSKEY uint16 = 60
83 - TypeOPENPGPKEY uint16 = 61
84 - TypeSPF uint16 = 99
85 - TypeUINFO uint16 = 100
86 - TypeUID uint16 = 101
87 - TypeGID uint16 = 102
88 - TypeUNSPEC uint16 = 103
89 - TypeNID uint16 = 104
90 - TypeL32 uint16 = 105
91 - TypeL64 uint16 = 106
92 - TypeLP uint16 = 107
93 - TypeEUI48 uint16 = 108
94 - TypeEUI64 uint16 = 109
95 -
96 - TypeTKEY uint16 = 249
97 - TypeTSIG uint16 = 250
98 -
99 - // valid Question.Qtype only
100 -
101 - TypeIXFR uint16 = 251
102 - TypeAXFR uint16 = 252
103 - TypeMAILB uint16 = 253
104 - TypeMAILA uint16 = 254
105 - TypeANY uint16 = 255
106 -
107 - TypeURI uint16 = 256
108 - TypeCAA uint16 = 257
109 - TypeTA uint16 = 32768
110 - TypeDLV uint16 = 32769
111 - TypeReserved uint16 = 65535
112 -
113 - // valid Question.Qclass
114 -
115 - ClassINET = 1
116 - ClassCSNET = 2
117 - ClassCHAOS = 3
118 - ClassHESIOD = 4
119 - ClassNONE = 254
120 - ClassANY = 255
121 -
122 - // Msg.rcode
123 -
124 - RcodeSuccess = 0
125 - RcodeFormatError = 1
126 - RcodeServerFailure = 2
127 - RcodeNameError = 3
128 - RcodeNotImplemented = 4
129 - RcodeRefused = 5
130 - RcodeYXDomain = 6
131 - RcodeYXRrset = 7
132 - RcodeNXRrset = 8
133 - RcodeNotAuth = 9
134 - RcodeNotZone = 10
135 - RcodeBadSig = 16 // TSIG
136 - RcodeBadVers = 16 // EDNS0
137 - RcodeBadKey = 17
138 - RcodeBadTime = 18
139 - RcodeBadMode = 19 // TKEY
140 - RcodeBadName = 20
141 - RcodeBadAlg = 21
142 - RcodeBadTrunc = 22 // TSIG
143 -
144 - // Opcode, there is no 3
145 -
146 - OpcodeQuery = 0
147 - OpcodeIQuery = 1
148 - OpcodeStatus = 2
149 - OpcodeNotify = 4
150 - OpcodeUpdate = 5
151 -)
152 -
153 -// The wire format for the DNS packet header.
154 -type Header struct {
155 - Id uint16
156 - Bits uint16
157 - Qdcount, Ancount, Nscount, Arcount uint16
158 -}
159 -
160 -const (
161 - // Header.Bits
162 - _QR = 1 << 15 // query/response (response=1)
163 - _AA = 1 << 10 // authoritative
164 - _TC = 1 << 9 // truncated
165 - _RD = 1 << 8 // recursion desired
166 - _RA = 1 << 7 // recursion available
167 - _Z = 1 << 6 // Z
168 - _AD = 1 << 5 // authticated data
169 - _CD = 1 << 4 // checking disabled
170 -
171 - LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
172 - LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2.
173 -
174 - LOC_HOURS = 60 * 1000
175 - LOC_DEGREES = 60 * LOC_HOURS
176 -
177 - LOC_ALTITUDEBASE = 100000
178 -)
179 -
180 -// RFC 4398, Section 2.1
181 -const (
182 - CertPKIX = 1 + iota
183 - CertSPKI
184 - CertPGP
185 - CertIPIX
186 - CertISPKI
187 - CertIPGP
188 - CertACPKIX
189 - CertIACPKIX
190 - CertURI = 253
191 - CertOID = 254
192 -)
193 -
194 -var CertTypeToString = map[uint16]string{
195 - CertPKIX: "PKIX",
196 - CertSPKI: "SPKI",
197 - CertPGP: "PGP",
198 - CertIPIX: "IPIX",
199 - CertISPKI: "ISPKI",
200 - CertIPGP: "IPGP",
201 - CertACPKIX: "ACPKIX",
202 - CertIACPKIX: "IACPKIX",
203 - CertURI: "URI",
204 - CertOID: "OID",
205 -}
206 -
207 -var StringToCertType = reverseInt16(CertTypeToString)
208 -
209 -// Question holds a DNS question. There can be multiple questions in the
210 -// question section of a message. Usually there is just one.
211 -type Question struct {
212 - Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed)
213 - Qtype uint16
214 - Qclass uint16
215 -}
216 -
217 -func (q *Question) String() (s string) {
218 - // prefix with ; (as in dig)
219 - s = ";" + sprintName(q.Name) + "\t"
220 - s += Class(q.Qclass).String() + "\t"
221 - s += " " + Type(q.Qtype).String()
222 - return s
223 -}
224 -
225 -func (q *Question) len() int {
226 - l := len(q.Name) + 1
227 - return l + 4
228 -}
229 -
230 -type ANY struct {
231 - Hdr RR_Header
232 - // Does not have any rdata
233 -}
234 -
235 -func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
236 -func (rr *ANY) copy() RR { return &ANY{*rr.Hdr.copyHeader()} }
237 -func (rr *ANY) String() string { return rr.Hdr.String() }
238 -func (rr *ANY) len() int { return rr.Hdr.len() }
239 -
240 -type CNAME struct {
241 - Hdr RR_Header
242 - Target string `dns:"cdomain-name"`
243 -}
244 -
245 -func (rr *CNAME) Header() *RR_Header { return &rr.Hdr }
246 -func (rr *CNAME) copy() RR { return &CNAME{*rr.Hdr.copyHeader(), sprintName(rr.Target)} }
247 -func (rr *CNAME) String() string { return rr.Hdr.String() + rr.Target }
248 -func (rr *CNAME) len() int { return rr.Hdr.len() + len(rr.Target) + 1 }
249 -
250 -type HINFO struct {
251 - Hdr RR_Header
252 - Cpu string
253 - Os string
254 -}
255 -
256 -func (rr *HINFO) Header() *RR_Header { return &rr.Hdr }
257 -func (rr *HINFO) copy() RR { return &HINFO{*rr.Hdr.copyHeader(), rr.Cpu, rr.Os} }
258 -func (rr *HINFO) String() string { return rr.Hdr.String() + rr.Cpu + " " + rr.Os }
259 -func (rr *HINFO) len() int { return rr.Hdr.len() + len(rr.Cpu) + len(rr.Os) }
260 -
261 -type MB struct {
262 - Hdr RR_Header
263 - Mb string `dns:"cdomain-name"`
264 -}
265 -
266 -func (rr *MB) Header() *RR_Header { return &rr.Hdr }
267 -func (rr *MB) copy() RR { return &MB{*rr.Hdr.copyHeader(), sprintName(rr.Mb)} }
268 -
269 -func (rr *MB) String() string { return rr.Hdr.String() + rr.Mb }
270 -func (rr *MB) len() int { return rr.Hdr.len() + len(rr.Mb) + 1 }
271 -
272 -type MG struct {
273 - Hdr RR_Header
274 - Mg string `dns:"cdomain-name"`
275 -}
276 -
277 -func (rr *MG) Header() *RR_Header { return &rr.Hdr }
278 -func (rr *MG) copy() RR { return &MG{*rr.Hdr.copyHeader(), rr.Mg} }
279 -func (rr *MG) len() int { l := len(rr.Mg) + 1; return rr.Hdr.len() + l }
280 -func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) }
281 -
282 -type MINFO struct {
283 - Hdr RR_Header
284 - Rmail string `dns:"cdomain-name"`
285 - Email string `dns:"cdomain-name"`
286 -}
287 -
288 -func (rr *MINFO) Header() *RR_Header { return &rr.Hdr }
289 -func (rr *MINFO) copy() RR { return &MINFO{*rr.Hdr.copyHeader(), rr.Rmail, rr.Email} }
290 -
291 -func (rr *MINFO) String() string {
292 - return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email)
293 -}
294 -
295 -func (rr *MINFO) len() int {
296 - l := len(rr.Rmail) + 1
297 - n := len(rr.Email) + 1
298 - return rr.Hdr.len() + l + n
299 -}
300 -
301 -type MR struct {
302 - Hdr RR_Header
303 - Mr string `dns:"cdomain-name"`
304 -}
305 -
306 -func (rr *MR) Header() *RR_Header { return &rr.Hdr }
307 -func (rr *MR) copy() RR { return &MR{*rr.Hdr.copyHeader(), rr.Mr} }
308 -func (rr *MR) len() int { l := len(rr.Mr) + 1; return rr.Hdr.len() + l }
309 -
310 -func (rr *MR) String() string {
311 - return rr.Hdr.String() + sprintName(rr.Mr)
312 -}
313 -
314 -type MF struct {
315 - Hdr RR_Header
316 - Mf string `dns:"cdomain-name"`
317 -}
318 -
319 -func (rr *MF) Header() *RR_Header { return &rr.Hdr }
320 -func (rr *MF) copy() RR { return &MF{*rr.Hdr.copyHeader(), rr.Mf} }
321 -func (rr *MF) len() int { return rr.Hdr.len() + len(rr.Mf) + 1 }
322 -
323 -func (rr *MF) String() string {
324 - return rr.Hdr.String() + sprintName(rr.Mf)
325 -}
326 -
327 -type MD struct {
328 - Hdr RR_Header
329 - Md string `dns:"cdomain-name"`
330 -}
331 -
332 -func (rr *MD) Header() *RR_Header { return &rr.Hdr }
333 -func (rr *MD) copy() RR { return &MD{*rr.Hdr.copyHeader(), rr.Md} }
334 -func (rr *MD) len() int { return rr.Hdr.len() + len(rr.Md) + 1 }
335 -
336 -func (rr *MD) String() string {
337 - return rr.Hdr.String() + sprintName(rr.Md)
338 -}
339 -
340 -type MX struct {
341 - Hdr RR_Header
342 - Preference uint16
343 - Mx string `dns:"cdomain-name"`
344 -}
345 -
346 -func (rr *MX) Header() *RR_Header { return &rr.Hdr }
347 -func (rr *MX) copy() RR { return &MX{*rr.Hdr.copyHeader(), rr.Preference, rr.Mx} }
348 -func (rr *MX) len() int { l := len(rr.Mx) + 1; return rr.Hdr.len() + l + 2 }
349 -
350 -func (rr *MX) String() string {
351 - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx)
352 -}
353 -
354 -type AFSDB struct {
355 - Hdr RR_Header
356 - Subtype uint16
357 - Hostname string `dns:"cdomain-name"`
358 -}
359 -
360 -func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
361 -func (rr *AFSDB) copy() RR { return &AFSDB{*rr.Hdr.copyHeader(), rr.Subtype, rr.Hostname} }
362 -func (rr *AFSDB) len() int { l := len(rr.Hostname) + 1; return rr.Hdr.len() + l + 2 }
363 -
364 -func (rr *AFSDB) String() string {
365 - return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname)
366 -}
367 -
368 -type X25 struct {
369 - Hdr RR_Header
370 - PSDNAddress string
371 -}
372 -
373 -func (rr *X25) Header() *RR_Header { return &rr.Hdr }
374 -func (rr *X25) copy() RR { return &X25{*rr.Hdr.copyHeader(), rr.PSDNAddress} }
375 -func (rr *X25) len() int { return rr.Hdr.len() + len(rr.PSDNAddress) + 1 }
376 -
377 -func (rr *X25) String() string {
378 - return rr.Hdr.String() + rr.PSDNAddress
379 -}
380 -
381 -type RT struct {
382 - Hdr RR_Header
383 - Preference uint16
384 - Host string `dns:"cdomain-name"`
385 -}
386 -
387 -func (rr *RT) Header() *RR_Header { return &rr.Hdr }
388 -func (rr *RT) copy() RR { return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host} }
389 -func (rr *RT) len() int { l := len(rr.Host) + 1; return rr.Hdr.len() + l + 2 }
390 -
391 -func (rr *RT) String() string {
392 - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host)
393 -}
394 -
395 -type NS struct {
396 - Hdr RR_Header
397 - Ns string `dns:"cdomain-name"`
398 -}
399 -
400 -func (rr *NS) Header() *RR_Header { return &rr.Hdr }
401 -func (rr *NS) len() int { l := len(rr.Ns) + 1; return rr.Hdr.len() + l }
402 -func (rr *NS) copy() RR { return &NS{*rr.Hdr.copyHeader(), rr.Ns} }
403 -
404 -func (rr *NS) String() string {
405 - return rr.Hdr.String() + sprintName(rr.Ns)
406 -}
407 -
408 -type PTR struct {
409 - Hdr RR_Header
410 - Ptr string `dns:"cdomain-name"`
411 -}
412 -
413 -func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
414 -func (rr *PTR) copy() RR { return &PTR{*rr.Hdr.copyHeader(), rr.Ptr} }
415 -func (rr *PTR) len() int { l := len(rr.Ptr) + 1; return rr.Hdr.len() + l }
416 -
417 -func (rr *PTR) String() string {
418 - return rr.Hdr.String() + sprintName(rr.Ptr)
419 -}
420 -
421 -type RP struct {
422 - Hdr RR_Header
423 - Mbox string `dns:"domain-name"`
424 - Txt string `dns:"domain-name"`
425 -}
426 -
427 -func (rr *RP) Header() *RR_Header { return &rr.Hdr }
428 -func (rr *RP) copy() RR { return &RP{*rr.Hdr.copyHeader(), rr.Mbox, rr.Txt} }
429 -func (rr *RP) len() int { return rr.Hdr.len() + len(rr.Mbox) + 1 + len(rr.Txt) + 1 }
430 -
431 -func (rr *RP) String() string {
432 - return rr.Hdr.String() + rr.Mbox + " " + sprintTxt([]string{rr.Txt})
433 -}
434 -
435 -type SOA struct {
436 - Hdr RR_Header
437 - Ns string `dns:"cdomain-name"`
438 - Mbox string `dns:"cdomain-name"`
439 - Serial uint32
440 - Refresh uint32
441 - Retry uint32
442 - Expire uint32
443 - Minttl uint32
444 -}
445 -
446 -func (rr *SOA) Header() *RR_Header { return &rr.Hdr }
447 -func (rr *SOA) copy() RR {
448 - return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
449 -}
450 -
451 -func (rr *SOA) String() string {
452 - return rr.Hdr.String() + sprintName(rr.Ns) + " " + sprintName(rr.Mbox) +
453 - " " + strconv.FormatInt(int64(rr.Serial), 10) +
454 - " " + strconv.FormatInt(int64(rr.Refresh), 10) +
455 - " " + strconv.FormatInt(int64(rr.Retry), 10) +
456 - " " + strconv.FormatInt(int64(rr.Expire), 10) +
457 - " " + strconv.FormatInt(int64(rr.Minttl), 10)
458 -}
459 -
460 -func (rr *SOA) len() int {
461 - l := len(rr.Ns) + 1
462 - n := len(rr.Mbox) + 1
463 - return rr.Hdr.len() + l + n + 20
464 -}
465 -
466 -type TXT struct {
467 - Hdr RR_Header
468 - Txt []string `dns:"txt"`
469 -}
470 -
471 -func (rr *TXT) Header() *RR_Header { return &rr.Hdr }
472 -func (rr *TXT) copy() RR {
473 - cp := make([]string, len(rr.Txt), cap(rr.Txt))
474 - copy(cp, rr.Txt)
475 - return &TXT{*rr.Hdr.copyHeader(), cp}
476 -}
477 -
478 -func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
479 -
480 -func sprintName(s string) string {
481 - src := []byte(s)
482 - dst := make([]byte, 0, len(src))
483 - for i := 0; i < len(src); {
484 - if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' {
485 - dst = append(dst, src[i:i+2]...)
486 - i += 2
487 - } else {
488 - b, n := nextByte(src, i)
489 - if n == 0 {
490 - i++ // dangling back slash
491 - } else if b == '.' {
492 - dst = append(dst, b)
493 - } else {
494 - dst = appendDomainNameByte(dst, b)
495 - }
496 - i += n
497 - }
498 - }
499 - return string(dst)
500 -}
501 -
502 -func sprintTxt(txt []string) string {
503 - var out []byte
504 - for i, s := range txt {
505 - if i > 0 {
506 - out = append(out, ` "`...)
507 - } else {
508 - out = append(out, '"')
509 - }
510 - bs := []byte(s)
511 - for j := 0; j < len(bs); {
512 - b, n := nextByte(bs, j)
513 - if n == 0 {
514 - break
515 - }
516 - out = appendTXTStringByte(out, b)
517 - j += n
518 - }
519 - out = append(out, '"')
520 - }
521 - return string(out)
522 -}
523 -
524 -func appendDomainNameByte(s []byte, b byte) []byte {
525 - switch b {
526 - case '.', ' ', '\'', '@', ';', '(', ')': // additional chars to escape
527 - return append(s, '\\', b)
528 - }
529 - return appendTXTStringByte(s, b)
530 -}
531 -
532 -func appendTXTStringByte(s []byte, b byte) []byte {
533 - switch b {
534 - case '\t':
535 - return append(s, '\\', 't')
536 - case '\r':
537 - return append(s, '\\', 'r')
538 - case '\n':
539 - return append(s, '\\', 'n')
540 - case '"', '\\':
541 - return append(s, '\\', b)
542 - }
543 - if b < ' ' || b > '~' {
544 - var buf [3]byte
545 - bufs := strconv.AppendInt(buf[:0], int64(b), 10)
546 - s = append(s, '\\')
547 - for i := 0; i < 3-len(bufs); i++ {
548 - s = append(s, '0')
549 - }
550 - for _, r := range bufs {
551 - s = append(s, r)
552 - }
553 - return s
554 -
555 - }
556 - return append(s, b)
557 -}
558 -
559 -func nextByte(b []byte, offset int) (byte, int) {
560 - if offset >= len(b) {
561 - return 0, 0
562 - }
563 - if b[offset] != '\\' {
564 - // not an escape sequence
565 - return b[offset], 1
566 - }
567 - switch len(b) - offset {
568 - case 1: // dangling escape
569 - return 0, 0
570 - case 2, 3: // too short to be \ddd
571 - default: // maybe \ddd
572 - if isDigit(b[offset+1]) && isDigit(b[offset+2]) && isDigit(b[offset+3]) {
573 - return dddToByte(b[offset+1:]), 4
574 - }
575 - }
576 - // not \ddd, maybe a control char
577 - switch b[offset+1] {
578 - case 't':
579 - return '\t', 2
580 - case 'r':
581 - return '\r', 2
582 - case 'n':
583 - return '\n', 2
584 - default:
585 - return b[offset+1], 2
586 - }
587 -}
588 -
589 -func (rr *TXT) len() int {
590 - l := rr.Hdr.len()
591 - for _, t := range rr.Txt {
592 - l += len(t) + 1
593 - }
594 - return l
595 -}
596 -
597 -type SPF struct {
598 - Hdr RR_Header
599 - Txt []string `dns:"txt"`
600 -}
601 -
602 -func (rr *SPF) Header() *RR_Header { return &rr.Hdr }
603 -func (rr *SPF) copy() RR {
604 - cp := make([]string, len(rr.Txt), cap(rr.Txt))
605 - copy(cp, rr.Txt)
606 - return &SPF{*rr.Hdr.copyHeader(), cp}
607 -}
608 -
609 -func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
610 -
611 -func (rr *SPF) len() int {
612 - l := rr.Hdr.len()
613 - for _, t := range rr.Txt {
614 - l += len(t) + 1
615 - }
616 - return l
617 -}
618 -
619 -type SRV struct {
620 - Hdr RR_Header
621 - Priority uint16
622 - Weight uint16
623 - Port uint16
624 - Target string `dns:"domain-name"`
625 -}
626 -
627 -func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
628 -func (rr *SRV) len() int { l := len(rr.Target) + 1; return rr.Hdr.len() + l + 6 }
629 -func (rr *SRV) copy() RR {
630 - return &SRV{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Port, rr.Target}
631 -}
632 -
633 -func (rr *SRV) String() string {
634 - return rr.Hdr.String() +
635 - strconv.Itoa(int(rr.Priority)) + " " +
636 - strconv.Itoa(int(rr.Weight)) + " " +
637 - strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target)
638 -}
639 -
640 -type NAPTR struct {
641 - Hdr RR_Header
642 - Order uint16
643 - Preference uint16
644 - Flags string
645 - Service string
646 - Regexp string
647 - Replacement string `dns:"domain-name"`
648 -}
649 -
650 -func (rr *NAPTR) Header() *RR_Header { return &rr.Hdr }
651 -func (rr *NAPTR) copy() RR {
652 - return &NAPTR{*rr.Hdr.copyHeader(), rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement}
653 -}
654 -
655 -func (rr *NAPTR) String() string {
656 - return rr.Hdr.String() +
657 - strconv.Itoa(int(rr.Order)) + " " +
658 - strconv.Itoa(int(rr.Preference)) + " " +
659 - "\"" + rr.Flags + "\" " +
660 - "\"" + rr.Service + "\" " +
661 - "\"" + rr.Regexp + "\" " +
662 - rr.Replacement
663 -}
664 -
665 -func (rr *NAPTR) len() int {
666 - return rr.Hdr.len() + 4 + len(rr.Flags) + 1 + len(rr.Service) + 1 +
667 - len(rr.Regexp) + 1 + len(rr.Replacement) + 1
668 -}
669 -
670 -// See RFC 4398.
671 -type CERT struct {
672 - Hdr RR_Header
673 - Type uint16
674 - KeyTag uint16
675 - Algorithm uint8
676 - Certificate string `dns:"base64"`
677 -}
678 -
679 -func (rr *CERT) Header() *RR_Header { return &rr.Hdr }
680 -func (rr *CERT) copy() RR {
681 - return &CERT{*rr.Hdr.copyHeader(), rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
682 -}
683 -
684 -func (rr *CERT) String() string {
685 - var (
686 - ok bool
687 - certtype, algorithm string
688 - )
689 - if certtype, ok = CertTypeToString[rr.Type]; !ok {
690 - certtype = strconv.Itoa(int(rr.Type))
691 - }
692 - if algorithm, ok = AlgorithmToString[rr.Algorithm]; !ok {
693 - algorithm = strconv.Itoa(int(rr.Algorithm))
694 - }
695 - return rr.Hdr.String() + certtype +
696 - " " + strconv.Itoa(int(rr.KeyTag)) +
697 - " " + algorithm +
698 - " " + rr.Certificate
699 -}
700 -
701 -func (rr *CERT) len() int {
702 - return rr.Hdr.len() + 5 +
703 - base64.StdEncoding.DecodedLen(len(rr.Certificate))
704 -}
705 -
706 -// See RFC 2672.
707 -type DNAME struct {
708 - Hdr RR_Header
709 - Target string `dns:"domain-name"`
710 -}
711 -
712 -func (rr *DNAME) Header() *RR_Header { return &rr.Hdr }
713 -func (rr *DNAME) copy() RR { return &DNAME{*rr.Hdr.copyHeader(), rr.Target} }
714 -func (rr *DNAME) len() int { l := len(rr.Target) + 1; return rr.Hdr.len() + l }
715 -
716 -func (rr *DNAME) String() string {
717 - return rr.Hdr.String() + sprintName(rr.Target)
718 -}
719 -
720 -type A struct {
721 - Hdr RR_Header
722 - A net.IP `dns:"a"`
723 -}
724 -
725 -func (rr *A) Header() *RR_Header { return &rr.Hdr }
726 -func (rr *A) copy() RR { return &A{*rr.Hdr.copyHeader(), copyIP(rr.A)} }
727 -func (rr *A) len() int { return rr.Hdr.len() + net.IPv4len }
728 -
729 -func (rr *A) String() string {
730 - if rr.A == nil {
731 - return rr.Hdr.String()
732 - }
733 - return rr.Hdr.String() + rr.A.String()
734 -}
735 -
736 -type AAAA struct {
737 - Hdr RR_Header
738 - AAAA net.IP `dns:"aaaa"`
739 -}
740 -
741 -func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
742 -func (rr *AAAA) copy() RR { return &AAAA{*rr.Hdr.copyHeader(), copyIP(rr.AAAA)} }
743 -func (rr *AAAA) len() int { return rr.Hdr.len() + net.IPv6len }
744 -
745 -func (rr *AAAA) String() string {
746 - if rr.AAAA == nil {
747 - return rr.Hdr.String()
748 - }
749 - return rr.Hdr.String() + rr.AAAA.String()
750 -}
751 -
752 -type PX struct {
753 - Hdr RR_Header
754 - Preference uint16
755 - Map822 string `dns:"domain-name"`
756 - Mapx400 string `dns:"domain-name"`
757 -}
758 -
759 -func (rr *PX) Header() *RR_Header { return &rr.Hdr }
760 -func (rr *PX) copy() RR { return &PX{*rr.Hdr.copyHeader(), rr.Preference, rr.Map822, rr.Mapx400} }
761 -func (rr *PX) String() string {
762 - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400)
763 -}
764 -func (rr *PX) len() int { return rr.Hdr.len() + 2 + len(rr.Map822) + 1 + len(rr.Mapx400) + 1 }
765 -
766 -type GPOS struct {
767 - Hdr RR_Header
768 - Longitude string
769 - Latitude string
770 - Altitude string
771 -}
772 -
773 -func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
774 -func (rr *GPOS) copy() RR { return &GPOS{*rr.Hdr.copyHeader(), rr.Longitude, rr.Latitude, rr.Altitude} }
775 -func (rr *GPOS) len() int {
776 - return rr.Hdr.len() + len(rr.Longitude) + len(rr.Latitude) + len(rr.Altitude) + 3
777 -}
778 -func (rr *GPOS) String() string {
779 - return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude
780 -}
781 -
782 -type LOC struct {
783 - Hdr RR_Header
784 - Version uint8
785 - Size uint8
786 - HorizPre uint8
787 - VertPre uint8
788 - Latitude uint32
789 - Longitude uint32
790 - Altitude uint32
791 -}
792 -
793 -func (rr *LOC) Header() *RR_Header { return &rr.Hdr }
794 -func (rr *LOC) len() int { return rr.Hdr.len() + 4 + 12 }
795 -func (rr *LOC) copy() RR {
796 - return &LOC{*rr.Hdr.copyHeader(), rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude}
797 -}
798 -
799 -// cmToM takes a cm value expressed in RFC1876 SIZE mantissa/exponent
800 -// format and returns a string in m (two decimals for the cm)
801 -func cmToM(m, e uint8) string {
802 - if e < 2 {
803 - if e == 1 {
804 - m *= 10
805 - }
806 -
807 - return fmt.Sprintf("0.%02d", m)
808 - }
809 -
810 - s := fmt.Sprintf("%d", m)
811 - for e > 2 {
812 - s += "0"
813 - e--
814 - }
815 - return s
816 -}
817 -
818 -// String returns a string version of a LOC
819 -func (rr *LOC) String() string {
820 - s := rr.Hdr.String()
821 -
822 - lat := rr.Latitude
823 - ns := "N"
824 - if lat > LOC_EQUATOR {
825 - lat = lat - LOC_EQUATOR
826 - } else {
827 - ns = "S"
828 - lat = LOC_EQUATOR - lat
829 - }
830 - h := lat / LOC_DEGREES
831 - lat = lat % LOC_DEGREES
832 - m := lat / LOC_HOURS
833 - lat = lat % LOC_HOURS
834 - s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lat) / 1000), ns)
835 -
836 - lon := rr.Longitude
837 - ew := "E"
838 - if lon > LOC_PRIMEMERIDIAN {
839 - lon = lon - LOC_PRIMEMERIDIAN
840 - } else {
841 - ew = "W"
842 - lon = LOC_PRIMEMERIDIAN - lon
843 - }
844 - h = lon / LOC_DEGREES
845 - lon = lon % LOC_DEGREES
846 - m = lon / LOC_HOURS
847 - lon = lon % LOC_HOURS
848 - s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lon) / 1000), ew)
849 -
850 - var alt = float64(rr.Altitude) / 100
851 - alt -= LOC_ALTITUDEBASE
852 - if rr.Altitude%100 != 0 {
853 - s += fmt.Sprintf("%.2fm ", alt)
854 - } else {
855 - s += fmt.Sprintf("%.0fm ", alt)
856 - }
857 -
858 - s += cmToM((rr.Size&0xf0)>>4, rr.Size&0x0f) + "m "
859 - s += cmToM((rr.HorizPre&0xf0)>>4, rr.HorizPre&0x0f) + "m "
860 - s += cmToM((rr.VertPre&0xf0)>>4, rr.VertPre&0x0f) + "m"
861 -
862 - return s
863 -}
864 -
865 -// SIG is identical to RRSIG and nowadays only used for SIG(0), RFC2931.
866 -type SIG struct {
867 - RRSIG
868 -}
869 -
870 -type RRSIG struct {
871 - Hdr RR_Header
872 - TypeCovered uint16
873 - Algorithm uint8
874 - Labels uint8
875 - OrigTtl uint32
876 - Expiration uint32
877 - Inception uint32
878 - KeyTag uint16
879 - SignerName string `dns:"domain-name"`
880 - Signature string `dns:"base64"`
881 -}
882 -
883 -func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr }
884 -func (rr *RRSIG) copy() RR {
885 - return &RRSIG{*rr.Hdr.copyHeader(), rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature}
886 -}
887 -
888 -func (rr *RRSIG) String() string {
889 - s := rr.Hdr.String()
890 - s += Type(rr.TypeCovered).String()
891 - s += " " + strconv.Itoa(int(rr.Algorithm)) +
892 - " " + strconv.Itoa(int(rr.Labels)) +
893 - " " + strconv.FormatInt(int64(rr.OrigTtl), 10) +
894 - " " + TimeToString(rr.Expiration) +
895 - " " + TimeToString(rr.Inception) +
896 - " " + strconv.Itoa(int(rr.KeyTag)) +
897 - " " + sprintName(rr.SignerName) +
898 - " " + rr.Signature
899 - return s
900 -}
901 -
902 -func (rr *RRSIG) len() int {
903 - return rr.Hdr.len() + len(rr.SignerName) + 1 +
904 - base64.StdEncoding.DecodedLen(len(rr.Signature)) + 18
905 -}
906 -
907 -type NSEC struct {
908 - Hdr RR_Header
909 - NextDomain string `dns:"domain-name"`
910 - TypeBitMap []uint16 `dns:"nsec"`
911 -}
912 -
913 -func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
914 -func (rr *NSEC) copy() RR {
915 - cp := make([]uint16, len(rr.TypeBitMap), cap(rr.TypeBitMap))
916 - copy(cp, rr.TypeBitMap)
917 - return &NSEC{*rr.Hdr.copyHeader(), rr.NextDomain, cp}
918 -}
919 -
920 -func (rr *NSEC) String() string {
921 - s := rr.Hdr.String() + sprintName(rr.NextDomain)
922 - for i := 0; i < len(rr.TypeBitMap); i++ {
923 - s += " " + Type(rr.TypeBitMap[i]).String()
924 - }
925 - return s
926 -}
927 -
928 -func (rr *NSEC) len() int {
929 - l := rr.Hdr.len() + len(rr.NextDomain) + 1
930 - lastwindow := uint32(2 ^ 32 + 1)
931 - for _, t := range rr.TypeBitMap {
932 - window := t / 256
933 - if uint32(window) != lastwindow {
934 - l += 1 + 32
935 - }
936 - lastwindow = uint32(window)
937 - }
938 - return l
939 -}
940 -
941 -type DLV struct {
942 - DS
943 -}
944 -
945 -type CDS struct {
946 - DS
947 -}
948 -
949 -type DS struct {
950 - Hdr RR_Header
951 - KeyTag uint16
952 - Algorithm uint8
953 - DigestType uint8
954 - Digest string `dns:"hex"`
955 -}
956 -
957 -func (rr *DS) Header() *RR_Header { return &rr.Hdr }
958 -func (rr *DS) len() int { return rr.Hdr.len() + 4 + len(rr.Digest)/2 }
959 -func (rr *DS) copy() RR {
960 - return &DS{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
961 -}
962 -
963 -func (rr *DS) String() string {
964 - return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
965 - " " + strconv.Itoa(int(rr.Algorithm)) +
966 - " " + strconv.Itoa(int(rr.DigestType)) +
967 - " " + strings.ToUpper(rr.Digest)
968 -}
969 -
970 -type KX struct {
971 - Hdr RR_Header
972 - Preference uint16
973 - Exchanger string `dns:"domain-name"`
974 -}
975 -
976 -func (rr *KX) Header() *RR_Header { return &rr.Hdr }
977 -func (rr *KX) len() int { return rr.Hdr.len() + 2 + len(rr.Exchanger) + 1 }
978 -func (rr *KX) copy() RR { return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger} }
979 -
980 -func (rr *KX) String() string {
981 - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
982 - " " + sprintName(rr.Exchanger)
983 -}
984 -
985 -type TA struct {
986 - Hdr RR_Header
987 - KeyTag uint16
988 - Algorithm uint8
989 - DigestType uint8
990 - Digest string `dns:"hex"`
991 -}
992 -
993 -func (rr *TA) Header() *RR_Header { return &rr.Hdr }
994 -func (rr *TA) len() int { return rr.Hdr.len() + 4 + len(rr.Digest)/2 }
995 -func (rr *TA) copy() RR {
996 - return &TA{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
997 -}
998 -
999 -func (rr *TA) String() string {
1000 - return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) +
1001 - " " + strconv.Itoa(int(rr.Algorithm)) +
1002 - " " + strconv.Itoa(int(rr.DigestType)) +
1003 - " " + strings.ToUpper(rr.Digest)
1004 -}
1005 -
1006 -type TALINK struct {
1007 - Hdr RR_Header
1008 - PreviousName string `dns:"domain-name"`
1009 - NextName string `dns:"domain-name"`
1010 -}
1011 -
1012 -func (rr *TALINK) Header() *RR_Header { return &rr.Hdr }
1013 -func (rr *TALINK) copy() RR { return &TALINK{*rr.Hdr.copyHeader(), rr.PreviousName, rr.NextName} }
1014 -func (rr *TALINK) len() int { return rr.Hdr.len() + len(rr.PreviousName) + len(rr.NextName) + 2 }
1015 -
1016 -func (rr *TALINK) String() string {
1017 - return rr.Hdr.String() +
1018 - sprintName(rr.PreviousName) + " " + sprintName(rr.NextName)
1019 -}
1020 -
1021 -type SSHFP struct {
1022 - Hdr RR_Header
1023 - Algorithm uint8
1024 - Type uint8
1025 - FingerPrint string `dns:"hex"`
1026 -}
1027 -
1028 -func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr }
1029 -func (rr *SSHFP) len() int { return rr.Hdr.len() + 2 + len(rr.FingerPrint)/2 }
1030 -func (rr *SSHFP) copy() RR {
1031 - return &SSHFP{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Type, rr.FingerPrint}
1032 -}
1033 -
1034 -func (rr *SSHFP) String() string {
1035 - return rr.Hdr.String() + strconv.Itoa(int(rr.Algorithm)) +
1036 - " " + strconv.Itoa(int(rr.Type)) +
1037 - " " + strings.ToUpper(rr.FingerPrint)
1038 -}
1039 -
1040 -type IPSECKEY struct {
1041 - Hdr RR_Header
1042 - Precedence uint8
1043 - // GatewayType: 1: A record, 2: AAAA record, 3: domainname.
1044 - // 0 is use for no type and GatewayName should be "." then.
1045 - GatewayType uint8
1046 - Algorithm uint8
1047 - // Gateway can be an A record, AAAA record or a domain name.
1048 - GatewayA net.IP `dns:"a"`
1049 - GatewayAAAA net.IP `dns:"aaaa"`
1050 - GatewayName string `dns:"domain-name"`
1051 - PublicKey string `dns:"base64"`
1052 -}
1053 -
1054 -func (rr *IPSECKEY) Header() *RR_Header { return &rr.Hdr }
1055 -func (rr *IPSECKEY) copy() RR {
1056 - return &IPSECKEY{*rr.Hdr.copyHeader(), rr.Precedence, rr.GatewayType, rr.Algorithm, rr.GatewayA, rr.GatewayAAAA, rr.GatewayName, rr.PublicKey}
1057 -}
1058 -
1059 -func (rr *IPSECKEY) String() string {
1060 - s := rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) +
1061 - " " + strconv.Itoa(int(rr.GatewayType)) +
1062 - " " + strconv.Itoa(int(rr.Algorithm))
1063 - switch rr.GatewayType {
1064 - case 0:
1065 - fallthrough
1066 - case 3:
1067 - s += " " + rr.GatewayName
1068 - case 1:
1069 - s += " " + rr.GatewayA.String()
1070 - case 2:
1071 - s += " " + rr.GatewayAAAA.String()
1072 - default:
1073 - s += " ."
1074 - }
1075 - s += " " + rr.PublicKey
1076 - return s
1077 -}
1078 -
1079 -func (rr *IPSECKEY) len() int {
1080 - l := rr.Hdr.len() + 3 + 1
1081 - switch rr.GatewayType {
1082 - default:
1083 - fallthrough
1084 - case 0:
1085 - fallthrough
1086 - case 3:
1087 - l += len(rr.GatewayName)
1088 - case 1:
1089 - l += 4
1090 - case 2:
1091 - l += 16
1092 - }
1093 - return l + base64.StdEncoding.DecodedLen(len(rr.PublicKey))
1094 -}
1095 -
1096 -type KEY struct {
1097 - DNSKEY
1098 -}
1099 -
1100 -type CDNSKEY struct {
1101 - DNSKEY
1102 -}
1103 -
1104 -type DNSKEY struct {
1105 - Hdr RR_Header
1106 - Flags uint16
1107 - Protocol uint8
1108 - Algorithm uint8
1109 - PublicKey string `dns:"base64"`
1110 -}
1111 -
1112 -func (rr *DNSKEY) Header() *RR_Header { return &rr.Hdr }
1113 -func (rr *DNSKEY) len() int {
1114 - return rr.Hdr.len() + 4 + base64.StdEncoding.DecodedLen(len(rr.PublicKey))
1115 -}
1116 -func (rr *DNSKEY) copy() RR {
1117 - return &DNSKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
1118 -}
1119 -
1120 -func (rr *DNSKEY) String() string {
1121 - return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
1122 - " " + strconv.Itoa(int(rr.Protocol)) +
1123 - " " + strconv.Itoa(int(rr.Algorithm)) +
1124 - " " + rr.PublicKey
1125 -}
1126 -
1127 -type RKEY struct {
1128 - Hdr RR_Header
1129 - Flags uint16
1130 - Protocol uint8
1131 - Algorithm uint8
1132 - PublicKey string `dns:"base64"`
1133 -}
1134 -
1135 -func (rr *RKEY) Header() *RR_Header { return &rr.Hdr }
1136 -func (rr *RKEY) len() int { return rr.Hdr.len() + 4 + base64.StdEncoding.DecodedLen(len(rr.PublicKey)) }
1137 -func (rr *RKEY) copy() RR {
1138 - return &RKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
1139 -}
1140 -
1141 -func (rr *RKEY) String() string {
1142 - return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) +
1143 - " " + strconv.Itoa(int(rr.Protocol)) +
1144 - " " + strconv.Itoa(int(rr.Algorithm)) +
1145 - " " + rr.PublicKey
1146 -}
1147 -
1148 -type NSAP struct {
1149 - Hdr RR_Header
1150 - Length uint8
1151 - Nsap string
1152 -}
1153 -
1154 -func (rr *NSAP) Header() *RR_Header { return &rr.Hdr }
1155 -func (rr *NSAP) copy() RR { return &NSAP{*rr.Hdr.copyHeader(), rr.Length, rr.Nsap} }
1156 -func (rr *NSAP) String() string { return rr.Hdr.String() + strconv.Itoa(int(rr.Length)) + " " + rr.Nsap }
1157 -func (rr *NSAP) len() int { return rr.Hdr.len() + 1 + len(rr.Nsap) + 1 }
1158 -
1159 -type NSAPPTR struct {
1160 - Hdr RR_Header
1161 - Ptr string `dns:"domain-name"`
1162 -}
1163 -
1164 -func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
1165 -func (rr *NSAPPTR) copy() RR { return &NSAPPTR{*rr.Hdr.copyHeader(), rr.Ptr} }
1166 -func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) }
1167 -func (rr *NSAPPTR) len() int { return rr.Hdr.len() + len(rr.Ptr) }
1168 -
1169 -type NSEC3 struct {
1170 - Hdr RR_Header
1171 - Hash uint8
1172 - Flags uint8
1173 - Iterations uint16
1174 - SaltLength uint8
1175 - Salt string `dns:"size-hex"`
1176 - HashLength uint8
1177 - NextDomain string `dns:"size-base32"`
1178 - TypeBitMap []uint16 `dns:"nsec"`
1179 -}
1180 -
1181 -func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
1182 -func (rr *NSEC3) copy() RR {
1183 - cp := make([]uint16, len(rr.TypeBitMap), cap(rr.TypeBitMap))
1184 - copy(cp, rr.TypeBitMap)
1185 - return &NSEC3{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, cp}
1186 -}
1187 -
1188 -func (rr *NSEC3) String() string {
1189 - s := rr.Hdr.String()
1190 - s += strconv.Itoa(int(rr.Hash)) +
1191 - " " + strconv.Itoa(int(rr.Flags)) +
1192 - " " + strconv.Itoa(int(rr.Iterations)) +
1193 - " " + saltToString(rr.Salt) +
1194 - " " + rr.NextDomain
1195 - for i := 0; i < len(rr.TypeBitMap); i++ {
1196 - s += " " + Type(rr.TypeBitMap[i]).String()
1197 - }
1198 - return s
1199 -}
1200 -
1201 -func (rr *NSEC3) len() int {
1202 - l := rr.Hdr.len() + 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1
1203 - lastwindow := uint32(2 ^ 32 + 1)
1204 - for _, t := range rr.TypeBitMap {
1205 - window := t / 256
1206 - if uint32(window) != lastwindow {
1207 - l += 1 + 32
1208 - }
1209 - lastwindow = uint32(window)
1210 - }
1211 - return l
1212 -}
1213 -
1214 -type NSEC3PARAM struct {
1215 - Hdr RR_Header
1216 - Hash uint8
1217 - Flags uint8
1218 - Iterations uint16
1219 - SaltLength uint8
1220 - Salt string `dns:"hex"`
1221 -}
1222 -
1223 -func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
1224 -func (rr *NSEC3PARAM) len() int { return rr.Hdr.len() + 2 + 4 + 1 + len(rr.Salt)/2 }
1225 -func (rr *NSEC3PARAM) copy() RR {
1226 - return &NSEC3PARAM{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
1227 -}
1228 -
1229 -func (rr *NSEC3PARAM) String() string {
1230 - s := rr.Hdr.String()
1231 - s += strconv.Itoa(int(rr.Hash)) +
1232 - " " + strconv.Itoa(int(rr.Flags)) +
1233 - " " + strconv.Itoa(int(rr.Iterations)) +
1234 - " " + saltToString(rr.Salt)
1235 - return s
1236 -}
1237 -
1238 -type TKEY struct {
1239 - Hdr RR_Header
1240 - Algorithm string `dns:"domain-name"`
1241 - Inception uint32
1242 - Expiration uint32
1243 - Mode uint16
1244 - Error uint16
1245 - KeySize uint16
1246 - Key string
1247 - OtherLen uint16
1248 - OtherData string
1249 -}
1250 -
1251 -func (rr *TKEY) Header() *RR_Header { return &rr.Hdr }
1252 -func (rr *TKEY) copy() RR {
1253 - return &TKEY{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData}
1254 -}
1255 -
1256 -func (rr *TKEY) String() string {
1257 - // It has no presentation format
1258 - return ""
1259 -}
1260 -
1261 -func (rr *TKEY) len() int {
1262 - return rr.Hdr.len() + len(rr.Algorithm) + 1 + 4 + 4 + 6 +
1263 - len(rr.Key) + 2 + len(rr.OtherData)
1264 -}
1265 -
1266 -// RFC3597 represents an unknown/generic RR.
1267 -type RFC3597 struct {
1268 - Hdr RR_Header
1269 - Rdata string `dns:"hex"`
1270 -}
1271 -
1272 -func (rr *RFC3597) Header() *RR_Header { return &rr.Hdr }
1273 -func (rr *RFC3597) copy() RR { return &RFC3597{*rr.Hdr.copyHeader(), rr.Rdata} }
1274 -func (rr *RFC3597) len() int { return rr.Hdr.len() + len(rr.Rdata)/2 + 2 }
1275 -
1276 -func (rr *RFC3597) String() string {
1277 - // Let's call it a hack
1278 - s := rfc3597Header(rr.Hdr)
1279 -
1280 - s += "\\# " + strconv.Itoa(len(rr.Rdata)/2) + " " + rr.Rdata
1281 - return s
1282 -}
1283 -
1284 -func rfc3597Header(h RR_Header) string {
1285 - var s string
1286 -
1287 - s += sprintName(h.Name) + "\t"
1288 - s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
1289 - s += "CLASS" + strconv.Itoa(int(h.Class)) + "\t"
1290 - s += "TYPE" + strconv.Itoa(int(h.Rrtype)) + "\t"
1291 - return s
1292 -}
1293 -
1294 -type URI struct {
1295 - Hdr RR_Header
1296 - Priority uint16
1297 - Weight uint16
1298 - Target []string `dns:"txt"`
1299 -}
1300 -
1301 -func (rr *URI) Header() *RR_Header { return &rr.Hdr }
1302 -func (rr *URI) copy() RR {
1303 - cp := make([]string, len(rr.Target), cap(rr.Target))
1304 - copy(cp, rr.Target)
1305 - return &URI{*rr.Hdr.copyHeader(), rr.Weight, rr.Priority, cp}
1306 -}
1307 -
1308 -func (rr *URI) String() string {
1309 - return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) +
1310 - " " + strconv.Itoa(int(rr.Weight)) + sprintTxt(rr.Target)
1311 -}
1312 -
1313 -func (rr *URI) len() int {
1314 - l := rr.Hdr.len() + 4
1315 - for _, t := range rr.Target {
1316 - l += len(t) + 1
1317 - }
1318 - return l
1319 -}
1320 -
1321 -type DHCID struct {
1322 - Hdr RR_Header
1323 - Digest string `dns:"base64"`
1324 -}
1325 -
1326 -func (rr *DHCID) Header() *RR_Header { return &rr.Hdr }
1327 -func (rr *DHCID) copy() RR { return &DHCID{*rr.Hdr.copyHeader(), rr.Digest} }
1328 -func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest }
1329 -func (rr *DHCID) len() int { return rr.Hdr.len() + base64.StdEncoding.DecodedLen(len(rr.Digest)) }
1330 -
1331 -type TLSA struct {
1332 - Hdr RR_Header
1333 - Usage uint8
1334 - Selector uint8
1335 - MatchingType uint8
1336 - Certificate string `dns:"hex"`
1337 -}
1338 -
1339 -func (rr *TLSA) Header() *RR_Header { return &rr.Hdr }
1340 -func (rr *TLSA) len() int { return rr.Hdr.len() + 3 + len(rr.Certificate)/2 }
1341 -
1342 -func (rr *TLSA) copy() RR {
1343 - return &TLSA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
1344 -}
1345 -
1346 -func (rr *TLSA) String() string {
1347 - return rr.Hdr.String() +
1348 - strconv.Itoa(int(rr.Usage)) +
1349 - " " + strconv.Itoa(int(rr.Selector)) +
1350 - " " + strconv.Itoa(int(rr.MatchingType)) +
1351 - " " + rr.Certificate
1352 -}
1353 -
1354 -type HIP struct {
1355 - Hdr RR_Header
1356 - HitLength uint8
1357 - PublicKeyAlgorithm uint8
1358 - PublicKeyLength uint16
1359 - Hit string `dns:"hex"`
1360 - PublicKey string `dns:"base64"`
1361 - RendezvousServers []string `dns:"domain-name"`
1362 -}
1363 -
1364 -func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
1365 -func (rr *HIP) copy() RR {
1366 - cp := make([]string, len(rr.RendezvousServers), cap(rr.RendezvousServers))
1367 - copy(cp, rr.RendezvousServers)
1368 - return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, cp}
1369 -}
1370 -
1371 -func (rr *HIP) String() string {
1372 - s := rr.Hdr.String() +
1373 - strconv.Itoa(int(rr.PublicKeyAlgorithm)) +
1374 - " " + rr.Hit +
1375 - " " + rr.PublicKey
1376 - for _, d := range rr.RendezvousServers {
1377 - s += " " + sprintName(d)
1378 - }
1379 - return s
1380 -}
1381 -
1382 -func (rr *HIP) len() int {
1383 - l := rr.Hdr.len() + 4 +
1384 - len(rr.Hit)/2 +
1385 - base64.StdEncoding.DecodedLen(len(rr.PublicKey))
1386 - for _, d := range rr.RendezvousServers {
1387 - l += len(d) + 1
1388 - }
1389 - return l
1390 -}
1391 -
1392 -type NINFO struct {
1393 - Hdr RR_Header
1394 - ZSData []string `dns:"txt"`
1395 -}
1396 -
1397 -func (rr *NINFO) Header() *RR_Header { return &rr.Hdr }
1398 -func (rr *NINFO) copy() RR {
1399 - cp := make([]string, len(rr.ZSData), cap(rr.ZSData))
1400 - copy(cp, rr.ZSData)
1401 - return &NINFO{*rr.Hdr.copyHeader(), cp}
1402 -}
1403 -
1404 -func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) }
1405 -
1406 -func (rr *NINFO) len() int {
1407 - l := rr.Hdr.len()
1408 - for _, t := range rr.ZSData {
1409 - l += len(t) + 1
1410 - }
1411 - return l
1412 -}
1413 -
1414 -type WKS struct {
1415 - Hdr RR_Header
1416 - Address net.IP `dns:"a"`
1417 - Protocol uint8
1418 - BitMap []uint16 `dns:"wks"`
1419 -}
1420 -
1421 -func (rr *WKS) Header() *RR_Header { return &rr.Hdr }
1422 -func (rr *WKS) len() int { return rr.Hdr.len() + net.IPv4len + 1 }
1423 -
1424 -func (rr *WKS) copy() RR {
1425 - cp := make([]uint16, len(rr.BitMap), cap(rr.BitMap))
1426 - copy(cp, rr.BitMap)
1427 - return &WKS{*rr.Hdr.copyHeader(), copyIP(rr.Address), rr.Protocol, cp}
1428 -}
1429 -
1430 -func (rr *WKS) String() (s string) {
1431 - s = rr.Hdr.String()
1432 - if rr.Address != nil {
1433 - s += rr.Address.String()
1434 - }
1435 - // TODO(miek): missing protocol here, see /etc/protocols
1436 - for i := 0; i < len(rr.BitMap); i++ {
1437 - // should lookup the port
1438 - s += " " + strconv.Itoa(int(rr.BitMap[i]))
1439 - }
1440 - return s
1441 -}
1442 -
1443 -type NID struct {
1444 - Hdr RR_Header
1445 - Preference uint16
1446 - NodeID uint64
1447 -}
1448 -
1449 -func (rr *NID) Header() *RR_Header { return &rr.Hdr }
1450 -func (rr *NID) copy() RR { return &NID{*rr.Hdr.copyHeader(), rr.Preference, rr.NodeID} }
1451 -func (rr *NID) len() int { return rr.Hdr.len() + 2 + 8 }
1452 -
1453 -func (rr *NID) String() string {
1454 - s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
1455 - node := fmt.Sprintf("%0.16x", rr.NodeID)
1456 - s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
1457 - return s
1458 -}
1459 -
1460 -type L32 struct {
1461 - Hdr RR_Header
1462 - Preference uint16
1463 - Locator32 net.IP `dns:"a"`
1464 -}
1465 -
1466 -func (rr *L32) Header() *RR_Header { return &rr.Hdr }
1467 -func (rr *L32) copy() RR { return &L32{*rr.Hdr.copyHeader(), rr.Preference, copyIP(rr.Locator32)} }
1468 -func (rr *L32) len() int { return rr.Hdr.len() + net.IPv4len }
1469 -
1470 -func (rr *L32) String() string {
1471 - if rr.Locator32 == nil {
1472 - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
1473 - }
1474 - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) +
1475 - " " + rr.Locator32.String()
1476 -}
1477 -
1478 -type L64 struct {
1479 - Hdr RR_Header
1480 - Preference uint16
1481 - Locator64 uint64
1482 -}
1483 -
1484 -func (rr *L64) Header() *RR_Header { return &rr.Hdr }
1485 -func (rr *L64) copy() RR { return &L64{*rr.Hdr.copyHeader(), rr.Preference, rr.Locator64} }
1486 -func (rr *L64) len() int { return rr.Hdr.len() + 2 + 8 }
1487 -
1488 -func (rr *L64) String() string {
1489 - s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference))
1490 - node := fmt.Sprintf("%0.16X", rr.Locator64)
1491 - s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16]
1492 - return s
1493 -}
1494 -
1495 -type LP struct {
1496 - Hdr RR_Header
1497 - Preference uint16
1498 - Fqdn string `dns:"domain-name"`
1499 -}
1500 -
1501 -func (rr *LP) Header() *RR_Header { return &rr.Hdr }
1502 -func (rr *LP) copy() RR { return &LP{*rr.Hdr.copyHeader(), rr.Preference, rr.Fqdn} }
1503 -func (rr *LP) len() int { return rr.Hdr.len() + 2 + len(rr.Fqdn) + 1 }
1504 -
1505 -func (rr *LP) String() string {
1506 - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn)
1507 -}
1508 -
1509 -type EUI48 struct {
1510 - Hdr RR_Header
1511 - Address uint64 `dns:"uint48"`
1512 -}
1513 -
1514 -func (rr *EUI48) Header() *RR_Header { return &rr.Hdr }
1515 -func (rr *EUI48) copy() RR { return &EUI48{*rr.Hdr.copyHeader(), rr.Address} }
1516 -func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) }
1517 -func (rr *EUI48) len() int { return rr.Hdr.len() + 6 }
1518 -
1519 -type EUI64 struct {
1520 - Hdr RR_Header
1521 - Address uint64
1522 -}
1523 -
1524 -func (rr *EUI64) Header() *RR_Header { return &rr.Hdr }
1525 -func (rr *EUI64) copy() RR { return &EUI64{*rr.Hdr.copyHeader(), rr.Address} }
1526 -func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) }
1527 -func (rr *EUI64) len() int { return rr.Hdr.len() + 8 }
1528 -
1529 -// Support in incomplete - just handle it as unknown record
1530 -/*
1531 -type CAA struct {
1532 - Hdr RR_Header
1533 - Flag uint8
1534 - Tag string
1535 - Value string `dns:"octet"`
1536 -}
1537 -
1538 -func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
1539 -func (rr *CAA) copy() RR { return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value} }
1540 -func (rr *CAA) len() int { return rr.Hdr.len() + 1 + len(rr.Tag) + 1 + len(rr.Value) }
1541 -
1542 -func (rr *CAA) String() string {
1543 - s := rr.Hdr.String() + strconv.FormatInt(int64(rr.Flag), 10) + " " + rr.Tag
1544 - s += strconv.QuoteToASCII(rr.Value)
1545 - return s
1546 -}
1547 -*/
1548 -
1549 -type UID struct {
1550 - Hdr RR_Header
1551 - Uid uint32
1552 -}
1553 -
1554 -func (rr *UID) Header() *RR_Header { return &rr.Hdr }
1555 -func (rr *UID) copy() RR { return &UID{*rr.Hdr.copyHeader(), rr.Uid} }
1556 -func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) }
1557 -func (rr *UID) len() int { return rr.Hdr.len() + 4 }
1558 -
1559 -type GID struct {
1560 - Hdr RR_Header
1561 - Gid uint32
1562 -}
1563 -
1564 -func (rr *GID) Header() *RR_Header { return &rr.Hdr }
1565 -func (rr *GID) copy() RR { return &GID{*rr.Hdr.copyHeader(), rr.Gid} }
1566 -func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) }
1567 -func (rr *GID) len() int { return rr.Hdr.len() + 4 }
1568 -
1569 -type UINFO struct {
1570 - Hdr RR_Header
1571 - Uinfo string
1572 -}
1573 -
1574 -func (rr *UINFO) Header() *RR_Header { return &rr.Hdr }
1575 -func (rr *UINFO) copy() RR { return &UINFO{*rr.Hdr.copyHeader(), rr.Uinfo} }
1576 -func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) }
1577 -func (rr *UINFO) len() int { return rr.Hdr.len() + len(rr.Uinfo) + 1 }
1578 -
1579 -type EID struct {
1580 - Hdr RR_Header
1581 - Endpoint string `dns:"hex"`
1582 -}
1583 -
1584 -func (rr *EID) Header() *RR_Header { return &rr.Hdr }
1585 -func (rr *EID) copy() RR { return &EID{*rr.Hdr.copyHeader(), rr.Endpoint} }
1586 -func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) }
1587 -func (rr *EID) len() int { return rr.Hdr.len() + len(rr.Endpoint)/2 }
1588 -
1589 -type NIMLOC struct {
1590 - Hdr RR_Header
1591 - Locator string `dns:"hex"`
1592 -}
1593 -
1594 -func (rr *NIMLOC) Header() *RR_Header { return &rr.Hdr }
1595 -func (rr *NIMLOC) copy() RR { return &NIMLOC{*rr.Hdr.copyHeader(), rr.Locator} }
1596 -func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) }
1597 -func (rr *NIMLOC) len() int { return rr.Hdr.len() + len(rr.Locator)/2 }
1598 -
1599 -type OPENPGPKEY struct {
1600 - Hdr RR_Header
1601 - PublicKey string `dns:"base64"`
1602 -}
1603 -
1604 -func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
1605 -func (rr *OPENPGPKEY) copy() RR { return &OPENPGPKEY{*rr.Hdr.copyHeader(), rr.PublicKey} }
1606 -func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey }
1607 -func (rr *OPENPGPKEY) len() int {
1608 - return rr.Hdr.len() + base64.StdEncoding.DecodedLen(len(rr.PublicKey))
1609 -}
1610 -
1611 -// TimeToString translates the RRSIG's incep. and expir. times to the
1612 -// string representation used when printing the record.
1613 -// It takes serial arithmetic (RFC 1982) into account.
1614 -func TimeToString(t uint32) string {
1615 - mod := ((int64(t) - time.Now().Unix()) / year68) - 1
1616 - if mod < 0 {
1617 - mod = 0
1618 - }
1619 - ti := time.Unix(int64(t)-(mod*year68), 0).UTC()
1620 - return ti.Format("20060102150405")
1621 -}
1622 -
1623 -// StringToTime translates the RRSIG's incep. and expir. times from
1624 -// string values like "20110403154150" to an 32 bit integer.
1625 -// It takes serial arithmetic (RFC 1982) into account.
1626 -func StringToTime(s string) (uint32, error) {
1627 - t, e := time.Parse("20060102150405", s)
1628 - if e != nil {
1629 - return 0, e
1630 - }
1631 - mod := (t.Unix() / year68) - 1
1632 - if mod < 0 {
1633 - mod = 0
1634 - }
1635 - return uint32(t.Unix() - (mod * year68)), nil
1636 -}
1637 -
1638 -// saltToString converts a NSECX salt to uppercase and
1639 -// returns "-" when it is empty
1640 -func saltToString(s string) string {
1641 - if len(s) == 0 {
1642 - return "-"
1643 - }
1644 - return strings.ToUpper(s)
1645 -}
1646 -
1647 -func euiToString(eui uint64, bits int) (hex string) {
1648 - switch bits {
1649 - case 64:
1650 - hex = fmt.Sprintf("%16.16x", eui)
1651 - hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
1652 - "-" + hex[8:10] + "-" + hex[10:12] + "-" + hex[12:14] + "-" + hex[14:16]
1653 - case 48:
1654 - hex = fmt.Sprintf("%12.12x", eui)
1655 - hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] +
1656 - "-" + hex[8:10] + "-" + hex[10:12]
1657 - }
1658 - return
1659 -}
1660 -
1661 -// copyIP returns a copy of ip.
1662 -func copyIP(ip net.IP) net.IP {
1663 - p := make(net.IP, len(ip))
1664 - copy(p, ip)
1665 - return p
1666 -}
1667 -
1668 -// Map of constructors for each RR type.
1669 -var typeToRR = map[uint16]func() RR{
1670 - TypeA: func() RR { return new(A) },
1671 - TypeAAAA: func() RR { return new(AAAA) },
1672 - TypeAFSDB: func() RR { return new(AFSDB) },
1673 - // TypeCAA: func() RR { return new(CAA) },
1674 - TypeCDS: func() RR { return new(CDS) },
1675 - TypeCERT: func() RR { return new(CERT) },
1676 - TypeCNAME: func() RR { return new(CNAME) },
1677 - TypeDHCID: func() RR { return new(DHCID) },
1678 - TypeDLV: func() RR { return new(DLV) },
1679 - TypeDNAME: func() RR { return new(DNAME) },
1680 - TypeKEY: func() RR { return new(KEY) },
1681 - TypeDNSKEY: func() RR { return new(DNSKEY) },
1682 - TypeDS: func() RR { return new(DS) },
1683 - TypeEUI48: func() RR { return new(EUI48) },
1684 - TypeEUI64: func() RR { return new(EUI64) },
1685 - TypeGID: func() RR { return new(GID) },
1686 - TypeGPOS: func() RR { return new(GPOS) },
1687 - TypeEID: func() RR { return new(EID) },
1688 - TypeHINFO: func() RR { return new(HINFO) },
1689 - TypeHIP: func() RR { return new(HIP) },
1690 - TypeIPSECKEY: func() RR { return new(IPSECKEY) },
1691 - TypeKX: func() RR { return new(KX) },
1692 - TypeL32: func() RR { return new(L32) },
1693 - TypeL64: func() RR { return new(L64) },
1694 - TypeLOC: func() RR { return new(LOC) },
1695 - TypeLP: func() RR { return new(LP) },
1696 - TypeMB: func() RR { return new(MB) },
1697 - TypeMD: func() RR { return new(MD) },
1698 - TypeMF: func() RR { return new(MF) },
1699 - TypeMG: func() RR { return new(MG) },
1700 - TypeMINFO: func() RR { return new(MINFO) },
1701 - TypeMR: func() RR { return new(MR) },
1702 - TypeMX: func() RR { return new(MX) },
1703 - TypeNAPTR: func() RR { return new(NAPTR) },
1704 - TypeNID: func() RR { return new(NID) },
1705 - TypeNINFO: func() RR { return new(NINFO) },
1706 - TypeNIMLOC: func() RR { return new(NIMLOC) },
1707 - TypeNS: func() RR { return new(NS) },
1708 - TypeNSAP: func() RR { return new(NSAP) },
1709 - TypeNSAPPTR: func() RR { return new(NSAPPTR) },
1710 - TypeNSEC3: func() RR { return new(NSEC3) },
1711 - TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
1712 - TypeNSEC: func() RR { return new(NSEC) },
1713 - TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
1714 - TypeOPT: func() RR { return new(OPT) },
1715 - TypePTR: func() RR { return new(PTR) },
1716 - TypeRKEY: func() RR { return new(RKEY) },
1717 - TypeRP: func() RR { return new(RP) },
1718 - TypePX: func() RR { return new(PX) },
1719 - TypeSIG: func() RR { return new(SIG) },
1720 - TypeRRSIG: func() RR { return new(RRSIG) },
1721 - TypeRT: func() RR { return new(RT) },
1722 - TypeSOA: func() RR { return new(SOA) },
1723 - TypeSPF: func() RR { return new(SPF) },
1724 - TypeSRV: func() RR { return new(SRV) },
1725 - TypeSSHFP: func() RR { return new(SSHFP) },
1726 - TypeTA: func() RR { return new(TA) },
1727 - TypeTALINK: func() RR { return new(TALINK) },
1728 - TypeTKEY: func() RR { return new(TKEY) },
1729 - TypeTLSA: func() RR { return new(TLSA) },
1730 - TypeTSIG: func() RR { return new(TSIG) },
1731 - TypeTXT: func() RR { return new(TXT) },
1732 - TypeUID: func() RR { return new(UID) },
1733 - TypeUINFO: func() RR { return new(UINFO) },
1734 - TypeURI: func() RR { return new(URI) },
1735 - TypeWKS: func() RR { return new(WKS) },
1736 - TypeX25: func() RR { return new(X25) },
1737 -}
Godeps/_workspace/src/github.com/miekg/dns/types_test.go deleted
-42
@@ -1,42 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "testing"
5 -)
6 -
7 -func TestCmToM(t *testing.T) {
8 - s := cmToM(0, 0)
9 - if s != "0.00" {
10 - t.Error("0, 0")
11 - }
12 -
13 - s = cmToM(1, 0)
14 - if s != "0.01" {
15 - t.Error("1, 0")
16 - }
17 -
18 - s = cmToM(3, 1)
19 - if s != "0.30" {
20 - t.Error("3, 1")
21 - }
22 -
23 - s = cmToM(4, 2)
24 - if s != "4" {
25 - t.Error("4, 2")
26 - }
27 -
28 - s = cmToM(5, 3)
29 - if s != "50" {
30 - t.Error("5, 3")
31 - }
32 -
33 - s = cmToM(7, 5)
34 - if s != "7000" {
35 - t.Error("7, 5")
36 - }
37 -
38 - s = cmToM(9, 9)
39 - if s != "90000000" {
40 - t.Error("9, 9")
41 - }
42 -}
Godeps/_workspace/src/github.com/miekg/dns/udp.go deleted
-55
@@ -1,55 +0,0 @@
1 -// +build !windows
2 -
3 -package dns
4 -
5 -import (
6 - "net"
7 - "syscall"
8 -)
9 -
10 -type SessionUDP struct {
11 - raddr *net.UDPAddr
12 - context []byte
13 -}
14 -
15 -func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
16 -
17 -// setUDPSocketOptions sets the UDP socket options.
18 -// This function is implemented on a per platform basis. See udp_*.go for more details
19 -func setUDPSocketOptions(conn *net.UDPConn) error {
20 - sa, err := getUDPSocketName(conn)
21 - if err != nil {
22 - return err
23 - }
24 - switch sa.(type) {
25 - case *syscall.SockaddrInet6:
26 - v6only, err := getUDPSocketOptions6Only(conn)
27 - if err != nil {
28 - return err
29 - }
30 - setUDPSocketOptions6(conn)
31 - if !v6only {
32 - setUDPSocketOptions4(conn)
33 - }
34 - case *syscall.SockaddrInet4:
35 - setUDPSocketOptions4(conn)
36 - }
37 - return nil
38 -}
39 -
40 -// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
41 -// net.UDPAddr.
42 -func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
43 - oob := make([]byte, 40)
44 - n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob)
45 - if err != nil {
46 - return n, nil, err
47 - }
48 - return n, &SessionUDP{raddr, oob[:oobn]}, err
49 -}
50 -
51 -// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
52 -func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
53 - n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr)
54 - return n, err
55 -}
Godeps/_workspace/src/github.com/miekg/dns/udp_linux.go deleted
-63
@@ -1,63 +0,0 @@
1 -// +build linux
2 -
3 -package dns
4 -
5 -// See:
6 -// * http://stackoverflow.com/questions/3062205/setting-the-source-ip-for-a-udp-socket and
7 -// * http://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/
8 -//
9 -// Why do we need this: When listening on 0.0.0.0 with UDP so kernel decides what is the outgoing
10 -// interface, this might not always be the correct one. This code will make sure the egress
11 -// packet's interface matched the ingress' one.
12 -
13 -import (
14 - "net"
15 - "syscall"
16 -)
17 -
18 -// setUDPSocketOptions4 prepares the v4 socket for sessions.
19 -func setUDPSocketOptions4(conn *net.UDPConn) error {
20 - file, err := conn.File()
21 - if err != nil {
22 - return err
23 - }
24 - if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil {
25 - return err
26 - }
27 - return nil
28 -}
29 -
30 -// setUDPSocketOptions6 prepares the v6 socket for sessions.
31 -func setUDPSocketOptions6(conn *net.UDPConn) error {
32 - file, err := conn.File()
33 - if err != nil {
34 - return err
35 - }
36 - if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil {
37 - return err
38 - }
39 - return nil
40 -}
41 -
42 -// getUDPSocketOption6Only return true if the socket is v6 only and false when it is v4/v6 combined
43 -// (dualstack).
44 -func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) {
45 - file, err := conn.File()
46 - if err != nil {
47 - return false, err
48 - }
49 - // dual stack. See http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections
50 - v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY)
51 - if err != nil {
52 - return false, err
53 - }
54 - return v6only == 1, nil
55 -}
56 -
57 -func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
58 - file, err := conn.File()
59 - if err != nil {
60 - return nil, err
61 - }
62 - return syscall.Getsockname(int(file.Fd()))
63 -}
Godeps/_workspace/src/github.com/miekg/dns/udp_other.go deleted
-17
@@ -1,17 +0,0 @@
1 -// +build !linux
2 -
3 -package dns
4 -
5 -import (
6 - "net"
7 - "syscall"
8 -)
9 -
10 -// These do nothing. See udp_linux.go for an example of how to implement this.
11 -
12 -// We tried to adhire to some kind of naming scheme.
13 -
14 -func setUDPSocketOptions4(conn *net.UDPConn) error { return nil }
15 -func setUDPSocketOptions6(conn *net.UDPConn) error { return nil }
16 -func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil }
17 -func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { return nil, nil }
Godeps/_workspace/src/github.com/miekg/dns/udp_windows.go deleted
-34
@@ -1,34 +0,0 @@
1 -// +build windows
2 -
3 -package dns
4 -
5 -import "net"
6 -
7 -type SessionUDP struct {
8 - raddr *net.UDPAddr
9 -}
10 -
11 -// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
12 -// net.UDPAddr.
13 -func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
14 - n, raddr, err := conn.ReadFrom(b)
15 - if err != nil {
16 - return n, nil, err
17 - }
18 - session := &SessionUDP{raddr.(*net.UDPAddr)}
19 - return n, session, err
20 -}
21 -
22 -// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr.
23 -func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
24 - n, err := conn.WriteTo(b, session.raddr)
25 - return n, err
26 -}
27 -
28 -func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
29 -
30 -// setUDPSocketOptions sets the UDP socket options.
31 -// This function is implemented on a per platform basis. See udp_*.go for more details
32 -func setUDPSocketOptions(conn *net.UDPConn) error {
33 - return nil
34 -}
Godeps/_workspace/src/github.com/miekg/dns/update.go deleted
-94
@@ -1,94 +0,0 @@
1 -package dns
2 -
3 -// NameUsed sets the RRs in the prereq section to
4 -// "Name is in use" RRs. RFC 2136 section 2.4.4.
5 -func (u *Msg) NameUsed(rr []RR) {
6 - u.Answer = make([]RR, len(rr))
7 - for i, r := range rr {
8 - u.Answer[i] = &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}
9 - }
10 -}
11 -
12 -// NameNotUsed sets the RRs in the prereq section to
13 -// "Name is in not use" RRs. RFC 2136 section 2.4.5.
14 -func (u *Msg) NameNotUsed(rr []RR) {
15 - u.Answer = make([]RR, len(rr))
16 - for i, r := range rr {
17 - u.Answer[i] = &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassNONE}}
18 - }
19 -}
20 -
21 -// Used sets the RRs in the prereq section to
22 -// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2.
23 -func (u *Msg) Used(rr []RR) {
24 - if len(u.Question) == 0 {
25 - panic("dns: empty question section")
26 - }
27 - u.Answer = make([]RR, len(rr))
28 - for i, r := range rr {
29 - u.Answer[i] = r
30 - u.Answer[i].Header().Class = u.Question[0].Qclass
31 - }
32 -}
33 -
34 -// RRsetUsed sets the RRs in the prereq section to
35 -// "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1.
36 -func (u *Msg) RRsetUsed(rr []RR) {
37 - u.Answer = make([]RR, len(rr))
38 - for i, r := range rr {
39 - u.Answer[i] = r
40 - u.Answer[i].Header().Class = ClassANY
41 - u.Answer[i].Header().Ttl = 0
42 - u.Answer[i].Header().Rdlength = 0
43 - }
44 -}
45 -
46 -// RRsetNotUsed sets the RRs in the prereq section to
47 -// "RRset does not exist" RRs. RFC 2136 section 2.4.3.
48 -func (u *Msg) RRsetNotUsed(rr []RR) {
49 - u.Answer = make([]RR, len(rr))
50 - for i, r := range rr {
51 - u.Answer[i] = r
52 - u.Answer[i].Header().Class = ClassNONE
53 - u.Answer[i].Header().Rdlength = 0
54 - u.Answer[i].Header().Ttl = 0
55 - }
56 -}
57 -
58 -// Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1.
59 -func (u *Msg) Insert(rr []RR) {
60 - if len(u.Question) == 0 {
61 - panic("dns: empty question section")
62 - }
63 - u.Ns = make([]RR, len(rr))
64 - for i, r := range rr {
65 - u.Ns[i] = r
66 - u.Ns[i].Header().Class = u.Question[0].Qclass
67 - }
68 -}
69 -
70 -// RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2.
71 -func (u *Msg) RemoveRRset(rr []RR) {
72 - u.Ns = make([]RR, len(rr))
73 - for i, r := range rr {
74 - u.Ns[i] = &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}}
75 - }
76 -}
77 -
78 -// RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3
79 -func (u *Msg) RemoveName(rr []RR) {
80 - u.Ns = make([]RR, len(rr))
81 - for i, r := range rr {
82 - u.Ns[i] = &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}
83 - }
84 -}
85 -
86 -// Remove creates a dynamic update packet deletes RR from the RRSset, see RFC 2136 section 2.5.4
87 -func (u *Msg) Remove(rr []RR) {
88 - u.Ns = make([]RR, len(rr))
89 - for i, r := range rr {
90 - u.Ns[i] = r
91 - u.Ns[i].Header().Class = ClassNONE
92 - u.Ns[i].Header().Ttl = 0
93 - }
94 -}
Godeps/_workspace/src/github.com/miekg/dns/update_test.go deleted
-84
@@ -1,84 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "bytes"
5 - "testing"
6 -)
7 -
8 -func TestDynamicUpdateParsing(t *testing.T) {
9 - prefix := "example.com. IN "
10 - for _, typ := range TypeToString {
11 - if typ == "CAA" || typ == "OPT" || typ == "AXFR" || typ == "IXFR" || typ == "ANY" || typ == "TKEY" ||
12 - typ == "TSIG" || typ == "ISDN" || typ == "UNSPEC" || typ == "NULL" || typ == "ATMA" {
13 - continue
14 - }
15 - r, err := NewRR(prefix + typ)
16 - if err != nil {
17 - t.Errorf("failure to parse: %s %s: %v", prefix, typ, err)
18 - } else {
19 - t.Logf("parsed: %s", r.String())
20 - }
21 - }
22 -}
23 -
24 -func TestDynamicUpdateUnpack(t *testing.T) {
25 - // From https://github.com/miekg/dns/issues/150#issuecomment-62296803
26 - // It should be an update message for the zone "example.",
27 - // deleting the A RRset "example." and then adding an A record at "example.".
28 - // class ANY, TYPE A
29 - buf := []byte{171, 68, 40, 0, 0, 1, 0, 0, 0, 2, 0, 0, 7, 101, 120, 97, 109, 112, 108, 101, 0, 0, 6, 0, 1, 192, 12, 0, 1, 0, 255, 0, 0, 0, 0, 0, 0, 192, 12, 0, 1, 0, 1, 0, 0, 0, 0, 0, 4, 127, 0, 0, 1}
30 - msg := new(Msg)
31 - err := msg.Unpack(buf)
32 - if err != nil {
33 - t.Errorf("failed to unpack: %v\n%s", err, msg.String())
34 - }
35 -}
36 -
37 -func TestDynamicUpdateZeroRdataUnpack(t *testing.T) {
38 - m := new(Msg)
39 - rr := &RR_Header{Name: ".", Rrtype: 0, Class: 1, Ttl: ^uint32(0), Rdlength: 0}
40 - m.Answer = []RR{rr, rr, rr, rr, rr}
41 - m.Ns = m.Answer
42 - for n, s := range TypeToString {
43 - rr.Rrtype = n
44 - bytes, err := m.Pack()
45 - if err != nil {
46 - t.Errorf("failed to pack %s: %v", s, err)
47 - continue
48 - }
49 - if err := new(Msg).Unpack(bytes); err != nil {
50 - t.Errorf("failed to unpack %s: %v", s, err)
51 - }
52 - }
53 -}
54 -
55 -func TestRemoveRRset(t *testing.T) {
56 - // Should add a zero data RR in Class ANY with a TTL of 0
57 - // for each set mentioned in the RRs provided to it.
58 - rr, err := NewRR(". 100 IN A 127.0.0.1")
59 - if err != nil {
60 - t.Fatalf("Error constructing RR: %v", err)
61 - }
62 - m := new(Msg)
63 - m.Ns = []RR{&RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY, Ttl: 0, Rdlength: 0}}
64 - expectstr := m.String()
65 - expect, err := m.Pack()
66 - if err != nil {
67 - t.Fatalf("Error packing expected msg: %v", err)
68 - }
69 -
70 - m.Ns = nil
71 - m.RemoveRRset([]RR{rr})
72 - actual, err := m.Pack()
73 - if err != nil {
74 - t.Fatalf("Error packing actual msg: %v", err)
75 - }
76 - if !bytes.Equal(actual, expect) {
77 - tmp := new(Msg)
78 - if err := tmp.Unpack(actual); err != nil {
79 - t.Fatalf("Error unpacking actual msg: %v", err)
80 - }
81 - t.Errorf("Expected msg:\n%s", expectstr)
82 - t.Errorf("Actual msg:\n%v", tmp)
83 - }
84 -}
Godeps/_workspace/src/github.com/miekg/dns/xfr.go deleted
-233
@@ -1,233 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "time"
5 -)
6 -
7 -// Envelope is used when doing a zone transfer with a remote server.
8 -type Envelope struct {
9 - RR []RR // The set of RRs in the answer section of the xfr reply message.
10 - Error error // If something went wrong, this contains the error.
11 -}
12 -
13 -// A Transfer defines parameters that are used during a zone transfer.
14 -type Transfer struct {
15 - *Conn
16 - DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
17 - ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
18 - WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
19 - TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified
20 - tsigTimersOnly bool
21 -}
22 -
23 -// Think we need to away to stop the transfer
24 -
25 -// In performs an incoming transfer with the server in a.
26 -func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
27 - timeout := dnsTimeout
28 - if t.DialTimeout != 0 {
29 - timeout = t.DialTimeout
30 - }
31 - t.Conn, err = DialTimeout("tcp", a, timeout)
32 - if err != nil {
33 - return nil, err
34 - }
35 - if err := t.WriteMsg(q); err != nil {
36 - return nil, err
37 - }
38 - env = make(chan *Envelope)
39 - go func() {
40 - if q.Question[0].Qtype == TypeAXFR {
41 - go t.inAxfr(q.Id, env)
42 - return
43 - }
44 - if q.Question[0].Qtype == TypeIXFR {
45 - go t.inIxfr(q.Id, env)
46 - return
47 - }
48 - }()
49 - return env, nil
50 -}
51 -
52 -func (t *Transfer) inAxfr(id uint16, c chan *Envelope) {
53 - first := true
54 - defer t.Close()
55 - defer close(c)
56 - timeout := dnsTimeout
57 - if t.ReadTimeout != 0 {
58 - timeout = t.ReadTimeout
59 - }
60 - for {
61 - t.Conn.SetReadDeadline(time.Now().Add(timeout))
62 - in, err := t.ReadMsg()
63 - if err != nil {
64 - c <- &Envelope{nil, err}
65 - return
66 - }
67 - if id != in.Id {
68 - c <- &Envelope{in.Answer, ErrId}
69 - return
70 - }
71 - if first {
72 - if !isSOAFirst(in) {
73 - c <- &Envelope{in.Answer, ErrSoa}
74 - return
75 - }
76 - first = !first
77 - // only one answer that is SOA, receive more
78 - if len(in.Answer) == 1 {
79 - t.tsigTimersOnly = true
80 - c <- &Envelope{in.Answer, nil}
81 - continue
82 - }
83 - }
84 -
85 - if !first {
86 - t.tsigTimersOnly = true // Subsequent envelopes use this.
87 - if isSOALast(in) {
88 - c <- &Envelope{in.Answer, nil}
89 - return
90 - }
91 - c <- &Envelope{in.Answer, nil}
92 - }
93 - }
94 - panic("dns: not reached")
95 -}
96 -
97 -func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
98 - serial := uint32(0) // The first serial seen is the current server serial
99 - first := true
100 - defer t.Close()
101 - defer close(c)
102 - timeout := dnsTimeout
103 - if t.ReadTimeout != 0 {
104 - timeout = t.ReadTimeout
105 - }
106 - for {
107 - t.SetReadDeadline(time.Now().Add(timeout))
108 - in, err := t.ReadMsg()
109 - if err != nil {
110 - c <- &Envelope{in.Answer, err}
111 - return
112 - }
113 - if id != in.Id {
114 - c <- &Envelope{in.Answer, ErrId}
115 - return
116 - }
117 - if first {
118 - // A single SOA RR signals "no changes"
119 - if len(in.Answer) == 1 && isSOAFirst(in) {
120 - c <- &Envelope{in.Answer, nil}
121 - return
122 - }
123 -
124 - // Check if the returned answer is ok
125 - if !isSOAFirst(in) {
126 - c <- &Envelope{in.Answer, ErrSoa}
127 - return
128 - }
129 - // This serial is important
130 - serial = in.Answer[0].(*SOA).Serial
131 - first = !first
132 - }
133 -
134 - // Now we need to check each message for SOA records, to see what we need to do
135 - if !first {
136 - t.tsigTimersOnly = true
137 - // If the last record in the IXFR contains the servers' SOA, we should quit
138 - if v, ok := in.Answer[len(in.Answer)-1].(*SOA); ok {
139 - if v.Serial == serial {
140 - c <- &Envelope{in.Answer, nil}
141 - return
142 - }
143 - }
144 - c <- &Envelope{in.Answer, nil}
145 - }
146 - }
147 -}
148 -
149 -// Out performs an outgoing transfer with the client connecting in w.
150 -// Basic use pattern:
151 -//
152 -// ch := make(chan *dns.Envelope)
153 -// tr := new(dns.Transfer)
154 -// tr.Out(w, r, ch)
155 -// c <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}}
156 -// close(ch)
157 -// w.Hijack()
158 -// // w.Close() // Client closes connection
159 -//
160 -// The server is responsible for sending the correct sequence of RRs through the
161 -// channel ch.
162 -func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error {
163 - for x := range ch {
164 - r := new(Msg)
165 - // Compress?
166 - r.SetReply(q)
167 - r.Authoritative = true
168 - // assume it fits TODO(miek): fix
169 - r.Answer = append(r.Answer, x.RR...)
170 - if err := w.WriteMsg(r); err != nil {
171 - return err
172 - }
173 - }
174 - w.TsigTimersOnly(true)
175 - return nil
176 -}
177 -
178 -// ReadMsg reads a message from the transfer connection t.
179 -func (t *Transfer) ReadMsg() (*Msg, error) {
180 - m := new(Msg)
181 - p := make([]byte, MaxMsgSize)
182 - n, err := t.Read(p)
183 - if err != nil && n == 0 {
184 - return nil, err
185 - }
186 - p = p[:n]
187 - if err := m.Unpack(p); err != nil {
188 - return nil, err
189 - }
190 - if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
191 - if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
192 - return m, ErrSecret
193 - }
194 - // Need to work on the original message p, as that was used to calculate the tsig.
195 - err = TsigVerify(p, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
196 - t.tsigRequestMAC = ts.MAC
197 - }
198 - return m, err
199 -}
200 -
201 -// WriteMsg writes a message through the transfer connection t.
202 -func (t *Transfer) WriteMsg(m *Msg) (err error) {
203 - var out []byte
204 - if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
205 - if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
206 - return ErrSecret
207 - }
208 - out, t.tsigRequestMAC, err = TsigGenerate(m, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
209 - } else {
210 - out, err = m.Pack()
211 - }
212 - if err != nil {
213 - return err
214 - }
215 - if _, err = t.Write(out); err != nil {
216 - return err
217 - }
218 - return nil
219 -}
220 -
221 -func isSOAFirst(in *Msg) bool {
222 - if len(in.Answer) > 0 {
223 - return in.Answer[0].Header().Rrtype == TypeSOA
224 - }
225 - return false
226 -}
227 -
228 -func isSOALast(in *Msg) bool {
229 - if len(in.Answer) > 0 {
230 - return in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
231 - }
232 - return false
233 -}
Godeps/_workspace/src/github.com/miekg/dns/xfr_test.go deleted
-92
@@ -1,92 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "net"
5 - "testing"
6 - "time"
7 -)
8 -
9 -func getIP(s string) string {
10 - a, err := net.LookupAddr(s)
11 - if err != nil {
12 - return ""
13 - }
14 - return a[0]
15 -}
16 -
17 -// flaky, need to setup local server and test from
18 -// that.
19 -func testClientAXFR(t *testing.T) {
20 - if testing.Short() {
21 - return
22 - }
23 - m := new(Msg)
24 - m.SetAxfr("miek.nl.")
25 -
26 - server := getIP("linode.atoom.net")
27 -
28 - tr := new(Transfer)
29 -
30 - if a, err := tr.In(m, net.JoinHostPort(server, "53")); err != nil {
31 - t.Fatal("failed to setup axfr: ", err)
32 - } else {
33 - for ex := range a {
34 - if ex.Error != nil {
35 - t.Errorf("error %v", ex.Error)
36 - break
37 - }
38 - for _, rr := range ex.RR {
39 - t.Log(rr.String())
40 - }
41 - }
42 - }
43 -}
44 -
45 -// fails.
46 -func testClientAXFRMultipleEnvelopes(t *testing.T) {
47 - if testing.Short() {
48 - return
49 - }
50 - m := new(Msg)
51 - m.SetAxfr("nlnetlabs.nl.")
52 -
53 - server := getIP("open.nlnetlabs.nl.")
54 -
55 - tr := new(Transfer)
56 - if a, err := tr.In(m, net.JoinHostPort(server, "53")); err != nil {
57 - t.Fatalf("Failed to setup axfr %v for server: %v", err, server)
58 - } else {
59 - for ex := range a {
60 - if ex.Error != nil {
61 - t.Errorf("Error %v", ex.Error)
62 - break
63 - }
64 - }
65 - }
66 -}
67 -
68 -func testClientTsigAXFR(t *testing.T) {
69 - if testing.Short() {
70 - return
71 - }
72 - m := new(Msg)
73 - m.SetAxfr("example.nl.")
74 - m.SetTsig("axfr.", HmacMD5, 300, time.Now().Unix())
75 -
76 - tr := new(Transfer)
77 - tr.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
78 -
79 - if a, err := tr.In(m, "176.58.119.54:53"); err != nil {
80 - t.Fatal("failed to setup axfr: ", err)
81 - } else {
82 - for ex := range a {
83 - if ex.Error != nil {
84 - t.Errorf("error %v", ex.Error)
85 - break
86 - }
87 - for _, rr := range ex.RR {
88 - t.Log(rr.String())
89 - }
90 - }
91 - }
92 -}
Godeps/_workspace/src/github.com/miekg/dns/zgenerate.go deleted
-158
@@ -1,158 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "bytes"
5 - "fmt"
6 - "strconv"
7 - "strings"
8 -)
9 -
10 -// Parse the $GENERATE statement as used in BIND9 zones.
11 -// See http://www.zytrax.com/books/dns/ch8/generate.html for instance.
12 -// We are called after '$GENERATE '. After which we expect:
13 -// * the range (12-24/2)
14 -// * lhs (ownername)
15 -// * [[ttl][class]]
16 -// * type
17 -// * rhs (rdata)
18 -// But we are lazy here, only the range is parsed *all* occurences
19 -// of $ after that are interpreted.
20 -// Any error are returned as a string value, the empty string signals
21 -// "no error".
22 -func generate(l lex, c chan lex, t chan *Token, o string) string {
23 - step := 1
24 - if i := strings.IndexAny(l.token, "/"); i != -1 {
25 - if i+1 == len(l.token) {
26 - return "bad step in $GENERATE range"
27 - }
28 - if s, e := strconv.Atoi(l.token[i+1:]); e == nil {
29 - if s < 0 {
30 - return "bad step in $GENERATE range"
31 - }
32 - step = s
33 - } else {
34 - return "bad step in $GENERATE range"
35 - }
36 - l.token = l.token[:i]
37 - }
38 - sx := strings.SplitN(l.token, "-", 2)
39 - if len(sx) != 2 {
40 - return "bad start-stop in $GENERATE range"
41 - }
42 - start, err := strconv.Atoi(sx[0])
43 - if err != nil {
44 - return "bad start in $GENERATE range"
45 - }
46 - end, err := strconv.Atoi(sx[1])
47 - if err != nil {
48 - return "bad stop in $GENERATE range"
49 - }
50 - if end < 0 || start < 0 || end < start {
51 - return "bad range in $GENERATE range"
52 - }
53 -
54 - <-c // _BLANK
55 - // Create a complete new string, which we then parse again.
56 - s := ""
57 -BuildRR:
58 - l = <-c
59 - if l.value != zNewline && l.value != zEOF {
60 - s += l.token
61 - goto BuildRR
62 - }
63 - for i := start; i <= end; i += step {
64 - var (
65 - escape bool
66 - dom bytes.Buffer
67 - mod string
68 - err string
69 - offset int
70 - )
71 -
72 - for j := 0; j < len(s); j++ { // No 'range' because we need to jump around
73 - switch s[j] {
74 - case '\\':
75 - if escape {
76 - dom.WriteByte('\\')
77 - escape = false
78 - continue
79 - }
80 - escape = true
81 - case '$':
82 - mod = "%d"
83 - offset = 0
84 - if escape {
85 - dom.WriteByte('$')
86 - escape = false
87 - continue
88 - }
89 - escape = false
90 - if j+1 >= len(s) { // End of the string
91 - dom.WriteString(fmt.Sprintf(mod, i+offset))
92 - continue
93 - } else {
94 - if s[j+1] == '$' {
95 - dom.WriteByte('$')
96 - j++
97 - continue
98 - }
99 - }
100 - // Search for { and }
101 - if s[j+1] == '{' { // Modifier block
102 - sep := strings.Index(s[j+2:], "}")
103 - if sep == -1 {
104 - return "bad modifier in $GENERATE"
105 - }
106 - mod, offset, err = modToPrintf(s[j+2 : j+2+sep])
107 - if err != "" {
108 - return err
109 - }
110 - j += 2 + sep // Jump to it
111 - }
112 - dom.WriteString(fmt.Sprintf(mod, i+offset))
113 - default:
114 - if escape { // Pretty useless here
115 - escape = false
116 - continue
117 - }
118 - dom.WriteByte(s[j])
119 - }
120 - }
121 - // Re-parse the RR and send it on the current channel t
122 - rx, e := NewRR("$ORIGIN " + o + "\n" + dom.String())
123 - if e != nil {
124 - return e.(*ParseError).err
125 - }
126 - t <- &Token{RR: rx}
127 - // Its more efficient to first built the rrlist and then parse it in
128 - // one go! But is this a problem?
129 - }
130 - return ""
131 -}
132 -
133 -// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
134 -func modToPrintf(s string) (string, int, string) {
135 - xs := strings.SplitN(s, ",", 3)
136 - if len(xs) != 3 {
137 - return "", 0, "bad modifier in $GENERATE"
138 - }
139 - // xs[0] is offset, xs[1] is width, xs[2] is base
140 - if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" {
141 - return "", 0, "bad base in $GENERATE"
142 - }
143 - offset, err := strconv.Atoi(xs[0])
144 - if err != nil {
145 - return "", 0, "bad offset in $GENERATE"
146 - }
147 - width, err := strconv.Atoi(xs[1])
148 - if err != nil {
149 - return "", offset, "bad width in $GENERATE"
150 - }
151 - switch {
152 - case width < 0:
153 - return "", offset, "bad width in $GENERATE"
154 - case width == 0:
155 - return "%" + xs[1] + xs[2], offset, ""
156 - }
157 - return "%0" + xs[1] + xs[2], offset, ""
158 -}
Godeps/_workspace/src/github.com/miekg/dns/zscan.go deleted
-964
@@ -1,964 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "io"
5 - "log"
6 - "os"
7 - "strconv"
8 - "strings"
9 -)
10 -
11 -type debugging bool
12 -
13 -const debug debugging = false
14 -
15 -func (d debugging) Printf(format string, args ...interface{}) {
16 - if d {
17 - log.Printf(format, args...)
18 - }
19 -}
20 -
21 -const maxTok = 2048 // Largest token we can return.
22 -const maxUint16 = 1<<16 - 1
23 -
24 -// Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
25 -// * Add ownernames if they are left blank;
26 -// * Suppress sequences of spaces;
27 -// * Make each RR fit on one line (_NEWLINE is send as last)
28 -// * Handle comments: ;
29 -// * Handle braces - anywhere.
30 -const (
31 - // Zonefile
32 - zEOF = iota
33 - zString
34 - zBlank
35 - zQuote
36 - zNewline
37 - zRrtpe
38 - zOwner
39 - zClass
40 - zDirOrigin // $ORIGIN
41 - zDirTtl // $TTL
42 - zDirInclude // $INCLUDE
43 - zDirGenerate // $GENERATE
44 -
45 - // Privatekey file
46 - zValue
47 - zKey
48 -
49 - zExpectOwnerDir // Ownername
50 - zExpectOwnerBl // Whitespace after the ownername
51 - zExpectAny // Expect rrtype, ttl or class
52 - zExpectAnyNoClass // Expect rrtype or ttl
53 - zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS
54 - zExpectAnyNoTtl // Expect rrtype or class
55 - zExpectAnyNoTtlBl // Whitespace after _EXPECT_ANY_NOTTL
56 - zExpectRrtype // Expect rrtype
57 - zExpectRrtypeBl // Whitespace BEFORE rrtype
58 - zExpectRdata // The first element of the rdata
59 - zExpectDirTtlBl // Space after directive $TTL
60 - zExpectDirTtl // Directive $TTL
61 - zExpectDirOriginBl // Space after directive $ORIGIN
62 - zExpectDirOrigin // Directive $ORIGIN
63 - zExpectDirIncludeBl // Space after directive $INCLUDE
64 - zExpectDirInclude // Directive $INCLUDE
65 - zExpectDirGenerate // Directive $GENERATE
66 - zExpectDirGenerateBl // Space after directive $GENERATE
67 -)
68 -
69 -// ParseError is a parsing error. It contains the parse error and the location in the io.Reader
70 -// where the error occured.
71 -type ParseError struct {
72 - file string
73 - err string
74 - lex lex
75 -}
76 -
77 -func (e *ParseError) Error() (s string) {
78 - if e.file != "" {
79 - s = e.file + ": "
80 - }
81 - s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " +
82 - strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column)
83 - return
84 -}
85 -
86 -type lex struct {
87 - token string // text of the token
88 - tokenUpper string // uppercase text of the token
89 - length int // lenght of the token
90 - err bool // when true, token text has lexer error
91 - value uint8 // value: zString, _BLANK, etc.
92 - line int // line in the file
93 - column int // column in the file
94 - torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
95 - comment string // any comment text seen
96 -}
97 -
98 -// Token holds the token that are returned when a zone file is parsed.
99 -type Token struct {
100 - // The scanned resource record when error is not nil.
101 - RR
102 - // When an error occured, this has the error specifics.
103 - Error *ParseError
104 - // A potential comment positioned after the RR and on the same line.
105 - Comment string
106 -}
107 -
108 -// NewRR reads the RR contained in the string s. Only the first RR is
109 -// returned. If s contains no RR, return nil with no error. The class
110 -// defaults to IN and TTL defaults to 3600. The full zone file syntax
111 -// like $TTL, $ORIGIN, etc. is supported. All fields of the returned
112 -// RR are set, except RR.Header().Rdlength which is set to 0.
113 -func NewRR(s string) (RR, error) {
114 - if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
115 - return ReadRR(strings.NewReader(s+"\n"), "")
116 - }
117 - return ReadRR(strings.NewReader(s), "")
118 -}
119 -
120 -// ReadRR reads the RR contained in q.
121 -// See NewRR for more documentation.
122 -func ReadRR(q io.Reader, filename string) (RR, error) {
123 - r := <-parseZoneHelper(q, ".", filename, 1)
124 - if r == nil {
125 - return nil, nil
126 - }
127 -
128 - if r.Error != nil {
129 - return nil, r.Error
130 - }
131 - return r.RR, nil
132 -}
133 -
134 -// ParseZone reads a RFC 1035 style one from r. It returns *Tokens on the
135 -// returned channel, which consist out the parsed RR, a potential comment or an error.
136 -// If there is an error the RR is nil. The string file is only used
137 -// in error reporting. The string origin is used as the initial origin, as
138 -// if the file would start with: $ORIGIN origin .
139 -// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported.
140 -// The channel t is closed by ParseZone when the end of r is reached.
141 -//
142 -// Basic usage pattern when reading from a string (z) containing the
143 -// zone data:
144 -//
145 -// for x := range dns.ParseZone(strings.NewReader(z), "", "") {
146 -// if x.Error != nil {
147 -// // Do something with x.RR
148 -// }
149 -// }
150 -//
151 -// Comments specified after an RR (and on the same line!) are returned too:
152 -//
153 -// foo. IN A 10.0.0.1 ; this is a comment
154 -//
155 -// The text "; this is comment" is returned in Token.Comment . Comments inside the
156 -// RR are discarded. Comments on a line by themselves are discarded too.
157 -func ParseZone(r io.Reader, origin, file string) chan *Token {
158 - return parseZoneHelper(r, origin, file, 10000)
159 -}
160 -
161 -func parseZoneHelper(r io.Reader, origin, file string, chansize int) chan *Token {
162 - t := make(chan *Token, chansize)
163 - go parseZone(r, origin, file, t, 0)
164 - return t
165 -}
166 -
167 -func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
168 - defer func() {
169 - if include == 0 {
170 - close(t)
171 - }
172 - }()
173 - s := scanInit(r)
174 - c := make(chan lex)
175 - // Start the lexer
176 - go zlexer(s, c)
177 - // 6 possible beginnings of a line, _ is a space
178 - // 0. zRRTYPE -> all omitted until the rrtype
179 - // 1. zOwner _ zRrtype -> class/ttl omitted
180 - // 2. zOwner _ zString _ zRrtype -> class omitted
181 - // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class
182 - // 4. zOwner _ zClass _ zRrtype -> ttl omitted
183 - // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed)
184 - // After detecting these, we know the zRrtype so we can jump to functions
185 - // handling the rdata for each of these types.
186 -
187 - if origin == "" {
188 - origin = "."
189 - }
190 - origin = Fqdn(origin)
191 - if _, ok := IsDomainName(origin); !ok {
192 - t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}}
193 - return
194 - }
195 -
196 - st := zExpectOwnerDir // initial state
197 - var h RR_Header
198 - var defttl uint32 = defaultTtl
199 - var prevName string
200 - for l := range c {
201 - // Lexer spotted an error already
202 - if l.err == true {
203 - t <- &Token{Error: &ParseError{f, l.token, l}}
204 - return
205 -
206 - }
207 - switch st {
208 - case zExpectOwnerDir:
209 - // We can also expect a directive, like $TTL or $ORIGIN
210 - h.Ttl = defttl
211 - h.Class = ClassINET
212 - switch l.value {
213 - case zNewline:
214 - st = zExpectOwnerDir
215 - case zOwner:
216 - h.Name = l.token
217 - if l.token[0] == '@' {
218 - h.Name = origin
219 - prevName = h.Name
220 - st = zExpectOwnerBl
221 - break
222 - }
223 - if h.Name[l.length-1] != '.' {
224 - h.Name = appendOrigin(h.Name, origin)
225 - }
226 - _, ok := IsDomainName(l.token)
227 - if !ok {
228 - t <- &Token{Error: &ParseError{f, "bad owner name", l}}
229 - return
230 - }
231 - prevName = h.Name
232 - st = zExpectOwnerBl
233 - case zDirTtl:
234 - st = zExpectDirTtlBl
235 - case zDirOrigin:
236 - st = zExpectDirOriginBl
237 - case zDirInclude:
238 - st = zExpectDirIncludeBl
239 - case zDirGenerate:
240 - st = zExpectDirGenerateBl
241 - case zRrtpe:
242 - h.Name = prevName
243 - h.Rrtype = l.torc
244 - st = zExpectRdata
245 - case zClass:
246 - h.Name = prevName
247 - h.Class = l.torc
248 - st = zExpectAnyNoClassBl
249 - case zBlank:
250 - // Discard, can happen when there is nothing on the
251 - // line except the RR type
252 - case zString:
253 - ttl, ok := stringToTtl(l.token)
254 - if !ok {
255 - t <- &Token{Error: &ParseError{f, "not a TTL", l}}
256 - return
257 - }
258 - h.Ttl = ttl
259 - // Don't about the defttl, we should take the $TTL value
260 - // defttl = ttl
261 - st = zExpectAnyNoTtlBl
262 -
263 - default:
264 - t <- &Token{Error: &ParseError{f, "syntax error at beginning", l}}
265 - return
266 - }
267 - case zExpectDirIncludeBl:
268 - if l.value != zBlank {
269 - t <- &Token{Error: &ParseError{f, "no blank after $INCLUDE-directive", l}}
270 - return
271 - }
272 - st = zExpectDirInclude
273 - case zExpectDirInclude:
274 - if l.value != zString {
275 - t <- &Token{Error: &ParseError{f, "expecting $INCLUDE value, not this...", l}}
276 - return
277 - }
278 - neworigin := origin // There may be optionally a new origin set after the filename, if not use current one
279 - l := <-c
280 - switch l.value {
281 - case zBlank:
282 - l := <-c
283 - if l.value == zString {
284 - if _, ok := IsDomainName(l.token); !ok {
285 - t <- &Token{Error: &ParseError{f, "bad origin name", l}}
286 - return
287 - }
288 - // a new origin is specified.
289 - if l.token[l.length-1] != '.' {
290 - if origin != "." { // Prevent .. endings
291 - neworigin = l.token + "." + origin
292 - } else {
293 - neworigin = l.token + origin
294 - }
295 - } else {
296 - neworigin = l.token
297 - }
298 - }
299 - case zNewline, zEOF:
300 - // Ok
301 - default:
302 - t <- &Token{Error: &ParseError{f, "garbage after $INCLUDE", l}}
303 - return
304 - }
305 - // Start with the new file
306 - r1, e1 := os.Open(l.token)
307 - if e1 != nil {
308 - t <- &Token{Error: &ParseError{f, "failed to open `" + l.token + "'", l}}
309 - return
310 - }
311 - if include+1 > 7 {
312 - t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}}
313 - return
314 - }
315 - parseZone(r1, l.token, neworigin, t, include+1)
316 - st = zExpectOwnerDir
317 - case zExpectDirTtlBl:
318 - if l.value != zBlank {
319 - t <- &Token{Error: &ParseError{f, "no blank after $TTL-directive", l}}
320 - return
321 - }
322 - st = zExpectDirTtl
323 - case zExpectDirTtl:
324 - if l.value != zString {
325 - t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
326 - return
327 - }
328 - if e, _ := slurpRemainder(c, f); e != nil {
329 - t <- &Token{Error: e}
330 - return
331 - }
332 - ttl, ok := stringToTtl(l.token)
333 - if !ok {
334 - t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}}
335 - return
336 - }
337 - defttl = ttl
338 - st = zExpectOwnerDir
339 - case zExpectDirOriginBl:
340 - if l.value != zBlank {
341 - t <- &Token{Error: &ParseError{f, "no blank after $ORIGIN-directive", l}}
342 - return
343 - }
344 - st = zExpectDirOrigin
345 - case zExpectDirOrigin:
346 - if l.value != zString {
347 - t <- &Token{Error: &ParseError{f, "expecting $ORIGIN value, not this...", l}}
348 - return
349 - }
350 - if e, _ := slurpRemainder(c, f); e != nil {
351 - t <- &Token{Error: e}
352 - }
353 - if _, ok := IsDomainName(l.token); !ok {
354 - t <- &Token{Error: &ParseError{f, "bad origin name", l}}
355 - return
356 - }
357 - if l.token[l.length-1] != '.' {
358 - if origin != "." { // Prevent .. endings
359 - origin = l.token + "." + origin
360 - } else {
361 - origin = l.token + origin
362 - }
363 - } else {
364 - origin = l.token
365 - }
366 - st = zExpectOwnerDir
367 - case zExpectDirGenerateBl:
368 - if l.value != zBlank {
369 - t <- &Token{Error: &ParseError{f, "no blank after $GENERATE-directive", l}}
370 - return
371 - }
372 - st = zExpectDirGenerate
373 - case zExpectDirGenerate:
374 - if l.value != zString {
375 - t <- &Token{Error: &ParseError{f, "expecting $GENERATE value, not this...", l}}
376 - return
377 - }
378 - if e := generate(l, c, t, origin); e != "" {
379 - t <- &Token{Error: &ParseError{f, e, l}}
380 - return
381 - }
382 - st = zExpectOwnerDir
383 - case zExpectOwnerBl:
384 - if l.value != zBlank {
385 - t <- &Token{Error: &ParseError{f, "no blank after owner", l}}
386 - return
387 - }
388 - st = zExpectAny
389 - case zExpectAny:
390 - switch l.value {
391 - case zRrtpe:
392 - h.Rrtype = l.torc
393 - st = zExpectRdata
394 - case zClass:
395 - h.Class = l.torc
396 - st = zExpectAnyNoClassBl
397 - case zString:
398 - ttl, ok := stringToTtl(l.token)
399 - if !ok {
400 - t <- &Token{Error: &ParseError{f, "not a TTL", l}}
401 - return
402 - }
403 - h.Ttl = ttl
404 - // defttl = ttl // don't set the defttl here
405 - st = zExpectAnyNoTtlBl
406 - default:
407 - t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}}
408 - return
409 - }
410 - case zExpectAnyNoClassBl:
411 - if l.value != zBlank {
412 - t <- &Token{Error: &ParseError{f, "no blank before class", l}}
413 - return
414 - }
415 - st = zExpectAnyNoClass
416 - case zExpectAnyNoTtlBl:
417 - if l.value != zBlank {
418 - t <- &Token{Error: &ParseError{f, "no blank before TTL", l}}
419 - return
420 - }
421 - st = zExpectAnyNoTtl
422 - case zExpectAnyNoTtl:
423 - switch l.value {
424 - case zClass:
425 - h.Class = l.torc
426 - st = zExpectRrtypeBl
427 - case zRrtpe:
428 - h.Rrtype = l.torc
429 - st = zExpectRdata
430 - default:
431 - t <- &Token{Error: &ParseError{f, "expecting RR type or class, not this...", l}}
432 - return
433 - }
434 - case zExpectAnyNoClass:
435 - switch l.value {
436 - case zString:
437 - ttl, ok := stringToTtl(l.token)
438 - if !ok {
439 - t <- &Token{Error: &ParseError{f, "not a TTL", l}}
440 - return
441 - }
442 - h.Ttl = ttl
443 - // defttl = ttl // don't set the def ttl anymore
444 - st = zExpectRrtypeBl
445 - case zRrtpe:
446 - h.Rrtype = l.torc
447 - st = zExpectRdata
448 - default:
449 - t <- &Token{Error: &ParseError{f, "expecting RR type or TTL, not this...", l}}
450 - return
451 - }
452 - case zExpectRrtypeBl:
453 - if l.value != zBlank {
454 - t <- &Token{Error: &ParseError{f, "no blank before RR type", l}}
455 - return
456 - }
457 - st = zExpectRrtype
458 - case zExpectRrtype:
459 - if l.value != zRrtpe {
460 - t <- &Token{Error: &ParseError{f, "unknown RR type", l}}
461 - return
462 - }
463 - h.Rrtype = l.torc
464 - st = zExpectRdata
465 - case zExpectRdata:
466 - r, e, c1 := setRR(h, c, origin, f)
467 - if e != nil {
468 - // If e.lex is nil than we have encounter a unknown RR type
469 - // in that case we substitute our current lex token
470 - if e.lex.token == "" && e.lex.value == 0 {
471 - e.lex = l // Uh, dirty
472 - }
473 - t <- &Token{Error: e}
474 - return
475 - }
476 - t <- &Token{RR: r, Comment: c1}
477 - st = zExpectOwnerDir
478 - }
479 - }
480 - // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this
481 - // is not an error, because an empty zone file is still a zone file.
482 -}
483 -
484 -// zlexer scans the sourcefile and returns tokens on the channel c.
485 -func zlexer(s *scan, c chan lex) {
486 - var l lex
487 - str := make([]byte, maxTok) // Should be enough for any token
488 - stri := 0 // Offset in str (0 means empty)
489 - com := make([]byte, maxTok) // Hold comment text
490 - comi := 0
491 - quote := false
492 - escape := false
493 - space := false
494 - commt := false
495 - rrtype := false
496 - owner := true
497 - brace := 0
498 - x, err := s.tokenText()
499 - defer close(c)
500 - for err == nil {
501 - l.column = s.position.Column
502 - l.line = s.position.Line
503 - if stri > maxTok {
504 - l.token = "token length insufficient for parsing"
505 - l.err = true
506 - debug.Printf("[%+v]", l.token)
507 - c <- l
508 - return
509 - }
510 - if comi > maxTok {
511 - l.token = "comment length insufficient for parsing"
512 - l.err = true
513 - debug.Printf("[%+v]", l.token)
514 - c <- l
515 - return
516 - }
517 -
518 - switch x {
519 - case ' ', '\t':
520 - if escape {
521 - escape = false
522 - str[stri] = x
523 - stri++
524 - break
525 - }
526 - if quote {
527 - // Inside quotes this is legal
528 - str[stri] = x
529 - stri++
530 - break
531 - }
532 - if commt {
533 - com[comi] = x
534 - comi++
535 - break
536 - }
537 - if stri == 0 {
538 - // Space directly in the beginning, handled in the grammar
539 - } else if owner {
540 - // If we have a string and its the first, make it an owner
541 - l.value = zOwner
542 - l.token = string(str[:stri])
543 - l.tokenUpper = strings.ToUpper(l.token)
544 - l.length = stri
545 - // escape $... start with a \ not a $, so this will work
546 - switch l.tokenUpper {
547 - case "$TTL":
548 - l.value = zDirTtl
549 - case "$ORIGIN":
550 - l.value = zDirOrigin
551 - case "$INCLUDE":
552 - l.value = zDirInclude
553 - case "$GENERATE":
554 - l.value = zDirGenerate
555 - }
556 - debug.Printf("[7 %+v]", l.token)
557 - c <- l
558 - } else {
559 - l.value = zString
560 - l.token = string(str[:stri])
561 - l.tokenUpper = strings.ToUpper(l.token)
562 - l.length = stri
563 - if !rrtype {
564 - if t, ok := StringToType[l.tokenUpper]; ok {
565 - l.value = zRrtpe
566 - l.torc = t
567 - rrtype = true
568 - } else {
569 - if strings.HasPrefix(l.tokenUpper, "TYPE") {
570 - t, ok := typeToInt(l.token)
571 - if !ok {
572 - l.token = "unknown RR type"
573 - l.err = true
574 - c <- l
575 - return
576 - }
577 - l.value = zRrtpe
578 - l.torc = t
579 - }
580 - }
581 - if t, ok := StringToClass[l.tokenUpper]; ok {
582 - l.value = zClass
583 - l.torc = t
584 - } else {
585 - if strings.HasPrefix(l.tokenUpper, "CLASS") {
586 - t, ok := classToInt(l.token)
587 - if !ok {
588 - l.token = "unknown class"
589 - l.err = true
590 - c <- l
591 - return
592 - }
593 - l.value = zClass
594 - l.torc = t
595 - }
596 - }
597 - }
598 - debug.Printf("[6 %+v]", l.token)
599 - c <- l
600 - }
601 - stri = 0
602 - // I reverse space stuff here
603 - if !space && !commt {
604 - l.value = zBlank
605 - l.token = " "
606 - l.length = 1
607 - debug.Printf("[5 %+v]", l.token)
608 - c <- l
609 - }
610 - owner = false
611 - space = true
612 - case ';':
613 - if escape {
614 - escape = false
615 - str[stri] = x
616 - stri++
617 - break
618 - }
619 - if quote {
620 - // Inside quotes this is legal
621 - str[stri] = x
622 - stri++
623 - break
624 - }
625 - if stri > 0 {
626 - l.value = zString
627 - l.token = string(str[:stri])
628 - l.length = stri
629 - debug.Printf("[4 %+v]", l.token)
630 - c <- l
631 - stri = 0
632 - }
633 - commt = true
634 - com[comi] = ';'
635 - comi++
636 - case '\r':
637 - escape = false
638 - if quote {
639 - str[stri] = x
640 - stri++
641 - break
642 - }
643 - // discard if outside of quotes
644 - case '\n':
645 - escape = false
646 - // Escaped newline
647 - if quote {
648 - str[stri] = x
649 - stri++
650 - break
651 - }
652 - // inside quotes this is legal
653 - if commt {
654 - // Reset a comment
655 - commt = false
656 - rrtype = false
657 - stri = 0
658 - // If not in a brace this ends the comment AND the RR
659 - if brace == 0 {
660 - owner = true
661 - owner = true
662 - l.value = zNewline
663 - l.token = "\n"
664 - l.length = 1
665 - l.comment = string(com[:comi])
666 - debug.Printf("[3 %+v %+v]", l.token, l.comment)
667 - c <- l
668 - l.comment = ""
669 - comi = 0
670 - break
671 - }
672 - com[comi] = ' ' // convert newline to space
673 - comi++
674 - break
675 - }
676 -
677 - if brace == 0 {
678 - // If there is previous text, we should output it here
679 - if stri != 0 {
680 - l.value = zString
681 - l.token = string(str[:stri])
682 - l.tokenUpper = strings.ToUpper(l.token)
683 -
684 - l.length = stri
685 - if !rrtype {
686 - if t, ok := StringToType[l.tokenUpper]; ok {
687 - l.value = zRrtpe
688 - l.torc = t
689 - rrtype = true
690 - }
691 - }
692 - debug.Printf("[2 %+v]", l.token)
693 - c <- l
694 - }
695 - l.value = zNewline
696 - l.token = "\n"
697 - l.length = 1
698 - debug.Printf("[1 %+v]", l.token)
699 - c <- l
700 - stri = 0
701 - commt = false
702 - rrtype = false
703 - owner = true
704 - comi = 0
705 - }
706 - case '\\':
707 - // comments do not get escaped chars, everything is copied
708 - if commt {
709 - com[comi] = x
710 - comi++
711 - break
712 - }
713 - // something already escaped must be in string
714 - if escape {
715 - str[stri] = x
716 - stri++
717 - escape = false
718 - break
719 - }
720 - // something escaped outside of string gets added to string
721 - str[stri] = x
722 - stri++
723 - escape = true
724 - case '"':
725 - if commt {
726 - com[comi] = x
727 - comi++
728 - break
729 - }
730 - if escape {
731 - str[stri] = x
732 - stri++
733 - escape = false
734 - break
735 - }
736 - space = false
737 - // send previous gathered text and the quote
738 - if stri != 0 {
739 - l.value = zString
740 - l.token = string(str[:stri])
741 - l.length = stri
742 -
743 - debug.Printf("[%+v]", l.token)
744 - c <- l
745 - stri = 0
746 - }
747 -
748 - // send quote itself as separate token
749 - l.value = zQuote
750 - l.token = "\""
751 - l.length = 1
752 - c <- l
753 - quote = !quote
754 - case '(', ')':
755 - if commt {
756 - com[comi] = x
757 - comi++
758 - break
759 - }
760 - if escape {
761 - str[stri] = x
762 - stri++
763 - escape = false
764 - break
765 - }
766 - if quote {
767 - str[stri] = x
768 - stri++
769 - break
770 - }
771 - switch x {
772 - case ')':
773 - brace--
774 - if brace < 0 {
775 - l.token = "extra closing brace"
776 - l.err = true
777 - debug.Printf("[%+v]", l.token)
778 - c <- l
779 - return
780 - }
781 - case '(':
782 - brace++
783 - }
784 - default:
785 - escape = false
786 - if commt {
787 - com[comi] = x
788 - comi++
789 - break
790 - }
791 - str[stri] = x
792 - stri++
793 - space = false
794 - }
795 - x, err = s.tokenText()
796 - }
797 - if stri > 0 {
798 - // Send remainder
799 - l.token = string(str[:stri])
800 - l.length = stri
801 - l.value = zString
802 - debug.Printf("[%+v]", l.token)
803 - c <- l
804 - }
805 -}
806 -
807 -// Extract the class number from CLASSxx
808 -func classToInt(token string) (uint16, bool) {
809 - class, ok := strconv.Atoi(token[5:])
810 - if ok != nil || class > maxUint16 {
811 - return 0, false
812 - }
813 - return uint16(class), true
814 -}
815 -
816 -// Extract the rr number from TYPExxx
817 -func typeToInt(token string) (uint16, bool) {
818 - typ, ok := strconv.Atoi(token[4:])
819 - if ok != nil || typ > maxUint16 {
820 - return 0, false
821 - }
822 - return uint16(typ), true
823 -}
824 -
825 -// Parse things like 2w, 2m, etc, Return the time in seconds.
826 -func stringToTtl(token string) (uint32, bool) {
827 - s := uint32(0)
828 - i := uint32(0)
829 - for _, c := range token {
830 - switch c {
831 - case 's', 'S':
832 - s += i
833 - i = 0
834 - case 'm', 'M':
835 - s += i * 60
836 - i = 0
837 - case 'h', 'H':
838 - s += i * 60 * 60
839 - i = 0
840 - case 'd', 'D':
841 - s += i * 60 * 60 * 24
842 - i = 0
843 - case 'w', 'W':
844 - s += i * 60 * 60 * 24 * 7
845 - i = 0
846 - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
847 - i *= 10
848 - i += uint32(c) - '0'
849 - default:
850 - return 0, false
851 - }
852 - }
853 - return s + i, true
854 -}
855 -
856 -// Parse LOC records' <digits>[.<digits>][mM] into a
857 -// mantissa exponent format. Token should contain the entire
858 -// string (i.e. no spaces allowed)
859 -func stringToCm(token string) (e, m uint8, ok bool) {
860 - if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' {
861 - token = token[0 : len(token)-1]
862 - }
863 - s := strings.SplitN(token, ".", 2)
864 - var meters, cmeters, val int
865 - var err error
866 - switch len(s) {
867 - case 2:
868 - if cmeters, err = strconv.Atoi(s[1]); err != nil {
869 - return
870 - }
871 - fallthrough
872 - case 1:
873 - if meters, err = strconv.Atoi(s[0]); err != nil {
874 - return
875 - }
876 - case 0:
877 - // huh?
878 - return 0, 0, false
879 - }
880 - ok = true
881 - if meters > 0 {
882 - e = 2
883 - val = meters
884 - } else {
885 - e = 0
886 - val = cmeters
887 - }
888 - for val > 10 {
889 - e++
890 - val /= 10
891 - }
892 - if e > 9 {
893 - ok = false
894 - }
895 - m = uint8(val)
896 - return
897 -}
898 -
899 -func appendOrigin(name, origin string) string {
900 - if origin == "." {
901 - return name + origin
902 - }
903 - return name + "." + origin
904 -}
905 -
906 -// LOC record helper function
907 -func locCheckNorth(token string, latitude uint32) (uint32, bool) {
908 - switch token {
909 - case "n", "N":
910 - return LOC_EQUATOR + latitude, true
911 - case "s", "S":
912 - return LOC_EQUATOR - latitude, true
913 - }
914 - return latitude, false
915 -}
916 -
917 -// LOC record helper function
918 -func locCheckEast(token string, longitude uint32) (uint32, bool) {
919 - switch token {
920 - case "e", "E":
921 - return LOC_EQUATOR + longitude, true
922 - case "w", "W":
923 - return LOC_EQUATOR - longitude, true
924 - }
925 - return longitude, false
926 -}
927 -
928 -// "Eat" the rest of the "line". Return potential comments
929 -func slurpRemainder(c chan lex, f string) (*ParseError, string) {
930 - l := <-c
931 - com := ""
932 - switch l.value {
933 - case zBlank:
934 - l = <-c
935 - com = l.comment
936 - if l.value != zNewline && l.value != zEOF {
937 - return &ParseError{f, "garbage after rdata", l}, ""
938 - }
939 - case zNewline:
940 - com = l.comment
941 - case zEOF:
942 - default:
943 - return &ParseError{f, "garbage after rdata", l}, ""
944 - }
945 - return nil, com
946 -}
947 -
948 -// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"
949 -// Used for NID and L64 record.
950 -func stringToNodeID(l lex) (uint64, *ParseError) {
951 - if len(l.token) < 19 {
952 - return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
953 - }
954 - // There must be three colons at fixes postitions, if not its a parse error
955 - if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' {
956 - return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
957 - }
958 - s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19]
959 - u, e := strconv.ParseUint(s, 16, 64)
960 - if e != nil {
961 - return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l}
962 - }
963 - return u, nil
964 -}
Godeps/_workspace/src/github.com/miekg/dns/zscan_rr.go deleted
-2202
@@ -1,2202 +0,0 @@
1 -package dns
2 -
3 -import (
4 - "encoding/base64"
5 - "net"
6 - "strconv"
7 - "strings"
8 -)
9 -
10 -type parserFunc struct {
11 - // Func defines the function that parses the tokens and returns the RR
12 - // or an error. The last string contains any comments in the line as
13 - // they returned by the lexer as well.
14 - Func func(h RR_Header, c chan lex, origin string, file string) (RR, *ParseError, string)
15 - // Signals if the RR ending is of variable length, like TXT or records
16 - // that have Hexadecimal or Base64 as their last element in the Rdata. Records
17 - // that have a fixed ending or for instance A, AAAA, SOA and etc.
18 - Variable bool
19 -}
20 -
21 -// Parse the rdata of each rrtype.
22 -// All data from the channel c is either zString or zBlank.
23 -// After the rdata there may come a zBlank and then a zNewline
24 -// or immediately a zNewline. If this is not the case we flag
25 -// an *ParseError: garbage after rdata.
26 -func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
27 - parserfunc, ok := typeToparserFunc[h.Rrtype]
28 - if ok {
29 - r, e, cm := parserfunc.Func(h, c, o, f)
30 - if parserfunc.Variable {
31 - return r, e, cm
32 - }
33 - if e != nil {
34 - return nil, e, ""
35 - }
36 - e, cm = slurpRemainder(c, f)
37 - if e != nil {
38 - return nil, e, ""
39 - }
40 - return r, nil, cm
41 - }
42 - // RFC3957 RR (Unknown RR handling)
43 - return setRFC3597(h, c, o, f)
44 -}
45 -
46 -// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces)
47 -// or an error
48 -func endingToString(c chan lex, errstr, f string) (string, *ParseError, string) {
49 - s := ""
50 - l := <-c // zString
51 - for l.value != zNewline && l.value != zEOF {
52 - switch l.value {
53 - case zString:
54 - s += l.token
55 - case zBlank: // Ok
56 - default:
57 - return "", &ParseError{f, errstr, l}, ""
58 - }
59 - l = <-c
60 - }
61 - return s, nil, l.comment
62 -}
63 -
64 -// A remainder of the rdata with embedded spaces, return the parsed string slice (sans the spaces)
65 -// or an error
66 -func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) {
67 - // Get the remaining data until we see a zNewline
68 - quote := false
69 - l := <-c
70 - var s []string
71 - switch l.value == zQuote {
72 - case true: // A number of quoted string
73 - s = make([]string, 0)
74 - empty := true
75 - for l.value != zNewline && l.value != zEOF {
76 - switch l.value {
77 - case zString:
78 - empty = false
79 - if len(l.token) > 255 {
80 - // split up tokens that are larger than 255 into 255-chunks
81 - sx := []string{}
82 - p, i := 0, 255
83 - for {
84 - if i <= len(l.token) {
85 - sx = append(sx, l.token[p:i])
86 - } else {
87 - sx = append(sx, l.token[p:])
88 - break
89 -
90 - }
91 - p, i = p+255, i+255
92 - }
93 - s = append(s, sx...)
94 - break;
95 - }
96 -
97 - s = append(s, l.token)
98 - case zBlank:
99 - if quote {
100 - // zBlank can only be seen in between txt parts.
101 - return nil, &ParseError{f, errstr, l}, ""
102 - }
103 - case zQuote:
104 - if empty && quote {
105 - s = append(s, "")
106 - }
107 - quote = !quote
108 - empty = true
109 - default:
110 - return nil, &ParseError{f, errstr, l}, ""
111 - }
112 - l = <-c
113 - }
114 - if quote {
115 - return nil, &ParseError{f, errstr, l}, ""
116 - }
117 - case false: // Unquoted text record
118 - s = make([]string, 1)
119 - for l.value != zNewline && l.value != zEOF {
120 - s[0] += l.token
121 - l = <-c
122 - }
123 - }
124 - return s, nil, l.comment
125 -}
126 -
127 -func setA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
128 - rr := new(A)
129 - rr.Hdr = h
130 -
131 - l := <-c
132 - if l.length == 0 { // Dynamic updates.
133 - return rr, nil, ""
134 - }
135 - rr.A = net.ParseIP(l.token)
136 - if rr.A == nil {
137 - return nil, &ParseError{f, "bad A A", l}, ""
138 - }
139 - return rr, nil, ""
140 -}
141 -
142 -func setAAAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
143 - rr := new(AAAA)
144 - rr.Hdr = h
145 -
146 - l := <-c
147 - if l.length == 0 {
148 - return rr, nil, ""
149 - }
150 - rr.AAAA = net.ParseIP(l.token)
151 - if rr.AAAA == nil {
152 - return nil, &ParseError{f, "bad AAAA AAAA", l}, ""
153 - }
154 - return rr, nil, ""
155 -}
156 -
157 -func setNS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
158 - rr := new(NS)
159 - rr.Hdr = h
160 -
161 - l := <-c
162 - rr.Ns = l.token
163 - if l.length == 0 {
164 - return rr, nil, ""
165 - }
166 - if l.token == "@" {
167 - rr.Ns = o
168 - return rr, nil, ""
169 - }
170 - _, ok := IsDomainName(l.token)
171 - if !ok {
172 - return nil, &ParseError{f, "bad NS Ns", l}, ""
173 - }
174 - if rr.Ns[l.length-1] != '.' {
175 - rr.Ns = appendOrigin(rr.Ns, o)
176 - }
177 - return rr, nil, ""
178 -}
179 -
180 -func setPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
181 - rr := new(PTR)
182 - rr.Hdr = h
183 -
184 - l := <-c
185 - rr.Ptr = l.token
186 - if l.length == 0 { // dynamic update rr.
187 - return rr, nil, ""
188 - }
189 - if l.token == "@" {
190 - rr.Ptr = o
191 - return rr, nil, ""
192 - }
193 - _, ok := IsDomainName(l.token)
194 - if !ok {
195 - return nil, &ParseError{f, "bad PTR Ptr", l}, ""
196 - }
197 - if rr.Ptr[l.length-1] != '.' {
198 - rr.Ptr = appendOrigin(rr.Ptr, o)
199 - }
200 - return rr, nil, ""
201 -}
202 -
203 -func setNSAPPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
204 - rr := new(NSAPPTR)
205 - rr.Hdr = h
206 -
207 - l := <-c
208 - rr.Ptr = l.token
209 - if l.length == 0 {
210 - return rr, nil, ""
211 - }
212 - if l.token == "@" {
213 - rr.Ptr = o
214 - return rr, nil, ""
215 - }
216 - _, ok := IsDomainName(l.token)
217 - if !ok {
218 - return nil, &ParseError{f, "bad NSAP-PTR Ptr", l}, ""
219 - }
220 - if rr.Ptr[l.length-1] != '.' {
221 - rr.Ptr = appendOrigin(rr.Ptr, o)
222 - }
223 - return rr, nil, ""
224 -}
225 -
226 -func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
227 - rr := new(RP)
228 - rr.Hdr = h
229 -
230 - l := <-c
231 - rr.Mbox = l.token
232 - if l.length == 0 {
233 - return rr, nil, ""
234 - }
235 - if l.token == "@" {
236 - rr.Mbox = o
237 - } else {
238 - _, ok := IsDomainName(l.token)
239 - if !ok {
240 - return nil, &ParseError{f, "bad RP Mbox", l}, ""
241 - }
242 - if rr.Mbox[l.length-1] != '.' {
243 - rr.Mbox = appendOrigin(rr.Mbox, o)
244 - }
245 - }
246 - <-c // zBlank
247 - l = <-c
248 - rr.Txt = l.token
249 - if l.token == "@" {
250 - rr.Txt = o
251 - return rr, nil, ""
252 - }
253 - _, ok := IsDomainName(l.token)
254 - if !ok {
255 - return nil, &ParseError{f, "bad RP Txt", l}, ""
256 - }
257 - if rr.Txt[l.length-1] != '.' {
258 - rr.Txt = appendOrigin(rr.Txt, o)
259 - }
260 - return rr, nil, ""
261 -}
262 -
263 -func setMR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
264 - rr := new(MR)
265 - rr.Hdr = h
266 -
267 - l := <-c
268 - rr.Mr = l.token
269 - if l.length == 0 {
270 - return rr, nil, ""
271 - }
272 - if l.token == "@" {
273 - rr.Mr = o
274 - return rr, nil, ""
275 - }
276 - _, ok := IsDomainName(l.token)
277 - if !ok {
278 - return nil, &ParseError{f, "bad MR Mr", l}, ""
279 - }
280 - if rr.Mr[l.length-1] != '.' {
281 - rr.Mr = appendOrigin(rr.Mr, o)
282 - }
283 - return rr, nil, ""
284 -}
285 -
286 -func setMB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
287 - rr := new(MB)
288 - rr.Hdr = h
289 -
290 - l := <-c
291 - rr.Mb = l.token
292 - if l.length == 0 {
293 - return rr, nil, ""
294 - }
295 - if l.token == "@" {
296 - rr.Mb = o
297 - return rr, nil, ""
298 - }
299 - _, ok := IsDomainName(l.token)
300 - if !ok {
301 - return nil, &ParseError{f, "bad MB Mb", l}, ""
302 - }
303 - if rr.Mb[l.length-1] != '.' {
304 - rr.Mb = appendOrigin(rr.Mb, o)
305 - }
306 - return rr, nil, ""
307 -}
308 -
309 -func setMG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
310 - rr := new(MG)
311 - rr.Hdr = h
312 -
313 - l := <-c
314 - rr.Mg = l.token
315 - if l.length == 0 {
316 - return rr, nil, ""
317 - }
318 - if l.token == "@" {
319 - rr.Mg = o
320 - return rr, nil, ""
321 - }
322 - _, ok := IsDomainName(l.token)
323 - if !ok {
324 - return nil, &ParseError{f, "bad MG Mg", l}, ""
325 - }
326 - if rr.Mg[l.length-1] != '.' {
327 - rr.Mg = appendOrigin(rr.Mg, o)
328 - }
329 - return rr, nil, ""
330 -}
331 -
332 -func setHINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
333 - rr := new(HINFO)
334 - rr.Hdr = h
335 -
336 - l := <-c
337 - rr.Cpu = l.token
338 - <-c // zBlank
339 - l = <-c // zString
340 - rr.Os = l.token
341 -
342 - return rr, nil, ""
343 -}
344 -
345 -func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
346 - rr := new(MINFO)
347 - rr.Hdr = h
348 -
349 - l := <-c
350 - rr.Rmail = l.token
351 - if l.length == 0 {
352 - return rr, nil, ""
353 - }
354 - if l.token == "@" {
355 - rr.Rmail = o
356 - } else {
357 - _, ok := IsDomainName(l.token)
358 - if !ok {
359 - return nil, &ParseError{f, "bad MINFO Rmail", l}, ""
360 - }
361 - if rr.Rmail[l.length-1] != '.' {
362 - rr.Rmail = appendOrigin(rr.Rmail, o)
363 - }
364 - }
365 - <-c // zBlank
366 - l = <-c
367 - rr.Email = l.token
368 - if l.token == "@" {
369 - rr.Email = o
370 - return rr, nil, ""
371 - }
372 - _, ok := IsDomainName(l.token)
373 - if !ok {
374 - return nil, &ParseError{f, "bad MINFO Email", l}, ""
375 - }
376 - if rr.Email[l.length-1] != '.' {
377 - rr.Email = appendOrigin(rr.Email, o)
378 - }
379 - return rr, nil, ""
380 -}
381 -
382 -func setMF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
383 - rr := new(MF)
384 - rr.Hdr = h
385 -
386 - l := <-c
387 - rr.Mf = l.token
388 - if l.length == 0 {
389 - return rr, nil, ""
390 - }
391 - if l.token == "@" {
392 - rr.Mf = o
393 - return rr, nil, ""
394 - }
395 - _, ok := IsDomainName(l.token)
396 - if !ok {
397 - return nil, &ParseError{f, "bad MF Mf", l}, ""
398 - }
399 - if rr.Mf[l.length-1] != '.' {
400 - rr.Mf = appendOrigin(rr.Mf, o)
401 - }
402 - return rr, nil, ""
403 -}
404 -
405 -func setMD(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
406 - rr := new(MD)
407 - rr.Hdr = h
408 -
409 - l := <-c
410 - rr.Md = l.token
411 - if l.length == 0 {
412 - return rr, nil, ""
413 - }
414 - if l.token == "@" {
415 - rr.Md = o
416 - return rr, nil, ""
417 - }
418 - _, ok := IsDomainName(l.token)
419 - if !ok {
420 - return nil, &ParseError{f, "bad MD Md", l}, ""
421 - }
422 - if rr.Md[l.length-1] != '.' {
423 - rr.Md = appendOrigin(rr.Md, o)
424 - }
425 - return rr, nil, ""
426 -}
427 -
428 -func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
429 - rr := new(MX)
430 - rr.Hdr = h
431 -
432 - l := <-c
433 - if l.length == 0 {
434 - return rr, nil, ""
435 - }
436 - i, e := strconv.Atoi(l.token)
437 - if e != nil {
438 - return nil, &ParseError{f, "bad MX Pref", l}, ""
439 - }
440 - rr.Preference = uint16(i)
441 - <-c // zBlank
442 - l = <-c // zString
443 - rr.Mx = l.token
444 - if l.token == "@" {
445 - rr.Mx = o
446 - return rr, nil, ""
447 - }
448 - _, ok := IsDomainName(l.token)
449 - if !ok || l.length == 0 {
450 - return nil, &ParseError{f, "bad MX Mx", l}, ""
451 - }
452 - if rr.Mx[l.length-1] != '.' {
453 - rr.Mx = appendOrigin(rr.Mx, o)
454 - }
455 - return rr, nil, ""
456 -}
457 -
458 -func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
459 - rr := new(RT)
460 - rr.Hdr = h
461 - l := <-c
462 - if l.length == 0 {
463 - return rr, nil, ""
464 - }
465 - i, e := strconv.Atoi(l.token)
466 - if e != nil {
467 - return nil, &ParseError{f, "bad RT Preference", l}, ""
468 - }
469 - rr.Preference = uint16(i)
470 - <-c // zBlank
471 - l = <-c // zString
472 - rr.Host = l.token
473 - if l.token == "@" {
474 - rr.Host = o
475 - return rr, nil, ""
476 - }
477 - _, ok := IsDomainName(l.token)
478 - if !ok || l.length == 0 {
479 - return nil, &ParseError{f, "bad RT Host", l}, ""
480 - }
481 - if rr.Host[l.length-1] != '.' {
482 - rr.Host = appendOrigin(rr.Host, o)
483 - }
484 - return rr, nil, ""
485 -}
486 -
487 -func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
488 - rr := new(AFSDB)
489 - rr.Hdr = h
490 -
491 - l := <-c
492 - if l.length == 0 {
493 - return rr, nil, ""
494 - }
495 - i, e := strconv.Atoi(l.token)
496 - if e != nil {
497 - return nil, &ParseError{f, "bad AFSDB Subtype", l}, ""
498 - }
499 - rr.Subtype = uint16(i)
500 - <-c // zBlank
501 - l = <-c // zString
502 - rr.Hostname = l.token
503 - if l.token == "@" {
504 - rr.Hostname = o
505 - return rr, nil, ""
506 - }
507 - _, ok := IsDomainName(l.token)
508 - if !ok || l.length == 0 {
509 - return nil, &ParseError{f, "bad AFSDB Hostname", l}, ""
510 - }
511 - if rr.Hostname[l.length-1] != '.' {
512 - rr.Hostname = appendOrigin(rr.Hostname, o)
513 - }
514 - return rr, nil, ""
515 -}
516 -
517 -func setX25(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
518 - rr := new(X25)
519 - rr.Hdr = h
520 -
521 - l := <-c
522 - rr.PSDNAddress = l.token
523 - return rr, nil, ""
524 -}
525 -
526 -func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
527 - rr := new(KX)
528 - rr.Hdr = h
529 -
530 - l := <-c
531 - if l.length == 0 {
532 - return rr, nil, ""
533 - }
534 - i, e := strconv.Atoi(l.token)
535 - if e != nil {
536 - return nil, &ParseError{f, "bad KX Pref", l}, ""
537 - }
538 - rr.Preference = uint16(i)
539 - <-c // zBlank
540 - l = <-c // zString
541 - rr.Exchanger = l.token
542 - if l.token == "@" {
543 - rr.Exchanger = o
544 - return rr, nil, ""
545 - }
546 - _, ok := IsDomainName(l.token)
547 - if !ok || l.length == 0 {
548 - return nil, &ParseError{f, "bad KX Exchanger", l}, ""
549 - }
550 - if rr.Exchanger[l.length-1] != '.' {
551 - rr.Exchanger = appendOrigin(rr.Exchanger, o)
552 - }
553 - return rr, nil, ""
554 -}
555 -
556 -func setCNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
557 - rr := new(CNAME)
558 - rr.Hdr = h
559 -
560 - l := <-c
561 - rr.Target = l.token
562 - if l.length == 0 {
563 - return rr, nil, ""
564 - }
565 - if l.token == "@" {
566 - rr.Target = o
567 - return rr, nil, ""
568 - }
569 - _, ok := IsDomainName(l.token)
570 - if !ok || l.length == 0 {
571 - return nil, &ParseError{f, "bad CNAME Target", l}, ""
572 - }
573 - if rr.Target[l.length-1] != '.' {
574 - rr.Target = appendOrigin(rr.Target, o)
575 - }
576 - return rr, nil, ""
577 -}
578 -
579 -func setDNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
580 - rr := new(DNAME)
581 - rr.Hdr = h
582 -
583 - l := <-c
584 - rr.Target = l.token
585 - if l.length == 0 {
586 - return rr, nil, ""
587 - }
588 - if l.token == "@" {
589 - rr.Target = o
590 - return rr, nil, ""
591 - }
592 - _, ok := IsDomainName(l.token)
593 - if !ok {
594 - return nil, &ParseError{f, "bad CNAME Target", l}, ""
595 - }
596 - if rr.Target[l.length-1] != '.' {
597 - rr.Target = appendOrigin(rr.Target, o)
598 - }
599 - return rr, nil, ""
600 -}
601 -
602 -func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
603 - rr := new(SOA)
604 - rr.Hdr = h
605 -
606 - l := <-c
607 - rr.Ns = l.token
608 - if l.length == 0 {
609 - return rr, nil, ""
610 - }
611 - <-c // zBlank
612 - if l.token == "@" {
613 - rr.Ns = o
614 - } else {
615 - _, ok := IsDomainName(l.token)
616 - if !ok {
617 - return nil, &ParseError{f, "bad SOA Ns", l}, ""
618 - }
619 - if rr.Ns[l.length-1] != '.' {
620 - rr.Ns = appendOrigin(rr.Ns, o)
621 - }
622 - }
623 -
624 - l = <-c
625 - rr.Mbox = l.token
626 - if l.token == "@" {
627 - rr.Mbox = o
628 - } else {
629 - _, ok := IsDomainName(l.token)
630 - if !ok || l.length == 0 {
631 - return nil, &ParseError{f, "bad SOA Mbox", l}, ""
632 - }
633 - if rr.Mbox[l.length-1] != '.' {
634 - rr.Mbox = appendOrigin(rr.Mbox, o)
635 - }
636 - }
637 - <-c // zBlank
638 -
639 - var (
640 - v uint32
641 - ok bool
642 - )
643 - for i := 0; i < 5; i++ {
644 - l = <-c
645 - if j, e := strconv.Atoi(l.token); e != nil {
646 - if i == 0 {
647 - // Serial should be a number
648 - return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
649 - }
650 - if v, ok = stringToTtl(l.token); !ok {
651 - return nil, &ParseError{f, "bad SOA zone parameter", l}, ""
652 -
653 - }
654 - } else {
655 - v = uint32(j)
656 - }
657 - switch i {
658 - case 0:
659 - rr.Serial = v
660 - <-c // zBlank
661 - case 1:
662 - rr.Refresh = v
663 - <-c // zBlank
664 - case 2:
665 - rr.Retry = v
666 - <-c // zBlank
667 - case 3:
668 - rr.Expire = v
669 - <-c // zBlank
670 - case 4:
671 - rr.Minttl = v
672 - }
673 - }
674 - return rr, nil, ""
675 -}
676 -
677 -func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
678 - rr := new(SRV)
679 - rr.Hdr = h
680 -
681 - l := <-c
682 - if l.length == 0 {
683 - return rr, nil, ""
684 - }
685 - i, e := strconv.Atoi(l.token)
686 - if e != nil {
687 - return nil, &ParseError{f, "bad SRV Priority", l}, ""
688 - }
689 - rr.Priority = uint16(i)
690 - <-c // zBlank
691 - l = <-c // zString
692 - i, e = strconv.Atoi(l.token)
693 - if e != nil {
694 - return nil, &ParseError{f, "bad SRV Weight", l}, ""
695 - }
696 - rr.Weight = uint16(i)
697 - <-c // zBlank
698 - l = <-c // zString
699 - i, e = strconv.Atoi(l.token)
700 - if e != nil {
701 - return nil, &ParseError{f, "bad SRV Port", l}, ""
702 - }
703 - rr.Port = uint16(i)
704 - <-c // zBlank
705 - l = <-c // zString
706 - rr.Target = l.token
707 - if l.token == "@" {
708 - rr.Target = o
709 - return rr, nil, ""
710 - }
711 - _, ok := IsDomainName(l.token)
712 - if !ok || l.length == 0 {
713 - return nil, &ParseError{f, "bad SRV Target", l}, ""
714 - }
715 - if rr.Target[l.length-1] != '.' {
716 - rr.Target = appendOrigin(rr.Target, o)
717 - }
718 - return rr, nil, ""
719 -}
720 -
721 -func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
722 - rr := new(NAPTR)
723 - rr.Hdr = h
724 -
725 - l := <-c
726 - if l.length == 0 {
727 - return rr, nil, ""
728 - }
729 - i, e := strconv.Atoi(l.token)
730 - if e != nil {
731 - return nil, &ParseError{f, "bad NAPTR Order", l}, ""
732 - }
733 - rr.Order = uint16(i)
734 - <-c // zBlank
735 - l = <-c // zString
736 - i, e = strconv.Atoi(l.token)
737 - if e != nil {
738 - return nil, &ParseError{f, "bad NAPTR Preference", l}, ""
739 - }
740 - rr.Preference = uint16(i)
741 - // Flags
742 - <-c // zBlank
743 - l = <-c // _QUOTE
744 - if l.value != zQuote {
745 - return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
746 - }
747 - l = <-c // Either String or Quote
748 - if l.value == zString {
749 - rr.Flags = l.token
750 - l = <-c // _QUOTE
751 - if l.value != zQuote {
752 - return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
753 - }
754 - } else if l.value == zQuote {
755 - rr.Flags = ""
756 - } else {
757 - return nil, &ParseError{f, "bad NAPTR Flags", l}, ""
758 - }
759 -
760 - // Service
761 - <-c // zBlank
762 - l = <-c // _QUOTE
763 - if l.value != zQuote {
764 - return nil, &ParseError{f, "bad NAPTR Service", l}, ""
765 - }
766 - l = <-c // Either String or Quote
767 - if l.value == zString {
768 - rr.Service = l.token
769 - l = <-c // _QUOTE
770 - if l.value != zQuote {
771 - return nil, &ParseError{f, "bad NAPTR Service", l}, ""
772 - }
773 - } else if l.value == zQuote {
774 - rr.Service = ""
775 - } else {
776 - return nil, &ParseError{f, "bad NAPTR Service", l}, ""
777 - }
778 -
779 - // Regexp
780 - <-c // zBlank
781 - l = <-c // _QUOTE
782 - if l.value != zQuote {
783 - return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
784 - }
785 - l = <-c // Either String or Quote
786 - if l.value == zString {
787 - rr.Regexp = l.token
788 - l = <-c // _QUOTE
789 - if l.value != zQuote {
790 - return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
791 - }
792 - } else if l.value == zQuote {
793 - rr.Regexp = ""
794 - } else {
795 - return nil, &ParseError{f, "bad NAPTR Regexp", l}, ""
796 - }
797 - // After quote no space??
798 - <-c // zBlank
799 - l = <-c // zString
800 - rr.Replacement = l.token
801 - if l.token == "@" {
802 - rr.Replacement = o
803 - return rr, nil, ""
804 - }
805 - _, ok := IsDomainName(l.token)
806 - if !ok || l.length == 0 {
807 - return nil, &ParseError{f, "bad NAPTR Replacement", l}, ""
808 - }
809 - if rr.Replacement[l.length-1] != '.' {
810 - rr.Replacement = appendOrigin(rr.Replacement, o)
811 - }
812 - return rr, nil, ""
813 -}
814 -
815 -func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
816 - rr := new(TALINK)
817 - rr.Hdr = h
818 -
819 - l := <-c
820 - rr.PreviousName = l.token
821 - if l.length == 0 {
822 - return rr, nil, ""
823 - }
824 - if l.token == "@" {
825 - rr.PreviousName = o
826 - } else {
827 - _, ok := IsDomainName(l.token)
828 - if !ok {
829 - return nil, &ParseError{f, "bad TALINK PreviousName", l}, ""
830 - }
831 - if rr.PreviousName[l.length-1] != '.' {
832 - rr.PreviousName = appendOrigin(rr.PreviousName, o)
833 - }
834 - }
835 - <-c // zBlank
836 - l = <-c
837 - rr.NextName = l.token
838 - if l.token == "@" {
839 - rr.NextName = o
840 - return rr, nil, ""
841 - }
842 - _, ok := IsDomainName(l.token)
843 - if !ok || l.length == 0 {
844 - return nil, &ParseError{f, "bad TALINK NextName", l}, ""
845 - }
846 - if rr.NextName[l.length-1] != '.' {
847 - rr.NextName = appendOrigin(rr.NextName, o)
848 - }
849 - return rr, nil, ""
850 -}
851 -
852 -func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
853 - rr := new(LOC)
854 - rr.Hdr = h
855 - // Non zero defaults for LOC record, see RFC 1876, Section 3.
856 - rr.HorizPre = 165 // 10000
857 - rr.VertPre = 162 // 10
858 - rr.Size = 18 // 1
859 - ok := false
860 - // North
861 - l := <-c
862 - if l.length == 0 {
863 - return rr, nil, ""
864 - }
865 - if i, e := strconv.Atoi(l.token); e != nil {
866 - return nil, &ParseError{f, "bad LOC Latitude", l}, ""
867 - } else {
868 - rr.Latitude = 1000 * 60 * 60 * uint32(i)
869 - }
870 - <-c // zBlank
871 - // Either number, 'N' or 'S'
872 - l = <-c
873 - if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
874 - goto East
875 - }
876 - if i, e := strconv.Atoi(l.token); e != nil {
877 - return nil, &ParseError{f, "bad LOC Latitude minutes", l}, ""
878 - } else {
879 - rr.Latitude += 1000 * 60 * uint32(i)
880 - }
881 - <-c // zBlank
882 - l = <-c
883 - if i, e := strconv.ParseFloat(l.token, 32); e != nil {
884 - return nil, &ParseError{f, "bad LOC Latitude seconds", l}, ""
885 - } else {
886 - rr.Latitude += uint32(1000 * i)
887 - }
888 - <-c // zBlank
889 - // Either number, 'N' or 'S'
890 - l = <-c
891 - if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
892 - goto East
893 - }
894 - // If still alive, flag an error
895 - return nil, &ParseError{f, "bad LOC Latitude North/South", l}, ""
896 -
897 -East:
898 - // East
899 - <-c // zBlank
900 - l = <-c
901 - if i, e := strconv.Atoi(l.token); e != nil {
902 - return nil, &ParseError{f, "bad LOC Longitude", l}, ""
903 - } else {
904 - rr.Longitude = 1000 * 60 * 60 * uint32(i)
905 - }
906 - <-c // zBlank
907 - // Either number, 'E' or 'W'
908 - l = <-c
909 - if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
910 - goto Altitude
911 - }
912 - if i, e := strconv.Atoi(l.token); e != nil {
913 - return nil, &ParseError{f, "bad LOC Longitude minutes", l}, ""
914 - } else {
915 - rr.Longitude += 1000 * 60 * uint32(i)
916 - }
917 - <-c // zBlank
918 - l = <-c
919 - if i, e := strconv.ParseFloat(l.token, 32); e != nil {
920 - return nil, &ParseError{f, "bad LOC Longitude seconds", l}, ""
921 - } else {
922 - rr.Longitude += uint32(1000 * i)
923 - }
924 - <-c // zBlank
925 - // Either number, 'E' or 'W'
926 - l = <-c
927 - if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
928 - goto Altitude
929 - }
930 - // If still alive, flag an error
931 - return nil, &ParseError{f, "bad LOC Longitude East/West", l}, ""
932 -
933 -Altitude:
934 - <-c // zBlank
935 - l = <-c
936 - if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' {
937 - l.token = l.token[0 : len(l.token)-1]
938 - }
939 - if i, e := strconv.ParseFloat(l.token, 32); e != nil {
940 - return nil, &ParseError{f, "bad LOC Altitude", l}, ""
941 - } else {
942 - rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5)
943 - }
944 -
945 - // And now optionally the other values
946 - l = <-c
947 - count := 0
948 - for l.value != zNewline && l.value != zEOF {
949 - switch l.value {
950 - case zString:
951 - switch count {
952 - case 0: // Size
953 - e, m, ok := stringToCm(l.token)
954 - if !ok {
955 - return nil, &ParseError{f, "bad LOC Size", l}, ""
956 - }
957 - rr.Size = (e & 0x0f) | (m << 4 & 0xf0)
958 - case 1: // HorizPre
959 - e, m, ok := stringToCm(l.token)
960 - if !ok {
961 - return nil, &ParseError{f, "bad LOC HorizPre", l}, ""
962 - }
963 - rr.HorizPre = (e & 0x0f) | (m << 4 & 0xf0)
964 - case 2: // VertPre
965 - e, m, ok := stringToCm(l.token)
966 - if !ok {
967 - return nil, &ParseError{f, "bad LOC VertPre", l}, ""
968 - }
969 - rr.VertPre = (e & 0x0f) | (m << 4 & 0xf0)
970 - }
971 - count++
972 - case zBlank:
973 - // Ok
974 - default:
975 - return nil, &ParseError{f, "bad LOC Size, HorizPre or VertPre", l}, ""
976 - }
977 - l = <-c
978 - }
979 - return rr, nil, ""
980 -}
981 -
982 -func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
983 - rr := new(HIP)
984 - rr.Hdr = h
985 -
986 - // HitLength is not represented
987 - l := <-c
988 - if l.length == 0 {
989 - return rr, nil, l.comment
990 - }
991 - i, e := strconv.Atoi(l.token)
992 - if e != nil {
993 - return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, ""
994 - }
995 - rr.PublicKeyAlgorithm = uint8(i)
996 - <-c // zBlank
997 - l = <-c // zString
998 - rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6.
999 - rr.HitLength = uint8(len(rr.Hit)) / 2
1000 -
1001 - <-c // zBlank
1002 - l = <-c // zString
1003 - rr.PublicKey = l.token // This cannot contain spaces
1004 - rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey)))
1005 -
1006 - // RendezvousServers (if any)
1007 - l = <-c
1008 - var xs []string
1009 - for l.value != zNewline && l.value != zEOF {
1010 - switch l.value {
1011 - case zString:
1012 - if l.token == "@" {
1013 - xs = append(xs, o)
1014 - continue
1015 - }
1016 - _, ok := IsDomainName(l.token)
1017 - if !ok || l.length == 0 {
1018 - return nil, &ParseError{f, "bad HIP RendezvousServers", l}, ""
1019 - }
1020 - if l.token[l.length-1] != '.' {
1021 - l.token = appendOrigin(l.token, o)
1022 - }
1023 - xs = append(xs, l.token)
1024 - case zBlank:
1025 - // Ok
1026 - default:
1027 - return nil, &ParseError{f, "bad HIP RendezvousServers", l}, ""
1028 - }
1029 - l = <-c
1030 - }
1031 - rr.RendezvousServers = xs
1032 - return rr, nil, l.comment
1033 -}
1034 -
1035 -func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1036 - rr := new(CERT)
1037 - rr.Hdr = h
1038 -
1039 - l := <-c
1040 - if l.length == 0 {
1041 - return rr, nil, l.comment
1042 - }
1043 - if v, ok := StringToCertType[l.token]; ok {
1044 - rr.Type = v
1045 - } else if i, e := strconv.Atoi(l.token); e != nil {
1046 - return nil, &ParseError{f, "bad CERT Type", l}, ""
1047 - } else {
1048 - rr.Type = uint16(i)
1049 - }
1050 - <-c // zBlank
1051 - l = <-c // zString
1052 - i, e := strconv.Atoi(l.token)
1053 - if e != nil {
1054 - return nil, &ParseError{f, "bad CERT KeyTag", l}, ""
1055 - }
1056 - rr.KeyTag = uint16(i)
1057 - <-c // zBlank
1058 - l = <-c // zString
1059 - if v, ok := StringToAlgorithm[l.token]; ok {
1060 - rr.Algorithm = v
1061 - } else if i, e := strconv.Atoi(l.token); e != nil {
1062 - return nil, &ParseError{f, "bad CERT Algorithm", l}, ""
1063 - } else {
1064 - rr.Algorithm = uint8(i)
1065 - }
1066 - s, e1, c1 := endingToString(c, "bad CERT Certificate", f)
1067 - if e1 != nil {
1068 - return nil, e1, c1
1069 - }
1070 - rr.Certificate = s
1071 - return rr, nil, c1
1072 -}
1073 -
1074 -func setOPENPGPKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1075 - rr := new(OPENPGPKEY)
1076 - rr.Hdr = h
1077 -
1078 - s, e, c1 := endingToString(c, "bad OPENPGPKEY PublicKey", f)
1079 - if e != nil {
1080 - return nil, e, c1
1081 - }
1082 - rr.PublicKey = s
1083 - return rr, nil, c1
1084 -}
1085 -
1086 -func setSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1087 - r, e, s := setRRSIG(h, c, o, f)
1088 - if r != nil {
1089 - return &SIG{*r.(*RRSIG)}, e, s
1090 - }
1091 - return nil, e, s
1092 -}
1093 -
1094 -func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1095 - rr := new(RRSIG)
1096 - rr.Hdr = h
1097 - l := <-c
1098 - if l.length == 0 {
1099 - return rr, nil, l.comment
1100 - }
1101 - if t, ok := StringToType[l.tokenUpper]; !ok {
1102 - if strings.HasPrefix(l.tokenUpper, "TYPE") {
1103 - t, ok = typeToInt(l.tokenUpper)
1104 - if !ok {
1105 - return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
1106 - }
1107 - rr.TypeCovered = t
1108 - } else {
1109 - return nil, &ParseError{f, "bad RRSIG Typecovered", l}, ""
1110 - }
1111 - } else {
1112 - rr.TypeCovered = t
1113 - }
1114 - <-c // zBlank
1115 - l = <-c
1116 - i, err := strconv.Atoi(l.token)
1117 - if err != nil {
1118 - return nil, &ParseError{f, "bad RRSIG Algorithm", l}, ""
1119 - }
1120 - rr.Algorithm = uint8(i)
1121 - <-c // zBlank
1122 - l = <-c
1123 - i, err = strconv.Atoi(l.token)
1124 - if err != nil {
1125 - return nil, &ParseError{f, "bad RRSIG Labels", l}, ""
1126 - }
1127 - rr.Labels = uint8(i)
1128 - <-c // zBlank
1129 - l = <-c
1130 - i, err = strconv.Atoi(l.token)
1131 - if err != nil {
1132 - return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, ""
1133 - }
1134 - rr.OrigTtl = uint32(i)
1135 - <-c // zBlank
1136 - l = <-c
1137 - if i, err := StringToTime(l.token); err != nil {
1138 - // Try to see if all numeric and use it as epoch
1139 - if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
1140 - // TODO(miek): error out on > MAX_UINT32, same below
1141 - rr.Expiration = uint32(i)
1142 - } else {
1143 - return nil, &ParseError{f, "bad RRSIG Expiration", l}, ""
1144 - }
1145 - } else {
1146 - rr.Expiration = i
1147 - }
1148 - <-c // zBlank
1149 - l = <-c
1150 - if i, err := StringToTime(l.token); err != nil {
1151 - if i, err := strconv.ParseInt(l.token, 10, 64); err == nil {
1152 - rr.Inception = uint32(i)
1153 - } else {
1154 - return nil, &ParseError{f, "bad RRSIG Inception", l}, ""
1155 - }
1156 - } else {
1157 - rr.Inception = i
1158 - }
1159 - <-c // zBlank
1160 - l = <-c
1161 - i, err = strconv.Atoi(l.token)
1162 - if err != nil {
1163 - return nil, &ParseError{f, "bad RRSIG KeyTag", l}, ""
1164 - }
1165 - rr.KeyTag = uint16(i)
1166 - <-c // zBlank
1167 - l = <-c
1168 - rr.SignerName = l.token
1169 - if l.token == "@" {
1170 - rr.SignerName = o
1171 - } else {
1172 - _, ok := IsDomainName(l.token)
1173 - if !ok || l.length == 0 {
1174 - return nil, &ParseError{f, "bad RRSIG SignerName", l}, ""
1175 - }
1176 - if rr.SignerName[l.length-1] != '.' {
1177 - rr.SignerName = appendOrigin(rr.SignerName, o)
1178 - }
1179 - }
1180 - s, e, c1 := endingToString(c, "bad RRSIG Signature", f)
1181 - if e != nil {
1182 - return nil, e, c1
1183 - }
1184 - rr.Signature = s
1185 - return rr, nil, c1
1186 -}
1187 -
1188 -func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1189 - rr := new(NSEC)
1190 - rr.Hdr = h
1191 -
1192 - l := <-c
1193 - rr.NextDomain = l.token
1194 - if l.length == 0 {
1195 - return rr, nil, l.comment
1196 - }
1197 - if l.token == "@" {
1198 - rr.NextDomain = o
1199 - } else {
1200 - _, ok := IsDomainName(l.token)
1201 - if !ok {
1202 - return nil, &ParseError{f, "bad NSEC NextDomain", l}, ""
1203 - }
1204 - if rr.NextDomain[l.length-1] != '.' {
1205 - rr.NextDomain = appendOrigin(rr.NextDomain, o)
1206 - }
1207 - }
1208 -
1209 - rr.TypeBitMap = make([]uint16, 0)
1210 - var (
1211 - k uint16
1212 - ok bool
1213 - )
1214 - l = <-c
1215 - for l.value != zNewline && l.value != zEOF {
1216 - switch l.value {
1217 - case zBlank:
1218 - // Ok
1219 - case zString:
1220 - if k, ok = StringToType[l.tokenUpper]; !ok {
1221 - if k, ok = typeToInt(l.tokenUpper); !ok {
1222 - return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
1223 - }
1224 - }
1225 - rr.TypeBitMap = append(rr.TypeBitMap, k)
1226 - default:
1227 - return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, ""
1228 - }
1229 - l = <-c
1230 - }
1231 - return rr, nil, l.comment
1232 -}
1233 -
1234 -func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1235 - rr := new(NSEC3)
1236 - rr.Hdr = h
1237 -
1238 - l := <-c
1239 - if l.length == 0 {
1240 - return rr, nil, l.comment
1241 - }
1242 - i, e := strconv.Atoi(l.token)
1243 - if e != nil {
1244 - return nil, &ParseError{f, "bad NSEC3 Hash", l}, ""
1245 - }
1246 - rr.Hash = uint8(i)
1247 - <-c // zBlank
1248 - l = <-c
1249 - i, e = strconv.Atoi(l.token)
1250 - if e != nil {
1251 - return nil, &ParseError{f, "bad NSEC3 Flags", l}, ""
1252 - }
1253 - rr.Flags = uint8(i)
1254 - <-c // zBlank
1255 - l = <-c
1256 - i, e = strconv.Atoi(l.token)
1257 - if e != nil {
1258 - return nil, &ParseError{f, "bad NSEC3 Iterations", l}, ""
1259 - }
1260 - rr.Iterations = uint16(i)
1261 - <-c
1262 - l = <-c
1263 - if len(l.token) == 0 {
1264 - return nil, &ParseError{f, "bad NSEC3 Salt", l}, ""
1265 - }
1266 - rr.SaltLength = uint8(len(l.token)) / 2
1267 - rr.Salt = l.token
1268 -
1269 - <-c
1270 - l = <-c
1271 - rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits)
1272 - rr.NextDomain = l.token
1273 -
1274 - rr.TypeBitMap = make([]uint16, 0)
1275 - var (
1276 - k uint16
1277 - ok bool
1278 - )
1279 - l = <-c
1280 - for l.value != zNewline && l.value != zEOF {
1281 - switch l.value {
1282 - case zBlank:
1283 - // Ok
1284 - case zString:
1285 - if k, ok = StringToType[l.tokenUpper]; !ok {
1286 - if k, ok = typeToInt(l.tokenUpper); !ok {
1287 - return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
1288 - }
1289 - }
1290 - rr.TypeBitMap = append(rr.TypeBitMap, k)
1291 - default:
1292 - return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, ""
1293 - }
1294 - l = <-c
1295 - }
1296 - return rr, nil, l.comment
1297 -}
1298 -
1299 -func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1300 - rr := new(NSEC3PARAM)
1301 - rr.Hdr = h
1302 -
1303 - l := <-c
1304 - if l.length == 0 {
1305 - return rr, nil, ""
1306 - }
1307 - i, e := strconv.Atoi(l.token)
1308 - if e != nil {
1309 - return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, ""
1310 - }
1311 - rr.Hash = uint8(i)
1312 - <-c // zBlank
1313 - l = <-c
1314 - i, e = strconv.Atoi(l.token)
1315 - if e != nil {
1316 - return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, ""
1317 - }
1318 - rr.Flags = uint8(i)
1319 - <-c // zBlank
1320 - l = <-c
1321 - i, e = strconv.Atoi(l.token)
1322 - if e != nil {
1323 - return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, ""
1324 - }
1325 - rr.Iterations = uint16(i)
1326 - <-c
1327 - l = <-c
1328 - rr.SaltLength = uint8(len(l.token))
1329 - rr.Salt = l.token
1330 - return rr, nil, ""
1331 -}
1332 -
1333 -func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1334 - rr := new(EUI48)
1335 - rr.Hdr = h
1336 -
1337 - l := <-c
1338 - if l.length == 0 {
1339 - return rr, nil, ""
1340 - }
1341 - if l.length != 17 {
1342 - return nil, &ParseError{f, "bad EUI48 Address", l}, ""
1343 - }
1344 - addr := make([]byte, 12)
1345 - dash := 0
1346 - for i := 0; i < 10; i += 2 {
1347 - addr[i] = l.token[i+dash]
1348 - addr[i+1] = l.token[i+1+dash]
1349 - dash++
1350 - if l.token[i+1+dash] != '-' {
1351 - return nil, &ParseError{f, "bad EUI48 Address", l}, ""
1352 - }
1353 - }
1354 - addr[10] = l.token[15]
1355 - addr[11] = l.token[16]
1356 -
1357 - i, e := strconv.ParseUint(string(addr), 16, 48)
1358 - if e != nil {
1359 - return nil, &ParseError{f, "bad EUI48 Address", l}, ""
1360 - }
1361 - rr.Address = i
1362 - return rr, nil, ""
1363 -}
1364 -
1365 -func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1366 - rr := new(EUI64)
1367 - rr.Hdr = h
1368 -
1369 - l := <-c
1370 - if l.length == 0 {
1371 - return rr, nil, ""
1372 - }
1373 - if l.length != 23 {
1374 - return nil, &ParseError{f, "bad EUI64 Address", l}, ""
1375 - }
1376 - addr := make([]byte, 16)
1377 - dash := 0
1378 - for i := 0; i < 14; i += 2 {
1379 - addr[i] = l.token[i+dash]
1380 - addr[i+1] = l.token[i+1+dash]
1381 - dash++
1382 - if l.token[i+1+dash] != '-' {
1383 - return nil, &ParseError{f, "bad EUI64 Address", l}, ""
1384 - }
1385 - }
1386 - addr[14] = l.token[21]
1387 - addr[15] = l.token[22]
1388 -
1389 - i, e := strconv.ParseUint(string(addr), 16, 64)
1390 - if e != nil {
1391 - return nil, &ParseError{f, "bad EUI68 Address", l}, ""
1392 - }
1393 - rr.Address = uint64(i)
1394 - return rr, nil, ""
1395 -}
1396 -
1397 -func setWKS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1398 - rr := new(WKS)
1399 - rr.Hdr = h
1400 -
1401 - l := <-c
1402 - if l.length == 0 {
1403 - return rr, nil, l.comment
1404 - }
1405 - rr.Address = net.ParseIP(l.token)
1406 - if rr.Address == nil {
1407 - return nil, &ParseError{f, "bad WKS Address", l}, ""
1408 - }
1409 -
1410 - <-c // zBlank
1411 - l = <-c
1412 - proto := "tcp"
1413 - i, e := strconv.Atoi(l.token)
1414 - if e != nil {
1415 - return nil, &ParseError{f, "bad WKS Protocol", l}, ""
1416 - }
1417 - rr.Protocol = uint8(i)
1418 - switch rr.Protocol {
1419 - case 17:
1420 - proto = "udp"
1421 - case 6:
1422 - proto = "tcp"
1423 - default:
1424 - return nil, &ParseError{f, "bad WKS Protocol", l}, ""
1425 - }
1426 -
1427 - <-c
1428 - l = <-c
1429 - rr.BitMap = make([]uint16, 0)
1430 - var (
1431 - k int
1432 - err error
1433 - )
1434 - for l.value != zNewline && l.value != zEOF {
1435 - switch l.value {
1436 - case zBlank:
1437 - // Ok
1438 - case zString:
1439 - if k, err = net.LookupPort(proto, l.token); err != nil {
1440 - if i, e := strconv.Atoi(l.token); e != nil { // If a number use that
1441 - rr.BitMap = append(rr.BitMap, uint16(i))
1442 - } else {
1443 - return nil, &ParseError{f, "bad WKS BitMap", l}, ""
1444 - }
1445 - }
1446 - rr.BitMap = append(rr.BitMap, uint16(k))
1447 - default:
1448 - return nil, &ParseError{f, "bad WKS BitMap", l}, ""
1449 - }
1450 - l = <-c
1451 - }
1452 - return rr, nil, l.comment
1453 -}
1454 -
1455 -func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1456 - rr := new(SSHFP)
1457 - rr.Hdr = h
1458 -
1459 - l := <-c
1460 - if l.length == 0 {
1461 - return rr, nil, ""
1462 - }
1463 - i, e := strconv.Atoi(l.token)
1464 - if e != nil {
1465 - return nil, &ParseError{f, "bad SSHFP Algorithm", l}, ""
1466 - }
1467 - rr.Algorithm = uint8(i)
1468 - <-c // zBlank
1469 - l = <-c
1470 - i, e = strconv.Atoi(l.token)
1471 - if e != nil {
1472 - return nil, &ParseError{f, "bad SSHFP Type", l}, ""
1473 - }
1474 - rr.Type = uint8(i)
1475 - <-c // zBlank
1476 - l = <-c
1477 - rr.FingerPrint = l.token
1478 - return rr, nil, ""
1479 -}
1480 -
1481 -func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
1482 - rr := new(DNSKEY)
1483 - rr.Hdr = h
1484 -
1485 - l := <-c
1486 - if l.length == 0 {
1487 - return rr, nil, l.comment
1488 - }
1489 - i, e := strconv.Atoi(l.token)
1490 - if e != nil {
1491 - return nil, &ParseError{f, "bad " + typ + " Flags", l}, ""
1492 - }
1493 - rr.Flags = uint16(i)
1494 - <-c // zBlank
1495 - l = <-c // zString
1496 - i, e = strconv.Atoi(l.token)
1497 - if e != nil {
1498 - return nil, &ParseError{f, "bad " + typ + " Protocol", l}, ""
1499 - }
1500 - rr.Protocol = uint8(i)
1501 - <-c // zBlank
1502 - l = <-c // zString
1503 - i, e = strconv.Atoi(l.token)
1504 - if e != nil {
1505 - return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
1506 - }
1507 - rr.Algorithm = uint8(i)
1508 - s, e1, c1 := endingToString(c, "bad "+typ+" PublicKey", f)
1509 - if e1 != nil {
1510 - return nil, e1, c1
1511 - }
1512 - rr.PublicKey = s
1513 - return rr, nil, c1
1514 -}
1515 -
1516 -func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1517 - r, e, s := setDNSKEYs(h, c, o, f, "KEY")
1518 - if r != nil {
1519 - return &KEY{*r.(*DNSKEY)}, e, s
1520 - }
1521 - return nil, e, s
1522 -}
1523 -
1524 -func setDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1525 - r, e, s := setDNSKEYs(h, c, o, f, "DNSKEY")
1526 - return r, e, s
1527 -}
1528 -
1529 -func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1530 - r, e, s := setDNSKEYs(h, c, o, f, "CDNSKEY")
1531 - if r != nil {
1532 - return &CDNSKEY{*r.(*DNSKEY)}, e, s
1533 - }
1534 - return nil, e, s
1535 -}
1536 -
1537 -func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1538 - rr := new(RKEY)
1539 - rr.Hdr = h
1540 -
1541 - l := <-c
1542 - if l.length == 0 {
1543 - return rr, nil, l.comment
1544 - }
1545 - i, e := strconv.Atoi(l.token)
1546 - if e != nil {
1547 - return nil, &ParseError{f, "bad RKEY Flags", l}, ""
1548 - }
1549 - rr.Flags = uint16(i)
1550 - <-c // zBlank
1551 - l = <-c // zString
1552 - i, e = strconv.Atoi(l.token)
1553 - if e != nil {
1554 - return nil, &ParseError{f, "bad RKEY Protocol", l}, ""
1555 - }
1556 - rr.Protocol = uint8(i)
1557 - <-c // zBlank
1558 - l = <-c // zString
1559 - i, e = strconv.Atoi(l.token)
1560 - if e != nil {
1561 - return nil, &ParseError{f, "bad RKEY Algorithm", l}, ""
1562 - }
1563 - rr.Algorithm = uint8(i)
1564 - s, e1, c1 := endingToString(c, "bad RKEY PublicKey", f)
1565 - if e1 != nil {
1566 - return nil, e1, c1
1567 - }
1568 - rr.PublicKey = s
1569 - return rr, nil, c1
1570 -}
1571 -
1572 -func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1573 - rr := new(EID)
1574 - rr.Hdr = h
1575 - s, e, c1 := endingToString(c, "bad EID Endpoint", f)
1576 - if e != nil {
1577 - return nil, e, c1
1578 - }
1579 - rr.Endpoint = s
1580 - return rr, nil, c1
1581 -}
1582 -
1583 -func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1584 - rr := new(NIMLOC)
1585 - rr.Hdr = h
1586 - s, e, c1 := endingToString(c, "bad NIMLOC Locator", f)
1587 - if e != nil {
1588 - return nil, e, c1
1589 - }
1590 - rr.Locator = s
1591 - return rr, nil, c1
1592 -}
1593 -
1594 -func setNSAP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1595 - rr := new(NSAP)
1596 - rr.Hdr = h
1597 - l := <-c
1598 - if l.length == 0 {
1599 - return rr, nil, l.comment
1600 - }
1601 - i, e := strconv.Atoi(l.token)
1602 - if e != nil {
1603 - return nil, &ParseError{f, "bad NSAP Length", l}, ""
1604 - }
1605 - rr.Length = uint8(i)
1606 - <-c // zBlank
1607 - s, e1, c1 := endingToString(c, "bad NSAP Nsap", f)
1608 - if e != nil {
1609 - return nil, e1, c1
1610 - }
1611 - rr.Nsap = s
1612 - return rr, nil, c1
1613 -}
1614 -
1615 -func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1616 - rr := new(GPOS)
1617 - rr.Hdr = h
1618 - l := <-c
1619 - if l.length == 0 {
1620 - return rr, nil, ""
1621 - }
1622 - _, e := strconv.ParseFloat(l.token, 64)
1623 - if e != nil {
1624 - return nil, &ParseError{f, "bad GPOS Longitude", l}, ""
1625 - }
1626 - rr.Longitude = l.token
1627 - <-c // zBlank
1628 - l = <-c
1629 - _, e = strconv.ParseFloat(l.token, 64)
1630 - if e != nil {
1631 - return nil, &ParseError{f, "bad GPOS Latitude", l}, ""
1632 - }
1633 - rr.Latitude = l.token
1634 - <-c // zBlank
1635 - l = <-c
1636 - _, e = strconv.ParseFloat(l.token, 64)
1637 - if e != nil {
1638 - return nil, &ParseError{f, "bad GPOS Altitude", l}, ""
1639 - }
1640 - rr.Altitude = l.token
1641 - return rr, nil, ""
1642 -}
1643 -
1644 -func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) {
1645 - rr := new(DS)
1646 - rr.Hdr = h
1647 - l := <-c
1648 - if l.length == 0 {
1649 - return rr, nil, l.comment
1650 - }
1651 - i, e := strconv.Atoi(l.token)
1652 - if e != nil {
1653 - return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, ""
1654 - }
1655 - rr.KeyTag = uint16(i)
1656 - <-c // zBlank
1657 - l = <-c
1658 - if i, e := strconv.Atoi(l.token); e != nil {
1659 - i, ok := StringToAlgorithm[l.tokenUpper]
1660 - if !ok {
1661 - return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, ""
1662 - }
1663 - rr.Algorithm = i
1664 - } else {
1665 - rr.Algorithm = uint8(i)
1666 - }
1667 - <-c // zBlank
1668 - l = <-c
1669 - i, e = strconv.Atoi(l.token)
1670 - if e != nil {
1671 - return nil, &ParseError{f, "bad " + typ + " DigestType", l}, ""
1672 - }
1673 - rr.DigestType = uint8(i)
1674 - s, e1, c1 := endingToString(c, "bad "+typ+" Digest", f)
1675 - if e1 != nil {
1676 - return nil, e1, c1
1677 - }
1678 - rr.Digest = s
1679 - return rr, nil, c1
1680 -}
1681 -
1682 -func setDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1683 - r, e, s := setDSs(h, c, o, f, "DS")
1684 - return r, e, s
1685 -}
1686 -
1687 -func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1688 - r, e, s := setDSs(h, c, o, f, "DLV")
1689 - if r != nil {
1690 - return &DLV{*r.(*DS)}, e, s
1691 - }
1692 - return nil, e, s
1693 -}
1694 -
1695 -func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1696 - r, e, s := setDSs(h, c, o, f, "CDS")
1697 - if r != nil {
1698 - return &CDS{*r.(*DS)}, e, s
1699 - }
1700 - return nil, e, s
1701 -}
1702 -
1703 -func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1704 - rr := new(TA)
1705 - rr.Hdr = h
1706 - l := <-c
1707 - if l.length == 0 {
1708 - return rr, nil, l.comment
1709 - }
1710 - i, e := strconv.Atoi(l.token)
1711 - if e != nil {
1712 - return nil, &ParseError{f, "bad TA KeyTag", l}, ""
1713 - }
1714 - rr.KeyTag = uint16(i)
1715 - <-c // zBlank
1716 - l = <-c
1717 - if i, e := strconv.Atoi(l.token); e != nil {
1718 - i, ok := StringToAlgorithm[l.tokenUpper]
1719 - if !ok {
1720 - return nil, &ParseError{f, "bad TA Algorithm", l}, ""
1721 - }
1722 - rr.Algorithm = i
1723 - } else {
1724 - rr.Algorithm = uint8(i)
1725 - }
1726 - <-c // zBlank
1727 - l = <-c
1728 - i, e = strconv.Atoi(l.token)
1729 - if e != nil {
1730 - return nil, &ParseError{f, "bad TA DigestType", l}, ""
1731 - }
1732 - rr.DigestType = uint8(i)
1733 - s, e, c1 := endingToString(c, "bad TA Digest", f)
1734 - if e != nil {
1735 - return nil, e.(*ParseError), c1
1736 - }
1737 - rr.Digest = s
1738 - return rr, nil, c1
1739 -}
1740 -
1741 -func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1742 - rr := new(TLSA)
1743 - rr.Hdr = h
1744 - l := <-c
1745 - if l.length == 0 {
1746 - return rr, nil, l.comment
1747 - }
1748 - i, e := strconv.Atoi(l.token)
1749 - if e != nil {
1750 - return nil, &ParseError{f, "bad TLSA Usage", l}, ""
1751 - }
1752 - rr.Usage = uint8(i)
1753 - <-c // zBlank
1754 - l = <-c
1755 - i, e = strconv.Atoi(l.token)
1756 - if e != nil {
1757 - return nil, &ParseError{f, "bad TLSA Selector", l}, ""
1758 - }
1759 - rr.Selector = uint8(i)
1760 - <-c // zBlank
1761 - l = <-c
1762 - i, e = strconv.Atoi(l.token)
1763 - if e != nil {
1764 - return nil, &ParseError{f, "bad TLSA MatchingType", l}, ""
1765 - }
1766 - rr.MatchingType = uint8(i)
1767 - s, e, c1 := endingToString(c, "bad TLSA Certificate", f)
1768 - if e != nil {
1769 - return nil, e.(*ParseError), c1
1770 - }
1771 - rr.Certificate = s
1772 - return rr, nil, c1
1773 -}
1774 -
1775 -func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1776 - rr := new(RFC3597)
1777 - rr.Hdr = h
1778 - l := <-c
1779 - if l.token != "\\#" {
1780 - return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
1781 - }
1782 - <-c // zBlank
1783 - l = <-c
1784 - rdlength, e := strconv.Atoi(l.token)
1785 - if e != nil {
1786 - return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, ""
1787 - }
1788 -
1789 - s, e1, c1 := endingToString(c, "bad RFC3597 Rdata", f)
1790 - if e1 != nil {
1791 - return nil, e1, c1
1792 - }
1793 - if rdlength*2 != len(s) {
1794 - return nil, &ParseError{f, "bad RFC3597 Rdata", l}, ""
1795 - }
1796 - rr.Rdata = s
1797 - return rr, nil, c1
1798 -}
1799 -
1800 -func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1801 - rr := new(SPF)
1802 - rr.Hdr = h
1803 -
1804 - s, e, c1 := endingToTxtSlice(c, "bad SPF Txt", f)
1805 - if e != nil {
1806 - return nil, e, ""
1807 - }
1808 - rr.Txt = s
1809 - return rr, nil, c1
1810 -}
1811 -
1812 -func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1813 - rr := new(TXT)
1814 - rr.Hdr = h
1815 -
1816 - // no zBlank reading here, because all this rdata is TXT
1817 - s, e, c1 := endingToTxtSlice(c, "bad TXT Txt", f)
1818 - if e != nil {
1819 - return nil, e, ""
1820 - }
1821 - rr.Txt = s
1822 - return rr, nil, c1
1823 -}
1824 -
1825 -// identical to setTXT
1826 -func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1827 - rr := new(NINFO)
1828 - rr.Hdr = h
1829 -
1830 - s, e, c1 := endingToTxtSlice(c, "bad NINFO ZSData", f)
1831 - if e != nil {
1832 - return nil, e, ""
1833 - }
1834 - rr.ZSData = s
1835 - return rr, nil, c1
1836 -}
1837 -
1838 -func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1839 - rr := new(URI)
1840 - rr.Hdr = h
1841 -
1842 - l := <-c
1843 - if l.length == 0 {
1844 - return rr, nil, l.comment
1845 - }
1846 - i, e := strconv.Atoi(l.token)
1847 - if e != nil {
1848 - return nil, &ParseError{f, "bad URI Priority", l}, ""
1849 - }
1850 - rr.Priority = uint16(i)
1851 - <-c // zBlank
1852 - l = <-c
1853 - i, e = strconv.Atoi(l.token)
1854 - if e != nil {
1855 - return nil, &ParseError{f, "bad URI Weight", l}, ""
1856 - }
1857 - rr.Weight = uint16(i)
1858 -
1859 - <-c // zBlank
1860 - s, e, c1 := endingToTxtSlice(c, "bad URI Target", f)
1861 - if e != nil {
1862 - return nil, e.(*ParseError), ""
1863 - }
1864 - rr.Target = s
1865 - return rr, nil, c1
1866 -}
1867 -
1868 -func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1869 - // awesome record to parse!
1870 - rr := new(DHCID)
1871 - rr.Hdr = h
1872 -
1873 - s, e, c1 := endingToString(c, "bad DHCID Digest", f)
1874 - if e != nil {
1875 - return nil, e, c1
1876 - }
1877 - rr.Digest = s
1878 - return rr, nil, c1
1879 -}
1880 -
1881 -func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1882 - rr := new(NID)
1883 - rr.Hdr = h
1884 -
1885 - l := <-c
1886 - if l.length == 0 {
1887 - return rr, nil, ""
1888 - }
1889 - i, e := strconv.Atoi(l.token)
1890 - if e != nil {
1891 - return nil, &ParseError{f, "bad NID Preference", l}, ""
1892 - }
1893 - rr.Preference = uint16(i)
1894 - <-c // zBlank
1895 - l = <-c // zString
1896 - u, err := stringToNodeID(l)
1897 - if err != nil {
1898 - return nil, err, ""
1899 - }
1900 - rr.NodeID = u
1901 - return rr, nil, ""
1902 -}
1903 -
1904 -func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1905 - rr := new(L32)
1906 - rr.Hdr = h
1907 -
1908 - l := <-c
1909 - if l.length == 0 {
1910 - return rr, nil, ""
1911 - }
1912 - i, e := strconv.Atoi(l.token)
1913 - if e != nil {
1914 - return nil, &ParseError{f, "bad L32 Preference", l}, ""
1915 - }
1916 - rr.Preference = uint16(i)
1917 - <-c // zBlank
1918 - l = <-c // zString
1919 - rr.Locator32 = net.ParseIP(l.token)
1920 - if rr.Locator32 == nil {
1921 - return nil, &ParseError{f, "bad L32 Locator", l}, ""
1922 - }
1923 - return rr, nil, ""
1924 -}
1925 -
1926 -func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1927 - rr := new(LP)
1928 - rr.Hdr = h
1929 -
1930 - l := <-c
1931 - if l.length == 0 {
1932 - return rr, nil, ""
1933 - }
1934 - i, e := strconv.Atoi(l.token)
1935 - if e != nil {
1936 - return nil, &ParseError{f, "bad LP Preference", l}, ""
1937 - }
1938 - rr.Preference = uint16(i)
1939 - <-c // zBlank
1940 - l = <-c // zString
1941 - rr.Fqdn = l.token
1942 - if l.length == 0 {
1943 - return rr, nil, ""
1944 - }
1945 - if l.token == "@" {
1946 - rr.Fqdn = o
1947 - return rr, nil, ""
1948 - }
1949 - _, ok := IsDomainName(l.token)
1950 - if !ok || l.length == 0 {
1951 - return nil, &ParseError{f, "bad LP Fqdn", l}, ""
1952 - }
1953 - if rr.Fqdn[l.length-1] != '.' {
1954 - rr.Fqdn = appendOrigin(rr.Fqdn, o)
1955 - }
1956 - return rr, nil, ""
1957 -}
1958 -
1959 -func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1960 - rr := new(L64)
1961 - rr.Hdr = h
1962 -
1963 - l := <-c
1964 - if l.length == 0 {
1965 - return rr, nil, ""
1966 - }
1967 - i, e := strconv.Atoi(l.token)
1968 - if e != nil {
1969 - return nil, &ParseError{f, "bad L64 Preference", l}, ""
1970 - }
1971 - rr.Preference = uint16(i)
1972 - <-c // zBlank
1973 - l = <-c // zString
1974 - u, err := stringToNodeID(l)
1975 - if err != nil {
1976 - return nil, err, ""
1977 - }
1978 - rr.Locator64 = u
1979 - return rr, nil, ""
1980 -}
1981 -
1982 -func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1983 - rr := new(UID)
1984 - rr.Hdr = h
1985 - l := <-c
1986 - if l.length == 0 {
1987 - return rr, nil, ""
1988 - }
1989 - i, e := strconv.Atoi(l.token)
1990 - if e != nil {
1991 - return nil, &ParseError{f, "bad UID Uid", l}, ""
1992 - }
1993 - rr.Uid = uint32(i)
1994 - return rr, nil, ""
1995 -}
1996 -
1997 -func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
1998 - rr := new(GID)
1999 - rr.Hdr = h
2000 - l := <-c
2001 - if l.length == 0 {
2002 - return rr, nil, ""
2003 - }
2004 - i, e := strconv.Atoi(l.token)
2005 - if e != nil {
2006 - return nil, &ParseError{f, "bad GID Gid", l}, ""
2007 - }
2008 - rr.Gid = uint32(i)
2009 - return rr, nil, ""
2010 -}
2011 -
2012 -func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
2013 - rr := new(UINFO)
2014 - rr.Hdr = h
2015 - s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f)
2016 - if e != nil {
2017 - return nil, e, ""
2018 - }
2019 - rr.Uinfo = s[0] // silently discard anything above
2020 - return rr, nil, c1
2021 -}
2022 -
2023 -func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
2024 - rr := new(PX)
2025 - rr.Hdr = h
2026 -
2027 - l := <-c
2028 - if l.length == 0 {
2029 - return rr, nil, ""
2030 - }
2031 - i, e := strconv.Atoi(l.token)
2032 - if e != nil {
2033 - return nil, &ParseError{f, "bad PX Preference", l}, ""
2034 - }
2035 - rr.Preference = uint16(i)
2036 - <-c // zBlank
2037 - l = <-c // zString
2038 - rr.Map822 = l.token
2039 - if l.length == 0 {
2040 - return rr, nil, ""
2041 - }
2042 - if l.token == "@" {
2043 - rr.Map822 = o
2044 - return rr, nil, ""
2045 - }
2046 - _, ok := IsDomainName(l.token)
2047 - if !ok {
2048 - return nil, &ParseError{f, "bad PX Map822", l}, ""
2049 - }
2050 - if rr.Map822[l.length-1] != '.' {
2051 - rr.Map822 = appendOrigin(rr.Map822, o)
2052 - }
2053 - <-c // zBlank
2054 - l = <-c // zString
2055 - rr.Mapx400 = l.token
2056 - if l.token == "@" {
2057 - rr.Mapx400 = o
2058 - return rr, nil, ""
2059 - }
2060 - _, ok = IsDomainName(l.token)
2061 - if !ok || l.length == 0 {
2062 - return nil, &ParseError{f, "bad PX Mapx400", l}, ""
2063 - }
2064 - if rr.Mapx400[l.length-1] != '.' {
2065 - rr.Mapx400 = appendOrigin(rr.Mapx400, o)
2066 - }
2067 - return rr, nil, ""
2068 -}
2069 -
2070 -func setIPSECKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
2071 - rr := new(IPSECKEY)
2072 - rr.Hdr = h
2073 - l := <-c
2074 - if l.length == 0 {
2075 - return rr, nil, l.comment
2076 - }
2077 - i, err := strconv.Atoi(l.token)
2078 - if err != nil {
2079 - return nil, &ParseError{f, "bad IPSECKEY Precedence", l}, ""
2080 - }
2081 - rr.Precedence = uint8(i)
2082 - <-c // zBlank
2083 - l = <-c
2084 - i, err = strconv.Atoi(l.token)
2085 - if err != nil {
2086 - return nil, &ParseError{f, "bad IPSECKEY GatewayType", l}, ""
2087 - }
2088 - rr.GatewayType = uint8(i)
2089 - <-c // zBlank
2090 - l = <-c
2091 - i, err = strconv.Atoi(l.token)
2092 - if err != nil {
2093 - return nil, &ParseError{f, "bad IPSECKEY Algorithm", l}, ""
2094 - }
2095 - rr.Algorithm = uint8(i)
2096 -
2097 - // Now according to GatewayType we can have different elements here
2098 - <-c // zBlank
2099 - l = <-c
2100 - switch rr.GatewayType {
2101 - case 0:
2102 - fallthrough
2103 - case 3:
2104 - rr.GatewayName = l.token
2105 - if l.token == "@" {
2106 - rr.GatewayName = o
2107 - }
2108 - _, ok := IsDomainName(l.token)
2109 - if !ok {
2110 - return nil, &ParseError{f, "bad IPSECKEY GatewayName", l}, ""
2111 - }
2112 - if rr.GatewayName[l.length-1] != '.' {
2113 - rr.GatewayName = appendOrigin(rr.GatewayName, o)
2114 - }
2115 - case 1:
2116 - rr.GatewayA = net.ParseIP(l.token)
2117 - if rr.GatewayA == nil {
2118 - return nil, &ParseError{f, "bad IPSECKEY GatewayA", l}, ""
2119 - }
2120 - case 2:
2121 - rr.GatewayAAAA = net.ParseIP(l.token)
2122 - if rr.GatewayAAAA == nil {
2123 - return nil, &ParseError{f, "bad IPSECKEY GatewayAAAA", l}, ""
2124 - }
2125 - default:
2126 - return nil, &ParseError{f, "bad IPSECKEY GatewayType", l}, ""
2127 - }
2128 -
2129 - s, e, c1 := endingToString(c, "bad IPSECKEY PublicKey", f)
2130 - if e != nil {
2131 - return nil, e, c1
2132 - }
2133 - rr.PublicKey = s
2134 - return rr, nil, c1
2135 -}
2136 -
2137 -var typeToparserFunc = map[uint16]parserFunc{
2138 - TypeAAAA: parserFunc{setAAAA, false},
2139 - TypeAFSDB: parserFunc{setAFSDB, false},
2140 - TypeA: parserFunc{setA, false},
2141 - TypeCDS: parserFunc{setCDS, true},
2142 - TypeCDNSKEY: parserFunc{setCDNSKEY, true},
2143 - TypeCERT: parserFunc{setCERT, true},
2144 - TypeCNAME: parserFunc{setCNAME, false},
2145 - TypeDHCID: parserFunc{setDHCID, true},
2146 - TypeDLV: parserFunc{setDLV, true},
2147 - TypeDNAME: parserFunc{setDNAME, false},
2148 - TypeKEY: parserFunc{setKEY, true},
2149 - TypeDNSKEY: parserFunc{setDNSKEY, true},
2150 - TypeDS: parserFunc{setDS, true},
2151 - TypeEID: parserFunc{setEID, true},
2152 - TypeEUI48: parserFunc{setEUI48, false},
2153 - TypeEUI64: parserFunc{setEUI64, false},
2154 - TypeGID: parserFunc{setGID, false},
2155 - TypeGPOS: parserFunc{setGPOS, false},
2156 - TypeHINFO: parserFunc{setHINFO, false},
2157 - TypeHIP: parserFunc{setHIP, true},
2158 - TypeIPSECKEY: parserFunc{setIPSECKEY, true},
2159 - TypeKX: parserFunc{setKX, false},
2160 - TypeL32: parserFunc{setL32, false},
2161 - TypeL64: parserFunc{setL64, false},
2162 - TypeLOC: parserFunc{setLOC, true},
2163 - TypeLP: parserFunc{setLP, false},
2164 - TypeMB: parserFunc{setMB, false},
2165 - TypeMD: parserFunc{setMD, false},
2166 - TypeMF: parserFunc{setMF, false},
2167 - TypeMG: parserFunc{setMG, false},
2168 - TypeMINFO: parserFunc{setMINFO, false},
2169 - TypeMR: parserFunc{setMR, false},
2170 - TypeMX: parserFunc{setMX, false},
2171 - TypeNAPTR: parserFunc{setNAPTR, false},
2172 - TypeNID: parserFunc{setNID, false},
2173 - TypeNIMLOC: parserFunc{setNIMLOC, true},
2174 - TypeNINFO: parserFunc{setNINFO, true},
2175 - TypeNSAP: parserFunc{setNSAP, true},
2176 - TypeNSAPPTR: parserFunc{setNSAPPTR, false},
2177 - TypeNSEC3PARAM: parserFunc{setNSEC3PARAM, false},
2178 - TypeNSEC3: parserFunc{setNSEC3, true},
2179 - TypeNSEC: parserFunc{setNSEC, true},
2180 - TypeNS: parserFunc{setNS, false},
2181 - TypeOPENPGPKEY: parserFunc{setOPENPGPKEY, true},
2182 - TypePTR: parserFunc{setPTR, false},
2183 - TypePX: parserFunc{setPX, false},
2184 - TypeSIG: parserFunc{setSIG, true},
2185 - TypeRKEY: parserFunc{setRKEY, true},
2186 - TypeRP: parserFunc{setRP, false},
2187 - TypeRRSIG: parserFunc{setRRSIG, true},
2188 - TypeRT: parserFunc{setRT, false},
2189 - TypeSOA: parserFunc{setSOA, false},
2190 - TypeSPF: parserFunc{setSPF, true},
2191 - TypeSRV: parserFunc{setSRV, false},
2192 - TypeSSHFP: parserFunc{setSSHFP, false},
2193 - TypeTALINK: parserFunc{setTALINK, false},
2194 - TypeTA: parserFunc{setTA, true},
2195 - TypeTLSA: parserFunc{setTLSA, true},
2196 - TypeTXT: parserFunc{setTXT, true},
2197 - TypeUID: parserFunc{setUID, false},
2198 - TypeUINFO: parserFunc{setUINFO, true},
2199 - TypeURI: parserFunc{setURI, true},
2200 - TypeWKS: parserFunc{setWKS, true},
2201 - TypeX25: parserFunc{setX25, false},
2202 -}
Godeps/_workspace/src/github.com/whyrusleeping/go-multiplex/.gitignore deleted
-1
@@ -1 +0,0 @@
1 -*.swp
Godeps/_workspace/src/github.com/whyrusleeping/go-multiplex/.gxlastpubver deleted
-1
@@ -1 +0,0 @@
1 -QmYmW76Y7NxvWwW3GPUmpbHd4mm1iW14f5UimeJ9UoofEs
\ No newline at end of file
Godeps/_workspace/src/github.com/whyrusleeping/go-multiplex/README.md deleted
-18
@@ -1,18 +0,0 @@
1 -# go-multiplex
2 -
3 -A super simple stream muxing library compatible with [multiplex](http://github.com/maxogden/multiplex)
4 -
5 -## Usage
6 -
7 -```go
8 -mplex := multiplex.NewMultiplex(mysocket)
9 -
10 -s := mplex.NewStream()
11 -s.Write([]byte("Hello World!")
12 -s.Close()
13 -
14 -mplex.Serve(func(s *multiplex.Stream) {
15 - // echo back everything received
16 - io.Copy(s, s)
17 -})
18 -```
Godeps/_workspace/src/github.com/whyrusleeping/go-multiplex/multiplex.go deleted
-393
@@ -1,393 +0,0 @@
1 -package multiplex
2 -
3 -import (
4 - "bufio"
5 - "encoding/binary"
6 - "errors"
7 - "fmt"
8 - "io"
9 - "io/ioutil"
10 - "sync"
11 -)
12 -
13 -const (
14 - NewStream = iota
15 - Receiver
16 - Initiator
17 - Unknown
18 - Close
19 -)
20 -
21 -var _ = ioutil.ReadAll
22 -var _ = bufio.NewReadWriter
23 -var _ = binary.MaxVarintLen16
24 -
25 -type msg struct {
26 - header uint64
27 - data []byte
28 - err chan<- error
29 -}
30 -
31 -type Stream struct {
32 - id uint64
33 - name string
34 - header uint64
35 - closed chan struct{}
36 - data_in chan []byte
37 - data_out chan<- msg
38 - extra []byte
39 -}
40 -
41 -func newStream(id uint64, name string, initiator bool, send chan<- msg) *Stream {
42 - var hfn uint64
43 - if initiator {
44 - hfn = 2
45 - } else {
46 - hfn = 1
47 - }
48 - return &Stream{
49 - id: id,
50 - name: name,
51 - header: (id << 3) | hfn,
52 - data_in: make(chan []byte, 8),
53 - data_out: send,
54 - closed: make(chan struct{}),
55 - }
56 -}
57 -
58 -func (s *Stream) Name() string {
59 - return s.name
60 -}
61 -
62 -func (s *Stream) receive(b []byte) {
63 - select {
64 - case s.data_in <- b:
65 - case <-s.closed:
66 - }
67 -}
68 -
69 -func (m *Multiplex) Accept() (*Stream, error) {
70 - select {
71 - case s, ok := <-m.nstreams:
72 - if !ok {
73 - return nil, errors.New("multiplex closed")
74 - }
75 - return s, nil
76 - case err := <-m.errs:
77 - return nil, err
78 - case <-m.closed:
79 - return nil, errors.New("multiplex closed")
80 - }
81 -}
82 -
83 -func (s *Stream) Read(b []byte) (int, error) {
84 - if s.extra == nil {
85 - select {
86 - case <-s.closed:
87 - return 0, io.EOF
88 - case read, ok := <-s.data_in:
89 - if !ok {
90 - return 0, io.EOF
91 - }
92 - s.extra = read
93 - }
94 - }
95 - n := copy(b, s.extra)
96 - if n < len(s.extra) {
97 - s.extra = s.extra[n:]
98 - } else {
99 - s.extra = nil
100 - }
101 - return n, nil
102 -}
103 -
104 -func (s *Stream) Write(b []byte) (int, error) {
105 - errs := make(chan error, 1)
106 - select {
107 - case s.data_out <- msg{header: s.header, data: b, err: errs}:
108 - select {
109 - case err := <-errs:
110 - return len(b), err
111 - case <-s.closed:
112 - return 0, errors.New("stream closed")
113 - }
114 -
115 - case <-s.closed:
116 - return 0, errors.New("stream closed")
117 - }
118 -}
119 -
120 -func (s *Stream) Close() error {
121 - select {
122 - case <-s.closed:
123 - return nil
124 - default:
125 - close(s.closed)
126 - select {
127 - case s.data_out <- msg{
128 - header: (s.id << 3) | Close,
129 - err: make(chan error, 1), //throw away error, whatever
130 - }:
131 - default:
132 - }
133 - close(s.data_in)
134 - return nil
135 - }
136 -}
137 -
138 -type Multiplex struct {
139 - con io.ReadWriteCloser
140 - buf *bufio.Reader
141 - nextID uint64
142 - outchan chan msg
143 - closed chan struct{}
144 - initiator bool
145 -
146 - nstreams chan *Stream
147 - errs chan error
148 -
149 - channels map[uint64]*Stream
150 - ch_lock sync.Mutex
151 -}
152 -
153 -func NewMultiplex(con io.ReadWriteCloser, initiator bool) *Multiplex {
154 - mp := &Multiplex{
155 - con: con,
156 - initiator: initiator,
157 - buf: bufio.NewReader(con),
158 - channels: make(map[uint64]*Stream),
159 - outchan: make(chan msg),
160 - closed: make(chan struct{}),
161 - nstreams: make(chan *Stream, 16),
162 - errs: make(chan error),
163 - }
164 -
165 - go mp.handleOutgoing()
166 - go mp.handleIncoming()
167 -
168 - return mp
169 -}
170 -
171 -func (mp *Multiplex) Close() error {
172 - if mp.IsClosed() {
173 - return nil
174 - }
175 - close(mp.closed)
176 - mp.ch_lock.Lock()
177 - defer mp.ch_lock.Unlock()
178 - for _, s := range mp.channels {
179 - err := s.Close()
180 - if err != nil {
181 - return err
182 - }
183 - }
184 - return nil
185 -}
186 -
187 -func (mp *Multiplex) IsClosed() bool {
188 - select {
189 - case <-mp.closed:
190 - return true
191 - default:
192 - return false
193 - }
194 -}
195 -
196 -func (mp *Multiplex) handleOutgoing() {
197 - for {
198 - select {
199 - case msg, ok := <-mp.outchan:
200 - if !ok {
201 - return
202 - }
203 -
204 - buf := EncodeVarint(msg.header)
205 - _, err := mp.con.Write(buf)
206 - if err != nil {
207 - msg.err <- err
208 - continue
209 - }
210 -
211 - buf = EncodeVarint(uint64(len(msg.data)))
212 - _, err = mp.con.Write(buf)
213 - if err != nil {
214 - msg.err <- err
215 - continue
216 - }
217 -
218 - _, err = mp.con.Write(msg.data)
219 - if err != nil {
220 - msg.err <- err
221 - continue
222 - }
223 -
224 - msg.err <- nil
225 - case <-mp.closed:
226 - return
227 - }
228 - }
229 -}
230 -
231 -func (mp *Multiplex) nextChanID() (out uint64) {
232 - if mp.initiator {
233 - out = mp.nextID + 1
234 - } else {
235 - out = mp.nextID
236 - }
237 - mp.nextID += 2
238 - return
239 -}
240 -
241 -func (mp *Multiplex) NewStream() *Stream {
242 - return mp.NewNamedStream("")
243 -}
244 -
245 -func (mp *Multiplex) NewNamedStream(name string) *Stream {
246 - mp.ch_lock.Lock()
247 - sid := mp.nextChanID()
248 - header := (sid << 3) | NewStream
249 -
250 - if name == "" {
251 - name = fmt.Sprint(sid)
252 - }
253 - s := newStream(sid, name, true, mp.outchan)
254 - mp.channels[sid] = s
255 - mp.ch_lock.Unlock()
256 -
257 - mp.outchan <- msg{
258 - header: header,
259 - data: []byte(name),
260 - err: make(chan error, 1), //throw away error
261 - }
262 -
263 - return s
264 -}
265 -
266 -func (mp *Multiplex) sendErr(err error) {
267 - select {
268 - case mp.errs <- err:
269 - case <-mp.closed:
270 - }
271 -}
272 -
273 -func (mp *Multiplex) handleIncoming() {
274 - defer mp.shutdown()
275 - for {
276 - ch, tag, err := mp.readNextHeader()
277 - if err != nil {
278 - mp.sendErr(err)
279 - return
280 - }
281 -
282 - b, err := mp.readNext()
283 - if err != nil {
284 - mp.sendErr(err)
285 - return
286 - }
287 -
288 - mp.ch_lock.Lock()
289 - msch, ok := mp.channels[ch]
290 - if !ok {
291 - var name string
292 - if tag == NewStream {
293 - name = string(b)
294 - }
295 - msch = newStream(ch, name, false, mp.outchan)
296 - mp.channels[ch] = msch
297 - select {
298 - case mp.nstreams <- msch:
299 - case <-mp.closed:
300 - return
301 - }
302 - if tag == NewStream {
303 - mp.ch_lock.Unlock()
304 - continue
305 - }
306 - }
307 - mp.ch_lock.Unlock()
308 -
309 - if tag == Close {
310 - msch.Close()
311 - mp.ch_lock.Lock()
312 - delete(mp.channels, ch)
313 - mp.ch_lock.Unlock()
314 - continue
315 - }
316 -
317 - msch.receive(b)
318 - }
319 -}
320 -
321 -func (mp *Multiplex) shutdown() {
322 - mp.ch_lock.Lock()
323 - defer mp.ch_lock.Unlock()
324 - for _, s := range mp.channels {
325 - s.Close()
326 - }
327 -}
328 -
329 -func (mp *Multiplex) readNextHeader() (uint64, uint64, error) {
330 - h, _, err := DecodeVarint(mp.buf)
331 - if err != nil {
332 - return 0, 0, err
333 - }
334 -
335 - // get channel ID
336 - ch := h >> 3
337 -
338 - rem := h & 7
339 -
340 - return ch, rem, nil
341 -}
342 -
343 -func (mp *Multiplex) readNext() ([]byte, error) {
344 - // get length
345 - l, _, err := DecodeVarint(mp.buf)
346 - if err != nil {
347 - return nil, err
348 - }
349 -
350 - buf := make([]byte, l)
351 - n, err := io.ReadFull(mp.buf, buf)
352 - if err != nil {
353 - return nil, err
354 - }
355 -
356 - if n != int(l) {
357 - panic("NOT THE SAME")
358 - }
359 -
360 - return buf, nil
361 -}
362 -
363 -func EncodeVarint(x uint64) []byte {
364 - var buf [10]byte
365 - var n int
366 - for n = 0; x > 127; n++ {
367 - buf[n] = 0x80 | uint8(x&0x7F)
368 - x >>= 7
369 - }
370 - buf[n] = uint8(x)
371 - n++
372 - return buf[0:n]
373 -}
374 -
375 -func DecodeVarint(r *bufio.Reader) (x uint64, n int, err error) {
376 - // x, n already 0
377 - for shift := uint(0); shift < 64; shift += 7 {
378 - val, err := r.ReadByte()
379 - if err != nil {
380 - return 0, 0, err
381 - }
382 -
383 - b := uint64(val)
384 - n++
385 - x |= (b & 0x7F) << shift
386 - if (b & 0x80) == 0 {
387 - return x, n, nil
388 - }
389 - }
390 -
391 - // The number is too large to represent in a 64-bit value.
392 - return 0, 0, errors.New("Too large of a number!")
393 -}
Godeps/_workspace/src/github.com/whyrusleeping/go-multiplex/multiplex_test.go deleted
-118
@@ -1,118 +0,0 @@
1 -package multiplex
2 -
3 -import (
4 - "fmt"
5 - "io"
6 - "net"
7 - "testing"
8 -
9 - rand "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/randbo"
10 -)
11 -
12 -func TestBasicStreams(t *testing.T) {
13 - a, b := net.Pipe()
14 -
15 - mpa := NewMultiplex(a, false)
16 - mpb := NewMultiplex(b, true)
17 -
18 - mes := []byte("Hello world")
19 - go func() {
20 - s, err := mpb.Accept()
21 - if err != nil {
22 - t.Fatal(err)
23 - }
24 -
25 - _, err = s.Write(mes)
26 - if err != nil {
27 - t.Fatal(err)
28 - }
29 -
30 - err = s.Close()
31 - if err != nil {
32 - t.Fatal(err)
33 - }
34 - }()
35 -
36 - s := mpa.NewStream()
37 -
38 - buf := make([]byte, len(mes))
39 - n, err := s.Read(buf)
40 - if err != nil {
41 - t.Fatal(err)
42 - }
43 -
44 - if n != len(mes) {
45 - t.Fatal("read wrong amount")
46 - }
47 -
48 - if string(buf) != string(mes) {
49 - t.Fatal("got bad data")
50 - }
51 -
52 - s.Close()
53 -
54 - mpa.Close()
55 - mpb.Close()
56 -}
57 -
58 -func TestEcho(t *testing.T) {
59 - a, b := net.Pipe()
60 -
61 - mpa := NewMultiplex(a, false)
62 - mpb := NewMultiplex(b, true)
63 -
64 - mes := make([]byte, 40960)
65 - rand.New().Read(mes)
66 - go func() {
67 - s, err := mpb.Accept()
68 - if err != nil {
69 - t.Fatal(err)
70 - }
71 -
72 - defer s.Close()
73 - io.Copy(s, s)
74 - }()
75 -
76 - s := mpa.NewStream()
77 -
78 - _, err := s.Write(mes)
79 - if err != nil {
80 - t.Fatal(err)
81 - }
82 -
83 - buf := make([]byte, len(mes))
84 - n, err := io.ReadFull(s, buf)
85 - if err != nil {
86 - t.Fatal(err)
87 - }
88 -
89 - if n != len(mes) {
90 - t.Fatal("read wrong amount")
91 - }
92 -
93 - if err := arrComp(buf, mes); err != nil {
94 - t.Fatal(err)
95 - }
96 - s.Close()
97 -
98 - mpa.Close()
99 - mpb.Close()
100 -}
101 -
102 -func arrComp(a, b []byte) error {
103 - msg := ""
104 - if len(a) != len(b) {
105 - msg += fmt.Sprintf("arrays differ in length: %d %d\n", len(a), len(b))
106 - }
107 -
108 - for i := 0; i < len(a) && i < len(b); i++ {
109 - if a[i] != b[i] {
110 - msg += fmt.Sprintf("content differs at index %d [%d != %d]", i, a[i], b[i])
111 - return fmt.Errorf(msg)
112 - }
113 - }
114 - if len(msg) > 0 {
115 - return fmt.Errorf(msg)
116 - }
117 - return nil
118 -}
Godeps/_workspace/src/github.com/whyrusleeping/go-multiplex/package.json deleted
-5
@@ -1,5 +0,0 @@
1 -{
2 - "name": "go-multiplex",
3 - "version": "1.0.0",
4 - "language": "go"
5 -}
\ No newline at end of file
Godeps/_workspace/src/github.com/whyrusleeping/go-multistream/README.md deleted
-43
@@ -1,43 +0,0 @@
1 -#Multistream-select router
2 -This package implements a simple stream router for the multistream-select protocol.
3 -The protocol is defined [here](https://github.com/jbenet/multistream).
4 -
5 -
6 -Usage:
7 -
8 -```go
9 -package main
10 -
11 -import (
12 - "fmt"
13 - ms "github.com/whyrusleeping/go-multistream"
14 - "io"
15 - "net"
16 -)
17 -
18 -func main() {
19 - mux := ms.NewMultistreamMuxer()
20 - mux.AddHandler("/cats", func(rwc io.ReadWriteCloser) error {
21 - fmt.Fprintln(rwc, "HELLO I LIKE CATS")
22 - return rwc.Close()
23 - })
24 - mux.AddHandler("/dogs", func(rwc io.ReadWriteCloser) error {
25 - fmt.Fprintln(rwc, "HELLO I LIKE DOGS")
26 - return rwc.Close()
27 - })
28 -
29 - list, err := net.Listen("tcp", ":8765")
30 - if err != nil {
31 - panic(err)
32 - }
33 -
34 - for {
35 - con, err := list.Accept()
36 - if err != nil {
37 - panic(err)
38 - }
39 -
40 - go mux.Handle(con)
41 - }
42 -}
43 -```
Godeps/_workspace/src/github.com/whyrusleeping/go-multistream/client.go deleted
-75
@@ -1,75 +0,0 @@
1 -package multistream
2 -
3 -import (
4 - "errors"
5 - "io"
6 -)
7 -
8 -var ErrNotSupported = errors.New("protocol not supported")
9 -
10 -func SelectProtoOrFail(proto string, rwc io.ReadWriteCloser) error {
11 - err := handshake(rwc)
12 - if err != nil {
13 - return err
14 - }
15 -
16 - return trySelect(proto, rwc)
17 -}
18 -
19 -func SelectOneOf(protos []string, rwc io.ReadWriteCloser) (string, error) {
20 - err := handshake(rwc)
21 - if err != nil {
22 - return "", err
23 - }
24 -
25 - for _, p := range protos {
26 - err := trySelect(p, rwc)
27 - switch err {
28 - case nil:
29 - return p, nil
30 - case ErrNotSupported:
31 - default:
32 - return "", err
33 - }
34 - }
35 - return "", ErrNotSupported
36 -}
37 -
38 -func handshake(rwc io.ReadWriteCloser) error {
39 - tok, err := ReadNextToken(rwc)
40 - if err != nil {
41 - return err
42 - }
43 -
44 - if tok != ProtocolID {
45 - return errors.New("received mismatch in protocol id")
46 - }
47 -
48 - err = delimWrite(rwc, []byte(ProtocolID))
49 - if err != nil {
50 - return err
51 - }
52 -
53 - return nil
54 -}
55 -
56 -func trySelect(proto string, rwc io.ReadWriteCloser) error {
57 - err := delimWrite(rwc, []byte(proto))
58 - if err != nil {
59 - return err
60 - }
61 -
62 - tok, err := ReadNextToken(rwc)
63 - if err != nil {
64 - return err
65 - }
66 -
67 - switch tok {
68 - case proto:
69 - return nil
70 - case "na":
71 - return ErrNotSupported
72 - default:
73 - return errors.New("unrecognized response: " + tok)
74 - }
75 -}
Godeps/_workspace/src/github.com/whyrusleeping/go-multistream/lazy.go deleted
-124
@@ -1,124 +0,0 @@
1 -package multistream
2 -
3 -import (
4 - "fmt"
5 - "io"
6 - "sync"
7 -)
8 -
9 -type Multistream interface {
10 - io.ReadWriteCloser
11 - Protocol() string
12 -}
13 -
14 -func NewMSSelect(c io.ReadWriteCloser, proto string) Multistream {
15 - return NewMultistream(NewMultistream(c, ProtocolID), proto)
16 -}
17 -
18 -func NewMultistream(c io.ReadWriteCloser, proto string) Multistream {
19 - return &lazyConn{
20 - proto: proto,
21 - con: c,
22 - }
23 -}
24 -
25 -type lazyConn struct {
26 - rhandshake bool // only accessed by 'Read' should not call read async
27 -
28 - rhlock sync.Mutex
29 - rhsync bool //protected by mutex
30 - rerr error
31 -
32 - whandshake bool
33 -
34 - whlock sync.Mutex
35 - whsync bool
36 - werr error
37 -
38 - proto string
39 - con io.ReadWriteCloser
40 -}
41 -
42 -func (l *lazyConn) Protocol() string {
43 - return l.proto
44 -}
45 -
46 -func (l *lazyConn) Read(b []byte) (int, error) {
47 - if !l.rhandshake {
48 - go l.writeHandshake()
49 - err := l.readHandshake()
50 - if err != nil {
51 - return 0, err
52 - }
53 -
54 - l.rhandshake = true
55 - }
56 -
57 - if len(b) == 0 {
58 - return 0, nil
59 - }
60 -
61 - return l.con.Read(b)
62 -}
63 -
64 -func (l *lazyConn) readHandshake() error {
65 - l.rhlock.Lock()
66 - defer l.rhlock.Unlock()
67 -
68 - // if we've already done this, exit
69 - if l.rhsync {
70 - return l.rerr
71 - }
72 - l.rhsync = true
73 -
74 - // read protocol
75 - tok, err := ReadNextToken(l.con)
76 - if err != nil {
77 - l.rerr = err
78 - return err
79 - }
80 -
81 - if tok != l.proto {
82 - l.rerr = fmt.Errorf("protocol mismatch in lazy handshake ( %s != %s )", tok, l.proto)
83 - return l.rerr
84 - }
85 -
86 - return nil
87 -}
88 -
89 -func (l *lazyConn) writeHandshake() error {
90 - l.whlock.Lock()
91 - defer l.whlock.Unlock()
92 -
93 - if l.whsync {
94 - return l.werr
95 - }
96 -
97 - l.whsync = true
98 -
99 - err := delimWrite(l.con, []byte(l.proto))
100 - if err != nil {
101 - l.werr = err
102 - return err
103 - }
104 -
105 - return nil
106 -}
107 -
108 -func (l *lazyConn) Write(b []byte) (int, error) {
109 - if !l.whandshake {
110 - go l.readHandshake()
111 - err := l.writeHandshake()
112 - if err != nil {
113 - return 0, err
114 - }
115 -
116 - l.whandshake = true
117 - }
118 -
119 - return l.con.Write(b)
120 -}
121 -
122 -func (l *lazyConn) Close() error {
123 - return l.con.Close()
124 -}
Godeps/_workspace/src/github.com/whyrusleeping/go-multistream/multistream.go deleted
-201
@@ -1,201 +0,0 @@
1 -package multistream
2 -
3 -import (
4 - "bytes"
5 - "encoding/binary"
6 - "errors"
7 - "io"
8 - "sync"
9 -)
10 -
11 -var ErrTooLarge = errors.New("incoming message was too large")
12 -
13 -const ProtocolID = "/multistream/1.0.0"
14 -
15 -type HandlerFunc func(io.ReadWriteCloser) error
16 -
17 -type MultistreamMuxer struct {
18 - handlerlock sync.Mutex
19 - handlers map[string]HandlerFunc
20 -}
21 -
22 -func NewMultistreamMuxer() *MultistreamMuxer {
23 - return &MultistreamMuxer{handlers: make(map[string]HandlerFunc)}
24 -}
25 -
26 -func writeUvarint(w io.Writer, i uint64) error {
27 - varintbuf := make([]byte, 32)
28 - n := binary.PutUvarint(varintbuf, i)
29 - _, err := w.Write(varintbuf[:n])
30 - if err != nil {
31 - return err
32 - }
33 - return nil
34 -}
35 -
36 -func delimWrite(w io.Writer, mes []byte) error {
37 - err := writeUvarint(w, uint64(len(mes)+1))
38 - if err != nil {
39 - return err
40 - }
41 -
42 - _, err = w.Write(mes)
43 - if err != nil {
44 - return err
45 - }
46 -
47 - _, err = w.Write([]byte{'\n'})
48 - if err != nil {
49 - return err
50 - }
51 - return nil
52 -}
53 -
54 -func (msm *MultistreamMuxer) AddHandler(protocol string, handler HandlerFunc) {
55 - msm.handlerlock.Lock()
56 - msm.handlers[protocol] = handler
57 - msm.handlerlock.Unlock()
58 -}
59 -
60 -func (msm *MultistreamMuxer) RemoveHandler(protocol string) {
61 - msm.handlerlock.Lock()
62 - delete(msm.handlers, protocol)
63 - msm.handlerlock.Unlock()
64 -}
65 -
66 -func (msm *MultistreamMuxer) Protocols() []string {
67 - var out []string
68 - msm.handlerlock.Lock()
69 - for k, _ := range msm.handlers {
70 - out = append(out, k)
71 - }
72 - msm.handlerlock.Unlock()
73 - return out
74 -}
75 -
76 -func (msm *MultistreamMuxer) Negotiate(rwc io.ReadWriteCloser) (string, HandlerFunc, error) {
77 - // Send our protocol ID
78 - err := delimWrite(rwc, []byte(ProtocolID))
79 - if err != nil {
80 - return "", nil, err
81 - }
82 -
83 - line, err := ReadNextToken(rwc)
84 - if err != nil {
85 - return "", nil, err
86 - }
87 -
88 - if line != ProtocolID {
89 - rwc.Close()
90 - return "", nil, errors.New("client connected with incorrect version")
91 - }
92 -
93 -loop:
94 - for {
95 - // Now read and respond to commands until they send a valid protocol id
96 - tok, err := ReadNextToken(rwc)
97 - if err != nil {
98 - return "", nil, err
99 - }
100 -
101 - switch tok {
102 - case "ls":
103 - err := msm.Ls(rwc)
104 - if err != nil {
105 - return "", nil, err
106 - }
107 - default:
108 - msm.handlerlock.Lock()
109 - h, ok := msm.handlers[tok]
110 - msm.handlerlock.Unlock()
111 - if !ok {
112 - err := delimWrite(rwc, []byte("na"))
113 - if err != nil {
114 - return "", nil, err
115 - }
116 - continue loop
117 - }
118 -
119 - err := delimWrite(rwc, []byte(tok))
120 - if err != nil {
121 - return "", nil, err
122 - }
123 -
124 - // hand off processing to the sub-protocol handler
125 - return tok, h, nil
126 - }
127 - }
128 -
129 -}
130 -
131 -func (msm *MultistreamMuxer) Ls(rwc io.Writer) error {
132 - buf := new(bytes.Buffer)
133 - msm.handlerlock.Lock()
134 - for proto, _ := range msm.handlers {
135 - err := delimWrite(buf, []byte(proto))
136 - if err != nil {
137 - msm.handlerlock.Unlock()
138 - return err
139 - }
140 - }
141 - msm.handlerlock.Unlock()
142 - err := delimWrite(rwc, buf.Bytes())
143 - if err != nil {
144 - return err
145 - }
146 - return nil
147 -}
148 -
149 -func (msm *MultistreamMuxer) Handle(rwc io.ReadWriteCloser) error {
150 - _, h, err := msm.Negotiate(rwc)
151 - if err != nil {
152 - return err
153 - }
154 - return h(rwc)
155 -}
156 -
157 -func ReadNextToken(rw io.ReadWriter) (string, error) {
158 - br := &byteReader{rw}
159 - length, err := binary.ReadUvarint(br)
160 - if err != nil {
161 - return "", err
162 - }
163 -
164 - if length > 64*1024 {
165 - err := delimWrite(rw, []byte("messages over 64k are not allowed"))
166 - if err != nil {
167 - return "", err
168 - }
169 - return "", ErrTooLarge
170 - }
171 -
172 - buf := make([]byte, length)
173 - _, err = io.ReadFull(rw, buf)
174 - if err != nil {
175 - return "", err
176 - }
177 -
178 - if len(buf) == 0 || buf[length-1] != '\n' {
179 - return "", errors.New("message did not have trailing newline")
180 - }
181 -
182 - // slice off the trailing newline
183 - buf = buf[:length-1]
184 -
185 - return string(buf), nil
186 -}
187 -
188 -// byteReader implements the ByteReader interface that ReadUVarint requires
189 -type byteReader struct {
190 - io.Reader
191 -}
192 -
193 -func (br *byteReader) ReadByte() (byte, error) {
194 - var b [1]byte
195 - _, err := br.Read(b[:])
196 -
197 - if err != nil {
198 - return 0, err
199 - }
200 - return b[0], nil
201 -}
Godeps/_workspace/src/github.com/whyrusleeping/go-multistream/multistream_test.go deleted
-259
@@ -1,259 +0,0 @@
1 -package multistream
2 -
3 -import (
4 - "crypto/rand"
5 - "io"
6 - "net"
7 - "testing"
8 - "time"
9 -)
10 -
11 -func TestProtocolNegotiation(t *testing.T) {
12 - a, b := net.Pipe()
13 -
14 - mux := NewMultistreamMuxer()
15 - mux.AddHandler("/a", nil)
16 - mux.AddHandler("/b", nil)
17 - mux.AddHandler("/c", nil)
18 -
19 - done := make(chan struct{})
20 - go func() {
21 - selected, _, err := mux.Negotiate(a)
22 - if err != nil {
23 - t.Fatal(err)
24 - }
25 - if selected != "/a" {
26 - t.Fatal("incorrect protocol selected")
27 - }
28 - close(done)
29 - }()
30 -
31 - err := SelectProtoOrFail("/a", b)
32 - if err != nil {
33 - t.Fatal(err)
34 - }
35 -
36 - select {
37 - case <-time.After(time.Second):
38 - t.Fatal("protocol negotiation didnt complete")
39 - case <-done:
40 - }
41 -
42 - verifyPipe(t, a, b)
43 -}
44 -
45 -func TestSelectOne(t *testing.T) {
46 - a, b := net.Pipe()
47 -
48 - mux := NewMultistreamMuxer()
49 - mux.AddHandler("/a", nil)
50 - mux.AddHandler("/b", nil)
51 - mux.AddHandler("/c", nil)
52 -
53 - done := make(chan struct{})
54 - go func() {
55 - selected, _, err := mux.Negotiate(a)
56 - if err != nil {
57 - t.Fatal(err)
58 - }
59 - if selected != "/c" {
60 - t.Fatal("incorrect protocol selected")
61 - }
62 - close(done)
63 - }()
64 -
65 - sel, err := SelectOneOf([]string{"/d", "/e", "/c"}, b)
66 - if err != nil {
67 - t.Fatal(err)
68 - }
69 -
70 - if sel != "/c" {
71 - t.Fatal("selected wrong protocol")
72 - }
73 -
74 - select {
75 - case <-time.After(time.Second):
76 - t.Fatal("protocol negotiation didnt complete")
77 - case <-done:
78 - }
79 -
80 - verifyPipe(t, a, b)
81 -}
82 -
83 -func TestSelectOneAndWrite(t *testing.T) {
84 - a, b := net.Pipe()
85 -
86 - mux := NewMultistreamMuxer()
87 - mux.AddHandler("/a", nil)
88 - mux.AddHandler("/b", nil)
89 - mux.AddHandler("/c", nil)
90 -
91 - done := make(chan struct{})
92 - go func() {
93 - selected, _, err := mux.Negotiate(a)
94 - if err != nil {
95 - t.Fatal(err)
96 - }
97 - if selected != "/c" {
98 - t.Fatal("incorrect protocol selected")
99 - }
100 - close(done)
101 - }()
102 -
103 - sel, err := SelectOneOf([]string{"/d", "/e", "/c"}, b)
104 - if err != nil {
105 - t.Fatal(err)
106 - }
107 -
108 - if sel != "/c" {
109 - t.Fatal("selected wrong protocol")
110 - }
111 -
112 - select {
113 - case <-time.After(time.Second):
114 - t.Fatal("protocol negotiation didnt complete")
115 - case <-done:
116 - }
117 -
118 - verifyPipe(t, a, b)
119 -}
120 -
121 -func TestLazyConns(t *testing.T) {
122 - a, b := net.Pipe()
123 -
124 - mux := NewMultistreamMuxer()
125 - mux.AddHandler("/a", nil)
126 - mux.AddHandler("/b", nil)
127 - mux.AddHandler("/c", nil)
128 -
129 - la := NewMSSelect(a, "/c")
130 - lb := NewMSSelect(b, "/c")
131 -
132 - verifyPipe(t, la, lb)
133 -}
134 -
135 -func TestLazyAndMux(t *testing.T) {
136 - a, b := net.Pipe()
137 -
138 - mux := NewMultistreamMuxer()
139 - mux.AddHandler("/a", nil)
140 - mux.AddHandler("/b", nil)
141 - mux.AddHandler("/c", nil)
142 -
143 - done := make(chan struct{})
144 - go func() {
145 - selected, _, err := mux.Negotiate(a)
146 - if err != nil {
147 - t.Fatal(err)
148 - }
149 - if selected != "/c" {
150 - t.Fatal("incorrect protocol selected")
151 - }
152 -
153 - msg := make([]byte, 5)
154 - _, err = a.Read(msg)
155 - if err != nil {
156 - t.Fatal(err)
157 - }
158 -
159 - close(done)
160 - }()
161 -
162 - lb := NewMSSelect(b, "/c")
163 -
164 - // do a write to push the handshake through
165 - _, err := lb.Write([]byte("hello"))
166 - if err != nil {
167 - t.Fatal(err)
168 - }
169 -
170 - select {
171 - case <-time.After(time.Second):
172 - t.Fatal("failed to complete in time")
173 - case <-done:
174 - }
175 -
176 - verifyPipe(t, a, lb)
177 -}
178 -
179 -func TestLazyAndMuxWrite(t *testing.T) {
180 - a, b := net.Pipe()
181 -
182 - mux := NewMultistreamMuxer()
183 - mux.AddHandler("/a", nil)
184 - mux.AddHandler("/b", nil)
185 - mux.AddHandler("/c", nil)
186 -
187 - done := make(chan struct{})
188 - go func() {
189 - selected, _, err := mux.Negotiate(a)
190 - if err != nil {
191 - t.Fatal(err)
192 - }
193 - if selected != "/c" {
194 - t.Fatal("incorrect protocol selected")
195 - }
196 -
197 - _, err = a.Write([]byte("hello"))
198 - if err != nil {
199 - t.Fatal(err)
200 - }
201 -
202 - close(done)
203 - }()
204 -
205 - lb := NewMSSelect(b, "/c")
206 -
207 - // do a write to push the handshake through
208 - msg := make([]byte, 5)
209 - _, err := lb.Read(msg)
210 - if err != nil {
211 - t.Fatal(err)
212 - }
213 -
214 - if string(msg) != "hello" {
215 - t.Fatal("wrong!")
216 - }
217 -
218 - select {
219 - case <-time.After(time.Second):
220 - t.Fatal("failed to complete in time")
221 - case <-done:
222 - }
223 -
224 - verifyPipe(t, a, lb)
225 -}
226 -
227 -func verifyPipe(t *testing.T, a, b io.ReadWriter) {
228 - mes := make([]byte, 1024)
229 - rand.Read(mes)
230 - go func() {
231 - b.Write(mes)
232 - a.Write(mes)
233 - }()
234 -
235 - buf := make([]byte, len(mes))
236 - n, err := a.Read(buf)
237 - if err != nil {
238 - t.Fatal(err)
239 - }
240 - if n != len(buf) {
241 - t.Fatal("failed to read enough")
242 - }
243 -
244 - if string(buf) != string(mes) {
245 - t.Fatal("somehow read wrong message")
246 - }
247 -
248 - n, err = b.Read(buf)
249 - if err != nil {
250 - t.Fatal(err)
251 - }
252 - if n != len(buf) {
253 - t.Fatal("failed to read enough")
254 - }
255 -
256 - if string(buf) != string(mes) {
257 - t.Fatal("somehow read wrong message")
258 - }
259 -}
Godeps/_workspace/src/github.com/whyrusleeping/iptb/util/proc_unix.go renamed
+1 -2
@@ -1,6 +1,5 @@
1 // +build !windows
2 -
3 -package main
2 +package iptbutil
3
4 import (
5 "os/exec"
Godeps/_workspace/src/github.com/whyrusleeping/iptb/util/util.go new
+542
@@ -0,0 +1,542 @@
1 +package iptbutil
2 +
3 +import (
4 + "encoding/json"
5 + "errors"
6 + "fmt"
7 + "io/ioutil"
8 + "log"
9 + "net/http"
10 + "os"
11 + "os/exec"
12 + "path"
13 + "strconv"
14 + "strings"
15 + "sync"
16 + "syscall"
17 + "time"
18 +
19 + serial "github.com/ipfs/go-ipfs/repo/fsrepo/serialize"
20 +
21 + manet "gx/ipfs/QmQB7mNP3QE7b4zP2MQmsyJDqG5hzYE2CL8k1VyLWky2Ed/go-multiaddr-net"
22 + ma "gx/ipfs/QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz/go-multiaddr"
23 +)
24 +
25 +var setupOpt = func(cmd *exec.Cmd) {}
26 +
27 +// GetNumNodes returns the number of testbed nodes configured in the testbed directory
28 +func GetNumNodes() int {
29 + for i := 0; i < 2000; i++ {
30 + _, err := os.Stat(IpfsDirN(i))
31 + if os.IsNotExist(err) {
32 + return i
33 + }
34 + }
35 + panic("i dont know whats going on")
36 +}
37 +
38 +func TestBedDir() string {
39 + tbd := os.Getenv("IPTB_ROOT")
40 + if len(tbd) != 0 {
41 + return tbd
42 + }
43 +
44 + home := os.Getenv("HOME")
45 + if len(home) == 0 {
46 + panic("could not find home")
47 + }
48 +
49 + return path.Join(home, "testbed")
50 +}
51 +
52 +func IpfsDirN(n int) string {
53 + return path.Join(TestBedDir(), fmt.Sprint(n))
54 +}
55 +
56 +type InitCfg struct {
57 + Count int
58 + Force bool
59 + Bootstrap string
60 + PortStart int
61 + Mdns bool
62 + Utp bool
63 + Override string
64 +}
65 +
66 +func (c *InitCfg) swarmAddrForPeer(i int) string {
67 + str := "/ip4/0.0.0.0/tcp/%d"
68 + if c.Utp {
69 + str = "/ip4/0.0.0.0/udp/%d/utp"
70 + }
71 +
72 + if c.PortStart == 0 {
73 + return fmt.Sprintf(str, 0)
74 + }
75 + return fmt.Sprintf(str, c.PortStart+i)
76 +}
77 +
78 +func (c *InitCfg) apiAddrForPeer(i int) string {
79 + if c.PortStart == 0 {
80 + return "/ip4/127.0.0.1/tcp/0"
81 + }
82 + return fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", c.PortStart+1000+i)
83 +}
84 +
85 +func YesNoPrompt(prompt string) bool {
86 + var s string
87 + for {
88 + fmt.Println(prompt)
89 + fmt.Scanf("%s", &s)
90 + switch s {
91 + case "y", "Y":
92 + return true
93 + case "n", "N":
94 + return false
95 + }
96 + fmt.Println("Please press either 'y' or 'n'")
97 + }
98 +}
99 +
100 +func IpfsInit(cfg *InitCfg) error {
101 + p := IpfsDirN(0)
102 + if _, err := os.Stat(p); !os.IsNotExist(err) {
103 + if !cfg.Force && !YesNoPrompt("testbed nodes already exist, overwrite? [y/n]") {
104 + return nil
105 + }
106 + err := os.RemoveAll(TestBedDir())
107 + if err != nil {
108 + return err
109 + }
110 + }
111 + wait := sync.WaitGroup{}
112 + for i := 0; i < cfg.Count; i++ {
113 + wait.Add(1)
114 + go func(v int) {
115 + defer wait.Done()
116 + dir := IpfsDirN(v)
117 + err := os.MkdirAll(dir, 0777)
118 + if err != nil {
119 + log.Println("ERROR: ", err)
120 + return
121 + }
122 +
123 + cmd := exec.Command("ipfs", "init", "-b=1024")
124 + cmd.Env = append(cmd.Env, "IPFS_PATH="+dir)
125 + out, err := cmd.CombinedOutput()
126 + if err != nil {
127 + log.Println("ERROR: ", err)
128 + log.Println(string(out))
129 + }
130 + }(i)
131 + }
132 + wait.Wait()
133 +
134 + // Now setup bootstrapping
135 + switch cfg.Bootstrap {
136 + case "star":
137 + err := starBootstrap(cfg)
138 + if err != nil {
139 + return err
140 + }
141 + case "none":
142 + err := clearBootstrapping(cfg)
143 + if err != nil {
144 + return err
145 + }
146 + default:
147 + return fmt.Errorf("unrecognized bootstrapping option: %s", cfg.Bootstrap)
148 + }
149 +
150 + /*
151 + if cfg.Override != "" {
152 + err := ApplyConfigOverride(cfg)
153 + if err != nil {
154 + return err
155 + }
156 + }
157 + */
158 +
159 + return nil
160 +}
161 +
162 +func ApplyConfigOverride(cfg *InitCfg) error {
163 + fir, err := os.Open(cfg.Override)
164 + if err != nil {
165 + return err
166 + }
167 + defer fir.Close()
168 +
169 + var configs map[string]interface{}
170 + err = json.NewDecoder(fir).Decode(&configs)
171 + if err != nil {
172 + return err
173 + }
174 +
175 + for i := 0; i < cfg.Count; i++ {
176 + err := applyOverrideToNode(configs, i)
177 + if err != nil {
178 + return err
179 + }
180 + }
181 +
182 + return nil
183 +}
184 +
185 +func applyOverrideToNode(ovr map[string]interface{}, node int) error {
186 + for k, v := range ovr {
187 + _ = k
188 + switch v.(type) {
189 + case map[string]interface{}:
190 + default:
191 + }
192 +
193 + }
194 +
195 + panic("not implemented")
196 +}
197 +
198 +func starBootstrap(icfg *InitCfg) error {
199 + // '0' node is the bootstrap node
200 + cfgpath := path.Join(IpfsDirN(0), "config")
201 + bcfg, err := serial.Load(cfgpath)
202 + if err != nil {
203 + return err
204 + }
205 + bcfg.Bootstrap = nil
206 + bcfg.Addresses.Swarm = []string{icfg.swarmAddrForPeer(0)}
207 + bcfg.Addresses.API = icfg.apiAddrForPeer(0)
208 + bcfg.Addresses.Gateway = ""
209 + bcfg.Discovery.MDNS.Enabled = icfg.Mdns
210 + err = serial.WriteConfigFile(cfgpath, bcfg)
211 + if err != nil {
212 + return err
213 + }
214 +
215 + for i := 1; i < icfg.Count; i++ {
216 + cfgpath := path.Join(IpfsDirN(i), "config")
217 + cfg, err := serial.Load(cfgpath)
218 + if err != nil {
219 + return err
220 + }
221 +
222 + ba := fmt.Sprintf("%s/ipfs/%s", bcfg.Addresses.Swarm[0], bcfg.Identity.PeerID)
223 + ba = strings.Replace(ba, "0.0.0.0", "127.0.0.1", -1)
224 + cfg.Bootstrap = []string{ba}
225 + cfg.Addresses.Gateway = ""
226 + cfg.Discovery.MDNS.Enabled = icfg.Mdns
227 + cfg.Addresses.Swarm = []string{
228 + icfg.swarmAddrForPeer(i),
229 + }
230 + cfg.Addresses.API = icfg.apiAddrForPeer(i)
231 + err = serial.WriteConfigFile(cfgpath, cfg)
232 + if err != nil {
233 + return err
234 + }
235 + }
236 + return nil
237 +}
238 +
239 +func clearBootstrapping(icfg *InitCfg) error {
240 + for i := 0; i < icfg.Count; i++ {
241 + cfgpath := path.Join(IpfsDirN(i), "config")
242 + cfg, err := serial.Load(cfgpath)
243 + if err != nil {
244 + return err
245 + }
246 +
247 + cfg.Bootstrap = nil
248 + cfg.Addresses.Gateway = ""
249 + cfg.Addresses.Swarm = []string{icfg.swarmAddrForPeer(i)}
250 + cfg.Addresses.API = icfg.apiAddrForPeer(i)
251 + cfg.Discovery.MDNS.Enabled = icfg.Mdns
252 + err = serial.WriteConfigFile(cfgpath, cfg)
253 + if err != nil {
254 + return err
255 + }
256 + }
257 + return nil
258 +}
259 +
260 +func IpfsPidOf(n int) (int, error) {
261 + dir := IpfsDirN(n)
262 + b, err := ioutil.ReadFile(path.Join(dir, "daemon.pid"))
263 + if err != nil {
264 + return -1, err
265 + }
266 +
267 + return strconv.Atoi(string(b))
268 +}
269 +
270 +func KillNode(i int) error {
271 + pid, err := IpfsPidOf(i)
272 + if err != nil {
273 + return fmt.Errorf("error killing daemon %d: %s", i, err)
274 + }
275 +
276 + p, err := os.FindProcess(pid)
277 + if err != nil {
278 + return fmt.Errorf("error killing daemon %d: %s", i, err)
279 + }
280 + err = p.Kill()
281 + if err != nil {
282 + return fmt.Errorf("error killing daemon %d: %s\n", i, err)
283 + }
284 +
285 + p.Wait()
286 +
287 + err = os.Remove(path.Join(IpfsDirN(i), "daemon.pid"))
288 + if err != nil {
289 + return fmt.Errorf("error removing pid file for daemon %d: %s\n", i, err)
290 + }
291 +
292 + return nil
293 +}
294 +
295 +func IpfsKillAll() error {
296 + n := GetNumNodes()
297 + for i := 0; i < n; i++ {
298 + err := KillNode(i)
299 + if err != nil {
300 + return err
301 + }
302 + }
303 + return nil
304 +}
305 +
306 +func envForDaemon(n int) []string {
307 + envs := os.Environ()
308 + npath := "IPFS_PATH=" + IpfsDirN(n)
309 + for i, e := range envs {
310 + p := strings.Split(e, "=")
311 + if p[0] == "IPFS_PATH" {
312 + envs[i] = npath
313 + return envs
314 + }
315 + }
316 +
317 + return append(envs, npath)
318 +}
319 +
320 +func IpfsStart(waitall bool) error {
321 + var addrs []string
322 + n := GetNumNodes()
323 + for i := 0; i < n; i++ {
324 + dir := IpfsDirN(i)
325 + cmd := exec.Command("ipfs", "daemon")
326 + cmd.Dir = dir
327 + cmd.Env = envForDaemon(i)
328 +
329 + setupOpt(cmd)
330 +
331 + stdout, err := os.Create(path.Join(dir, "daemon.stdout"))
332 + if err != nil {
333 + return err
334 + }
335 +
336 + stderr, err := os.Create(path.Join(dir, "daemon.stderr"))
337 + if err != nil {
338 + return err
339 + }
340 +
341 + cmd.Stdout = stdout
342 + cmd.Stderr = stderr
343 +
344 + err = cmd.Start()
345 + if err != nil {
346 + return err
347 + }
348 + pid := cmd.Process.Pid
349 +
350 + fmt.Printf("Started daemon %d, pid = %d\n", i, pid)
351 + err = ioutil.WriteFile(path.Join(dir, "daemon.pid"), []byte(fmt.Sprint(pid)), 0666)
352 + if err != nil {
353 + return err
354 + }
355 +
356 + // Make sure node 0 is up before starting the rest so
357 + // bootstrapping works properly
358 + cfg, err := serial.Load(path.Join(IpfsDirN(i), "config"))
359 + if err != nil {
360 + return err
361 + }
362 +
363 + maddr := ma.StringCast(cfg.Addresses.API)
364 + _, addr, err := manet.DialArgs(maddr)
365 + if err != nil {
366 + return err
367 + }
368 +
369 + addrs = append(addrs, addr)
370 +
371 + err = waitOnAPI(cfg.Identity.PeerID, i)
372 + if err != nil {
373 + return err
374 + }
375 + }
376 + if waitall {
377 + for i := 0; i < n; i++ {
378 + err := waitOnSwarmPeers(i)
379 + if err != nil {
380 + return err
381 + }
382 + }
383 +
384 + }
385 + return nil
386 +}
387 +
388 +func waitOnAPI(peerid string, nnum int) error {
389 + for i := 0; i < 50; i++ {
390 + err := tryAPICheck(peerid, nnum)
391 + if err == nil {
392 + return nil
393 + }
394 + time.Sleep(time.Millisecond * 200)
395 + }
396 + return fmt.Errorf("node %d failed to come online in given time period", nnum)
397 +}
398 +
399 +func GetNodesAPIAddr(nnum int) (string, error) {
400 + addrb, err := ioutil.ReadFile(path.Join(IpfsDirN(nnum), "api"))
401 + if err != nil {
402 + return "", err
403 + }
404 +
405 + maddr, err := ma.NewMultiaddr(string(addrb))
406 + if err != nil {
407 + fmt.Println("error parsing multiaddr: ", err)
408 + return "", err
409 + }
410 +
411 + _, addr, err := manet.DialArgs(maddr)
412 + if err != nil {
413 + fmt.Println("error on multiaddr dialargs: ", err)
414 + return "", err
415 + }
416 + return addr, nil
417 +}
418 +
419 +func tryAPICheck(peerid string, nnum int) error {
420 + addr, err := GetNodesAPIAddr(nnum)
421 + if err != nil {
422 + return err
423 + }
424 +
425 + resp, err := http.Get("http://" + addr + "/api/v0/id")
426 + if err != nil {
427 + return err
428 + }
429 +
430 + out := make(map[string]interface{})
431 + err = json.NewDecoder(resp.Body).Decode(&out)
432 + if err != nil {
433 + return fmt.Errorf("liveness check failed: %s", err)
434 + }
435 +
436 + id, ok := out["ID"]
437 + if !ok {
438 + return fmt.Errorf("liveness check failed: ID field not present in output")
439 + }
440 +
441 + idstr := id.(string)
442 + if idstr != peerid {
443 + return fmt.Errorf("liveness check failed: unexpected peer at endpoint")
444 + }
445 +
446 + return nil
447 +}
448 +
449 +func waitOnSwarmPeers(nnum int) error {
450 + addr, err := GetNodesAPIAddr(nnum)
451 + if err != nil {
452 + return err
453 + }
454 +
455 + for i := 0; i < 50; i++ {
456 + resp, err := http.Get("http://" + addr + "/api/v0/swarm/peers")
457 + if err == nil {
458 + out := make(map[string]interface{})
459 + err := json.NewDecoder(resp.Body).Decode(&out)
460 + if err != nil {
461 + return fmt.Errorf("liveness check failed: %s", err)
462 + }
463 +
464 + peers := out["Strings"].([]interface{})
465 + if len(peers) == 0 {
466 + time.Sleep(time.Millisecond * 200)
467 + continue
468 + }
469 +
470 + return nil
471 + }
472 + time.Sleep(time.Millisecond * 200)
473 + }
474 + return fmt.Errorf("node at %s failed to bootstrap in given time period", addr)
475 +}
476 +
477 +// GetPeerID reads the config of node 'n' and returns its peer ID
478 +func GetPeerID(n int) (string, error) {
479 + cfg, err := serial.Load(path.Join(IpfsDirN(n), "config"))
480 + if err != nil {
481 + return "", err
482 + }
483 + return cfg.Identity.PeerID, nil
484 +}
485 +
486 +// IpfsShell sets up environment variables for a new shell to more easily
487 +// control the given daemon
488 +func IpfsShell(n int) error {
489 + shell := os.Getenv("SHELL")
490 + if shell == "" {
491 + return fmt.Errorf("couldnt find shell!")
492 + }
493 +
494 + dir := IpfsDirN(n)
495 + nenvs := []string{"IPFS_PATH=" + dir}
496 +
497 + nnodes := GetNumNodes()
498 + for i := 0; i < nnodes; i++ {
499 + peerid, err := GetPeerID(i)
500 + if err != nil {
501 + return err
502 + }
503 + nenvs = append(nenvs, fmt.Sprintf("NODE%d=%s", i, peerid))
504 + }
505 + nenvs = append(os.Environ(), nenvs...)
506 +
507 + return syscall.Exec(shell, []string{shell}, nenvs)
508 +}
509 +
510 +func ConnectNodes(from, to int) error {
511 + if from == to {
512 + // skip connecting to self..
513 + return nil
514 + }
515 + fmt.Printf("connecting %d -> %d\n", from, to)
516 + cmd := exec.Command("ipfs", "id", "-f", "<addrs>")
517 + cmd.Env = []string{"IPFS_PATH=" + IpfsDirN(to)}
518 + out, err := cmd.Output()
519 + if err != nil {
520 + fmt.Println("ERR: ", string(out))
521 + return err
522 + }
523 + addr := strings.Split(string(out), "\n")[0]
524 +
525 + connectcmd := exec.Command("ipfs", "swarm", "connect", addr)
526 + connectcmd.Env = []string{"IPFS_PATH=" + IpfsDirN(from)}
527 + out, err = connectcmd.CombinedOutput()
528 + if err != nil {
529 + fmt.Println(string(out))
530 + return err
531 + }
532 + return nil
533 +}
534 +
535 +func GetAttr(attr string, node int) (string, error) {
536 + switch attr {
537 + case "id":
538 + return GetPeerID(node)
539 + default:
540 + return "", errors.New("unrecognized attribute")
541 + }
542 +}
repo/fsrepo/datastores.go deleted
-38
@@ -1,38 +0,0 @@
1 -package fsrepo
2 -
3 -import (
4 - "fmt"
5 -
6 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/aws"
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
8 -
9 - repo "github.com/ipfs/go-ipfs/repo"
10 - config "github.com/ipfs/go-ipfs/repo/config"
11 - "github.com/ipfs/go-ipfs/thirdparty/s3-datastore"
12 -)
13 -
14 -func openS3Datastore(params config.S3Datastore) (repo.Datastore, error) {
15 - // TODO support credentials files
16 - auth, err := aws.EnvAuth()
17 - if err != nil {
18 - return nil, err
19 - }
20 -
21 - region := aws.GetRegion(params.Region)
22 - if region.Name == "" {
23 - return nil, fmt.Errorf("unknown AWS region: %q", params.Region)
24 - }
25 -
26 - if params.Bucket == "" {
27 - return nil, fmt.Errorf("invalid S3 bucket: %q", params.Bucket)
28 - }
29 -
30 - client := s3.New(auth, region)
31 - // There are too many gophermucking s3datastores in my
32 - // gophermucking source.
33 - return &s3datastore.S3Datastore{
34 - Client: client,
35 - Bucket: params.Bucket,
36 - ACL: s3.ACL(params.ACL),
37 - }, nil
38 -}
repo/fsrepo/fsrepo.go
-13
@@ -1,7 +1,6 @@
1 package fsrepo
2
3 import (
4 - "encoding/json"
4 "errors"
5 "fmt"
6 "io"
@@ -334,18 +333,6 @@ func (r *FSRepo) openDatastore() error {
333 return err
334 }
335 r.ds = d
337 - case "s3":
338 - var dscfg config.S3Datastore
339 - if err := json.Unmarshal(r.config.Datastore.ParamData(), &dscfg); err != nil {
340 - return fmt.Errorf("datastore s3: %v", err)
341 - }
342 -
343 - ds, err := openS3Datastore(dscfg)
344 - if err != nil {
345 - return err
346 - }
347 -
348 - r.ds = ds
336 default:
337 return fmt.Errorf("unknown datastore type: %s", r.config.Datastore.Type)
338 }
test/dependencies/iptb/main.go
+168 -574
@@ -1,492 +1,17 @@
1 package main
2
3 import (
4 - "encoding/json"
5 - "errors"
4 "fmt"
7 - "io/ioutil"
8 - "log"
5 + "io"
6 "net/http"
7 "os"
11 - "os/exec"
12 - "path"
8 "strconv"
9 "strings"
15 - "sync"
16 - "syscall"
17 - "time"
10
19 - kingpin "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/alecthomas/kingpin"
20 - serial "github.com/ipfs/go-ipfs/repo/fsrepo/serialize"
21 -
22 - manet "gx/ipfs/QmQB7mNP3QE7b4zP2MQmsyJDqG5hzYE2CL8k1VyLWky2Ed/go-multiaddr-net"
23 - ma "gx/ipfs/QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz/go-multiaddr"
11 + cli "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codegangsta/cli"
12 + util "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/iptb/util"
13 )
14
26 -var setupOpt = func(cmd *exec.Cmd) {}
27 -
28 -// GetNumNodes returns the number of testbed nodes configured in the testbed directory
29 -func GetNumNodes() int {
30 - for i := 0; i < 2000; i++ {
31 - _, err := os.Stat(IpfsDirN(i))
32 - if os.IsNotExist(err) {
33 - return i
34 - }
35 - }
36 - panic("i dont know whats going on")
37 -}
38 -
39 -func TestBedDir() string {
40 - tbd := os.Getenv("IPTB_ROOT")
41 - if len(tbd) != 0 {
42 - return tbd
43 - }
44 -
45 - home := os.Getenv("HOME")
46 - if len(home) == 0 {
47 - panic("could not find home")
48 - }
49 -
50 - return path.Join(home, "testbed")
51 -}
52 -
53 -func IpfsDirN(n int) string {
54 - return path.Join(TestBedDir(), fmt.Sprint(n))
55 -}
56 -
57 -func YesNoPrompt(prompt string) bool {
58 - var s string
59 - for {
60 - fmt.Println(prompt)
61 - fmt.Scanf("%s", &s)
62 - switch s {
63 - case "y", "Y":
64 - return true
65 - case "n", "N":
66 - return false
67 - }
68 - fmt.Println("Please press either 'y' or 'n'")
69 - }
70 -}
71 -
72 -type initCfg struct {
73 - Count int
74 - Force bool
75 - Bootstrap string
76 - PortStart int
77 - Mdns bool
78 - Utp bool
79 -}
80 -
81 -func (c *initCfg) swarmAddrForPeer(i int) string {
82 - str := "/ip4/0.0.0.0/tcp/%d"
83 - if c.Utp {
84 - str = "/ip4/0.0.0.0/udp/%d/utp"
85 - }
86 -
87 - if c.PortStart == 0 {
88 - return fmt.Sprintf(str, 0)
89 - }
90 - return fmt.Sprintf(str, c.PortStart+i)
91 -}
92 -
93 -func (c *initCfg) apiAddrForPeer(i int) string {
94 - if c.PortStart == 0 {
95 - return "/ip4/127.0.0.1/tcp/0"
96 - }
97 - return fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", c.PortStart+1000+i)
98 -}
99 -
100 -func IpfsInit(cfg *initCfg) error {
101 - p := IpfsDirN(0)
102 - if _, err := os.Stat(p); !os.IsNotExist(err) {
103 - if !cfg.Force && !YesNoPrompt("testbed nodes already exist, overwrite? [y/n]") {
104 - return nil
105 - }
106 - err := os.RemoveAll(TestBedDir())
107 - if err != nil {
108 - return err
109 - }
110 - }
111 - wait := sync.WaitGroup{}
112 - for i := 0; i < cfg.Count; i++ {
113 - wait.Add(1)
114 - go func(v int) {
115 - defer wait.Done()
116 - dir := IpfsDirN(v)
117 - err := os.MkdirAll(dir, 0777)
118 - if err != nil {
119 - log.Println("ERROR: ", err)
120 - return
121 - }
122 -
123 - cmd := exec.Command("ipfs", "init", "-b=1024")
124 - cmd.Env = append(cmd.Env, "IPFS_PATH="+dir)
125 - out, err := cmd.CombinedOutput()
126 - if err != nil {
127 - log.Println("ERROR: ", err)
128 - log.Println(string(out))
129 - }
130 - }(i)
131 - }
132 - wait.Wait()
133 -
134 - // Now setup bootstrapping
135 - switch cfg.Bootstrap {
136 - case "star":
137 - err := starBootstrap(cfg)
138 - if err != nil {
139 - return err
140 - }
141 - case "none":
142 - err := clearBootstrapping(cfg)
143 - if err != nil {
144 - return err
145 - }
146 - default:
147 - return fmt.Errorf("unrecognized bootstrapping option: %s", cfg.Bootstrap)
148 - }
149 -
150 - return nil
151 -}
152 -
153 -func starBootstrap(icfg *initCfg) error {
154 - // '0' node is the bootstrap node
155 - cfgpath := path.Join(IpfsDirN(0), "config")
156 - bcfg, err := serial.Load(cfgpath)
157 - if err != nil {
158 - return err
159 - }
160 - bcfg.Bootstrap = nil
161 - bcfg.Addresses.Swarm = []string{icfg.swarmAddrForPeer(0)}
162 - bcfg.Addresses.API = icfg.apiAddrForPeer(0)
163 - bcfg.Addresses.Gateway = ""
164 - bcfg.Discovery.MDNS.Enabled = icfg.Mdns
165 - err = serial.WriteConfigFile(cfgpath, bcfg)
166 - if err != nil {
167 - return err
168 - }
169 -
170 - for i := 1; i < icfg.Count; i++ {
171 - cfgpath := path.Join(IpfsDirN(i), "config")
172 - cfg, err := serial.Load(cfgpath)
173 - if err != nil {
174 - return err
175 - }
176 -
177 - ba := fmt.Sprintf("%s/ipfs/%s", bcfg.Addresses.Swarm[0], bcfg.Identity.PeerID)
178 - ba = strings.Replace(ba, "0.0.0.0", "127.0.0.1", -1)
179 - cfg.Bootstrap = []string{ba}
180 - cfg.Addresses.Gateway = ""
181 - cfg.Discovery.MDNS.Enabled = icfg.Mdns
182 - cfg.Addresses.Swarm = []string{
183 - icfg.swarmAddrForPeer(i),
184 - }
185 - cfg.Addresses.API = icfg.apiAddrForPeer(i)
186 - err = serial.WriteConfigFile(cfgpath, cfg)
187 - if err != nil {
188 - return err
189 - }
190 - }
191 - return nil
192 -}
193 -
194 -func clearBootstrapping(icfg *initCfg) error {
195 - for i := 0; i < icfg.Count; i++ {
196 - cfgpath := path.Join(IpfsDirN(i), "config")
197 - cfg, err := serial.Load(cfgpath)
198 - if err != nil {
199 - return err
200 - }
201 -
202 - cfg.Bootstrap = nil
203 - cfg.Addresses.Gateway = ""
204 - cfg.Addresses.Swarm = []string{icfg.swarmAddrForPeer(i)}
205 - cfg.Addresses.API = icfg.apiAddrForPeer(i)
206 - cfg.Discovery.MDNS.Enabled = icfg.Mdns
207 - err = serial.WriteConfigFile(cfgpath, cfg)
208 - if err != nil {
209 - return err
210 - }
211 - }
212 - return nil
213 -}
214 -
215 -func IpfsPidOf(n int) (int, error) {
216 - dir := IpfsDirN(n)
217 - b, err := ioutil.ReadFile(path.Join(dir, "daemon.pid"))
218 - if err != nil {
219 - return -1, err
220 - }
221 -
222 - return strconv.Atoi(string(b))
223 -}
224 -
225 -func KillNode(i int) error {
226 - pid, err := IpfsPidOf(i)
227 - if err != nil {
228 - return fmt.Errorf("error killing daemon %d: %s", i, err)
229 - }
230 -
231 - p, err := os.FindProcess(pid)
232 - if err != nil {
233 - return fmt.Errorf("error killing daemon %d: %s", i, err)
234 - }
235 - err = p.Kill()
236 - if err != nil {
237 - return fmt.Errorf("error killing daemon %d: %s\n", i, err)
238 - }
239 -
240 - p.Wait()
241 -
242 - err = os.Remove(path.Join(IpfsDirN(i), "daemon.pid"))
243 - if err != nil {
244 - return fmt.Errorf("error removing pid file for daemon %d: %s\n", i, err)
245 - }
246 -
247 - return nil
248 -}
249 -
250 -func IpfsKillAll() error {
251 - n := GetNumNodes()
252 - for i := 0; i < n; i++ {
253 - err := KillNode(i)
254 - if err != nil {
255 - return err
256 - }
257 - }
258 - return nil
259 -}
260 -
261 -func envForDaemon(n int) []string {
262 - envs := os.Environ()
263 - npath := "IPFS_PATH=" + IpfsDirN(n)
264 - for i, e := range envs {
265 - p := strings.Split(e, "=")
266 - if p[0] == "IPFS_PATH" {
267 - envs[i] = npath
268 - return envs
269 - }
270 - }
271 -
272 - return append(envs, npath)
273 -}
274 -
275 -func IpfsStart(waitall bool) error {
276 - var addrs []string
277 - n := GetNumNodes()
278 - for i := 0; i < n; i++ {
279 - dir := IpfsDirN(i)
280 - cmd := exec.Command("ipfs", "daemon")
281 - cmd.Dir = dir
282 - cmd.Env = envForDaemon(i)
283 -
284 - setupOpt(cmd)
285 -
286 - stdout, err := os.Create(path.Join(dir, "daemon.stdout"))
287 - if err != nil {
288 - return err
289 - }
290 -
291 - stderr, err := os.Create(path.Join(dir, "daemon.stderr"))
292 - if err != nil {
293 - return err
294 - }
295 -
296 - cmd.Stdout = stdout
297 - cmd.Stderr = stderr
298 -
299 - err = cmd.Start()
300 - if err != nil {
301 - return err
302 - }
303 - pid := cmd.Process.Pid
304 -
305 - fmt.Printf("Started daemon %d, pid = %d\n", i, pid)
306 - err = ioutil.WriteFile(path.Join(dir, "daemon.pid"), []byte(fmt.Sprint(pid)), 0666)
307 - if err != nil {
308 - return err
309 - }
310 -
311 - // Make sure node 0 is up before starting the rest so
312 - // bootstrapping works properly
313 - cfg, err := serial.Load(path.Join(IpfsDirN(i), "config"))
314 - if err != nil {
315 - return err
316 - }
317 -
318 - maddr := ma.StringCast(cfg.Addresses.API)
319 - _, addr, err := manet.DialArgs(maddr)
320 - if err != nil {
321 - return err
322 - }
323 -
324 - addrs = append(addrs, addr)
325 -
326 - err = waitOnAPI(cfg.Identity.PeerID, i)
327 - if err != nil {
328 - return err
329 - }
330 - }
331 - if waitall {
332 - for i := 0; i < n; i++ {
333 - err := waitOnSwarmPeers(i)
334 - if err != nil {
335 - return err
336 - }
337 - }
338 -
339 - }
340 - return nil
341 -}
342 -
343 -func waitOnAPI(peerid string, nnum int) error {
344 - for i := 0; i < 50; i++ {
345 - err := tryAPICheck(peerid, nnum)
346 - if err == nil {
347 - return nil
348 - }
349 - time.Sleep(time.Millisecond * 200)
350 - }
351 - return fmt.Errorf("node %d failed to come online in given time period", nnum)
352 -}
353 -
354 -func getNodesAPIAddr(nnum int) (string, error) {
355 - addrb, err := ioutil.ReadFile(path.Join(IpfsDirN(nnum), "api"))
356 - if err != nil {
357 - return "", err
358 - }
359 -
360 - maddr, err := ma.NewMultiaddr(string(addrb))
361 - if err != nil {
362 - fmt.Println("error parsing multiaddr: ", err)
363 - return "", err
364 - }
365 -
366 - _, addr, err := manet.DialArgs(maddr)
367 - if err != nil {
368 - fmt.Println("error on multiaddr dialargs: ", err)
369 - return "", err
370 - }
371 - return addr, nil
372 -}
373 -
374 -func tryAPICheck(peerid string, nnum int) error {
375 - addr, err := getNodesAPIAddr(nnum)
376 - if err != nil {
377 - return err
378 - }
379 -
380 - resp, err := http.Get("http://" + addr + "/api/v0/id")
381 - if err != nil {
382 - return err
383 - }
384 -
385 - out := make(map[string]interface{})
386 - err = json.NewDecoder(resp.Body).Decode(&out)
387 - if err != nil {
388 - return fmt.Errorf("liveness check failed: %s", err)
389 - }
390 -
391 - id, ok := out["ID"]
392 - if !ok {
393 - return fmt.Errorf("liveness check failed: ID field not present in output")
394 - }
395 -
396 - idstr := id.(string)
397 - if idstr != peerid {
398 - return fmt.Errorf("liveness check failed: unexpected peer at endpoint")
399 - }
400 -
401 - return nil
402 -}
403 -
404 -func waitOnSwarmPeers(nnum int) error {
405 - addr, err := getNodesAPIAddr(nnum)
406 - if err != nil {
407 - return err
408 - }
409 -
410 - for i := 0; i < 50; i++ {
411 - resp, err := http.Get("http://" + addr + "/api/v0/swarm/peers")
412 - if err == nil {
413 - out := make(map[string]interface{})
414 - err := json.NewDecoder(resp.Body).Decode(&out)
415 - if err != nil {
416 - return fmt.Errorf("liveness check failed: %s", err)
417 - }
418 -
419 - peers := out["Strings"].([]interface{})
420 - if len(peers) == 0 {
421 - time.Sleep(time.Millisecond * 200)
422 - continue
423 - }
424 -
425 - return nil
426 - }
427 - time.Sleep(time.Millisecond * 200)
428 - }
429 - return fmt.Errorf("node at %s failed to bootstrap in given time period", addr)
430 -}
431 -
432 -// GetPeerID reads the config of node 'n' and returns its peer ID
433 -func GetPeerID(n int) (string, error) {
434 - cfg, err := serial.Load(path.Join(IpfsDirN(n), "config"))
435 - if err != nil {
436 - return "", err
437 - }
438 - return cfg.Identity.PeerID, nil
439 -}
440 -
441 -// IpfsShell sets up environment variables for a new shell to more easily
442 -// control the given daemon
443 -func IpfsShell(n int) error {
444 - shell := os.Getenv("SHELL")
445 - if shell == "" {
446 - return fmt.Errorf("couldnt find shell!")
447 - }
448 -
449 - dir := IpfsDirN(n)
450 - nenvs := []string{"IPFS_PATH=" + dir}
451 -
452 - nnodes := GetNumNodes()
453 - for i := 0; i < nnodes; i++ {
454 - peerid, err := GetPeerID(i)
455 - if err != nil {
456 - return err
457 - }
458 - nenvs = append(nenvs, fmt.Sprintf("NODE%d=%s", i, peerid))
459 - }
460 - nenvs = append(os.Environ(), nenvs...)
461 -
462 - return syscall.Exec(shell, []string{shell}, nenvs)
463 -}
464 -
465 -func ConnectNodes(from, to int) error {
466 - if from == to {
467 - // skip connecting to self..
468 - return nil
469 - }
470 - fmt.Printf("connecting %d -> %d\n", from, to)
471 - cmd := exec.Command("ipfs", "id", "-f", "<addrs>")
472 - cmd.Env = []string{"IPFS_PATH=" + IpfsDirN(to)}
473 - out, err := cmd.Output()
474 - if err != nil {
475 - fmt.Println("ERR: ", string(out))
476 - return err
477 - }
478 - addr := strings.Split(string(out), "\n")[0]
479 -
480 - connectcmd := exec.Command("ipfs", "swarm", "connect", addr)
481 - connectcmd.Env = []string{"IPFS_PATH=" + IpfsDirN(from)}
482 - out, err = connectcmd.CombinedOutput()
483 - if err != nil {
484 - fmt.Println(string(out))
485 - return err
486 - }
487 - return nil
488 -}
489 -
15 func parseRange(s string) ([]int, error) {
16 if strings.HasPrefix(s, "[") && strings.HasSuffix(s, "]") {
17 ranges := strings.Split(s[1:len(s)-1], ",")
@@ -536,52 +61,6 @@ func expandDashRange(s string) ([]int, error) {
61 return out, nil
62 }
63
539 -func GetAttr(attr string, node int) (string, error) {
540 - switch attr {
541 - case "id":
542 - return GetPeerID(node)
543 - default:
544 - return "", errors.New("unrecognized attribute")
545 - }
546 -}
547 -
548 -var helptext = `Ipfs Testbed
549 -
550 -Commands:
551 - init
552 - creates and initializes 'n' repos
553 -
554 - Options:
555 - -n=[number of nodes]
556 - -f - force overwriting of existing nodes
557 - -bootstrap - select bootstrapping style for cluster
558 - choices: star, none
559 -
560 - start
561 - starts up all testbed nodes
562 -
563 - Options:
564 - -wait - wait until daemons are fully initialized
565 - stop
566 - kills all testbed nodes
567 - restart
568 - kills, then restarts all testbed nodes
569 -
570 - shell [n]
571 - execs your shell with environment variables set as follows:
572 - IPFS_PATH - set to testbed node n's IPFS_PATH
573 - NODE[x] - set to the peer ID of node x
574 -
575 - get [attribute] [node]
576 - get an attribute of the given node
577 - currently supports: "id"
578 -
579 -Env Vars:
580 -
581 -IPTB_ROOT:
582 - Used to specify the directory that nodes will be created in.
583 -`
584 -
64 func handleErr(s string, err error) {
65 if err != nil {
66 fmt.Fprintln(os.Stderr, s, err)
@@ -590,80 +69,171 @@ func handleErr(s string, err error) {
69 }
70
71 func main() {
593 - cfg := new(initCfg)
594 - kingpin.Flag("n", "number of ipfs nodes to initialize").Short('n').IntVar(&cfg.Count)
595 - kingpin.Flag("port", "port to start allocations from").Default("4002").Short('p').IntVar(&cfg.PortStart)
596 - kingpin.Flag("force", "force initialization (overwrite existing configs)").Short('f').BoolVar(&cfg.Force)
597 - kingpin.Flag("mdns", "turn on mdns for nodes").BoolVar(&cfg.Mdns)
598 - kingpin.Flag("bootstrap", "select bootstrapping style for cluster").Default("star").StringVar(&cfg.Bootstrap)
599 - kingpin.Flag("utp", "use utp for addresses").BoolVar(&cfg.Utp)
600 -
601 - wait := kingpin.Flag("wait", "wait for nodes to come fully online before exiting").Bool()
602 -
603 - var args []string
604 - kingpin.Arg("args", "arguments").StringsVar(&args)
605 - kingpin.Parse()
606 -
607 - if len(args) == 0 {
608 - kingpin.Usage()
609 - return
72 + app := cli.NewApp()
73 + app.Commands = []cli.Command{
74 + initCmd,
75 + startCmd,
76 + killCmd,
77 + restartCmd,
78 + shellCmd,
79 + getCmd,
80 + connectCmd,
81 + dumpStacksCmd,
82 + }
83 +
84 + err := app.Run(os.Args)
85 + if err != nil {
86 + fmt.Println(err)
87 + os.Exit(1)
88 }
89 +}
90
612 - switch args[0] {
613 - case "init":
614 - if cfg.Count == 0 {
91 +var initCmd = cli.Command{
92 + Name: "init",
93 + Usage: "create and initialize testbed nodes",
94 + Flags: []cli.Flag{
95 + cli.IntFlag{
96 + Name: "count, n",
97 + Usage: "number of ipfs nodes to initialize",
98 + },
99 + cli.IntFlag{
100 + Name: "port, p",
101 + Usage: "port to start allocations from",
102 + },
103 + cli.BoolFlag{
104 + Name: "force, f",
105 + Usage: "force initialization (overwrite existing configs)",
106 + },
107 + cli.BoolFlag{
108 + Name: "mdns",
109 + Usage: "turn on mdns for nodes",
110 + },
111 + cli.StringFlag{
112 + Name: "bootstrap",
113 + Usage: "select bootstrapping style for cluster",
114 + Value: "star",
115 + },
116 + cli.BoolFlag{
117 + Name: "utp",
118 + Usage: "use utp for addresses",
119 + },
120 + cli.StringFlag{
121 + Name: "cfg",
122 + Usage: "override default config with values from the given file",
123 + },
124 + },
125 + Action: func(c *cli.Context) {
126 + if c.Int("count") == 0 {
127 fmt.Printf("please specify number of nodes: '%s init -n 10'\n", os.Args[0])
128 os.Exit(1)
129 }
618 - err := IpfsInit(cfg)
130 + cfg := &util.InitCfg{
131 + Bootstrap: c.String("bootstrap"),
132 + Force: c.Bool("f"),
133 + Count: c.Int("count"),
134 + Mdns: c.Bool("mdns"),
135 + Utp: c.Bool("utp"),
136 + PortStart: c.Int("port"),
137 + Override: c.String("cfg"),
138 + }
139 +
140 + err := util.IpfsInit(cfg)
141 handleErr("ipfs init err: ", err)
620 - case "start":
621 - err := IpfsStart(*wait)
142 + },
143 +}
144 +
145 +var startCmd = cli.Command{
146 + Name: "start",
147 + Usage: "starts up all testbed nodes",
148 + Flags: []cli.Flag{
149 + cli.BoolFlag{
150 + Name: "wait",
151 + Usage: "wait for nodes to fully come online before returning",
152 + },
153 + },
154 + Action: func(c *cli.Context) {
155 + err := util.IpfsStart(c.Bool("wait"))
156 handleErr("ipfs start err: ", err)
623 - case "stop", "kill":
624 - if len(args) > 1 {
625 - i, err := strconv.Atoi(args[1])
157 + },
158 +}
159 +
160 +var killCmd = cli.Command{
161 + Name: "kill",
162 + Usage: "kill a given node (or all nodes if none specified)",
163 + Aliases: []string{"stop"},
164 + Action: func(c *cli.Context) {
165 + if c.Args().Present() {
166 + i, err := strconv.Atoi(c.Args()[0])
167 if err != nil {
168 fmt.Println("failed to parse node number: ", err)
169 os.Exit(1)
170 }
630 - err = KillNode(i)
171 + err = util.KillNode(i)
172 if err != nil {
173 fmt.Println("failed to kill node: ", err)
174 }
175 return
176 }
636 - err := IpfsKillAll()
177 + err := util.IpfsKillAll()
178 handleErr("ipfs kill err: ", err)
638 - case "restart":
639 - err := IpfsKillAll()
179 + },
180 +}
181 +
182 +var restartCmd = cli.Command{
183 + Name: "restart",
184 + Usage: "kill all nodes, then restart",
185 + Flags: []cli.Flag{
186 + cli.BoolFlag{
187 + Name: "wait",
188 + Usage: "wait for nodes to come online before returning",
189 + },
190 + },
191 + Action: func(c *cli.Context) {
192 + err := util.IpfsKillAll()
193 handleErr("ipfs kill err: ", err)
194
642 - err = IpfsStart(*wait)
195 + err = util.IpfsStart(c.Bool("wait"))
196 handleErr("ipfs start err: ", err)
644 - case "shell":
645 - if len(args) < 2 {
197 + },
198 +}
199 +
200 +var shellCmd = cli.Command{
201 + Name: "shell",
202 + Usage: "execs your shell with certain environment variables set",
203 + Description: `Starts a new shell and sets some environment variables for you:
204 +
205 +IPFS_PATH - set to testbed node 'n's IPFS_PATH
206 +NODE[x] - set to the peer ID of node x
207 +`,
208 + Action: func(c *cli.Context) {
209 + if !c.Args().Present() {
210 fmt.Println("please specify which node you want a shell for")
211 os.Exit(1)
212 }
649 - n, err := strconv.Atoi(args[1])
213 + n, err := strconv.Atoi(c.Args()[0])
214 handleErr("parse err: ", err)
215
652 - err = IpfsShell(n)
216 + err = util.IpfsShell(n)
217 handleErr("ipfs shell err: ", err)
654 - case "connect":
655 - if len(args) < 3 {
218 + },
219 +}
220 +
221 +var connectCmd = cli.Command{
222 + Name: "connect",
223 + Usage: "connect two nodes together",
224 + Action: func(c *cli.Context) {
225 + if len(c.Args()) < 2 {
226 fmt.Println("iptb connect [node] [node]")
227 os.Exit(1)
228 }
229
660 - from, err := parseRange(args[1])
230 + from, err := parseRange(c.Args()[0])
231 if err != nil {
232 fmt.Printf("failed to parse: %s\n", err)
233 return
234 }
235
666 - to, err := parseRange(args[2])
236 + to, err := parseRange(c.Args()[1])
237 if err != nil {
238 fmt.Printf("failed to parse: %s\n", err)
239 return
@@ -671,29 +241,53 @@ func main() {
241
242 for _, f := range from {
243 for _, t := range to {
674 - err = ConnectNodes(f, t)
244 + err = util.ConnectNodes(f, t)
245 if err != nil {
246 fmt.Printf("failed to connect: %s\n", err)
247 return
248 }
249 }
250 }
251 + },
252 +}
253
682 - case "get":
683 - if len(args) < 3 {
254 +var getCmd = cli.Command{
255 + Name: "get",
256 + Usage: "get an attribute of the given node",
257 + Action: func(c *cli.Context) {
258 + if len(c.Args()) < 2 {
259 fmt.Println("iptb get [attr] [node]")
260 os.Exit(1)
261 }
687 - attr := args[1]
688 - num, err := strconv.Atoi(args[2])
262 + attr := c.Args().First()
263 + num, err := strconv.Atoi(c.Args()[1])
264 handleErr("error parsing node number: ", err)
265
691 - val, err := GetAttr(attr, num)
266 + val, err := util.GetAttr(attr, num)
267 handleErr("error getting attribute: ", err)
268 fmt.Println(val)
694 - default:
695 - kingpin.Usage()
696 - fmt.Println(helptext)
697 - os.Exit(1)
698 - }
269 + },
270 +}
271 +
272 +var dumpStacksCmd = cli.Command{
273 + Name: "dump-stack",
274 + Usage: "get a stack dump from the given daemon",
275 + Action: func(c *cli.Context) {
276 + if len(c.Args()) < 1 {
277 + fmt.Println("iptb dump-stack [node]")
278 + os.Exit(1)
279 + }
280 +
281 + num, err := strconv.Atoi(c.Args()[0])
282 + handleErr("error parsing node number: ", err)
283 +
284 + addr, err := util.GetNodesAPIAddr(num)
285 + handleErr("failed to get api addr: ", err)
286 +
287 + resp, err := http.Get("http://" + addr + "/debug/pprof/goroutine?debug=2")
288 + handleErr("GET stack dump failed: ", err)
289 + defer resp.Body.Close()
290 +
291 + io.Copy(os.Stdout, resp.Body)
292 + },
293 }
test/sharness/t0240-republisher.sh
+1 -1
@@ -15,7 +15,7 @@ setup_iptb() {
15 bound=$(expr "$num_nodes" - 1)
16
17 test_expect_success "iptb init" '
18 - iptb init -n$num_nodes --bootstrap none --port 0
18 + iptb init -n $num_nodes --bootstrap none --port 0
19 '
20
21 for i in $(test_seq 0 "$bound")
thirdparty/s3-datastore/datastore.go deleted
-78
@@ -1,78 +0,0 @@
1 -package s3datastore
2 -
3 -import (
4 - "encoding/hex"
5 - "errors"
6 -
7 - "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/crowdmob/goamz/s3"
8 - datastore "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore"
9 - query "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/ipfs/go-datastore/query"
10 -)
11 -
12 -var _ datastore.ThreadSafeDatastore = &S3Datastore{}
13 -
14 -var errTODO = errors.New("TODO")
15 -
16 -var ErrInvalidType = errors.New("s3 datastore: invalid type error")
17 -
18 -type S3Datastore struct {
19 - Client *s3.S3
20 - Bucket string
21 - ACL s3.ACL
22 -}
23 -
24 -func (ds *S3Datastore) encode(key datastore.Key) string {
25 - return hex.EncodeToString(key.Bytes())
26 -}
27 -
28 -func (ds *S3Datastore) decode(raw string) (datastore.Key, bool) {
29 - k, err := hex.DecodeString(raw)
30 - if err != nil {
31 - return datastore.Key{}, false
32 - }
33 - return datastore.NewKey(string(k)), true
34 -}
35 -
36 -func (ds *S3Datastore) Put(key datastore.Key, value interface{}) (err error) {
37 - data, ok := value.([]byte)
38 - if !ok {
39 - return ErrInvalidType
40 - }
41 - // TODO extract s3 options
42 -
43 - k := ds.encode(key)
44 - acl := ds.ACL
45 - if acl == "" {
46 - acl = s3.Private
47 - }
48 - return ds.Client.Bucket(ds.Bucket).Put(k, data, "application/protobuf", acl, s3.Options{})
49 -}
50 -
51 -func (ds *S3Datastore) Get(key datastore.Key) (value interface{}, err error) {
52 - k := ds.encode(key)
53 - return ds.Client.Bucket(ds.Bucket).Get(k)
54 -}
55 -
56 -func (ds *S3Datastore) Has(key datastore.Key) (exists bool, err error) {
57 - k := ds.encode(key)
58 - return ds.Client.Bucket(ds.Bucket).Exists(k)
59 -}
60 -
61 -func (ds *S3Datastore) Delete(key datastore.Key) (err error) {
62 - k := ds.encode(key)
63 - return ds.Client.Bucket(ds.Bucket).Del(k)
64 -}
65 -
66 -func (ds *S3Datastore) Query(q query.Query) (query.Results, error) {
67 - return nil, errors.New("TODO implement query for s3 datastore?")
68 -}
69 -
70 -func (ds *S3Datastore) Close() error {
71 - return nil
72 -}
73 -
74 -func (ds *S3Datastore) Batch() (datastore.Batch, error) {
75 - return datastore.NewBasicBatch(ds), nil
76 -}
77 -
78 -func (ds *S3Datastore) IsThreadSafe() {}