New Project Structure - Encryption From and to Server

This commit is contained in:
Pablu23
2023-11-11 00:09:11 +01:00
parent 82ca232d61
commit 2c83751574
14 changed files with 396 additions and 340 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,3 @@
bin/ bin/
testFile testFiles/
testFile.recv
testFile2
out/ out/

View File

@@ -2,4 +2,7 @@ build:
go build -o bin/helloGo main.go client.go packets.go server.go go build -o bin/helloGo main.go client.go packets.go server.go
server: server:
go run main.go server.go client.go packets.go server go run main.go server
test:
go run main.go client testFiles/testFile

181
client.go
View File

@@ -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
}

6
go.mod
View File

@@ -2,6 +2,8 @@ module pablu/uftp
go 1.21.1 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

4
go.sum
View File

@@ -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=

8
go.work Normal file
View File

@@ -0,0 +1,8 @@
go 1.21.1
use (
.
./internal/client
./internal/common
./internal/server
)

211
internal/client/client.go Normal file
View File

@@ -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
}

3
internal/client/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module client
go 1.21.1

7
internal/common/go.mod Normal file
View File

@@ -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

4
internal/common/go.sum Normal file
View File

@@ -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=

View File

@@ -1,4 +1,4 @@
package main package common
import ( import (
"crypto/rand" "crypto/rand"
@@ -9,30 +9,32 @@ import (
"golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/chacha20poly1305"
) )
const PacketSize = 504
const HeaderSize int = 32 + 1 + 4 + 4 const HeaderSize int = 32 + 1 + 4 + 4
const SecureHeaderSize int = 1 + 42 + 32 + 4 const SecureHeaderSize int = 1 + 42 + 32 + 4
type SessionID [32]byte type SessionID [32]byte
type SecurePacket struct { type SecurePacket struct {
isRsa byte // 0 = false everything else is true IsRsa byte // 0 = false everything else is true
nonce [24]byte Nonce [24]byte
sid SessionID Sid SessionID
dataLength uint32 DataLength uint32
encryptedData []byte EncryptedData []byte
} }
type Packet struct { type Packet struct {
// headerLength uint32 // headerLength uint32
sid SessionID Sid SessionID
flag HeaderFlag Flag HeaderFlag
sync uint32 Sync uint32
dataLength uint32 DataLength uint32
data []byte Data []byte
} }
func NewSymetricSecurePacket(key [32]byte, pck *Packet) *SecurePacket { func NewSymetricSecurePacket(key [32]byte, pck *Packet) *SecurePacket {
sid := pck.sid sid := pck.Sid
data := pck.ToBytes() data := pck.ToBytes()
aead, err := chacha20poly1305.NewX(key[:]) aead, err := chacha20poly1305.NewX(key[:])
if err != nil { if err != nil {
@@ -48,11 +50,11 @@ func NewSymetricSecurePacket(key [32]byte, pck *Packet) *SecurePacket {
encrypted = aead.Seal(nil, nonce, data, nil) encrypted = aead.Seal(nil, nonce, data, nil)
return &SecurePacket{ return &SecurePacket{
isRsa: 0, IsRsa: 0,
nonce: [24]byte(nonce), Nonce: [24]byte(nonce),
sid: sid, Sid: sid,
dataLength: uint32(len(encrypted)), DataLength: uint32(len(encrypted)),
encryptedData: encrypted, EncryptedData: encrypted,
} }
} }
@@ -64,49 +66,50 @@ func SecurePacketFromBytes(bytes []byte) SecurePacket {
enc := bytes[61 : 61+length] enc := bytes[61 : 61+length]
return SecurePacket{ return SecurePacket{
isRsa: isRsa, IsRsa: isRsa,
nonce: [24]byte(nonce), Nonce: [24]byte(nonce),
sid: sid, Sid: sid,
encryptedData: enc, DataLength: length,
dataLength: length, EncryptedData: enc,
} }
} }
func (secPck *SecurePacket) ToBytes() []byte { func (secPck *SecurePacket) ToBytes() []byte {
arr := make([]byte, SecureHeaderSize+len(secPck.encryptedData)) arr := make([]byte, SecureHeaderSize+len(secPck.EncryptedData))
arr[0] = secPck.isRsa arr[0] = secPck.IsRsa
copy(arr[1:25], secPck.nonce[:]) copy(arr[1:25], secPck.Nonce[:])
copy(arr[25:57], secPck.sid[:]) copy(arr[25:57], secPck.Sid[:])
binary.LittleEndian.PutUint32(arr[57:61], secPck.dataLength) binary.LittleEndian.PutUint32(arr[57:61], secPck.DataLength)
copy(arr[61:], secPck.encryptedData) copy(arr[61:], secPck.EncryptedData)
return arr 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[:]) aead, err := chacha20poly1305.NewX(key[:])
if err != nil { if err != nil {
panic(err) 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 { if err != nil {
return nil, err return Packet{}, err
} }
// fmt.Println(data)
packet := PacketFromBytes(data) packet := PacketFromBytes(data)
return &packet, nil return packet, nil
} }
func NewRsaPacket(sid SessionID, key [32]byte) *SecurePacket { func NewRsaPacket(sid SessionID, key [32]byte) *SecurePacket {
return &SecurePacket{ return &SecurePacket{
isRsa: 1, IsRsa: 1,
nonce: [24]byte(make([]byte, 24)), Nonce: [24]byte(make([]byte, 24)),
sid: sid, Sid: sid,
encryptedData: key[:], EncryptedData: key[:],
} }
} }
func (secPck *SecurePacket) ExtractKey( /*RSA HERE LATER*/ ) []byte { func (secPck *SecurePacket) ExtractKey( /*RSA HERE LATER*/ ) []byte {
return secPck.encryptedData[:32] return secPck.EncryptedData[:32]
} }
func PacketFromBytes(bytes []byte) Packet { func PacketFromBytes(bytes []byte) Packet {
@@ -115,24 +118,24 @@ func PacketFromBytes(bytes []byte) Packet {
sync := binary.LittleEndian.Uint32(bytes[33:37]) sync := binary.LittleEndian.Uint32(bytes[33:37])
dataLength := binary.LittleEndian.Uint32(bytes[37:41]) dataLength := binary.LittleEndian.Uint32(bytes[37:41])
pck := Packet{ pck := Packet{
sid: sid, Sid: sid,
flag: flag, Flag: flag,
sync: sync, Sync: sync,
dataLength: dataLength, DataLength: dataLength,
data: bytes[HeaderSize : HeaderSize+int(dataLength)], Data: bytes[HeaderSize : HeaderSize+int(dataLength)],
} }
return pck return pck
} }
func NewAck(pckToAck *Packet) *Packet { func NewAck(pckToAck *Packet) *Packet {
data := make([]byte, 4) data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, pckToAck.sync) binary.LittleEndian.PutUint32(data, pckToAck.Sync)
return &Packet{ return &Packet{
sid: pckToAck.sid, Sid: pckToAck.Sid,
flag: Ack, Flag: Ack,
sync: pckToAck.sync + 1, Sync: pckToAck.Sync + 1,
dataLength: uint32(4), DataLength: uint32(4),
data: data, Data: data,
} }
} }
@@ -145,59 +148,59 @@ func NewRequest(path string) *Packet {
} }
return &Packet{ return &Packet{
sid: SessionID(buf), Sid: SessionID(buf),
flag: Request, Flag: Request,
sync: 0, Sync: 0,
dataLength: uint32(len(data)), DataLength: uint32(len(data)),
data: data, Data: data,
} }
} }
func (pck *Packet) GetUint32Payload() (uint32, error) { func (pck *Packet) GetUint32Payload() (uint32, error) {
flag := pck.flag flag := pck.Flag
if flag != PTE && flag != Ack && flag != End && flag != Resend { 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 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) { 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 "", 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 { func NewResendFile(resendPck *Packet, data []byte) *Packet {
sync, _ := resendPck.GetUint32Payload() sync, _ := resendPck.GetUint32Payload()
return &Packet{ return &Packet{
sid: resendPck.sid, Sid: resendPck.Sid,
flag: File, Flag: File,
sync: sync, Sync: sync,
dataLength: uint32(len(data)), DataLength: uint32(len(data)),
data: data, Data: data,
} }
} }
func NewFile(lastPck *Packet, data []byte) *Packet { func NewFile(lastPck *Packet, data []byte) *Packet {
return &Packet{ return &Packet{
sid: lastPck.sid, Sid: lastPck.Sid,
flag: File, Flag: File,
sync: lastPck.sync + 1, Sync: lastPck.Sync + 1,
dataLength: uint32(len(data)), DataLength: uint32(len(data)),
data: data, Data: data,
} }
} }
func NewEnd(lastFilePck *Packet) *Packet { func NewEnd(lastFilePck *Packet) *Packet {
data := make([]byte, 4) data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, lastFilePck.sync) binary.LittleEndian.PutUint32(data, lastFilePck.Sync)
return &Packet{ return &Packet{
sid: lastFilePck.sid, Sid: lastFilePck.Sid,
flag: End, Flag: End,
sync: lastFilePck.sync + 1, Sync: lastFilePck.Sync + 1,
dataLength: uint32(4), DataLength: uint32(4),
data: data, Data: data,
} }
} }
@@ -205,11 +208,11 @@ func NewResend(sync uint32, lastPck *Packet) *Packet {
data := make([]byte, 4) data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, sync) binary.LittleEndian.PutUint32(data, sync)
return &Packet{ return &Packet{
sid: lastPck.sid, Sid: lastPck.Sid,
flag: Resend, Flag: Resend,
sync: lastPck.sync + 1, Sync: lastPck.Sync + 1,
dataLength: uint32(4), DataLength: uint32(4),
data: data, Data: data,
} }
} }
@@ -217,21 +220,21 @@ func NewPte(fileSize uint32, lastPck *Packet) *Packet {
data := make([]byte, 4) data := make([]byte, 4)
binary.LittleEndian.PutUint32(data, fileSize) binary.LittleEndian.PutUint32(data, fileSize)
return &Packet{ return &Packet{
sid: lastPck.sid, Sid: lastPck.Sid,
flag: PTE, Flag: PTE,
sync: lastPck.sync + 1, Sync: lastPck.Sync + 1,
dataLength: uint32(4), DataLength: uint32(4),
data: data, Data: data,
} }
} }
func (pck *Packet) ToBytes() []byte { func (pck *Packet) ToBytes() []byte {
arr := make([]byte, HeaderSize+int(pck.dataLength)) arr := make([]byte, HeaderSize+int(pck.DataLength))
arr[0] = byte(pck.flag) arr[0] = byte(pck.Flag)
copy(arr[1:33], pck.sid[:]) copy(arr[1:33], pck.Sid[:])
binary.LittleEndian.PutUint32(arr[33:37], pck.sync) binary.LittleEndian.PutUint32(arr[33:37], pck.Sync)
binary.LittleEndian.PutUint32(arr[37:41], pck.dataLength) binary.LittleEndian.PutUint32(arr[37:41], pck.DataLength)
copy(arr[41:], pck.data) copy(arr[41:], pck.Data)
return arr return arr
} }

3
internal/server/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module server
go 1.21.1

View File

@@ -1,6 +1,7 @@
package main package server
import ( import (
"common"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"encoding/hex" "encoding/hex"
@@ -14,12 +15,12 @@ import (
type info struct { type info struct {
path string path string
lastSync uint32 lastSync uint32
lastPckSend HeaderFlag lastPckSend common.HeaderFlag
key [32]byte key [32]byte
} }
type Server struct { type Server struct {
sessions map[SessionID]*info sessions map[common.SessionID]*info
rsa *rsa.PrivateKey rsa *rsa.PrivateKey
} }
@@ -31,31 +32,43 @@ func New() (*Server, error) {
} }
return &Server{ return &Server{
sessions: make(map[SessionID]*info), sessions: make(map[common.SessionID]*info),
rsa: key, rsa: key,
}, nil }, nil
} }
func (server *Server) handlePacket(conn *net.UDPConn, addr *net.UDPAddr, rPacket *Packet) { func (server *Server) sendPacket(conn *net.UDPConn, addr *net.UDPAddr, pck *common.Packet) {
switch rPacket.flag { key := server.sessions[pck.Sid].key
case Request:
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) server.sendPTE(conn, addr, rPacket)
break break
case Ack: case common.Ack:
server.handleAck(conn, addr, rPacket) server.handleAck(conn, addr, rPacket)
break break
case Resend: case common.Resend:
server.resend(conn, addr, rPacket) 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() resend, err := pck.GetUint32Payload()
if err != nil { if err != nil {
panic(err) panic(err)
} }
path := server.sessions[pck.sid].path path := server.sessions[pck.Sid].path
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
panic(err) panic(err)
@@ -63,29 +76,24 @@ func (server *Server) resend(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet)
defer file.Close() defer file.Close()
// This should be different // This should be different
offset := (int64(resend) - 3) * (PacketSize - int64(HeaderSize)) offset := (int64(resend) - 3) * (common.PacketSize - int64(common.HeaderSize))
// fmt.Printf("Requested Sync: %v, Calculated Offset: %v\n", resend, offset) buf := make([]byte, common.PacketSize-common.HeaderSize)
buf := make([]byte, PacketSize-HeaderSize)
_, err = file.ReadAt(buf, offset) _, err = file.ReadAt(buf, offset)
if err != nil && !errors.Is(err, io.EOF) { if err != nil && !errors.Is(err, io.EOF) {
panic(err) panic(err)
} }
fmt.Printf("Resending Packet %v\n", resend) resendPck := common.NewResendFile(pck, buf)
server.sendPacket(conn, addr, resendPck)
resendPck := NewResendFile(pck, buf)
conn.WriteToUDP(resendPck.ToBytes(), addr)
} }
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() ack, err := pck.GetUint32Payload()
if err != nil { if err != nil {
panic(err) panic(err)
} }
session := server.sessions[pck.sid] session := server.sessions[pck.Sid]
if session == nil { if session == nil {
panic(err) panic(err)
} }
@@ -94,16 +102,15 @@ func (server *Server) handleAck(conn *net.UDPConn, addr *net.UDPAddr, pck *Packe
return return
} }
if session.lastPckSend == End { if session.lastPckSend == common.End {
fmt.Printf("Deleting Session %v\n", hex.EncodeToString(pck.sid[:])) fmt.Printf("Deleting Session %v\n", hex.EncodeToString(pck.Sid[:]))
delete(server.sessions, pck.sid) delete(server.sessions, pck.Sid)
} else { } else {
fmt.Printf("Sending Data for Session %v\n", hex.EncodeToString(pck.sid[:]))
server.sendData(conn, addr, pck) 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() path, err := pck.GetFilePath()
if err != nil { if err != nil {
panic(err) panic(err)
@@ -116,23 +123,23 @@ func (server *Server) sendPTE(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet)
fileSize := fi.Size() fileSize := fi.Size()
ptePck := NewPte(uint32(fileSize), pck) ptePck := common.NewPte(uint32(fileSize), pck)
conn.WriteToUDP(ptePck.ToBytes(), addr) server.sendPacket(conn, addr, ptePck)
server.sessions[pck.sid].path = path server.sessions[pck.Sid].path = path
server.sessions[pck.sid].lastSync = ptePck.sync server.sessions[pck.Sid].lastSync = ptePck.Sync
server.sessions[pck.sid].lastPckSend = ptePck.flag server.sessions[pck.Sid].lastPckSend = ptePck.Flag
} }
func (server *Server) sendData(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet) { func (server *Server) sendData(conn *net.UDPConn, addr *net.UDPAddr, pck *common.Packet) {
path := server.sessions[pck.sid].path path := server.sessions[pck.Sid].path
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
panic(err) panic(err)
} }
defer file.Close() defer file.Close()
buf := make([]byte, PacketSize-HeaderSize) buf := make([]byte, common.PacketSize-common.HeaderSize)
filePck := pck filePck := pck
for { for {
r, err := file.Read(buf) r, err := file.Read(buf)
@@ -142,18 +149,15 @@ func (server *Server) sendData(conn *net.UDPConn, addr *net.UDPAddr, pck *Packet
if r == 0 { if r == 0 {
break break
} }
filePck = NewFile(filePck, buf[:r]) filePck = common.NewFile(filePck, buf[:r])
fmt.Printf("Sending File Packet %v\n", filePck.sync)
conn.WriteToUDP(filePck.ToBytes(), addr) server.sendPacket(conn, addr, filePck)
} }
eodPck := NewEnd(filePck) eodPck := common.NewEnd(filePck)
server.sessions[pck.sid].lastSync = eodPck.sync server.sessions[pck.Sid].lastSync = eodPck.Sync
server.sessions[pck.sid].lastPckSend = eodPck.flag server.sessions[pck.Sid].lastPckSend = eodPck.Flag
server.sendPacket(conn, addr, eodPck)
fmt.Printf("Sending Eod Packet %v\n", eodPck.sync)
conn.WriteToUDP(eodPck.ToBytes(), addr)
} }
func (server *Server) Serve() { func (server *Server) Serve() {
@@ -172,33 +176,28 @@ func (server *Server) Serve() {
} }
for { for {
var buf [PacketSize]byte var buf [common.PacketSize]byte
_, addr, err := conn.ReadFromUDP(buf[0:]) _, addr, err := conn.ReadFromUDP(buf[0:])
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return 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) pck, err := secPck.ExtractPacket(key)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
//fmt.Println("Could not establish secure connection")
} }
go server.handlePacket(conn, addr, pck) go server.handlePacket(conn, addr, &pck)
} else { } else {
key := secPck.ExtractKey() key := secPck.ExtractKey()
fmt.Println(key) fmt.Printf("Session: %v, Key: %v\n", hex.EncodeToString(secPck.Sid[:]), hex.EncodeToString(key))
fmt.Println(secPck.sid) server.sessions[secPck.Sid] = &info{
server.sessions[secPck.sid] = &info{
key: [32]byte(key), key: [32]byte(key),
} }
} }
} }
} }

View File

@@ -1,19 +1,19 @@
package main package main
import ( import (
"client"
"os" "os"
"server"
) )
const PacketSize = 504
func main() { func main() {
if os.Args[1] == "server" { if os.Args[1] == "server" {
server, err := New() server, err := server.New()
if err != nil { if err != nil {
panic(err) panic(err)
} }
server.Serve() server.Serve()
} else { } else {
GetFile(os.Args[2]) client.GetFile(os.Args[2])
} }
} }