wip: relaying working
This commit is contained in:
		| @@ -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) | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user