diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index ce56dbf78c621f9a58339fb56c9f0c56d5509287..8960a4c949244ab2ab3438d6d1d7c30697e5368c 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,6 +1,6 @@ { "ImportPath": "github.com/jbenet/go-ipfs", - "GoVersion": "go1.3.3", + "GoVersion": "go1.3", "Packages": [ "./..." ], @@ -102,8 +102,8 @@ }, { "ImportPath": "github.com/jbenet/go-multiaddr", - "Comment": "0.1.2-17-g68a2067", - "Rev": "68a20675cb0829da219def0d90afe17a7219e8c7" + "Comment": "0.1.2-27-g62a88e0", + "Rev": "62a88e015e1bf5d6aaca29aec1aba0722f21c8d3" }, { "ImportPath": "github.com/jbenet/go-multihash", diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md index 7ff9854f18f38a9c1da58a59bb288f13ce6117b0..f2545485d1f069ec5ef14ddd629f235a9987315d 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/README.md @@ -34,16 +34,6 @@ addr.Protocols() // } ``` -### Other formats - -```go -// handles the stupid url version too -m = ma.NewUrl("udp4://127.0.0.1:1234") -// <Multiaddr /ip4/127.0.0.1/udp/1234> -m.Url(buf) -// udp4://127.0.0.1:1234 -``` - ### En/decapsulate ```go diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go index a6cf9911ce3cb7e6a6a2a4313a77aa450311444f..d08544b46a521b283c6ba377afc8037f1515f0d5 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/codec.go @@ -67,6 +67,30 @@ func bytesToString(b []byte) (ret string, err error) { return s, nil } +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 { + p := ProtocolWithCode(int(b[0])) + if p == nil { + return [][]byte{}, fmt.Errorf("no protocol with code %d", b[0]) + } + + length := 1 + (p.Size / 8) + ret = append(ret, b[:length]) + b = b[length:] + } + + return ret, nil +} + func addressStringToBytes(p *Protocol, s string) []byte { switch p.Code { diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go index 4ee63ca43bb1949b3d4981dc09f2eb1be1ae21a7..a2bea09addec6365e1be4d52e3652e4555bd7fcb 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr.go @@ -84,10 +84,10 @@ func (m *multiaddr) Encapsulate(o Multiaddr) Multiaddr { mb := m.bytes ob := o.Bytes() - var b bytes.Buffer - b.Write(mb) - b.Write(ob) - return &multiaddr{bytes: b.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. diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr new file mode 100644 index 0000000000000000000000000000000000000000..c54b3bf0834323c47190c49f9700ed855cf49761 Binary files /dev/null and b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr differ diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr.go new file mode 100644 index 0000000000000000000000000000000000000000..441f607a6df4af76675881abc6ca86ac0c3650ff --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr/multiaddr.go @@ -0,0 +1,96 @@ +package main + +import ( + "encoding/hex" + "flag" + "fmt" + "os" + + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" + manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net" +) + +// flags +var formats = []string{"string", "bytes", "hex", "slice"} +var format string +var hideLoopback bool + +func init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "usage: %s [<multiaddr>]\n\nFlags:\n", os.Args[0]) + flag.PrintDefaults() + } + + usage := fmt.Sprintf("output format, one of: %v", formats) + flag.StringVar(&format, "format", "string", usage) + flag.StringVar(&format, "f", "string", usage+" (shorthand)") + flag.BoolVar(&hideLoopback, "hide-loopback", false, "do not display loopback addresses") +} + +func main() { + flag.Parse() + args := flag.Args() + if len(args) == 0 { + output(localAddresses()...) + } else { + output(address(args[0])) + } +} + +func localAddresses() []ma.Multiaddr { + maddrs, err := manet.InterfaceMultiaddrs() + if err != nil { + die(err) + } + + if !hideLoopback { + return maddrs + } + + var maddrs2 []ma.Multiaddr + for _, a := range maddrs { + if !manet.IsIPLoopback(a) { + maddrs2 = append(maddrs2, a) + } + } + + return maddrs2 +} + +func address(addr string) ma.Multiaddr { + m, err := ma.NewMultiaddr(addr) + if err != nil { + die(err) + } + + return m +} + +func output(ms ...ma.Multiaddr) { + for _, m := range ms { + fmt.Println(outfmt(m)) + } +} + +func outfmt(m ma.Multiaddr) string { + switch format { + case "string": + return m.String() + case "slice": + return fmt.Sprintf("%v", m.Bytes()) + case "bytes": + return string(m.Bytes()) + case "hex": + return "0x" + hex.EncodeToString(m.Bytes()) + } + + die("error: invalid format", format) + return "" +} + +func die(v ...interface{}) { + 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-multiaddr/multiaddr_test.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go index 3a7820400d6f862b50ff7f4ff1aa0ed0da660129..a5cb666a08293028b2397098a50f17f99011eb0b 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/multiaddr_test.go @@ -91,6 +91,49 @@ func TestBytesToString(t *testing.T) { testString("/ip4/127.0.0.1/udp/1234", "047f0000011104d2") } +func TestBytesSplitAndJoin(t *testing.T) { + + testString := func(s string, res []string) { + m, err := NewMultiaddr(s) + if err != nil { + t.Error("failed to convert", s) + } + + 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"}) +} + func TestProtocols(t *testing.T) { m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234") if err != nil { diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert.go index d7749d89dfca9baf311a72f061d712a030edbd77..c28159f84f1ee6bc4990a0806269d264d5347a71 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert.go @@ -1,4 +1,4 @@ -package net +package manet import ( "fmt" @@ -62,6 +62,13 @@ func FromNetAddr(a net.Addr) (ma.Multiaddr, error) { } return FromIP(ac.IP) + case "ip+net": + ac, ok := a.(*net.IPNet) + if !ok { + return nil, errIncorrectNetAddr + } + return FromIP(ac.IP) + default: return nil, fmt.Errorf("unknown network %v", a.Network()) } @@ -123,30 +130,3 @@ func DialArgs(m ma.Multiaddr) (string, string, error) { } return network, host, nil } - -// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols. -// This means: /{IP4, IP6}[/{TCP, UDP}] -func IsThinWaist(m ma.Multiaddr) bool { - p := m.Protocols() - - // nothing? not even a waist. - if len(p) == 0 { - return false - } - - if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 { - return false - } - - // only IP? still counts. - if len(p) == 1 { - return true - } - - switch p[1].Code { - case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6: - return true - default: - return false - } -} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert_test.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert_test.go index 7dc8e50a345738d977747c324db366e9d4c81d4a..47b25e7b9078e1006c8530fcf2c8b368649503c2 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert_test.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/convert_test.go @@ -1,4 +1,4 @@ -package net +package manet import ( "net" diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/doc.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/doc.go index d73b8652ff81fdfb0959a462a77fc43a8d688a7b..040ad3f02fa6cd98f7b14d9499e341eee85f9c94 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/doc.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/doc.go @@ -1,5 +1,5 @@ -// Package net provides Multiaddr specific versions of common +// Package manet provides Multiaddr specific versions of common // functions in stdlib's net package. This means wrappers of // standard net symbols like net.Dial and net.Listen, as well // as conversion to/from net.Addr. -package net +package manet diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/ip.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/ip.go new file mode 100644 index 0000000000000000000000000000000000000000..57d2e38d6ee5156dda68734cb9f6b7f29371b7b3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/ip.go @@ -0,0 +1,76 @@ +package manet + +import ( + "bytes" + + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" +) + +// Loopback Addresses +var ( + // IP4Loopback is the ip4 loopback multiaddr + IP4Loopback = ma.StringCast("/ip4/127.0.0.1") + + // IP6Loopback is the ip6 loopback multiaddr + IP6Loopback = ma.StringCast("/ip6/::1") + + // IP6LinkLocalLoopback is the ip6 link-local loopback multiaddr + IP6LinkLocalLoopback = ma.StringCast("/ip6/fe80::1") +) + +// Unspecified Addresses (used for ) +var ( + IP4Unspecified = ma.StringCast("/ip4/0.0.0.0") + IP6Unspecified = ma.StringCast("/ip6/::") +) + +// IsThinWaist returns whether a Multiaddr starts with "Thin Waist" Protocols. +// This means: /{IP4, IP6}[/{TCP, UDP}] +func IsThinWaist(m ma.Multiaddr) bool { + p := m.Protocols() + + // nothing? not even a waist. + if len(p) == 0 { + return false + } + + if p[0].Code != ma.P_IP4 && p[0].Code != ma.P_IP6 { + return false + } + + // only IP? still counts. + if len(p) == 1 { + return true + } + + switch p[1].Code { + case ma.P_TCP, ma.P_UDP, ma.P_IP4, ma.P_IP6: + return true + default: + return false + } +} + +// IsIPLoopback returns whether a Multiaddr is a "Loopback" IP address +// This means either /ip4/127.0.0.1 or /ip6/::1 +func IsIPLoopback(m ma.Multiaddr) bool { + b := m.Bytes() + + // /ip4/127 prefix (_entire_ /8 is loopback...) + if bytes.HasPrefix(b, []byte{4, 127}) { + return true + } + + // /ip6/::1 + if IP6Loopback.Equal(m) || IP6LinkLocalLoopback.Equal(m) { + return true + } + + return false +} + +// IsIPUnspecified returns whether a Multiaddr is am Unspecified IP address +// This means either /ip4/0.0.0.0 or /ip6/:: +func IsIPUnspecified(m ma.Multiaddr) bool { + return IP4Unspecified.Equal(m) || IP6Unspecified.Equal(m) +} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net.go index 3cb41622f61d6ea77e4778899646bfc9868cbd87..a4eb0893870ec9914212afb6185b41945b7116d7 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net.go @@ -1,4 +1,4 @@ -package net +package manet import ( "fmt" @@ -216,3 +216,20 @@ func Listen(laddr ma.Multiaddr) (Listener, error) { laddr: laddr, }, nil } + +// InterfaceMultiaddrs will return the addresses matching net.InterfaceAddrs +func InterfaceMultiaddrs() ([]ma.Multiaddr, error) { + addrs, err := net.InterfaceAddrs() + if err != nil { + return nil, err + } + + maddrs := make([]ma.Multiaddr, len(addrs)) + for i, a := range addrs { + maddrs[i], err = FromNetAddr(a) + if err != nil { + return nil, err + } + } + return maddrs, nil +} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net_test.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net_test.go index 316a57afae1ca713cf63a09d0513a02c357b46af..46fd7aed4fa5b067a4855ce2c50a630bcc4dc452 100644 --- a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net_test.go +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net/net_test.go @@ -1,4 +1,4 @@ -package net +package manet import ( "bytes" @@ -198,3 +198,47 @@ func TestListenAndDial(t *testing.T) { cA.Close() wg.Wait() } + +func TestIPLoopback(t *testing.T) { + if IP4Loopback.String() != "/ip4/127.0.0.1" { + t.Error("IP4Loopback incorrect:", IP4Loopback) + } + + if IP6Loopback.String() != "/ip6/::1" { + t.Error("IP6Loopback incorrect:", IP6Loopback) + } + + if IP6LinkLocalLoopback.String() != "/ip6/fe80::1" { + t.Error("IP6LinkLocalLoopback incorrect:", IP6Loopback) + } + + if !IsIPLoopback(IP4Loopback) { + t.Error("IsIPLoopback failed (IP4Loopback)") + } + + if !IsIPLoopback(IP6Loopback) { + t.Error("IsIPLoopback failed (IP6Loopback)") + } + + if !IsIPLoopback(IP6LinkLocalLoopback) { + t.Error("IsIPLoopback failed (IP6LinkLocalLoopback)") + } +} + +func TestIPUnspecified(t *testing.T) { + if IP4Unspecified.String() != "/ip4/0.0.0.0" { + t.Error("IP4Unspecified incorrect:", IP4Unspecified) + } + + if IP6Unspecified.String() != "/ip6/::" { + t.Error("IP6Unspecified incorrect:", IP6Unspecified) + } + + if !IsIPUnspecified(IP4Unspecified) { + t.Error("IsIPUnspecified failed (IP4Unspecified)") + } + + if !IsIPUnspecified(IP6Unspecified) { + t.Error("IsIPUnspecified failed (IP6Unspecified)") + } +} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go new file mode 100644 index 0000000000000000000000000000000000000000..d1b54afbb6a64260c8c5a154e42d0e9a8d03cd6b --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/util.go @@ -0,0 +1,56 @@ +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 +}