From eb7cd49b0eef3e487e89bc3afa8f1bdd426e4473 Mon Sep 17 00:00:00 2001 From: Unbewohnte Date: Tue, 9 Nov 2021 10:13:32 +0300 Subject: [PATCH] [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 --- src/fsys/file.go | 24 +++++++--- src/node/node.go | 82 ++++++++++++++++----------------- src/protocol/headers.go | 8 ++-- src/protocol/packetConstruct.go | 10 +--- 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/fsys/file.go b/src/fsys/file.go index 5189a8f..557aea2 100644 --- a/src/fsys/file.go +++ b/src/fsys/file.go @@ -4,18 +4,18 @@ import ( "fmt" "os" "path/filepath" -) -var FileIDsCounter uint64 = 1 + "github.com/Unbewohnte/ftu/checksum" +) // A struct that represents the necessary file information for transportation through node type File struct { - ID uint64 + ID uint64 // Set manually Name string Path string ParentPath string Size uint64 - Checksum string // Set manually + Checksum string Handler *os.File // Set when .Open() is called SentBytes uint64 // Set manually during transportation } @@ -43,7 +43,6 @@ func GetFile(path string) (*File, error) { } file := File{ - ID: FileIDsCounter, Name: stats.Name(), Path: absPath, ParentPath: filepath.Dir(absPath), @@ -51,8 +50,19 @@ func GetFile(path string) (*File, error) { Handler: nil, } - // increment ids counter so the next file will have a different ID - FileIDsCounter++ + // get checksum + 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 } diff --git a/src/node/node.go b/src/node/node.go index 89f027a..d6296bd 100644 --- a/src/node/node.go +++ b/src/node/node.go @@ -35,10 +35,12 @@ type netInfoInfo struct { // Sending-side node information type sending struct { - ServingPath string // path to the thing that will be sent - IsDirectory bool // is ServingPath a directory - Recursive bool // recursively send directory - CanSendBytes bool // is the other node ready to receive another piece + ServingPath string // path to the thing that will be sent + IsDirectory bool // is ServingPath a directory + Recursive bool // recursively send directory + 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 @@ -191,25 +193,25 @@ func (node *Node) Start() { } // retrieve information about the file|directory - var file *fsys.File - var dir *fsys.Directory + var fileToSend *fsys.File + var dirToSend *fsys.Directory switch node.transferInfo.Sending.IsDirectory { 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 { panic(err) } case false: - file, err = fsys.GetFile(node.transferInfo.Sending.ServingPath) + fileToSend, err = fsys.GetFile(node.transferInfo.Sending.ServingPath) if err != nil { panic(err) } } - if dir != nil { - fmt.Printf("Sending \"%s\" (%.2f MB) locally on %s:%d\n", dir.Name, float32(dir.Size)/1024/1024, localIP, node.netInfo.Port) + if dirToSend != nil { + fmt.Printf("Sending \"%s\" (%.2f MB) locally on %s:%d\n", dirToSend.Name, float32(dirToSend.Size)/1024/1024, localIP, node.netInfo.Port) } 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) // 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 for { @@ -276,12 +278,18 @@ func (node *Node) Start() { var filesToSend []*fsys.File if node.transferInfo.Sending.Recursive { - filesToSend = dir.GetAllFiles(true) + filesToSend = dirToSend.GetAllFiles(true) } 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) if err != nil { 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: // 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 { panic(err) } @@ -323,6 +336,9 @@ func (node *Node) Start() { if err != nil { panic(err) } + + // set current file id to the first and only file + node.transferInfo.Sending.CurrentFileID = 0 } case protocol.HeaderReject: @@ -332,7 +348,6 @@ func (node *Node) Start() { case protocol.HeaderDisconnecting: node.state.Stopped = true - fmt.Printf("%s disconnected\n", node.netInfo.Conn.RemoteAddr()) } @@ -346,17 +361,19 @@ func (node *Node) Start() { if !node.transferInfo.Sending.Recursive { } else { + // send bytes of all files one by one } case false: // 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 { case protocol.ErrorSentAll: // the file has been sent fully 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 { panic(err) } @@ -375,8 +392,8 @@ func (node *Node) Start() { protocol.SendPacket(node.netInfo.Conn, endFilePacket) - // because there`s still no handling for directories - send - // done packet + // as only one file has been requested to send - there`s nothing else to do + // sending DONE packet protocol.SendPacket(node.netInfo.Conn, protocol.Packet{ Header: protocol.HeaderDone, }) @@ -391,7 +408,8 @@ func (node *Node) Start() { default: 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) } @@ -465,19 +483,9 @@ func (node *Node) Start() { // yes // send aceptance packet - responsePacketFileIDBuffer := new(bytes.Buffer) - binary.Write(responsePacketFileIDBuffer, binary.BigEndian, file.ID) acceptancePacket := protocol.Packet{ 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) @@ -496,19 +504,9 @@ func (node *Node) Start() { } else { // no - responsePacketFileIDBuffer := new(bytes.Buffer) - binary.Write(responsePacketFileIDBuffer, binary.BigEndian, file.ID) rejectionPacket := protocol.Packet{ 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) diff --git a/src/protocol/headers.go b/src/protocol/headers.go index 88d06a7..308aff4 100644 --- a/src/protocol/headers.go +++ b/src/protocol/headers.go @@ -16,15 +16,13 @@ const HeaderEncryptionKey Header = "ENCRKEY" // REJECT. // 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~(file id in binary) +// ie: REJECT~ const HeaderReject Header = "REJECT" // ACCEPT. // The opposite of the previous REJECT. Sent by receiver when -// he has agreed to download the file|directory. The body must contain -// the ID of a file in binary that is allowed to upload -// ie: ACCEPT~(file id in binary) +// he has agreed to download the file|directory. +// ie: ACCEPT~ const HeaderAccept Header = "ACCEPT" // DONE. diff --git a/src/protocol/packetConstruct.go b/src/protocol/packetConstruct.go index ce98c58..f2e1915 100644 --- a/src/protocol/packetConstruct.go +++ b/src/protocol/packetConstruct.go @@ -5,7 +5,6 @@ import ( "bytes" "encoding/binary" - "github.com/Unbewohnte/ftu/checksum" "github.com/Unbewohnte/ftu/fsys" ) @@ -36,14 +35,9 @@ func CreateFilePacket(file *fsys.File) (*Packet, error) { binary.Write(fPacketBodyBuff, binary.BigEndian, &file.Size) // checksum - fileChecksum, err := checksum.GetPartialCheckSum(file.Handler) - if err != nil { - return nil, err - } - - checksumLen := uint64(len([]byte(fileChecksum))) + checksumLen := uint64(len([]byte(file.Checksum))) binary.Write(fPacketBodyBuff, binary.BigEndian, &checksumLen) - fPacketBodyBuff.Write([]byte(fileChecksum)) + fPacketBodyBuff.Write([]byte(file.Checksum)) filePacket.Body = fPacketBodyBuff.Bytes()