Code to parse socket addresses

This commit is contained in:
Kovid Goyal
2022-08-18 10:11:17 +05:30
parent 417c8887b9
commit a7bc2fcba8
8 changed files with 138 additions and 20 deletions

46
tools/utils/sockets.go Normal file
View File

@@ -0,0 +1,46 @@
package utils
import (
"fmt"
"github.com/seancfoley/ipaddress-go/ipaddr"
"runtime"
"strings"
)
func Cut(s string, sep string) (string, string, bool) {
if i := strings.Index(s, sep); i >= 0 {
return s[:i], s[i+len(sep):], true
}
return s, "", false
}
func ParseSocketAddress(spec string) (network string, addr string, err error) {
network, addr, found := Cut(spec, ":")
if !found {
err = fmt.Errorf("Invalid socket address: %s", spec)
return
}
if network == "unix" {
if strings.HasSuffix(addr, "@") && runtime.GOOS != "linux" {
err = fmt.Errorf("Abstract UNIX sockets are only supported on Linux. Cannot use: %s", spec)
}
return
}
if network == "tcp" || network == "tcp6" || network == "tcp4" {
host := ipaddr.NewHostName(addr)
if host.IsAddress() {
network = "ip"
}
return
}
if network == "ip" || network == "ip6" || network == "ip4" {
host := ipaddr.NewHostName(addr)
if !host.IsAddress() {
err = fmt.Errorf("Not a valid IP address: %#v. Cannot use: %s", addr, spec)
}
return
}
err = fmt.Errorf("Unknown network type: %#v in socket address: %s", network, spec)
return
}

View File

@@ -0,0 +1,57 @@
package utils
import (
"fmt"
"runtime"
"testing"
)
func TestParseSocketAddress(t *testing.T) {
en := "unix"
ea := "/tmp/test"
var eerr error = nil
test := func(spec string) {
n, a, err := ParseSocketAddress(spec)
if err != eerr {
if eerr == nil {
t.Fatalf("Parsing of %s failed with unexpected error: %s", spec, err)
}
if err == nil {
t.Fatalf("Parsing of %s did not fail, unexpectedly", spec)
}
return
}
if a != ea {
t.Fatalf("actual != expected, %s != %s, when parsing %s", a, ea, spec)
}
if n != en {
t.Fatalf("actual != expected, %s != %s, when parsing %s", n, en, spec)
}
}
testf := func(spec string, netw string, addr string) {
eerr = nil
en = netw
ea = addr
test(spec)
}
teste := func(spec string, e string) {
eerr = fmt.Errorf(e)
test(spec)
}
test("unix:/tmp/test")
if runtime.GOOS == "linux" {
ea = "@test"
} else {
eerr = fmt.Errorf("bad kitty")
}
test("unix:@test")
testf("tcp:localhost:123", "tcp", "localhost:123")
testf("tcp:1.1.1.1:123", "ip", "1.1.1.1:123")
testf("tcp:fe80::1", "ip", "fe80::1")
teste("xxx", "bad kitty")
teste("xxx:yyy", "bad kitty")
teste(":yyy", "bad kitty")
}