142 lines
3.0 KiB
Go
142 lines
3.0 KiB
Go
package common
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
type Packet struct {
|
|
Flag HeaderFlag
|
|
Sync uint32
|
|
Data []byte
|
|
|
|
// NOT IN BYTES THAT ARE SENT
|
|
Sid SessionID
|
|
DataLength uint32
|
|
}
|
|
|
|
func PacketFromBytes(bytes []byte, dataLength uint32, sid SessionID) Packet {
|
|
flag := HeaderFlag(bytes[0])
|
|
sync := binary.LittleEndian.Uint32(bytes[1:5])
|
|
pck := Packet{
|
|
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)
|
|
return &Packet{
|
|
Sid: pckToAck.Sid,
|
|
Flag: Ack,
|
|
Sync: pckToAck.Sync + 1,
|
|
DataLength: uint32(4),
|
|
Data: data,
|
|
}
|
|
}
|
|
|
|
func NewRequest(path string) *Packet {
|
|
data := []byte(path)
|
|
buf := make([]byte, 32)
|
|
_, err := rand.Read(buf)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return &Packet{
|
|
Sid: SessionID(buf),
|
|
Flag: Request,
|
|
Sync: 0,
|
|
DataLength: uint32(len(data)),
|
|
Data: data,
|
|
}
|
|
}
|
|
|
|
func (pck *Packet) GetUint32Payload() (uint32, error) {
|
|
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
|
|
}
|
|
|
|
func (pck *Packet) GetFilePath() (string, error) {
|
|
if pck.Flag != Request {
|
|
return "", errors.New("Can not get FilePath from Packet that is not Request")
|
|
}
|
|
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,
|
|
}
|
|
}
|
|
|
|
func NewFile(lastPck *Packet, data []byte) *Packet {
|
|
return &Packet{
|
|
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)
|
|
return &Packet{
|
|
Sid: lastFilePck.Sid,
|
|
Flag: End,
|
|
Sync: lastFilePck.Sync + 1,
|
|
DataLength: uint32(4),
|
|
Data: data,
|
|
}
|
|
}
|
|
|
|
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,
|
|
}
|
|
}
|
|
|
|
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,
|
|
}
|
|
}
|
|
|
|
func (pck *Packet) ToBytes() []byte {
|
|
arr := make([]byte, HeaderSize+int(pck.DataLength))
|
|
arr[0] = byte(pck.Flag)
|
|
binary.LittleEndian.PutUint32(arr[1:5], pck.Sync)
|
|
copy(arr[HeaderSize:HeaderSize+int(pck.DataLength)], pck.Data)
|
|
|
|
return arr
|
|
}
|