Notify the InterHost when routes change

This commit is contained in:
David Wragg committed 2015-06-12 16:12:59 +01:00
1 parent 0f888e9735
commit a9c710211b
4 files changed
+86 -13

No files matched your search

+9 -1
View File
@@ -9,6 +9,10 @@ type InterHost interface {
// Start consuming forwarded packets.
ConsumePackets(*Peer, *Peers, InterHostConsumer) error
// The routes have changed, so any cached information should
// be discarded.
InvalidateRoutes()
// Form a packet-forwarding connection. The remote UDPAddr
// can be nil if unknown (in which case the implementation
// needs to discover it).
@@ -53,10 +57,14 @@ type InterHostForwarderListener interface {
type NullInterHost struct{}
func (NullInterHost) ConsumePackets(*Peer, *Peers, InterHostConsumer) error {
func (NullInterHost) ConsumeInterHostPackets(*Peer, *Peers,
InterHostConsumer) error {
return nil
}
func (NullInterHost) InvalidateRoutes() {
}
func (NullInterHost) MakeForwarder(*Peer, net.IP, *net.UDPAddr, uint64,
InterHostCrypto, func([]byte) error) (InterHostForwarder, error) {
return NullInterHost{}, nil
+1 -1
View File
@@ -70,7 +70,7 @@ func (peer *Peer) Info() string {
// NB: This function should generally be invoked while holding a read
// lock on Peers and LocalPeer.
func (peer *Peer) Routes(stopAt *Peer, establishedAndSymmetric bool) (bool, map[PeerName]PeerName) {
routes := make(map[PeerName]PeerName)
routes := make(unicastRoutes)
routes[peer.Name] = UnknownPeerName
nextWorklist := []*Peer{peer}
for len(nextWorklist) > 0 {
+72 -11
View File
@@ -7,14 +7,17 @@ import (
"sync"
)
type unicastRoutes map[PeerName]PeerName
type broadcastRoutes map[PeerName][]PeerName
type Routes struct {
sync.RWMutex
ourself *LocalPeer
peers *Peers
unicast map[PeerName]PeerName
unicastAll map[PeerName]PeerName // [1]
broadcast map[PeerName][]PeerName
broadcastAll map[PeerName][]PeerName // [1]
unicast unicastRoutes
unicastAll unicastRoutes // [1]
broadcast broadcastRoutes
broadcastAll broadcastRoutes // [1]
recalculate chan<- *struct{}
wait chan<- chan struct{}
// [1] based on *all* connections, not just established &
@@ -27,10 +30,10 @@ func NewRoutes(ourself *LocalPeer, peers *Peers) *Routes {
routes := &Routes{
ourself: ourself,
peers: peers,
unicast: make(map[PeerName]PeerName),
unicastAll: make(map[PeerName]PeerName),
broadcast: make(map[PeerName][]PeerName),
broadcastAll: make(map[PeerName][]PeerName),
unicast: make(unicastRoutes),
unicastAll: make(unicastRoutes),
broadcast: make(broadcastRoutes),
broadcastAll: make(broadcastRoutes),
recalculate: recalculate,
wait: wait}
routes.unicast[ourself.Name] = UnknownPeerName
@@ -166,6 +169,8 @@ func (routes *Routes) calculate() {
routes.peers.RLock()
routes.ourself.RLock()
var (
oldUnicast = routes.unicast
oldBroadcast = routes.broadcast
unicast = routes.calculateUnicast(true)
unicastAll = routes.calculateUnicast(false)
broadcast = routes.calculateBroadcast(true)
@@ -180,6 +185,10 @@ func (routes *Routes) calculate() {
routes.broadcast = broadcast
routes.broadcastAll = broadcastAll
routes.Unlock()
if !unicast.equals(oldUnicast) || !broadcast.equals(oldBroadcast) {
routes.ourself.router.InterHost.InvalidateRoutes()
}
}
// Calculate all the routes for the question: if *we* want to send a
@@ -191,7 +200,7 @@ func (routes *Routes) calculate() {
// any knowledge of the MAC address at all. Thus there's no need
// to exchange knowledge of MAC addresses, nor any constraints on
// the routes that we construct.
func (routes *Routes) calculateUnicast(establishedAndSymmetric bool) map[PeerName]PeerName {
func (routes *Routes) calculateUnicast(establishedAndSymmetric bool) unicastRoutes {
_, unicast := routes.ourself.Routes(nil, establishedAndSymmetric)
return unicast
}
@@ -214,8 +223,8 @@ func (routes *Routes) calculateUnicast(establishedAndSymmetric bool) map[PeerNam
// Y =/= Z /\ X.Routes(Y) <= X.Routes(Z) =>
// X.Routes(Y) u [P | Y.HasSymmetricConnectionTo(P)] <= X.Routes(Z)
// where <= is the subset relationship on keys of the returned map.
func (routes *Routes) calculateBroadcast(establishedAndSymmetric bool) map[PeerName][]PeerName {
broadcast := make(map[PeerName][]PeerName)
func (routes *Routes) calculateBroadcast(establishedAndSymmetric bool) broadcastRoutes {
broadcast := make(broadcastRoutes)
for _, peer := range routes.peers.table {
hops := []PeerName{}
if found, reached := peer.Routes(routes.ourself.Peer, establishedAndSymmetric); found {
@@ -226,3 +235,55 @@ func (routes *Routes) calculateBroadcast(establishedAndSymmetric bool) map[PeerN
}
return broadcast
}
func (a unicastRoutes) equals(b unicastRoutes) bool {
for key, aval := range a {
if bval, ok := b[key]; !ok || bval != aval {
return false
}
}
for key := range b {
if _, ok := a[key]; !ok {
return false
}
}
return true
}
func (a broadcastRoutes) equals(b broadcastRoutes) bool {
set := make(map[PeerName]struct{})
for key, aval := range a {
bval, ok := b[key]
if !ok {
return false
}
for _, peer := range aval {
set[peer] = struct{}{}
}
for _, peer := range bval {
if _, ok := set[peer]; !ok {
return false
}
delete(set, peer)
}
if len(set) != 0 {
return false
}
}
for key := range b {
if _, ok := a[key]; !ok {
return false
}
}
return true
}
+4
View File
@@ -86,6 +86,10 @@ func (sleeve *SleeveInterHost) ConsumePackets(localPeer *Peer, peers *Peers,
return nil
}
func (*SleeveInterHost) InvalidateRoutes() {
// no cached information, so nothing to do
}
func (sleeve *SleeveInterHost) logFrame(string, []byte, *layers.Ethernet) {
// XXX
}