|
@@ -1,10 +1,10 @@
|
|
|
package libnetwork
|
|
|
|
|
|
import (
|
|
|
- "container/heap"
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
"net"
|
|
|
+ "sort"
|
|
|
"strings"
|
|
|
"sync"
|
|
|
"time"
|
|
@@ -63,8 +63,6 @@ func (sb *sandbox) processOptions(options ...SandboxOption) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-type epHeap []*endpoint
|
|
|
-
|
|
|
type sandbox struct {
|
|
|
id string
|
|
|
containerID string
|
|
@@ -75,7 +73,7 @@ type sandbox struct {
|
|
|
resolver Resolver
|
|
|
resolverOnce sync.Once
|
|
|
refCnt int
|
|
|
- endpoints epHeap
|
|
|
+ endpoints []*endpoint
|
|
|
epPriority map[string]int
|
|
|
populatedEndpoints map[string]struct{}
|
|
|
joinLeaveDone chan struct{}
|
|
@@ -353,20 +351,36 @@ func (sb *sandbox) getConnectedEndpoints() []*endpoint {
|
|
|
defer sb.Unlock()
|
|
|
|
|
|
eps := make([]*endpoint, len(sb.endpoints))
|
|
|
- for i, ep := range sb.endpoints {
|
|
|
- eps[i] = ep
|
|
|
- }
|
|
|
+ copy(eps, sb.endpoints)
|
|
|
|
|
|
return eps
|
|
|
}
|
|
|
|
|
|
+func (sb *sandbox) addEndpoint(ep *endpoint) {
|
|
|
+ sb.Lock()
|
|
|
+ defer sb.Unlock()
|
|
|
+
|
|
|
+ l := len(sb.endpoints)
|
|
|
+ i := sort.Search(l, func(j int) bool {
|
|
|
+ return ep.Less(sb.endpoints[j])
|
|
|
+ })
|
|
|
+
|
|
|
+ sb.endpoints = append(sb.endpoints, nil)
|
|
|
+ copy(sb.endpoints[i+1:], sb.endpoints[i:])
|
|
|
+ sb.endpoints[i] = ep
|
|
|
+}
|
|
|
+
|
|
|
func (sb *sandbox) removeEndpoint(ep *endpoint) {
|
|
|
sb.Lock()
|
|
|
defer sb.Unlock()
|
|
|
|
|
|
+ sb.removeEndpointRaw(ep)
|
|
|
+}
|
|
|
+
|
|
|
+func (sb *sandbox) removeEndpointRaw(ep *endpoint) {
|
|
|
for i, e := range sb.endpoints {
|
|
|
if e == ep {
|
|
|
- heap.Remove(&sb.endpoints, i)
|
|
|
+ sb.endpoints = append(sb.endpoints[:i], sb.endpoints[i+1:]...)
|
|
|
return
|
|
|
}
|
|
|
}
|
|
@@ -940,7 +954,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
- heap.Remove(&sb.endpoints, index)
|
|
|
+ sb.removeEndpointRaw(ep)
|
|
|
for _, e := range sb.endpoints {
|
|
|
if len(e.Gateway()) > 0 {
|
|
|
gwepAfter = e
|
|
@@ -1165,80 +1179,69 @@ func OptionIngress() SandboxOption {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (eh epHeap) Len() int { return len(eh) }
|
|
|
-
|
|
|
-func (eh epHeap) Less(i, j int) bool {
|
|
|
+// <=> Returns true if a < b, false if a > b and advances to next level if a == b
|
|
|
+// epi.prio <=> epj.prio # 2 < 1
|
|
|
+// epi.gw <=> epj.gw # non-gw < gw
|
|
|
+// epi.internal <=> epj.internal # non-internal < internal
|
|
|
+// epi.joininfo <=> epj.joininfo # ipv6 < ipv4
|
|
|
+// epi.name <=> epj.name # bar < foo
|
|
|
+func (epi *endpoint) Less(epj *endpoint) bool {
|
|
|
var (
|
|
|
- cip, cjp int
|
|
|
- ok bool
|
|
|
+ prioi, prioj int
|
|
|
)
|
|
|
|
|
|
- ci, _ := eh[i].getSandbox()
|
|
|
- cj, _ := eh[j].getSandbox()
|
|
|
-
|
|
|
- epi := eh[i]
|
|
|
- epj := eh[j]
|
|
|
+ sbi, _ := epi.getSandbox()
|
|
|
+ sbj, _ := epj.getSandbox()
|
|
|
|
|
|
- if epi.endpointInGWNetwork() {
|
|
|
- return false
|
|
|
+ // Prio defaults to 0
|
|
|
+ if sbi != nil {
|
|
|
+ prioi = sbi.epPriority[epi.ID()]
|
|
|
+ }
|
|
|
+ if sbj != nil {
|
|
|
+ prioj = sbj.epPriority[epj.ID()]
|
|
|
}
|
|
|
|
|
|
- if epj.endpointInGWNetwork() {
|
|
|
- return true
|
|
|
+ if prioi != prioj {
|
|
|
+ return prioi > prioj
|
|
|
}
|
|
|
|
|
|
- if epi.getNetwork().Internal() {
|
|
|
- return false
|
|
|
+ gwi := epi.endpointInGWNetwork()
|
|
|
+ gwj := epj.endpointInGWNetwork()
|
|
|
+ if gwi != gwj {
|
|
|
+ return gwj
|
|
|
}
|
|
|
|
|
|
- if epj.getNetwork().Internal() {
|
|
|
- return true
|
|
|
+ inti := epi.getNetwork().Internal()
|
|
|
+ intj := epj.getNetwork().Internal()
|
|
|
+ if inti != intj {
|
|
|
+ return intj
|
|
|
}
|
|
|
|
|
|
- if epi.joinInfo != nil && epj.joinInfo != nil {
|
|
|
- if (epi.joinInfo.gw != nil && epi.joinInfo.gw6 != nil) &&
|
|
|
- (epj.joinInfo.gw == nil || epj.joinInfo.gw6 == nil) {
|
|
|
- return true
|
|
|
+ jii := 0
|
|
|
+ if epi.joinInfo != nil {
|
|
|
+ if epi.joinInfo.gw != nil {
|
|
|
+ jii = jii + 1
|
|
|
}
|
|
|
- if (epj.joinInfo.gw != nil && epj.joinInfo.gw6 != nil) &&
|
|
|
- (epi.joinInfo.gw == nil || epi.joinInfo.gw6 == nil) {
|
|
|
- return false
|
|
|
+ if epi.joinInfo.gw6 != nil {
|
|
|
+ jii = jii + 2
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ci != nil {
|
|
|
- cip, ok = ci.epPriority[eh[i].ID()]
|
|
|
- if !ok {
|
|
|
- cip = 0
|
|
|
+ jij := 0
|
|
|
+ if epj.joinInfo != nil {
|
|
|
+ if epj.joinInfo.gw != nil {
|
|
|
+ jij = jij + 1
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- if cj != nil {
|
|
|
- cjp, ok = cj.epPriority[eh[j].ID()]
|
|
|
- if !ok {
|
|
|
- cjp = 0
|
|
|
+ if epj.joinInfo.gw6 != nil {
|
|
|
+ jij = jij + 2
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if cip == cjp {
|
|
|
- return eh[i].network.Name() < eh[j].network.Name()
|
|
|
+ if jii != jij {
|
|
|
+ return jii > jij
|
|
|
}
|
|
|
|
|
|
- return cip > cjp
|
|
|
-}
|
|
|
-
|
|
|
-func (eh epHeap) Swap(i, j int) { eh[i], eh[j] = eh[j], eh[i] }
|
|
|
-
|
|
|
-func (eh *epHeap) Push(x interface{}) {
|
|
|
- *eh = append(*eh, x.(*endpoint))
|
|
|
-}
|
|
|
-
|
|
|
-func (eh *epHeap) Pop() interface{} {
|
|
|
- old := *eh
|
|
|
- n := len(old)
|
|
|
- x := old[n-1]
|
|
|
- *eh = old[0 : n-1]
|
|
|
- return x
|
|
|
+ return epi.network.Name() < epj.network.Name()
|
|
|
}
|
|
|
|
|
|
func (sb *sandbox) NdotsSet() bool {
|