{"tcp", "no-such-name:80"},
{"tcp", "mh/astro/r70:http"},
- {"tcp", "127.0.0.1:0"},
- {"udp", "127.0.0.1:0"},
+ {"tcp", JoinHostPort("127.0.0.1", "-1")},
+ {"tcp", JoinHostPort("127.0.0.1", "123456789")},
+ {"udp", JoinHostPort("127.0.0.1", "-1")},
+ {"udp", JoinHostPort("127.0.0.1", "123456789")},
{"ip:icmp", "127.0.0.1"},
{"unix", "/path/to/somewhere"},
for i, tt := range dialErrorTests {
c, err := d.Dial(tt.network, tt.address)
if err == nil {
- t.Errorf("#%d: should fail; %s:%s->%s", i, tt.network, c.LocalAddr(), c.RemoteAddr())
+ t.Errorf("#%d: should fail; %s:%s->%s", i, c.LocalAddr().Network(), c.LocalAddr(), c.RemoteAddr())
c.Close()
continue
}
+ if tt.network == "tcp" || tt.network == "udp" {
+ nerr := err
+ if op, ok := nerr.(*OpError); ok {
+ nerr = op.Err
+ }
+ if sys, ok := nerr.(*os.SyscallError); ok {
+ nerr = sys.Err
+ }
+ if nerr == errOpNotSupported {
+ t.Errorf("#%d: should fail without %v; %s:%s->", i, nerr, tt.network, tt.address)
+ continue
+ }
+ }
if c != nil {
t.Errorf("Dial returned non-nil interface %T(%v) with err != nil", c, c)
}
{"tcp", "no-such-name:80"},
{"tcp", "mh/astro/r70:http"},
- {"tcp", "127.0.0.1:0"},
+ {"tcp", JoinHostPort("127.0.0.1", "-1")},
+ {"tcp", JoinHostPort("127.0.0.1", "123456789")},
{"unix", "/path/to/somewhere"},
{"unixpacket", "/path/to/somewhere"},
for i, tt := range listenErrorTests {
ln, err := Listen(tt.network, tt.address)
if err == nil {
- t.Errorf("#%d: should fail; %s:%s->", i, tt.network, ln.Addr())
+ t.Errorf("#%d: should fail; %s:%s->", i, ln.Addr().Network(), ln.Addr())
ln.Close()
continue
}
+ if tt.network == "tcp" {
+ nerr := err
+ if op, ok := nerr.(*OpError); ok {
+ nerr = op.Err
+ }
+ if sys, ok := nerr.(*os.SyscallError); ok {
+ nerr = sys.Err
+ }
+ if nerr == errOpNotSupported {
+ t.Errorf("#%d: should fail without %v; %s:%s->", i, nerr, tt.network, tt.address)
+ continue
+ }
+ }
if ln != nil {
t.Errorf("Listen returned non-nil interface %T(%v) with err != nil", ln, ln)
}
{"udp", "127.0.0.1:☺"},
{"udp", "no-such-name:80"},
{"udp", "mh/astro/r70:http"},
+
+ {"udp", JoinHostPort("127.0.0.1", "-1")},
+ {"udp", JoinHostPort("127.0.0.1", "123456789")},
}
func TestListenPacketError(t *testing.T) {
for i, tt := range listenPacketErrorTests {
c, err := ListenPacket(tt.network, tt.address)
if err == nil {
- t.Errorf("#%d: should fail; %s:%s->", i, tt.network, c.LocalAddr())
+ t.Errorf("#%d: should fail; %s:%s->", i, c.LocalAddr().Network(), c.LocalAddr())
c.Close()
continue
}
if host, port, err = SplitHostPort(addr); err != nil {
return nil, err
}
- if portnum, err = parsePort(net, port); err != nil {
+ if portnum, err = LookupPort(net, port); err != nil {
return nil, err
}
}
// LookupPort looks up the port for the given network and service.
func LookupPort(network, service string) (port int, err error) {
- if n, i, ok := dtoi(service, 0); ok && i == len(service) {
- return n, nil
+ port, _, ok := dtoi(service, 0)
+ if !ok && port != big && port != -big {
+ port, err = lookupPort(network, service)
+ if err != nil {
+ return 0, err
+ }
}
- return lookupPort(network, service)
+ if 0 > port || port > 65535 {
+ return 0, &AddrError{Err: "invalid port", Addr: service}
+ }
+ return port, nil
}
// LookupCNAME returns the canonical DNS host for the given name.
// Returns number, new offset, success.
func dtoi(s string, i0 int) (n int, i int, ok bool) {
n = 0
+ neg := false
+ if len(s) > 0 && s[0] == '-' {
+ neg = true
+ s = s[1:]
+ }
for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
n = n*10 + int(s[i]-'0')
if n >= big {
- return 0, i, false
+ if neg {
+ return -big, i + 1, false
+ }
+ return big, i, false
}
}
if i == i0 {
return 0, i, false
}
+ if neg {
+ n = -n
+ i++
+ }
return n, i, true
}
}
}
}
+
+func TestDtoi(t *testing.T) {
+ for _, tt := range []struct {
+ in string
+ out int
+ off int
+ ok bool
+ }{
+ {"", 0, 0, false},
+
+ {"-123456789", -big, 9, false},
+ {"-1", -1, 2, true},
+ {"0", 0, 1, true},
+ {"65536", 65536, 5, true},
+ {"123456789", big, 8, false},
+ } {
+ n, i, ok := dtoi(tt.in, 0)
+ if n != tt.out || i != tt.off || ok != tt.ok {
+ t.Errorf("got %d, %d, %v; want %d, %d, %v", n, i, ok, tt.out, tt.off, tt.ok)
+ }
+ }
+}
+++ /dev/null
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Network service port manipulations
-
-package net
-
-// parsePort parses port as a network service port number for both
-// TCP and UDP.
-func parsePort(net, port string) (int, error) {
- p, i, ok := dtoi(port, 0)
- if !ok || i != len(port) {
- var err error
- p, err = LookupPort(net, port)
- if err != nil {
- return 0, err
- }
- }
- if p < 0 || p > 0xFFFF {
- return 0, &AddrError{Err: "invalid port", Addr: port}
- }
- return p, nil
-}
"testing"
)
-var portTests = []struct {
+var lookupPortTests = []struct {
network string
name string
port int
ok bool
}{
+ {"tcp", "0", 0, true},
{"tcp", "echo", 7, true},
{"tcp", "discard", 9, true},
{"tcp", "systat", 11, true},
{"tcp", "finger", 79, true},
{"tcp", "42", 42, true},
+ {"udp", "0", 0, true},
{"udp", "echo", 7, true},
{"udp", "tftp", 69, true},
{"udp", "bootpc", 68, true},
{"--badnet--", "zzz", 0, false},
{"tcp", "--badport--", 0, false},
+ {"tcp", "-1", 0, false},
+ {"tcp", "65536", 0, false},
+ {"udp", "-1", 0, false},
+ {"udp", "65536", 0, false},
}
func TestLookupPort(t *testing.T) {
t.Skipf("not supported on %s", runtime.GOOS)
}
- for _, tt := range portTests {
+ for _, tt := range lookupPortTests {
if port, err := LookupPort(tt.network, tt.name); port != tt.port || (err == nil) != tt.ok {
- t.Errorf("LookupPort(%q, %q) = %v, %v; want %v", tt.network, tt.name, port, err, tt.port)
+ t.Errorf("LookupPort(%q, %q) = %d, %v; want %d", tt.network, tt.name, port, err, tt.port)
}
}
}