diff options
author | Ian Lance Taylor <iant@google.com> | 2016-02-03 21:58:02 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-02-03 21:58:02 +0000 |
commit | f98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch) | |
tree | 2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/net/addrselect.go | |
parent | b081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff) | |
download | gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.zip gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.gz gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.bz2 |
libgo: Update to go1.6rc1.
Reviewed-on: https://go-review.googlesource.com/19200
From-SVN: r233110
Diffstat (limited to 'libgo/go/net/addrselect.go')
-rw-r--r-- | libgo/go/net/addrselect.go | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/libgo/go/net/addrselect.go b/libgo/go/net/addrselect.go index e22fbac..58ab7d7 100644 --- a/libgo/go/net/addrselect.go +++ b/libgo/go/net/addrselect.go @@ -197,6 +197,24 @@ func (s *byRFC6724) Less(i, j int) bool { if da4 == db4 { commonA := commonPrefixLen(SourceDA, DA) commonB := commonPrefixLen(SourceDB, DB) + + // CommonPrefixLen doesn't really make sense for IPv4, and even + // causes problems for common load balancing practices + // (e.g., https://golang.org/issue/13283). Glibc instead only + // uses CommonPrefixLen for IPv4 when the source and destination + // addresses are on the same subnet, but that requires extra + // work to find the netmask for our source addresses. As a + // simpler heuristic, we limit its use to when the source and + // destination belong to the same special purpose block. + if da4 { + if !sameIPv4SpecialPurposeBlock(SourceDA, DA) { + commonA = 0 + } + if !sameIPv4SpecialPurposeBlock(SourceDB, DB) { + commonB = 0 + } + } + if commonA > commonB { return preferDA } @@ -386,3 +404,28 @@ func commonPrefixLen(a, b IP) (cpl int) { } return } + +// sameIPv4SpecialPurposeBlock reports whether a and b belong to the same +// address block reserved by the IANA IPv4 Special-Purpose Address Registry: +// http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +func sameIPv4SpecialPurposeBlock(a, b IP) bool { + a, b = a.To4(), b.To4() + if a == nil || b == nil || a[0] != b[0] { + return false + } + // IANA defines more special-purpose blocks, but these are the only + // ones likely to be relevant to typical Go systems. + switch a[0] { + case 10: // 10.0.0.0/8: Private-Use + return true + case 127: // 127.0.0.0/8: Loopback + return true + case 169: // 169.254.0.0/16: Link Local + return a[1] == 254 && b[1] == 254 + case 172: // 172.16.0.0/12: Private-Use + return a[1]&0xf0 == 16 && b[1]&0xf0 == 16 + case 192: // 192.168.0.0/16: Private-Use + return a[1] == 168 && b[1] == 168 + } + return false +} |