diff --git a/index.go b/index.go index 994693b..413a971 100644 --- a/index.go +++ b/index.go @@ -67,3 +67,36 @@ func (m *Multiaddr) Decapsulate(o *Multiaddr) (*Multiaddr, error) { } return NewMultiaddr(s1[:i]) } + +func (m *Multiaddr) DialArgs() (string, string, error) { + if !m.IsThinWaist() { + return "", "", fmt.Errorf("%s is not a 'thin waist' address.", m) + } + + str, err := m.String() + if err != nil { + return "", "", err + } + + parts := strings.Split(str, "/")[1:] + network := parts[2] + host := strings.Join([]string{parts[1], parts[3]}, ":") + return network, host, nil +} + +func (m *Multiaddr) IsThinWaist() bool { + p, err := m.Protocols() + if err != nil { + return false + } + + if p[0].Code != P_IP4 && p[0].Code != P_IP6 { + return false + } + + if p[1].Code != P_TCP && p[1].Code != P_UDP { + return false + } + + return true +} diff --git a/multiaddr_test.go b/multiaddr_test.go index df9a3fe..976e095 100644 --- a/multiaddr_test.go +++ b/multiaddr_test.go @@ -107,3 +107,23 @@ func TestEncapsulate(t *testing.T) { t.Error("decapsulate /ip4 failed.", "/", s) } } + +func TestDialArgs(t *testing.T) { + m, err := NewMultiaddr("/ip4/127.0.0.1/udp/1234") + if err != nil { + t.Fatal("failed to construct", "/ip4/127.0.0.1/udp/1234") + } + + nw, host, err := m.DialArgs() + if err != nil { + t.Fatal("failed to get dial args", "/ip4/127.0.0.1/udp/1234", err) + } + + if nw != "udp" { + t.Error("failed to get udp network Dial Arg") + } + + if host != "127.0.0.1:1234" { + t.Error("failed to get host:port Dial Arg") + } +} diff --git a/protocols.go b/protocols.go index 65052e8..e08d01f 100644 --- a/protocols.go +++ b/protocols.go @@ -11,14 +11,23 @@ type Protocol struct { // 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 +) + var Protocols = []*Protocol{ - &Protocol{4, 32, "ip4"}, - &Protocol{6, 16, "tcp"}, - &Protocol{17, 16, "udp"}, - &Protocol{33, 16, "dccp"}, - &Protocol{41, 128, "ip6"}, + &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"}, // these require varint: - &Protocol{132, 16, "sctp"}, + &Protocol{P_SCTP, 16, "sctp"}, // {480, 0, "http"}, // {443, 0, "https"}, }