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" | ||||
| 	"net" | ||||
| 	"net/netip" | ||||
| 	"sync/atomic" | ||||
| 	"vppn/fasttime" | ||||
| ) | ||||
|  | ||||
| // TODO: | ||||
| type connRouter interface { | ||||
| 	Lookup(byte) *peer | ||||
| 	Mediator() *peer | ||||
| } | ||||
|  | ||||
| type connWriter struct { | ||||
| 	*net.UDPConn | ||||
| 	localIP  byte | ||||
| @@ -37,10 +44,8 @@ func (w *connWriter) WriteTo(remoteIP, packetType byte, data []byte) error { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	w.counters[remoteIP]++ | ||||
|  | ||||
| 	h := header{ | ||||
| 		Counter:    w.counters[remoteIP], | ||||
| 		Counter:    atomic.AddUint64(&w.counters[remoteIP], 1), | ||||
| 		SourceIP:   w.localIP, | ||||
| 		ViaIP:      0, | ||||
| 		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 { | ||||
| 	IP   byte | ||||
| 	// TODO: Version | ||||
| 	Addr *netip.AddrPort | ||||
| 	// TODO: ViaIP | ||||
| 	// TODO: EncPubKey | ||||
| 	// TODO: SignPrivKey | ||||
| 	Addr *netip.AddrPort // If we have direct connection, otherwise use mediator. | ||||
| 	// TODO: SharedKey []byte | ||||
| } | ||||
|  | ||||
| type peerRepo [256]*atomic.Pointer[peer] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user