mirror of
https://github.com/golang/go
synced 2024-11-18 09:04:49 -07:00
net: fix multicast and IPv6 related issues on Plan 9
Fix issues that make these tests pass: - TestDialerLocalAddr: return error if local address is not IPv4 for "tcp4" network. - TestInterfaceAddrs, TestInterfaceUnicastAddrs: don't assume each interface has only one address. It may have more than one or none. - TestConcurrentPreferGoResolversDial: should be skipped on Plan 9. - TestListenMulticastUDP: remove IP from `announce` command and don't mix IPv4 address with IPv6 address in `addmulti` command. Fixes #34931 Change-Id: Ie0fdfe19ea282e5d6d6c938bf3c9139f8f5b0308 Reviewed-on: https://go-review.googlesource.com/c/go/+/201397 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
f6c624a22a
commit
e94475eab1
@ -143,8 +143,8 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
|
||||
ifcs = []Interface{*ifi}
|
||||
}
|
||||
|
||||
addrs := make([]Addr, len(ifcs))
|
||||
for i, ifc := range ifcs {
|
||||
var addrs []Addr
|
||||
for _, ifc := range ifcs {
|
||||
status := ifc.Name + "/status"
|
||||
statusf, err := open(status)
|
||||
if err != nil {
|
||||
@ -157,39 +157,36 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
|
||||
if _, ok := statusf.readLine(); !ok {
|
||||
return nil, errors.New("cannot read header line for interface: " + status)
|
||||
}
|
||||
line, ok := statusf.readLine()
|
||||
if !ok {
|
||||
return nil, errors.New("cannot read IP address for interface: " + status)
|
||||
}
|
||||
|
||||
// This assumes only a single address for the interface.
|
||||
fields := getFields(line)
|
||||
if len(fields) < 1 {
|
||||
return nil, errors.New("cannot parse IP address for interface: " + status)
|
||||
}
|
||||
addr := fields[0]
|
||||
ip := ParseIP(addr)
|
||||
if ip == nil {
|
||||
return nil, errors.New("cannot parse IP address for interface: " + status)
|
||||
}
|
||||
for line, ok := statusf.readLine(); ok; line, ok = statusf.readLine() {
|
||||
fields := getFields(line)
|
||||
if len(fields) < 1 {
|
||||
return nil, errors.New("cannot parse IP address for interface: " + status)
|
||||
}
|
||||
addr := fields[0]
|
||||
ip := ParseIP(addr)
|
||||
if ip == nil {
|
||||
return nil, errors.New("cannot parse IP address for interface: " + status)
|
||||
}
|
||||
|
||||
// The mask is represented as CIDR relative to the IPv6 address.
|
||||
// Plan 9 internal representation is always IPv6.
|
||||
maskfld := fields[1]
|
||||
maskfld = maskfld[1:]
|
||||
pfxlen, _, ok := dtoi(maskfld)
|
||||
if !ok {
|
||||
return nil, errors.New("cannot parse network mask for interface: " + status)
|
||||
}
|
||||
var mask IPMask
|
||||
if ip.To4() != nil { // IPv4 or IPv6 IPv4-mapped address
|
||||
mask = CIDRMask(pfxlen-8*len(v4InV6Prefix), 8*IPv4len)
|
||||
}
|
||||
if ip.To16() != nil && ip.To4() == nil { // IPv6 address
|
||||
mask = CIDRMask(pfxlen, 8*IPv6len)
|
||||
}
|
||||
// The mask is represented as CIDR relative to the IPv6 address.
|
||||
// Plan 9 internal representation is always IPv6.
|
||||
maskfld := fields[1]
|
||||
maskfld = maskfld[1:]
|
||||
pfxlen, _, ok := dtoi(maskfld)
|
||||
if !ok {
|
||||
return nil, errors.New("cannot parse network mask for interface: " + status)
|
||||
}
|
||||
var mask IPMask
|
||||
if ip.To4() != nil { // IPv4 or IPv6 IPv4-mapped address
|
||||
mask = CIDRMask(pfxlen-8*len(v4InV6Prefix), 8*IPv4len)
|
||||
}
|
||||
if ip.To16() != nil && ip.To4() == nil { // IPv6 address
|
||||
mask = CIDRMask(pfxlen, 8*IPv6len)
|
||||
}
|
||||
|
||||
addrs[i] = &IPNet{IP: ip, Mask: mask}
|
||||
addrs = append(addrs, &IPNet{IP: ip, Mask: mask})
|
||||
}
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
|
@ -227,7 +227,7 @@ func listenPlan9(ctx context.Context, net string, laddr Addr) (fd *netFD, err er
|
||||
_, err = f.WriteString("announce " + dest)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return nil, err
|
||||
return nil, &OpError{Op: "announce", Net: net, Source: laddr, Addr: nil, Err: err}
|
||||
}
|
||||
laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
|
||||
if err != nil {
|
||||
|
@ -972,10 +972,11 @@ func (lcr *lookupCustomResolver) dial() func(ctx context.Context, network, addre
|
||||
// TestConcurrentPreferGoResolversDial tests that multiple resolvers with the
|
||||
// PreferGo option used concurrently are all dialed properly.
|
||||
func TestConcurrentPreferGoResolversDial(t *testing.T) {
|
||||
// The windows implementation of the resolver does not use the Dial
|
||||
// function.
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skip on windows")
|
||||
// The windows and plan9 implementation of the resolver does not use
|
||||
// the Dial function.
|
||||
switch runtime.GOOS {
|
||||
case "windows", "plan9":
|
||||
t.Skipf("skip on %v", runtime.GOOS)
|
||||
}
|
||||
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
|
@ -23,7 +23,12 @@ func (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPCo
|
||||
|
||||
func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
|
||||
switch sd.network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
case "tcp4":
|
||||
// Plan 9 doesn't complain about [::]:0->127.0.0.1, so it's up to us.
|
||||
if laddr != nil && len(laddr.IP) != 0 && laddr.IP.To4() == nil {
|
||||
return nil, &AddrError{Err: "non-IPv4 local address", Addr: laddr.String()}
|
||||
}
|
||||
case "tcp", "tcp6":
|
||||
default:
|
||||
return nil, UnknownNetworkError(sd.network)
|
||||
}
|
||||
|
@ -109,7 +109,9 @@ func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn,
|
||||
}
|
||||
|
||||
func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
|
||||
l, err := listenPlan9(ctx, sl.network, gaddr)
|
||||
// Plan 9 does not like announce command with a multicast address,
|
||||
// so do not specify an IP address when listening.
|
||||
l, err := listenPlan9(ctx, sl.network, &UDPAddr{IP: nil, Port: gaddr.Port, Zone: gaddr.Zone})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -129,11 +131,13 @@ func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, g
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
have4 := gaddr.IP.To4() != nil
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*IPNet); ok {
|
||||
if ipnet, ok := addr.(*IPNet); ok && (ipnet.IP.To4() != nil) == have4 {
|
||||
_, err = l.ctl.WriteString("addmulti " + ipnet.IP.String() + " " + gaddr.IP.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, &OpError{Op: "addmulti", Net: "", Source: nil, Addr: ipnet, Err: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func TestListenMulticastUDP(t *testing.T) {
|
||||
|
||||
c1, err := ListenMulticastUDP("udp4", mifc, &UDPAddr{IP: ParseIP("224.0.0.254")})
|
||||
if err != nil {
|
||||
t.Fatalf("multicast not working on %s", runtime.GOOS)
|
||||
t.Fatalf("multicast not working on %s: %v", runtime.GOOS, err)
|
||||
}
|
||||
c1addr := c1.LocalAddr().(*UDPAddr)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user