mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
net: filter destination addresses when source address is specified
This change filters out destination addresses by address family when source address is specified to avoid running Dial operation with wrong addressing scopes. Fixes #11837. Change-Id: I10b7a1fa325add2cd8ed58f105d527700a10d342 Reviewed-on: https://go-review.googlesource.com/20586 Reviewed-by: Paul Marks <pmarks@google.com>
This commit is contained in:
parent
76b724cc63
commit
790053b25e
6 changed files with 176 additions and 48 deletions
|
|
@ -646,41 +646,118 @@ func TestDialerPartialDeadline(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
type dialerLocalAddrTest struct {
|
||||
network, raddr string
|
||||
laddr Addr
|
||||
error
|
||||
}
|
||||
|
||||
var dialerLocalAddrTests = []dialerLocalAddrTest{
|
||||
{"tcp4", "127.0.0.1", nil, nil},
|
||||
{"tcp4", "127.0.0.1", &TCPAddr{}, nil},
|
||||
{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
|
||||
{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
|
||||
{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, &AddrError{Err: "some error"}},
|
||||
{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, nil},
|
||||
{"tcp4", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, nil},
|
||||
{"tcp4", "127.0.0.1", &TCPAddr{IP: IPv6loopback}, errNoSuitableAddress},
|
||||
{"tcp4", "127.0.0.1", &UDPAddr{}, &AddrError{Err: "some error"}},
|
||||
{"tcp4", "127.0.0.1", &UnixAddr{}, &AddrError{Err: "some error"}},
|
||||
|
||||
{"tcp6", "::1", nil, nil},
|
||||
{"tcp6", "::1", &TCPAddr{}, nil},
|
||||
{"tcp6", "::1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
|
||||
{"tcp6", "::1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
|
||||
{"tcp6", "::1", &TCPAddr{IP: ParseIP("::")}, nil},
|
||||
{"tcp6", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, errNoSuitableAddress},
|
||||
{"tcp6", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, errNoSuitableAddress},
|
||||
{"tcp6", "::1", &TCPAddr{IP: IPv6loopback}, nil},
|
||||
{"tcp6", "::1", &UDPAddr{}, &AddrError{Err: "some error"}},
|
||||
{"tcp6", "::1", &UnixAddr{}, &AddrError{Err: "some error"}},
|
||||
|
||||
{"tcp", "127.0.0.1", nil, nil},
|
||||
{"tcp", "127.0.0.1", &TCPAddr{}, nil},
|
||||
{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
|
||||
{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
|
||||
{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, nil},
|
||||
{"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, nil},
|
||||
{"tcp", "127.0.0.1", &TCPAddr{IP: IPv6loopback}, errNoSuitableAddress},
|
||||
{"tcp", "127.0.0.1", &UDPAddr{}, &AddrError{Err: "some error"}},
|
||||
{"tcp", "127.0.0.1", &UnixAddr{}, &AddrError{Err: "some error"}},
|
||||
|
||||
{"tcp", "::1", nil, nil},
|
||||
{"tcp", "::1", &TCPAddr{}, nil},
|
||||
{"tcp", "::1", &TCPAddr{IP: ParseIP("0.0.0.0")}, nil},
|
||||
{"tcp", "::1", &TCPAddr{IP: ParseIP("0.0.0.0").To4()}, nil},
|
||||
{"tcp", "::1", &TCPAddr{IP: ParseIP("::")}, nil},
|
||||
{"tcp", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To4()}, errNoSuitableAddress},
|
||||
{"tcp", "::1", &TCPAddr{IP: ParseIP("127.0.0.1").To16()}, errNoSuitableAddress},
|
||||
{"tcp", "::1", &TCPAddr{IP: IPv6loopback}, nil},
|
||||
{"tcp", "::1", &UDPAddr{}, &AddrError{Err: "some error"}},
|
||||
{"tcp", "::1", &UnixAddr{}, &AddrError{Err: "some error"}},
|
||||
}
|
||||
|
||||
func TestDialerLocalAddr(t *testing.T) {
|
||||
ch := make(chan error, 1)
|
||||
handler := func(ls *localServer, ln Listener) {
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
ch <- nil
|
||||
}
|
||||
ls, err := newLocalServer("tcp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ls.teardown()
|
||||
if err := ls.buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
if !supportsIPv4 || !supportsIPv6 {
|
||||
t.Skip("both IPv4 and IPv6 are required")
|
||||
}
|
||||
|
||||
laddr, err := ResolveTCPAddr(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
if supportsIPv4map {
|
||||
dialerLocalAddrTests = append(dialerLocalAddrTests, dialerLocalAddrTest{
|
||||
"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, nil,
|
||||
})
|
||||
} else {
|
||||
dialerLocalAddrTests = append(dialerLocalAddrTests, dialerLocalAddrTest{
|
||||
"tcp", "127.0.0.1", &TCPAddr{IP: ParseIP("::")}, &AddrError{Err: "some error"},
|
||||
})
|
||||
}
|
||||
laddr.Port = 0
|
||||
d := &Dialer{LocalAddr: laddr}
|
||||
c, err := d.Dial(ls.Listener.Addr().Network(), ls.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
origTestHookLookupIP := testHookLookupIP
|
||||
defer func() { testHookLookupIP = origTestHookLookupIP }()
|
||||
testHookLookupIP = lookupLocalhost
|
||||
handler := func(ls *localServer, ln Listener) {
|
||||
for {
|
||||
c, err := ln.Accept()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
}
|
||||
defer c.Close()
|
||||
c.Read(make([]byte, 1))
|
||||
err = <-ch
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
var err error
|
||||
var lss [2]*localServer
|
||||
for i, network := range []string{"tcp4", "tcp6"} {
|
||||
lss[i], err = newLocalServer(network)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer lss[i].teardown()
|
||||
if err := lss[i].buildup(handler); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, tt := range dialerLocalAddrTests {
|
||||
d := &Dialer{LocalAddr: tt.laddr}
|
||||
var addr string
|
||||
ip := ParseIP(tt.raddr)
|
||||
if ip.To4() != nil {
|
||||
addr = lss[0].Listener.Addr().String()
|
||||
}
|
||||
if ip.To16() != nil && ip.To4() == nil {
|
||||
addr = lss[1].Listener.Addr().String()
|
||||
}
|
||||
c, err := d.Dial(tt.network, addr)
|
||||
if err == nil && tt.error != nil || err != nil && tt.error == nil {
|
||||
t.Errorf("%s %v->%s: got %v; want %v", tt.network, tt.laddr, tt.raddr, err, tt.error)
|
||||
}
|
||||
if err != nil {
|
||||
if perr := parseDialError(err); perr != nil {
|
||||
t.Error(perr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue