wip
This commit is contained in:
		| @@ -12,11 +12,10 @@ type connReader struct { | |||||||
| 	sender  encryptedPacketSender | 	sender  encryptedPacketSender | ||||||
| 	super   controlMsgHandler | 	super   controlMsgHandler | ||||||
| 	localIP byte | 	localIP byte | ||||||
| 	routes  [256]*atomic.Pointer[peerRoute] | 	peers   [256]*atomic.Pointer[RemotePeer] | ||||||
|  |  | ||||||
| 	buf    []byte | 	buf    []byte | ||||||
| 	decBuf []byte | 	decBuf []byte | ||||||
| 	dupChecks [256]*dupCheck |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func newConnReader( | func newConnReader( | ||||||
| @@ -25,7 +24,7 @@ func newConnReader( | |||||||
| 	sender encryptedPacketSender, | 	sender encryptedPacketSender, | ||||||
| 	super controlMsgHandler, | 	super controlMsgHandler, | ||||||
| 	localIP byte, | 	localIP byte, | ||||||
| 	routes [256]*atomic.Pointer[peerRoute], | 	peers [256]*atomic.Pointer[RemotePeer], | ||||||
| ) *connReader { | ) *connReader { | ||||||
| 	return &connReader{ | 	return &connReader{ | ||||||
| 		conn:    conn, | 		conn:    conn, | ||||||
| @@ -33,15 +32,9 @@ func newConnReader( | |||||||
| 		sender:  sender, | 		sender:  sender, | ||||||
| 		super:   super, | 		super:   super, | ||||||
| 		localIP: localIP, | 		localIP: localIP, | ||||||
| 		routes:  routes, | 		peers:   peers, | ||||||
| 		buf:     make([]byte, bufferSize), | 		buf:     make([]byte, bufferSize), | ||||||
| 		decBuf:  make([]byte, bufferSize), | 		decBuf:  make([]byte, bufferSize), | ||||||
| 		dupChecks: func() (out [256]*dupCheck) { |  | ||||||
| 			for i := range out { |  | ||||||
| 				out[i] = newDupCheck(0) |  | ||||||
| 			} |  | ||||||
| 			return |  | ||||||
| 		}(), |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -69,19 +62,16 @@ func (r *connReader) handleNextPacket() { | |||||||
| 	remoteAddr = netip.AddrPortFrom(remoteAddr.Addr().Unmap(), remoteAddr.Port()) | 	remoteAddr = netip.AddrPortFrom(remoteAddr.Addr().Unmap(), remoteAddr.Port()) | ||||||
|  |  | ||||||
| 	buf = buf[:n] | 	buf = buf[:n] | ||||||
| 	h, ok := parseHeader(buf) | 	h := parseHeader(buf) | ||||||
| 	if !ok { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	route := r.routes[h.SourceIP].Load() | 	peer := r.peers[h.SourceIP].Load() | ||||||
|  |  | ||||||
| 	switch h.StreamID { | 	switch h.StreamID { | ||||||
| 	case controlStreamID: | 	case controlStreamID: | ||||||
| 		r.handleControlPacket(route, remoteAddr, h, buf) | 		r.handleControlPacket(peer, remoteAddr, h, buf) | ||||||
|  |  | ||||||
| 	case dataStreamID: | 	case dataStreamID: | ||||||
| 		r.handleDataPacket(route, h, buf) | 		r.handleDataPacket(peer, h, buf) | ||||||
|  |  | ||||||
| 	default: | 	default: | ||||||
| 		r.logf("Unknown stream ID: %d", h.StreamID) | 		r.logf("Unknown stream ID: %d", h.StreamID) | ||||||
| @@ -89,12 +79,12 @@ func (r *connReader) handleNextPacket() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (r *connReader) handleControlPacket( | func (r *connReader) handleControlPacket( | ||||||
| 	route *peerRoute, | 	peer *RemotePeer, | ||||||
| 	addr netip.AddrPort, | 	addr netip.AddrPort, | ||||||
| 	h header, | 	h header, | ||||||
| 	enc []byte, | 	enc []byte, | ||||||
| ) { | ) { | ||||||
| 	if route.ControlCipher == nil { | 	if peer.ControlCipher == nil { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -103,7 +93,7 @@ func (r *connReader) handleControlPacket( | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	msg, err := decryptControlPacket(route, addr, h, enc, r.decBuf) | 	msg, err := decryptControlPacket(peer, addr, h, enc, r.decBuf) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		r.logf("Failed to decrypt control packet: %v", err) | 		r.logf("Failed to decrypt control packet: %v", err) | ||||||
| 		return | 		return | ||||||
| @@ -112,13 +102,13 @@ func (r *connReader) handleControlPacket( | |||||||
| 	r.super.HandleControlMsg(msg) | 	r.super.HandleControlMsg(msg) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *connReader) handleDataPacket(route *peerRoute, h header, enc []byte) { | func (r *connReader) handleDataPacket(peer *RemotePeer, h header, enc []byte) { | ||||||
| 	if !route.Up { | 	if !peer.Up { | ||||||
| 		r.logf("Not connected (recv).") | 		r.logf("Not connected (recv).") | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	data, err := decryptDataPacket(route, h, enc, r.decBuf) | 	data, err := decryptDataPacket(peer, h, enc, r.decBuf) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		r.logf("Failed to decrypt data packet: %v", err) | 		r.logf("Failed to decrypt data packet: %v", err) | ||||||
| 		return | 		return | ||||||
| @@ -131,11 +121,11 @@ func (r *connReader) handleDataPacket(route *peerRoute, h header, enc []byte) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	destRoute := r.routes[h.DestIP].Load() | 	destPeer := r.peers[h.DestIP].Load() | ||||||
| 	if !destRoute.Up { | 	if !destPeer.Up { | ||||||
| 		r.logf("Not connected (relay): %d", destRoute.IP) | 		r.logf("Not connected (relay): %d", destPeer.IP) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	r.sender.SendEncryptedDataPacket(data, destRoute) | 	r.sender.SendEncryptedDataPacket(data, destPeer) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package peer | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"crypto/rand" | ||||||
| 	"net/netip" | 	"net/netip" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"sync/atomic" | 	"sync/atomic" | ||||||
| @@ -19,14 +20,14 @@ func (w *mockIfWriter) Write(b []byte) (int, error) { | |||||||
|  |  | ||||||
| type mockEncryptedPacket struct { | type mockEncryptedPacket struct { | ||||||
| 	Packet []byte | 	Packet []byte | ||||||
| 	Route  *peerRoute | 	Route  *RemotePeer | ||||||
| } | } | ||||||
|  |  | ||||||
| type mockEncryptedPacketSender struct { | type mockEncryptedPacketSender struct { | ||||||
| 	Sent []mockEncryptedPacket | 	Sent []mockEncryptedPacket | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *mockEncryptedPacketSender) SendEncryptedDataPacket(pkt []byte, route *peerRoute) { | func (m *mockEncryptedPacketSender) SendEncryptedDataPacket(pkt []byte, route *RemotePeer) { | ||||||
| 	m.Sent = append(m.Sent, mockEncryptedPacket{ | 	m.Sent = append(m.Sent, mockEncryptedPacket{ | ||||||
| 		Packet: bytes.Clone(pkt), | 		Packet: bytes.Clone(pkt), | ||||||
| 		Route:  route, | 		Route:  route, | ||||||
| @@ -65,8 +66,8 @@ type connReaderTestHarness struct { | |||||||
| 	R            *connReader | 	R            *connReader | ||||||
| 	WRemote      *connWriter | 	WRemote      *connWriter | ||||||
| 	WRelayRemote *connWriter | 	WRelayRemote *connWriter | ||||||
| 	Remote       *peerRoute | 	Remote       *RemotePeer | ||||||
| 	RelayRemote  *peerRoute | 	RelayRemote  *RemotePeer | ||||||
| 	IFace        *mockIfWriter | 	IFace        *mockIfWriter | ||||||
| 	Sender       *mockEncryptedPacketSender | 	Sender       *mockEncryptedPacketSender | ||||||
| 	Super        *mockControlMsgHandler | 	Super        *mockControlMsgHandler | ||||||
| @@ -75,10 +76,10 @@ type connReaderTestHarness struct { | |||||||
| // Peer 2 is indirect, peer 3 is direct. | // Peer 2 is indirect, peer 3 is direct. | ||||||
| func newConnReadeTestHarness() (h connReaderTestHarness) { | func newConnReadeTestHarness() (h connReaderTestHarness) { | ||||||
| 	pipe := newUDPPipe() | 	pipe := newUDPPipe() | ||||||
| 	routes := [256]*atomic.Pointer[peerRoute]{} | 	routes := [256]*atomic.Pointer[RemotePeer]{} | ||||||
| 	for i := range routes { | 	for i := range routes { | ||||||
| 		routes[i] = &atomic.Pointer[peerRoute]{} | 		routes[i] = &atomic.Pointer[RemotePeer]{} | ||||||
| 		routes[i].Store(&peerRoute{}) | 		routes[i].Store(&RemotePeer{}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	local, remote, relayLocal, relayRemote := testConnWriter_getTestRoutes() | 	local, remote, relayLocal, relayRemote := testConnWriter_getTestRoutes() | ||||||
| @@ -255,8 +256,6 @@ func TestConnReader_handleControlPacket_duplicate(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| /* |  | ||||||
|  |  | ||||||
| // Testing that we can receive a data packet. | // Testing that we can receive a data packet. | ||||||
| func TestConnReader_handleDataPacket(t *testing.T) { | func TestConnReader_handleDataPacket(t *testing.T) { | ||||||
| 	h := newConnReadeTestHarness() | 	h := newConnReadeTestHarness() | ||||||
| @@ -285,7 +284,7 @@ func TestConnReader_handleDataPacket_routeDown(t *testing.T) { | |||||||
| 	rand.Read(pkt) | 	rand.Read(pkt) | ||||||
|  |  | ||||||
| 	h.WRemote.SendDataPacket(pkt, h.Remote) | 	h.WRemote.SendDataPacket(pkt, h.Remote) | ||||||
| 	route := h.R.routes[2].Load() | 	route := h.R.peers[2].Load() | ||||||
| 	route.Up = false | 	route.Up = false | ||||||
|  |  | ||||||
| 	h.R.handleNextPacket() | 	h.R.handleNextPacket() | ||||||
| @@ -294,9 +293,61 @@ func TestConnReader_handleDataPacket_routeDown(t *testing.T) { | |||||||
| 		t.Fatal(h.IFace.Written) | 		t.Fatal(h.IFace.Written) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| */ |  | ||||||
| // Testing that a duplicate data packet is ignored. | // Testing that a duplicate data packet is ignored. | ||||||
|  | func TestConnReader_handleDataPacket_duplicate(t *testing.T) { | ||||||
|  | 	h := newConnReadeTestHarness() | ||||||
|  |  | ||||||
| // Testing that we send a relayed data packet. | 	pkt := make([]byte, 123) | ||||||
|  |  | ||||||
| // Testing that a relayed data packet is ignored if destination isn't up. | 	h.WRemote.SendDataPacket(pkt, h.Remote) | ||||||
|  | 	*h.Remote.Counter = *h.Remote.Counter - 1 | ||||||
|  | 	h.WRemote.SendDataPacket(pkt, h.Remote) | ||||||
|  |  | ||||||
|  | 	h.R.handleNextPacket() | ||||||
|  | 	h.R.handleNextPacket() | ||||||
|  |  | ||||||
|  | 	if len(h.IFace.Written) != 1 { | ||||||
|  | 		t.Fatal(h.IFace.Written) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !bytes.Equal(pkt, h.IFace.Written[0]) { | ||||||
|  | 		t.Fatal(h.IFace.Written) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Testing that we can relay a data packet. | ||||||
|  | func TestConnReader_handleDataPacket_relay(t *testing.T) { | ||||||
|  | 	h := newConnReadeTestHarness() | ||||||
|  |  | ||||||
|  | 	pkt := make([]byte, 1024) | ||||||
|  | 	rand.Read(pkt) | ||||||
|  |  | ||||||
|  | 	h.RelayRemote.IP = 3 | ||||||
|  | 	h.WRemote.RelayDataPacket(pkt, h.RelayRemote, h.Remote) | ||||||
|  | 	h.R.handleNextPacket() | ||||||
|  |  | ||||||
|  | 	if len(h.Sender.Sent) != 1 { | ||||||
|  | 		t.Fatal(h.Sender.Sent) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Testing that we drop a relayed packet if destination is down. | ||||||
|  | func TestConnReader_handleDataPacket_relayDown(t *testing.T) { | ||||||
|  | 	h := newConnReadeTestHarness() | ||||||
|  |  | ||||||
|  | 	pkt := make([]byte, 1024) | ||||||
|  | 	rand.Read(pkt) | ||||||
|  |  | ||||||
|  | 	h.RelayRemote.IP = 3 | ||||||
|  | 	relay := h.R.peers[3].Load() | ||||||
|  | 	relay.Up = false | ||||||
|  |  | ||||||
|  | 	h.WRemote.RelayDataPacket(pkt, h.RelayRemote, h.Remote) | ||||||
|  | 	h.R.handleNextPacket() | ||||||
|  |  | ||||||
|  | 	if len(h.Sender.Sent) != 0 { | ||||||
|  | 		t.Fatal(h.Sender.Sent) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -37,29 +37,29 @@ func newConnWriter(conn udpWriter, localIP byte) *connWriter { | |||||||
| } | } | ||||||
|  |  | ||||||
| // Not safe for concurrent use. Should only be called by supervisor. | // Not safe for concurrent use. Should only be called by supervisor. | ||||||
| func (w *connWriter) SendControlPacket(pkt marshaller, route *peerRoute) { | func (w *connWriter) SendControlPacket(pkt marshaller, peer *RemotePeer) { | ||||||
| 	enc := encryptControlPacket(w.localIP, route, pkt, w.cBuf1, w.cBuf2) | 	enc := encryptControlPacket(w.localIP, peer, pkt, w.cBuf1, w.cBuf2) | ||||||
| 	w.writeTo(enc, route.RemoteAddr) | 	w.writeTo(enc, peer.DirectAddr) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Relay control packet. Route must not be nil. | // Relay control packet. Peer must not be nil. | ||||||
| func (w *connWriter) RelayControlPacket(pkt marshaller, route, relay *peerRoute) { | func (w *connWriter) RelayControlPacket(pkt marshaller, peer, relay *RemotePeer) { | ||||||
| 	enc := encryptControlPacket(w.localIP, route, pkt, w.cBuf1, w.cBuf2) | 	enc := encryptControlPacket(w.localIP, peer, pkt, w.cBuf1, w.cBuf2) | ||||||
| 	enc = encryptDataPacket(w.localIP, route.IP, relay, enc, w.cBuf1) | 	enc = encryptDataPacket(w.localIP, peer.IP, relay, enc, w.cBuf1) | ||||||
| 	w.writeTo(enc, relay.RemoteAddr) | 	w.writeTo(enc, relay.DirectAddr) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Not safe for concurrent use. Should only be called by ifReader. | // Not safe for concurrent use. Should only be called by ifReader. | ||||||
| func (w *connWriter) SendDataPacket(pkt []byte, route *peerRoute) { | func (w *connWriter) SendDataPacket(pkt []byte, peer *RemotePeer) { | ||||||
| 	enc := encryptDataPacket(w.localIP, route.IP, route, pkt, w.dBuf1) | 	enc := encryptDataPacket(w.localIP, peer.IP, peer, pkt, w.dBuf1) | ||||||
| 	w.writeTo(enc, route.RemoteAddr) | 	w.writeTo(enc, peer.DirectAddr) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Relay a data packet. Route must not be nil. | // Relay a data packet. Peer must not be nil. | ||||||
| func (w *connWriter) RelayDataPacket(pkt []byte, route, relay *peerRoute) { | func (w *connWriter) RelayDataPacket(pkt []byte, peer, relay *RemotePeer) { | ||||||
| 	enc := encryptDataPacket(w.localIP, route.IP, route, pkt, w.dBuf1) | 	enc := encryptDataPacket(w.localIP, peer.IP, peer, pkt, w.dBuf1) | ||||||
| 	enc = encryptDataPacket(w.localIP, route.IP, relay, enc, w.dBuf2) | 	enc = encryptDataPacket(w.localIP, peer.IP, relay, enc, w.dBuf2) | ||||||
| 	w.writeTo(enc, relay.RemoteAddr) | 	w.writeTo(enc, relay.DirectAddr) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Safe for concurrent use. Should only be called by connReader. | // Safe for concurrent use. Should only be called by connReader. | ||||||
| @@ -67,8 +67,8 @@ func (w *connWriter) RelayDataPacket(pkt []byte, route, relay *peerRoute) { | |||||||
| // This function will send pkt to the peer directly. This is used when a peer | // This function will send pkt to the peer directly. This is used when a peer | ||||||
| // is acting as a relay and is forwarding already encrypted data for another | // is acting as a relay and is forwarding already encrypted data for another | ||||||
| // peer. | // peer. | ||||||
| func (w *connWriter) SendEncryptedDataPacket(pkt []byte, route *peerRoute) { | func (w *connWriter) SendEncryptedDataPacket(pkt []byte, peer *RemotePeer) { | ||||||
| 	w.writeTo(pkt, route.RemoteAddr) | 	w.writeTo(pkt, peer.DirectAddr) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (w *connWriter) writeTo(packet []byte, addr netip.AddrPort) { | func (w *connWriter) writeTo(packet []byte, addr netip.AddrPort) { | ||||||
|   | |||||||
| @@ -43,46 +43,46 @@ func (p testPacket) Marshal(b []byte) []byte { | |||||||
|  |  | ||||||
| // ---------------------------------------------------------------------------- | // ---------------------------------------------------------------------------- | ||||||
|  |  | ||||||
| func testConnWriter_getTestRoutes() (local, remote, relayLocal, relayRemote *peerRoute) { | func testConnWriter_getTestRoutes() (local, remote, relayLocal, relayRemote *RemotePeer) { | ||||||
| 	localKeys := generateKeys() | 	localKeys := generateKeys() | ||||||
| 	remoteKeys := generateKeys() | 	remoteKeys := generateKeys() | ||||||
|  |  | ||||||
| 	local = newPeerRoute(2) | 	local = NewRemotePeer(2) | ||||||
| 	local.Up = true | 	local.Up = true | ||||||
| 	local.Relay = false | 	local.Relay = false | ||||||
| 	local.PubSignKey = remoteKeys.PubSignKey | 	local.PubSignKey = remoteKeys.PubSignKey | ||||||
| 	local.ControlCipher = newControlCipher(localKeys.PrivKey, remoteKeys.PubKey) | 	local.ControlCipher = newControlCipher(localKeys.PrivKey, remoteKeys.PubKey) | ||||||
| 	local.DataCipher = newDataCipher() | 	local.DataCipher = newDataCipher() | ||||||
| 	local.RemoteAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 2}), 100) | 	local.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 2}), 100) | ||||||
|  |  | ||||||
| 	remote = newPeerRoute(1) | 	remote = NewRemotePeer(1) | ||||||
| 	remote.Up = true | 	remote.Up = true | ||||||
| 	remote.Relay = false | 	remote.Relay = false | ||||||
| 	remote.PubSignKey = localKeys.PubSignKey | 	remote.PubSignKey = localKeys.PubSignKey | ||||||
| 	remote.ControlCipher = newControlCipher(remoteKeys.PrivKey, localKeys.PubKey) | 	remote.ControlCipher = newControlCipher(remoteKeys.PrivKey, localKeys.PubKey) | ||||||
| 	remote.DataCipher = local.DataCipher | 	remote.DataCipher = local.DataCipher | ||||||
| 	remote.RemoteAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 100) | 	remote.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 100) | ||||||
|  |  | ||||||
| 	rLocalKeys := generateKeys() | 	rLocalKeys := generateKeys() | ||||||
| 	rRemoteKeys := generateKeys() | 	rRemoteKeys := generateKeys() | ||||||
|  |  | ||||||
| 	relayLocal = newPeerRoute(3) | 	relayLocal = NewRemotePeer(3) | ||||||
| 	relayLocal.Up = true | 	relayLocal.Up = true | ||||||
| 	relayLocal.Relay = true | 	relayLocal.Relay = true | ||||||
| 	relayLocal.Direct = true | 	relayLocal.Direct = true | ||||||
| 	relayLocal.PubSignKey = rRemoteKeys.PubSignKey | 	relayLocal.PubSignKey = rRemoteKeys.PubSignKey | ||||||
| 	relayLocal.ControlCipher = newControlCipher(rLocalKeys.PrivKey, rRemoteKeys.PubKey) | 	relayLocal.ControlCipher = newControlCipher(rLocalKeys.PrivKey, rRemoteKeys.PubKey) | ||||||
| 	relayLocal.DataCipher = newDataCipher() | 	relayLocal.DataCipher = newDataCipher() | ||||||
| 	relayLocal.RemoteAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 3}), 100) | 	relayLocal.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 3}), 100) | ||||||
|  |  | ||||||
| 	relayRemote = newPeerRoute(1) | 	relayRemote = NewRemotePeer(1) | ||||||
| 	relayRemote.Up = true | 	relayRemote.Up = true | ||||||
| 	relayRemote.Relay = false | 	relayRemote.Relay = false | ||||||
| 	relayRemote.Direct = true | 	relayRemote.Direct = true | ||||||
| 	relayRemote.PubSignKey = rLocalKeys.PubSignKey | 	relayRemote.PubSignKey = rLocalKeys.PubSignKey | ||||||
| 	relayRemote.ControlCipher = newControlCipher(rRemoteKeys.PrivKey, rLocalKeys.PubKey) | 	relayRemote.ControlCipher = newControlCipher(rRemoteKeys.PrivKey, rLocalKeys.PubKey) | ||||||
| 	relayRemote.DataCipher = relayLocal.DataCipher | 	relayRemote.DataCipher = relayLocal.DataCipher | ||||||
| 	relayRemote.RemoteAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 100) | 	relayRemote.DirectAddr = netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 1, 1, 1}), 100) | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @@ -104,7 +104,7 @@ func TestConnWriter_SendControlPacket_direct(t *testing.T) { | |||||||
| 		t.Fatal(out) | 		t.Fatal(out) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if out[0].Addr != route.RemoteAddr { | 	if out[0].Addr != route.DirectAddr { | ||||||
| 		t.Fatal(out[0]) | 		t.Fatal(out[0]) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -132,7 +132,7 @@ func TestConnWriter_RelayControlPacket_relay(t *testing.T) { | |||||||
| 		t.Fatal(out) | 		t.Fatal(out) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if out[0].Addr != relay.RemoteAddr { | 	if out[0].Addr != relay.DirectAddr { | ||||||
| 		t.Fatal(out[0]) | 		t.Fatal(out[0]) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -167,7 +167,7 @@ func TestConnWriter_SendDataPacket_direct(t *testing.T) { | |||||||
| 		t.Fatal(out) | 		t.Fatal(out) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if out[0].Addr != route.RemoteAddr { | 	if out[0].Addr != route.DirectAddr { | ||||||
| 		t.Fatal(out[0]) | 		t.Fatal(out[0]) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -196,7 +196,7 @@ func TestConnWriter_RelayDataPacket_relay(t *testing.T) { | |||||||
| 		t.Fatal(out) | 		t.Fatal(out) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if out[0].Addr != relay.RemoteAddr { | 	if out[0].Addr != relay.DirectAddr { | ||||||
| 		t.Fatal(out[0]) | 		t.Fatal(out[0]) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -230,7 +230,7 @@ func TestConnWriter_SendEncryptedDataPacket(t *testing.T) { | |||||||
| 		t.Fatal(out) | 		t.Fatal(out) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if out[0].Addr != route.RemoteAddr { | 	if out[0].Addr != route.DirectAddr { | ||||||
| 		t.Fatal(out[0]) | 		t.Fatal(out[0]) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,40 +33,40 @@ func generateKeys() cryptoKeys { | |||||||
|  |  | ||||||
| // ---------------------------------------------------------------------------- | // ---------------------------------------------------------------------------- | ||||||
|  |  | ||||||
| // Route must have a ControlCipher. | // Peer must have a ControlCipher. | ||||||
| func encryptControlPacket( | func encryptControlPacket( | ||||||
| 	localIP byte, | 	localIP byte, | ||||||
| 	route *peerRoute, | 	peer *RemotePeer, | ||||||
| 	pkt marshaller, | 	pkt marshaller, | ||||||
| 	tmp []byte, | 	tmp []byte, | ||||||
| 	out []byte, | 	out []byte, | ||||||
| ) []byte { | ) []byte { | ||||||
| 	h := header{ | 	h := header{ | ||||||
| 		StreamID: controlStreamID, | 		StreamID: controlStreamID, | ||||||
| 		Counter:  atomic.AddUint64(route.Counter, 1), | 		Counter:  atomic.AddUint64(peer.Counter, 1), | ||||||
| 		SourceIP: localIP, | 		SourceIP: localIP, | ||||||
| 		DestIP:   route.IP, | 		DestIP:   peer.IP, | ||||||
| 	} | 	} | ||||||
| 	tmp = pkt.Marshal(tmp) | 	tmp = pkt.Marshal(tmp) | ||||||
| 	return route.ControlCipher.Encrypt(h, tmp, out) | 	return peer.ControlCipher.Encrypt(h, tmp, out) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Returns a controlMsg[PacketType]. Route must have ControlCipher. | // Returns a controlMsg[PacketType]. Peer must have a non-nil ControlCipher. | ||||||
| // | // | ||||||
| // This function also drops packets with duplicate sequence numbers. | // This function also drops packets with duplicate sequence numbers. | ||||||
| func decryptControlPacket( | func decryptControlPacket( | ||||||
| 	route *peerRoute, | 	peer *RemotePeer, | ||||||
| 	fromAddr netip.AddrPort, | 	fromAddr netip.AddrPort, | ||||||
| 	h header, | 	h header, | ||||||
| 	encrypted []byte, | 	encrypted []byte, | ||||||
| 	tmp []byte, | 	tmp []byte, | ||||||
| ) (any, error) { | ) (any, error) { | ||||||
| 	out, ok := route.ControlCipher.Decrypt(encrypted, tmp) | 	out, ok := peer.ControlCipher.Decrypt(encrypted, tmp) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, errDecryptionFailed | 		return nil, errDecryptionFailed | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if route.DupCheck.IsDup(h.Counter) { | 	if peer.DupCheck.IsDup(h.Counter) { | ||||||
| 		return nil, errDuplicateSeqNum | 		return nil, errDuplicateSeqNum | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -83,31 +83,32 @@ func decryptControlPacket( | |||||||
| func encryptDataPacket( | func encryptDataPacket( | ||||||
| 	localIP byte, | 	localIP byte, | ||||||
| 	destIP byte, | 	destIP byte, | ||||||
| 	route *peerRoute, | 	peer *RemotePeer, | ||||||
| 	data []byte, | 	data []byte, | ||||||
| 	out []byte, | 	out []byte, | ||||||
| ) []byte { | ) []byte { | ||||||
| 	h := header{ | 	h := header{ | ||||||
| 		StreamID: dataStreamID, | 		StreamID: dataStreamID, | ||||||
| 		Counter:  atomic.AddUint64(route.Counter, 1), | 		Counter:  atomic.AddUint64(peer.Counter, 1), | ||||||
| 		SourceIP: localIP, | 		SourceIP: localIP, | ||||||
| 		DestIP:   destIP, | 		DestIP:   destIP, | ||||||
| 	} | 	} | ||||||
| 	return route.DataCipher.Encrypt(h, data, out) | 	return peer.DataCipher.Encrypt(h, data, out) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Decrypts and de-dups incoming data packets. | ||||||
| func decryptDataPacket( | func decryptDataPacket( | ||||||
| 	route *peerRoute, | 	peer *RemotePeer, | ||||||
| 	h header, | 	h header, | ||||||
| 	encrypted []byte, | 	encrypted []byte, | ||||||
| 	out []byte, | 	out []byte, | ||||||
| ) ([]byte, error) { | ) ([]byte, error) { | ||||||
| 	dec, ok := route.DataCipher.Decrypt(encrypted, out) | 	dec, ok := peer.DataCipher.Decrypt(encrypted, out) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, errDecryptionFailed | 		return nil, errDecryptionFailed | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if route.DupCheck.IsDup(h.Counter) { | 	if peer.DupCheck.IsDup(h.Counter) { | ||||||
| 		return nil, errDuplicateSeqNum | 		return nil, errDuplicateSeqNum | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,16 +9,16 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func newRoutePairForTesting() (*peerRoute, *peerRoute) { | func newRoutePairForTesting() (*RemotePeer, *RemotePeer) { | ||||||
| 	keys1 := generateKeys() | 	keys1 := generateKeys() | ||||||
| 	keys2 := generateKeys() | 	keys2 := generateKeys() | ||||||
|  |  | ||||||
| 	r1 := newPeerRoute(1) | 	r1 := NewRemotePeer(1) | ||||||
| 	r1.PubSignKey = keys1.PubSignKey | 	r1.PubSignKey = keys1.PubSignKey | ||||||
| 	r1.ControlCipher = newControlCipher(keys1.PrivKey, keys2.PubKey) | 	r1.ControlCipher = newControlCipher(keys1.PrivKey, keys2.PubKey) | ||||||
| 	r1.DataCipher = newDataCipher() | 	r1.DataCipher = newDataCipher() | ||||||
|  |  | ||||||
| 	r2 := newPeerRoute(2) | 	r2 := NewRemotePeer(2) | ||||||
| 	r2.PubSignKey = keys2.PubSignKey | 	r2.PubSignKey = keys2.PubSignKey | ||||||
| 	r2.ControlCipher = newControlCipher(keys2.PrivKey, keys1.PubKey) | 	r2.ControlCipher = newControlCipher(keys2.PrivKey, keys1.PubKey) | ||||||
| 	r2.DataCipher = r1.DataCipher | 	r2.DataCipher = r1.DataCipher | ||||||
| @@ -40,10 +40,7 @@ func TestDecryptControlPacket(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | ||||||
| 	h, ok := parseHeader(enc) | 	h := parseHeader(enc) | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatal(h, ok) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	iMsg, err := decryptControlPacket(r2, netip.AddrPort{}, h, enc, tmp) | 	iMsg, err := decryptControlPacket(r2, netip.AddrPort{}, h, enc, tmp) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -74,10 +71,7 @@ func TestDecryptControlPacket_decryptionFailed(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | ||||||
| 	h, ok := parseHeader(enc) | 	h := parseHeader(enc) | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatal(h, ok) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for i := range enc { | 	for i := range enc { | ||||||
| 		x := bytes.Clone(enc) | 		x := bytes.Clone(enc) | ||||||
| @@ -103,10 +97,7 @@ func TestDecryptControlPacket_duplicate(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | ||||||
| 	h, ok := parseHeader(enc) | 	h := parseHeader(enc) | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatal(h, ok) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if _, err := decryptControlPacket(r2, netip.AddrPort{}, h, enc, tmp); err != nil { | 	if _, err := decryptControlPacket(r2, netip.AddrPort{}, h, enc, tmp); err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| @@ -128,10 +119,7 @@ func TestDecryptControlPacket_invalidPacket(t *testing.T) { | |||||||
| 	in := testPacket("hello!") | 	in := testPacket("hello!") | ||||||
|  |  | ||||||
| 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | 	enc := encryptControlPacket(r1.IP, r2, in, tmp, out) | ||||||
| 	h, ok := parseHeader(enc) | 	h := parseHeader(enc) | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatal(h, ok) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	_, err := decryptControlPacket(r2, netip.AddrPort{}, h, enc, tmp) | 	_, err := decryptControlPacket(r2, netip.AddrPort{}, h, enc, tmp) | ||||||
| 	if !errors.Is(err, errUnknownPacketType) { | 	if !errors.Is(err, errUnknownPacketType) { | ||||||
| @@ -149,10 +137,7 @@ func TestDecryptDataPacket(t *testing.T) { | |||||||
| 	rand.Read(data) | 	rand.Read(data) | ||||||
|  |  | ||||||
| 	enc := encryptDataPacket(r1.IP, r2.IP, r2, data, out) | 	enc := encryptDataPacket(r1.IP, r2.IP, r2, data, out) | ||||||
| 	h, ok := parseHeader(enc) | 	h := parseHeader(enc) | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatal(h, ok) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	out, err := decryptDataPacket(r1, h, bytes.Clone(enc), out) | 	out, err := decryptDataPacket(r1, h, bytes.Clone(enc), out) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -174,10 +159,7 @@ func TestDecryptDataPacket_incorrectCipher(t *testing.T) { | |||||||
| 	rand.Read(data) | 	rand.Read(data) | ||||||
|  |  | ||||||
| 	enc := encryptDataPacket(r1.IP, r2.IP, r2, data, bytes.Clone(out)) | 	enc := encryptDataPacket(r1.IP, r2.IP, r2, data, bytes.Clone(out)) | ||||||
| 	h, ok := parseHeader(enc) | 	h := parseHeader(enc) | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatal(h, ok) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	r1.DataCipher = newDataCipher() | 	r1.DataCipher = newDataCipher() | ||||||
| 	_, err := decryptDataPacket(r1, h, enc, bytes.Clone(out)) | 	_, err := decryptDataPacket(r1, h, enc, bytes.Clone(out)) | ||||||
| @@ -196,10 +178,7 @@ func TestDecryptDataPacket_duplicate(t *testing.T) { | |||||||
| 	rand.Read(data) | 	rand.Read(data) | ||||||
|  |  | ||||||
| 	enc := encryptDataPacket(r1.IP, r2.IP, r2, data, bytes.Clone(out)) | 	enc := encryptDataPacket(r1.IP, r2.IP, r2, data, bytes.Clone(out)) | ||||||
| 	h, ok := parseHeader(enc) | 	h := parseHeader(enc) | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatal(h, ok) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	_, err := decryptDataPacket(r1, h, enc, bytes.Clone(out)) | 	_, err := decryptDataPacket(r1, h, enc, bytes.Clone(out)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -20,16 +20,13 @@ type header struct { | |||||||
| 	Counter  uint64 // Init with time.Now().Unix << 30 to ensure monotonic. | 	Counter  uint64 // Init with time.Now().Unix << 30 to ensure monotonic. | ||||||
| } | } | ||||||
|  |  | ||||||
| func parseHeader(b []byte) (h header, ok bool) { | func parseHeader(b []byte) (h header) { | ||||||
| 	if len(b) < headerSize { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	h.Version = b[0] | 	h.Version = b[0] | ||||||
| 	h.StreamID = b[1] | 	h.StreamID = b[1] | ||||||
| 	h.SourceIP = b[2] | 	h.SourceIP = b[2] | ||||||
| 	h.DestIP = b[3] | 	h.DestIP = b[3] | ||||||
| 	h.Counter = *(*uint64)(unsafe.Pointer(&b[4])) | 	h.Counter = *(*uint64)(unsafe.Pointer(&b[4])) | ||||||
| 	return h, true | 	return h | ||||||
| } | } | ||||||
|  |  | ||||||
| func (h *header) Parse(b []byte) { | func (h *header) Parse(b []byte) { | ||||||
|   | |||||||
| @@ -8,20 +8,20 @@ import ( | |||||||
|  |  | ||||||
| type ifReader struct { | type ifReader struct { | ||||||
| 	iface  io.Reader | 	iface  io.Reader | ||||||
| 	routes [256]*atomic.Pointer[peerRoute] | 	peers  [256]*atomic.Pointer[RemotePeer] | ||||||
| 	relay  *atomic.Pointer[peerRoute] | 	relay  *atomic.Pointer[RemotePeer] | ||||||
| 	sender dataPacketSender | 	sender dataPacketSender | ||||||
| } | } | ||||||
|  |  | ||||||
| func newIFReader( | func newIFReader( | ||||||
| 	iface io.Reader, | 	iface io.Reader, | ||||||
| 	routes [256]*atomic.Pointer[peerRoute], | 	peers [256]*atomic.Pointer[RemotePeer], | ||||||
| 	relay *atomic.Pointer[peerRoute], | 	relay *atomic.Pointer[RemotePeer], | ||||||
| 	sender dataPacketSender, | 	sender dataPacketSender, | ||||||
| ) *ifReader { | ) *ifReader { | ||||||
| 	return &ifReader{ | 	return &ifReader{ | ||||||
| 		iface:  iface, | 		iface:  iface, | ||||||
| 		routes: routes, | 		peers:  peers, | ||||||
| 		relay:  relay, | 		relay:  relay, | ||||||
| 		sender: sender, | 		sender: sender, | ||||||
| 	} | 	} | ||||||
| @@ -43,20 +43,20 @@ func (r *ifReader) Run() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (r *ifReader) sendPacket(pkt []byte, remoteIP byte) { | func (r *ifReader) sendPacket(pkt []byte, remoteIP byte) { | ||||||
| 	route := r.routes[remoteIP].Load() | 	peer := r.peers[remoteIP].Load() | ||||||
| 	if !route.Up { | 	if !peer.Up { | ||||||
| 		log.Printf("Route not connected: %d", remoteIP) | 		log.Printf("Peer not connected: %d", remoteIP) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Direct path => early return. | 	// Direct path => early return. | ||||||
| 	if route.Direct { | 	if peer.Direct { | ||||||
| 		r.sender.SendDataPacket(pkt, route) | 		r.sender.SendDataPacket(pkt, peer) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if relay := r.relay.Load(); relay != nil && relay.Up { | 	if relay := r.relay.Load(); relay != nil && relay.Up { | ||||||
| 		r.sender.RelayDataPacket(pkt, route, relay) | 		r.sender.RelayDataPacket(pkt, peer, relay) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import ( | |||||||
|  |  | ||||||
| // Test that we parse IPv4 packets correctly. | // Test that we parse IPv4 packets correctly. | ||||||
| func TestIFReader_parsePacket_ipv4(t *testing.T) { | func TestIFReader_parsePacket_ipv4(t *testing.T) { | ||||||
| 	r := newIFReader(nil, [256]*atomic.Pointer[peerRoute]{}, nil, nil) | 	r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) | ||||||
|  |  | ||||||
| 	pkt := make([]byte, 1234) | 	pkt := make([]byte, 1234) | ||||||
| 	pkt[0] = 4 << 4 | 	pkt[0] = 4 << 4 | ||||||
| @@ -23,7 +23,7 @@ func TestIFReader_parsePacket_ipv4(t *testing.T) { | |||||||
|  |  | ||||||
| // Test that we parse IPv6 packets correctly. | // Test that we parse IPv6 packets correctly. | ||||||
| func TestIFReader_parsePacket_ipv6(t *testing.T) { | func TestIFReader_parsePacket_ipv6(t *testing.T) { | ||||||
| 	r := newIFReader(nil, [256]*atomic.Pointer[peerRoute]{}, nil, nil) | 	r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) | ||||||
|  |  | ||||||
| 	pkt := make([]byte, 1234) | 	pkt := make([]byte, 1234) | ||||||
| 	pkt[0] = 6 << 4 | 	pkt[0] = 6 << 4 | ||||||
| @@ -36,7 +36,7 @@ func TestIFReader_parsePacket_ipv6(t *testing.T) { | |||||||
|  |  | ||||||
| // Test that empty packets work as expected. | // Test that empty packets work as expected. | ||||||
| func TestIFReader_parsePacket_emptyPacket(t *testing.T) { | func TestIFReader_parsePacket_emptyPacket(t *testing.T) { | ||||||
| 	r := newIFReader(nil, [256]*atomic.Pointer[peerRoute]{}, nil, nil) | 	r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) | ||||||
|  |  | ||||||
| 	pkt := make([]byte, 0) | 	pkt := make([]byte, 0) | ||||||
| 	if ip, ok := r.parsePacket(pkt); ok { | 	if ip, ok := r.parsePacket(pkt); ok { | ||||||
| @@ -46,7 +46,7 @@ func TestIFReader_parsePacket_emptyPacket(t *testing.T) { | |||||||
|  |  | ||||||
| // Test that invalid IP versions fail. | // Test that invalid IP versions fail. | ||||||
| func TestIFReader_parsePacket_invalidIPVersion(t *testing.T) { | func TestIFReader_parsePacket_invalidIPVersion(t *testing.T) { | ||||||
| 	r := newIFReader(nil, [256]*atomic.Pointer[peerRoute]{}, nil, nil) | 	r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) | ||||||
|  |  | ||||||
| 	for i := byte(1); i < 16; i++ { | 	for i := byte(1); i < 16; i++ { | ||||||
| 		if i == 4 || i == 6 { | 		if i == 4 || i == 6 { | ||||||
| @@ -63,7 +63,7 @@ func TestIFReader_parsePacket_invalidIPVersion(t *testing.T) { | |||||||
|  |  | ||||||
| // Test that short IPv4 packets fail. | // Test that short IPv4 packets fail. | ||||||
| func TestIFReader_parsePacket_shortIPv4(t *testing.T) { | func TestIFReader_parsePacket_shortIPv4(t *testing.T) { | ||||||
| 	r := newIFReader(nil, [256]*atomic.Pointer[peerRoute]{}, nil, nil) | 	r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) | ||||||
|  |  | ||||||
| 	pkt := make([]byte, 19) | 	pkt := make([]byte, 19) | ||||||
| 	pkt[0] = 4 << 4 | 	pkt[0] = 4 << 4 | ||||||
| @@ -75,7 +75,7 @@ func TestIFReader_parsePacket_shortIPv4(t *testing.T) { | |||||||
|  |  | ||||||
| // Test that short IPv6 packets fail. | // Test that short IPv6 packets fail. | ||||||
| func TestIFReader_parsePacket_shortIPv6(t *testing.T) { | func TestIFReader_parsePacket_shortIPv6(t *testing.T) { | ||||||
| 	r := newIFReader(nil, [256]*atomic.Pointer[peerRoute]{}, nil, nil) | 	r := newIFReader(nil, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) | ||||||
|  |  | ||||||
| 	pkt := make([]byte, 39) | 	pkt := make([]byte, 39) | ||||||
| 	pkt[0] = 6 << 4 | 	pkt[0] = 6 << 4 | ||||||
| @@ -88,7 +88,7 @@ func TestIFReader_parsePacket_shortIPv6(t *testing.T) { | |||||||
| // Test that we can read a packet. | // Test that we can read a packet. | ||||||
| func TestIFReader_readNextpacket(t *testing.T) { | func TestIFReader_readNextpacket(t *testing.T) { | ||||||
| 	in, out := net.Pipe() | 	in, out := net.Pipe() | ||||||
| 	r := newIFReader(out, [256]*atomic.Pointer[peerRoute]{}, nil, nil) | 	r := newIFReader(out, [256]*atomic.Pointer[RemotePeer]{}, nil, nil) | ||||||
| 	defer in.Close() | 	defer in.Close() | ||||||
| 	defer out.Close() | 	defer out.Close() | ||||||
|  |  | ||||||
| @@ -105,22 +105,22 @@ func TestIFReader_readNextpacket(t *testing.T) { | |||||||
| type sentPacket struct { | type sentPacket struct { | ||||||
| 	Relayed bool | 	Relayed bool | ||||||
| 	Packet  []byte | 	Packet  []byte | ||||||
| 	Route   peerRoute | 	Route   RemotePeer | ||||||
| 	Relay   peerRoute | 	Relay   RemotePeer | ||||||
| } | } | ||||||
|  |  | ||||||
| type sendPacketTestHarness struct { | type sendPacketTestHarness struct { | ||||||
| 	Packets []sentPacket | 	Packets []sentPacket | ||||||
| } | } | ||||||
|  |  | ||||||
| func (h *sendPacketTestHarness) SendDataPacket(pkt []byte, route *peerRoute) { | func (h *sendPacketTestHarness) SendDataPacket(pkt []byte, route *RemotePeer) { | ||||||
| 	h.Packets = append(h.Packets, sentPacket{ | 	h.Packets = append(h.Packets, sentPacket{ | ||||||
| 		Packet: bytes.Clone(pkt), | 		Packet: bytes.Clone(pkt), | ||||||
| 		Route:  *route, | 		Route:  *route, | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (h *sendPacketTestHarness) RelayDataPacket(pkt []byte, route, relay *peerRoute) { | func (h *sendPacketTestHarness) RelayDataPacket(pkt []byte, route, relay *RemotePeer) { | ||||||
| 	h.Packets = append(h.Packets, sentPacket{ | 	h.Packets = append(h.Packets, sentPacket{ | ||||||
| 		Relayed: true, | 		Relayed: true, | ||||||
| 		Packet:  bytes.Clone(pkt), | 		Packet:  bytes.Clone(pkt), | ||||||
| @@ -132,12 +132,12 @@ func (h *sendPacketTestHarness) RelayDataPacket(pkt []byte, route, relay *peerRo | |||||||
| func newIFReaderForSendPacketTesting() (*ifReader, *sendPacketTestHarness) { | func newIFReaderForSendPacketTesting() (*ifReader, *sendPacketTestHarness) { | ||||||
| 	h := &sendPacketTestHarness{} | 	h := &sendPacketTestHarness{} | ||||||
|  |  | ||||||
| 	routes := [256]*atomic.Pointer[peerRoute]{} | 	routes := [256]*atomic.Pointer[RemotePeer]{} | ||||||
| 	for i := range routes { | 	for i := range routes { | ||||||
| 		routes[i] = &atomic.Pointer[peerRoute]{} | 		routes[i] = &atomic.Pointer[RemotePeer]{} | ||||||
| 		routes[i].Store(&peerRoute{}) | 		routes[i].Store(&RemotePeer{}) | ||||||
| 	} | 	} | ||||||
| 	relay := &atomic.Pointer[peerRoute]{} | 	relay := &atomic.Pointer[RemotePeer]{} | ||||||
| 	r := newIFReader(nil, routes, relay, h) | 	r := newIFReader(nil, routes, relay, h) | ||||||
| 	return r, h | 	return r, h | ||||||
| } | } | ||||||
| @@ -146,7 +146,7 @@ func newIFReaderForSendPacketTesting() (*ifReader, *sendPacketTestHarness) { | |||||||
| func TestIFReader_sendPacket_direct(t *testing.T) { | func TestIFReader_sendPacket_direct(t *testing.T) { | ||||||
| 	r, h := newIFReaderForSendPacketTesting() | 	r, h := newIFReaderForSendPacketTesting() | ||||||
|  |  | ||||||
| 	route := r.routes[2].Load() | 	route := r.peers[2].Load() | ||||||
| 	route.Up = true | 	route.Up = true | ||||||
| 	route.Direct = true | 	route.Direct = true | ||||||
|  |  | ||||||
| @@ -172,7 +172,7 @@ func TestIFReader_sendPacket_direct(t *testing.T) { | |||||||
| func TestIFReader_sendPacket_directNotUp(t *testing.T) { | func TestIFReader_sendPacket_directNotUp(t *testing.T) { | ||||||
| 	r, h := newIFReaderForSendPacketTesting() | 	r, h := newIFReaderForSendPacketTesting() | ||||||
|  |  | ||||||
| 	route := r.routes[2].Load() | 	route := r.peers[2].Load() | ||||||
| 	route.Direct = true | 	route.Direct = true | ||||||
|  |  | ||||||
| 	in := []byte("hello world") | 	in := []byte("hello world") | ||||||
| @@ -187,11 +187,11 @@ func TestIFReader_sendPacket_directNotUp(t *testing.T) { | |||||||
| func TestIFReader_sendPacket_relayed(t *testing.T) { | func TestIFReader_sendPacket_relayed(t *testing.T) { | ||||||
| 	r, h := newIFReaderForSendPacketTesting() | 	r, h := newIFReaderForSendPacketTesting() | ||||||
|  |  | ||||||
| 	route := r.routes[2].Load() | 	route := r.peers[2].Load() | ||||||
| 	route.Up = true | 	route.Up = true | ||||||
| 	route.Direct = false | 	route.Direct = false | ||||||
|  |  | ||||||
| 	relay := r.routes[3].Load() | 	relay := r.peers[3].Load() | ||||||
| 	r.relay.Store(relay) | 	r.relay.Store(relay) | ||||||
| 	relay.Up = true | 	relay.Up = true | ||||||
| 	relay.Direct = true | 	relay.Direct = true | ||||||
| @@ -219,7 +219,7 @@ func TestIFReader_sendPacket_relayed(t *testing.T) { | |||||||
| func TestIFReader_sendPacket_nilRealy(t *testing.T) { | func TestIFReader_sendPacket_nilRealy(t *testing.T) { | ||||||
| 	r, h := newIFReaderForSendPacketTesting() | 	r, h := newIFReaderForSendPacketTesting() | ||||||
|  |  | ||||||
| 	route := r.routes[2].Load() | 	route := r.peers[2].Load() | ||||||
| 	route.Up = true | 	route.Up = true | ||||||
| 	route.Direct = false | 	route.Direct = false | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,9 @@ | |||||||
| package peer | package peer | ||||||
|  |  | ||||||
| import "net/netip" | import ( | ||||||
|  | 	"net" | ||||||
|  | 	"net/netip" | ||||||
|  | ) | ||||||
|  |  | ||||||
| type udpReader interface { | type udpReader interface { | ||||||
| 	ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) | 	ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) | ||||||
| @@ -15,14 +18,18 @@ type marshaller interface { | |||||||
| } | } | ||||||
|  |  | ||||||
| type dataPacketSender interface { | type dataPacketSender interface { | ||||||
| 	SendDataPacket(pkt []byte, route *peerRoute) | 	SendDataPacket(pkt []byte, peer *RemotePeer) | ||||||
| 	RelayDataPacket(pkt []byte, route, relay *peerRoute) | 	RelayDataPacket(pkt []byte, peer, relay *RemotePeer) | ||||||
| } | } | ||||||
|  |  | ||||||
| type encryptedPacketSender interface { | type encryptedPacketSender interface { | ||||||
| 	SendEncryptedDataPacket(pkt []byte, route *peerRoute) | 	SendEncryptedDataPacket(pkt []byte, peer *RemotePeer) | ||||||
| } | } | ||||||
|  |  | ||||||
| type controlMsgHandler interface { | type controlMsgHandler interface { | ||||||
| 	HandleControlMsg(pkt any) | 	HandleControlMsg(pkt any) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type mcUDPWriter interface { | ||||||
|  | 	WriteToUDP([]byte, *net.UDPAddr) (int, error) | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										57
									
								
								peer/mcreader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								peer/mcreader.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | package peer | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"log" | ||||||
|  | 	"sync/atomic" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type mcReader struct { | ||||||
|  | 	conn  udpReader | ||||||
|  | 	super controlMsgHandler | ||||||
|  | 	peers [256]*atomic.Pointer[RemotePeer] | ||||||
|  |  | ||||||
|  | 	incoming []byte | ||||||
|  | 	buf      []byte | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newMCReader( | ||||||
|  | 	conn udpReader, | ||||||
|  | 	super controlMsgHandler, | ||||||
|  | 	peers [256]*atomic.Pointer[RemotePeer], | ||||||
|  | ) *mcReader { | ||||||
|  | 	return &mcReader{conn, super, peers, newBuf(), newBuf()} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *mcReader) Run() { | ||||||
|  | 	for { | ||||||
|  | 		r.handleNextPacket() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *mcReader) handleNextPacket() { | ||||||
|  | 	incoming := r.incoming[:bufferSize] | ||||||
|  | 	n, remoteAddr, err := r.conn.ReadFromUDPAddrPort(incoming) | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatalf("Failed to read from UDP multicast port: %v", err) | ||||||
|  | 	} | ||||||
|  | 	incoming = incoming[:n] | ||||||
|  |  | ||||||
|  | 	h, ok := headerFromLocalDiscoveryPacket(incoming) | ||||||
|  | 	if !ok { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	peer := r.peers[h.SourceIP].Load() | ||||||
|  | 	if peer == nil || peer.PubSignKey == nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !verifyLocalDiscoveryPacket(incoming, r.buf, peer.PubSignKey) { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	r.super.HandleControlMsg(controlMsg[localDiscoveryPacket]{ | ||||||
|  | 		SrcIP:   h.SourceIP, | ||||||
|  | 		SrcAddr: remoteAddr, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
| @@ -2,19 +2,10 @@ package peer | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"log" | 	"log" | ||||||
| 	"net" |  | ||||||
|  |  | ||||||
| 	"golang.org/x/crypto/nacl/sign" | 	"golang.org/x/crypto/nacl/sign" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ---------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| type mcUDPWriter interface { |  | ||||||
| 	WriteToUDP([]byte, *net.UDPAddr) (int, error) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ---------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| func createLocalDiscoveryPacket(localIP byte, signingKey []byte) []byte { | func createLocalDiscoveryPacket(localIP byte, signingKey []byte) []byte { | ||||||
| 	h := header{ | 	h := header{ | ||||||
| 		SourceIP: localIP, | 		SourceIP: localIP, | ||||||
|   | |||||||
| @@ -5,23 +5,23 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type peerRoute struct { | type RemotePeer struct { | ||||||
| 	IP            byte           // VPN IP of peer (last byte). | 	IP            byte           // VPN IP of peer (last byte). | ||||||
| 	Up            bool // True if data can be sent on the route. | 	Up            bool           // True if data can be sent on the peer. | ||||||
| 	Relay         bool           // True if the peer is a relay. | 	Relay         bool           // True if the peer is a relay. | ||||||
| 	Direct        bool           // True if this is a direct connection. | 	Direct        bool           // True if this is a direct connection. | ||||||
|  | 	DirectAddr    netip.AddrPort // Remote address if directly connected. | ||||||
| 	PubSignKey    []byte | 	PubSignKey    []byte | ||||||
| 	ControlCipher *controlCipher | 	ControlCipher *controlCipher | ||||||
| 	DataCipher    *dataCipher | 	DataCipher    *dataCipher | ||||||
| 	RemoteAddr    netip.AddrPort // Remote address if directly connected. |  | ||||||
|  |  | ||||||
| 	Counter  *uint64   // For sending to. Atomic access only. | 	Counter  *uint64   // For sending to. Atomic access only. | ||||||
| 	DupCheck *dupCheck // For receiving from. Not safe for concurrent use. | 	DupCheck *dupCheck // For receiving from. Not safe for concurrent use. | ||||||
| } | } | ||||||
|  |  | ||||||
| func newPeerRoute(ip byte) *peerRoute { | func NewRemotePeer(ip byte) *RemotePeer { | ||||||
| 	counter := uint64(time.Now().Unix()<<30 + 1) | 	counter := uint64(time.Now().Unix()<<30 + 1) | ||||||
| 	return &peerRoute{ | 	return &RemotePeer{ | ||||||
| 		IP:       ip, | 		IP:       ip, | ||||||
| 		Counter:  &counter, | 		Counter:  &counter, | ||||||
| 		DupCheck: newDupCheck(0), | 		DupCheck: newDupCheck(0), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user