]> Cypherpunks repositories - gostls13.git/commitdiff
net: return correct point-to-point interface address on linux
authorMikio Hara <mikioh.mikioh@gmail.com>
Tue, 19 Feb 2013 22:31:44 +0000 (07:31 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Tue, 19 Feb 2013 22:31:44 +0000 (07:31 +0900)
On Linux point-to-point interface an IFA_ADDRESS attribute
represents a peer address. For a correct interface address
we should take an IFA_LOCAL attribute instead.

Fixes #4839.

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/7352045

src/pkg/net/interface_linux.go

index ce2e921e865f696837ed0468c06af3b25e1bbc6e..13a788a003e4048e70e99eb755deacd626f05eb9 100644 (file)
@@ -119,12 +119,16 @@ func addrTable(msgs []syscall.NetlinkMessage, ifindex int) ([]Addr, error) {
                        goto done
                case syscall.RTM_NEWADDR:
                        ifam := (*syscall.IfAddrmsg)(unsafe.Pointer(&m.Data[0]))
+                       ifi, err := InterfaceByIndex(int(ifam.Index))
+                       if err != nil {
+                               return nil, err
+                       }
                        if ifindex == 0 || ifindex == int(ifam.Index) {
                                attrs, err := syscall.ParseNetlinkRouteAttr(&m)
                                if err != nil {
                                        return nil, os.NewSyscallError("netlink routeattr", err)
                                }
-                               ifat = append(ifat, newAddr(attrs, int(ifam.Family), int(ifam.Prefixlen)))
+                               ifat = append(ifat, newAddr(attrs, ifi, ifam))
                        }
                }
        }
@@ -132,19 +136,19 @@ done:
        return ifat, nil
 }
 
-func newAddr(attrs []syscall.NetlinkRouteAttr, family, pfxlen int) Addr {
+func newAddr(attrs []syscall.NetlinkRouteAttr, ifi *Interface, ifam *syscall.IfAddrmsg) Addr {
        ifa := &IPNet{}
        for _, a := range attrs {
-               switch a.Attr.Type {
-               case syscall.IFA_ADDRESS:
-                       switch family {
+               if ifi.Flags&FlagPointToPoint != 0 && a.Attr.Type == syscall.IFA_LOCAL ||
+                       ifi.Flags&FlagPointToPoint == 0 && a.Attr.Type == syscall.IFA_ADDRESS {
+                       switch ifam.Family {
                        case syscall.AF_INET:
                                ifa.IP = IPv4(a.Value[0], a.Value[1], a.Value[2], a.Value[3])
-                               ifa.Mask = CIDRMask(pfxlen, 8*IPv4len)
+                               ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv4len)
                        case syscall.AF_INET6:
                                ifa.IP = make(IP, IPv6len)
                                copy(ifa.IP, a.Value[:])
-                               ifa.Mask = CIDRMask(pfxlen, 8*IPv6len)
+                               ifa.Mask = CIDRMask(int(ifam.Prefixlen), 8*IPv6len)
                        }
                }
        }