diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a186a0e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin/gx* +*.swp diff --git a/.travis.yml b/.travis.yml index 7725b30..b8ab51b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,20 @@ +os: + - linux + - osx + language: go +sudo: false + go: - - 1.3 - - release - - tip + - 1.5.3 + +install: + - make deps script: - make test -env: TEST_VERBOSE=1 +cache: + directories: + - $GOPATH/src/gx diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json deleted file mode 100644 index 9cbebc8..0000000 --- a/Godeps/Godeps.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "ImportPath": "github.com/jbenet/go-multiaddr-net", - "GoVersion": "go1.4.2", - "Packages": [ - "./..." - ], - "Deps": [ - { - "ImportPath": "github.com/anacrolix/jitter", - "Rev": "2ea5c18645100745b24e9f5cfc9b3f6f7eac51ef" - }, - { - "ImportPath": "github.com/anacrolix/missinggo", - "Rev": "4e1ca5963308863b56c31863f60c394a7365ec29" - }, - { - "ImportPath": "github.com/anacrolix/utp", - "Rev": "0bb24de92c268452fb9106ca4fb9302442ca0dee" - }, - { - "ImportPath": "github.com/bradfitz/iter", - "Rev": "454541ec3da2a73fc34fd049b19ee5777bf19345" - }, - { - "ImportPath": "github.com/jbenet/go-base58", - "Rev": "568a28d73fd97651d3442392036a658b6976eed5" - }, - { - "ImportPath": "github.com/jbenet/go-multiaddr", - "Comment": "0.1.2-38-gc13f11b", - "Rev": "c13f11bbfe6439771f4df7bfb330f686826144e8" - }, - { - "ImportPath": "github.com/jbenet/go-multihash", - "Comment": "0.1.0-36-g87e53a9", - "Rev": "87e53a9d2875a18a7863b351d22f912545e6b3a3" - }, - { - "ImportPath": "golang.org/x/crypto/sha3", - "Rev": "1351f936d976c60a0a48d728281922cf63eafb8d" - } - ] -} diff --git a/Godeps/Readme b/Godeps/Readme deleted file mode 100644 index 4cdaa53..0000000 --- a/Godeps/Readme +++ /dev/null @@ -1,5 +0,0 @@ -This directory tree is generated automatically by godep. - -Please do not edit. - -See https://github.com/tools/godep for more information. diff --git a/Godeps/_workspace/.gitignore b/Godeps/_workspace/.gitignore deleted file mode 100644 index f037d68..0000000 --- a/Godeps/_workspace/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/pkg -/bin diff --git a/Godeps/_workspace/src/github.com/anacrolix/jitter/jitter.go b/Godeps/_workspace/src/github.com/anacrolix/jitter/jitter.go deleted file mode 100644 index 7f0f39b..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/jitter/jitter.go +++ /dev/null @@ -1,12 +0,0 @@ -package jitter - -import ( - "math/rand" - "time" -) - -func Duration(average, plusMinus time.Duration) (ret time.Duration) { - ret = average - plusMinus - ret += time.Duration(rand.Int63n(2*int64(plusMinus) + 1)) - return -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/addr.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/addr.go deleted file mode 100644 index 7d7a4f8..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/addr.go +++ /dev/null @@ -1,72 +0,0 @@ -package missinggo - -import ( - "net" - "strconv" - "strings" -) - -type HostMaybePort struct { - Host string - Port int - NoPort bool -} - -func (me HostMaybePort) String() string { - if me.NoPort { - return me.Host - } - return net.JoinHostPort(me.Host, strconv.FormatInt(int64(me.Port), 10)) -} - -func SplitHostPort(hostport string) (ret HostMaybePort) { - host, port, err := net.SplitHostPort(hostport) - if err != nil { - if strings.Contains(err.Error(), "missing port") { - ret.Host = hostport - ret.NoPort = true - return - } - panic(err) - } - i64, err := strconv.ParseInt(port, 0, 0) - ret.Host = host - ret.Port = int(i64) - if err != nil { - ret.NoPort = true - } - return -} - -// Extracts the port as an integer from an address string. -func AddrPort(addr net.Addr) int { - switch raw := addr.(type) { - case *net.UDPAddr: - return raw.Port - default: - _, port, err := net.SplitHostPort(addr.String()) - if err != nil { - panic(err) - } - i64, err := strconv.ParseInt(port, 0, 0) - if err != nil { - panic(err) - } - return int(i64) - } -} - -func AddrIP(addr net.Addr) net.IP { - switch raw := addr.(type) { - case *net.UDPAddr: - return raw.IP - case *net.TCPAddr: - return raw.IP - default: - host, _, err := net.SplitHostPort(addr.String()) - if err != nil { - panic(err) - } - return net.ParseIP(host) - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/addr_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/addr_test.go deleted file mode 100644 index 96ffee0..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/addr_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package missinggo - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestSplitHostPort(t *testing.T) { - assert.EqualValues(t, HostMaybePort{"a", 1, false}, SplitHostPort("a:1")) - assert.EqualValues(t, HostMaybePort{"a", 0, true}, SplitHostPort("a")) -} - -func TestHostMaybePortString(t *testing.T) { - assert.EqualValues(t, "a:1", (HostMaybePort{"a", 1, false}).String()) - assert.EqualValues(t, "a", (HostMaybePort{"a", 0, true}).String()) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/args/args.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/args/args.go deleted file mode 100644 index 8f0d614..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/args/args.go +++ /dev/null @@ -1,15 +0,0 @@ -package args - -import ( - "flag" - "fmt" - "os" -) - -func Parse() { - flag.Parse() - if flag.NArg() != 0 { - fmt.Fprintf(os.Stderr, "unexpected positional arguments\n") - os.Exit(2) - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime.go deleted file mode 100644 index 41ede58..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime.go +++ /dev/null @@ -1,11 +0,0 @@ -package missinggo - -import ( - "os" - "time" -) - -// Extracts the access time from the FileInfo internals. -func FileInfoAccessTime(fi os.FileInfo) time.Time { - return fileInfoAccessTime(fi) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_darwin.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_darwin.go deleted file mode 100644 index 5ccbc43..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_darwin.go +++ /dev/null @@ -1,12 +0,0 @@ -package missinggo - -import ( - "os" - "syscall" - "time" -) - -func fileInfoAccessTime(fi os.FileInfo) time.Time { - ts := fi.Sys().(*syscall.Stat_t).Atimespec - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_freebsd.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_freebsd.go deleted file mode 100644 index 5ccbc43..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_freebsd.go +++ /dev/null @@ -1,12 +0,0 @@ -package missinggo - -import ( - "os" - "syscall" - "time" -) - -func fileInfoAccessTime(fi os.FileInfo) time.Time { - ts := fi.Sys().(*syscall.Stat_t).Atimespec - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_linux.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_linux.go deleted file mode 100644 index e599d8b..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_linux.go +++ /dev/null @@ -1,12 +0,0 @@ -package missinggo - -import ( - "os" - "syscall" - "time" -) - -func fileInfoAccessTime(fi os.FileInfo) time.Time { - ts := fi.Sys().(*syscall.Stat_t).Atim - return time.Unix(int64(ts.Sec), int64(ts.Nsec)) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_windows.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_windows.go deleted file mode 100644 index bedf8c3..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime_windows.go +++ /dev/null @@ -1,12 +0,0 @@ -package missinggo - -import ( - "os" - "syscall" - "time" -) - -func fileInfoAccessTime(fi os.FileInfo) time.Time { - ts := fi.Sys().(syscall.Win32FileAttributeData).LastAccessTime - return time.Unix(0, int64(ts.Nanoseconds())) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/castslice.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/castslice.go deleted file mode 100644 index 5370c3e..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/castslice.go +++ /dev/null @@ -1,17 +0,0 @@ -package missinggo - -import ( - "reflect" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/bradfitz/iter" -) - -func ConvertToSliceOfEmptyInterface(slice interface{}) (ret []interface{}) { - v := reflect.ValueOf(slice) - l := v.Len() - ret = make([]interface{}, 0, l) - for i := range iter.N(v.Len()) { - ret = append(ret, v.Index(i).Interface()) - } - return -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/go-env/main.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/go-env/main.go deleted file mode 100644 index 66a736e..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/go-env/main.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import ( - "fmt" - "os" -) - -func main() { - for _, v := range os.Environ() { - fmt.Printf("%s\n", v) - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/nop/main.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/nop/main.go deleted file mode 100644 index 38dd16d..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/nop/main.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -func main() {} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-escape/main.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-escape/main.go deleted file mode 100644 index cddd9d9..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-escape/main.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -import ( - "fmt" - "net/url" - "os" -) - -func main() { - fmt.Println(url.QueryEscape(os.Args[1])) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-unescape/main.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-unescape/main.go deleted file mode 100644 index 3099cc8..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/cmd/query-unescape/main.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -import ( - "fmt" - "net/url" - "os" -) - -func main() { - fmt.Println(url.QueryUnescape(os.Args[1])) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/copy.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/copy.go deleted file mode 100644 index 79aa58f..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/copy.go +++ /dev/null @@ -1,32 +0,0 @@ -package missinggo - -import ( - "fmt" - "reflect" -) - -func CopyExact(dest interface{}, src interface{}) { - dV := reflect.ValueOf(dest) - sV := reflect.ValueOf(src) - if dV.Kind() == reflect.Ptr { - dV = dV.Elem() - } - if dV.Kind() == reflect.Array && !dV.CanAddr() { - panic(fmt.Sprintf("dest not addressable: %T", dest)) - } - if sV.Kind() == reflect.Ptr { - sV = sV.Elem() - } - if sV.Kind() == reflect.String { - sV = sV.Convert(reflect.SliceOf(dV.Type().Elem())) - } - if !sV.IsValid() { - panic("invalid source, probably nil") - } - if dV.Len() != sV.Len() { - panic(fmt.Sprintf("dest len (%d) != src len (%d)", dV.Len(), sV.Len())) - } - if dV.Len() != reflect.Copy(dV, sV) { - panic("dammit") - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/copy_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/copy_test.go deleted file mode 100644 index 190f2a1..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/copy_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package missinggo - -import ( - "bytes" - "strings" - "testing" -) - -func TestCopyToArray(t *testing.T) { - var arr [3]byte - bb := []byte{1, 2, 3} - CopyExact(&arr, bb) - if !bytes.Equal(arr[:], bb) { - t.FailNow() - } -} - -func TestCopyToSlicedArray(t *testing.T) { - var arr [5]byte - CopyExact(arr[:], "hello") - if !bytes.Equal(arr[:], []byte("hello")) { - t.FailNow() - } -} - -func TestCopyDestNotAddr(t *testing.T) { - defer func() { - r := recover() - if r == nil { - t.FailNow() - } - t.Log(r) - }() - var arr [3]byte - CopyExact(arr, "nope") -} - -func TestCopyLenMismatch(t *testing.T) { - defer func() { - r := recover() - if r == nil { - t.FailNow() - } - t.Log(r) - }() - CopyExact(make([]byte, 2), "abc") -} - -func TestCopySrcString(t *testing.T) { - dest := make([]byte, 3) - CopyExact(dest, "lol") - if string(dest) != "lol" { - t.FailNow() - } - func() { - defer func() { - r := recover() - if r == nil { - t.FailNow() - } - }() - CopyExact(dest, "rofl") - }() - var arr [5]byte - CopyExact(&arr, interface{}("hello")) - if string(arr[:]) != "hello" { - t.FailNow() - } -} - -func TestCopySrcNilInterface(t *testing.T) { - var arr [3]byte - defer func() { - r := recover().(string) - if !strings.Contains(r, "invalid source") { - t.FailNow() - } - }() - CopyExact(&arr, nil) -} - -func TestCopySrcPtr(t *testing.T) { - var bigDst [1024]byte - var bigSrc [1024]byte = [1024]byte{'h', 'i'} - CopyExact(&bigDst, &bigSrc) - if !bytes.Equal(bigDst[:], bigSrc[:]) { - t.FailNow() - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/croak.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/croak.go deleted file mode 100644 index ded86ef..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/croak.go +++ /dev/null @@ -1,18 +0,0 @@ -package missinggo - -import ( - "fmt" - "os" -) - -func Unchomp(s string) string { - if len(s) > 0 && s[len(s)-1] == '\n' { - return s - } - return s + "\n" -} - -func Fatal(msg interface{}) { - os.Stderr.WriteString(Unchomp(fmt.Sprint(msg))) - os.Exit(1) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/doc.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/doc.go deleted file mode 100644 index 9b8aa8d..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package missinggo contains miscellaneous helpers used in many of anacrolix' -// projects. -package missinggo diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/expvarIndentMap.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/expvarIndentMap.go deleted file mode 100644 index c995299..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/expvarIndentMap.go +++ /dev/null @@ -1,35 +0,0 @@ -package missinggo - -import ( - "bytes" - "expvar" - "fmt" -) - -type IndentMap struct { - expvar.Map -} - -var _ expvar.Var = &IndentMap{} - -func NewExpvarIndentMap(name string) *IndentMap { - v := new(IndentMap) - v.Init() - expvar.Publish(name, v) - return v -} - -func (v *IndentMap) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "{") - first := true - v.Do(func(kv expvar.KeyValue) { - if !first { - fmt.Fprintf(&b, ",") - } - fmt.Fprintf(&b, "\n\t%q: %v", kv.Key, kv.Value) - first = false - }) - fmt.Fprintf(&b, "}") - return b.String() -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache.go deleted file mode 100644 index 43c95bd..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache.go +++ /dev/null @@ -1,269 +0,0 @@ -package filecache - -import ( - "errors" - "log" - "os" - "path" - "path/filepath" - "sync" - "time" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" -) - -type Cache struct { - mu sync.Mutex - capacity int64 - filled int64 - items *lruItems - paths map[string]ItemInfo - root string -} - -type CacheInfo struct { - Capacity int64 - Filled int64 - NumItems int -} - -type ItemInfo struct { - Accessed time.Time - Size int64 - Path string -} - -// Calls the function for every item known to the cache. The ItemInfo should -// not be modified. -func (me *Cache) WalkItems(cb func(ItemInfo)) { - me.mu.Lock() - defer me.mu.Unlock() - for e := me.items.Front(); e != nil; e = e.Next() { - cb(e.Value().(ItemInfo)) - } -} - -func (me *Cache) Info() (ret CacheInfo) { - me.mu.Lock() - defer me.mu.Unlock() - ret.Capacity = me.capacity - ret.Filled = me.filled - ret.NumItems = len(me.paths) - return -} - -func (me *Cache) SetCapacity(capacity int64) { - me.mu.Lock() - defer me.mu.Unlock() - me.capacity = capacity -} - -func NewCache(root string) (ret *Cache, err error) { - if !filepath.IsAbs(root) { - err = errors.New("root is not an absolute filepath") - return - } - ret = &Cache{ - root: root, - capacity: -1, // unlimited - } - ret.mu.Lock() - go func() { - defer ret.mu.Unlock() - ret.rescan() - }() - return -} - -// An empty return path is an error. -func sanitizePath(p string) (ret string) { - if p == "" { - return - } - ret = path.Clean("/" + p) - if ret[0] == '/' { - ret = ret[1:] - } - return -} - -// Leaf is a descendent of root. -func pruneEmptyDirs(root string, leaf string) (err error) { - rootInfo, err := os.Stat(root) - if err != nil { - return - } - for { - var leafInfo os.FileInfo - leafInfo, err = os.Stat(leaf) - if os.IsNotExist(err) { - goto parent - } - if err != nil { - return - } - if !leafInfo.IsDir() { - return - } - if os.SameFile(rootInfo, leafInfo) { - return - } - if os.Remove(leaf) != nil { - return - } - parent: - leaf = filepath.Dir(leaf) - } -} - -func (me *Cache) Remove(path string) (err error) { - path = sanitizePath(path) - me.mu.Lock() - defer me.mu.Unlock() - err = me.remove(path) - return -} - -var ( - ErrBadPath = errors.New("bad path") - ErrIsDir = errors.New("is directory") -) - -func (me *Cache) OpenFile(path string, flag int) (ret *File, err error) { - path = sanitizePath(path) - if path == "" { - err = ErrIsDir - return - } - f, err := os.OpenFile(me.realpath(path), flag, 0644) - if flag&os.O_CREATE != 0 && os.IsNotExist(err) { - os.MkdirAll(me.root, 0755) - os.MkdirAll(filepath.Dir(me.realpath(path)), 0755) - f, err = os.OpenFile(me.realpath(path), flag, 0644) - if err != nil { - me.pruneEmptyDirs(path) - } - } - if err != nil { - return - } - ret = &File{ - c: me, - path: path, - f: f, - } - me.mu.Lock() - go func() { - defer me.mu.Unlock() - me.statItem(path, time.Now()) - }() - return -} - -func (me *Cache) rescan() { - me.filled = 0 - me.items = newLRUItems() - me.paths = make(map[string]ItemInfo) - err := filepath.Walk(me.root, func(path string, info os.FileInfo, err error) error { - if os.IsNotExist(err) { - return nil - } - if err != nil { - return err - } - if info.IsDir() { - return nil - } - path, err = filepath.Rel(me.root, path) - if err != nil { - log.Print(err) - return nil - } - me.statItem(path, time.Time{}) - return nil - }) - if err != nil { - panic(err) - } -} - -func (me *Cache) insertItem(i ItemInfo) { - me.items.Insert(i) -} - -func (me *Cache) removeInfo(path string) (ret ItemInfo, ok bool) { - ret, ok = me.paths[path] - if !ok { - return - } - if !me.items.Remove(ret) { - panic(ret) - } - me.filled -= ret.Size - delete(me.paths, path) - return -} - -// Triggers the item for path to be updated. If access is non-zero, set the -// item's access time to that value, otherwise deduce it appropriately. -func (me *Cache) statItem(path string, access time.Time) { - info, ok := me.removeInfo(path) - fi, err := os.Stat(me.realpath(path)) - if os.IsNotExist(err) { - return - } - if err != nil { - panic(err) - } - if !ok { - info.Path = path - } - if !access.IsZero() { - info.Accessed = access - } - if info.Accessed.IsZero() { - info.Accessed = missinggo.FileInfoAccessTime(fi) - } - info.Size = fi.Size() - me.filled += info.Size - me.insertItem(info) - me.paths[path] = info -} - -func (me *Cache) realpath(path string) string { - return filepath.Join(me.root, filepath.FromSlash(path)) -} - -func (me *Cache) TrimToCapacity() { - me.mu.Lock() - defer me.mu.Unlock() - me.trimToCapacity() -} - -func (me *Cache) pruneEmptyDirs(path string) { - pruneEmptyDirs(me.root, me.realpath(path)) -} - -func (me *Cache) remove(path string) (err error) { - err = os.Remove(me.realpath(path)) - if os.IsNotExist(err) { - err = nil - } - me.pruneEmptyDirs(path) - me.removeInfo(path) - return -} - -func (me *Cache) trimToCapacity() { - if me.capacity < 0 { - return - } - for me.filled > me.capacity { - item := me.items.LRU() - me.remove(item.Path) - } -} - -func (me *Cache) pathInfo(p string) ItemInfo { - return me.paths[p] -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache_test.go deleted file mode 100644 index ddaed5d..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/cache_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package filecache - -import ( - "io" - "io/ioutil" - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" -) - -func TestCache(t *testing.T) { - td, err := ioutil.TempDir("", "gotest") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(td) - c, err := NewCache(filepath.Join(td, "cache")) - if err != nil { - t.Fatal(err) - } - assert.EqualValues(t, 0, c.Info().Filled) - c.WalkItems(func(i ItemInfo) {}) - _, err = c.OpenFile("/", os.O_CREATE) - assert.NotNil(t, err) - _, err = c.OpenFile("", os.O_CREATE) - assert.NotNil(t, err) - c.WalkItems(func(i ItemInfo) {}) - require.Equal(t, 0, c.Info().NumItems) - _, err = c.OpenFile("notexist", 0) - assert.True(t, os.IsNotExist(err), err) - _, err = c.OpenFile("/notexist", 0) - assert.True(t, os.IsNotExist(err), err) - _, err = c.OpenFile("/dir/notexist", 0) - assert.True(t, os.IsNotExist(err), err) - f, err := c.OpenFile("dir/blah", os.O_CREATE) - require.NoError(t, err) - defer f.Close() - c.WalkItems(func(i ItemInfo) {}) - assert.True(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("cache/dir/blah")))) - assert.True(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("cache/dir/")))) - assert.Equal(t, 1, c.Info().NumItems) - f.Remove() - assert.False(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("dir/blah")))) - assert.False(t, missinggo.FilePathExists(filepath.Join(td, filepath.FromSlash("dir/")))) - _, err = f.Read(nil) - assert.NotEqual(t, io.EOF, err) - a, err := c.OpenFile("/a", os.O_CREATE|os.O_WRONLY) - defer a.Close() - require.Nil(t, err) - b, err := c.OpenFile("b", os.O_CREATE|os.O_WRONLY) - defer b.Close() - require.Nil(t, err) - c.mu.Lock() - assert.True(t, c.pathInfo("a").Accessed.Before(c.pathInfo("b").Accessed)) - c.mu.Unlock() - n, err := a.Write([]byte("hello")) - assert.Nil(t, err) - assert.EqualValues(t, 5, n) - assert.EqualValues(t, 5, c.Info().Filled) - assert.True(t, c.pathInfo("b").Accessed.Before(c.pathInfo("a").Accessed)) - c.SetCapacity(5) - n, err = a.Write([]byte(" world")) - assert.NotNil(t, err) - _, err = b.Write([]byte("boom!")) - // "a" and "b" have been evicted. - assert.NotNil(t, err) - assert.EqualValues(t, 0, c.Info().Filled) - assert.EqualValues(t, 0, c.Info().NumItems) - _, err = a.Seek(0, os.SEEK_SET) - assert.NotNil(t, err) -} - -func TestSanitizePath(t *testing.T) { - assert.Equal(t, "", sanitizePath("////")) - assert.Equal(t, "", sanitizePath("/../..")) - assert.Equal(t, "a", sanitizePath("/a//b/..")) - assert.Equal(t, "a", sanitizePath("../a")) - assert.Equal(t, "a", sanitizePath("./a")) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/file.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/file.go deleted file mode 100644 index 70e4743..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/file.go +++ /dev/null @@ -1,117 +0,0 @@ -package filecache - -import ( - "errors" - "math" - "os" - "sync" - "time" -) - -type File struct { - mu sync.Mutex - c *Cache - path string - f *os.File - gone bool -} - -func (me *File) Remove() (err error) { - return me.c.Remove(me.path) -} - -func (me *File) Seek(offset int64, whence int) (ret int64, err error) { - ret, err = me.f.Seek(offset, whence) - return -} - -func (me *File) maxWrite() (max int64, err error) { - if me.c.capacity < 0 { - max = math.MaxInt64 - return - } - pos, err := me.Seek(0, os.SEEK_CUR) - if err != nil { - return - } - max = me.c.capacity - pos - if max < 0 { - max = 0 - } - return -} - -var ( - ErrFileTooLarge = errors.New("file too large for cache") - ErrFileDisappeared = errors.New("file disappeared") -) - -func (me *File) checkGone() { - if me.gone { - return - } - ffi, _ := me.Stat() - fsfi, _ := os.Stat(me.c.realpath(me.path)) - me.gone = !os.SameFile(ffi, fsfi) -} - -func (me *File) goneErr() error { - me.mu.Lock() - defer me.mu.Unlock() - me.checkGone() - if me.gone { - me.f.Close() - return ErrFileDisappeared - } - return nil -} - -func (me *File) Write(b []byte) (n int, err error) { - err = me.goneErr() - if err != nil { - return - } - n, err = me.f.Write(b) - me.c.mu.Lock() - me.c.statItem(me.path, time.Now()) - me.c.trimToCapacity() - me.c.mu.Unlock() - if err == nil { - err = me.goneErr() - } - return -} - -func (me *File) Close() error { - return me.f.Close() -} - -func (me *File) Stat() (os.FileInfo, error) { - return me.f.Stat() -} - -func (me *File) Read(b []byte) (n int, err error) { - err = me.goneErr() - if err != nil { - return - } - defer func() { - me.c.mu.Lock() - defer me.c.mu.Unlock() - me.c.statItem(me.path, time.Now()) - }() - return me.f.Read(b) -} - -func (me *File) ReadAt(b []byte, off int64) (n int, err error) { - err = me.goneErr() - if err != nil { - return - } - defer func() { - me.c.mu.Lock() - defer me.c.mu.Unlock() - me.c.statItem(me.path, time.Now()) - }() - return me.f.ReadAt(b, off) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems.go deleted file mode 100644 index 75f0f7b..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems.go +++ /dev/null @@ -1,94 +0,0 @@ -package filecache - -import ( - "container/list" - "io" - - "github.com/cznic/b" -) - -type Iterator interface { - Next() Iterator - Value() interface{} -} - -type listElementIterator struct { - le *list.Element -} - -func (me listElementIterator) Next() Iterator { - e := me.le.Next() - if e == nil { - return nil - } - return listElementIterator{e} -} - -func (me listElementIterator) Value() interface{} { - return me.le.Value -} - -func newLRUItems() *lruItems { - return &lruItems{b.TreeNew(func(_a, _b interface{}) int { - a := _a.(ItemInfo) - b := _b.(ItemInfo) - if a.Accessed != b.Accessed { - if a.Accessed.Before(b.Accessed) { - return -1 - } else { - return 1 - } - } - if a.Path == b.Path { - return 0 - } - if a.Path < b.Path { - return -1 - } - return 1 - })} -} - -type lruItems struct { - tree *b.Tree -} - -type bEnumeratorIterator struct { - e *b.Enumerator - v ItemInfo -} - -func (me bEnumeratorIterator) Next() Iterator { - _, v, err := me.e.Next() - if err == io.EOF { - return nil - } - return bEnumeratorIterator{me.e, v.(ItemInfo)} -} - -func (me bEnumeratorIterator) Value() interface{} { - return me.v -} - -func (me *lruItems) Front() Iterator { - e, _ := me.tree.SeekFirst() - if e == nil { - return nil - } - return bEnumeratorIterator{ - e: e, - }.Next() -} - -func (me *lruItems) LRU() ItemInfo { - _, v := me.tree.First() - return v.(ItemInfo) -} - -func (me *lruItems) Insert(ii ItemInfo) { - me.tree.Set(ii, ii) -} - -func (me *lruItems) Remove(ii ItemInfo) bool { - return me.tree.Delete(ii) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems_test.go deleted file mode 100644 index 557739a..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/filecache/lruitems_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package filecache - -import ( - "math/rand" - "testing" - "time" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/bradfitz/iter" -) - -func BenchmarkInsert(b *testing.B) { - for _ = range iter.N(b.N) { - li := newLRUItems() - for _ = range iter.N(10000) { - r := rand.Int63() - t := time.Unix(r/1e9, r%1e9) - li.Insert(ItemInfo{ - Accessed: t, - }) - } - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange.go deleted file mode 100644 index acf1002..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange.go +++ /dev/null @@ -1,38 +0,0 @@ -package missinggo - -import ( - "regexp" - "strconv" -) - -type HTTPBytesContentRange struct { - First, Last, Length int64 -} - -var bytesContentRangeRegexp = regexp.MustCompile(`bytes[ =](\d+)-(\d+)/(\d+|\*)`) - -func ParseHTTPBytesContentRange(s string) (ret HTTPBytesContentRange, ok bool) { - ss := bytesContentRangeRegexp.FindStringSubmatch(s) - if ss == nil { - return - } - var err error - ret.First, err = strconv.ParseInt(ss[1], 10, 64) - if err != nil { - return - } - ret.Last, err = strconv.ParseInt(ss[2], 10, 64) - if err != nil { - return - } - if ss[3] == "*" { - ret.Length = -1 - } else { - ret.Length, err = strconv.ParseInt(ss[3], 10, 64) - if err != nil { - return - } - } - ok = true - return -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange_test.go deleted file mode 100644 index e76ce60..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpcontentrange_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package missinggo - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestParseHTTPContentRange(t *testing.T) { - for _, _case := range []struct { - h string - cr *HTTPBytesContentRange - }{ - {"", nil}, - {"1-2/*", nil}, - {"bytes=1-2/3", &HTTPBytesContentRange{1, 2, 3}}, - {"bytes=12-34/*", &HTTPBytesContentRange{12, 34, -1}}, - {" bytes=12-34/*", &HTTPBytesContentRange{12, 34, -1}}, - {" bytes 12-34/56", &HTTPBytesContentRange{12, 34, 56}}, - } { - ret, ok := ParseHTTPBytesContentRange(_case.h) - assert.Equal(t, _case.cr != nil, ok) - if _case.cr != nil { - assert.Equal(t, *_case.cr, ret) - } - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpfile/httpfile.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpfile/httpfile.go deleted file mode 100644 index 8208f85..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpfile/httpfile.go +++ /dev/null @@ -1,222 +0,0 @@ -package httpfile - -import ( - "bytes" - "errors" - "fmt" - "io" - "net/http" - "os" - "strconv" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" -) - -type File struct { - off int64 - r io.ReadCloser - rOff int64 - length int64 - url string -} - -func OpenSectionReader(url string, off, n int64) (ret io.ReadCloser, err error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return - } - req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", off, off+n-1)) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return - } - if resp.StatusCode == http.StatusNotFound { - err = ErrNotFound - resp.Body.Close() - return - } - if resp.StatusCode != http.StatusPartialContent { - err = fmt.Errorf("bad response status: %s", resp.Status) - resp.Body.Close() - return - } - ret = resp.Body - return -} - -func Open(url string) *File { - return &File{ - url: url, - } -} - -func (me *File) prepareReader() (err error) { - if me.r != nil && me.off != me.rOff { - me.r.Close() - me.r = nil - } - if me.r != nil { - return nil - } - req, err := http.NewRequest("GET", me.url, nil) - if err != nil { - return - } - if me.off != 0 { - req.Header.Set("Range", fmt.Sprintf("bytes=%d-", me.off)) - } - resp, err := http.DefaultClient.Do(req) - if err != nil { - return - } - switch resp.StatusCode { - case http.StatusPartialContent: - cr, ok := missinggo.ParseHTTPBytesContentRange(resp.Header.Get("Content-Range")) - if !ok || cr.First != me.off { - err = errors.New("bad response") - resp.Body.Close() - return - } - me.length = cr.Length - case http.StatusOK: - if me.off != 0 { - err = errors.New("bad response") - resp.Body.Close() - return - } - if h := resp.Header.Get("Content-Length"); h != "" { - var cl uint64 - cl, err = strconv.ParseUint(h, 10, 64) - if err != nil { - resp.Body.Close() - return - } - me.length = int64(cl) - } - default: - err = errors.New(resp.Status) - resp.Body.Close() - return - } - me.r = resp.Body - me.rOff = me.off - return -} - -func (me *File) Read(b []byte) (n int, err error) { - err = me.prepareReader() - if err != nil { - return - } - n, err = me.r.Read(b) - me.off += int64(n) - me.rOff += int64(n) - return -} - -func instanceLength(r *http.Response) (int64, error) { - switch r.StatusCode { - case http.StatusOK: - if h := r.Header.Get("Content-Length"); h != "" { - return strconv.ParseInt(h, 10, 64) - } else { - return -1, nil - } - case http.StatusPartialContent: - cr, ok := missinggo.ParseHTTPBytesContentRange(r.Header.Get("Content-Range")) - if !ok { - return -1, errors.New("bad 206 response") - } - return cr.Length, nil - default: - return -1, errors.New(r.Status) - } -} - -func (me *File) Seek(offset int64, whence int) (ret int64, err error) { - switch whence { - case os.SEEK_SET: - ret = offset - case os.SEEK_CUR: - ret = me.off + offset - case os.SEEK_END: - if me.length < 0 { - err = errors.New("length unknown") - return - } - ret = me.length + offset - default: - err = fmt.Errorf("unhandled whence: %d", whence) - return - } - me.off = ret - return -} - -func (me *File) Write(b []byte) (n int, err error) { - req, err := http.NewRequest("PATCH", me.url, bytes.NewReader(b)) - if err != nil { - return - } - req.Header.Set("Content-Range", fmt.Sprintf("bytes=%d-", me.off)) - req.ContentLength = int64(len(b)) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return - } - resp.Body.Close() - if resp.StatusCode != http.StatusPartialContent { - err = errors.New(resp.Status) - return - } - n = len(b) - me.off += int64(n) - return -} - -var ( - ErrNotFound = errors.New("not found") -) - -// Returns the length of the resource in bytes. -func GetLength(url string) (ret int64, err error) { - resp, err := http.Head(url) - if err != nil { - return - } - resp.Body.Close() - if resp.StatusCode == http.StatusNotFound { - err = ErrNotFound - return - } - return instanceLength(resp) -} - -func (me *File) Close() error { - me.url = "" - if me.r != nil { - me.r.Close() - me.r = nil - } - return nil -} - -func Delete(urlStr string) (err error) { - req, err := http.NewRequest("DELETE", urlStr, nil) - if err != nil { - return - } - resp, err := http.DefaultClient.Do(req) - if err != nil { - return - } - resp.Body.Close() - if resp.StatusCode == http.StatusNotFound { - err = ErrNotFound - return - } - if resp.StatusCode != 200 { - err = fmt.Errorf("response: %s", resp.Status) - } - return -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpgzip.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpgzip.go deleted file mode 100644 index 503eb0f..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpgzip.go +++ /dev/null @@ -1,47 +0,0 @@ -package missinggo - -import ( - "compress/gzip" - "io" - "net/http" - "strings" -) - -type gzipResponseWriter struct { - io.Writer - http.ResponseWriter - haveWritten bool -} - -func (w *gzipResponseWriter) Write(b []byte) (int, error) { - if w.haveWritten { - goto write - } - w.haveWritten = true - if w.Header().Get("Content-Type") != "" { - goto write - } - if type_ := http.DetectContentType(b); type_ != "application/octet-stream" { - w.Header().Set("Content-Type", type_) - } -write: - return w.Writer.Write(b) -} - -// Gzips response body if the request says it'll allow it. -func GzipHTTPHandler(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") || w.Header().Get("Content-Encoding") != "" || w.Header().Get("Vary") != "" { - h.ServeHTTP(w, r) - return - } - w.Header().Set("Content-Encoding", "gzip") - w.Header().Set("Vary", "Accept-Encoding") - gz := gzip.NewWriter(w) - defer gz.Close() - h.ServeHTTP(&gzipResponseWriter{ - Writer: gz, - ResponseWriter: w, - }, r) - }) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpresponsestatus.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpresponsestatus.go deleted file mode 100644 index a42e098..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/httpresponsestatus.go +++ /dev/null @@ -1,60 +0,0 @@ -package missinggo - -import ( - "bufio" - "io" - "net" - "net/http" -) - -// A http.ResponseWriter that tracks the status of the response. The status -// code, and number of bytes written for example. -type StatusResponseWriter struct { - RW http.ResponseWriter - Code int - BytesWritten int64 -} - -var _ http.ResponseWriter = &StatusResponseWriter{} - -func (me *StatusResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { - return me.RW.(http.Hijacker).Hijack() -} - -func (me *StatusResponseWriter) CloseNotify() <-chan bool { - return me.RW.(http.CloseNotifier).CloseNotify() -} - -func (me *StatusResponseWriter) Flush() { - me.RW.(http.Flusher).Flush() -} - -func (me *StatusResponseWriter) Header() http.Header { - return me.RW.Header() -} - -func (me *StatusResponseWriter) Write(b []byte) (n int, err error) { - if me.Code == 0 { - me.Code = 200 - } - n, err = me.RW.Write(b) - me.BytesWritten += int64(n) - return -} - -func (me *StatusResponseWriter) WriteHeader(code int) { - me.RW.WriteHeader(code) - me.Code = code -} - -type ReaderFromStatusResponseWriter struct { - StatusResponseWriter - io.ReaderFrom -} - -func NewReaderFromStatusResponseWriter(w http.ResponseWriter) *ReaderFromStatusResponseWriter { - return &ReaderFromStatusResponseWriter{ - StatusResponseWriter{RW: w}, - w.(io.ReaderFrom), - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby.go deleted file mode 100644 index 17761fa..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby.go +++ /dev/null @@ -1,81 +0,0 @@ -package itertools - -type groupBy struct { - curKey interface{} - curKeyOk bool - curValue interface{} - keyFunc func(interface{}) interface{} - input Iterator - groupKey interface{} - groupKeyOk bool -} - -type Group interface { - Iterator - Key() interface{} -} - -type group struct { - gb *groupBy - key interface{} - first bool -} - -func (me *group) Next() (ok bool) { - if me.first { - me.first = false - return true - } - me.gb.advance() - if !me.gb.curKeyOk || me.gb.curKey != me.key { - return - } - ok = true - return -} - -func (me group) Value() (ret interface{}) { - ret = me.gb.curValue - return -} - -func (me group) Key() interface{} { - return me.key -} - -func (me *groupBy) advance() { - me.curKeyOk = me.input.Next() - if me.curKeyOk { - me.curValue = me.input.Value() - me.curKey = me.keyFunc(me.curValue) - } -} - -func (me *groupBy) Next() (ok bool) { - for me.curKey == me.groupKey { - ok = me.input.Next() - if !ok { - return - } - me.curValue = me.input.Value() - me.curKey = me.keyFunc(me.curValue) - me.curKeyOk = true - } - me.groupKey = me.curKey - me.groupKeyOk = true - return true -} - -func (me *groupBy) Value() (ret interface{}) { - return &group{me, me.groupKey, true} -} - -func GroupBy(input Iterator, keyFunc func(interface{}) interface{}) Iterator { - if keyFunc == nil { - keyFunc = func(a interface{}) interface{} { return a } - } - return &groupBy{ - input: input, - keyFunc: keyFunc, - } -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby_test.go deleted file mode 100644 index c194e73..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/groupby_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package itertools - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestGroupByKey(t *testing.T) { - var ks []byte - gb := GroupBy(StringIterator("AAAABBBCCDAABBB"), nil) - for gb.Next() { - ks = append(ks, gb.Value().(Group).Key().(byte)) - } - t.Log(ks) - require.EqualValues(t, "ABCDAB", ks) -} - -func TestGroupByList(t *testing.T) { - var gs []string - gb := GroupBy(StringIterator("AAAABBBCCD"), nil) - for gb.Next() { - i := gb.Value().(Iterator) - var g string - for i.Next() { - g += string(i.Value().(byte)) - } - gs = append(gs, g) - } - t.Log(gs) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator.go deleted file mode 100644 index 2cec8c1..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator.go +++ /dev/null @@ -1,41 +0,0 @@ -package itertools - -import "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" - -type Iterator interface { - Next() bool - Value() interface{} -} - -type sliceIterator struct { - slice []interface{} - value interface{} - ok bool -} - -func (me *sliceIterator) Next() bool { - if len(me.slice) == 0 { - return false - } - me.value = me.slice[0] - me.slice = me.slice[1:] - me.ok = true - return true -} - -func (me *sliceIterator) Value() interface{} { - if !me.ok { - panic("no value; call Next") - } - return me.value -} - -func SliceIterator(a []interface{}) Iterator { - return &sliceIterator{ - slice: a, - } -} - -func StringIterator(a string) Iterator { - return SliceIterator(missinggo.ConvertToSliceOfEmptyInterface(a)) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator_test.go deleted file mode 100644 index 61f0be8..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/itertools/iterator_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package itertools - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestIterator(t *testing.T) { - const s = "AAAABBBCCDAABBB" - si := StringIterator(s) - for i := range s { - require.True(t, si.Next()) - require.Equal(t, s[i], si.Value().(byte)) - } - require.False(t, si.Next()) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/net.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/net.go deleted file mode 100644 index ce406d3..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/net.go +++ /dev/null @@ -1,26 +0,0 @@ -package missinggo - -import ( - "net" -) - -type HostPort struct { - Host string // Just the host, with no port. - Port string // May be empty if no port was given. - Err error // The error returned from net.SplitHostPort. -} - -// Parse a "hostport" string, a concept that floats around the stdlib a lot -// and is painful to work with. If no port is present, what's usually present -// is just the host. -func ParseHostPort(hostPort string) (ret HostPort) { - ret.Host, ret.Port, ret.Err = net.SplitHostPort(hostPort) - if ret.Err != nil { - ret.Host = hostPort - } - return -} - -func (me *HostPort) Join() string { - return net.JoinHostPort(me.Host, me.Port) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/path.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/path.go deleted file mode 100644 index 6e3428c..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/path.go +++ /dev/null @@ -1,20 +0,0 @@ -package missinggo - -import ( - "os" - "path" -) - -// Splits the pathname p into Root and Ext, such that Root+Ext==p. -func PathSplitExt(p string) (ret struct { - Root, Ext string -}) { - ret.Ext = path.Ext(p) - ret.Root = p[:len(p)-len(ret.Ext)] - return -} - -func FilePathExists(p string) bool { - _, err := os.Stat(p) - return err == nil -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/path_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/path_test.go deleted file mode 100644 index a38aa2e..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/path_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package missinggo - -import ( - "fmt" -) - -func ExamplePathSplitExt() { - fmt.Printf("%q\n", PathSplitExt(".cshrc")) - fmt.Printf("%q\n", PathSplitExt("dir/a.ext")) - fmt.Printf("%q\n", PathSplitExt("dir/.rc")) - fmt.Printf("%q\n", PathSplitExt("home/.secret/file")) - // Output: - // {"" ".cshrc"} - // {"dir/a" ".ext"} - // {"dir/" ".rc"} - // {"home/.secret/file" ""} -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/mutex.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/mutex.go deleted file mode 100644 index ff9f1a7..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/mutex.go +++ /dev/null @@ -1,48 +0,0 @@ -package perf - -import ( - "sync" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" -) - -type TimedLocker struct { - L sync.Locker - Desc string -} - -func (me *TimedLocker) Lock() { - tr := NewTimer() - me.L.Lock() - tr.Stop(me.Desc) -} - -func (me *TimedLocker) Unlock() { - me.L.Unlock() -} - -type TimedRWLocker struct { - RWL missinggo.RWLocker - WriteDesc string - ReadDesc string -} - -func (me *TimedRWLocker) Lock() { - tr := NewTimer() - me.RWL.Lock() - tr.Stop(me.WriteDesc) -} - -func (me *TimedRWLocker) Unlock() { - me.RWL.Unlock() -} - -func (me *TimedRWLocker) RLock() { - tr := NewTimer() - me.RWL.RLock() - tr.Stop(me.ReadDesc) -} - -func (me *TimedRWLocker) RUnlock() { - me.RWL.RUnlock() -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf.go deleted file mode 100644 index 3266e02..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf.go +++ /dev/null @@ -1,92 +0,0 @@ -package perf - -import ( - "bytes" - "expvar" - "fmt" - "strconv" - "sync" - "time" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" -) - -var ( - em = missinggo.NewExpvarIndentMap("perfBuckets") - mu sync.RWMutex -) - -type Timer struct { - started time.Time -} - -func NewTimer() Timer { - return Timer{time.Now()} -} - -func bucketExponent(d time.Duration) int { - e := -9 - for d != 0 { - d /= 10 - e++ - } - return e -} - -type buckets struct { - mu sync.Mutex - buckets []int64 -} - -func (me *buckets) Add(t time.Duration) { - e := bucketExponent(t) - me.mu.Lock() - for e+9 >= len(me.buckets) { - me.buckets = append(me.buckets, 0) - } - me.buckets[e+9]++ - me.mu.Unlock() -} - -func (me *buckets) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "{") - first := true - me.mu.Lock() - for i, count := range me.buckets { - if first { - if count == 0 { - continue - } - first = false - } else { - fmt.Fprintf(&b, ", ") - } - key := strconv.Itoa(i - 9) - fmt.Fprintf(&b, "%q: %d", key, count) - } - me.mu.Unlock() - fmt.Fprintf(&b, "}") - return b.String() -} - -var _ expvar.Var = &buckets{} - -func (t *Timer) Stop(desc string) time.Duration { - d := time.Since(t.started) - mu.RLock() - _m := em.Get(desc) - mu.RUnlock() - if _m == nil { - mu.Lock() - _m = em.Get(desc) - if _m == nil { - _m = new(buckets) - em.Set(desc, _m) - } - mu.Unlock() - } - m := _m.(*buckets) - m.Add(d) - return d -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf_test.go deleted file mode 100644 index dc7397e..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/perf/perf_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package perf - -import ( - "fmt" - "strconv" - "testing" - "time" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/bradfitz/iter" - "github.com/stretchr/testify/assert" -) - -func TestTimer(t *testing.T) { - tr := NewTimer() - tr.Stop("hiyo") - tr.Stop("hiyo") - t.Log(em.Get("hiyo").(*buckets)) -} - -func BenchmarkStopWarm(b *testing.B) { - tr := NewTimer() - for _ = range iter.N(b.N) { - tr.Stop("a") - } -} - -func BenchmarkStopCold(b *testing.B) { - tr := NewTimer() - for i := range iter.N(b.N) { - tr.Stop(strconv.FormatInt(int64(i), 10)) - } -} - -func TestExponent(t *testing.T) { - for _, c := range []struct { - e int - d time.Duration - }{ - {-1, 10 * time.Millisecond}, - {-2, 5 * time.Millisecond}, - {-2, time.Millisecond}, - {-3, 500 * time.Microsecond}, - {-3, 100 * time.Microsecond}, - } { - tr := NewTimer() - time.Sleep(c.d) - assert.Equal(t, c.e, bucketExponent(tr.Stop(fmt.Sprintf("%d", c.e))), "%s", c.d) - } - assert.Equal(t, `{"-1": 1}`, em.Get("-1").String()) - assert.Equal(t, `{"-2": 2}`, em.Get("-2").String()) - assert.Equal(t, `{"-3": 2}`, em.Get("-3").String()) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub.go deleted file mode 100644 index f923385..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub.go +++ /dev/null @@ -1,92 +0,0 @@ -package pubsub - -import ( - "sync" -) - -type PubSub struct { - mu sync.Mutex - next chan item - closed bool -} - -type item struct { - value interface{} - next chan item -} - -type Subscription struct { - next chan item - Values chan interface{} - mu sync.Mutex - closed chan struct{} -} - -func NewPubSub() (ret *PubSub) { - return &PubSub{ - next: make(chan item, 1), - } -} - -func (me *PubSub) Publish(v interface{}) { - next := make(chan item, 1) - i := item{v, next} - me.mu.Lock() - me.next <- i - me.next = next - me.mu.Unlock() -} - -func (me *Subscription) Close() { - me.mu.Lock() - defer me.mu.Unlock() - select { - case <-me.closed: - default: - close(me.closed) - } -} - -func (me *Subscription) runner() { - defer close(me.Values) - for { - select { - case i, ok := <-me.next: - if !ok { - me.Close() - return - } - me.next <- i - me.next = i.next - select { - case me.Values <- i.value: - case <-me.closed: - return - } - case <-me.closed: - return - } - } -} - -func (me *PubSub) Subscribe() (ret *Subscription) { - ret = &Subscription{ - closed: make(chan struct{}), - Values: make(chan interface{}), - } - me.mu.Lock() - ret.next = me.next - me.mu.Unlock() - go ret.runner() - return -} - -func (me *PubSub) Close() { - me.mu.Lock() - defer me.mu.Unlock() - if me.closed { - return - } - close(me.next) - me.closed = true -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub_test.go deleted file mode 100644 index c761669..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/pubsub/pubsub_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package pubsub - -import ( - "sync" - "testing" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/bradfitz/iter" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestDoubleClose(t *testing.T) { - ps := NewPubSub() - ps.Close() - ps.Close() -} - -func testBroadcast(t testing.TB, subs, vals int) { - ps := NewPubSub() - var wg sync.WaitGroup - for _ = range iter.N(subs) { - wg.Add(1) - s := ps.Subscribe() - go func() { - defer wg.Done() - var e int - for i := range s.Values { - assert.Equal(t, e, i.(int)) - e++ - } - assert.Equal(t, vals, e) - }() - } - for i := range iter.N(vals) { - ps.Publish(i) - } - ps.Close() - wg.Wait() -} - -func TestBroadcast(t *testing.T) { - testBroadcast(t, 100, 10) -} - -func BenchmarkBroadcast(b *testing.B) { - for _ = range iter.N(b.N) { - testBroadcast(b, 10, 1000) - } -} - -func TestCloseSubscription(t *testing.T) { - ps := NewPubSub() - ps.Publish(1) - s := ps.Subscribe() - select { - case <-s.Values: - t.FailNow() - default: - } - ps.Publish(2) - s2 := ps.Subscribe() - ps.Publish(3) - require.Equal(t, 2, <-s.Values) - require.EqualValues(t, 3, <-s.Values) - s.Close() - _, ok := <-s.Values - require.False(t, ok) - ps.Publish(4) - ps.Close() - require.Equal(t, 3, <-s2.Values) - require.Equal(t, 4, <-s2.Values) - require.Nil(t, <-s2.Values) - s2.Close() -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/rle.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/rle.go deleted file mode 100644 index 63d4997..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/rle.go +++ /dev/null @@ -1,46 +0,0 @@ -package missinggo - -// A RunLengthEncoder counts successive duplicate elements and emits the -// element and the run length when the element changes or the encoder is -// flushed. -type RunLengthEncoder interface { - // Add a series of identical elements to the stream. - Append(element interface{}, count uint64) - // Emit the current element and its count if non-zero without waiting for - // the element to change. - Flush() -} - -type runLengthEncoder struct { - eachRun func(element interface{}, count uint64) - element interface{} - count uint64 -} - -// Creates a new RunLengthEncoder. eachRun is called when an element and its -// count is emitted, per the RunLengthEncoder interface. -func NewRunLengthEncoder(eachRun func(element interface{}, count uint64)) RunLengthEncoder { - return &runLengthEncoder{ - eachRun: eachRun, - } -} - -func (me *runLengthEncoder) Append(element interface{}, count uint64) { - if element == me.element { - me.count += count - return - } - if me.count != 0 { - me.eachRun(me.element, me.count) - } - me.count = count - me.element = element -} - -func (me *runLengthEncoder) Flush() { - if me.count == 0 { - return - } - me.eachRun(me.element, me.count) - me.count = 0 -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/rle_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/rle_test.go deleted file mode 100644 index d6f2051..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/rle_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package missinggo_test - -import ( - "fmt" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" -) - -func ExampleNewRunLengthEncoder() { - var s string - rle := missinggo.NewRunLengthEncoder(func(e interface{}, count uint64) { - s += fmt.Sprintf("%d%c", count, e) - }) - for _, e := range "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW" { - rle.Append(e, 1) - } - rle.Flush() - fmt.Println(s) - // Output: 12W1B12W3B24W1B14W -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/singleflight.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/singleflight.go deleted file mode 100644 index 7a6e299..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/singleflight.go +++ /dev/null @@ -1,39 +0,0 @@ -package missinggo - -import "sync" - -type ongoing struct { - do sync.Mutex - users int -} - -type SingleFlight struct { - mu sync.Mutex - ongoing map[string]*ongoing -} - -func (me *SingleFlight) Lock(id string) { - me.mu.Lock() - on, ok := me.ongoing[id] - if !ok { - on = new(ongoing) - if me.ongoing == nil { - me.ongoing = make(map[string]*ongoing) - } - me.ongoing[id] = on - } - on.users++ - me.mu.Unlock() - on.do.Lock() -} - -func (me *SingleFlight) Unlock(id string) { - me.mu.Lock() - on := me.ongoing[id] - on.do.Unlock() - on.users-- - if on.users == 0 { - delete(me.ongoing, id) - } - me.mu.Unlock() -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/sync.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/sync.go deleted file mode 100644 index fc099bd..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/sync.go +++ /dev/null @@ -1,11 +0,0 @@ -package missinggo - -import ( - "sync" -) - -type RWLocker interface { - sync.Locker - RLock() - RUnlock() -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/url.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/url.go deleted file mode 100644 index 5f01eee..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/url.go +++ /dev/null @@ -1,30 +0,0 @@ -package missinggo - -import ( - "net/http" - "net/url" -) - -// Deep copies a URL. -func CopyURL(u *url.URL) (ret *url.URL) { - ret = new(url.URL) - *ret = *u - if u.User != nil { - ret.User = new(url.Userinfo) - *ret.User = *u.User - } - return -} - -// Reconstructs the URL that would have produced the given Request. -// Request.URLs are not fully populated in http.Server handlers. -func RequestedURL(r *http.Request) (ret *url.URL) { - ret = CopyURL(r.URL) - ret.Host = r.Host - if r.TLS != nil { - ret.Scheme = "https" - } else { - ret.Scheme = "http" - } - return -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf.go deleted file mode 100644 index 5552c61..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf.go +++ /dev/null @@ -1,51 +0,0 @@ -package missinggo - -import ( - "log" - "runtime" - "sync" - "sync/atomic" -) - -const debug = false - -// A Wolf represents some event that becomes less and less interesting as it -// occurs. Call CryHeard to see if we should pay attention this time. -type Wolf struct { - cries uint64 -} - -// Returns true less and less often. Convenient for exponentially decreasing -// the amount of noise due to errors. -func (me *Wolf) CryHeard() bool { - n := atomic.AddUint64(&me.cries, 1) - return n&(n-1) == 0 -} - -var ( - mu sync.Mutex - wolves map[uintptr]*Wolf -) - -// Calls CryHeard() on a Wolf that is unique to the callers program counter. -// i.e. every CryHeard() expression has its own Wolf. -func CryHeard() bool { - pc, file, line, ok := runtime.Caller(1) - if debug { - log.Println(pc, file, line, ok) - } - if !ok { - return true - } - mu.Lock() - if wolves == nil { - wolves = make(map[uintptr]*Wolf) - } - w, ok := wolves[pc] - if !ok { - w = new(Wolf) - wolves[pc] = w - } - mu.Unlock() - return w.CryHeard() -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf_test.go b/Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf_test.go deleted file mode 100644 index 3ee59ca..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/missinggo/wolf_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package missinggo - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func cryHeard() bool { - return CryHeard() -} - -func TestCrySameLocation(t *testing.T) { - require.True(t, cryHeard()) - require.True(t, cryHeard()) - require.False(t, cryHeard()) - require.True(t, cryHeard()) - require.False(t, cryHeard()) - require.False(t, cryHeard()) - require.False(t, cryHeard()) - require.True(t, cryHeard()) -} - -func TestCryDifferentLocations(t *testing.T) { - require.True(t, CryHeard()) - require.True(t, CryHeard()) - require.True(t, CryHeard()) - require.True(t, CryHeard()) - require.True(t, CryHeard()) -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/utp/.utp.go.swp b/Godeps/_workspace/src/github.com/anacrolix/utp/.utp.go.swp deleted file mode 100644 index 612b7cc..0000000 Binary files a/Godeps/_workspace/src/github.com/anacrolix/utp/.utp.go.swp and /dev/null differ diff --git a/Godeps/_workspace/src/github.com/anacrolix/utp/LICENSE b/Godeps/_workspace/src/github.com/anacrolix/utp/LICENSE deleted file mode 100644 index be2cc4d..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/utp/LICENSE +++ /dev/null @@ -1,362 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. diff --git a/Godeps/_workspace/src/github.com/anacrolix/utp/README.md b/Godeps/_workspace/src/github.com/anacrolix/utp/README.md deleted file mode 100644 index 01c049e..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/utp/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# utp -[![GoDoc](https://godoc.org/github.com/anacrolix/utp?status.svg)](https://godoc.org/github.com/anacrolix/utp) -[![Build Status](https://drone.io/github.com/anacrolix/utp/status.png)](https://drone.io/github.com/anacrolix/utp/latest) - -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. - -## Supported - - * Multiple uTP connections switched on a single PacketConn, including those initiated locally. - * Raw access to the PacketConn for non-uTP purposes, like sharing the PacketConn with a DHT implementation. - -## Implementation characteristics - - * Receive window size is used to limit out of order packets received. - * There is no MTU path discovery. The minimum size is always used. - * A fixed 64 slot selective ack window is used in both sending and receiving. - * All received non-ACK packets are ACKed in response. - -Patches welcomed. diff --git a/Godeps/_workspace/src/github.com/anacrolix/utp/cmd/ucat/ucat.go b/Godeps/_workspace/src/github.com/anacrolix/utp/cmd/ucat/ucat.go deleted file mode 100644 index 06f6222..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/utp/cmd/ucat/ucat.go +++ /dev/null @@ -1,66 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "io" - "log" - "net" - "os" - "os/signal" - - "github.com/anacrolix/envpprof" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/utp" -) - -func main() { - defer envpprof.Stop() - listen := flag.Bool("l", false, "listen") - port := flag.Int("p", 0, "port to listen on") - flag.Parse() - var ( - conn net.Conn - err error - ) - if *listen { - s, err := utp.NewSocket("udp", fmt.Sprintf(":%d", *port)) - if err != nil { - log.Fatal(err) - } - defer s.Close() - conn, err = s.Accept() - if err != nil { - log.Fatal(err) - } - } else { - conn, err = utp.Dial(net.JoinHostPort(flag.Arg(0), flag.Arg(1))) - if err != nil { - log.Fatal(err) - } - } - defer conn.Close() - go func() { - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt) - <-sig - conn.Close() - }() - writerDone := make(chan struct{}) - go func() { - defer close(writerDone) - written, err := io.Copy(conn, os.Stdin) - if err != nil { - conn.Close() - log.Fatalf("error after writing %d bytes: %s", written, err) - } - log.Printf("wrote %d bytes", written) - conn.Close() - }() - n, err := io.Copy(os.Stdout, conn) - if err != nil { - log.Fatal(err) - } - log.Printf("received %d bytes", n) - // <-writerDone -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/utp/pingpong b/Godeps/_workspace/src/github.com/anacrolix/utp/pingpong deleted file mode 100644 index 0a9333e..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/utp/pingpong +++ /dev/null @@ -1,61 +0,0 @@ -# This shell script uses nc-like executables to send and receive the file at -# $1, and prints the checksums. 3 such executables are -# github.com/h2so5/utp/ucat, invoked as h2so5-ucat, libutp-ucat, which is the -# ucat or ucat-static generated by the C++ libutp, and lastly, ./cmd/ucat from -# this repository. A good file in my experiments is no more than a few 100MB, -# or you'll be waiting a while. - -set -eu -# set -x - -# Passed to invocations of godo for package ./cmd/ucat. -#GODOFLAGS=-race - -#export GO_UTP_PACKET_DROP=0.1 -export GOPPROF= - -# Invokes the implementation to test against. If there's an arg, then it's -# expected to listen. -function other_ucat() { - if [[ $# != 0 ]]; then - libutp-ucat -l -p 4000 - # h2so5-ucat -l :4000 - else - libutp-ucat localhost 4000 - # h2so5-ucat localhost:4000 - fi -} - -# Check what the correct result is. -md5 "$1" - -rate() { - pv -a -W -b -} - -echo 'utp->other_ucat' -# Send from this uTP implementation to another client. -other_ucat -l | rate | md5 & -# sleep 1 -godo ${GODOFLAGS-} ./cmd/ucat localhost 4000 < "$1" -wait - -echo 'other_ucat->utp' -# Send from the other implementation, to this one. -GO_UTP_LOGGING=0 GOPPROF= godo ${GODOFLAGS-} ./cmd/ucat -l -p 4000 | rate | md5 & -# Never receive from h2so5's ucat without a small sleep first. Don't know why. -# sleep 1 -other_ucat < "$1" -wait - -echo 'libutp->libutp' -libutp-ucat -l -p 4000 | rate | md5 & -libutp-ucat localhost 4000 < "$1" -wait - -echo 'utp->utp' -godo ./cmd/ucat -l -p 4000 | rate | md5 & -godo ./cmd/ucat localhost 4000 < "$1" -wait - -# Now check the hashes match (yes you). diff --git a/Godeps/_workspace/src/github.com/anacrolix/utp/utp.go b/Godeps/_workspace/src/github.com/anacrolix/utp/utp.go deleted file mode 100644 index e0c9972..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/utp/utp.go +++ /dev/null @@ -1,1461 +0,0 @@ -// 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. It allows using the underlying OS-level transport despite -// dispatching uTP on top to allow for example, shared socket use with DHT. -// Additionally, multiple uTP connections can share the same OS socket, to -// truly realize uTP's claim to be light on system and network switching -// resources. -// -// Socket is a wrapper of net.UDPConn, and performs dispatching of uTP packets -// to attached uTP Conns. Dial and Accept is done via Socket. Conn implements -// net.Conn over uTP, via aforementioned Socket. -package utp - -import ( - "encoding/binary" - "errors" - "expvar" - "fmt" - "io" - "log" - "math/rand" - "net" - "os" - "strconv" - "sync" - "time" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/jitter" - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" -) - -const ( - // Maximum received SYNs that haven't been accepted. If more SYNs are - // received, a pseudo randomly selected SYN is replied to with a reset to - // make room. - backlog = 50 - - // IPv6 min MTU is 1280, -40 for IPv6 header, and ~8 for fragment header? - minMTU = 1232 - recvWindow = 0x8000 // 32KiB - // uTP header of 20, +2 for the next extension, and 8 bytes of selective - // ACK. - maxHeaderSize = 30 - maxPayloadSize = minMTU - maxHeaderSize - maxRecvSize = 0x2000 - - // Maximum out-of-order packets to buffer. - maxUnackedInbound = 64 - - // If an send isn't acknowledged after this period, its connection is - // destroyed. There are resends during this period. - sendTimeout = 15 * time.Second -) - -var ( - ackSkippedResends = expvar.NewInt("utpAckSkippedResends") - // Inbound packets processed by a Conn. - deliveriesProcessed = expvar.NewInt("utpDeliveriesProcessed") - sentStatePackets = expvar.NewInt("utpSentStatePackets") - unusedReads = expvar.NewInt("utpUnusedReads") - sendBufferPool = sync.Pool{ - New: func() interface{} { return make([]byte, minMTU) }, - } -) - -type deadlineCallback struct { - deadline time.Time - timer *time.Timer - callback func() - inited bool -} - -func (me *deadlineCallback) deadlineExceeded() bool { - return !me.deadline.IsZero() && !time.Now().Before(me.deadline) -} - -func (me *deadlineCallback) updateTimer() { - if me.timer != nil { - me.timer.Stop() - } - if me.deadline.IsZero() { - return - } - if me.callback == nil { - panic("deadline callback is nil") - } - me.timer = time.AfterFunc(me.deadline.Sub(time.Now()), me.callback) -} - -func (me *deadlineCallback) setDeadline(t time.Time) { - me.deadline = t - me.updateTimer() -} - -func (me *deadlineCallback) setCallback(f func()) { - me.callback = f - me.updateTimer() -} - -type connDeadlines struct { - // mu sync.Mutex - read, write deadlineCallback -} - -func (c *connDeadlines) SetDeadline(t time.Time) error { - c.read.setDeadline(t) - c.write.setDeadline(t) - return nil -} - -func (c *connDeadlines) SetReadDeadline(t time.Time) error { - c.read.setDeadline(t) - return nil -} - -func (c *connDeadlines) SetWriteDeadline(t time.Time) error { - c.write.setDeadline(t) - return nil -} - -// Strongly-type guarantee of resolved network address. -type resolvedAddrStr string - -// Uniquely identifies any uTP connection on top of the underlying packet -// stream. -type connKey struct { - remoteAddr resolvedAddrStr - connID uint16 -} - -// A Socket wraps a net.PacketConn, diverting uTP packets to its child uTP -// Conns. -type Socket struct { - mu sync.RWMutex - event sync.Cond - pc net.PacketConn - conns map[connKey]*Conn - backlog map[syn]struct{} - reads chan read - closing chan struct{} - - unusedReads chan read - connDeadlines - // If a read error occurs on the underlying net.PacketConn, it is put - // here. This is because reading is done in its own goroutine to dispatch - // to uTP Conns. - ReadErr error -} - -type read struct { - data []byte - from net.Addr -} - -type syn struct { - seq_nr, conn_id uint16 - addr string -} - -const ( - extensionTypeSelectiveAck = 1 -) - -type extensionField struct { - Type byte - Bytes []byte -} - -type header struct { - Type st - Version int - ConnID uint16 - Timestamp uint32 - TimestampDiff uint32 - WndSize uint32 - SeqNr uint16 - AckNr uint16 - Extensions []extensionField -} - -var ( - mu sync.RWMutex - logLevel = 0 - artificialPacketDropChance = 0.0 -) - -func init() { - logLevel, _ = strconv.Atoi(os.Getenv("GO_UTP_LOGGING")) - fmt.Sscanf(os.Getenv("GO_UTP_PACKET_DROP"), "%f", &artificialPacketDropChance) -} - -var ( - errClosed = errors.New("closed") - errNotImplemented = errors.New("not implemented") - errTimeout net.Error = timeoutError{"i/o timeout"} - errAckTimeout = timeoutError{"timed out waiting for ack"} -) - -type timeoutError struct { - msg string -} - -func (me timeoutError) Timeout() bool { return true } -func (me timeoutError) Error() string { return me.msg } -func (me timeoutError) Temporary() bool { return false } - -func unmarshalExtensions(_type byte, b []byte) (n int, ef []extensionField, err error) { - for _type != 0 { - if _type != extensionTypeSelectiveAck { - // An extension type that is not known to us. Generally we're - // unmarshalling an packet that isn't actually uTP but we don't - // yet know for sure until we try to deliver it. - - // logonce.Stderr.Printf("utp extension %d", _type) - } - if len(b) < 2 || len(b) < int(b[1])+2 { - err = fmt.Errorf("buffer ends prematurely: %x", b) - return - } - ef = append(ef, extensionField{ - Type: _type, - Bytes: append([]byte{}, b[2:int(b[1])+2]...), - }) - _type = b[0] - n += 2 + int(b[1]) - b = b[2+int(b[1]):] - } - return -} - -var errInvalidHeader = errors.New("invalid header") - -func (h *header) Unmarshal(b []byte) (n int, err error) { - h.Type = st(b[0] >> 4) - h.Version = int(b[0] & 0xf) - if h.Type > stMax || h.Version != 1 { - err = errInvalidHeader - return - } - n, h.Extensions, err = unmarshalExtensions(b[1], b[20:]) - if err != nil { - return - } - h.ConnID = binary.BigEndian.Uint16(b[2:4]) - h.Timestamp = binary.BigEndian.Uint32(b[4:8]) - h.TimestampDiff = binary.BigEndian.Uint32(b[8:12]) - h.WndSize = binary.BigEndian.Uint32(b[12:16]) - h.SeqNr = binary.BigEndian.Uint16(b[16:18]) - h.AckNr = binary.BigEndian.Uint16(b[18:20]) - n += 20 - return -} - -func (h *header) Marshal() (ret []byte) { - hLen := 20 + func() (ret int) { - for _, ext := range h.Extensions { - ret += 2 + len(ext.Bytes) - } - return - }() - ret = sendBufferPool.Get().([]byte)[:hLen:minMTU] - // ret = make([]byte, hLen, minMTU) - p := ret // Used for manipulating ret. - p[0] = byte(h.Type<<4 | 1) - binary.BigEndian.PutUint16(p[2:4], h.ConnID) - binary.BigEndian.PutUint32(p[4:8], h.Timestamp) - binary.BigEndian.PutUint32(p[8:12], h.TimestampDiff) - binary.BigEndian.PutUint32(p[12:16], h.WndSize) - binary.BigEndian.PutUint16(p[16:18], h.SeqNr) - binary.BigEndian.PutUint16(p[18:20], h.AckNr) - // Pointer to the last type field so the next extension can set it. - _type := &p[1] - // We're done with the basic header. - p = p[20:] - for _, ext := range h.Extensions { - *_type = ext.Type - // The next extension's type will go here. - _type = &p[0] - p[1] = uint8(len(ext.Bytes)) - if int(p[1]) != copy(p[2:], ext.Bytes) { - panic("unexpected extension length") - } - p = p[2+len(ext.Bytes):] - } - if len(p) != 0 { - panic("header length changed") - } - return -} - -var ( - _ net.Listener = &Socket{} - _ net.PacketConn = &Socket{} -) - -const ( - csInvalid = iota - csSynSent - csConnected - csDestroy -) - -type st int - -func (me st) String() string { - switch me { - case stData: - return "stData" - case stFin: - return "stFin" - case stState: - return "stState" - case stReset: - return "stReset" - case stSyn: - return "stSyn" - default: - panic(fmt.Sprintf("%d", me)) - } -} - -const ( - stData st = 0 - stFin = 1 - stState = 2 - stReset = 3 - stSyn = 4 - - // Used for validating packet headers. - stMax = stSyn -) - -// Conn is a uTP stream and implements net.Conn. It owned by a Socket, which -// handles dispatching packets to and from Conns. -type Conn struct { - mu sync.Mutex - event sync.Cond - - recv_id, send_id uint16 - seq_nr, ack_nr uint16 - lastAck uint16 - lastTimeDiff uint32 - peerWndSize uint32 - - readBuf []byte - - socket *Socket - remoteAddr net.Addr - // The uTP timestamp. - startTimestamp uint32 - // When the conn was allocated. - created time.Time - // Callback to unregister Conn from a parent Socket. Should be called when - // no more packets will be handled. - detach func() - - cs int - gotFin bool - sentFin bool - err error - - unackedSends []*send - // Inbound payloads, the first is ack_nr+1. - inbound []recv - packetsIn chan packet - connDeadlines - latencies []time.Duration - pendingSendState bool - destroyed chan struct{} -} - -type send struct { - acked chan struct{} // Closed with Conn lock. - payloadSize uint32 - started time.Time - // This send was skipped in a selective ack. - resend func() - timedOut func() - conn *Conn - - mu sync.Mutex - acksSkipped int - resendTimer *time.Timer - numResends int -} - -func (s *send) Ack() (latency time.Duration) { - s.mu.Lock() - defer s.mu.Unlock() - s.resendTimer.Stop() - select { - case <-s.acked: - return - default: - close(s.acked) - } - latency = time.Since(s.started) - return -} - -type recv struct { - seen bool - data []byte - Type st -} - -var ( - _ net.Conn = &Conn{} -) - -func (c *Conn) age() time.Duration { - return time.Since(c.created) -} - -func (c *Conn) timestamp() uint32 { - return nowTimestamp() - c.startTimestamp -} - -func (c *Conn) connected() bool { - return c.cs == csConnected -} - -// addr is used to create a listening UDP conn which becomes the underlying -// net.PacketConn for the Socket. -func NewSocket(network, addr string) (s *Socket, err error) { - s = &Socket{ - backlog: make(map[syn]struct{}, backlog), - reads: make(chan read, 100), - closing: make(chan struct{}), - - unusedReads: make(chan read, 100), - } - s.event.L = &s.mu - s.pc, err = net.ListenPacket(network, addr) - if err != nil { - return - } - go s.reader() - go s.dispatcher() - return -} - -func packetDebugString(h *header, payload []byte) string { - return fmt.Sprintf("%s->%d: %q", h.Type, h.ConnID, payload) -} - -func (s *Socket) reader() { - defer close(s.reads) - var b [maxRecvSize]byte - for { - if s.pc == nil { - break - } - n, addr, err := s.pc.ReadFrom(b[:]) - if err != nil { - select { - case <-s.closing: - default: - s.ReadErr = err - } - return - } - var nilB []byte - s.reads <- read{append(nilB, b[:n:n]...), addr} - } -} - -func (s *Socket) unusedRead(read read) { - unusedReads.Add(1) - select { - case s.unusedReads <- read: - default: - // Drop the packet. - } -} - -func stringAddr(s string) net.Addr { - addr, err := net.ResolveUDPAddr("udp", s) - if err != nil { - panic(err) - } - return addr -} - -func (s *Socket) pushBacklog(syn syn) { - if _, ok := s.backlog[syn]; ok { - return - } - for k := range s.backlog { - if len(s.backlog) < backlog { - break - } - delete(s.backlog, k) - // A syn is sent on the remote's recv_id, so this is where we can send - // the reset. - s.reset(stringAddr(k.addr), k.seq_nr, k.conn_id) - } - s.backlog[syn] = struct{}{} - s.event.Broadcast() -} - -func (s *Socket) dispatcher() { - for { - select { - case read, ok := <-s.reads: - if !ok { - return - } - if len(read.data) < 20 { - s.unusedRead(read) - continue - } - s.dispatch(read) - } - } -} - -func (s *Socket) dispatch(read read) { - b := read.data - addr := read.from - var h header - hEnd, err := h.Unmarshal(b) - if logLevel >= 1 { - log.Printf("recvd utp msg: %s", packetDebugString(&h, b[hEnd:])) - } - if err != nil || h.Type > stMax || h.Version != 1 { - s.unusedRead(read) - return - } - s.mu.RLock() - c, ok := s.conns[connKey{resolvedAddrStr(addr.String()), func() (recvID uint16) { - recvID = h.ConnID - // If a SYN is resent, its connection ID field will be one lower - // than we expect. - if h.Type == stSyn { - recvID++ - } - return - }()}] - s.mu.RUnlock() - if ok { - if h.Type == stSyn { - if h.ConnID == c.send_id-2 { - // This is a SYN for connection that cannot exist locally. The - // connection the remote wants to establish here with the proposed - // recv_id, already has an existing connection that was dialled - // *out* from this socket, which is why the send_id is 1 higher, - // rather than 1 lower than the recv_id. - log.Print("resetting conflicting syn") - s.reset(addr, h.SeqNr, h.ConnID) - return - } else if h.ConnID != c.send_id { - panic("bad assumption") - } - } - c.deliver(h, b[hEnd:]) - return - } - if h.Type == stSyn { - if logLevel >= 1 { - log.Printf("adding SYN to backlog") - } - syn := syn{ - seq_nr: h.SeqNr, - conn_id: h.ConnID, - addr: addr.String(), - } - s.mu.Lock() - s.pushBacklog(syn) - s.mu.Unlock() - return - } else if h.Type != stReset { - // This is an unexpected packet. We'll send a reset, but also pass - // it on. - // log.Print("resetting unexpected packet") - // 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. - s.reset(addr, h.SeqNr, h.ConnID) - s.reset(addr, h.SeqNr, h.ConnID-1) - s.reset(addr, h.SeqNr, h.ConnID+1) - } - s.unusedRead(read) -} - -// Send a reset in response to a packet with the given header. -func (s *Socket) reset(addr net.Addr, ackNr, connId uint16) { - go s.writeTo((&header{ - Type: stReset, - Version: 1, - ConnID: connId, - AckNr: ackNr, - }).Marshal(), addr) -} - -// Attempt to connect to a remote uTP listener, creating a Socket just for -// this connection. -func Dial(addr string) (net.Conn, error) { - return DialTimeout(addr, 0) -} - -// Same as Dial with a timeout parameter. -func DialTimeout(addr string, timeout time.Duration) (nc net.Conn, err error) { - s, err := NewSocket("udp", ":0") - if err != nil { - return - } - return s.DialTimeout(addr, timeout) - -} - -// Return a recv_id that should be free. Handling the case where it isn't is -// deferred to a more appropriate function. -func (s *Socket) newConnID(remoteAddr resolvedAddrStr) (id uint16) { - // Rather than use math.Rand, which requires generating all the IDs up - // front and allocating a slice, we do it on the stack, generating the IDs - // only as required. To do this, we use the fact that the array is - // default-initialized. IDs that are 0, are actually their index in the - // array. IDs that are non-zero, are +1 from their intended ID. - var idsBack [0x10000]int - ids := idsBack[:] - for len(ids) != 0 { - // Pick the next ID from the untried ids. - i := rand.Intn(len(ids)) - id = uint16(ids[i]) - // If it's zero, then treat it as though the index i was the ID. - // Otherwise the value we get is the ID+1. - if id == 0 { - id = uint16(i) - } else { - id-- - } - // Check there's no connection using this ID for its recv_id... - _, ok1 := s.conns[connKey{remoteAddr, id}] - // and if we're connecting to our own Socket, that there isn't a Conn - // already receiving on what will correspond to our send_id. Note that - // we just assume that we could be connecting to our own Socket. This - // will halve the available connection IDs to each distinct remote - // address. Presumably that's ~0x8000, down from ~0x10000. - _, ok2 := s.conns[connKey{remoteAddr, id + 1}] - _, ok4 := s.conns[connKey{remoteAddr, id - 1}] - if !ok1 && !ok2 && !ok4 { - return - } - // The set of possible IDs is shrinking. The highest one will be lost, so - // it's moved to the location of the one we just tried. - ids[i] = len(ids) // Conveniently already +1. - // And shrink. - ids = ids[:len(ids)-1] - } - return -} - -func (c *Conn) sendPendingState() { - if !c.pendingSendState { - return - } - c.sendState() -} - -func (s *Socket) newConn(addr net.Addr) (c *Conn) { - c = &Conn{ - socket: s, - remoteAddr: addr, - startTimestamp: nowTimestamp(), - created: time.Now(), - packetsIn: make(chan packet, 100), - destroyed: make(chan struct{}), - } - c.event.L = &c.mu - c.mu.Lock() - c.connDeadlines.read.setCallback(func() { - c.mu.Lock() - c.event.Broadcast() - c.mu.Unlock() - }) - c.connDeadlines.write.setCallback(func() { - c.mu.Lock() - c.event.Broadcast() - c.mu.Unlock() - }) - c.mu.Unlock() - go c.deliveryProcessor() - return -} - -func (s *Socket) Dial(addr string) (net.Conn, error) { - return s.DialTimeout(addr, 0) -} - -func (s *Socket) DialTimeout(addr string, timeout time.Duration) (nc net.Conn, err error) { - netAddr, err := net.ResolveUDPAddr("udp", addr) - if err != nil { - return - } - - s.mu.Lock() - c := s.newConn(netAddr) - c.recv_id = s.newConnID(resolvedAddrStr(netAddr.String())) - c.send_id = c.recv_id + 1 - if logLevel >= 1 { - log.Printf("dial registering addr: %s", netAddr.String()) - } - if !s.registerConn(c.recv_id, resolvedAddrStr(netAddr.String()), c) { - err = errors.New("couldn't register new connection") - log.Println(c.recv_id, netAddr.String()) - for k, c := range s.conns { - log.Println(k, c, c.age()) - } - log.Printf("that's %d connections", len(s.conns)) - } - s.mu.Unlock() - if err != nil { - return - } - - connErr := make(chan error, 1) - go func() { - connErr <- c.connect() - }() - var timeoutCh <-chan time.Time - if timeout != 0 { - timeoutCh = time.After(timeout) - } - select { - case err = <-connErr: - case <-timeoutCh: - c.Close() - err = errTimeout - } - if err == nil { - nc = c - } - return -} - -func (c *Conn) wndSize() uint32 { - if len(c.inbound) > maxUnackedInbound/2 { - return 0 - } - var buffered int - for _, r := range c.inbound { - buffered += len(r.data) - } - buffered += len(c.readBuf) - if buffered >= recvWindow { - return 0 - } - return recvWindow - uint32(buffered) -} - -func nowTimestamp() uint32 { - return uint32(time.Now().UnixNano() / int64(time.Microsecond)) -} - -// Send the given payload with an up to date header. -func (c *Conn) send(_type st, connID uint16, payload []byte, seqNr uint16) (err error) { - // Always selectively ack the first 64 packets. Don't bother with rest for - // now. - selAck := selectiveAckBitmask(make([]byte, 8)) - for i := 1; i < 65; i++ { - if len(c.inbound) <= i { - break - } - if c.inbound[i].seen { - selAck.SetBit(i - 1) - } - } - h := header{ - Type: _type, - Version: 1, - ConnID: connID, - SeqNr: seqNr, - AckNr: c.ack_nr, - WndSize: c.wndSize(), - Timestamp: c.timestamp(), - TimestampDiff: c.lastTimeDiff, - // Currently always send an 8 byte selective ack. - Extensions: []extensionField{{ - Type: extensionTypeSelectiveAck, - Bytes: selAck, - }}, - } - p := h.Marshal() - // Extension headers are currently fixed in size. - if len(p) != maxHeaderSize { - panic("header has unexpected size") - } - p = append(p, payload...) - if logLevel >= 1 { - log.Printf("writing utp msg to %s: %s", c.remoteAddr, packetDebugString(&h, payload)) - } - n1, err := c.socket.writeTo(p, c.remoteAddr) - if err != nil { - return - } - if n1 != len(p) { - panic(n1) - } - c.unpendSendState() - return -} - -func (me *Conn) unpendSendState() { - me.pendingSendState = false -} - -func (c *Conn) pendSendState() { - c.pendingSendState = true -} - -func (me *Socket) writeTo(b []byte, addr net.Addr) (n int, err error) { - mu.RLock() - apdc := artificialPacketDropChance - mu.RUnlock() - if apdc != 0 { - if rand.Float64() < apdc { - n = len(b) - return - } - } - n, err = me.pc.WriteTo(b, addr) - return -} - -func (s *send) timeoutResend() { - select { - case <-s.acked: - return - default: - } - if time.Since(s.started) >= sendTimeout { - s.timedOut() - return - } - s.conn.mu.Lock() - rt := s.conn.resendTimeout() - s.conn.mu.Unlock() - go s.resend() - s.mu.Lock() - s.numResends++ - s.resendTimer.Reset(rt) - s.mu.Unlock() -} - -func (me *Conn) writeSyn() (err error) { - if me.cs != csInvalid { - panic(me.cs) - } - _, err = me.write(stSyn, me.recv_id, nil, me.seq_nr) - return -} - -func (c *Conn) write(_type st, connID uint16, payload []byte, seqNr uint16) (n int, err error) { - switch _type { - case stSyn, stFin, stData: - default: - panic(_type) - } - switch c.cs { - case csConnected, csSynSent, csInvalid: - default: - panic(c.cs) - } - if c.sentFin { - panic(c) - } - if len(payload) > maxPayloadSize { - payload = payload[:maxPayloadSize] - } - err = c.send(_type, connID, payload, seqNr) - if err != nil { - return - } - n = len(payload) - // Copy payload so caller to write can continue to use the buffer. - if payload != nil { - payload = append(sendBufferPool.Get().([]byte)[:0:minMTU], payload...) - } - send := &send{ - acked: make(chan struct{}), - payloadSize: uint32(len(payload)), - started: time.Now(), - resend: func() { - c.mu.Lock() - err := c.send(_type, connID, payload, seqNr) - if err != nil { - log.Printf("error resending packet: %s", err) - } - c.mu.Unlock() - }, - timedOut: func() { - c.mu.Lock() - c.destroy(errAckTimeout) - c.mu.Unlock() - }, - conn: c, - } - send.mu.Lock() - send.resendTimer = time.AfterFunc(c.resendTimeout(), send.timeoutResend) - send.mu.Unlock() - c.unackedSends = append(c.unackedSends, send) - c.seq_nr++ - return -} - -func (c *Conn) latency() (ret time.Duration) { - if len(c.latencies) == 0 { - // Sort of the p95 of latencies? - return 200 * time.Millisecond - } - for _, l := range c.latencies { - ret += l - } - ret = (ret + time.Duration(len(c.latencies)) - 1) / time.Duration(len(c.latencies)) - return -} - -func (c *Conn) numUnackedSends() (num int) { - for _, s := range c.unackedSends { - select { - case <-s.acked: - default: - num++ - } - } - return -} - -func (c *Conn) cur_window() (window uint32) { - for _, s := range c.unackedSends { - select { - case <-s.acked: - default: - window += s.payloadSize - } - } - return -} - -func (c *Conn) sendState() { - c.send(stState, c.send_id, nil, c.seq_nr) - sentStatePackets.Add(1) -} - -func seqLess(a, b uint16) bool { - if b < 0x8000 { - return a < b || a >= b-0x8000 - } else { - return a < b && a >= b-0x8000 - } -} - -// Ack our send with the given sequence number. -func (c *Conn) ack(nr uint16) { - if !seqLess(c.lastAck, nr) { - // Already acked. - return - } - i := nr - c.lastAck - 1 - if int(i) >= len(c.unackedSends) { - log.Printf("got ack ahead of syn (%x > %x)", nr, c.seq_nr-1) - return - } - latency := c.unackedSends[i].Ack() - if latency != 0 { - c.latencies = append(c.latencies, latency) - if len(c.latencies) > 10 { - c.latencies = c.latencies[len(c.latencies)-10:] - } - } - for { - if len(c.unackedSends) == 0 { - break - } - select { - case <-c.unackedSends[0].acked: - default: - // Can't trim unacked sends any further. - return - } - // Trim the front of the unacked sends. - c.unackedSends = c.unackedSends[1:] - c.lastAck++ - } - c.event.Broadcast() -} - -func (c *Conn) ackTo(nr uint16) { - if !seqLess(nr, c.seq_nr) { - return - } - for seqLess(c.lastAck, nr) { - c.ack(c.lastAck + 1) - } -} - -type selectiveAckBitmask []byte - -func (me selectiveAckBitmask) NumBits() int { - return len(me) * 8 -} - -func (me selectiveAckBitmask) SetBit(index int) { - me[index/8] |= 1 << uint(index%8) -} - -func (me selectiveAckBitmask) BitIsSet(index int) bool { - return me[index/8]>>uint(index%8)&1 == 1 -} - -// Return the send state for the sequence number. Returns nil if there's no -// outstanding send for that sequence number. -func (c *Conn) seqSend(seqNr uint16) *send { - if !seqLess(c.lastAck, seqNr) { - // Presumably already acked. - return nil - } - i := int(seqNr - c.lastAck - 1) - if i >= len(c.unackedSends) { - // No such send. - return nil - } - return c.unackedSends[i] -} - -func (c *Conn) resendTimeout() time.Duration { - l := c.latency() - if l < 10*time.Millisecond { - l = 10 * time.Millisecond - } - ret := jitter.Duration(3*l, l) - // log.Print(ret) - return ret -} - -func (c *Conn) ackSkipped(seqNr uint16) { - send := c.seqSend(seqNr) - if send == nil { - return - } - send.mu.Lock() - defer send.mu.Unlock() - send.acksSkipped++ - switch send.acksSkipped { - case 3, 60: - ackSkippedResends.Add(1) - go send.resend() - send.resendTimer.Reset(c.resendTimeout()) - default: - } -} - -type packet struct { - h header - payload []byte -} - -func (c *Conn) deliver(h header, payload []byte) { - c.packetsIn <- packet{h, payload} -} - -func (c *Conn) deliveryProcessor() { - for { - select { - case p := <-c.packetsIn: - c.processDelivery(p.h, p.payload) - timeout := time.After(500 * time.Microsecond) - batched: - for { - select { - case p := <-c.packetsIn: - c.processDelivery(p.h, p.payload) - case <-timeout: - break batched - } - } - c.mu.Lock() - c.sendPendingState() - c.mu.Unlock() - case <-c.destroyed: - return - } - } -} - -func (c *Conn) processDelivery(h header, payload []byte) { - deliveriesProcessed.Add(1) - c.mu.Lock() - defer c.mu.Unlock() - defer c.event.Broadcast() - c.assertHeader(h) - c.peerWndSize = h.WndSize - c.applyAcks(h) - if h.Timestamp == 0 { - c.lastTimeDiff = 0 - } else { - c.lastTimeDiff = c.timestamp() - h.Timestamp - } - - // We want this connection destroyed, and our peer has acked everything. - if c.sentFin && len(c.unackedSends) == 0 { - // log.Print("gracefully completed") - c.destroy(nil) - return - } - if h.Type == stReset { - c.destroy(errors.New("peer reset")) - return - } - if c.cs == csSynSent { - if h.Type != stState { - return - } - c.changeState(csConnected) - c.ack_nr = h.SeqNr - 1 - return - } - if h.Type == stState { - return - } - c.pendSendState() - if !seqLess(c.ack_nr, h.SeqNr) { - // Already received this packet. - return - } - inboundIndex := int(h.SeqNr - c.ack_nr - 1) - if inboundIndex < len(c.inbound) && c.inbound[inboundIndex].seen { - // Already received this packet. - return - } - // Derived from running in production: - // grep -oP '(?<=packet out of order, index=)\d+' log | sort -n | uniq -c - // 64 should correspond to 8 bytes of selective ack. - if inboundIndex >= maxUnackedInbound { - // Discard packet too far ahead. - if missinggo.CryHeard() { - // I can't tell if this occurs due to bad peers, or something - // missing in the implementation. - log.Printf("received packet from %s %d ahead of next seqnr (%x > %x)", c.remoteAddr, inboundIndex, h.SeqNr, c.ack_nr+1) - } - return - } - // Extend inbound so the new packet has a place. - for inboundIndex >= len(c.inbound) { - c.inbound = append(c.inbound, recv{}) - } - c.inbound[inboundIndex] = recv{true, payload, h.Type} - c.processInbound() -} - -func (c *Conn) applyAcks(h header) { - c.ackTo(h.AckNr) - for _, ext := range h.Extensions { - switch ext.Type { - case extensionTypeSelectiveAck: - c.ackSkipped(h.AckNr + 1) - bitmask := selectiveAckBitmask(ext.Bytes) - for i := 0; i < bitmask.NumBits(); i++ { - if bitmask.BitIsSet(i) { - nr := h.AckNr + 2 + uint16(i) - // log.Printf("selectively acked %d", nr) - c.ack(nr) - } else { - c.ackSkipped(h.AckNr + 2 + uint16(i)) - } - } - } - } -} - -func (c *Conn) assertHeader(h header) { - if h.Type == stSyn { - if h.ConnID != c.send_id { - panic(fmt.Sprintf("%d != %d", h.ConnID, c.send_id)) - } - } else { - if h.ConnID != c.recv_id { - panic("erroneous delivery") - } - } -} - -func (c *Conn) processInbound() { - // Consume consecutive next packets. - for !c.gotFin && len(c.inbound) > 0 && c.inbound[0].seen { - c.ack_nr++ - p := c.inbound[0] - c.inbound = c.inbound[1:] - c.readBuf = append(c.readBuf, p.data...) - if p.Type == stFin { - c.gotFin = true - } - } -} - -func (c *Conn) waitAck(seq uint16) { - send := c.seqSend(seq) - if send == nil { - return - } - c.mu.Unlock() - defer c.mu.Lock() - <-send.acked - return -} - -func (c *Conn) changeState(cs int) { - // log.Println(c, "goes", c.cs, "->", cs) - c.cs = cs -} - -func (c *Conn) connect() error { - c.mu.Lock() - defer c.mu.Unlock() - c.seq_nr = 1 - err := c.writeSyn() - if err != nil { - return err - } - c.changeState(csSynSent) - if logLevel >= 2 { - log.Printf("sent syn") - } - // c.seq_nr++ - c.waitAck(1) - if c.err != nil { - err = c.err - } - c.event.Broadcast() - return err -} - -// Returns true if the connection was newly registered, false otherwise. -func (s *Socket) registerConn(recvID uint16, remoteAddr resolvedAddrStr, c *Conn) bool { - if s.conns == nil { - s.conns = make(map[connKey]*Conn) - } - key := connKey{remoteAddr, recvID} - if _, ok := s.conns[key]; ok { - return false - } - s.conns[key] = c - c.detach = func() { - s.mu.Lock() - defer s.mu.Unlock() - defer s.event.Broadcast() - if s.conns[key] != c { - panic("conn changed") - } - // log.Println("detached", key) - delete(s.conns, key) - if len(s.conns) == 0 { - s.pc.Close() - } - } - return true -} - -func (s *Socket) nextSyn() (syn syn, ok bool) { - s.mu.Lock() - defer s.mu.Unlock() - for { - for k := range s.backlog { - syn = k - delete(s.backlog, k) - ok = true - return - } - select { - case <-s.closing: - return - default: - } - s.event.Wait() - } -} - -// Accept and return a new uTP connection. -func (s *Socket) Accept() (c net.Conn, err error) { - for { - syn, ok := s.nextSyn() - if !ok { - err = errClosed - return - } - s.mu.Lock() - _c := s.newConn(stringAddr(syn.addr)) - _c.send_id = syn.conn_id - _c.recv_id = _c.send_id + 1 - _c.seq_nr = uint16(rand.Int()) - _c.lastAck = _c.seq_nr - 1 - _c.ack_nr = syn.seq_nr - _c.cs = csConnected - if !s.registerConn(_c.recv_id, resolvedAddrStr(syn.addr), _c) { - // SYN that triggered this accept duplicates existing connection. - // Ack again in case the SYN was a resend. - _c = s.conns[connKey{resolvedAddrStr(syn.addr), _c.recv_id}] - if _c.send_id != syn.conn_id { - panic(":|") - } - _c.sendState() - s.mu.Unlock() - continue - } - _c.sendState() - // _c.seq_nr++ - c = _c - s.mu.Unlock() - return - } -} - -// The address we're listening on for new uTP connections. -func (s *Socket) Addr() net.Addr { - return s.pc.LocalAddr() -} - -// Marks the Socket for close. Currently this just axes the underlying OS -// socket. -func (s *Socket) Close() (err error) { - s.mu.Lock() - defer s.mu.Unlock() - select { - case <-s.closing: - return - default: - } - s.event.Broadcast() - close(s.closing) - if len(s.conns) == 0 { - err = s.pc.Close() - } - return -} - -func (s *Socket) LocalAddr() net.Addr { - return s.pc.LocalAddr() -} - -func (s *Socket) ReadFrom(p []byte) (n int, addr net.Addr, err error) { - read, ok := <-s.unusedReads - if !ok { - err = io.EOF - } - n = copy(p, read.data) - addr = read.from - return -} - -func (s *Socket) WriteTo(b []byte, addr net.Addr) (int, error) { - return s.pc.WriteTo(b, addr) -} - -func (c *Conn) writeFin() (err error) { - if c.sentFin { - return - } - _, err = c.write(stFin, c.send_id, nil, c.seq_nr) - if err != nil { - return - } - c.sentFin = true - c.event.Broadcast() - return -} - -func (c *Conn) destroy(reason error) { - if c.err != nil && reason != nil { - log.Printf("duplicate destroy call: %s", reason) - } - if c.cs == csDestroy { - return - } - close(c.destroyed) - c.writeFin() - c.changeState(csDestroy) - c.err = reason - c.event.Broadcast() - c.detach() - for _, s := range c.unackedSends { - s.Ack() - } -} - -func (c *Conn) Close() error { - c.mu.Lock() - defer c.mu.Unlock() - return c.writeFin() -} - -func (c *Conn) LocalAddr() net.Addr { - return c.socket.Addr() -} - -func (c *Conn) Read(b []byte) (n int, err error) { - c.mu.Lock() - defer c.mu.Unlock() - for { - if len(c.readBuf) != 0 { - break - } - if c.cs == csDestroy || c.gotFin || c.sentFin { - err = c.err - if err == nil { - err = io.EOF - } - return - } - if c.connDeadlines.read.deadlineExceeded() { - err = errTimeout - return - } - if logLevel >= 2 { - log.Printf("nothing to read, state=%d", c.cs) - } - c.event.Wait() - } - n = copy(b, c.readBuf) - c.readBuf = c.readBuf[n:] - - return -} - -func (c *Conn) RemoteAddr() net.Addr { - return c.remoteAddr -} - -func (c *Conn) String() string { - return fmt.Sprintf("", c.LocalAddr(), c.RemoteAddr(), c.recv_id) -} - -func (c *Conn) Write(p []byte) (n int, err error) { - c.mu.Lock() - defer c.mu.Unlock() - for len(p) != 0 { - for { - if c.sentFin { - err = io.ErrClosedPipe - return - } - // If peerWndSize is 0, we still want to send something, so don't - // block until we exceed it. - if c.cur_window() <= c.peerWndSize && len(c.unackedSends) < 64 && c.cs == csConnected { - break - } - if c.connDeadlines.write.deadlineExceeded() { - err = errTimeout - return - } - c.event.Wait() - } - var n1 int - n1, err = c.write(stData, c.send_id, p, c.seq_nr) - if err != nil { - return - } - // c.seq_nr++ - n += n1 - p = p[n1:] - } - return -} diff --git a/Godeps/_workspace/src/github.com/anacrolix/utp/utp_test.go b/Godeps/_workspace/src/github.com/anacrolix/utp/utp_test.go deleted file mode 100644 index b118d8e..0000000 --- a/Godeps/_workspace/src/github.com/anacrolix/utp/utp_test.go +++ /dev/null @@ -1,411 +0,0 @@ -package utp - -import ( - "fmt" - "io" - "io/ioutil" - "log" - "net" - "runtime" - "sync" - "testing" - "time" - - _ "github.com/anacrolix/envpprof" - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo" - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/bradfitz/iter" - "github.com/stretchr/testify/require" -) - -func init() { - log.SetFlags(log.Flags() | log.Lshortfile) -} - -func TestUTPPingPong(t *testing.T) { - defer goroutineLeakCheck(t)() - s, err := NewSocket("udp", "localhost:0") - require.NoError(t, err) - defer s.Close() - pingerClosed := make(chan struct{}) - go func() { - defer close(pingerClosed) - b, err := Dial(s.Addr().String()) - require.NoError(t, err) - defer b.Close() - n, err := b.Write([]byte("ping")) - require.NoError(t, err) - require.EqualValues(t, 4, n) - buf := make([]byte, 4) - b.Read(buf) - require.EqualValues(t, "pong", buf) - log.Printf("got pong") - }() - a, err := s.Accept() - require.NoError(t, err) - defer a.Close() - log.Printf("accepted %s", a) - buf := make([]byte, 42) - n, err := a.Read(buf) - require.NoError(t, err) - require.EqualValues(t, "ping", buf[:n]) - log.Print("got ping") - n, err = a.Write([]byte("pong")) - require.NoError(t, err) - require.Equal(t, 4, n) - log.Print("waiting for pinger to close") - <-pingerClosed -} - -func goroutineLeakCheck(t testing.TB) func() { - if !testing.Verbose() { - return func() {} - } - numStart := runtime.NumGoroutine() - return func() { - var numNow int - for _ = range iter.N(1) { - numNow = runtime.NumGoroutine() - if numNow == numStart { - return - } - time.Sleep(10 * time.Millisecond) - } - // I'd print stacks, or treat this as fatal, but I think - // runtime.NumGoroutine is including system routines for which we are - // not provided the stacks, and are spawned unpredictably. - t.Logf("have %d goroutines, started with %d", numNow, numStart) - } -} - -func TestDialTimeout(t *testing.T) { - defer goroutineLeakCheck(t)() - s, _ := NewSocket("udp", "localhost:0") - defer s.Close() - conn, err := DialTimeout(s.Addr().String(), 10*time.Millisecond) - if err == nil { - conn.Close() - t.Fatal("expected timeout") - } - t.Log(err) -} - -func TestMinMaxHeaderType(t *testing.T) { - require.Equal(t, stSyn, stMax) -} - -func TestUTPRawConn(t *testing.T) { - l, err := NewSocket("udp", "") - require.NoError(t, err) - defer l.Close() - go func() { - for { - _, err := l.Accept() - if err != nil { - break - } - } - }() - // Connect a UTP peer to see if the RawConn will still work. - log.Print("dialing") - utpPeer := func() net.Conn { - s, _ := NewSocket("udp", "") - defer s.Close() - ret, err := s.Dial(fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr()))) - require.NoError(t, err) - return ret - }() - log.Print("dial returned") - if err != nil { - t.Fatalf("error dialing utp listener: %s", err) - } - defer utpPeer.Close() - peer, err := net.ListenPacket("udp", ":0") - if err != nil { - t.Fatal(err) - } - defer peer.Close() - - msgsReceived := 0 - const N = 5000 // How many messages to send. - readerStopped := make(chan struct{}) - // The reader goroutine. - go func() { - defer close(readerStopped) - b := make([]byte, 500) - for i := 0; i < N; i++ { - n, _, err := l.ReadFrom(b) - if err != nil { - t.Fatalf("error reading from raw conn: %s", err) - } - msgsReceived++ - var d int - fmt.Sscan(string(b[:n]), &d) - if d != i { - log.Printf("got wrong number: expected %d, got %d", i, d) - } - } - }() - udpAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("localhost:%d", missinggo.AddrPort(l.Addr()))) - if err != nil { - t.Fatal(err) - } - for i := 0; i < N; i++ { - _, err := peer.WriteTo([]byte(fmt.Sprintf("%d", i)), udpAddr) - if err != nil { - t.Fatal(err) - } - time.Sleep(time.Microsecond) - } - select { - case <-readerStopped: - case <-time.After(time.Second): - t.Fatal("reader timed out") - } - if msgsReceived != N { - t.Fatalf("messages received: %d", msgsReceived) - } -} - -func TestConnReadDeadline(t *testing.T) { - ls, _ := NewSocket("udp", "localhost:0") - ds, _ := NewSocket("udp", "localhost:0") - dcReadErr := make(chan error) - go func() { - c, _ := ds.Dial(ls.Addr().String()) - defer c.Close() - _, err := c.Read(nil) - dcReadErr <- err - }() - c, _ := ls.Accept() - dl := time.Now().Add(time.Millisecond) - c.SetReadDeadline(dl) - _, err := c.Read(nil) - require.Equal(t, errTimeout, err) - // The deadline has passed. - if !time.Now().After(dl) { - t.FailNow() - } - // Returns timeout on subsequent read. - _, err = c.Read(nil) - require.Equal(t, errTimeout, err) - // Disable the deadline. - c.SetReadDeadline(time.Time{}) - readReturned := make(chan struct{}) - go func() { - c.Read(nil) - close(readReturned) - }() - select { - case <-readReturned: - // Read returned but shouldn't have. - t.FailNow() - case <-time.After(time.Millisecond): - } - c.Close() - select { - case <-readReturned: - case <-time.After(time.Millisecond): - t.Fatal("read should return after Conn is closed") - } - if err := <-dcReadErr; err != io.EOF { - t.Fatalf("dial conn read returned %s", err) - } -} - -func connectSelfLots(n int, t testing.TB) { - defer goroutineLeakCheck(t)() - s, err := NewSocket("udp", "localhost:0") - if err != nil { - t.Fatal(err) - } - go func() { - for _ = range iter.N(n) { - c, err := s.Accept() - if err != nil { - log.Fatal(err) - } - defer c.Close() - } - }() - dialErr := make(chan error) - connCh := make(chan net.Conn) - dialSema := make(chan struct{}, backlog) - for _ = range iter.N(n) { - go func() { - dialSema <- struct{}{} - c, err := s.Dial(s.Addr().String()) - <-dialSema - if err != nil { - dialErr <- err - return - } - connCh <- c - }() - } - conns := make([]net.Conn, 0, n) - for _ = range iter.N(n) { - select { - case c := <-connCh: - conns = append(conns, c) - case err := <-dialErr: - t.Fatal(err) - } - } - for _, c := range conns { - if c != nil { - c.Close() - } - } - s.mu.Lock() - for len(s.conns) != 0 { - // log.Print(len(s.conns)) - s.event.Wait() - } - s.mu.Unlock() - s.Close() -} - -// Connect to ourself heaps. -func TestConnectSelf(t *testing.T) { - // A rough guess says that at worst, I can only have 0x10000/3 connections - // to the same socket, due to fragmentation in the assigned connection - // IDs. - connectSelfLots(0x1000, t) -} - -func BenchmarkConnectSelf(b *testing.B) { - for _ = range iter.N(b.N) { - connectSelfLots(2, b) - } -} - -func BenchmarkNewCloseSocket(b *testing.B) { - for _ = range iter.N(b.N) { - s, err := NewSocket("udp", "localhost:0") - if err != nil { - b.Fatal(err) - } - err = s.Close() - if err != nil { - b.Fatal(err) - } - } -} - -func TestRejectDialBacklogFilled(t *testing.T) { - s, err := NewSocket("udp", "localhost:0") - if err != nil { - t.Fatal(err) - } - errChan := make(chan error, 1) - dial := func() { - _, err := s.Dial(s.Addr().String()) - if err != nil { - errChan <- err - } - } - // Fill the backlog. - for _ = range iter.N(backlog + 1) { - go dial() - } - s.mu.Lock() - for len(s.backlog) < backlog { - s.event.Wait() - } - s.mu.Unlock() - select { - case <-errChan: - t.FailNow() - default: - } - // One more connection should cause a dial attempt to get reset. - go dial() - err = <-errChan - if err.Error() != "peer reset" { - t.FailNow() - } - s.Close() -} - -// Make sure that we can reset AfterFunc timers, so we don't have to create -// brand new ones everytime they fire. Specifically for the Conn resend timer. -func TestResetAfterFuncTimer(t *testing.T) { - fired := make(chan struct{}) - timer := time.AfterFunc(time.Millisecond, func() { - fired <- struct{}{} - }) - <-fired - if timer.Reset(time.Millisecond) { - // The timer should have expired - t.FailNow() - } - <-fired -} - -func connPair() (initer, accepted net.Conn) { - s, err := NewSocket("udp", "localhost:0") - if err != nil { - panic(err) - } - defer s.Close() - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - var err error - initer, err = Dial(s.Addr().String()) - if err != nil { - panic(err) - } - }() - accepted, err = s.Accept() - if err != nil { - panic(err) - } - wg.Wait() - return -} - -// Check that peer sending FIN doesn't cause unread data to be dropped in a -// receiver. -func TestReadFinishedConn(t *testing.T) { - a, b := connPair() - defer a.Close() - defer b.Close() - mu.Lock() - originalAPDC := artificialPacketDropChance - artificialPacketDropChance = 1 - mu.Unlock() - n, err := a.Write([]byte("hello")) - require.Equal(t, 5, n) - require.NoError(t, err) - n, err = a.Write([]byte("world")) - require.Equal(t, 5, n) - require.NoError(t, err) - mu.Lock() - artificialPacketDropChance = originalAPDC - mu.Unlock() - a.Close() - all, err := ioutil.ReadAll(b) - require.NoError(t, err) - require.EqualValues(t, "helloworld", all) -} - -func TestCloseDetachesQuickly(t *testing.T) { - s, _ := NewSocket("udp", "localhost:0") - defer s.Close() - go func() { - a, _ := s.Dial(s.Addr().String()) - log.Print("close a") - a.Close() - log.Print("closed a") - }() - b, _ := s.Accept() - b.Close() - s.mu.Lock() - for len(s.conns) != 0 { - log.Print(len(s.conns)) - s.event.Wait() - } - s.mu.Unlock() -} diff --git a/Godeps/_workspace/src/github.com/bradfitz/iter/.gitignore b/Godeps/_workspace/src/github.com/bradfitz/iter/.gitignore deleted file mode 100644 index b25c15b..0000000 --- a/Godeps/_workspace/src/github.com/bradfitz/iter/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*~ diff --git a/Godeps/_workspace/src/github.com/bradfitz/iter/README.txt b/Godeps/_workspace/src/github.com/bradfitz/iter/README.txt deleted file mode 100644 index 763a71c..0000000 --- a/Godeps/_workspace/src/github.com/bradfitz/iter/README.txt +++ /dev/null @@ -1 +0,0 @@ -See http://godoc.org/github.com/bradfitz/iter diff --git a/Godeps/_workspace/src/github.com/bradfitz/iter/iter.go b/Godeps/_workspace/src/github.com/bradfitz/iter/iter.go deleted file mode 100644 index 547b3d9..0000000 --- a/Godeps/_workspace/src/github.com/bradfitz/iter/iter.go +++ /dev/null @@ -1,17 +0,0 @@ -// Package iter provides a syntantically different way to iterate over integers. That's it. -package iter - -// N returns a slice of n 0-sized elements, suitable for ranging over. -// -// For example: -// -// for i := range iter.N(10) { -// fmt.Println(i) -// } -// -// ... will print 0 to 9, inclusive. -// -// It does not cause any allocations. -func N(n int) []struct{} { - return make([]struct{}, n) -} diff --git a/Godeps/_workspace/src/github.com/bradfitz/iter/iter_test.go b/Godeps/_workspace/src/github.com/bradfitz/iter/iter_test.go deleted file mode 100644 index b294261..0000000 --- a/Godeps/_workspace/src/github.com/bradfitz/iter/iter_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package iter_test - -import ( - "fmt" - "testing" - - "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/bradfitz/iter" -) - -func ExampleN() { - for i := range iter.N(4) { - fmt.Println(i) - } - // Output: - // 0 - // 1 - // 2 - // 3 -} - -func TestAllocs(t *testing.T) { - var x []struct{} - allocs := testing.AllocsPerRun(500, func() { - x = iter.N(1e9) - }) - if allocs > 0.1 { - t.Errorf("allocs = %v", allocs) - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-base58/LICENSE b/Godeps/_workspace/src/github.com/jbenet/go-base58/LICENSE deleted file mode 100644 index 0d760cb..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-base58/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (c) 2013 Conformal Systems LLC. - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/jbenet/go-base58/README.md b/Godeps/_workspace/src/github.com/jbenet/go-base58/README.md deleted file mode 100644 index ece2433..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-base58/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# go-base58 - -I extracted this package from https://github.com/conformal/btcutil to provide a simple base58 package that -- defaults to base58-check (btc) -- and allows using different alphabets. - -## Usage - -```go -package main - -import ( - "fmt" - b58 "github.com/jbenet/go-base58" -) - -func main() { - buf := []byte{255, 254, 253, 252} - fmt.Printf("buffer: %v\n", buf) - - str := b58.Encode(buf) - fmt.Printf("encoded: %s\n", str) - - buf2 := b58.Decode(str) - fmt.Printf("decoded: %v\n", buf2) -} -``` - -### Another alphabet - -```go -package main - -import ( - "fmt" - b58 "github.com/jbenet/go-base58" -) - -const BogusAlphabet = "ZYXWVUTSRQPNMLKJHGFEDCBAzyxwvutsrqponmkjihgfedcba987654321" - - -func encdec(alphabet string) { - fmt.Printf("using: %s\n", alphabet) - - buf := []byte{255, 254, 253, 252} - fmt.Printf("buffer: %v\n", buf) - - str := b58.EncodeAlphabet(buf, alphabet) - fmt.Printf("encoded: %s\n", str) - - buf2 := b58.DecodeAlphabet(str, alphabet) - fmt.Printf("decoded: %v\n\n", buf2) -} - - -func main() { - encdec(b58.BTCAlphabet) - encdec(b58.FlickrAlphabet) - encdec(BogusAlphabet) -} -``` - - -## License - -Package base58 (and the original btcutil) are licensed under the ISC License. diff --git a/Godeps/_workspace/src/github.com/jbenet/go-base58/base58.go b/Godeps/_workspace/src/github.com/jbenet/go-base58/base58.go deleted file mode 100644 index ad91df5..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-base58/base58.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2013-2014 Conformal Systems LLC. -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. -// Modified by Juan Benet (juan@benet.ai) - -package base58 - -import ( - "math/big" - "strings" -) - -// alphabet is the modified base58 alphabet used by Bitcoin. -const BTCAlphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" -const FlickrAlphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ" - -var bigRadix = big.NewInt(58) -var bigZero = big.NewInt(0) - -// Decode decodes a modified base58 string to a byte slice, using BTCAlphabet -func Decode(b string) []byte { - return DecodeAlphabet(b, BTCAlphabet) -} - -// Encode encodes a byte slice to a modified base58 string, using BTCAlphabet -func Encode(b []byte) string { - return EncodeAlphabet(b, BTCAlphabet) -} - -// DecodeAlphabet decodes a modified base58 string to a byte slice, using alphabet. -func DecodeAlphabet(b, alphabet string) []byte { - answer := big.NewInt(0) - j := big.NewInt(1) - - for i := len(b) - 1; i >= 0; i-- { - tmp := strings.IndexAny(alphabet, string(b[i])) - if tmp == -1 { - return []byte("") - } - idx := big.NewInt(int64(tmp)) - tmp1 := big.NewInt(0) - tmp1.Mul(j, idx) - - answer.Add(answer, tmp1) - j.Mul(j, bigRadix) - } - - tmpval := answer.Bytes() - - var numZeros int - for numZeros = 0; numZeros < len(b); numZeros++ { - if b[numZeros] != alphabet[0] { - break - } - } - flen := numZeros + len(tmpval) - val := make([]byte, flen, flen) - copy(val[numZeros:], tmpval) - - return val -} - -// Encode encodes a byte slice to a modified base58 string, using alphabet -func EncodeAlphabet(b []byte, alphabet string) string { - x := new(big.Int) - x.SetBytes(b) - - answer := make([]byte, 0, len(b)*136/100) - for x.Cmp(bigZero) > 0 { - mod := new(big.Int) - x.DivMod(x, bigRadix, mod) - answer = append(answer, alphabet[mod.Int64()]) - } - - // leading zero bytes - for _, i := range b { - if i != 0 { - break - } - answer = append(answer, alphabet[0]) - } - - // reverse - alen := len(answer) - for i := 0; i < alen/2; i++ { - answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i] - } - - return string(answer) -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-base58/base58_test.go b/Godeps/_workspace/src/github.com/jbenet/go-base58/base58_test.go deleted file mode 100644 index 516781b..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-base58/base58_test.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2013-2014 Conformal Systems LLC. -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package base58 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -var stringTests = []struct { - in string - out string -}{ - {"", ""}, - {" ", "Z"}, - {"-", "n"}, - {"0", "q"}, - {"1", "r"}, - {"-1", "4SU"}, - {"11", "4k8"}, - {"abc", "ZiCa"}, - {"1234598760", "3mJr7AoUXx2Wqd"}, - {"abcdefghijklmnopqrstuvwxyz", "3yxU3u1igY8WkgtjK92fbJQCd4BZiiT1v25f"}, - {"00000000000000000000000000000000000000000000000000000000000000", "3sN2THZeE9Eh9eYrwkvZqNstbHGvrxSAM7gXUXvyFQP8XvQLUqNCS27icwUeDT7ckHm4FUHM2mTVh1vbLmk7y"}, -} - -var invalidStringTests = []struct { - in string - out string -}{ - {"0", ""}, - {"O", ""}, - {"I", ""}, - {"l", ""}, - {"3mJr0", ""}, - {"O3yxU", ""}, - {"3sNI", ""}, - {"4kl8", ""}, - {"0OIl", ""}, - {"!@#$%^&*()-_=+~`", ""}, -} - -var hexTests = []struct { - in string - out string -}{ - {"61", "2g"}, - {"626262", "a3gV"}, - {"636363", "aPEr"}, - {"73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2"}, - {"00eb15231dfceb60925886b67d065299925915aeb172c06647", "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L"}, - {"516b6fcd0f", "ABnLTmg"}, - {"bf4f89001e670274dd", "3SEo3LWLoPntC"}, - {"572e4794", "3EFU7m"}, - {"ecac89cad93923c02321", "EJDM8drfXA6uyA"}, - {"10c8511e", "Rt5zm"}, - {"00000000000000000000", "1111111111"}, -} - -func TestBase58(t *testing.T) { - // Base58Encode tests - for x, test := range stringTests { - tmp := []byte(test.in) - if res := Encode(tmp); res != test.out { - t.Errorf("Base58Encode test #%d failed: got: %s want: %s", - x, res, test.out) - continue - } - } - - // Base58Decode tests - for x, test := range hexTests { - b, err := hex.DecodeString(test.in) - if err != nil { - t.Errorf("hex.DecodeString failed failed #%d: got: %s", x, test.in) - continue - } - if res := Decode(test.out); bytes.Equal(res, b) != true { - t.Errorf("Base58Decode test #%d failed: got: %q want: %q", - x, res, test.in) - continue - } - } - - // Base58Decode with invalid input - for x, test := range invalidStringTests { - if res := Decode(test.in); string(res) != test.out { - t.Errorf("Base58Decode invalidString test #%d failed: got: %q want: %q", - x, res, test.out) - continue - } - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-base58/doc.go b/Godeps/_workspace/src/github.com/jbenet/go-base58/doc.go deleted file mode 100644 index 315c610..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-base58/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2013-2014 Conformal Systems LLC. -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -/* -Package base58 provides base58-check encoding. -The alphabet is modifyiable for - -Base58 Usage - -To decode a base58 string: - - rawData := base58.Base58Decode(encodedData) - -Similarly, to encode the same data: - - encodedData := base58.Base58Encode(rawData) - -*/ -package base58 diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/.travis.yml b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/.travis.yml deleted file mode 100644 index 7b571f4..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - 1.3 - - release - - tip - -script: - - go test -race -cpu=5 -v ./... diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/LICENSE b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/LICENSE deleted file mode 100644 index c7386b3..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Juan Batiz-Benet - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md deleted file mode 100644 index 42c23ff..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# go-multiaddr - -[multiaddr](https://github.com/jbenet/multiaddr) implementation in Go. - -## Example - -### Simple - -```go -import ma "github.com/jbenet/go-multiaddr" - -// construct from a string (err signals parse failure) -m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") - -// construct from bytes (err signals parse failure) -m2, err := ma.NewMultiaddrBytes(m1.Bytes()) - -// true -strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") -strings.Equal(m1.String(), m2.String()) -bytes.Equal(m1.Bytes(), m2.Bytes()) -m1.Equal(m2) -m2.Equal(m1) -``` - -### Protocols - -```go -// get the multiaddr protocol description objects -addr.Protocols() -// []Protocol{ -// Protocol{ Code: 4, Name: 'ip4', Size: 32}, -// Protocol{ Code: 17, Name: 'udp', Size: 16}, -// } -``` - -### En/decapsulate - -```go -m.Encapsulate(ma.NewMultiaddr("/sctp/5678")) -// -m.Decapsulate(ma.NewMultiaddr("/udp")) // up to + inc last occurrence of subaddr -// -``` - -### Tunneling - -Multiaddr allows expressing tunnels very nicely. - -```js -printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") -proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") -printerOverProxy := proxy.Encapsulate(printer) -// /ip4/10.20.30.40/tcp/443/ip4/192.168.0.13/tcp/80 - -proxyAgain := printerOverProxy.Decapsulate(printer) -// /ip4/10.20.30.40/tcp/443 -``` diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go deleted file mode 100644 index c318873..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go +++ /dev/null @@ -1,209 +0,0 @@ -package multiaddr - -import ( - "encoding/binary" - "errors" - "fmt" - "net" - "strconv" - "strings" - - mh "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multihash" -) - -func stringToBytes(s string) ([]byte, error) { - - // consume trailing slashes - s = strings.TrimRight(s, "/") - - b := []byte{} - sp := strings.Split(s, "/") - - if sp[0] != "" { - return nil, fmt.Errorf("invalid multiaddr, must begin with /") - } - - // consume first empty elem - sp = sp[1:] - - for len(sp) > 0 { - p := ProtocolWithName(sp[0]) - if p.Code == 0 { - return nil, fmt.Errorf("no protocol with name %s", sp[0]) - } - b = append(b, CodeToVarint(p.Code)...) - sp = sp[1:] - - if p.Size == 0 { // no length. - continue - } - - if len(sp) < 1 { - return nil, fmt.Errorf("protocol requires address, none given: %s", p.Name) - } - a, err := addressStringToBytes(p, sp[0]) - if err != nil { - return nil, fmt.Errorf("failed to parse %s: %s %s", p.Name, sp[0], err) - } - b = append(b, a...) - sp = sp[1:] - } - return b, nil -} - -func bytesToString(b []byte) (ret string, err error) { - // panic handler, in case we try accessing bytes incorrectly. - defer func() { - if e := recover(); e != nil { - ret = "" - switch e := e.(type) { - case error: - err = e - case string: - err = errors.New(e) - default: - err = fmt.Errorf("%v", e) - } - } - }() - - s := "" - - for len(b) > 0 { - - code, n := ReadVarintCode(b) - b = b[n:] - p := ProtocolWithCode(code) - if p.Code == 0 { - return "", fmt.Errorf("no protocol with code %d", code) - } - s += "/" + p.Name - - if p.Size == 0 { - continue - } - - size := sizeForAddr(p, b) - a, err := addressBytesToString(p, b[:size]) - if err != nil { - return "", err - } - if len(a) > 0 { - s += "/" + a - } - b = b[size:] - } - - return s, nil -} - -func sizeForAddr(p Protocol, b []byte) int { - switch { - case p.Size > 0: - return (p.Size / 8) - case p.Size == 0: - return 0 - default: - size, n := ReadVarintCode(b) - return size + n - } -} - -func bytesSplit(b []byte) (ret [][]byte, err error) { - // panic handler, in case we try accessing bytes incorrectly. - defer func() { - if e := recover(); e != nil { - ret = [][]byte{} - err = e.(error) - } - }() - - ret = [][]byte{} - for len(b) > 0 { - code, n := ReadVarintCode(b) - p := ProtocolWithCode(code) - if p.Code == 0 { - return [][]byte{}, fmt.Errorf("no protocol with code %d", b[0]) - } - - size := sizeForAddr(p, b[n:]) - length := n + size - ret = append(ret, b[:length]) - b = b[length:] - } - - return ret, nil -} - -func addressStringToBytes(p Protocol, s string) ([]byte, error) { - switch p.Code { - - case P_IP4: // ipv4 - i := net.ParseIP(s).To4() - if i == nil { - return nil, fmt.Errorf("failed to parse ip4 addr: %s", s) - } - return i, nil - - case P_IP6: // ipv6 - i := net.ParseIP(s).To16() - if i == nil { - return nil, fmt.Errorf("failed to parse ip6 addr: %s", s) - } - return i, nil - - // tcp udp dccp sctp - case P_TCP, P_UDP, P_DCCP, P_SCTP: - i, err := strconv.Atoi(s) - if err != nil { - return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, err) - } - if i >= 65536 { - return nil, fmt.Errorf("failed to parse %s addr: %s", p.Name, "greater than 65536") - } - b := make([]byte, 2) - binary.BigEndian.PutUint16(b, uint16(i)) - return b, nil - - case P_IPFS: // ipfs - // the address is a varint prefixed multihash string representation - m, err := mh.FromB58String(s) - if err != nil { - return nil, fmt.Errorf("failed to parse ipfs addr: %s %s", s, err) - } - size := CodeToVarint(len(m)) - b := append(size, m...) - return b, nil - } - - return []byte{}, fmt.Errorf("failed to parse %s addr: unknown", p.Name) -} - -func addressBytesToString(p Protocol, b []byte) (string, error) { - switch p.Code { - - // ipv4,6 - case P_IP4, P_IP6: - return net.IP(b).String(), nil - - // tcp udp dccp sctp - case P_TCP, P_UDP, P_DCCP, P_SCTP: - i := binary.BigEndian.Uint16(b) - return strconv.Itoa(int(i)), nil - - case P_IPFS: // ipfs - // the address is a varint-prefixed multihash string representation - size, n := ReadVarintCode(b) - b = b[n:] - if len(b) != size { - panic("inconsistent lengths") - } - m, err := mh.Cast(b) - if err != nil { - return "", err - } - return m.B58String(), nil - } - - return "", fmt.Errorf("unknown protocol") -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/doc.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/doc.go deleted file mode 100644 index c26e443..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/doc.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Package multiaddr provides an implementation of the Multiaddr network -address format. Multiaddr emphasizes explicitness, self-description, and -portability. It allows applications to treat addresses as opaque tokens, -and to avoid making assumptions about the address representation (e.g. length). -Learn more at https://github.com/jbenet/multiaddr - -Basic Use: - - import ( - "bytes" - "strings" - ma "github.com/jbenet/go-multiaddr" - ) - - // construct from a string (err signals parse failure) - m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") - - // construct from bytes (err signals parse failure) - m2, err := ma.NewMultiaddrBytes(m1.Bytes()) - - // true - strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") - strings.Equal(m1.String(), m2.String()) - bytes.Equal(m1.Bytes(), m2.Bytes()) - m1.Equal(m2) - m2.Equal(m1) - - // tunneling (en/decap) - printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") - proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") - printerOverProxy := proxy.Encapsulate(printer) - proxyAgain := printerOverProxy.Decapsulate(printer) - -*/ -package multiaddr diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/interface.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/interface.go deleted file mode 100644 index 512cb62..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/interface.go +++ /dev/null @@ -1,42 +0,0 @@ -package multiaddr - -/* -Multiaddr is a cross-protocol, cross-platform format for representing -internet addresses. It emphasizes explicitness and self-description. -Learn more here: https://github.com/jbenet/multiaddr - -Multiaddrs have both a binary and string representation. - - import ma "github.com/jbenet/go-multiaddr" - - addr, err := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/80") - // err non-nil when parsing failed. - -*/ -type Multiaddr interface { - // Equal returns whether two Multiaddrs are exactly equal - Equal(Multiaddr) bool - - // Bytes returns the []byte representation of this Multiaddr - Bytes() []byte - - // String returns the string representation of this Multiaddr - // (may panic if internal state is corrupted) - String() string - - // Protocols returns the list of Protocols this Multiaddr includes - // will panic if protocol code incorrect (and bytes accessed incorrectly) - Protocols() []Protocol - - // Encapsulate wraps this Multiaddr around another. For example: - // - // /ip4/1.2.3.4 encapsulate /tcp/80 = /ip4/1.2.3.4/tcp/80 - // - Encapsulate(Multiaddr) Multiaddr - - // Decapsultate removes a Multiaddr wrapping. For example: - // - // /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80 - // - Decapsulate(Multiaddr) Multiaddr -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go deleted file mode 100644 index 1cb7ad4..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go +++ /dev/null @@ -1,115 +0,0 @@ -package multiaddr - -import ( - "bytes" - "fmt" - "strings" -) - -// multiaddr is the data structure representing a Multiaddr -type multiaddr struct { - bytes []byte -} - -// NewMultiaddr parses and validates an input string, returning a *Multiaddr -func NewMultiaddr(s string) (Multiaddr, error) { - b, err := stringToBytes(s) - if err != nil { - return nil, err - } - return &multiaddr{bytes: b}, nil -} - -// NewMultiaddrBytes initializes a Multiaddr from a byte representation. -// It validates it as an input string. -func NewMultiaddrBytes(b []byte) (Multiaddr, error) { - s, err := bytesToString(b) - if err != nil { - return nil, err - } - return NewMultiaddr(s) -} - -// Equal tests whether two multiaddrs are equal -func (m *multiaddr) Equal(m2 Multiaddr) bool { - return bytes.Equal(m.bytes, m2.Bytes()) -} - -// Bytes returns the []byte representation of this Multiaddr -func (m *multiaddr) Bytes() []byte { - // consider returning copy to prevent changing underneath us? - cpy := make([]byte, len(m.bytes)) - copy(cpy, m.bytes) - return cpy -} - -// String returns the string representation of a Multiaddr -func (m *multiaddr) String() string { - s, err := bytesToString(m.bytes) - if err != nil { - panic("multiaddr failed to convert back to string. corrupted?") - } - return s -} - -// Protocols returns the list of protocols this Multiaddr has. -// will panic in case we access bytes incorrectly. -func (m *multiaddr) Protocols() []Protocol { - - // panic handler, in case we try accessing bytes incorrectly. - defer func() { - if e := recover(); e != nil { - err := e.(error) - panic("Multiaddr.Protocols error: " + err.Error()) - } - }() - - size := 0 - ps := []Protocol{} - b := m.bytes[:] - for len(b) > 0 { - code, n := ReadVarintCode(b) - p := ProtocolWithCode(code) - if p.Code == 0 { - // this is a panic (and not returning err) because this should've been - // caught on constructing the Multiaddr - panic(fmt.Errorf("no protocol with code %d", b[0])) - } - ps = append(ps, p) - b = b[n:] - - size = sizeForAddr(p, b) - b = b[size:] - } - return ps -} - -// Encapsulate wraps a given Multiaddr, returning the resulting joined Multiaddr -func (m *multiaddr) Encapsulate(o Multiaddr) Multiaddr { - mb := m.bytes - ob := o.Bytes() - - b := make([]byte, len(mb)+len(ob)) - copy(b, mb) - copy(b[len(mb):], ob) - return &multiaddr{bytes: b} -} - -// Decapsulate unwraps Multiaddr up until the given Multiaddr is found. -func (m *multiaddr) Decapsulate(o Multiaddr) Multiaddr { - s1 := m.String() - s2 := o.String() - i := strings.LastIndex(s1, s2) - if i < 0 { - // if multiaddr not contained, returns a copy. - cpy := make([]byte, len(m.bytes)) - copy(cpy, m.bytes) - return &multiaddr{bytes: cpy} - } - - ma, err := NewMultiaddr(s1[:i]) - if err != nil { - panic("Multiaddr.Decapsulate incorrect byte boundaries.") - } - return ma -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go deleted file mode 100644 index f0e9c36..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go +++ /dev/null @@ -1,294 +0,0 @@ -package multiaddr - -import ( - "bytes" - "encoding/hex" - "testing" -) - -func newMultiaddr(t *testing.T, a string) Multiaddr { - m, err := NewMultiaddr(a) - if err != nil { - t.Error(err) - } - return m -} - -func TestConstructFails(t *testing.T) { - cases := []string{ - "/ip4", - "/ip4/::1", - "/ip4/fdpsofodsajfdoisa", - "/ip6", - "/udp", - "/tcp", - "/sctp", - "/udp/65536", - "/tcp/65536", - "/udp/1234/sctp", - "/udp/1234/udt/1234", - "/udp/1234/utp/1234", - "/ip4/127.0.0.1/udp/jfodsajfidosajfoidsa", - "/ip4/127.0.0.1/udp", - "/ip4/127.0.0.1/tcp/jfodsajfidosajfoidsa", - "/ip4/127.0.0.1/tcp", - "/ip4/127.0.0.1/ipfs", - "/ip4/127.0.0.1/ipfs/tcp", - } - - for _, a := range cases { - if _, err := NewMultiaddr(a); err == nil { - t.Errorf("should have failed: %s - %s", a, err) - } - } -} - -func TestConstructSucceeds(t *testing.T) { - cases := []string{ - "/ip4/1.2.3.4", - "/ip4/0.0.0.0", - "/ip6/::1", - "/ip6/2601:9:4f81:9700:803e:ca65:66e8:c21", - "/udp/0", - "/tcp/0", - "/sctp/0", - "/udp/1234", - "/tcp/1234", - "/sctp/1234", - "/udp/65535", - "/tcp/65535", - "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC", - "/udp/1234/sctp/1234", - "/udp/1234/udt", - "/udp/1234/utp", - "/tcp/1234/http", - "/tcp/1234/https", - "/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234", - "/ip4/127.0.0.1/udp/1234", - "/ip4/127.0.0.1/udp/0", - "/ip4/127.0.0.1/tcp/1234", - "/ip4/127.0.0.1/tcp/1234/", - "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC", - "/ip4/127.0.0.1/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSupNKC/tcp/1234", - } - - for _, a := range cases { - if _, err := NewMultiaddr(a); err != nil { - t.Errorf("should have succeeded: %s -- %s", a, err) - } - } -} - -func TestEqual(t *testing.T) { - m1 := newMultiaddr(t, "/ip4/127.0.0.1/udp/1234") - m2 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234") - m3 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234") - m4 := newMultiaddr(t, "/ip4/127.0.0.1/tcp/1234/") - - if m1.Equal(m2) { - t.Error("should not be equal") - } - - if m2.Equal(m1) { - t.Error("should not be equal") - } - - if !m2.Equal(m3) { - t.Error("should be equal") - } - - if !m3.Equal(m2) { - t.Error("should be equal") - } - - if !m1.Equal(m1) { - t.Error("should be equal") - } - - if !m2.Equal(m4) { - t.Error("should be equal") - } - - if !m4.Equal(m3) { - t.Error("should be equal") - } -} - -func TestStringToBytes(t *testing.T) { - - testString := func(s string, h string) { - b1, err := hex.DecodeString(h) - if err != nil { - t.Error("failed to decode hex", h) - } - - b2, err := stringToBytes(s) - if err != nil { - t.Error("failed to convert", s) - } - - if !bytes.Equal(b1, b2) { - t.Error("failed to convert", s, "to", b1, "got", b2) - } - } - - testString("/ip4/127.0.0.1/udp/1234", "047f0000011104d2") - testString("/ip4/127.0.0.1/tcp/4321", "047f0000010610e1") - testString("/ip4/127.0.0.1/udp/1234/ip4/127.0.0.1/tcp/4321", "047f0000011104d2047f0000010610e1") -} - -func TestBytesToString(t *testing.T) { - - testString := func(s1 string, h string) { - b, err := hex.DecodeString(h) - if err != nil { - t.Error("failed to decode hex", h) - } - - s2, err := bytesToString(b) - if err != nil { - t.Error("failed to convert", b) - } - - if s1 != s2 { - t.Error("failed to convert", b, "to", s1, "got", s2) - } - } - - testString("/ip4/127.0.0.1/udp/1234", "047f0000011104d2") - testString("/ip4/127.0.0.1/tcp/4321", "047f0000010610e1") - testString("/ip4/127.0.0.1/udp/1234/ip4/127.0.0.1/tcp/4321", "047f0000011104d2047f0000010610e1") -} - -func TestBytesSplitAndJoin(t *testing.T) { - - testString := func(s string, res []string) { - m, err := NewMultiaddr(s) - if err != nil { - t.Fatal("failed to convert", s, err) - } - - split := Split(m) - if len(split) != len(res) { - t.Error("not enough split components", split) - return - } - - for i, a := range split { - if a.String() != res[i] { - t.Errorf("split component failed: %s != %s", a, res[i]) - } - } - - joined := Join(split...) - if !m.Equal(joined) { - t.Errorf("joined components failed: %s != %s", m, joined) - } - - // modifying underlying bytes is fine. - m2 := m.(*multiaddr) - for i := range m2.bytes { - m2.bytes[i] = 0 - } - - for i, a := range split { - if a.String() != res[i] { - t.Errorf("split component failed: %s != %s", a, res[i]) - } - } - } - - testString("/ip4/1.2.3.4/udp/1234", []string{"/ip4/1.2.3.4", "/udp/1234"}) - testString("/ip4/1.2.3.4/tcp/1/ip4/2.3.4.5/udp/2", - []string{"/ip4/1.2.3.4", "/tcp/1", "/ip4/2.3.4.5", "/udp/2"}) - testString("/ip4/1.2.3.4/utp/ip4/2.3.4.5/udp/2/udt", - []string{"/ip4/1.2.3.4", "/utp", "/ip4/2.3.4.5", "/udp/2", "/udt"}) -} - -func TestProtocols(t *testing.T) { - m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234") - if err != nil { - t.Error("failed to construct", "/ip4/127.0.0.1/udp/1234") - } - - ps := m.Protocols() - if ps[0].Code != ProtocolWithName("ip4").Code { - t.Error(ps[0], ProtocolWithName("ip4")) - t.Error("failed to get ip4 protocol") - } - - if ps[1].Code != ProtocolWithName("udp").Code { - t.Error(ps[1], ProtocolWithName("udp")) - t.Error("failed to get udp protocol") - } - -} - -func TestProtocolsWithString(t *testing.T) { - pwn := ProtocolWithName - good := map[string][]Protocol{ - "/ip4": []Protocol{pwn("ip4")}, - "/ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")}, - "ip4/tcp/udp/ip6": []Protocol{pwn("ip4"), pwn("tcp"), pwn("udp"), pwn("ip6")}, - "////////ip4/tcp": []Protocol{pwn("ip4"), pwn("tcp")}, - "ip4/udp/////////": []Protocol{pwn("ip4"), pwn("udp")}, - "////////ip4/tcp////////": []Protocol{pwn("ip4"), pwn("tcp")}, - } - - for s, ps1 := range good { - ps2, err := ProtocolsWithString(s) - if err != nil { - t.Error("ProtocolsWithString(%s) should have succeeded", s) - } - - for i, ps1p := range ps1 { - ps2p := ps2[i] - if ps1p.Code != ps2p.Code { - t.Errorf("mismatch: %s != %s, %s", ps1p.Name, ps2p.Name, s) - } - } - } - - bad := []string{ - "dsijafd", // bogus proto - "/ip4/tcp/fidosafoidsa", // bogus proto - "////////ip4/tcp/21432141/////////", // bogus proto - "////////ip4///////tcp/////////", // empty protos in between - } - - for _, s := range bad { - if _, err := ProtocolsWithString(s); err == nil { - t.Error("ProtocolsWithString(%s) should have failed", s) - } - } - -} - -func TestEncapsulate(t *testing.T) { - m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234") - if err != nil { - t.Error(err) - } - - m2, err := NewMultiaddr("/udp/5678") - if err != nil { - t.Error(err) - } - - b := m.Encapsulate(m2) - if s := b.String(); s != "/ip4/127.0.0.1/udp/1234/udp/5678" { - t.Error("encapsulate /ip4/127.0.0.1/udp/1234/udp/5678 failed.", s) - } - - m3, _ := NewMultiaddr("/udp/5678") - c := b.Decapsulate(m3) - if s := c.String(); s != "/ip4/127.0.0.1/udp/1234" { - t.Error("decapsulate /udp failed.", "/ip4/127.0.0.1/udp/1234", s) - } - - m4, _ := NewMultiaddr("/ip4/127.0.0.1") - d := c.Decapsulate(m4) - if s := d.String(); s != "" { - t.Error("decapsulate /ip4 failed.", "/", s) - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.csv b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.csv deleted file mode 100644 index 213e9b5..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.csv +++ /dev/null @@ -1,12 +0,0 @@ -code size name -4 32 ip4 -6 16 tcp -17 16 udp -33 16 dccp -41 128 ip6 -132 16 sctp -301 0 udt -302 0 utp -421 V ipfs -480 0 http -443 0 https diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.go deleted file mode 100644 index c4ee5df..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/protocols.go +++ /dev/null @@ -1,116 +0,0 @@ -package multiaddr - -import ( - "encoding/binary" - "fmt" - "strings" -) - -// Protocol is a Multiaddr protocol description structure. -type Protocol struct { - Code int - Size int // a size of -1 indicates a length-prefixed variable size - Name string - VCode []byte -} - -// replicating table here to: -// 1. avoid parsing the csv -// 2. ensuring errors in the csv don't screw up code. -// 3. changing a number has to happen in two places. -const ( - P_IP4 = 4 - P_TCP = 6 - P_UDP = 17 - P_DCCP = 33 - P_IP6 = 41 - P_SCTP = 132 - P_UTP = 301 - P_UDT = 302 - P_IPFS = 421 - P_HTTP = 480 - P_HTTPS = 443 -) - -// These are special sizes -const ( - LengthPrefixedVarSize = -1 -) - -// Protocols is the list of multiaddr protocols supported by this module. -var Protocols = []Protocol{ - Protocol{P_IP4, 32, "ip4", CodeToVarint(P_IP4)}, - Protocol{P_TCP, 16, "tcp", CodeToVarint(P_TCP)}, - Protocol{P_UDP, 16, "udp", CodeToVarint(P_UDP)}, - Protocol{P_DCCP, 16, "dccp", CodeToVarint(P_DCCP)}, - Protocol{P_IP6, 128, "ip6", CodeToVarint(P_IP6)}, - // these require varint: - Protocol{P_SCTP, 16, "sctp", CodeToVarint(P_SCTP)}, - Protocol{P_UTP, 0, "utp", CodeToVarint(P_UTP)}, - Protocol{P_UDT, 0, "udt", CodeToVarint(P_UDT)}, - Protocol{P_HTTP, 0, "http", CodeToVarint(P_HTTP)}, - Protocol{P_HTTPS, 0, "https", CodeToVarint(P_HTTPS)}, - Protocol{P_IPFS, LengthPrefixedVarSize, "ipfs", CodeToVarint(P_IPFS)}, -} - -// ProtocolWithName returns the Protocol description with given string name. -func ProtocolWithName(s string) Protocol { - for _, p := range Protocols { - if p.Name == s { - return p - } - } - return Protocol{} -} - -// ProtocolWithCode returns the Protocol description with given protocol code. -func ProtocolWithCode(c int) Protocol { - for _, p := range Protocols { - if p.Code == c { - return p - } - } - return Protocol{} -} - -// ProtocolsWithString returns a slice of protocols matching given string. -func ProtocolsWithString(s string) ([]Protocol, error) { - s = strings.Trim(s, "/") - sp := strings.Split(s, "/") - if len(sp) == 0 { - return nil, nil - } - - t := make([]Protocol, len(sp)) - for i, name := range sp { - p := ProtocolWithName(name) - if p.Code == 0 { - return nil, fmt.Errorf("no protocol with name: %s", name) - } - t[i] = p - } - return t, nil -} - -// CodeToVarint converts an integer to a varint-encoded []byte -func CodeToVarint(num int) []byte { - buf := make([]byte, (num/7)+1) // varint package is uint64 - n := binary.PutUvarint(buf, uint64(num)) - return buf[:n] -} - -// VarintToCode converts a varint-encoded []byte to an integer protocol code -func VarintToCode(buf []byte) int { - num, _ := ReadVarintCode(buf) - return num -} - -// ReadVarintCode reads a varint code from the beginning of buf. -// returns the code, and the number of bytes read. -func ReadVarintCode(buf []byte) (int, int) { - num, n := binary.Uvarint(buf) - if n < 0 { - panic("varints larger than uint64 not yet supported") - } - return int(num), n -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go deleted file mode 100644 index d1b54af..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go +++ /dev/null @@ -1,56 +0,0 @@ -package multiaddr - -import "fmt" - -// Split returns the sub-address portions of a multiaddr. -func Split(m Multiaddr) []Multiaddr { - split, err := bytesSplit(m.Bytes()) - if err != nil { - panic(fmt.Errorf("invalid multiaddr %s", m.String())) - } - - addrs := make([]Multiaddr, len(split)) - for i, addr := range split { - addrs[i] = &multiaddr{bytes: addr} - } - return addrs -} - -// Join returns a combination of addresses. -func Join(ms ...Multiaddr) Multiaddr { - - length := 0 - bs := make([][]byte, len(ms)) - for i, m := range ms { - bs[i] = m.Bytes() - length += len(bs[i]) - } - - bidx := 0 - b := make([]byte, length) - for _, mb := range bs { - for i := range mb { - b[bidx] = mb[i] - bidx++ - } - } - return &multiaddr{bytes: b} -} - -// Cast re-casts a byte slice as a multiaddr. will panic if it fails to parse. -func Cast(b []byte) Multiaddr { - _, err := bytesToString(b) - if err != nil { - panic(fmt.Errorf("multiaddr failed to parse: %s", err)) - } - return &multiaddr{bytes: b} -} - -// StringCast like Cast, but parses a string. Will also panic if it fails to parse. -func StringCast(s string) Multiaddr { - m, err := NewMultiaddr(s) - if err != nil { - panic(fmt.Errorf("multiaddr failed to parse: %s", err)) - } - return m -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/.travis.yml b/Godeps/_workspace/src/github.com/jbenet/go-multihash/.travis.yml deleted file mode 100644 index 7725b30..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: go - -go: - - 1.3 - - release - - tip - -script: - - make test - -env: TEST_VERBOSE=1 diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/LICENSE b/Godeps/_workspace/src/github.com/jbenet/go-multihash/LICENSE deleted file mode 100644 index c7386b3..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Juan Batiz-Benet - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/Makefile b/Godeps/_workspace/src/github.com/jbenet/go-multihash/Makefile deleted file mode 100644 index d6e3bf6..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -test: go_test other_tests - -other_tests: - cd test && make test - -go_test: go_deps - go test -race -cpu=5 -v ./... - -go_deps: - go get golang.org/x/crypto/sha3 - go get github.com/jbenet/go-base58 diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/README.md b/Godeps/_workspace/src/github.com/jbenet/go-multihash/README.md deleted file mode 100644 index f891499..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# go-multihash - -![travis](https://travis-ci.org/jbenet/go-multihash.svg) - -[multihash](//github.com/jbenet/multihash) implementation in Go. - -## Example - -```go -package main - -import ( - "encoding/hex" - "fmt" - "github.com/jbenet/go-multihash" -) - -func main() { - // ignores errors for simplicity. - // don't do that at home. - - buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") - mhbuf, _ := multihash.EncodeName(buf, "sha1"); - mhhex := hex.EncodeToString(mhbuf) - fmt.Printf("hex: %v\n", mhhex); - - o, _ := multihash.Decode(mhbuf); - mhhex = hex.EncodeToString(o.Digest); - fmt.Printf("obj: %v 0x%x %d %s\n", o.Name, o.Code, o.Length, mhhex); -} -``` - -Run [test/foo.go](test/foo.go) - -``` -> cd test/ -> go build -> ./test -hex: 11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 -obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 -``` - -## License - -MIT diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/io.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/io.go deleted file mode 100644 index cdd234c..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/io.go +++ /dev/null @@ -1,79 +0,0 @@ -package multihash - -import ( - "fmt" - "io" -) - -// Reader is an io.Reader wrapper that exposes a function -// to read a whole multihash, parse it, and return it. -type Reader interface { - io.Reader - - ReadMultihash() (Multihash, error) -} - -// Writer is an io.Writer wrapper that exposes a function -// to write a whole multihash. -type Writer interface { - io.Writer - - WriteMultihash(Multihash) error -} - -// NewReader wraps an io.Reader with a multihash.Reader -func NewReader(r io.Reader) Reader { - return &mhReader{r} -} - -// NewWriter wraps an io.Writer with a multihash.Writer -func NewWriter(w io.Writer) Writer { - return &mhWriter{w} -} - -type mhReader struct { - r io.Reader -} - -func (r *mhReader) Read(buf []byte) (n int, err error) { - return r.r.Read(buf) -} - -func (r *mhReader) ReadMultihash() (Multihash, error) { - mhhdr := make([]byte, 2) - if _, err := io.ReadFull(r.r, mhhdr); err != nil { - return nil, err - } - - // first byte is the algo, the second is the length. - - // (varints someday...) - length := uint(mhhdr[1]) - - if length > 127 { - return nil, fmt.Errorf("varints not yet supported (length is %d)", length) - } - - buf := make([]byte, length+2) - buf[0] = mhhdr[0] - buf[1] = mhhdr[1] - - if _, err := io.ReadFull(r.r, buf[2:]); err != nil { - return nil, err - } - - return Cast(buf) -} - -type mhWriter struct { - w io.Writer -} - -func (w *mhWriter) Write(buf []byte) (n int, err error) { - return w.w.Write(buf) -} - -func (w *mhWriter) WriteMultihash(m Multihash) error { - _, err := w.w.Write([]byte(m)) - return err -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/io_test.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/io_test.go deleted file mode 100644 index 44da78e..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/io_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package multihash - -import ( - "bytes" - "io" - "testing" -) - -func TestReader(t *testing.T) { - - var buf bytes.Buffer - - for _, tc := range testCases { - m, err := tc.Multihash() - if err != nil { - t.Fatal(err) - } - - buf.Write([]byte(m)) - } - - r := NewReader(&buf) - - for _, tc := range testCases { - h, err := tc.Multihash() - if err != nil { - t.Fatal(err) - } - - h2, err := r.ReadMultihash() - if err != nil { - t.Error(err) - continue - } - - if !bytes.Equal(h, h2) { - t.Error("h and h2 should be equal") - } - } -} - -func TestWriter(t *testing.T) { - - var buf bytes.Buffer - w := NewWriter(&buf) - - for _, tc := range testCases { - m, err := tc.Multihash() - if err != nil { - t.Error(err) - continue - } - - if err := w.WriteMultihash(m); err != nil { - t.Error(err) - continue - } - - buf2 := make([]byte, len(m)) - if _, err := io.ReadFull(&buf, buf2); err != nil { - t.Error(err) - continue - } - - if !bytes.Equal(m, buf2) { - t.Error("m and buf2 should be equal") - } - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash.go deleted file mode 100644 index e03fa98..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash.go +++ /dev/null @@ -1,188 +0,0 @@ -package multihash - -import ( - "encoding/hex" - "errors" - "fmt" - - b58 "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-base58" -) - -// errors -var ( - ErrUnknownCode = errors.New("unknown multihash code") - ErrTooShort = errors.New("multihash too short. must be > 3 bytes") - ErrTooLong = errors.New("multihash too long. must be < 129 bytes") - ErrLenNotSupported = errors.New("multihash does not yet support digests longer than 127 bytes") -) - -// ErrInconsistentLen is returned when a decoded multihash has an inconsistent length -type ErrInconsistentLen struct { - dm *DecodedMultihash -} - -func (e ErrInconsistentLen) Error() string { - return fmt.Sprintf("multihash length inconsistent: %v", e.dm) -} - -// constants -const ( - SHA1 = 0x11 - SHA2_256 = 0x12 - SHA2_512 = 0x13 - SHA3 = 0x14 - BLAKE2B = 0x40 - BLAKE2S = 0x41 -) - -// Names maps the name of a hash to the code -var Names = map[string]int{ - "sha1": SHA1, - "sha2-256": SHA2_256, - "sha2-512": SHA2_512, - "sha3": SHA3, - "blake2b": BLAKE2B, - "blake2s": BLAKE2S, -} - -// Codes maps a hash code to it's name -var Codes = map[int]string{ - SHA1: "sha1", - SHA2_256: "sha2-256", - SHA2_512: "sha2-512", - SHA3: "sha3", - BLAKE2B: "blake2b", - BLAKE2S: "blake2s", -} - -// DefaultLengths maps a hash code to it's default length -var DefaultLengths = map[int]int{ - SHA1: 20, - SHA2_256: 32, - SHA2_512: 64, - SHA3: 64, - BLAKE2B: 64, - BLAKE2S: 32, -} - -type DecodedMultihash struct { - Code int - Name string - Length int - Digest []byte -} - -type Multihash []byte - -func (m *Multihash) HexString() string { - return hex.EncodeToString([]byte(*m)) -} - -func (m *Multihash) String() string { - return m.HexString() -} - -func FromHexString(s string) (Multihash, error) { - b, err := hex.DecodeString(s) - if err != nil { - return Multihash{}, err - } - - return Cast(b) -} - -func (m Multihash) B58String() string { - return b58.Encode([]byte(m)) -} - -func FromB58String(s string) (m Multihash, err error) { - // panic handler, in case we try accessing bytes incorrectly. - defer func() { - if e := recover(); e != nil { - m = Multihash{} - err = e.(error) - } - }() - - //b58 smells like it can panic... - b := b58.Decode(s) - return Cast(b) -} - -func Cast(buf []byte) (Multihash, error) { - dm, err := Decode(buf) - if err != nil { - return Multihash{}, err - } - - if !ValidCode(dm.Code) { - return Multihash{}, ErrUnknownCode - } - - return Multihash(buf), nil -} - -// Decode a hash from the given Multihash. -func Decode(buf []byte) (*DecodedMultihash, error) { - - if len(buf) < 3 { - return nil, ErrTooShort - } - - if len(buf) > 129 { - return nil, ErrTooLong - } - - dm := &DecodedMultihash{ - Code: int(uint8(buf[0])), - Name: Codes[int(uint8(buf[0]))], - Length: int(uint8(buf[1])), - Digest: buf[2:], - } - - if len(dm.Digest) != dm.Length { - return nil, ErrInconsistentLen{dm} - } - - return dm, nil -} - -// Encode a hash digest along with the specified function code. -// Note: the length is derived from the length of the digest itself. -func Encode(buf []byte, code int) ([]byte, error) { - - if !ValidCode(code) { - return nil, ErrUnknownCode - } - - if len(buf) > 127 { - return nil, ErrLenNotSupported - } - - pre := make([]byte, 2) - pre[0] = byte(uint8(code)) - pre[1] = byte(uint8(len(buf))) - return append(pre, buf...), nil -} - -func EncodeName(buf []byte, name string) ([]byte, error) { - return Encode(buf, Names[name]) -} - -// ValidCode checks whether a multihash code is valid. -func ValidCode(code int) bool { - if AppCode(code) { - return true - } - - if _, ok := Codes[code]; ok { - return true - } - - return false -} - -// AppCode checks whether a multihash code is part of the App range. -func AppCode(code int) bool { - return code >= 0 && code < 0x10 -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/.gitignore b/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/.gitignore deleted file mode 100644 index 2826f17..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/.gitignore +++ /dev/null @@ -1 +0,0 @@ -multihash diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/README.md b/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/README.md deleted file mode 100644 index e1b5012..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# multihash tool - -The `multihash` tool uses `go-multihash` to hash things much like `shasum`. - -Warning: this is a **multihash** tool! Its digests follow the [multihash](https://github.com/jbenet/multihash) format. - -### Install - -``` -go get github.com/jbenet/go-multihash/multihash -``` - -### Usage - -```sh -> multihash -h -usage: ./multihash [options] [FILE] -Print or check multihash checksums. -With no FILE, or when FILE is -, read standard input. - -Options: - -a="sha2-256": one of: sha1, sha2-256, sha2-512, sha3 (shorthand) - -algorithm="sha2-256": one of: sha1, sha2-256, sha2-512, sha3 - -c="": check checksum matches (shorthand) - -check="": check checksum matches - -e="base58": one of: raw, hex, base58, base64 (shorthand) - -encoding="base58": one of: raw, hex, base58, base64 - -l=-1: checksums length in bits (truncate). -1 is default (shorthand) - -length=-1: checksums length in bits (truncate). -1 is default -``` - -### Examples - -#### Input - -```sh -# from stdin -> multihash < main.go -QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 - -# from file -> ./multihash main.go -QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 - -# from stdin "filename" -> multihash - < main.go -QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 -``` - -#### Algorithms - -```sh -> multihash -a ? -error: algorithm '?' not one of: sha1, sha2-256, sha2-512, sha3 - -> multihash -a sha1 < main.go -5drkbcqJUo6fZVvcZJeVEVWAgndvLm - -> multihash -a sha2-256 < main.go -QmcK3s36goo9v2HYcfTrDKKwxaxmJJ59etodQQFYsL5T5N - -> multihash -a sha2-512 < main.go -8VuDcW4CooyPQA8Cc4eYpwjhyDJZqu5m5ZMDFzWULYsVS8d119JaGeNWsZbZ2ZG2kPtbrMx31MidokCigaD65yUPAs - -> multihash -a sha3 < main.go -8tWDCTfAX24DYmzNixTj2ARJkqwRG736VHx5aJppmqRjhW9QT1EuTgKUmu9Pmunzq292jzPKxb2VxSsTXmjFY1HD3B -``` - -#### Encodings - -```sh -> multihash -e raw < main.go - Ϛ�����I�5 S��WG>���_��]g�����u - -> multihash -e hex < main.go -1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275 - -> multihash -e base64 < main.go -EiDPmqK4o4ubSdE1CVOQBZpXRz6XrOtfyuJdZ6i2/rWCdQ== - -> multihash -e base58 < main.go -Qmf1QjEXDmqBm7RqHKqFGNUyhzUjnX7cmgKMrGzzPceZDQ -``` - -#### Digest Length - -```sh -# we're outputing hex (good byte alignment) to show the codes changing -# notice the multihash code (first 2 chars) differs! -> multihash -e hex -a sha2-256 -l 256 < main.go -1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275 -> multihash -e hex -a sha2-512 -l 256 < main.go -132047a4b6c629f5545f529b0ff461dc09119969f3593186277a1cc7a8ea3560a6f1 -> multihash -e hex -a sha3 -l 256 < main.go -14206b9222a1a47939e665261bd2b5573e55e7988675223adde73c1011066ad66335 - -# notice the multihash length (next 2 chars) differs! -> multihash -e hex -a sha2-256 -l 256 < main.go -1220cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d67a8b6feb58275 -> multihash -e hex -a sha2-256 -l 200 < main.go -1219cf9aa2b8a38b9b49d135095390059a57473e97aceb5fcae25d -``` - -#### Verify Checksum - -```sh -> multihash -c QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8 < main.go -OK checksums match (-q for no output) - -> multihash -c QmcKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa < main.go -error: computed checksum did not match (-q for no output) - -# works with other arguments too -> multihash -e hex -l 128 -c "12102ffc284a1e82bf51e567c75b2ae6edb9" < main.go -OK checksums match (-q for no output) -``` diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/coding.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/coding.go deleted file mode 100644 index 563cd3e..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/coding.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "encoding/base64" - "encoding/hex" - "fmt" - - base58 "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-base58" - mh "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multihash" -) - -func Decode(encoding, digest string) (mh.Multihash, error) { - switch encoding { - case "raw": - return mh.Cast([]byte(digest)) - case "hex": - return hex.DecodeString(digest) - case "base58": - return base58.Decode(digest), nil - case "base64": - return base64.StdEncoding.DecodeString(digest) - default: - return nil, fmt.Errorf("unknown encoding: %s", encoding) - } -} - -func Encode(encoding string, hash mh.Multihash) (string, error) { - switch encoding { - case "raw": - return string(hash), nil - case "hex": - return hex.EncodeToString(hash), nil - case "base58": - return base58.Encode(hash), nil - case "base64": - return base64.StdEncoding.EncodeToString(hash), nil - default: - return "", fmt.Errorf("unknown encoding: %s", encoding) - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/main.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/main.go deleted file mode 100644 index 77ebc13..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash/main.go +++ /dev/null @@ -1,208 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "io" - "io/ioutil" - "os" - "strings" - - mh "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multihash" -) - -var usage = `usage: %s [options] [FILE] -Print or check multihash checksums. -With no FILE, or when FILE is -, read standard input. - -Options: -` - -// flags -var encodings = []string{"raw", "hex", "base58", "base64"} -var algorithms = []string{"sha1", "sha2-256", "sha2-512", "sha3"} -var encoding string -var algorithm string -var algorithmCode int -var length int -var checkRaw string -var checkMh mh.Multihash -var inputFilename string -var quiet bool - -// joined names -var algoStr string -var encStr string - -func init() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, usage, os.Args[0]) - flag.PrintDefaults() - } - - algoStr = "one of: " + strings.Join(algorithms, ", ") - flag.StringVar(&algorithm, "algorithm", "sha2-256", algoStr) - flag.StringVar(&algorithm, "a", "sha2-256", algoStr+" (shorthand)") - - encStr = "one of: " + strings.Join(encodings, ", ") - flag.StringVar(&encoding, "encoding", "base58", encStr) - flag.StringVar(&encoding, "e", "base58", encStr+" (shorthand)") - - checkStr := "check checksum matches" - flag.StringVar(&checkRaw, "check", "", checkStr) - flag.StringVar(&checkRaw, "c", "", checkStr+" (shorthand)") - - lengthStr := "checksums length in bits (truncate). -1 is default" - flag.IntVar(&length, "length", -1, lengthStr) - flag.IntVar(&length, "l", -1, lengthStr+" (shorthand)") - - quietStr := "quiet output (no newline on checksum, no error text)" - flag.BoolVar(&quiet, "quiet", false, quietStr) - flag.BoolVar(&quiet, "q", false, quietStr+" (shorthand)") -} - -func strIn(a string, set []string) bool { - for _, s := range set { - if s == a { - return true - } - } - return false -} - -func parseFlags() error { - flag.Parse() - - if !strIn(algorithm, algorithms) { - return fmt.Errorf("algorithm '%s' not %s", algorithm, algoStr) - } - var found bool - algorithmCode, found = mh.Names[algorithm] - if !found { - return fmt.Errorf("algorithm '%s' not found (lib error, pls report).") - } - - if !strIn(encoding, encodings) { - return fmt.Errorf("encoding '%s' not %s", encoding, encStr) - } - - if checkRaw != "" { - var err error - checkMh, err = Decode(encoding, checkRaw) - if err != nil { - return fmt.Errorf("fail to decode check '%s': %s", checkRaw, err) - } - } - - if length >= 0 { - if length%8 != 0 { - return fmt.Errorf("length must be multiple of 8") - } - length = length / 8 - - if length > mh.DefaultLengths[algorithmCode] { - length = mh.DefaultLengths[algorithmCode] - } - } - return nil -} - -func getInput() (io.ReadCloser, error) { - args := flag.Args() - - switch { - case len(args) < 1: - inputFilename = "-" - return os.Stdin, nil - case args[0] == "-": - inputFilename = "-" - return os.Stdin, nil - default: - inputFilename = args[0] - f, err := os.Open(args[0]) - if err != nil { - return nil, fmt.Errorf("failed to open '%s': %s", args[0], err) - } - return f, nil - } -} - -func check(h1 mh.Multihash, r io.Reader) error { - h2, err := hash(r) - if err != nil { - return err - } - - if !bytes.Equal(h1, h2) { - if quiet { - os.Exit(1) - } - return fmt.Errorf("computed checksum did not match (-q for no output)") - } - - if !quiet { - fmt.Println("OK checksums match (-q for no output)") - } - return nil -} - -func hash(r io.Reader) (mh.Multihash, error) { - b, err := ioutil.ReadAll(r) - if err != nil { - return nil, err - } - - return mh.Sum(b, algorithmCode, length) -} - -func printHash(r io.Reader) error { - h, err := hash(r) - if err != nil { - return err - } - - s, err := Encode(encoding, h) - if err != nil { - return err - } - - if quiet { - fmt.Print(s) - } else { - fmt.Println(s) - } - return nil -} - -func main() { - checkErr := func(err error) { - if err != nil { - die("error: ", err) - } - } - - err := parseFlags() - checkErr(err) - - inp, err := getInput() - checkErr(err) - - if checkMh != nil { - err = check(checkMh, inp) - checkErr(err) - } else { - err = printHash(inp) - checkErr(err) - } - inp.Close() -} - -func die(v ...interface{}) { - if !quiet { - fmt.Fprint(os.Stderr, v...) - fmt.Fprint(os.Stderr, "\n") - } - // flag.Usage() - os.Exit(1) -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash_test.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash_test.go deleted file mode 100644 index dfa858e..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/multihash_test.go +++ /dev/null @@ -1,270 +0,0 @@ -package multihash - -import ( - "bytes" - "encoding/hex" - "fmt" - "testing" -) - -// maybe silly, but makes it so changing -// the table accidentally has to happen twice. -var tCodes = map[int]string{ - 0x11: "sha1", - 0x12: "sha2-256", - 0x13: "sha2-512", - 0x14: "sha3", - 0x40: "blake2b", - 0x41: "blake2s", -} - -type TestCase struct { - hex string - code int - name string -} - -var testCases = []TestCase{ - TestCase{"0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", 0x11, "sha1"}, - TestCase{"0beec7b5", 0x11, "sha1"}, - TestCase{"2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae", 0x12, "sha2-256"}, - TestCase{"2c26b46b", 0x12, "sha2-256"}, - TestCase{"0beec7b5ea3f0fdbc9", 0x40, "blake2b"}, -} - -func (tc TestCase) Multihash() (Multihash, error) { - ob, err := hex.DecodeString(tc.hex) - if err != nil { - return nil, err - } - - b := make([]byte, 2+len(ob)) - b[0] = byte(uint8(tc.code)) - b[1] = byte(uint8(len(ob))) - copy(b[2:], ob) - return Cast(b) -} - -func TestEncode(t *testing.T) { - for _, tc := range testCases { - ob, err := hex.DecodeString(tc.hex) - if err != nil { - t.Error(err) - continue - } - - pre := make([]byte, 2) - pre[0] = byte(uint8(tc.code)) - pre[1] = byte(uint8(len(ob))) - nb := append(pre, ob...) - - encC, err := Encode(ob, tc.code) - if err != nil { - t.Error(err) - continue - } - - if !bytes.Equal(encC, nb) { - t.Error("encoded byte mismatch: ", encC, nb) - } - - encN, err := EncodeName(ob, tc.name) - if err != nil { - t.Error(err) - continue - } - - if !bytes.Equal(encN, nb) { - t.Error("encoded byte mismatch: ", encN, nb) - } - - h, err := tc.Multihash() - if err != nil { - t.Error(err) - } - if !bytes.Equal(h, nb) { - t.Error("Multihash func mismatch.") - } - } -} - -func ExampleEncodeName() { - // ignores errors for simplicity - don't do that at home. - buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") - mhbuf, _ := EncodeName(buf, "sha1") - mhhex := hex.EncodeToString(mhbuf) - fmt.Printf("hex: %v\n", mhhex) - - // Output: - // hex: 11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 -} - -func TestDecode(t *testing.T) { - for _, tc := range testCases { - ob, err := hex.DecodeString(tc.hex) - if err != nil { - t.Error(err) - continue - } - - pre := make([]byte, 2) - pre[0] = byte(uint8(tc.code)) - pre[1] = byte(uint8(len(ob))) - nb := append(pre, ob...) - - dec, err := Decode(nb) - if err != nil { - t.Error(err) - continue - } - - if dec.Code != tc.code { - t.Error("decoded code mismatch: ", dec.Code, tc.code) - } - - if dec.Name != tc.name { - t.Error("decoded name mismatch: ", dec.Name, tc.name) - } - - if dec.Length != len(ob) { - t.Error("decoded length mismatch: ", dec.Length, len(ob)) - } - - if !bytes.Equal(dec.Digest, ob) { - t.Error("decoded byte mismatch: ", dec.Digest, ob) - } - } -} - -func TestTable(t *testing.T) { - for k, v := range tCodes { - if Codes[k] != v { - t.Error("Table mismatch: ", Codes[k], v) - } - if Names[v] != k { - t.Error("Table mismatch: ", Names[v], k) - } - } -} - -func ExampleDecode() { - // ignores errors for simplicity - don't do that at home. - buf, _ := hex.DecodeString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") - mhbuf, _ := EncodeName(buf, "sha1") - o, _ := Decode(mhbuf) - mhhex := hex.EncodeToString(o.Digest) - fmt.Printf("obj: %v 0x%x %d %s\n", o.Name, o.Code, o.Length, mhhex) - - // Output: - // obj: sha1 0x11 20 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 -} - -func TestValidCode(t *testing.T) { - for i := 0; i < 0xff; i++ { - _, ok := tCodes[i] - b := AppCode(i) || ok - - if ValidCode(i) != b { - t.Error("ValidCode incorrect for: ", i) - } - } -} - -func TestAppCode(t *testing.T) { - for i := 0; i < 0xff; i++ { - b := i >= 0 && i < 0x10 - if AppCode(i) != b { - t.Error("AppCode incorrect for: ", i) - } - } -} - -func TestCast(t *testing.T) { - for _, tc := range testCases { - ob, err := hex.DecodeString(tc.hex) - if err != nil { - t.Error(err) - continue - } - - pre := make([]byte, 2) - pre[0] = byte(uint8(tc.code)) - pre[1] = byte(uint8(len(ob))) - nb := append(pre, ob...) - - if _, err := Cast(nb); err != nil { - t.Error(err) - continue - } - - if _, err = Cast(ob); err == nil { - t.Error("cast failed to detect non-multihash") - continue - } - } -} - -func TestHex(t *testing.T) { - for _, tc := range testCases { - ob, err := hex.DecodeString(tc.hex) - if err != nil { - t.Error(err) - continue - } - - pre := make([]byte, 2) - pre[0] = byte(uint8(tc.code)) - pre[1] = byte(uint8(len(ob))) - nb := append(pre, ob...) - - hs := hex.EncodeToString(nb) - mh, err := FromHexString(hs) - if err != nil { - t.Error(err) - continue - } - - if !bytes.Equal(mh, nb) { - t.Error("FromHexString failed", nb, mh) - continue - } - - if mh.HexString() != hs { - t.Error("Multihash.HexString failed", hs, mh.HexString) - continue - } - } -} - -func BenchmarkEncode(b *testing.B) { - tc := testCases[0] - ob, err := hex.DecodeString(tc.hex) - if err != nil { - b.Error(err) - return - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - Encode(ob, tc.code) - } -} - -func BenchmarkDecode(b *testing.B) { - tc := testCases[0] - ob, err := hex.DecodeString(tc.hex) - if err != nil { - b.Error(err) - return - } - - pre := make([]byte, 2) - pre[0] = byte(uint8(tc.code)) - pre[1] = byte(uint8(len(ob))) - nb := append(pre, ob...) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - Decode(nb) - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/sum.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/sum.go deleted file mode 100644 index 370ebd6..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/sum.go +++ /dev/null @@ -1,72 +0,0 @@ -package multihash - -import ( - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "errors" - "fmt" - - sha3 "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/golang.org/x/crypto/sha3" -) - -var ErrSumNotSupported = errors.New("Function not implemented. Complain to lib maintainer.") - -func Sum(data []byte, code int, length int) (Multihash, error) { - m := Multihash{} - err := error(nil) - if !ValidCode(code) { - return m, fmt.Errorf("invalid multihash code %d", code) - } - - var d []byte - switch code { - case SHA1: - d = sumSHA1(data) - case SHA2_256: - d = sumSHA256(data) - case SHA2_512: - d = sumSHA512(data) - case SHA3: - d, err = sumSHA3(data) - default: - return m, ErrSumNotSupported - } - - if err != nil { - return m, err - } - - if length < 0 { - var ok bool - length, ok = DefaultLengths[code] - if !ok { - return m, fmt.Errorf("no default length for code %d", code) - } - } - - return Encode(d[0:length], code) -} - -func sumSHA1(data []byte) []byte { - a := sha1.Sum(data) - return a[0:20] -} - -func sumSHA256(data []byte) []byte { - a := sha256.Sum256(data) - return a[0:32] -} - -func sumSHA512(data []byte) []byte { - a := sha512.Sum512(data) - return a[0:64] -} - -func sumSHA3(data []byte) ([]byte, error) { - h := sha3.New512() - if _, err := h.Write(data); err != nil { - return nil, err - } - return h.Sum(nil), nil -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/sum_test.go b/Godeps/_workspace/src/github.com/jbenet/go-multihash/sum_test.go deleted file mode 100644 index 1e5891b..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/sum_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package multihash - -import ( - "bytes" - "testing" -) - -type SumTestCase struct { - code int - length int - input string - hex string -} - -var sumTestCases = []SumTestCase{ - SumTestCase{SHA1, -1, "foo", "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"}, - SumTestCase{SHA1, 10, "foo", "110a0beec7b5ea3f0fdbc95d"}, - SumTestCase{SHA2_256, -1, "foo", "12202c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"}, - SumTestCase{SHA2_256, 16, "foo", "12102c26b46b68ffc68ff99b453c1d304134"}, - SumTestCase{SHA2_512, -1, "foo", "1340f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7"}, - SumTestCase{SHA2_512, 32, "foo", "1320f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc663832"}, -} - -func TestSum(t *testing.T) { - - for _, tc := range sumTestCases { - - m1, err := FromHexString(tc.hex) - if err != nil { - t.Error(err) - continue - } - - m2, err := Sum([]byte(tc.input), tc.code, tc.length) - if err != nil { - t.Error(tc.code, "sum failed.", err) - continue - } - - if !bytes.Equal(m1, m2) { - t.Error(tc.code, "sum failed.", m1, m2) - } - - s1 := m1.HexString() - if s1 != tc.hex { - t.Error("hex strings not the same") - } - - s2 := m1.B58String() - m3, err := FromB58String(s2) - if err != nil { - t.Error("failed to decode b58") - } else if !bytes.Equal(m3, m1) { - t.Error("b58 failing bytes") - } else if s2 != m3.B58String() { - t.Error("b58 failing string") - } - } -} - -func BenchmarkSum(b *testing.B) { - tc := sumTestCases[0] - for i := 0; i < b.N; i++ { - Sum([]byte(tc.input), tc.code, tc.length) - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/.gitignore b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/.gitignore deleted file mode 100644 index 27f75ed..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bin/multihash diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/Makefile b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/Makefile deleted file mode 100644 index e9660d0..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -BINS = bin/multihash -MULTIHASH_ROOT = ../ -MULTIHASH_CMD = ../multihash - -all: deps - -deps: bins - -clean: - rm $(BINS) - -bins: $(BINS) - -bin/multihash: $(MULTIHASH_ROOT)/**/*.go - go build -o bin/multihash $(MULTIHASH_CMD) - -test: test_expensive - -test_expensive: - cd sharness && make TEST_EXPENSIVE=1 - -test_cheap: - cd sharness && make - -.PHONY: all clean diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/.gitignore b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/.gitignore deleted file mode 100644 index 5e59048..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -lib/sharness/ -test-results/ -trash directory.*.sh/ diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/Makefile b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/Makefile deleted file mode 100644 index ad806a0..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# Run tests -# -# Copyright (c) 2014 Christian Couder -# MIT Licensed; see the LICENSE file in this repository. -# - -# NOTE: run with TEST_VERBOSE=1 for verbose sharness tests. - -T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)) -BINS = bin/multihash -SHARNESS = lib/sharness/sharness.sh - -all: clean deps $(T) aggregate - -clean: - @echo "*** $@ ***" - -rm -rf test-results - -$(T): - @echo "*** $@ ***" - ./$@ - -aggregate: - @echo "*** $@ ***" - lib/test-aggregate-results.sh - -deps: $(SHARNESS) $(BINS) - -$(SHARNESS): - @echo "*** installing $@ ***" - lib/install-sharness.sh - -bin/%: - @echo "*** installing $@ ***" - cd .. && make $@ - -.PHONY: all clean $(T) aggregate diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/bin b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/bin deleted file mode 120000 index 19f285a..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/bin +++ /dev/null @@ -1 +0,0 @@ -../bin \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/install-sharness.sh b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/install-sharness.sh deleted file mode 100644 index d573c40..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/install-sharness.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# install sharness.sh -# -# Copyright (c) 2014 Juan Batiz-Benet -# MIT Licensed; see the LICENSE file in this repository. -# - -# settings -version=50229a79ba22b2f13ccd82451d86570fecbd194c -urlprefix=https://github.com/mlafeldt/sharness.git -clonedir=lib -sharnessdir=sharness - -die() { - echo >&2 "$@" - exit 1 -} - -mkdir -p "$clonedir" || die "Could not create '$clonedir' directory" -cd "$clonedir" || die "Could not cd into '$clonedir' directory" - -git clone "$urlprefix" || die "Could not clone '$urlprefix'" -cd "$sharnessdir" || die "Could not cd into '$sharnessdir' directory" -git checkout "$version" || die "Could not checkout '$version'" - -exit 0 diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-aggregate-results.sh b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-aggregate-results.sh deleted file mode 100644 index c2ff76c..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-aggregate-results.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# -# Script to aggregate results using Sharness -# -# Copyright (c) 2014 Christian Couder -# MIT Licensed; see the LICENSE file in this repository. -# - -SHARNESS_AGGREGATE="lib/sharness/aggregate-results.sh" - -test -f "$SHARNESS_AGGREGATE" || { - echo >&2 "Cannot find: $SHARNESS_AGGREGATE" - echo >&2 "Please check Sharness installation." - exit 1 -} - -ls test-results/t*-*.sh.*.counts | "$SHARNESS_AGGREGATE" diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-lib.sh b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-lib.sh deleted file mode 100644 index 988164a..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/lib/test-lib.sh +++ /dev/null @@ -1,43 +0,0 @@ -# Test framework for go-ipfs -# -# Copyright (c) 2014 Christian Couder -# MIT Licensed; see the LICENSE file in this repository. -# -# We are using sharness (https://github.com/mlafeldt/sharness) -# which was extracted from the Git test framework. - -# Use the multihash tool to test against - -# Add current directory to path, for multihash tool. -PATH=$(pwd)/bin:${PATH} - -# Set sharness verbosity. we set the env var directly as -# it's too late to pass in --verbose, and --verbose is harder -# to pass through in some cases. -test "$TEST_VERBOSE" = 1 && verbose=t - -# assert the `multihash` we're using is the right one. -if test `which multihash` != $(pwd)/bin/multihash; then - echo >&2 "Cannot find the tests' local multihash tool." - echo >&2 "Please check test and multihash tool installation." - exit 1 -fi - -SHARNESS_LIB="lib/sharness/sharness.sh" - -. "$SHARNESS_LIB" || { - echo >&2 "Cannot source: $SHARNESS_LIB" - echo >&2 "Please check Sharness installation." - exit 1 -} - -# Please put go-multihash specific shell functions below - -for hashbin in sha1sum shasum; do - if type "$hashbin"; then - export SHASUMBIN="$hashbin" && - test_set_prereq SHASUM && - break - fi -done - diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0010-basics.sh b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0010-basics.sh deleted file mode 100644 index 1ff86ff..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0010-basics.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2015 Christian Couder -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="Basic tests" - -. lib/test-lib.sh - -test_expect_success "current dir is writable" ' - echo "It works!" >test.txt -' - -test_expect_success "multihash is available" ' - type multihash -' - -test_expect_success "multihash help output looks good" ' - test_must_fail multihash -h 2>help.txt && - cat help.txt | egrep -i "^usage:" >/dev/null && - cat help.txt | egrep -i "multihash .*options.*file" >/dev/null -' - -test_done diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0020-sha1.sh b/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0020-sha1.sh deleted file mode 100644 index a5be58b..0000000 --- a/Godeps/_workspace/src/github.com/jbenet/go-multihash/test/sharness/t0020-sha1.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2015 Christian Couder -# MIT Licensed; see the LICENSE file in this repository. -# - -test_description="sha1 tests" - -. lib/test-lib.sh - -test_expect_success "setup sha1 tests" ' - echo "Hash me!" >hash_me.txt && - SHA1=bc6f2c3cd945bc754789e50b2f68deee2f421810 && - echo "1114$SHA1" >actual -' - -test_expect_success "'multihash -a=sha1 -e=hex' works" ' - multihash -a=sha1 -e=hex hash_me.txt >expected -' - -test_expect_success "'multihash -a=sha1 -e=hex' output looks good" ' - test_cmp expected actual -' - -test_expect_success SHASUM "check hash using shasum" ' - echo "$SHA1 hash_me.txt" >actual && - $SHASUMBIN hash_me.txt >expected && - test_cmp expected actual -' - -test_done diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/doc.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/doc.go deleted file mode 100644 index 3dab530..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/doc.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package sha3 implements the SHA-3 fixed-output-length hash functions and -// the SHAKE variable-output-length hash functions defined by FIPS-202. -// -// Both types of hash function use the "sponge" construction and the Keccak -// permutation. For a detailed specification see http://keccak.noekeon.org/ -// -// -// Guidance -// -// If you aren't sure what function you need, use SHAKE256 with at least 64 -// bytes of output. The SHAKE instances are faster than the SHA3 instances; -// the latter have to allocate memory to conform to the hash.Hash interface. -// -// If you need a secret-key MAC (message authentication code), prepend the -// secret key to the input, hash with SHAKE256 and read at least 32 bytes of -// output. -// -// -// Security strengths -// -// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security -// strength against preimage attacks of x bits. Since they only produce "x" -// bits of output, their collision-resistance is only "x/2" bits. -// -// The SHAKE-256 and -128 functions have a generic security strength of 256 and -// 128 bits against all attacks, provided that at least 2x bits of their output -// is used. Requesting more than 64 or 32 bytes of output, respectively, does -// not increase the collision-resistance of the SHAKE functions. -// -// -// The sponge construction -// -// A sponge builds a pseudo-random function from a public pseudo-random -// permutation, by applying the permutation to a state of "rate + capacity" -// bytes, but hiding "capacity" of the bytes. -// -// A sponge starts out with a zero state. To hash an input using a sponge, up -// to "rate" bytes of the input are XORed into the sponge's state. The sponge -// is then "full" and the permutation is applied to "empty" it. This process is -// repeated until all the input has been "absorbed". The input is then padded. -// The digest is "squeezed" from the sponge in the same way, except that output -// output is copied out instead of input being XORed in. -// -// A sponge is parameterized by its generic security strength, which is equal -// to half its capacity; capacity + rate is equal to the permutation's width. -// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means -// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2. -// -// -// Recommendations -// -// The SHAKE functions are recommended for most new uses. They can produce -// output of arbitrary length. SHAKE256, with an output length of at least -// 64 bytes, provides 256-bit security against all attacks. The Keccak team -// recommends it for most applications upgrading from SHA2-512. (NIST chose a -// much stronger, but much slower, sponge instance for SHA3-512.) -// -// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions. -// They produce output of the same length, with the same security strengths -// against all attacks. This means, in particular, that SHA3-256 only has -// 128-bit collision resistance, because its output length is 32 bytes. -package sha3 diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/hashes.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/hashes.go deleted file mode 100644 index 2b51cf4..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/hashes.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -// This file provides functions for creating instances of the SHA-3 -// and SHAKE hash functions, as well as utility functions for hashing -// bytes. - -import ( - "hash" -) - -// New224 creates a new SHA3-224 hash. -// Its generic security strength is 224 bits against preimage attacks, -// and 112 bits against collision attacks. -func New224() hash.Hash { return &state{rate: 144, outputLen: 28, dsbyte: 0x06} } - -// New256 creates a new SHA3-256 hash. -// Its generic security strength is 256 bits against preimage attacks, -// and 128 bits against collision attacks. -func New256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x06} } - -// New384 creates a new SHA3-384 hash. -// Its generic security strength is 384 bits against preimage attacks, -// and 192 bits against collision attacks. -func New384() hash.Hash { return &state{rate: 104, outputLen: 48, dsbyte: 0x06} } - -// New512 creates a new SHA3-512 hash. -// Its generic security strength is 512 bits against preimage attacks, -// and 256 bits against collision attacks. -func New512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} } - -// Sum224 returns the SHA3-224 digest of the data. -func Sum224(data []byte) (digest [28]byte) { - h := New224() - h.Write(data) - h.Sum(digest[:0]) - return -} - -// Sum256 returns the SHA3-256 digest of the data. -func Sum256(data []byte) (digest [32]byte) { - h := New256() - h.Write(data) - h.Sum(digest[:0]) - return -} - -// Sum384 returns the SHA3-384 digest of the data. -func Sum384(data []byte) (digest [48]byte) { - h := New384() - h.Write(data) - h.Sum(digest[:0]) - return -} - -// Sum512 returns the SHA3-512 digest of the data. -func Sum512(data []byte) (digest [64]byte) { - h := New512() - h.Write(data) - h.Sum(digest[:0]) - return -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/keccakf.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/keccakf.go deleted file mode 100644 index 13e7058..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/keccakf.go +++ /dev/null @@ -1,410 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -// rc stores the round constants for use in the ι step. -var rc = [24]uint64{ - 0x0000000000000001, - 0x0000000000008082, - 0x800000000000808A, - 0x8000000080008000, - 0x000000000000808B, - 0x0000000080000001, - 0x8000000080008081, - 0x8000000000008009, - 0x000000000000008A, - 0x0000000000000088, - 0x0000000080008009, - 0x000000008000000A, - 0x000000008000808B, - 0x800000000000008B, - 0x8000000000008089, - 0x8000000000008003, - 0x8000000000008002, - 0x8000000000000080, - 0x000000000000800A, - 0x800000008000000A, - 0x8000000080008081, - 0x8000000000008080, - 0x0000000080000001, - 0x8000000080008008, -} - -// keccakF1600 applies the Keccak permutation to a 1600b-wide -// state represented as a slice of 25 uint64s. -func keccakF1600(a *[25]uint64) { - // Implementation translated from Keccak-inplace.c - // in the keccak reference code. - var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64 - - for i := 0; i < 24; i += 4 { - // Combines the 5 steps in each round into 2 steps. - // Unrolls 4 rounds per loop and spreads some steps across rounds. - - // Round 1 - bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] - bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] - bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] - bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] - bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] - d0 = bc4 ^ (bc1<<1 | bc1>>63) - d1 = bc0 ^ (bc2<<1 | bc2>>63) - d2 = bc1 ^ (bc3<<1 | bc3>>63) - d3 = bc2 ^ (bc4<<1 | bc4>>63) - d4 = bc3 ^ (bc0<<1 | bc0>>63) - - bc0 = a[0] ^ d0 - t = a[6] ^ d1 - bc1 = t<<44 | t>>(64-44) - t = a[12] ^ d2 - bc2 = t<<43 | t>>(64-43) - t = a[18] ^ d3 - bc3 = t<<21 | t>>(64-21) - t = a[24] ^ d4 - bc4 = t<<14 | t>>(64-14) - a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i] - a[6] = bc1 ^ (bc3 &^ bc2) - a[12] = bc2 ^ (bc4 &^ bc3) - a[18] = bc3 ^ (bc0 &^ bc4) - a[24] = bc4 ^ (bc1 &^ bc0) - - t = a[10] ^ d0 - bc2 = t<<3 | t>>(64-3) - t = a[16] ^ d1 - bc3 = t<<45 | t>>(64-45) - t = a[22] ^ d2 - bc4 = t<<61 | t>>(64-61) - t = a[3] ^ d3 - bc0 = t<<28 | t>>(64-28) - t = a[9] ^ d4 - bc1 = t<<20 | t>>(64-20) - a[10] = bc0 ^ (bc2 &^ bc1) - a[16] = bc1 ^ (bc3 &^ bc2) - a[22] = bc2 ^ (bc4 &^ bc3) - a[3] = bc3 ^ (bc0 &^ bc4) - a[9] = bc4 ^ (bc1 &^ bc0) - - t = a[20] ^ d0 - bc4 = t<<18 | t>>(64-18) - t = a[1] ^ d1 - bc0 = t<<1 | t>>(64-1) - t = a[7] ^ d2 - bc1 = t<<6 | t>>(64-6) - t = a[13] ^ d3 - bc2 = t<<25 | t>>(64-25) - t = a[19] ^ d4 - bc3 = t<<8 | t>>(64-8) - a[20] = bc0 ^ (bc2 &^ bc1) - a[1] = bc1 ^ (bc3 &^ bc2) - a[7] = bc2 ^ (bc4 &^ bc3) - a[13] = bc3 ^ (bc0 &^ bc4) - a[19] = bc4 ^ (bc1 &^ bc0) - - t = a[5] ^ d0 - bc1 = t<<36 | t>>(64-36) - t = a[11] ^ d1 - bc2 = t<<10 | t>>(64-10) - t = a[17] ^ d2 - bc3 = t<<15 | t>>(64-15) - t = a[23] ^ d3 - bc4 = t<<56 | t>>(64-56) - t = a[4] ^ d4 - bc0 = t<<27 | t>>(64-27) - a[5] = bc0 ^ (bc2 &^ bc1) - a[11] = bc1 ^ (bc3 &^ bc2) - a[17] = bc2 ^ (bc4 &^ bc3) - a[23] = bc3 ^ (bc0 &^ bc4) - a[4] = bc4 ^ (bc1 &^ bc0) - - t = a[15] ^ d0 - bc3 = t<<41 | t>>(64-41) - t = a[21] ^ d1 - bc4 = t<<2 | t>>(64-2) - t = a[2] ^ d2 - bc0 = t<<62 | t>>(64-62) - t = a[8] ^ d3 - bc1 = t<<55 | t>>(64-55) - t = a[14] ^ d4 - bc2 = t<<39 | t>>(64-39) - a[15] = bc0 ^ (bc2 &^ bc1) - a[21] = bc1 ^ (bc3 &^ bc2) - a[2] = bc2 ^ (bc4 &^ bc3) - a[8] = bc3 ^ (bc0 &^ bc4) - a[14] = bc4 ^ (bc1 &^ bc0) - - // Round 2 - bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] - bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] - bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] - bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] - bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] - d0 = bc4 ^ (bc1<<1 | bc1>>63) - d1 = bc0 ^ (bc2<<1 | bc2>>63) - d2 = bc1 ^ (bc3<<1 | bc3>>63) - d3 = bc2 ^ (bc4<<1 | bc4>>63) - d4 = bc3 ^ (bc0<<1 | bc0>>63) - - bc0 = a[0] ^ d0 - t = a[16] ^ d1 - bc1 = t<<44 | t>>(64-44) - t = a[7] ^ d2 - bc2 = t<<43 | t>>(64-43) - t = a[23] ^ d3 - bc3 = t<<21 | t>>(64-21) - t = a[14] ^ d4 - bc4 = t<<14 | t>>(64-14) - a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1] - a[16] = bc1 ^ (bc3 &^ bc2) - a[7] = bc2 ^ (bc4 &^ bc3) - a[23] = bc3 ^ (bc0 &^ bc4) - a[14] = bc4 ^ (bc1 &^ bc0) - - t = a[20] ^ d0 - bc2 = t<<3 | t>>(64-3) - t = a[11] ^ d1 - bc3 = t<<45 | t>>(64-45) - t = a[2] ^ d2 - bc4 = t<<61 | t>>(64-61) - t = a[18] ^ d3 - bc0 = t<<28 | t>>(64-28) - t = a[9] ^ d4 - bc1 = t<<20 | t>>(64-20) - a[20] = bc0 ^ (bc2 &^ bc1) - a[11] = bc1 ^ (bc3 &^ bc2) - a[2] = bc2 ^ (bc4 &^ bc3) - a[18] = bc3 ^ (bc0 &^ bc4) - a[9] = bc4 ^ (bc1 &^ bc0) - - t = a[15] ^ d0 - bc4 = t<<18 | t>>(64-18) - t = a[6] ^ d1 - bc0 = t<<1 | t>>(64-1) - t = a[22] ^ d2 - bc1 = t<<6 | t>>(64-6) - t = a[13] ^ d3 - bc2 = t<<25 | t>>(64-25) - t = a[4] ^ d4 - bc3 = t<<8 | t>>(64-8) - a[15] = bc0 ^ (bc2 &^ bc1) - a[6] = bc1 ^ (bc3 &^ bc2) - a[22] = bc2 ^ (bc4 &^ bc3) - a[13] = bc3 ^ (bc0 &^ bc4) - a[4] = bc4 ^ (bc1 &^ bc0) - - t = a[10] ^ d0 - bc1 = t<<36 | t>>(64-36) - t = a[1] ^ d1 - bc2 = t<<10 | t>>(64-10) - t = a[17] ^ d2 - bc3 = t<<15 | t>>(64-15) - t = a[8] ^ d3 - bc4 = t<<56 | t>>(64-56) - t = a[24] ^ d4 - bc0 = t<<27 | t>>(64-27) - a[10] = bc0 ^ (bc2 &^ bc1) - a[1] = bc1 ^ (bc3 &^ bc2) - a[17] = bc2 ^ (bc4 &^ bc3) - a[8] = bc3 ^ (bc0 &^ bc4) - a[24] = bc4 ^ (bc1 &^ bc0) - - t = a[5] ^ d0 - bc3 = t<<41 | t>>(64-41) - t = a[21] ^ d1 - bc4 = t<<2 | t>>(64-2) - t = a[12] ^ d2 - bc0 = t<<62 | t>>(64-62) - t = a[3] ^ d3 - bc1 = t<<55 | t>>(64-55) - t = a[19] ^ d4 - bc2 = t<<39 | t>>(64-39) - a[5] = bc0 ^ (bc2 &^ bc1) - a[21] = bc1 ^ (bc3 &^ bc2) - a[12] = bc2 ^ (bc4 &^ bc3) - a[3] = bc3 ^ (bc0 &^ bc4) - a[19] = bc4 ^ (bc1 &^ bc0) - - // Round 3 - bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] - bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] - bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] - bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] - bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] - d0 = bc4 ^ (bc1<<1 | bc1>>63) - d1 = bc0 ^ (bc2<<1 | bc2>>63) - d2 = bc1 ^ (bc3<<1 | bc3>>63) - d3 = bc2 ^ (bc4<<1 | bc4>>63) - d4 = bc3 ^ (bc0<<1 | bc0>>63) - - bc0 = a[0] ^ d0 - t = a[11] ^ d1 - bc1 = t<<44 | t>>(64-44) - t = a[22] ^ d2 - bc2 = t<<43 | t>>(64-43) - t = a[8] ^ d3 - bc3 = t<<21 | t>>(64-21) - t = a[19] ^ d4 - bc4 = t<<14 | t>>(64-14) - a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2] - a[11] = bc1 ^ (bc3 &^ bc2) - a[22] = bc2 ^ (bc4 &^ bc3) - a[8] = bc3 ^ (bc0 &^ bc4) - a[19] = bc4 ^ (bc1 &^ bc0) - - t = a[15] ^ d0 - bc2 = t<<3 | t>>(64-3) - t = a[1] ^ d1 - bc3 = t<<45 | t>>(64-45) - t = a[12] ^ d2 - bc4 = t<<61 | t>>(64-61) - t = a[23] ^ d3 - bc0 = t<<28 | t>>(64-28) - t = a[9] ^ d4 - bc1 = t<<20 | t>>(64-20) - a[15] = bc0 ^ (bc2 &^ bc1) - a[1] = bc1 ^ (bc3 &^ bc2) - a[12] = bc2 ^ (bc4 &^ bc3) - a[23] = bc3 ^ (bc0 &^ bc4) - a[9] = bc4 ^ (bc1 &^ bc0) - - t = a[5] ^ d0 - bc4 = t<<18 | t>>(64-18) - t = a[16] ^ d1 - bc0 = t<<1 | t>>(64-1) - t = a[2] ^ d2 - bc1 = t<<6 | t>>(64-6) - t = a[13] ^ d3 - bc2 = t<<25 | t>>(64-25) - t = a[24] ^ d4 - bc3 = t<<8 | t>>(64-8) - a[5] = bc0 ^ (bc2 &^ bc1) - a[16] = bc1 ^ (bc3 &^ bc2) - a[2] = bc2 ^ (bc4 &^ bc3) - a[13] = bc3 ^ (bc0 &^ bc4) - a[24] = bc4 ^ (bc1 &^ bc0) - - t = a[20] ^ d0 - bc1 = t<<36 | t>>(64-36) - t = a[6] ^ d1 - bc2 = t<<10 | t>>(64-10) - t = a[17] ^ d2 - bc3 = t<<15 | t>>(64-15) - t = a[3] ^ d3 - bc4 = t<<56 | t>>(64-56) - t = a[14] ^ d4 - bc0 = t<<27 | t>>(64-27) - a[20] = bc0 ^ (bc2 &^ bc1) - a[6] = bc1 ^ (bc3 &^ bc2) - a[17] = bc2 ^ (bc4 &^ bc3) - a[3] = bc3 ^ (bc0 &^ bc4) - a[14] = bc4 ^ (bc1 &^ bc0) - - t = a[10] ^ d0 - bc3 = t<<41 | t>>(64-41) - t = a[21] ^ d1 - bc4 = t<<2 | t>>(64-2) - t = a[7] ^ d2 - bc0 = t<<62 | t>>(64-62) - t = a[18] ^ d3 - bc1 = t<<55 | t>>(64-55) - t = a[4] ^ d4 - bc2 = t<<39 | t>>(64-39) - a[10] = bc0 ^ (bc2 &^ bc1) - a[21] = bc1 ^ (bc3 &^ bc2) - a[7] = bc2 ^ (bc4 &^ bc3) - a[18] = bc3 ^ (bc0 &^ bc4) - a[4] = bc4 ^ (bc1 &^ bc0) - - // Round 4 - bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] - bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] - bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] - bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] - bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] - d0 = bc4 ^ (bc1<<1 | bc1>>63) - d1 = bc0 ^ (bc2<<1 | bc2>>63) - d2 = bc1 ^ (bc3<<1 | bc3>>63) - d3 = bc2 ^ (bc4<<1 | bc4>>63) - d4 = bc3 ^ (bc0<<1 | bc0>>63) - - bc0 = a[0] ^ d0 - t = a[1] ^ d1 - bc1 = t<<44 | t>>(64-44) - t = a[2] ^ d2 - bc2 = t<<43 | t>>(64-43) - t = a[3] ^ d3 - bc3 = t<<21 | t>>(64-21) - t = a[4] ^ d4 - bc4 = t<<14 | t>>(64-14) - a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3] - a[1] = bc1 ^ (bc3 &^ bc2) - a[2] = bc2 ^ (bc4 &^ bc3) - a[3] = bc3 ^ (bc0 &^ bc4) - a[4] = bc4 ^ (bc1 &^ bc0) - - t = a[5] ^ d0 - bc2 = t<<3 | t>>(64-3) - t = a[6] ^ d1 - bc3 = t<<45 | t>>(64-45) - t = a[7] ^ d2 - bc4 = t<<61 | t>>(64-61) - t = a[8] ^ d3 - bc0 = t<<28 | t>>(64-28) - t = a[9] ^ d4 - bc1 = t<<20 | t>>(64-20) - a[5] = bc0 ^ (bc2 &^ bc1) - a[6] = bc1 ^ (bc3 &^ bc2) - a[7] = bc2 ^ (bc4 &^ bc3) - a[8] = bc3 ^ (bc0 &^ bc4) - a[9] = bc4 ^ (bc1 &^ bc0) - - t = a[10] ^ d0 - bc4 = t<<18 | t>>(64-18) - t = a[11] ^ d1 - bc0 = t<<1 | t>>(64-1) - t = a[12] ^ d2 - bc1 = t<<6 | t>>(64-6) - t = a[13] ^ d3 - bc2 = t<<25 | t>>(64-25) - t = a[14] ^ d4 - bc3 = t<<8 | t>>(64-8) - a[10] = bc0 ^ (bc2 &^ bc1) - a[11] = bc1 ^ (bc3 &^ bc2) - a[12] = bc2 ^ (bc4 &^ bc3) - a[13] = bc3 ^ (bc0 &^ bc4) - a[14] = bc4 ^ (bc1 &^ bc0) - - t = a[15] ^ d0 - bc1 = t<<36 | t>>(64-36) - t = a[16] ^ d1 - bc2 = t<<10 | t>>(64-10) - t = a[17] ^ d2 - bc3 = t<<15 | t>>(64-15) - t = a[18] ^ d3 - bc4 = t<<56 | t>>(64-56) - t = a[19] ^ d4 - bc0 = t<<27 | t>>(64-27) - a[15] = bc0 ^ (bc2 &^ bc1) - a[16] = bc1 ^ (bc3 &^ bc2) - a[17] = bc2 ^ (bc4 &^ bc3) - a[18] = bc3 ^ (bc0 &^ bc4) - a[19] = bc4 ^ (bc1 &^ bc0) - - t = a[20] ^ d0 - bc3 = t<<41 | t>>(64-41) - t = a[21] ^ d1 - bc4 = t<<2 | t>>(64-2) - t = a[22] ^ d2 - bc0 = t<<62 | t>>(64-62) - t = a[23] ^ d3 - bc1 = t<<55 | t>>(64-55) - t = a[24] ^ d4 - bc2 = t<<39 | t>>(64-39) - a[20] = bc0 ^ (bc2 &^ bc1) - a[21] = bc1 ^ (bc3 &^ bc2) - a[22] = bc2 ^ (bc4 &^ bc3) - a[23] = bc3 ^ (bc0 &^ bc4) - a[24] = bc4 ^ (bc1 &^ bc0) - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/register.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/register.go deleted file mode 100644 index 3cf6a22..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/register.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.4 - -package sha3 - -import ( - "crypto" -) - -func init() { - crypto.RegisterHash(crypto.SHA3_224, New224) - crypto.RegisterHash(crypto.SHA3_256, New256) - crypto.RegisterHash(crypto.SHA3_384, New384) - crypto.RegisterHash(crypto.SHA3_512, New512) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/sha3.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/sha3.go deleted file mode 100644 index c8fd31c..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/sha3.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -// spongeDirection indicates the direction bytes are flowing through the sponge. -type spongeDirection int - -const ( - // spongeAbsorbing indicates that the sponge is absorbing input. - spongeAbsorbing spongeDirection = iota - // spongeSqueezing indicates that the sponge is being squeezed. - spongeSqueezing -) - -const ( - // maxRate is the maximum size of the internal buffer. SHAKE-256 - // currently needs the largest buffer. - maxRate = 168 -) - -type state struct { - // Generic sponge components. - a [25]uint64 // main state of the hash - buf []byte // points into storage - rate int // the number of bytes of state to use - - // dsbyte contains the "domain separation" bits and the first bit of - // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the - // SHA-3 and SHAKE functions by appending bitstrings to the message. - // Using a little-endian bit-ordering convention, these are "01" for SHA-3 - // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the - // padding rule from section 5.1 is applied to pad the message to a multiple - // of the rate, which involves adding a "1" bit, zero or more "0" bits, and - // a final "1" bit. We merge the first "1" bit from the padding into dsbyte, - // giving 00000110b (0x06) and 00011111b (0x1f). - // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf - // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and - // Extendable-Output Functions (May 2014)" - dsbyte byte - storage [maxRate]byte - - // Specific to SHA-3 and SHAKE. - fixedOutput bool // whether this is a fixed-ouput-length instance - outputLen int // the default output size in bytes - state spongeDirection // whether the sponge is absorbing or squeezing -} - -// BlockSize returns the rate of sponge underlying this hash function. -func (d *state) BlockSize() int { return d.rate } - -// Size returns the output size of the hash function in bytes. -func (d *state) Size() int { return d.outputLen } - -// Reset clears the internal state by zeroing the sponge state and -// the byte buffer, and setting Sponge.state to absorbing. -func (d *state) Reset() { - // Zero the permutation's state. - for i := range d.a { - d.a[i] = 0 - } - d.state = spongeAbsorbing - d.buf = d.storage[:0] -} - -func (d *state) clone() *state { - ret := *d - if ret.state == spongeAbsorbing { - ret.buf = ret.storage[:len(ret.buf)] - } else { - ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate] - } - - return &ret -} - -// permute applies the KeccakF-1600 permutation. It handles -// any input-output buffering. -func (d *state) permute() { - switch d.state { - case spongeAbsorbing: - // If we're absorbing, we need to xor the input into the state - // before applying the permutation. - xorIn(d, d.buf) - d.buf = d.storage[:0] - keccakF1600(&d.a) - case spongeSqueezing: - // If we're squeezing, we need to apply the permutatin before - // copying more output. - keccakF1600(&d.a) - d.buf = d.storage[:d.rate] - copyOut(d, d.buf) - } -} - -// pads appends the domain separation bits in dsbyte, applies -// the multi-bitrate 10..1 padding rule, and permutes the state. -func (d *state) padAndPermute(dsbyte byte) { - if d.buf == nil { - d.buf = d.storage[:0] - } - // Pad with this instance's domain-separator bits. We know that there's - // at least one byte of space in d.buf because, if it were full, - // permute would have been called to empty it. dsbyte also contains the - // first one bit for the padding. See the comment in the state struct. - d.buf = append(d.buf, dsbyte) - zerosStart := len(d.buf) - d.buf = d.storage[:d.rate] - for i := zerosStart; i < d.rate; i++ { - d.buf[i] = 0 - } - // This adds the final one bit for the padding. Because of the way that - // bits are numbered from the LSB upwards, the final bit is the MSB of - // the last byte. - d.buf[d.rate-1] ^= 0x80 - // Apply the permutation - d.permute() - d.state = spongeSqueezing - d.buf = d.storage[:d.rate] - copyOut(d, d.buf) -} - -// Write absorbs more data into the hash's state. It produces an error -// if more data is written to the ShakeHash after writing -func (d *state) Write(p []byte) (written int, err error) { - if d.state != spongeAbsorbing { - panic("sha3: write to sponge after read") - } - if d.buf == nil { - d.buf = d.storage[:0] - } - written = len(p) - - for len(p) > 0 { - if len(d.buf) == 0 && len(p) >= d.rate { - // The fast path; absorb a full "rate" bytes of input and apply the permutation. - xorIn(d, p[:d.rate]) - p = p[d.rate:] - keccakF1600(&d.a) - } else { - // The slow path; buffer the input until we can fill the sponge, and then xor it in. - todo := d.rate - len(d.buf) - if todo > len(p) { - todo = len(p) - } - d.buf = append(d.buf, p[:todo]...) - p = p[todo:] - - // If the sponge is full, apply the permutation. - if len(d.buf) == d.rate { - d.permute() - } - } - } - - return -} - -// Read squeezes an arbitrary number of bytes from the sponge. -func (d *state) Read(out []byte) (n int, err error) { - // If we're still absorbing, pad and apply the permutation. - if d.state == spongeAbsorbing { - d.padAndPermute(d.dsbyte) - } - - n = len(out) - - // Now, do the squeezing. - for len(out) > 0 { - n := copy(out, d.buf) - d.buf = d.buf[n:] - out = out[n:] - - // Apply the permutation if we've squeezed the sponge dry. - if len(d.buf) == 0 { - d.permute() - } - } - - return -} - -// Sum applies padding to the hash state and then squeezes out the desired -// number of output bytes. -func (d *state) Sum(in []byte) []byte { - // Make a copy of the original hash so that caller can keep writing - // and summing. - dup := d.clone() - hash := make([]byte, dup.outputLen) - dup.Read(hash) - return append(in, hash...) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/sha3_test.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/sha3_test.go deleted file mode 100644 index cbf811d..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/sha3_test.go +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -// Tests include all the ShortMsgKATs provided by the Keccak team at -// https://github.com/gvanas/KeccakCodePackage -// -// They only include the zero-bit case of the bitwise testvectors -// published by NIST in the draft of FIPS-202. - -import ( - "bytes" - "compress/flate" - "encoding/hex" - "encoding/json" - "hash" - "os" - "strings" - "testing" -) - -const ( - testString = "brekeccakkeccak koax koax" - katFilename = "testdata/keccakKats.json.deflate" -) - -// Internal-use instances of SHAKE used to test against KATs. -func newHashShake128() hash.Hash { - return &state{rate: 168, dsbyte: 0x1f, outputLen: 512} -} -func newHashShake256() hash.Hash { - return &state{rate: 136, dsbyte: 0x1f, outputLen: 512} -} - -// testDigests contains functions returning hash.Hash instances -// with output-length equal to the KAT length for both SHA-3 and -// SHAKE instances. -var testDigests = map[string]func() hash.Hash{ - "SHA3-224": New224, - "SHA3-256": New256, - "SHA3-384": New384, - "SHA3-512": New512, - "SHAKE128": newHashShake128, - "SHAKE256": newHashShake256, -} - -// testShakes contains functions that return ShakeHash instances for -// testing the ShakeHash-specific interface. -var testShakes = map[string]func() ShakeHash{ - "SHAKE128": NewShake128, - "SHAKE256": NewShake256, -} - -// decodeHex converts a hex-encoded string into a raw byte string. -func decodeHex(s string) []byte { - b, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - return b -} - -// structs used to marshal JSON test-cases. -type KeccakKats struct { - Kats map[string][]struct { - Digest string `json:"digest"` - Length int64 `json:"length"` - Message string `json:"message"` - } -} - -func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) { - xorInOrig, copyOutOrig := xorIn, copyOut - xorIn, copyOut = xorInGeneric, copyOutGeneric - testf("generic") - if xorImplementationUnaligned != "generic" { - xorIn, copyOut = xorInUnaligned, copyOutUnaligned - testf("unaligned") - } - xorIn, copyOut = xorInOrig, copyOutOrig -} - -// TestKeccakKats tests the SHA-3 and Shake implementations against all the -// ShortMsgKATs from https://github.com/gvanas/KeccakCodePackage -// (The testvectors are stored in keccakKats.json.deflate due to their length.) -func TestKeccakKats(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - // Read the KATs. - deflated, err := os.Open(katFilename) - if err != nil { - t.Errorf("error opening %s: %s", katFilename, err) - } - file := flate.NewReader(deflated) - dec := json.NewDecoder(file) - var katSet KeccakKats - err = dec.Decode(&katSet) - if err != nil { - t.Errorf("error decoding KATs: %s", err) - } - - // Do the KATs. - for functionName, kats := range katSet.Kats { - d := testDigests[functionName]() - for _, kat := range kats { - d.Reset() - in, err := hex.DecodeString(kat.Message) - if err != nil { - t.Errorf("error decoding KAT: %s", err) - } - d.Write(in[:kat.Length/8]) - got := strings.ToUpper(hex.EncodeToString(d.Sum(nil))) - if got != kat.Digest { - t.Errorf("function=%s, implementation=%s, length=%d\nmessage:\n %s\ngot:\n %s\nwanted:\n %s", - functionName, impl, kat.Length, kat.Message, got, kat.Digest) - t.Logf("wanted %+v", kat) - t.FailNow() - } - continue - } - } - }) -} - -// TestUnalignedWrite tests that writing data in an arbitrary pattern with -// small input buffers. -func testUnalignedWrite(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - buf := sequentialBytes(0x10000) - for alg, df := range testDigests { - d := df() - d.Reset() - d.Write(buf) - want := d.Sum(nil) - d.Reset() - for i := 0; i < len(buf); { - // Cycle through offsets which make a 137 byte sequence. - // Because 137 is prime this sequence should exercise all corner cases. - offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1} - for _, j := range offsets { - if v := len(buf) - i; v < j { - j = v - } - d.Write(buf[i : i+j]) - i += j - } - } - got := d.Sum(nil) - if !bytes.Equal(got, want) { - t.Errorf("Unaligned writes, implementation=%s, alg=%s\ngot %q, want %q", impl, alg, got, want) - } - } - }) -} - -// TestAppend checks that appending works when reallocation is necessary. -func TestAppend(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - d := New224() - - for capacity := 2; capacity < 64; capacity += 64 { - // The first time around the loop, Sum will have to reallocate. - // The second time, it will not. - buf := make([]byte, 2, capacity) - d.Reset() - d.Write([]byte{0xcc}) - buf = d.Sum(buf) - expected := "0000DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39" - if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected { - t.Errorf("got %s, want %s", got, expected) - } - } - }) -} - -// TestAppendNoRealloc tests that appending works when no reallocation is necessary. -func TestAppendNoRealloc(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - buf := make([]byte, 1, 200) - d := New224() - d.Write([]byte{0xcc}) - buf = d.Sum(buf) - expected := "00DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39" - if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected { - t.Errorf("%s: got %s, want %s", impl, got, expected) - } - }) -} - -// TestSqueezing checks that squeezing the full output a single time produces -// the same output as repeatedly squeezing the instance. -func TestSqueezing(t *testing.T) { - testUnalignedAndGeneric(t, func(impl string) { - for functionName, newShakeHash := range testShakes { - d0 := newShakeHash() - d0.Write([]byte(testString)) - ref := make([]byte, 32) - d0.Read(ref) - - d1 := newShakeHash() - d1.Write([]byte(testString)) - var multiple []byte - for _ = range ref { - one := make([]byte, 1) - d1.Read(one) - multiple = append(multiple, one...) - } - if !bytes.Equal(ref, multiple) { - t.Errorf("%s (%s): squeezing %d bytes one at a time failed", functionName, impl, len(ref)) - } - } - }) -} - -// sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing. -func sequentialBytes(size int) []byte { - result := make([]byte, size) - for i := range result { - result[i] = byte(i) - } - return result -} - -// BenchmarkPermutationFunction measures the speed of the permutation function -// with no input data. -func BenchmarkPermutationFunction(b *testing.B) { - b.SetBytes(int64(200)) - var lanes [25]uint64 - for i := 0; i < b.N; i++ { - keccakF1600(&lanes) - } -} - -// benchmarkHash tests the speed to hash num buffers of buflen each. -func benchmarkHash(b *testing.B, h hash.Hash, size, num int) { - b.StopTimer() - h.Reset() - data := sequentialBytes(size) - b.SetBytes(int64(size * num)) - b.StartTimer() - - var state []byte - for i := 0; i < b.N; i++ { - for j := 0; j < num; j++ { - h.Write(data) - } - state = h.Sum(state[:0]) - } - b.StopTimer() - h.Reset() -} - -// benchmarkShake is specialized to the Shake instances, which don't -// require a copy on reading output. -func benchmarkShake(b *testing.B, h ShakeHash, size, num int) { - b.StopTimer() - h.Reset() - data := sequentialBytes(size) - d := make([]byte, 32) - - b.SetBytes(int64(size * num)) - b.StartTimer() - - for i := 0; i < b.N; i++ { - h.Reset() - for j := 0; j < num; j++ { - h.Write(data) - } - h.Read(d) - } -} - -func BenchmarkSha3_512_MTU(b *testing.B) { benchmarkHash(b, New512(), 1350, 1) } -func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) } -func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) } -func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) } - -func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 1350, 1) } -func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) } -func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) } -func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) } - -func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) } - -func Example_sum() { - buf := []byte("some data to hash") - // A hash needs to be 64 bytes long to have 256-bit collision resistance. - h := make([]byte, 64) - // Compute a 64-byte hash of buf and put it in h. - ShakeSum256(h, buf) -} - -func Example_mac() { - k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long") - buf := []byte("and this is some data to authenticate") - // A MAC with 32 bytes of output has 256-bit security strength -- if you use at least a 32-byte-long key. - h := make([]byte, 32) - d := NewShake256() - // Write the key into the hash. - d.Write(k) - // Now write the data. - d.Write(buf) - // Read 32 bytes of output from the hash into h. - d.Read(h) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/shake.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/shake.go deleted file mode 100644 index 841f986..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/shake.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -// This file defines the ShakeHash interface, and provides -// functions for creating SHAKE instances, as well as utility -// functions for hashing bytes to arbitrary-length output. - -import ( - "io" -) - -// ShakeHash defines the interface to hash functions that -// support arbitrary-length output. -type ShakeHash interface { - // Write absorbs more data into the hash's state. It panics if input is - // written to it after output has been read from it. - io.Writer - - // Read reads more output from the hash; reading affects the hash's - // state. (ShakeHash.Read is thus very different from Hash.Sum) - // It never returns an error. - io.Reader - - // Clone returns a copy of the ShakeHash in its current state. - Clone() ShakeHash - - // Reset resets the ShakeHash to its initial state. - Reset() -} - -func (d *state) Clone() ShakeHash { - return d.clone() -} - -// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash. -// Its generic security strength is 128 bits against all attacks if at -// least 32 bytes of its output are used. -func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} } - -// NewShake256 creates a new SHAKE128 variable-output-length ShakeHash. -// Its generic security strength is 256 bits against all attacks if -// at least 64 bytes of its output are used. -func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} } - -// ShakeSum128 writes an arbitrary-length digest of data into hash. -func ShakeSum128(hash, data []byte) { - h := NewShake128() - h.Write(data) - h.Read(hash) -} - -// ShakeSum256 writes an arbitrary-length digest of data into hash. -func ShakeSum256(hash, data []byte) { - h := NewShake256() - h.Write(data) - h.Read(hash) -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/testdata/keccakKats.json.deflate b/Godeps/_workspace/src/golang.org/x/crypto/sha3/testdata/keccakKats.json.deflate deleted file mode 100644 index 62e85ae..0000000 Binary files a/Godeps/_workspace/src/golang.org/x/crypto/sha3/testdata/keccakKats.json.deflate and /dev/null differ diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor.go deleted file mode 100644 index d622979..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !amd64,!386 appengine - -package sha3 - -var ( - xorIn = xorInGeneric - copyOut = copyOutGeneric - xorInUnaligned = xorInGeneric - copyOutUnaligned = copyOutGeneric -) - -const xorImplementationUnaligned = "generic" diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor_generic.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor_generic.go deleted file mode 100644 index fd35f02..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor_generic.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sha3 - -import "encoding/binary" - -// xorInGeneric xors the bytes in buf into the state; it -// makes no non-portable assumptions about memory layout -// or alignment. -func xorInGeneric(d *state, buf []byte) { - n := len(buf) / 8 - - for i := 0; i < n; i++ { - a := binary.LittleEndian.Uint64(buf) - d.a[i] ^= a - buf = buf[8:] - } -} - -// copyOutGeneric copies ulint64s to a byte buffer. -func copyOutGeneric(d *state, b []byte) { - for i := 0; len(b) >= 8; i++ { - binary.LittleEndian.PutUint64(b, d.a[i]) - b = b[8:] - } -} diff --git a/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor_unaligned.go b/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor_unaligned.go deleted file mode 100644 index c7851a1..0000000 --- a/Godeps/_workspace/src/golang.org/x/crypto/sha3/xor_unaligned.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build amd64 386 -// +build !appengine - -package sha3 - -import "unsafe" - -func xorInUnaligned(d *state, buf []byte) { - bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0])) - n := len(buf) - if n >= 72 { - d.a[0] ^= bw[0] - d.a[1] ^= bw[1] - d.a[2] ^= bw[2] - d.a[3] ^= bw[3] - d.a[4] ^= bw[4] - d.a[5] ^= bw[5] - d.a[6] ^= bw[6] - d.a[7] ^= bw[7] - d.a[8] ^= bw[8] - } - if n >= 104 { - d.a[9] ^= bw[9] - d.a[10] ^= bw[10] - d.a[11] ^= bw[11] - d.a[12] ^= bw[12] - } - if n >= 136 { - d.a[13] ^= bw[13] - d.a[14] ^= bw[14] - d.a[15] ^= bw[15] - d.a[16] ^= bw[16] - } - if n >= 144 { - d.a[17] ^= bw[17] - } - if n >= 168 { - d.a[18] ^= bw[18] - d.a[19] ^= bw[19] - d.a[20] ^= bw[20] - } -} - -func copyOutUnaligned(d *state, buf []byte) { - ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0])) - copy(buf, ab[:]) -} - -var ( - xorIn = xorInUnaligned - copyOut = copyOutUnaligned -) - -const xorImplementationUnaligned = "unaligned" diff --git a/Makefile b/Makefile index ed03c80..825b65d 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,28 @@ -all: install +export PATH := bin:$(PATH) -godep: - go get github.com/tools/godep +deps: gxbins + bin/gx install --global + bin/gx-go rewrite -# saves/vendors third-party dependencies to Godeps/_workspace -# -r flag rewrites import paths to use the vendored path -# ./... performs operation on all packages in tree -vendor: godep - godep save -r ./... +publish: + bin/gx-go rewrite --undo + bin/gx publish -install: dep - cd multiaddr && go install - -test: +test: deps go test -race -cpu=5 -v ./... -dep: - cd multiaddr && go get ./... +gxbins: bin/gx-v0.6.0 bin/gx-go-v1.2.0 + +bin/gx-v0.6.0: + mkdir -p bin + ./bin/dist_get gx bin/gx-v0.6.0 v0.6.0 + ln -s gx-v0.6.0 bin/gx + +bin/gx-go-v1.2.0: + mkdir -p bin + ./bin/dist_get gx-go bin/gx-go-v1.2.0 v1.2.0 + ln -s gx-go-v1.2.0 bin/gx-go + +clean: + rm -f bin/gx* + rm -rf bin/tmp diff --git a/bin/dist_get b/bin/dist_get new file mode 100755 index 0000000..d6bdd12 --- /dev/null +++ b/bin/dist_get @@ -0,0 +1,146 @@ +#!/bin/bash + +die() { + echo "$@" >&2 + exit 1 +} + +have_binary() { + type "$1" > /dev/null 2> /dev/null +} + +check_writeable() { + printf "" > "$1" && rm "$1" +} + +download() { + local url="$1" + local output="$2" + + if [ -z "$url" ] || [ -z "$output" ]; then + die "download takes exactly two arguments. was given '$@'" + fi + + if ! check_writeable "$output"; then + die "download error: cannot write to $output" + fi + + if have_binary wget; then + printf 'Using wget to download "%s" to "%s"\n' "$url" "$output" + wget "$url" -O "$output" + elif have_binary curl; then + printf 'Using curl to download "%s" to "%s"\n' "$url" "$output" + curl --silent "$url" > "$output" + elif have_binary fetch; then + printf 'Using fetch to download "%s" to "%s"\n' "$url" "$output" + fetch "$url" -o "$output" + else + die "no binary found to download $url. exiting." + fi +} + +unarchive() { + local archivetype="$1" + local infile="$2" + local outfile="$3" + local distname="$4" + + if ! check_writeable "$outfile"; then + die "unarchive error: cannot write to $outfile" + fi + + case $archivetype in + tar.gz) + if have_binary tar; then + echo "==> using 'tar' to extract binary from archive" + cat "$infile" | tar -O -z -x "$distname/$distname" > "$outfile" + else + die "no binary on system for extracting tar files" + fi + ;; + zip) + if have_binary unzip; then + echo "==> using 'unzip' to extract binary from archive" + unzip -p "$infile" "$distname/$distname" > "$outfile" + else + die "no installed method for extracting .zip archives" + fi + ;; + *) + die "unrecognized archive type '$archivetype'" + esac + + chmod +x "$outfile" +} + +get_go_vars() { + if [ ! -z "$GOOS" ] && [ ! -z "$GOARCH" ]; then + printf "%s-%s" "$GOOS" "$GOARCH" + fi + + if have_binary go; then + printf "%s-%s" "$(go env GOOS)" "$(go env GOARCH)" + else + die "no way of determining system GOOS and GOARCH\nPlease manually set GOOS and GOARCH then retry." + fi +} + +mkurl() { + local name="$1" + local vers="$2" + local archive="$3" + + local govars=$(get_go_vars) + + echo "http://dist.ipfs.io/$name/$vers/${name}_${vers}_$govars.$archive" +} + +distname="$1" +outpath="$2" +version="$3" + +if [ -z "$distname" ] || [ -z "$outpath" ] || [ -z "$version" ]; then + die "usage: dist_get " +fi + +if [ ${version:0:1} != "v" ]; then + echo "invalid version '$version'" >&2 + die "versions must begin with 'v', for example: v0.4.0" +fi + +# TODO: don't depend on the go tool being installed to detect this +goenv=$(get_go_vars) + +case $goenv in + linux-*) + archive="tar.gz" + ;; + darwin-*) + archive="tar.gz" + ;; + windows-*) + archive="zip" + ;; + freebsd-*) + archive="tar.gz" + ;; + *) + echo "unrecognized system environment: $goenv" >&2 + die "currently only linux, darwin, windows and freebsd are supported by this script" +esac + + +mkdir -p bin/tmp + +url=$(mkurl "$distname" "$version" "$archive") +tmpfi="bin/tmp/$distname.$archive" + +download "$url" "$tmpfi" +if [ $? -ne 0 ]; then + die "failed to download $url to $tmpfi" +fi + +unarchive "$archive" "$tmpfi" "$outpath" "$distname" +if [ $? -ne 0 ]; then + die "failed to exract archive $tmpfi" +fi diff --git a/convert.go b/convert.go index ac857f5..50c6fff 100644 --- a/convert.go +++ b/convert.go @@ -5,7 +5,7 @@ import ( "net" "strings" - ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" + ma "github.com/jbenet/go-multiaddr" utp "github.com/jbenet/go-multiaddr-net/utp" ) diff --git a/convert_test.go b/convert_test.go index f99a8ec..3a00c55 100644 --- a/convert_test.go +++ b/convert_test.go @@ -4,7 +4,7 @@ import ( "net" "testing" - ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" + ma "github.com/jbenet/go-multiaddr" mautp "github.com/jbenet/go-multiaddr-net/utp" ) diff --git a/ip.go b/ip.go index 91b8f0b..f0536d4 100644 --- a/ip.go +++ b/ip.go @@ -3,7 +3,7 @@ package manet import ( "bytes" - ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" + ma "github.com/jbenet/go-multiaddr" ) // Loopback Addresses diff --git a/multiaddr/multiaddr.go b/multiaddr/multiaddr.go index 3b216d7..d72c60c 100644 --- a/multiaddr/multiaddr.go +++ b/multiaddr/multiaddr.go @@ -6,8 +6,8 @@ import ( "fmt" "os" + ma "github.com/jbenet/go-multiaddr" manet "github.com/jbenet/go-multiaddr-net" - ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" ) // flags diff --git a/net.go b/net.go index 5ea5a02..c4233a3 100644 --- a/net.go +++ b/net.go @@ -4,7 +4,7 @@ import ( "fmt" "net" - ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" + ma "github.com/jbenet/go-multiaddr" mautp "github.com/jbenet/go-multiaddr-net/utp" ) diff --git a/net_test.go b/net_test.go index 0e7a37c..4617c6d 100644 --- a/net_test.go +++ b/net_test.go @@ -7,7 +7,7 @@ import ( "sync" "testing" - ma "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" + ma "github.com/jbenet/go-multiaddr" ) func newMultiaddr(t *testing.T, m string) ma.Multiaddr { diff --git a/package.json b/package.json new file mode 100644 index 0000000..4d2d6bf --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "author": "jbenet", + "bugs": { + "url": "https://github.com/jbenet/go-multiaddr-net" + }, + "gx": { + "dvcsimport": "github.com/jbenet/go-multiaddr-net" + }, + "gxDependencies": [ + { + "author": "whyrusleeping", + "hash": "QmaxuoSyFFzKgrujaburn4j3MQWFQu8ASqVSwrMER6Mk9L", + "name": "utp", + "version": "0.0.0" + }, + { + "author": "whyrusleeping", + "hash": "QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz", + "name": "go-multiaddr", + "version": "0.0.0" + } + ], + "gxVersion": "0.6.0", + "language": "go", + "license": "", + "name": "go-multiaddr-net", + "version": "0.0.0" +} \ No newline at end of file diff --git a/utp/utp_util.go b/utp/utp_util.go index e1ce12f..51d30e5 100644 --- a/utp/utp_util.go +++ b/utp/utp_util.go @@ -5,7 +5,7 @@ import ( "net" "time" - utp "github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/utp" + utp "github.com/anacrolix/utp" ) type Listener struct {