wip: use atomic add for counters, added crypto
This commit is contained in:
		
							
								
								
									
										11
									
								
								node/conn.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								node/conn.go
									
									
									
									
									
								
							| @@ -4,9 +4,16 @@ import ( | |||||||
| 	"log" | 	"log" | ||||||
| 	"net" | 	"net" | ||||||
| 	"net/netip" | 	"net/netip" | ||||||
|  | 	"sync/atomic" | ||||||
| 	"vppn/fasttime" | 	"vppn/fasttime" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // TODO: | ||||||
|  | type connRouter interface { | ||||||
|  | 	Lookup(byte) *peer | ||||||
|  | 	Mediator() *peer | ||||||
|  | } | ||||||
|  |  | ||||||
| type connWriter struct { | type connWriter struct { | ||||||
| 	*net.UDPConn | 	*net.UDPConn | ||||||
| 	localIP  byte | 	localIP  byte | ||||||
| @@ -37,10 +44,8 @@ func (w *connWriter) WriteTo(remoteIP, packetType byte, data []byte) error { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	w.counters[remoteIP]++ |  | ||||||
|  |  | ||||||
| 	h := header{ | 	h := header{ | ||||||
| 		Counter:    w.counters[remoteIP], | 		Counter:    atomic.AddUint64(&w.counters[remoteIP], 1), | ||||||
| 		SourceIP:   w.localIP, | 		SourceIP:   w.localIP, | ||||||
| 		ViaIP:      0, | 		ViaIP:      0, | ||||||
| 		DestIP:     remoteIP, | 		DestIP:     remoteIP, | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								node/crypto.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								node/crypto.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | package node | ||||||
|  |  | ||||||
|  | import "golang.org/x/crypto/nacl/box" | ||||||
|  |  | ||||||
|  | // Encrypting the packet will also set the header's DataSize field. | ||||||
|  | func encryptPacket(h *header, sharedKey, data, out []byte) []byte { | ||||||
|  | 	h.DataSize = uint16(len(data) + box.Overhead) | ||||||
|  | 	out = out[:h.DataSize+headerSize] | ||||||
|  | 	h.Marshal(out) | ||||||
|  | 	box.SealAfterPrecomputation(out[headerSize:headerSize], data, (*[24]byte)(out[:headerSize]), (*[32]byte)(sharedKey)) | ||||||
|  | 	return out | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func decryptPacket(sharedKey, packetAndHeader, out []byte) (decrypted []byte, ok bool) { | ||||||
|  | 	return box.OpenAfterPrecomputation( | ||||||
|  | 		out[:0], | ||||||
|  | 		packetAndHeader[headerSize:], | ||||||
|  | 		(*[24]byte)(packetAndHeader[:headerSize]), | ||||||
|  | 		(*[32]byte)(sharedKey)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func computeSharedKey(peerPubKey, privKey []byte) []byte { | ||||||
|  | 	shared := [32]byte{} | ||||||
|  | 	box.Precompute(&shared, (*[32]byte)(peerPubKey), (*[32]byte)(privKey)) | ||||||
|  | 	return shared[:] | ||||||
|  | } | ||||||
							
								
								
									
										121
									
								
								node/crypto_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								node/crypto_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | package node | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"reflect" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"golang.org/x/crypto/nacl/box" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestEncryptDecryptPacket(t *testing.T) { | ||||||
|  | 	pubKey1, privKey1, err := box.GenerateKey(rand.Reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pubKey2, privKey2, err := box.GenerateKey(rand.Reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sharedEncKey := [32]byte{} | ||||||
|  | 	box.Precompute(&sharedEncKey, pubKey2, privKey1) | ||||||
|  |  | ||||||
|  | 	sharedDecKey := [32]byte{} | ||||||
|  | 	box.Precompute(&sharedDecKey, pubKey1, privKey2) | ||||||
|  |  | ||||||
|  | 	original := make([]byte, if_mtu-64) | ||||||
|  | 	rand.Read(original) | ||||||
|  |  | ||||||
|  | 	h := header{ | ||||||
|  | 		Counter:    2893749238, | ||||||
|  | 		SourceIP:   5, | ||||||
|  | 		ViaIP:      8, | ||||||
|  | 		DestIP:     12, | ||||||
|  | 		PacketType: 32, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	encrypted := make([]byte, bufferSize) | ||||||
|  | 	encrypted = encryptPacket(&h, sharedEncKey[:], original, encrypted) | ||||||
|  |  | ||||||
|  | 	decrypted := make([]byte, bufferSize) | ||||||
|  | 	var ok bool | ||||||
|  | 	decrypted, ok = decryptPacket(sharedDecKey[:], encrypted, decrypted) | ||||||
|  | 	if !ok { | ||||||
|  | 		t.Fatal(ok) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var h2 header | ||||||
|  | 	h2.Parse(encrypted) | ||||||
|  |  | ||||||
|  | 	if !reflect.DeepEqual(h, h2) { | ||||||
|  | 		t.Fatal(h, h2) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !bytes.Equal(original, decrypted) { | ||||||
|  | 		t.Fatal("mismatch") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | func BenchmarkEncryptPacket(b *testing.B) { | ||||||
|  | 	_, privKey1, err := box.GenerateKey(rand.Reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pubKey2, _, err := box.GenerateKey(rand.Reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sharedEncKey := [32]byte{} | ||||||
|  | 	box.Precompute(&sharedEncKey, pubKey2, privKey1) | ||||||
|  |  | ||||||
|  | 	original := make([]byte, MTU) | ||||||
|  | 	rand.Read(original) | ||||||
|  |  | ||||||
|  | 	nonce := make([]byte, NONCE_SIZE) | ||||||
|  | 	rand.Read(nonce) | ||||||
|  |  | ||||||
|  | 	encrypted := make([]byte, BUFFER_SIZE) | ||||||
|  |  | ||||||
|  | 	for i := 0; i < b.N; i++ { | ||||||
|  | 		encrypted = encryptPacket(sharedEncKey[:], nonce, original, encrypted) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func BenchmarkDecryptPacket(b *testing.B) { | ||||||
|  | 	pubKey1, privKey1, err := box.GenerateKey(rand.Reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pubKey2, privKey2, err := box.GenerateKey(rand.Reader) | ||||||
|  | 	if err != nil { | ||||||
|  | 		b.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sharedEncKey := [32]byte{} | ||||||
|  | 	box.Precompute(&sharedEncKey, pubKey2, privKey1) | ||||||
|  |  | ||||||
|  | 	sharedDecKey := [32]byte{} | ||||||
|  | 	box.Precompute(&sharedDecKey, pubKey1, privKey2) | ||||||
|  |  | ||||||
|  | 	original := make([]byte, MTU) | ||||||
|  | 	rand.Read(original) | ||||||
|  |  | ||||||
|  | 	nonce := make([]byte, NONCE_SIZE) | ||||||
|  | 	rand.Read(nonce) | ||||||
|  |  | ||||||
|  | 	encrypted := make([]byte, BUFFER_SIZE) | ||||||
|  | 	encrypted = encryptPacket(sharedEncKey[:], nonce, original, encrypted) | ||||||
|  |  | ||||||
|  | 	decrypted := make([]byte, MTU) | ||||||
|  | 	for i := 0; i < b.N; i++ { | ||||||
|  | 		decrypted, _ = decryptPacket(sharedDecKey[:], encrypted, decrypted) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | */ | ||||||
| @@ -7,11 +7,8 @@ import ( | |||||||
|  |  | ||||||
| type peer struct { | type peer struct { | ||||||
| 	IP   byte | 	IP   byte | ||||||
| 	// TODO: Version | 	Addr *netip.AddrPort // If we have direct connection, otherwise use mediator. | ||||||
| 	Addr *netip.AddrPort | 	// TODO: SharedKey []byte | ||||||
| 	// TODO: ViaIP |  | ||||||
| 	// TODO: EncPubKey |  | ||||||
| 	// TODO: SignPrivKey |  | ||||||
| } | } | ||||||
|  |  | ||||||
| type peerRepo [256]*atomic.Pointer[peer] | type peerRepo [256]*atomic.Pointer[peer] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user