sym-encryption #1
@ -3,6 +3,7 @@ package node
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math/rand"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -22,7 +23,7 @@ type peerState interface {
|
|||||||
|
|
||||||
type stateBase struct {
|
type stateBase struct {
|
||||||
// The purpose of this state machine is to manage this published data.
|
// The purpose of this state machine is to manage this published data.
|
||||||
published *atomic.Pointer[peerData]
|
published *atomic.Pointer[peerRoutingData]
|
||||||
|
|
||||||
// The other remote peers.
|
// The other remote peers.
|
||||||
peers *remotePeers
|
peers *remotePeers
|
||||||
@ -40,7 +41,7 @@ type stateBase struct {
|
|||||||
// Mutable peer data.
|
// Mutable peer data.
|
||||||
peer *m.Peer
|
peer *m.Peer
|
||||||
remotePub bool
|
remotePub bool
|
||||||
data peerData // Local copy of shared data. See publish().
|
routingData peerRoutingData // Local copy of shared data. See publish().
|
||||||
|
|
||||||
// Timers
|
// Timers
|
||||||
pingTimer *time.Timer
|
pingTimer *time.Timer
|
||||||
@ -63,16 +64,24 @@ func (s *stateBase) OnPeerUpdate(peer *m.Peer) peerState {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s.peer = peer
|
return s.selectStateFromPeer(peer)
|
||||||
|
}
|
||||||
|
|
||||||
s.data = peerData{}
|
func (s *stateBase) selectStateFromPeer(peer *m.Peer) peerState {
|
||||||
s.data.controlCipher = newControlCipher(s.privKey, peer.EncPubKey)
|
s.peer = peer
|
||||||
|
s.routingData = peerRoutingData{}
|
||||||
|
|
||||||
|
if peer == nil {
|
||||||
|
return newStateNoPeer(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.routingData.controlCipher = newControlCipher(s.privKey, peer.EncPubKey)
|
||||||
|
|
||||||
ip, isValid := netip.AddrFromSlice(peer.PublicIP)
|
ip, isValid := netip.AddrFromSlice(peer.PublicIP)
|
||||||
if isValid {
|
if isValid {
|
||||||
s.remotePub = true
|
s.remotePub = true
|
||||||
s.data.remoteAddr = netip.AddrPortFrom(ip, peer.Port)
|
s.routingData.remoteAddr = netip.AddrPortFrom(ip, peer.Port)
|
||||||
s.data.relay = peer.Mediator
|
s.routingData.relay = peer.Mediator
|
||||||
|
|
||||||
if s.localPub && s.localIP < s.remoteIP {
|
if s.localPub && s.localIP < s.remoteIP {
|
||||||
return newStateServer(s)
|
return newStateServer(s)
|
||||||
@ -84,9 +93,7 @@ func (s *stateBase) OnPeerUpdate(peer *m.Peer) peerState {
|
|||||||
return newStateServer(s)
|
return newStateServer(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: return newStateMediated(a/b)
|
return newStateSelectRelay(s)
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stateBase) OnPing(rAddr netip.AddrPort, p pingPacket) peerState { return nil }
|
func (s *stateBase) OnPing(rAddr netip.AddrPort, p pingPacket) peerState { return nil }
|
||||||
@ -106,10 +113,24 @@ func (s *stateBase) logf(msg string, args ...any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *stateBase) publish() {
|
func (s *stateBase) publish() {
|
||||||
data := s.data
|
data := s.routingData
|
||||||
s.published.Store(&data)
|
s.published.Store(&data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *stateBase) selectRelay() byte {
|
||||||
|
possible := make([]byte, 0, 8)
|
||||||
|
for i, peer := range s.peers {
|
||||||
|
if peer.CanRelay() {
|
||||||
|
possible = append(possible, byte(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(possible) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return possible[rand.Intn(len(possible))]
|
||||||
|
}
|
||||||
|
|
||||||
func (s *stateBase) sendPing(sharedKey [32]byte) {
|
func (s *stateBase) sendPing(sharedKey [32]byte) {
|
||||||
s.sendControlPacket(newPingPacket(sharedKey))
|
s.sendControlPacket(newPingPacket(sharedKey))
|
||||||
}
|
}
|
||||||
@ -127,13 +148,22 @@ func (s *stateBase) sendControlPacket(pkt interface{ Marshal([]byte) []byte }) {
|
|||||||
DestIP: s.remoteIP,
|
DestIP: s.remoteIP,
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = s.data.controlCipher.Encrypt(h, buf, s.encBuf)
|
buf = s.routingData.controlCipher.Encrypt(h, buf, s.encBuf)
|
||||||
if s.data.relayIP == 0 {
|
if s.routingData.relayIP != 0 {
|
||||||
s.conn.WriteTo(buf, s.data.remoteAddr)
|
s.peers[s.routingData.relayIP].RelayFor(s.remoteIP, buf)
|
||||||
return
|
} else {
|
||||||
|
s.conn.WriteTo(buf, s.routingData.remoteAddr)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Relay!
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type stateNoPeer struct{ *stateBase }
|
||||||
|
|
||||||
|
func newStateNoPeer(b *stateBase) *stateNoPeer {
|
||||||
|
s := &stateNoPeer{b}
|
||||||
|
s.publish()
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -147,8 +177,8 @@ func newStateClient(b *stateBase) peerState {
|
|||||||
s := &stateClient{stateBase: b}
|
s := &stateClient{stateBase: b}
|
||||||
s.publish()
|
s.publish()
|
||||||
|
|
||||||
s.data.dataCipher = newDataCipher()
|
s.routingData.dataCipher = newDataCipher()
|
||||||
s.sharedKey = s.data.dataCipher.Key()
|
s.sharedKey = s.routingData.dataCipher.Key()
|
||||||
|
|
||||||
s.sendPing(s.sharedKey)
|
s.sendPing(s.sharedKey)
|
||||||
s.resetPingTimer()
|
s.resetPingTimer()
|
||||||
@ -159,8 +189,8 @@ func newStateClient(b *stateBase) peerState {
|
|||||||
func (s *stateClient) Name() string { return "client" }
|
func (s *stateClient) Name() string { return "client" }
|
||||||
|
|
||||||
func (s *stateClient) OnPong(addr netip.AddrPort, p pongPacket) peerState {
|
func (s *stateClient) OnPong(addr netip.AddrPort, p pongPacket) peerState {
|
||||||
if !s.data.up {
|
if !s.routingData.up {
|
||||||
s.data.up = true
|
s.routingData.up = true
|
||||||
s.publish()
|
s.publish()
|
||||||
}
|
}
|
||||||
s.resetTimeoutTimer()
|
s.resetTimeoutTimer()
|
||||||
@ -174,7 +204,7 @@ func (s *stateClient) OnPingTimer() peerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *stateClient) OnTimeoutTimer() peerState {
|
func (s *stateClient) OnTimeoutTimer() peerState {
|
||||||
s.data.up = false
|
s.routingData.up = false
|
||||||
s.publish()
|
s.publish()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -196,19 +226,134 @@ func newStateServer(b *stateBase) peerState {
|
|||||||
func (s *stateServer) Name() string { return "server" }
|
func (s *stateServer) Name() string { return "server" }
|
||||||
|
|
||||||
func (s *stateServer) OnPing(addr netip.AddrPort, p pingPacket) peerState {
|
func (s *stateServer) OnPing(addr netip.AddrPort, p pingPacket) peerState {
|
||||||
if addr != s.data.remoteAddr {
|
if addr != s.routingData.remoteAddr {
|
||||||
s.logf("Got new peer address: %v", addr)
|
s.logf("Got new peer address: %v", addr)
|
||||||
s.data.remoteAddr = addr
|
s.routingData.remoteAddr = addr
|
||||||
s.data.up = true
|
s.routingData.up = true
|
||||||
s.publish()
|
s.publish()
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.data.dataCipher == nil || p.SharedKey != s.data.dataCipher.Key() {
|
if s.routingData.dataCipher == nil || p.SharedKey != s.routingData.dataCipher.Key() {
|
||||||
s.logf("Got new shared key.")
|
s.logf("Got new shared key.")
|
||||||
s.data.dataCipher = newDataCipherFromKey(p.SharedKey)
|
s.routingData.dataCipher = newDataCipherFromKey(p.SharedKey)
|
||||||
|
s.routingData.up = true
|
||||||
s.publish()
|
s.publish()
|
||||||
}
|
}
|
||||||
|
|
||||||
s.sendPong(p)
|
s.sendPong(p)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type stateSelectRelay struct {
|
||||||
|
*stateBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStateSelectRelay(b *stateBase) peerState {
|
||||||
|
s := &stateSelectRelay{stateBase: b}
|
||||||
|
s.routingData.dataCipher = nil
|
||||||
|
s.routingData.up = false
|
||||||
|
s.publish()
|
||||||
|
|
||||||
|
if relay := s.selectRelay(); relay != 0 {
|
||||||
|
s.routingData.up = false
|
||||||
|
s.routingData.relayIP = relay
|
||||||
|
return s.selectRole()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.resetPingTimer()
|
||||||
|
s.stopTimeoutTimer()
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stateSelectRelay) selectRole() peerState {
|
||||||
|
if s.localIP < s.remoteIP {
|
||||||
|
return newStateServerRelayed(s.stateBase)
|
||||||
|
}
|
||||||
|
return newStateClientRelayed(s.stateBase)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stateSelectRelay) Name() string { return "select-relay" }
|
||||||
|
|
||||||
|
func (s *stateSelectRelay) OnPingTimer() peerState {
|
||||||
|
if relay := s.selectRelay(); relay != 0 {
|
||||||
|
s.routingData.relayIP = relay
|
||||||
|
return s.selectRole()
|
||||||
|
}
|
||||||
|
s.resetPingTimer()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type stateClientRelayed struct {
|
||||||
|
sharedKey [32]byte
|
||||||
|
*stateBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStateClientRelayed(b *stateBase) peerState {
|
||||||
|
s := &stateClientRelayed{stateBase: b}
|
||||||
|
|
||||||
|
s.routingData.dataCipher = newDataCipher()
|
||||||
|
s.sharedKey = s.routingData.dataCipher.Key()
|
||||||
|
s.publish()
|
||||||
|
|
||||||
|
s.sendPing(s.sharedKey)
|
||||||
|
s.resetPingTimer()
|
||||||
|
s.resetTimeoutTimer()
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stateClientRelayed) Name() string { return "client-relayed" }
|
||||||
|
|
||||||
|
func (s *stateClientRelayed) OnPong(addr netip.AddrPort, p pongPacket) peerState {
|
||||||
|
if !s.routingData.up {
|
||||||
|
s.routingData.up = true
|
||||||
|
s.publish()
|
||||||
|
}
|
||||||
|
s.resetTimeoutTimer()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stateClientRelayed) OnPingTimer() peerState {
|
||||||
|
s.sendPing(s.sharedKey)
|
||||||
|
s.resetPingTimer()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stateClientRelayed) OnTimeoutTimer() peerState {
|
||||||
|
return newStateSelectRelay(s.stateBase)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type stateServerRelayed struct {
|
||||||
|
*stateBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStateServerRelayed(b *stateBase) peerState {
|
||||||
|
s := &stateServerRelayed{b}
|
||||||
|
s.stopPingTimer()
|
||||||
|
s.resetTimeoutTimer()
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stateServerRelayed) Name() string { return "server-relayed" }
|
||||||
|
|
||||||
|
func (s *stateServerRelayed) OnPing(addr netip.AddrPort, p pingPacket) peerState {
|
||||||
|
if s.routingData.dataCipher == nil || p.SharedKey != s.routingData.dataCipher.Key() {
|
||||||
|
s.logf("Got new shared key.")
|
||||||
|
s.routingData.up = true
|
||||||
|
s.routingData.dataCipher = newDataCipherFromKey(p.SharedKey)
|
||||||
|
s.publish()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.sendPong(p)
|
||||||
|
s.resetTimeoutTimer()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stateServerRelayed) OnTimeoutTimer() peerState {
|
||||||
|
return newStateSelectRelay(s.stateBase)
|
||||||
|
}
|
||||||
|
@ -11,12 +11,7 @@ const (
|
|||||||
timeoutInterval = 20 * time.Second
|
timeoutInterval = 20 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
func (rp *remotePeer) supervise(
|
func (rp *remotePeer) supervise(conf m.PeerConfig) {
|
||||||
conf m.PeerConfig,
|
|
||||||
remoteIP byte,
|
|
||||||
conn *connWriter,
|
|
||||||
peers *remotePeers,
|
|
||||||
) {
|
|
||||||
defer panicHandler()
|
defer panicHandler()
|
||||||
|
|
||||||
base := &stateBase{
|
base := &stateBase{
|
||||||
|
80
node/peer.go
80
node/peer.go
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
type remotePeers [256]*remotePeer
|
type remotePeers [256]*remotePeer
|
||||||
|
|
||||||
type peerData struct {
|
type peerRoutingData struct {
|
||||||
up bool
|
up bool
|
||||||
relay bool
|
relay bool
|
||||||
controlCipher *controlCipher
|
controlCipher *controlCipher
|
||||||
@ -29,7 +29,7 @@ type remotePeer struct {
|
|||||||
|
|
||||||
// Shared state.
|
// Shared state.
|
||||||
peers *remotePeers
|
peers *remotePeers
|
||||||
published *atomic.Pointer[peerData]
|
published *atomic.Pointer[peerRoutingData]
|
||||||
|
|
||||||
// Only used in HandlePacket / Not synchronized.
|
// Only used in HandlePacket / Not synchronized.
|
||||||
dupCheck *dupCheck
|
dupCheck *dupCheck
|
||||||
@ -53,7 +53,7 @@ func newRemotePeer(conf m.PeerConfig, remoteIP byte, iface *ifWriter, conn *conn
|
|||||||
iface: iface,
|
iface: iface,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
peers: peers,
|
peers: peers,
|
||||||
published: &atomic.Pointer[peerData]{},
|
published: &atomic.Pointer[peerRoutingData]{},
|
||||||
dupCheck: newDupCheck(0),
|
dupCheck: newDupCheck(0),
|
||||||
decryptBuf: make([]byte, bufferSize),
|
decryptBuf: make([]byte, bufferSize),
|
||||||
encryptBuf: make([]byte, bufferSize),
|
encryptBuf: make([]byte, bufferSize),
|
||||||
@ -62,11 +62,11 @@ func newRemotePeer(conf m.PeerConfig, remoteIP byte, iface *ifWriter, conn *conn
|
|||||||
controlPackets: make(chan controlPacket, 512),
|
controlPackets: make(chan controlPacket, 512),
|
||||||
}
|
}
|
||||||
|
|
||||||
pd := peerData{}
|
pd := peerRoutingData{}
|
||||||
rp.published.Store(&pd)
|
rp.published.Store(&pd)
|
||||||
|
|
||||||
//go newPeerSuper(rp).Run()
|
//go newPeerSuper(rp).Run()
|
||||||
go rp.supervise(conf, remoteIP, conn, peers)
|
go rp.supervise(conf)
|
||||||
return rp
|
return rp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,9 +102,8 @@ func (rp *remotePeer) HandlePacket(addr netip.AddrPort, h header, data []byte) {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
func (rp *remotePeer) handleControlPacket(addr netip.AddrPort, h header, data []byte) {
|
func (rp *remotePeer) handleControlPacket(addr netip.AddrPort, h header, data []byte) {
|
||||||
shared := rp.published.Load()
|
routingData := rp.published.Load()
|
||||||
if shared.controlCipher == nil {
|
if routingData.controlCipher == nil {
|
||||||
log.Printf("Shared: %+v", *shared)
|
|
||||||
rp.logf("Not connected (control).")
|
rp.logf("Not connected (control).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -114,7 +113,7 @@ func (rp *remotePeer) handleControlPacket(addr netip.AddrPort, h header, data []
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
out, ok := shared.controlCipher.Decrypt(data, rp.decryptBuf)
|
out, ok := routingData.controlCipher.Decrypt(data, rp.decryptBuf)
|
||||||
if !ok {
|
if !ok {
|
||||||
rp.logf("Failed to decrypt control packet.")
|
rp.logf("Failed to decrypt control packet.")
|
||||||
return
|
return
|
||||||
@ -150,13 +149,13 @@ func (rp *remotePeer) handleControlPacket(addr netip.AddrPort, h header, data []
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
func (rp *remotePeer) handleDataPacket(data []byte) {
|
func (rp *remotePeer) handleDataPacket(data []byte) {
|
||||||
shared := rp.published.Load()
|
routingData := rp.published.Load()
|
||||||
if shared.dataCipher == nil {
|
if routingData.dataCipher == nil {
|
||||||
rp.logf("Not connected (recv).")
|
rp.logf("Not connected (recv).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dec, ok := shared.dataCipher.Decrypt(data, rp.decryptBuf)
|
dec, ok := routingData.dataCipher.Decrypt(data, rp.decryptBuf)
|
||||||
if !ok {
|
if !ok {
|
||||||
rp.logf("Failed to decrypt data packet.")
|
rp.logf("Failed to decrypt data packet.")
|
||||||
return
|
return
|
||||||
@ -168,19 +167,19 @@ func (rp *remotePeer) handleDataPacket(data []byte) {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
func (rp *remotePeer) handleRelayPacket(h header, data []byte) {
|
func (rp *remotePeer) handleRelayPacket(h header, data []byte) {
|
||||||
shared := rp.published.Load()
|
routingData := rp.published.Load()
|
||||||
if shared.dataCipher == nil {
|
if routingData.dataCipher == nil {
|
||||||
rp.logf("Not connected (recv).")
|
rp.logf("Not connected (recv).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dec, ok := shared.dataCipher.Decrypt(data, rp.decryptBuf)
|
dec, ok := routingData.dataCipher.Decrypt(data, rp.decryptBuf)
|
||||||
if !ok {
|
if !ok {
|
||||||
rp.logf("Failed to decrypt data packet.")
|
rp.logf("Failed to decrypt data packet.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rp.peers[h.DestIP].sendDirect(dec)
|
rp.peers[h.DestIP].SendAsIs(dec)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -189,13 +188,13 @@ func (rp *remotePeer) handleRelayPacket(h header, data []byte) {
|
|||||||
//
|
//
|
||||||
// This function is called by a single thread.
|
// This function is called by a single thread.
|
||||||
func (rp *remotePeer) SendData(data []byte) {
|
func (rp *remotePeer) SendData(data []byte) {
|
||||||
rp.sendData(dataStreamID, rp.remoteIP, data)
|
rp.encryptAndSend(dataStreamID, rp.remoteIP, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rp *remotePeer) HandleInterfacePacket(data []byte) {
|
func (rp *remotePeer) HandleInterfacePacket(data []byte) {
|
||||||
shared := rp.published.Load()
|
routingData := rp.published.Load()
|
||||||
|
|
||||||
if shared.dataCipher == nil {
|
if routingData.dataCipher == nil {
|
||||||
rp.logf("Not connected (handle interface).")
|
rp.logf("Not connected (handle interface).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -207,10 +206,10 @@ func (rp *remotePeer) HandleInterfacePacket(data []byte) {
|
|||||||
DestIP: rp.remoteIP,
|
DestIP: rp.remoteIP,
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := shared.dataCipher.Encrypt(h, data, rp.encryptBuf)
|
enc := routingData.dataCipher.Encrypt(h, data, rp.encryptBuf)
|
||||||
|
|
||||||
if shared.relayIP != 0 {
|
if routingData.relayIP != 0 {
|
||||||
rp.peers[shared.relayIP].RelayData(shared.relayIP, enc)
|
rp.peers[routingData.relayIP].RelayFor(rp.remoteIP, enc)
|
||||||
} else {
|
} else {
|
||||||
rp.SendData(data)
|
rp.SendData(data)
|
||||||
}
|
}
|
||||||
@ -218,16 +217,23 @@ func (rp *remotePeer) HandleInterfacePacket(data []byte) {
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
func (rp *remotePeer) RelayData(destIP byte, data []byte) {
|
func (rp *remotePeer) CanRelay() bool {
|
||||||
rp.sendData(relayStreamID, destIP, data)
|
data := rp.published.Load()
|
||||||
|
return data.relay && data.up
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
func (rp *remotePeer) sendData(streamID byte, destIP byte, data []byte) {
|
func (rp *remotePeer) RelayFor(destIP byte, data []byte) {
|
||||||
shared := rp.published.Load()
|
rp.encryptAndSend(relayStreamID, destIP, data)
|
||||||
if shared.dataCipher == nil || shared.remoteAddr == zeroAddrPort {
|
}
|
||||||
rp.logf("Not connected (send).")
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func (rp *remotePeer) encryptAndSend(streamID byte, destIP byte, data []byte) {
|
||||||
|
routingData := rp.published.Load()
|
||||||
|
if routingData.dataCipher == nil || routingData.remoteAddr == zeroAddrPort {
|
||||||
|
rp.logf("Not connected (encrypt and send).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,15 +244,19 @@ func (rp *remotePeer) sendData(streamID byte, destIP byte, data []byte) {
|
|||||||
DestIP: destIP,
|
DestIP: destIP,
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := shared.dataCipher.Encrypt(h, data, rp.encryptBuf)
|
enc := routingData.dataCipher.Encrypt(h, data, rp.encryptBuf)
|
||||||
rp.conn.WriteTo(enc, shared.remoteAddr)
|
rp.conn.WriteTo(enc, routingData.remoteAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rp *remotePeer) sendDirect(data []byte) {
|
// ----------------------------------------------------------------------------
|
||||||
shared := rp.published.Load()
|
|
||||||
if shared.remoteAddr == zeroAddrPort {
|
// SendAsIs is used when forwarding already-encrypted data from one peer to
|
||||||
rp.logf("Not connected (send).")
|
// another.
|
||||||
|
func (rp *remotePeer) SendAsIs(data []byte) {
|
||||||
|
routingData := rp.published.Load()
|
||||||
|
if routingData.remoteAddr == zeroAddrPort {
|
||||||
|
rp.logf("Not connected (send direct).")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rp.conn.WriteTo(data, shared.remoteAddr)
|
rp.conn.WriteTo(data, routingData.remoteAddr)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user