From 2c8375157486995a9a42080757088ade0442ba3d Mon Sep 17 00:00:00 2001 From: Pablu23 Date: Sat, 11 Nov 2023 00:09:11 +0100 Subject: [PATCH] New Project Structure - Encryption From and to Server --- .gitignore | 4 +- Makefile | 5 +- client.go | 181 ------------------- go.mod | 6 +- go.sum | 4 - go.work | 8 + internal/client/client.go | 211 +++++++++++++++++++++++ internal/client/go.mod | 3 + internal/common/go.mod | 7 + internal/common/go.sum | 4 + packets.go => internal/common/packets.go | 181 +++++++++---------- internal/server/go.mod | 3 + server.go => internal/server/server.go | 111 ++++++------ main.go | 8 +- 14 files changed, 396 insertions(+), 340 deletions(-) delete mode 100644 client.go create mode 100644 go.work create mode 100644 internal/client/client.go create mode 100644 internal/client/go.mod create mode 100644 internal/common/go.mod create mode 100644 internal/common/go.sum rename packets.go => internal/common/packets.go (52%) create mode 100644 internal/server/go.mod rename server.go => internal/server/server.go (52%) diff --git a/.gitignore b/.gitignore index f83594c..b9ffcc5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ bin/ -testFile -testFile.recv -testFile2 +testFiles/ out/ \ No newline at end of file diff --git a/Makefile b/Makefile index 292bbd1..5e4f6f0 100644 --- a/Makefile +++ b/Makefile @@ -2,4 +2,7 @@ build: go build -o bin/helloGo main.go client.go packets.go server.go server: - go run main.go server.go client.go packets.go server \ No newline at end of file + go run main.go server + +test: + go run main.go client testFiles/testFile \ No newline at end of file diff --git a/client.go b/client.go deleted file mode 100644 index 76bce69..0000000 --- a/client.go +++ /dev/null @@ -1,181 +0,0 @@ -package main - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "net" - "os" - "sort" - "time" -) - -func SendPacket(pck *Packet, key [32]byte, conn *net.UDPConn) { - secPck := NewSymetricSecurePacket(key, pck) - fmt.Println(secPck) - if _, err := conn.Write(secPck.ToBytes()); err != nil { - panic(err) - } -} - -func GetFile(path string) { - request := NewRequest(path) - - k := make([]byte, 32) - _, err := rand.Read(k) - if err != nil { - panic(err) - } - key := [32]byte(k) - keyExchangePck := NewRsaPacket(request.sid, key) - - udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:13374") - // udpAddr, err := net.ResolveUDPAddr("udp", "192.168.2.145:13374") - - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - // Dial to the address with UDP - conn, err := net.DialUDP("udp", nil, udpAddr) - - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - _, err = conn.Write(keyExchangePck.ToBytes()) - if err != nil { - panic(err) - } - - SendPacket(request, key, conn) - - bytes := make([]byte, PacketSize) - file, err := os.Create("out/" + hex.EncodeToString(request.sid[:]) + ".recv") - if err != nil { - panic(err) - } - - _, _, err = conn.ReadFrom(bytes) - if err != nil { - panic(err) - } - - pck := PacketFromBytes(bytes) - if pck.flag != PTE { - panic("Header flag was supposed to be PTE") - } - - size, err := pck.GetUint32Payload() - if err != nil { - panic(err) - } - - file.Truncate(int64(size)) - - ackPck := NewAck(&pck) - SendPacket(ackPck, key, conn) - - recvPackets := make([]uint32, 0) - var endPacket Packet - - for { - _, _, err = conn.ReadFrom(bytes) - if err != nil { - panic(err) - } - - pck := PacketFromBytes(bytes) - if pck.flag == End { - endPacket = pck - break - } - recvPackets = append(recvPackets, pck.sync) - - offset := (int64(pck.sync) - int64(ackPck.sync+1)) * (PacketSize - int64(HeaderSize)) - fmt.Printf("Sync: %v, Offset: %v\n", pck.sync, offset) - - _, err = file.WriteAt(pck.data, offset) - if err != nil { - panic(err) - } - } - - sort.Slice(recvPackets, func(i, j int) bool { - pckI := recvPackets[i] - pckJ := recvPackets[j] - return pckI < pckJ - }) - - lostPackets := make([]uint32, 0) - - for i := ackPck.sync + 1; i < endPacket.sync; i++ { - if b, _ := contains(recvPackets, i); !b { - lostPackets = append(lostPackets, i) - } - } - - for _, i := range lostPackets { - fmt.Println(i) - } - - lastPacket := ackPck - - for { - if len(lostPackets) == 0 { - break - } - - for _, sync := range lostPackets { - - fmt.Printf("Request resend for %v\n", sync) - resend := NewResend(uint32(sync), lastPacket) - SendPacket(resend, key, conn) - lastPacket = resend - - conn.SetReadDeadline(time.Now().Add(10 * time.Second)) - - _, _, err = conn.ReadFrom(bytes) - if err != nil { - if e, ok := err.(net.Error); !ok || !e.Timeout() { - // If it's not a timeout, log the error as usual - panic(err) - } - continue - } - - pck := PacketFromBytes(bytes) - offset := (int64(pck.sync) - int64(ackPck.sync+1)) * (PacketSize - int64(HeaderSize)) - // fmt.Printf("Sync: %v, Offset: %v\n", pck.sync, offset) - - _, err = file.WriteAt(pck.data, offset) - if err != nil { - panic(err) - } - - _, index := contains(lostPackets, pck.sync) - fmt.Printf("Removing sync %v from LostPackets\n", pck.sync) - lostPackets = remove(lostPackets, index) - - } - } - - ack := NewAck(&endPacket) - SendPacket(ack, key, conn) -} - -func remove(s []uint32, i int) []uint32 { - s[i] = s[len(s)-1] - return s[:len(s)-1] -} - -func contains(s []uint32, e uint32) (bool, int) { - for i, a := range s { - if a == e { - return true, i - } - } - return false, 0 -} diff --git a/go.mod b/go.mod index a9a7408..08f73f0 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module pablu/uftp go 1.21.1 -require golang.org/x/crypto v0.15.0 +replace internal/common => ./internal/common -require golang.org/x/sys v0.14.0 // indirect +replace internal/client => ./internal/client + +replace internal/server => ./internal/server diff --git a/go.sum b/go.sum index 4888ad1..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +0,0 @@ -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/go.work b/go.work new file mode 100644 index 0000000..5896ff4 --- /dev/null +++ b/go.work @@ -0,0 +1,8 @@ +go 1.21.1 + +use ( + . + ./internal/client + ./internal/common + ./internal/server +) diff --git a/internal/client/client.go b/internal/client/client.go new file mode 100644 index 0000000..8ac992d --- /dev/null +++ b/internal/client/client.go @@ -0,0 +1,211 @@ +package client + +import ( + "common" + "crypto/rand" + "encoding/hex" + "fmt" + "net" + "os" + "sort" + "time" +) + +func SendPacket(pck *common.Packet, key [32]byte, conn *net.UDPConn) { + secPck := common.NewSymetricSecurePacket(key, pck) + if _, err := conn.Write(secPck.ToBytes()); err != nil { + panic(err) + } +} + +func ReceivePacket(key [32]byte, conn *net.UDPConn) common.Packet { + bytes := make([]byte, common.PacketSize+common.SecureHeaderSize) + _, _, err := conn.ReadFrom(bytes) + if err != nil { + panic(err) + } + + secPck := common.SecurePacketFromBytes(bytes) + pck, err := secPck.ExtractPacket(key) + + if err != nil { + panic(err) + } + + fmt.Printf("Decrypted Packet, Sync: %v, Type: %v\n", pck.Sync, pck.Flag) + + return pck +} + +func ReceivePacketWithTimeout(key [32]byte, conn *net.UDPConn) (common.Packet, bool) { + conn.SetReadDeadline(time.Now().Add(10 * time.Second)) + + bytes := make([]byte, common.PacketSize) + + _, _, err := conn.ReadFrom(bytes) + if err != nil { + if e, ok := err.(net.Error); !ok || !e.Timeout() { + // If it's not a timeout, log the error as usual + panic(err) + } + + return common.Packet{}, false + } + + secPck := common.SecurePacketFromBytes(bytes) + pck, err := secPck.ExtractPacket(key) + if err != nil { + panic(err) + } + + return pck, true +} + +func GetFile(path string) { + request := common.NewRequest(path) + + k := make([]byte, 32) + _, err := rand.Read(k) + if err != nil { + panic(err) + } + key := [32]byte(k) + keyExchangePck := common.NewRsaPacket(request.Sid, key) + + udpAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:13374") + // udpAddr, err := net.ResolveUDPAddr("udp", "192.168.2.145:13374") + + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Dial to the address with UDP + conn, err := net.DialUDP("udp", nil, udpAddr) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + _, err = conn.Write(keyExchangePck.ToBytes()) + if err != nil { + panic(err) + } + + SendPacket(request, key, conn) + + file, err := os.Create("out/" + hex.EncodeToString(request.Sid[:]) + ".recv") + if err != nil { + panic(err) + } + + pck := ReceivePacket(key, conn) + if pck.Flag != common.PTE { + panic("Header flag was supposed to be PTE") + } + + size, err := pck.GetUint32Payload() + if err != nil { + panic(err) + } + + file.Truncate(int64(size)) + + ackPck := common.NewAck(&pck) + SendPacket(ackPck, key, conn) + + recvPackets := make([]uint32, 0) + var endPacket common.Packet + + for { + pck := ReceivePacket(key, conn) + if pck.Flag == common.End { + endPacket = pck + break + } + if pck.Flag != common.File { + fmt.Printf("Received %v Packet, but expected File Packet\n", pck.Flag) + continue + } + + recvPackets = append(recvPackets, pck.Sync) + + offset := (int64(pck.Sync) - int64(ackPck.Sync+1)) * (common.PacketSize - int64(common.HeaderSize)) + // fmt.Printf("Sync: %v, Offset: %v\n", pck.Sync, offset) + + _, err = file.WriteAt(pck.Data, offset) + if err != nil { + panic(err) + } + } + + sort.Slice(recvPackets, func(i, j int) bool { + pckI := recvPackets[i] + pckJ := recvPackets[j] + return pckI < pckJ + }) + + lostPackets := make([]uint32, 0) + + for i := ackPck.Sync + 1; i < endPacket.Sync; i++ { + if b, _ := contains(recvPackets, i); !b { + lostPackets = append(lostPackets, i) + } + } + + for _, i := range lostPackets { + fmt.Println(i) + } + + lastPacket := ackPck + + for { + if len(lostPackets) == 0 { + break + } + + for _, sync := range lostPackets { + + fmt.Printf("Request resend for %v\n", sync) + resend := common.NewResend(uint32(sync), lastPacket) + SendPacket(resend, key, conn) + lastPacket = resend + + pck, received := ReceivePacketWithTimeout(key, conn) + + if !received { + continue + } + + offset := (int64(pck.Sync) - int64(ackPck.Sync+1)) * (common.PacketSize - int64(common.HeaderSize)) + // fmt.Printf("Sync: %v, Offset: %v\n", pck.sync, offset) + + _, err = file.WriteAt(pck.Data, offset) + if err != nil { + panic(err) + } + + _, index := contains(lostPackets, pck.Sync) + fmt.Printf("Removing sync %v from LostPackets\n", pck.Sync) + lostPackets = remove(lostPackets, index) + + } + } + + ack := common.NewAck(&endPacket) + SendPacket(ack, key, conn) +} + +func remove(s []uint32, i int) []uint32 { + s[i] = s[len(s)-1] + return s[:len(s)-1] +} + +func contains(s []uint32, e uint32) (bool, int) { + for i, a := range s { + if a == e { + return true, i + } + } + return false, 0 +} diff --git a/internal/client/go.mod b/internal/client/go.mod new file mode 100644 index 0000000..34cd850 --- /dev/null +++ b/internal/client/go.mod @@ -0,0 +1,3 @@ +module client + +go 1.21.1 \ No newline at end of file diff --git a/internal/common/go.mod b/internal/common/go.mod new file mode 100644 index 0000000..6d65dc5 --- /dev/null +++ b/internal/common/go.mod @@ -0,0 +1,7 @@ +module common + +go 1.21.1 + +require golang.org/x/crypto v0.15.0 + +require golang.org/x/sys v0.14.0 // indirect diff --git a/internal/common/go.sum b/internal/common/go.sum new file mode 100644 index 0000000..4888ad1 --- /dev/null +++ b/internal/common/go.sum @@ -0,0 +1,4 @@ +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/packets.go b/internal/common/packets.go similarity index 52% rename from packets.go rename to internal/common/packets.go index 4c6f758..63985a5 100644 --- a/packets.go +++ b/internal/common/packets.go @@ -1,4 +1,4 @@ -package main +package common import ( "crypto/rand" @@ -9,30 +9,32 @@ import ( "golang.org/x/crypto/chacha20poly1305" ) +const PacketSize = 504 + const HeaderSize int = 32 + 1 + 4 + 4 const SecureHeaderSize int = 1 + 42 + 32 + 4 type SessionID [32]byte type SecurePacket struct { - isRsa byte // 0 = false everything else is true - nonce [24]byte - sid SessionID - dataLength uint32 - encryptedData []byte + IsRsa byte // 0 = false everything else is true + Nonce [24]byte + Sid SessionID + DataLength uint32 + EncryptedData []byte } type Packet struct { // headerLength uint32 - sid SessionID - flag HeaderFlag - sync uint32 - dataLength uint32 - data []byte + Sid SessionID + Flag HeaderFlag + Sync uint32 + DataLength uint32 + Data []byte } func NewSymetricSecurePacket(key [32]byte, pck *Packet) *SecurePacket { - sid := pck.sid + sid := pck.Sid data := pck.ToBytes() aead, err := chacha20poly1305.NewX(key[:]) if err != nil { @@ -48,11 +50,11 @@ func NewSymetricSecurePacket(key [32]byte, pck *Packet) *SecurePacket { encrypted = aead.Seal(nil, nonce, data, nil) return &SecurePacket{ - isRsa: 0, - nonce: [24]byte(nonce), - sid: sid, - dataLength: uint32(len(encrypted)), - encryptedData: encrypted, + IsRsa: 0, + Nonce: [24]byte(nonce), + Sid: sid, + DataLength: uint32(len(encrypted)), + EncryptedData: encrypted, } } @@ -64,49 +66,50 @@ func SecurePacketFromBytes(bytes []byte) SecurePacket { enc := bytes[61 : 61+length] return SecurePacket{ - isRsa: isRsa, - nonce: [24]byte(nonce), - sid: sid, - encryptedData: enc, - dataLength: length, + IsRsa: isRsa, + Nonce: [24]byte(nonce), + Sid: sid, + DataLength: length, + EncryptedData: enc, } } func (secPck *SecurePacket) ToBytes() []byte { - arr := make([]byte, SecureHeaderSize+len(secPck.encryptedData)) - arr[0] = secPck.isRsa - copy(arr[1:25], secPck.nonce[:]) - copy(arr[25:57], secPck.sid[:]) - binary.LittleEndian.PutUint32(arr[57:61], secPck.dataLength) - copy(arr[61:], secPck.encryptedData) + arr := make([]byte, SecureHeaderSize+len(secPck.EncryptedData)) + arr[0] = secPck.IsRsa + copy(arr[1:25], secPck.Nonce[:]) + copy(arr[25:57], secPck.Sid[:]) + binary.LittleEndian.PutUint32(arr[57:61], secPck.DataLength) + copy(arr[61:], secPck.EncryptedData) return arr } -func (secPck *SecurePacket) ExtractPacket(key [32]byte) (*Packet, error) { +func (secPck *SecurePacket) ExtractPacket(key [32]byte) (Packet, error) { aead, err := chacha20poly1305.NewX(key[:]) if err != nil { panic(err) } - data, err := aead.Open(nil, secPck.nonce[:], secPck.encryptedData, nil) + data, err := aead.Open(nil, secPck.Nonce[:], secPck.EncryptedData, nil) if err != nil { - return nil, err + return Packet{}, err } + // fmt.Println(data) packet := PacketFromBytes(data) - return &packet, nil + return packet, nil } func NewRsaPacket(sid SessionID, key [32]byte) *SecurePacket { return &SecurePacket{ - isRsa: 1, - nonce: [24]byte(make([]byte, 24)), - sid: sid, - encryptedData: key[:], + IsRsa: 1, + Nonce: [24]byte(make([]byte, 24)), + Sid: sid, + EncryptedData: key[:], } } func (secPck *SecurePacket) ExtractKey( /*RSA HERE LATER*/ ) []byte { - return secPck.encryptedData[:32] + return secPck.EncryptedData[:32] } func PacketFromBytes(bytes []byte) Packet { @@ -115,24 +118,24 @@ func PacketFromBytes(bytes []byte) Packet { sync := binary.LittleEndian.Uint32(bytes[33:37]) dataLength := binary.LittleEndian.Uint32(bytes[37:41]) pck := Packet{ - sid: sid, - flag: flag, - sync: sync, - dataLength: dataLength, - data: bytes[HeaderSize : HeaderSize+int(dataLength)], + Sid: sid, + Flag: flag, + Sync: sync, + DataLength: dataLength, + Data: bytes[HeaderSize : HeaderSize+int(dataLength)], } return pck } func NewAck(pckToAck *Packet) *Packet { data := make([]byte, 4) - binary.LittleEndian.PutUint32(data, pckToAck.sync) + binary.LittleEndian.PutUint32(data, pckToAck.Sync) return &Packet{ - sid: pckToAck.sid, - flag: Ack, - sync: pckToAck.sync + 1, - dataLength: uint32(4), - data: data, + Sid: pckToAck.Sid, + Flag: Ack, + Sync: pckToAck.Sync + 1, + DataLength: uint32(4), + Data: data, } } @@ -145,59 +148,59 @@ func NewRequest(path string) *Packet { } return &Packet{ - sid: SessionID(buf), - flag: Request, - sync: 0, - dataLength: uint32(len(data)), - data: data, + Sid: SessionID(buf), + Flag: Request, + Sync: 0, + DataLength: uint32(len(data)), + Data: data, } } func (pck *Packet) GetUint32Payload() (uint32, error) { - flag := pck.flag + flag := pck.Flag if flag != PTE && flag != Ack && flag != End && flag != Resend { return 0, errors.New(fmt.Sprintf("Can not get Sync from Packet Type with flag: %v", flag)) } - return binary.LittleEndian.Uint32(pck.data), nil + return binary.LittleEndian.Uint32(pck.Data), nil } func (pck *Packet) GetFilePath() (string, error) { - if pck.flag != Request { + if pck.Flag != Request { return "", errors.New("Can not get FilePath from Packet that is not Request") } - return string(pck.data), nil + return string(pck.Data), nil } func NewResendFile(resendPck *Packet, data []byte) *Packet { sync, _ := resendPck.GetUint32Payload() return &Packet{ - sid: resendPck.sid, - flag: File, - sync: sync, - dataLength: uint32(len(data)), - data: data, + Sid: resendPck.Sid, + Flag: File, + Sync: sync, + DataLength: uint32(len(data)), + Data: data, } } func NewFile(lastPck *Packet, data []byte) *Packet { return &Packet{ - sid: lastPck.sid, - flag: File, - sync: lastPck.sync + 1, - dataLength: uint32(len(data)), - data: data, + Sid: lastPck.Sid, + Flag: File, + Sync: lastPck.Sync + 1, + DataLength: uint32(len(data)), + Data: data, } } func NewEnd(lastFilePck *Packet) *Packet { data := make([]byte, 4) - binary.LittleEndian.PutUint32(data, lastFilePck.sync) + binary.LittleEndian.PutUint32(data, lastFilePck.Sync) return &Packet{ - sid: lastFilePck.sid, - flag: End, - sync: lastFilePck.sync + 1, - dataLength: uint32(4), - data: data, + Sid: lastFilePck.Sid, + Flag: End, + Sync: lastFilePck.Sync + 1, + DataLength: uint32(4), + Data: data, } } @@ -205,11 +208,11 @@ func NewResend(sync uint32, lastPck *Packet) *Packet { data := make([]byte, 4) binary.LittleEndian.PutUint32(data, sync) return &Packet{ - sid: lastPck.sid, - flag: Resend, - sync: lastPck.sync + 1, - dataLength: uint32(4), - data: data, + Sid: lastPck.Sid, + Flag: Resend, + Sync: lastPck.Sync + 1, + DataLength: uint32(4), + Data: data, } } @@ -217,21 +220,21 @@ func NewPte(fileSize uint32, lastPck *Packet) *Packet { data := make([]byte, 4) binary.LittleEndian.PutUint32(data, fileSize) return &Packet{ - sid: lastPck.sid, - flag: PTE, - sync: lastPck.sync + 1, - dataLength: uint32(4), - data: data, + Sid: lastPck.Sid, + Flag: PTE, + Sync: lastPck.Sync + 1, + DataLength: uint32(4), + Data: data, } } func (pck *Packet) ToBytes() []byte { - arr := make([]byte, HeaderSize+int(pck.dataLength)) - arr[0] = byte(pck.flag) - copy(arr[1:33], pck.sid[:]) - binary.LittleEndian.PutUint32(arr[33:37], pck.sync) - binary.LittleEndian.PutUint32(arr[37:41], pck.dataLength) - copy(arr[41:], pck.data) + arr := make([]byte, HeaderSize+int(pck.DataLength)) + arr[0] = byte(pck.Flag) + copy(arr[1:33], pck.Sid[:]) + binary.LittleEndian.PutUint32(arr[33:37], pck.Sync) + binary.LittleEndian.PutUint32(arr[37:41], pck.DataLength) + copy(arr[41:], pck.Data) return arr } diff --git a/internal/server/go.mod b/internal/server/go.mod new file mode 100644 index 0000000..c7f5a1b --- /dev/null +++ b/internal/server/go.mod @@ -0,0 +1,3 @@ +module server + +go 1.21.1 \ No newline at end of file diff --git a/server.go b/internal/server/server.go similarity index 52% rename from server.go rename to internal/server/server.go index 0354ec3..49680b3 100644 --- a/server.go +++ b/internal/server/server.go @@ -1,6 +1,7 @@ -package main +package server import ( + "common" "crypto/rand" "crypto/rsa" "encoding/hex" @@ -14,12 +15,12 @@ import ( type info struct { path string lastSync uint32 - lastPckSend HeaderFlag + lastPckSend common.HeaderFlag key [32]byte } type Server struct { - sessions map[SessionID]*info + sessions map[common.SessionID]*info rsa *rsa.PrivateKey } @@ -31,31 +32,43 @@ func New() (*Server, error) { } return &Server{ - sessions: make(map[SessionID]*info), + sessions: make(map[common.SessionID]*info), rsa: key, }, nil } -func (server *Server) handlePacket(conn *net.UDPConn, addr *net.UDPAddr, rPacket *Packet) { - switch rPacket.flag { - case Request: +func (server *Server) sendPacket(conn *net.UDPConn, addr *net.UDPAddr, pck *common.Packet) { + key := server.sessions[pck.Sid].key + + fmt.Printf("Sending Packet, Sync: %v, Type: %v\n", pck.Sync, pck.Flag) + + secPck := common.NewSymetricSecurePacket(key, pck) + if _, err := conn.WriteToUDP(secPck.ToBytes(), addr); err != nil { + panic(err) + } + conn.WriteToUDP(secPck.ToBytes(), addr) +} + +func (server *Server) handlePacket(conn *net.UDPConn, addr *net.UDPAddr, rPacket *common.Packet) { + switch rPacket.Flag { + case common.Request: server.sendPTE(conn, addr, rPacket) break - case Ack: + case common.Ack: server.handleAck(conn, addr, rPacket) break - case Resend: + case common.Resend: server.resend(conn, addr, rPacket) } } -func (server *Server) resend(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet) { +func (server *Server) resend(conn *net.UDPConn, addr *net.UDPAddr, pck *common.Packet) { resend, err := pck.GetUint32Payload() if err != nil { panic(err) } - path := server.sessions[pck.sid].path + path := server.sessions[pck.Sid].path file, err := os.Open(path) if err != nil { panic(err) @@ -63,29 +76,24 @@ func (server *Server) resend(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet) defer file.Close() // This should be different - offset := (int64(resend) - 3) * (PacketSize - int64(HeaderSize)) - // fmt.Printf("Requested Sync: %v, Calculated Offset: %v\n", resend, offset) - buf := make([]byte, PacketSize-HeaderSize) + offset := (int64(resend) - 3) * (common.PacketSize - int64(common.HeaderSize)) + buf := make([]byte, common.PacketSize-common.HeaderSize) _, err = file.ReadAt(buf, offset) if err != nil && !errors.Is(err, io.EOF) { panic(err) } - fmt.Printf("Resending Packet %v\n", resend) - - resendPck := NewResendFile(pck, buf) - - conn.WriteToUDP(resendPck.ToBytes(), addr) - + resendPck := common.NewResendFile(pck, buf) + server.sendPacket(conn, addr, resendPck) } -func (server *Server) handleAck(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet) { +func (server *Server) handleAck(conn *net.UDPConn, addr *net.UDPAddr, pck *common.Packet) { ack, err := pck.GetUint32Payload() if err != nil { panic(err) } - session := server.sessions[pck.sid] + session := server.sessions[pck.Sid] if session == nil { panic(err) } @@ -94,16 +102,15 @@ func (server *Server) handleAck(conn *net.UDPConn, addr *net.UDPAddr, pck *Packe return } - if session.lastPckSend == End { - fmt.Printf("Deleting Session %v\n", hex.EncodeToString(pck.sid[:])) - delete(server.sessions, pck.sid) + if session.lastPckSend == common.End { + fmt.Printf("Deleting Session %v\n", hex.EncodeToString(pck.Sid[:])) + delete(server.sessions, pck.Sid) } else { - fmt.Printf("Sending Data for Session %v\n", hex.EncodeToString(pck.sid[:])) server.sendData(conn, addr, pck) } } -func (server *Server) sendPTE(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet) { +func (server *Server) sendPTE(conn *net.UDPConn, addr *net.UDPAddr, pck *common.Packet) { path, err := pck.GetFilePath() if err != nil { panic(err) @@ -116,23 +123,23 @@ func (server *Server) sendPTE(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet) fileSize := fi.Size() - ptePck := NewPte(uint32(fileSize), pck) - conn.WriteToUDP(ptePck.ToBytes(), addr) + ptePck := common.NewPte(uint32(fileSize), pck) + server.sendPacket(conn, addr, ptePck) - server.sessions[pck.sid].path = path - server.sessions[pck.sid].lastSync = ptePck.sync - server.sessions[pck.sid].lastPckSend = ptePck.flag + server.sessions[pck.Sid].path = path + server.sessions[pck.Sid].lastSync = ptePck.Sync + server.sessions[pck.Sid].lastPckSend = ptePck.Flag } -func (server *Server) sendData(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet) { - path := server.sessions[pck.sid].path +func (server *Server) sendData(conn *net.UDPConn, addr *net.UDPAddr, pck *common.Packet) { + path := server.sessions[pck.Sid].path file, err := os.Open(path) if err != nil { panic(err) } defer file.Close() - buf := make([]byte, PacketSize-HeaderSize) + buf := make([]byte, common.PacketSize-common.HeaderSize) filePck := pck for { r, err := file.Read(buf) @@ -142,18 +149,15 @@ func (server *Server) sendData(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet if r == 0 { break } - filePck = NewFile(filePck, buf[:r]) - fmt.Printf("Sending File Packet %v\n", filePck.sync) + filePck = common.NewFile(filePck, buf[:r]) - conn.WriteToUDP(filePck.ToBytes(), addr) + server.sendPacket(conn, addr, filePck) } - eodPck := NewEnd(filePck) - server.sessions[pck.sid].lastSync = eodPck.sync - server.sessions[pck.sid].lastPckSend = eodPck.flag - - fmt.Printf("Sending Eod Packet %v\n", eodPck.sync) - conn.WriteToUDP(eodPck.ToBytes(), addr) + eodPck := common.NewEnd(filePck) + server.sessions[pck.Sid].lastSync = eodPck.Sync + server.sessions[pck.Sid].lastPckSend = eodPck.Flag + server.sendPacket(conn, addr, eodPck) } func (server *Server) Serve() { @@ -172,33 +176,28 @@ func (server *Server) Serve() { } for { - var buf [PacketSize]byte + var buf [common.PacketSize]byte _, addr, err := conn.ReadFromUDP(buf[0:]) if err != nil { fmt.Println(err) return } - secPck := SecurePacketFromBytes(buf[:]) + secPck := common.SecurePacketFromBytes(buf[:]) - fmt.Println(secPck) - - if secPck.isRsa == 0 { - key := server.sessions[secPck.sid].key + if secPck.IsRsa == 0 { + key := server.sessions[secPck.Sid].key pck, err := secPck.ExtractPacket(key) if err != nil { fmt.Println(err) - //fmt.Println("Could not establish secure connection") } - go server.handlePacket(conn, addr, pck) + go server.handlePacket(conn, addr, &pck) } else { key := secPck.ExtractKey() - fmt.Println(key) - fmt.Println(secPck.sid) - server.sessions[secPck.sid] = &info{ + fmt.Printf("Session: %v, Key: %v\n", hex.EncodeToString(secPck.Sid[:]), hex.EncodeToString(key)) + server.sessions[secPck.Sid] = &info{ key: [32]byte(key), } - } } } diff --git a/main.go b/main.go index b449b65..9cbd1d3 100644 --- a/main.go +++ b/main.go @@ -1,19 +1,19 @@ package main import ( + "client" "os" + "server" ) -const PacketSize = 504 - func main() { if os.Args[1] == "server" { - server, err := New() + server, err := server.New() if err != nil { panic(err) } server.Serve() } else { - GetFile(os.Args[2]) + client.GetFile(os.Args[2]) } }