Source File
addrselect.go
Belonging Package
net
package net
import
func ( []IPAddr) {
if len() < 2 {
return
}
sortByRFC6724withSrcs(, srcAddrs())
}
func ( []IPAddr, []IP) {
if len() != len() {
panic("internal error")
}
:= make([]ipAttr, len())
:= make([]ipAttr, len())
for , := range {
[] = ipAttrOf(.IP)
[] = ipAttrOf([])
}
sort.Stable(&byRFC6724{
addrs: ,
addrAttr: ,
srcs: ,
srcAttr: ,
})
}
func ( []IPAddr) []IP {
:= make([]IP, len())
:= UDPAddr{Port: 9}
for := range {
.IP = [].IP
.Zone = [].Zone
, := DialUDP("udp", nil, &)
if == nil {
if , := .LocalAddr().(*UDPAddr); {
[] = .IP
}
.Close()
}
}
return
}
type ipAttr struct {
Scope scope
Precedence uint8
Label uint8
}
func ( IP) ipAttr {
if == nil {
return ipAttr{}
}
:= rfc6724policyTable.Classify()
return ipAttr{
Scope: classifyScope(),
Precedence: .Precedence,
Label: .Label,
}
}
type byRFC6724 struct {
addrs []IPAddr // addrs to sort
addrAttr []ipAttr
srcs []IP // or nil if unreachable
srcAttr []ipAttr
}
func ( *byRFC6724) () int { return len(.addrs) }
func ( *byRFC6724) (, int) {
.addrs[], .addrs[] = .addrs[], .addrs[]
.srcs[], .srcs[] = .srcs[], .srcs[]
.addrAttr[], .addrAttr[] = .addrAttr[], .addrAttr[]
.srcAttr[], .srcAttr[] = .srcAttr[], .srcAttr[]
}
if .Precedence > .Precedence {
return
}
if .Precedence < .Precedence {
return
}
if .To4() == nil && .To4() == nil {
:= commonPrefixLen(, )
:= commonPrefixLen(, )
if > {
return
}
if < {
return
}
}
return false // "equal"
}
type policyTableEntry struct {
Prefix *IPNet
Precedence uint8
Label uint8
}
type policyTable []policyTableEntry
var rfc6724policyTable = policyTable{
{
Prefix: mustCIDR("::1/128"),
Precedence: 50,
Label: 0,
},
{
Prefix: mustCIDR("::/0"),
Precedence: 40,
Label: 1,
},
Prefix: mustCIDR("::ffff:0:0/96"),
Precedence: 35,
Label: 4,
},
Prefix: mustCIDR("2002::/16"),
Precedence: 30,
Label: 2,
},
Prefix: mustCIDR("2001::/32"),
Precedence: 5,
Label: 5,
},
{
Prefix: mustCIDR("fc00::/7"),
Precedence: 3,
Label: 13,
},
{
Prefix: mustCIDR("::/96"),
Precedence: 1,
Label: 3,
},
{
Prefix: mustCIDR("fec0::/10"),
Precedence: 1,
Label: 11,
},
{
Prefix: mustCIDR("3ffe::/16"),
Precedence: 1,
Label: 12,
},
}
func () {
sort.Sort(sort.Reverse(byMaskLength(rfc6724policyTable)))
}
type byMaskLength []policyTableEntry
func ( byMaskLength) () int { return len() }
func ( byMaskLength) (, int) { [], [] = [], [] }
func ( byMaskLength) (, int) bool {
, := [].Prefix.Mask.Size()
, := [].Prefix.Mask.Size()
return <
}
func ( policyTable) ( IP) policyTableEntry {
for , := range {
if .Prefix.Contains() {
return
}
}
return policyTableEntry{}
}
type scope uint8
const (
scopeInterfaceLocal scope = 0x1
scopeLinkLocal scope = 0x2
scopeAdminLocal scope = 0x4
scopeSiteLocal scope = 0x5
scopeOrgLocal scope = 0x8
scopeGlobal scope = 0xe
)
func ( IP) scope {
if .IsLoopback() || .IsLinkLocalUnicast() {
return scopeLinkLocal
}
:= len() == IPv6len && .To4() == nil
if && .IsMulticast() {
return scope([1] & 0xf)
if && [0] == 0xfe && [1]&0xc0 == 0xc0 {
return scopeSiteLocal
}
return scopeGlobal
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |