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 {
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
_, 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 {
// 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)
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)
}
}
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
}
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}
}
}
}
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 {