Browse Source

[fsys] file checksums are automatically generated when GetFile is called; [protocol] ACCEPT and REJECT packets do not need to include file ids now; [node] progress on sending directories

main
Unbewohnte 3 years ago
parent
commit
eb7cd49b0e
  1. 24
      src/fsys/file.go
  2. 82
      src/node/node.go
  3. 8
      src/protocol/headers.go
  4. 10
      src/protocol/packetConstruct.go

24
src/fsys/file.go

@ -4,18 +4,18 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
)
var FileIDsCounter uint64 = 1 "github.com/Unbewohnte/ftu/checksum"
)
// A struct that represents the necessary file information for transportation through node // A struct that represents the necessary file information for transportation through node
type File struct { type File struct {
ID uint64 ID uint64 // Set manually
Name string Name string
Path string Path string
ParentPath string ParentPath string
Size uint64 Size uint64
Checksum string // Set manually Checksum string
Handler *os.File // Set when .Open() is called Handler *os.File // Set when .Open() is called
SentBytes uint64 // Set manually during transportation SentBytes uint64 // Set manually during transportation
} }
@ -43,7 +43,6 @@ func GetFile(path string) (*File, error) {
} }
file := File{ file := File{
ID: FileIDsCounter,
Name: stats.Name(), Name: stats.Name(),
Path: absPath, Path: absPath,
ParentPath: filepath.Dir(absPath), ParentPath: filepath.Dir(absPath),
@ -51,8 +50,19 @@ func GetFile(path string) (*File, error) {
Handler: nil, Handler: nil,
} }
// increment ids counter so the next file will have a different ID // get checksum
FileIDsCounter++ err = file.Open()
if err != nil {
return nil, err
}
defer file.Handler.Close()
checksum, err := checksum.GetPartialCheckSum(file.Handler)
if err != nil {
return nil, err
}
file.Checksum = checksum
return &file, nil return &file, nil
} }

82
src/node/node.go

@ -35,10 +35,12 @@ type netInfoInfo struct {
// Sending-side node information // Sending-side node information
type sending struct { type sending struct {
ServingPath string // path to the thing that will be sent ServingPath string // path to the thing that will be sent
IsDirectory bool // is ServingPath a directory IsDirectory bool // is ServingPath a directory
Recursive bool // recursively send directory Recursive bool // recursively send directory
CanSendBytes bool // is the other node ready to receive another piece CanSendBytes bool // is the other node ready to receive another piece
FilesToSend []*fsys.File
CurrentFileID uint64 // an id of a file that is currently being transported
} }
// Receiving-side node information // Receiving-side node information
@ -191,25 +193,25 @@ func (node *Node) Start() {
} }
// retrieve information about the file|directory // retrieve information about the file|directory
var file *fsys.File var fileToSend *fsys.File
var dir *fsys.Directory var dirToSend *fsys.Directory
switch node.transferInfo.Sending.IsDirectory { switch node.transferInfo.Sending.IsDirectory {
case true: case true:
dir, err = fsys.GetDir(node.transferInfo.Sending.ServingPath, node.transferInfo.Sending.Recursive) dirToSend, err = fsys.GetDir(node.transferInfo.Sending.ServingPath, node.transferInfo.Sending.Recursive)
if err != nil { if err != nil {
panic(err) panic(err)
} }
case false: case false:
file, err = fsys.GetFile(node.transferInfo.Sending.ServingPath) fileToSend, err = fsys.GetFile(node.transferInfo.Sending.ServingPath)
if err != nil { if err != nil {
panic(err) panic(err)
} }
} }
if dir != nil { if dirToSend != nil {
fmt.Printf("Sending \"%s\" (%.2f MB) locally on %s:%d\n", dir.Name, float32(dir.Size)/1024/1024, localIP, node.netInfo.Port) fmt.Printf("Sending \"%s\" (%.2f MB) locally on %s:%d\n", dirToSend.Name, float32(dirToSend.Size)/1024/1024, localIP, node.netInfo.Port)
} else { } else {
fmt.Printf("Sending \"%s\" (%.2f MB) locally on %s:%d\n", file.Name, float32(file.Size)/1024/1024, localIP, node.netInfo.Port) fmt.Printf("Sending \"%s\" (%.2f MB) locally on %s:%d\n", fileToSend.Name, float32(fileToSend.Size)/1024/1024, localIP, node.netInfo.Port)
} }
@ -233,7 +235,7 @@ func (node *Node) Start() {
go protocol.ReceivePackets(node.netInfo.Conn, node.packetPipe) go protocol.ReceivePackets(node.netInfo.Conn, node.packetPipe)
// send info about file/directory // send info about file/directory
go protocol.SendTransferOffer(node.netInfo.Conn, file, dir, node.netInfo.EncryptionKey) go protocol.SendTransferOffer(node.netInfo.Conn, fileToSend, dirToSend, node.netInfo.EncryptionKey)
// mainloop // mainloop
for { for {
@ -276,12 +278,18 @@ func (node *Node) Start() {
var filesToSend []*fsys.File var filesToSend []*fsys.File
if node.transferInfo.Sending.Recursive { if node.transferInfo.Sending.Recursive {
filesToSend = dir.GetAllFiles(true) filesToSend = dirToSend.GetAllFiles(true)
} else { } else {
filesToSend = dir.GetAllFiles(false) filesToSend = dirToSend.GetAllFiles(false)
} }
for _, file := range filesToSend { // notify the other node about all the files that are going to be sent
for counter, file := range filesToSend {
// assign ID and add it to the node sendlist
file.ID = uint64(counter)
node.transferInfo.Sending.FilesToSend = append(node.transferInfo.Sending.FilesToSend, file)
filePacket, err := protocol.CreateFilePacket(file) filePacket, err := protocol.CreateFilePacket(file)
if err != nil { if err != nil {
panic(err) panic(err)
@ -302,10 +310,15 @@ func (node *Node) Start() {
} }
} }
// set current file id to the first file
node.transferInfo.Sending.CurrentFileID = 0
case false: case false:
// send a filepacket of a single file // send a filepacket of a single file
fileToSend.ID = 0
node.transferInfo.Sending.FilesToSend = append(node.transferInfo.Sending.FilesToSend, fileToSend)
filePacket, err := protocol.CreateFilePacket(file) filePacket, err := protocol.CreateFilePacket(node.transferInfo.Sending.FilesToSend[0])
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -323,6 +336,9 @@ func (node *Node) Start() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
// set current file id to the first and only file
node.transferInfo.Sending.CurrentFileID = 0
} }
case protocol.HeaderReject: case protocol.HeaderReject:
@ -332,7 +348,6 @@ func (node *Node) Start() {
case protocol.HeaderDisconnecting: case protocol.HeaderDisconnecting:
node.state.Stopped = true node.state.Stopped = true
fmt.Printf("%s disconnected\n", node.netInfo.Conn.RemoteAddr()) fmt.Printf("%s disconnected\n", node.netInfo.Conn.RemoteAddr())
} }
@ -346,17 +361,19 @@ func (node *Node) Start() {
if !node.transferInfo.Sending.Recursive { if !node.transferInfo.Sending.Recursive {
} else { } else {
// send bytes of all files one by one
} }
case false: case false:
// sending a piece of a single file // sending a piece of a single file
err = protocol.SendPiece(file, node.netInfo.Conn, node.netInfo.EncryptionKey) currentFileID := node.transferInfo.Sending.CurrentFileID
err = protocol.SendPiece(node.transferInfo.Sending.FilesToSend[currentFileID], node.netInfo.Conn, node.netInfo.EncryptionKey)
switch err { switch err {
case protocol.ErrorSentAll: case protocol.ErrorSentAll:
// the file has been sent fully // the file has been sent fully
fileIDBuff := new(bytes.Buffer) fileIDBuff := new(bytes.Buffer)
err = binary.Write(fileIDBuff, binary.BigEndian, file.ID) err = binary.Write(fileIDBuff, binary.BigEndian, node.transferInfo.Sending.FilesToSend[currentFileID].ID)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -375,8 +392,8 @@ func (node *Node) Start() {
protocol.SendPacket(node.netInfo.Conn, endFilePacket) protocol.SendPacket(node.netInfo.Conn, endFilePacket)
// because there`s still no handling for directories - send // as only one file has been requested to send - there`s nothing else to do
// done packet // sending DONE packet
protocol.SendPacket(node.netInfo.Conn, protocol.Packet{ protocol.SendPacket(node.netInfo.Conn, protocol.Packet{
Header: protocol.HeaderDone, Header: protocol.HeaderDone,
}) })
@ -391,7 +408,8 @@ func (node *Node) Start() {
default: default:
node.state.Stopped = true node.state.Stopped = true
fmt.Printf("An error occured while sending a piece of \"%s\": %s\n", file.Name, err) currentFileID := node.transferInfo.Sending.CurrentFileID
fmt.Printf("An error occured while sending a piece of \"%s\": %s\n", node.transferInfo.Sending.FilesToSend[currentFileID].Name, err)
panic(err) panic(err)
} }
@ -465,19 +483,9 @@ func (node *Node) Start() {
// yes // yes
// send aceptance packet // send aceptance packet
responsePacketFileIDBuffer := new(bytes.Buffer)
binary.Write(responsePacketFileIDBuffer, binary.BigEndian, file.ID)
acceptancePacket := protocol.Packet{ acceptancePacket := protocol.Packet{
Header: protocol.HeaderAccept, Header: protocol.HeaderAccept,
Body: responsePacketFileIDBuffer.Bytes(),
}
if node.netInfo.EncryptionKey != nil {
err = acceptancePacket.EncryptBody(node.netInfo.EncryptionKey)
if err != nil {
panic(err)
}
} }
err = protocol.SendPacket(node.netInfo.Conn, acceptancePacket) err = protocol.SendPacket(node.netInfo.Conn, acceptancePacket)
@ -496,19 +504,9 @@ func (node *Node) Start() {
} else { } else {
// no // no
responsePacketFileIDBuffer := new(bytes.Buffer)
binary.Write(responsePacketFileIDBuffer, binary.BigEndian, file.ID)
rejectionPacket := protocol.Packet{ rejectionPacket := protocol.Packet{
Header: protocol.HeaderReject, Header: protocol.HeaderReject,
Body: responsePacketFileIDBuffer.Bytes(),
}
if node.netInfo.EncryptionKey != nil {
err = rejectionPacket.EncryptBody(node.netInfo.EncryptionKey)
if err != nil {
panic(err)
}
} }
err = protocol.SendPacket(node.netInfo.Conn, rejectionPacket) err = protocol.SendPacket(node.netInfo.Conn, rejectionPacket)

8
src/protocol/headers.go

@ -16,15 +16,13 @@ const HeaderEncryptionKey Header = "ENCRKEY"
// REJECT. // REJECT.
// Sent only by receiver if the receiver has decided to not download the contents. // Sent only by receiver if the receiver has decided to not download the contents.
// The body must contain a file ID in binary. // ie: REJECT~
// ie: REJECT~(file id in binary)
const HeaderReject Header = "REJECT" const HeaderReject Header = "REJECT"
// ACCEPT. // ACCEPT.
// The opposite of the previous REJECT. Sent by receiver when // The opposite of the previous REJECT. Sent by receiver when
// he has agreed to download the file|directory. The body must contain // he has agreed to download the file|directory.
// the ID of a file in binary that is allowed to upload // ie: ACCEPT~
// ie: ACCEPT~(file id in binary)
const HeaderAccept Header = "ACCEPT" const HeaderAccept Header = "ACCEPT"
// DONE. // DONE.

10
src/protocol/packetConstruct.go

@ -5,7 +5,6 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"github.com/Unbewohnte/ftu/checksum"
"github.com/Unbewohnte/ftu/fsys" "github.com/Unbewohnte/ftu/fsys"
) )
@ -36,14 +35,9 @@ func CreateFilePacket(file *fsys.File) (*Packet, error) {
binary.Write(fPacketBodyBuff, binary.BigEndian, &file.Size) binary.Write(fPacketBodyBuff, binary.BigEndian, &file.Size)
// checksum // checksum
fileChecksum, err := checksum.GetPartialCheckSum(file.Handler) checksumLen := uint64(len([]byte(file.Checksum)))
if err != nil {
return nil, err
}
checksumLen := uint64(len([]byte(fileChecksum)))
binary.Write(fPacketBodyBuff, binary.BigEndian, &checksumLen) binary.Write(fPacketBodyBuff, binary.BigEndian, &checksumLen)
fPacketBodyBuff.Write([]byte(fileChecksum)) fPacketBodyBuff.Write([]byte(file.Checksum))
filePacket.Body = fPacketBodyBuff.Bytes() filePacket.Body = fPacketBodyBuff.Bytes()

Loading…
Cancel
Save