en/decapsulation

This commit is contained in:
Juan Batiz-Benet 2014-07-04 00:48:33 -07:00
parent e20c5b9d3b
commit 3855a29d4e
4 changed files with 72 additions and 10 deletions

View File

@ -9,7 +9,7 @@
```go
import "github.com/jbenet/go-multiaddr"
m := multiaddr.NewString("/ip4/127.0.0.1/udp/1234")
m := multiaddr.NewMultiaddr("/ip4/127.0.0.1/udp/1234")
// <Multiaddr /ip4/127.0.0.1/udp/1234>
m.buffer
// <Buffer >
@ -45,9 +45,9 @@ m.Url(buf)
### En/decapsulate
```go
m.Encapsulate(m.NewString("/sctp/5678"))
m.Encapsulate(m.NewMultiaddr("/sctp/5678"))
// <Multiaddr /ip4/127.0.0.1/udp/1234/sctp/5678>
m.Decapsulate(m.NewString("/udp")) // up to + inc last occurrence of subaddr
m.Decapsulate(m.NewMultiaddr("/udp")) // up to + inc last occurrence of subaddr
// <Multiaddr /ip4/127.0.0.1>
```
@ -56,11 +56,11 @@ m.Decapsulate(m.NewString("/udp")) // up to + inc last occurrence of subaddr
Multiaddr allows expressing tunnels very nicely.
```js
printer := multiaddr.NewString("/ip4/192.168.0.13/tcp/80")
proxy := multiaddr.NewString("/ip4/10.20.30.40/tcp/443")
printer := multiaddr.NewMultiaddr("/ip4/192.168.0.13/tcp/80")
proxy := multiaddr.NewMultiaddr("/ip4/10.20.30.40/tcp/443")
printerOverProxy := proxy.Encapsulate(printer)
// <Multiaddr /ip4/10.20.30.40/tcp/443/ip4/192.168.0.13/tcp/80>
proxyAgain := printerOverProxy.Decapsulate(multiaddr.NewString("/ip4"))
proxyAgain := printerOverProxy.Decapsulate(multiaddr.NewMultiaddr("/ip4"))
// <Multiaddr /ip4/10.20.30.40/tcp/443>
```

View File

@ -50,7 +50,7 @@ func BytesToString(b []byte) (ret string, err error) {
s = strings.Join([]string{s, "/", p.Name}, "")
b = b[1:]
a := AddressBytesToString(p, b)
a := AddressBytesToString(p, b[:(p.Size / 8)])
if len(a) > 0 {
s = strings.Join([]string{s, "/", a}, "")
}

View File

@ -2,13 +2,14 @@ package multiaddr
import (
"fmt"
"strings"
)
type Multiaddr struct {
Bytes []byte
}
func NewString(s string) (*Multiaddr, error) {
func NewMultiaddr(s string) (*Multiaddr, error) {
b, err := StringToBytes(s)
if err != nil {
return nil, err
@ -42,3 +43,27 @@ func (m *Multiaddr) Protocols() (ret []*Protocol, err error) {
}
return ps, nil
}
func (m *Multiaddr) Encapsulate(o *Multiaddr) *Multiaddr {
b := make([]byte, len(m.Bytes) + len(o.Bytes))
b = append(m.Bytes, o.Bytes...)
return &Multiaddr{Bytes: b}
}
func (m *Multiaddr) Decapsulate(o *Multiaddr) (*Multiaddr, error) {
s1, err := m.String()
if err != nil {
return nil, err
}
s2, err := o.String()
if err != nil {
return nil, err
}
i := strings.LastIndex(s1, s2)
if i < 0 {
return nil, fmt.Errorf("%s not contained in %s", s2, s1)
}
return NewMultiaddr(s1[:i])
}

View File

@ -41,7 +41,7 @@ func TestBytesToString(t *testing.T) {
t.Error("failed to convert", b)
}
if s1 == s2 {
if s1 != s2 {
t.Error("failed to convert", b, "to", s1, "got", s2)
}
}
@ -51,7 +51,7 @@ func TestBytesToString(t *testing.T) {
func TestProtocols(t *testing.T) {
m, err := NewString("/ip4/127.0.0.1/udp/1234")
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")
}
@ -72,3 +72,40 @@ func TestProtocols(t *testing.T) {
}
}
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, err := b.Decapsulate(m3)
if err != nil {
t.Error("decapsulate /udp failed.", err)
}
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, err := c.Decapsulate(m4)
if err != nil {
t.Error("decapsulate /ip4 failed.", err)
}
if s, _ := d.String(); s != "" {
t.Error("decapsulate /ip4 failed.", "/", s)
}
}