refactor: split out LocalPeer
This has been a source of confusion for a long time.
This commit is contained in:
1 parent
059360416a
commit
465915d7d4
6 files changed
+64
-62
No files matched your search
@@ -52,7 +52,7 @@ func (conn *RemoteConnection) String() string {
|
||||
// Async. Does not return anything. If the connection is successful,
|
||||
// it will end up in the local peer's connections map.
|
||||
func NewLocalConnection(connRemote *RemoteConnection, acceptNewPeer bool, tcpConn *net.TCPConn, udpAddr *net.UDPAddr, router *Router) {
|
||||
if connRemote.local != router.Ourself {
|
||||
if connRemote.local != router.Ourself.Peer {
|
||||
log.Fatal("Attempt to create local connection from a peer which is not ourself")
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ func (conn *LocalConnection) queryLoop(queryChan <-chan *ConnectionInteraction,
|
||||
conn.handleShutdown()
|
||||
return
|
||||
}
|
||||
conn.local.AddConnection(conn)
|
||||
conn.Router.Ourself.AddConnection(conn)
|
||||
if conn.remoteUDPAddr != nil {
|
||||
if err = conn.ensureForwarders(); err == nil {
|
||||
conn.heartbeat = time.NewTicker(FastHeartbeat)
|
||||
@@ -231,7 +231,7 @@ func (conn *LocalConnection) handleSetEstablished() error {
|
||||
conn.established = true
|
||||
conn.Unlock()
|
||||
if !old {
|
||||
conn.local.ConnectionEstablished(conn)
|
||||
conn.Router.Ourself.ConnectionEstablished(conn)
|
||||
if err := conn.ensureForwarders(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -280,7 +280,7 @@ func (conn *LocalConnection) handleShutdown() {
|
||||
|
||||
if conn.remote != nil {
|
||||
conn.remote.DecrementLocalRefCount()
|
||||
conn.local.DeleteConnection(conn)
|
||||
conn.Router.Ourself.DeleteConnection(conn)
|
||||
}
|
||||
|
||||
stopTicker(conn.heartbeat)
|
||||
@@ -507,7 +507,7 @@ func (conn *LocalConnection) receiveTCP(decoder *gob.Decoder, usingPassword bool
|
||||
}
|
||||
if len(newUpdate) != 0 {
|
||||
conn.Router.Routes.Recalculate()
|
||||
conn.local.BroadcastTCP(Concat(ProtocolUpdateByte, newUpdate))
|
||||
conn.Router.Ourself.BroadcastTCP(Concat(ProtocolUpdateByte, newUpdate))
|
||||
}
|
||||
} else if msg[0] == ProtocolPMTUVerified {
|
||||
conn.verifyPMTU <- int(binary.BigEndian.Uint16(msg[1:]))
|
||||
|
||||
@@ -22,7 +22,7 @@ const (
|
||||
)
|
||||
|
||||
type ConnectionMaker struct {
|
||||
ourself *Peer
|
||||
ourself *LocalPeer
|
||||
peers *Peers
|
||||
targets map[string]*Target
|
||||
cmdLineAddress map[string]bool
|
||||
@@ -41,7 +41,7 @@ type ConnectionMakerInteraction struct {
|
||||
address string
|
||||
}
|
||||
|
||||
func StartConnectionMaker(ourself *Peer, peers *Peers) *ConnectionMaker {
|
||||
func StartConnectionMaker(ourself *LocalPeer, peers *Peers) *ConnectionMaker {
|
||||
queryChan := make(chan *ConnectionMakerInteraction, ChannelSize)
|
||||
state := &ConnectionMaker{
|
||||
ourself: ourself,
|
||||
|
||||
+39
-40
@@ -20,6 +20,12 @@ func NewPeer(name PeerName, uid uint64, version uint64, router *Router) *Peer {
|
||||
Router: router}
|
||||
}
|
||||
|
||||
func (peer *Peer) String() string {
|
||||
peer.RLock()
|
||||
defer peer.RUnlock()
|
||||
return fmt.Sprint("Peer ", peer.Name, " (v", peer.version, ") (UID ", peer.UID, ")")
|
||||
}
|
||||
|
||||
func (peer *Peer) Version() uint64 {
|
||||
peer.RLock()
|
||||
defer peer.RUnlock()
|
||||
@@ -133,7 +139,7 @@ func (peer *Peer) Routes(stopAt *Peer, symmetric bool) (bool, map[PeerName]PeerN
|
||||
}
|
||||
|
||||
func (peer *Peer) SetVersionAndConnections(version uint64, connections map[PeerName]Connection) {
|
||||
if peer == peer.Router.Ourself {
|
||||
if peer == peer.Router.Ourself.Peer {
|
||||
log.Fatal("Attempt to set version and connections on the local peer", peer.Name)
|
||||
}
|
||||
peer.Lock()
|
||||
@@ -142,15 +148,23 @@ func (peer *Peer) SetVersionAndConnections(version uint64, connections map[PeerN
|
||||
peer.connections = connections
|
||||
}
|
||||
|
||||
func (peer *Peer) Forward(dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
return peer.Relay(peer, dstPeer, df, frame, dec)
|
||||
func StartLocalPeer(name PeerName, router *Router) *LocalPeer {
|
||||
peer := &LocalPeer{Peer: NewPeer(name, 0, 0, router)}
|
||||
queryChan := make(chan *PeerInteraction, ChannelSize)
|
||||
peer.queryChan = queryChan
|
||||
go peer.queryLoop(queryChan)
|
||||
return peer
|
||||
}
|
||||
|
||||
func (peer *Peer) Broadcast(df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
return peer.RelayBroadcast(peer, df, frame, dec)
|
||||
func (peer *LocalPeer) Forward(dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
return peer.Relay(peer.Peer, dstPeer, df, frame, dec)
|
||||
}
|
||||
|
||||
func (peer *Peer) Relay(srcPeer, dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
func (peer *LocalPeer) Broadcast(df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
return peer.RelayBroadcast(peer.Peer, df, frame, dec)
|
||||
}
|
||||
|
||||
func (peer *LocalPeer) Relay(srcPeer, dstPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
relayPeerName, found := peer.Router.Routes.Unicast(dstPeer.Name)
|
||||
if !found {
|
||||
// Not necessarily an error as there could be a race with the
|
||||
@@ -171,7 +185,7 @@ func (peer *Peer) Relay(srcPeer, dstPeer *Peer, df bool, frame []byte, dec *Ethe
|
||||
dec)
|
||||
}
|
||||
|
||||
func (peer *Peer) RelayBroadcast(srcPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
func (peer *LocalPeer) RelayBroadcast(srcPeer *Peer, df bool, frame []byte, dec *EthernetDecoder) error {
|
||||
nextHops := peer.Router.Routes.Broadcast(srcPeer.Name)
|
||||
if len(nextHops) == 0 {
|
||||
return nil
|
||||
@@ -203,22 +217,7 @@ func (peer *Peer) RelayBroadcast(srcPeer *Peer, df bool, frame []byte, dec *Ethe
|
||||
return nil
|
||||
}
|
||||
|
||||
func (peer *Peer) String() string {
|
||||
peer.RLock()
|
||||
defer peer.RUnlock()
|
||||
return fmt.Sprint("Peer ", peer.Name, " (v", peer.version, ") (UID ", peer.UID, ")")
|
||||
}
|
||||
|
||||
func (peer *Peer) StartLocalPeer() {
|
||||
if peer.Router.Ourself != peer {
|
||||
log.Fatal("Attempt to start peer which is not the local peer")
|
||||
}
|
||||
queryChan := make(chan *PeerInteraction, ChannelSize)
|
||||
peer.queryChan = queryChan
|
||||
go peer.queryLoop(queryChan)
|
||||
}
|
||||
|
||||
func (peer *Peer) CreateConnection(peerAddr string, acceptNewPeer bool) error {
|
||||
func (peer *LocalPeer) CreateConnection(peerAddr string, acceptNewPeer bool) error {
|
||||
if err := peer.checkConnectionLimit(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -237,7 +236,7 @@ func (peer *Peer) CreateConnection(peerAddr string, acceptNewPeer bool) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
connRemote := NewRemoteConnection(peer, nil, tcpConn.RemoteAddr().String())
|
||||
connRemote := NewRemoteConnection(peer.Peer, nil, tcpConn.RemoteAddr().String())
|
||||
NewLocalConnection(connRemote, acceptNewPeer, tcpConn, udpAddr, peer.Router)
|
||||
return nil
|
||||
}
|
||||
@@ -253,14 +252,14 @@ const (
|
||||
|
||||
// Async: rely on the peer to shut us down if we shouldn't be adding
|
||||
// ourselves, so therefore this can be async
|
||||
func (peer *Peer) AddConnection(conn *LocalConnection) {
|
||||
func (peer *LocalPeer) AddConnection(conn *LocalConnection) {
|
||||
peer.queryChan <- &PeerInteraction{
|
||||
Interaction: Interaction{code: PAddConnection},
|
||||
payload: conn}
|
||||
}
|
||||
|
||||
// Sync.
|
||||
func (peer *Peer) DeleteConnection(conn *LocalConnection) {
|
||||
func (peer *LocalPeer) DeleteConnection(conn *LocalConnection) {
|
||||
resultChan := make(chan interface{})
|
||||
peer.queryChan <- &PeerInteraction{
|
||||
Interaction: Interaction{code: PDeleteConnection, resultChan: resultChan},
|
||||
@@ -269,14 +268,14 @@ func (peer *Peer) DeleteConnection(conn *LocalConnection) {
|
||||
}
|
||||
|
||||
// Async.
|
||||
func (peer *Peer) ConnectionEstablished(conn *LocalConnection) {
|
||||
func (peer *LocalPeer) ConnectionEstablished(conn *LocalConnection) {
|
||||
peer.queryChan <- &PeerInteraction{
|
||||
Interaction: Interaction{code: PConnectionEstablished},
|
||||
payload: conn}
|
||||
}
|
||||
|
||||
// Async.
|
||||
func (peer *Peer) BroadcastTCP(msg []byte) {
|
||||
func (peer *LocalPeer) BroadcastTCP(msg []byte) {
|
||||
peer.queryChan <- &PeerInteraction{
|
||||
Interaction: Interaction{code: PBroadcastTCP},
|
||||
payload: msg}
|
||||
@@ -284,7 +283,7 @@ func (peer *Peer) BroadcastTCP(msg []byte) {
|
||||
|
||||
// ACTOR server
|
||||
|
||||
func (peer *Peer) queryLoop(queryChan <-chan *PeerInteraction) {
|
||||
func (peer *LocalPeer) queryLoop(queryChan <-chan *PeerInteraction) {
|
||||
for {
|
||||
query, ok := <-queryChan
|
||||
if !ok {
|
||||
@@ -304,8 +303,8 @@ func (peer *Peer) queryLoop(queryChan <-chan *PeerInteraction) {
|
||||
}
|
||||
}
|
||||
|
||||
func (peer *Peer) handleAddConnection(conn *LocalConnection) {
|
||||
if peer != conn.Local() {
|
||||
func (peer *LocalPeer) handleAddConnection(conn *LocalConnection) {
|
||||
if peer.Peer != conn.Local() {
|
||||
log.Fatal("Attempt made to add connection to peer where peer is not the source of connection")
|
||||
}
|
||||
if conn.Remote() == nil {
|
||||
@@ -344,8 +343,8 @@ func (peer *Peer) handleAddConnection(conn *LocalConnection) {
|
||||
peer.Unlock()
|
||||
}
|
||||
|
||||
func (peer *Peer) handleDeleteConnection(conn *LocalConnection) {
|
||||
if peer != conn.Local() {
|
||||
func (peer *LocalPeer) handleDeleteConnection(conn *LocalConnection) {
|
||||
if peer.Peer != conn.Local() {
|
||||
log.Fatal("Attempt made to delete connection from peer where peer is not the source of connection")
|
||||
}
|
||||
if conn.Remote() == nil {
|
||||
@@ -367,14 +366,14 @@ func (peer *Peer) handleDeleteConnection(conn *LocalConnection) {
|
||||
}
|
||||
// Must do garbage collection first to ensure we don't send out an
|
||||
// update with unreachable peers (can cause looping)
|
||||
peer.Router.Peers.GarbageCollect(peer.Router.Ourself, peer.Router.Macs)
|
||||
peer.Router.Peers.GarbageCollect(peer.Router.Ourself.Peer, peer.Router.Macs)
|
||||
if broadcast {
|
||||
peer.broadcastPeerUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
func (peer *Peer) handleConnectionEstablished(conn *LocalConnection) {
|
||||
if peer != conn.Local() {
|
||||
func (peer *LocalPeer) handleConnectionEstablished(conn *LocalConnection) {
|
||||
if peer.Peer != conn.Local() {
|
||||
log.Fatal("Peer informed of active connection where peer is not the source of connection")
|
||||
}
|
||||
if dupConn, found := peer.connections[conn.Remote().Name]; !found || conn != dupConn {
|
||||
@@ -388,18 +387,18 @@ func (peer *Peer) handleConnectionEstablished(conn *LocalConnection) {
|
||||
peer.broadcastPeerUpdate(conn.Remote())
|
||||
}
|
||||
|
||||
func (peer *Peer) handleBroadcastTCP(msg []byte) {
|
||||
func (peer *LocalPeer) handleBroadcastTCP(msg []byte) {
|
||||
peer.ForEachConnection(func(_ PeerName, conn Connection) {
|
||||
conn.(*LocalConnection).SendTCP(msg)
|
||||
})
|
||||
}
|
||||
|
||||
func (peer *Peer) broadcastPeerUpdate(peers ...*Peer) {
|
||||
func (peer *LocalPeer) broadcastPeerUpdate(peers ...*Peer) {
|
||||
peer.Router.Routes.Recalculate()
|
||||
peer.handleBroadcastTCP(Concat(ProtocolUpdateByte, EncodePeers(append(peers, peer)...)))
|
||||
peer.handleBroadcastTCP(Concat(ProtocolUpdateByte, EncodePeers(append(peers, peer.Peer)...)))
|
||||
}
|
||||
|
||||
func (peer *Peer) checkConnectionLimit() error {
|
||||
func (peer *LocalPeer) checkConnectionLimit() error {
|
||||
if 0 != peer.Router.ConnLimit && peer.ConnectionCount() >= peer.Router.ConnLimit {
|
||||
return fmt.Errorf("Connection limit reached (%v)", peer.Router.ConnLimit)
|
||||
}
|
||||
|
||||
+2
-2
@@ -68,9 +68,9 @@ func (peers *Peers) ApplyUpdate(update []byte, router *Router) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Now apply the updates
|
||||
newUpdate := peers.applyUpdate(decodedUpdate, decodedConns, router.Ourself)
|
||||
newUpdate := peers.applyUpdate(decodedUpdate, decodedConns, router.Ourself.Peer)
|
||||
|
||||
for _, peerRemoved := range peers.garbageCollect(router.Ourself, router.Macs) {
|
||||
for _, peerRemoved := range peers.garbageCollect(router.Ourself.Peer, router.Macs) {
|
||||
delete(newUpdate, peerRemoved.Name)
|
||||
}
|
||||
|
||||
|
||||
+10
-11
@@ -34,9 +34,8 @@ func NewRouter(iface *net.Interface, name PeerName, password []byte, connLimit i
|
||||
if len(password) > 0 {
|
||||
router.Password = &password
|
||||
}
|
||||
ourself := NewPeer(name, 0, 0, router)
|
||||
router.Ourself = router.Peers.FetchWithDefault(ourself)
|
||||
router.Ourself.StartLocalPeer()
|
||||
router.Ourself = StartLocalPeer(name, router)
|
||||
router.Peers.FetchWithDefault(router.Ourself.Peer)
|
||||
log.Println("Our name is", router.Ourself.Name)
|
||||
|
||||
return router
|
||||
@@ -53,7 +52,7 @@ func (router *Router) Start() {
|
||||
po, err := NewPcapO(router.Iface.Name)
|
||||
checkFatal(err)
|
||||
router.ConnectionMaker = StartConnectionMaker(router.Ourself, router.Peers)
|
||||
router.Routes = StartRoutes(router.Ourself, router.Peers)
|
||||
router.Routes = StartRoutes(router.Ourself.Peer, router.Peers)
|
||||
router.UDPListener = router.listenUDP(Port, po)
|
||||
router.listenTCP(Port)
|
||||
router.sniff(pio)
|
||||
@@ -77,7 +76,7 @@ func (router *Router) sniff(pio PacketSourceSink) {
|
||||
injectFrame := func(frame []byte) error { return pio.WritePacket(frame) }
|
||||
checkFrameTooBig := func(err error) error { return dec.CheckFrameTooBig(err, injectFrame) }
|
||||
mac := router.Iface.HardwareAddr
|
||||
if router.Macs.Enter(mac, router.Ourself) {
|
||||
if router.Macs.Enter(mac, router.Ourself.Peer) {
|
||||
log.Println("Discovered our MAC", mac)
|
||||
}
|
||||
go func() {
|
||||
@@ -101,10 +100,10 @@ func (router *Router) handleCapturedPacket(frameData []byte, dec *EthernetDecode
|
||||
// We need to filter out frames we injected ourselves. For such
|
||||
// frames, the srcMAC will have been recorded as associated with a
|
||||
// different peer.
|
||||
if found && srcPeer != router.Ourself {
|
||||
if found && srcPeer != router.Ourself.Peer {
|
||||
return nil
|
||||
}
|
||||
if router.Macs.Enter(srcMac, router.Ourself) {
|
||||
if router.Macs.Enter(srcMac, router.Ourself.Peer) {
|
||||
log.Println("Discovered local MAC", srcMac)
|
||||
}
|
||||
if dec.DropFrame() {
|
||||
@@ -112,7 +111,7 @@ func (router *Router) handleCapturedPacket(frameData []byte, dec *EthernetDecode
|
||||
}
|
||||
dstMac := dec.eth.DstMAC
|
||||
dstPeer, found := router.Macs.Lookup(dstMac)
|
||||
if found && dstPeer == router.Ourself {
|
||||
if found && dstPeer == router.Ourself.Peer {
|
||||
return nil
|
||||
}
|
||||
df := decodedLen == 2 && (dec.ip.Flags&layers.IPv4DontFragment != 0)
|
||||
@@ -157,7 +156,7 @@ func (router *Router) acceptTCP(tcpConn *net.TCPConn) {
|
||||
// someone else is dialing us, so our udp sender is the conn
|
||||
// on Port and we wait for them to send us something on UDP to
|
||||
// start.
|
||||
connRemote := NewRemoteConnection(router.Ourself, nil, tcpConn.RemoteAddr().String())
|
||||
connRemote := NewRemoteConnection(router.Ourself.Peer, nil, tcpConn.RemoteAddr().String())
|
||||
NewLocalConnection(connRemote, true, tcpConn, nil, router)
|
||||
}
|
||||
|
||||
@@ -245,7 +244,7 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
df := decodedLen == 2 && (dec.ip.Flags&layers.IPv4DontFragment != 0)
|
||||
srcMac := dec.eth.SrcMAC
|
||||
|
||||
if dstPeer != router.Ourself {
|
||||
if dstPeer != router.Ourself.Peer {
|
||||
// it's not for us, we're just relaying it
|
||||
if decodedLen == 0 {
|
||||
return nil
|
||||
@@ -288,7 +287,7 @@ func (router *Router) handleUDPPacketFunc(dec *EthernetDecoder, po PacketSink) F
|
||||
checkWarn(po.WritePacket(frame))
|
||||
|
||||
dstPeer, found = router.Macs.Lookup(dec.eth.DstMAC)
|
||||
if !found || dstPeer != router.Ourself {
|
||||
if !found || dstPeer != router.Ourself.Peer {
|
||||
return checkFrameTooBig(router.Ourself.RelayBroadcast(srcPeer, df, frame, dec), srcPeer)
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
type Router struct {
|
||||
Ourself *Peer
|
||||
Ourself *LocalPeer
|
||||
Iface *net.Interface
|
||||
Macs *MacCache
|
||||
Peers *Peers
|
||||
@@ -34,7 +34,11 @@ type Peer struct {
|
||||
UID uint64
|
||||
Router *Router
|
||||
localRefCount uint64
|
||||
queryChan chan<- *PeerInteraction
|
||||
}
|
||||
|
||||
type LocalPeer struct {
|
||||
*Peer
|
||||
queryChan chan<- *PeerInteraction
|
||||
}
|
||||
|
||||
type PeerInteraction struct {
|
||||
|
||||
Reference in new issue
Block a user