mirror of
https://github.com/logos-messaging/go-multiaddr.git
synced 2026-01-02 13:03:11 +00:00
implement varints + add utp, udt
This commit is contained in:
parent
62a88e015e
commit
59f6cfc921
35
codec.go
35
codec.go
@ -28,12 +28,14 @@ func stringToBytes(s string) ([]byte, error) {
|
||||
if p == nil {
|
||||
return nil, fmt.Errorf("no protocol with name %s", sp[0])
|
||||
}
|
||||
b = append(b, byte(p.Code))
|
||||
b = append(b, CodeToVarint(p.Code)...)
|
||||
sp = sp[1:]
|
||||
|
||||
a := addressStringToBytes(p, sp[1])
|
||||
b = append(b, a...)
|
||||
|
||||
sp = sp[2:]
|
||||
if p.Size > 0 {
|
||||
a := addressStringToBytes(p, sp[0])
|
||||
b = append(b, a...)
|
||||
sp = sp[1:]
|
||||
}
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
@ -50,18 +52,22 @@ func bytesToString(b []byte) (ret string, err error) {
|
||||
s := ""
|
||||
|
||||
for len(b) > 0 {
|
||||
p := ProtocolWithCode(int(b[0]))
|
||||
|
||||
code, n := ReadVarintCode(b)
|
||||
b = b[n:]
|
||||
p := ProtocolWithCode(code)
|
||||
if p == nil {
|
||||
return "", fmt.Errorf("no protocol with code %d", b[0])
|
||||
return "", fmt.Errorf("no protocol with code %d", code)
|
||||
}
|
||||
s = strings.Join([]string{s, "/", p.Name}, "")
|
||||
b = b[1:]
|
||||
|
||||
a := addressBytesToString(p, b[:(p.Size/8)])
|
||||
if len(a) > 0 {
|
||||
s = strings.Join([]string{s, "/", a}, "")
|
||||
if p.Size > 0 {
|
||||
a := addressBytesToString(p, b[:(p.Size/8)])
|
||||
if len(a) > 0 {
|
||||
s = strings.Join([]string{s, "/", a}, "")
|
||||
}
|
||||
b = b[(p.Size / 8):]
|
||||
}
|
||||
b = b[(p.Size / 8):]
|
||||
}
|
||||
|
||||
return s, nil
|
||||
@ -78,12 +84,13 @@ func bytesSplit(b []byte) (ret [][]byte, err error) {
|
||||
|
||||
ret = [][]byte{}
|
||||
for len(b) > 0 {
|
||||
p := ProtocolWithCode(int(b[0]))
|
||||
code, n := ReadVarintCode(b)
|
||||
p := ProtocolWithCode(code)
|
||||
if p == nil {
|
||||
return [][]byte{}, fmt.Errorf("no protocol with code %d", b[0])
|
||||
}
|
||||
|
||||
length := 1 + (p.Size / 8)
|
||||
length := n + (p.Size / 8)
|
||||
ret = append(ret, b[:length])
|
||||
b = b[length:]
|
||||
}
|
||||
|
||||
@ -67,14 +67,15 @@ func (m *multiaddr) Protocols() []*Protocol {
|
||||
ps := []*Protocol{}
|
||||
b := m.bytes[:]
|
||||
for len(b) > 0 {
|
||||
p := ProtocolWithCode(int(b[0]))
|
||||
code, n := ReadVarintCode(b)
|
||||
p := ProtocolWithCode(code)
|
||||
if p == nil {
|
||||
// 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[1+(p.Size/8):]
|
||||
b = b[n+(p.Size/8):]
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
@ -68,6 +68,8 @@ func TestStringToBytes(t *testing.T) {
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -89,6 +91,8 @@ func TestBytesToString(t *testing.T) {
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -96,7 +100,7 @@ func TestBytesSplitAndJoin(t *testing.T) {
|
||||
testString := func(s string, res []string) {
|
||||
m, err := NewMultiaddr(s)
|
||||
if err != nil {
|
||||
t.Error("failed to convert", s)
|
||||
t.Fatal("failed to convert", s, err)
|
||||
}
|
||||
|
||||
split := Split(m)
|
||||
@ -132,6 +136,8 @@ func TestBytesSplitAndJoin(t *testing.T) {
|
||||
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) {
|
||||
|
||||
@ -5,5 +5,7 @@ code size name
|
||||
33 16 dccp
|
||||
41 128 ip6
|
||||
132 16 sctp
|
||||
301 0 udt
|
||||
302 0 utp
|
||||
480 0 http
|
||||
443 0 https
|
||||
|
||||
|
50
protocols.go
50
protocols.go
@ -1,10 +1,15 @@
|
||||
package multiaddr
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// Protocol is a Multiaddr protocol description structure.
|
||||
type Protocol struct {
|
||||
Code int
|
||||
Size int
|
||||
Name string
|
||||
Code int
|
||||
Size int
|
||||
Name string
|
||||
VCode []byte
|
||||
}
|
||||
|
||||
// replicating table here to:
|
||||
@ -18,17 +23,21 @@ const (
|
||||
P_DCCP = 33
|
||||
P_IP6 = 41
|
||||
P_SCTP = 132
|
||||
P_UTP = 301
|
||||
P_UDT = 302
|
||||
)
|
||||
|
||||
// Protocols is the list of multiaddr protocols supported by this module.
|
||||
var Protocols = []*Protocol{
|
||||
&Protocol{P_IP4, 32, "ip4"},
|
||||
&Protocol{P_TCP, 16, "tcp"},
|
||||
&Protocol{P_UDP, 16, "udp"},
|
||||
&Protocol{P_DCCP, 16, "dccp"},
|
||||
&Protocol{P_IP6, 128, "ip6"},
|
||||
&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"},
|
||||
&Protocol{P_SCTP, 16, "sctp", CodeToVarint(P_SCTP)},
|
||||
&Protocol{P_UTP, 0, "utp", CodeToVarint(P_UTP)},
|
||||
&Protocol{P_UDT, 0, "udt", CodeToVarint(P_UDT)},
|
||||
// {480, 0, "http"},
|
||||
// {443, 0, "https"},
|
||||
}
|
||||
@ -52,3 +61,26 @@ func ProtocolWithCode(c int) *Protocol {
|
||||
}
|
||||
return 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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user