From 68d8c1187273f64a6990d4fed68274aae45d5f99 Mon Sep 17 00:00:00 2001 From: Kleissner Date: Tue, 30 Nov 2021 03:53:19 +0100 Subject: [PATCH] Refactor file transfer header encoding into protocol sub-module. --- Transfer UDT.go | 35 +++------------------------- protocol/File Transfer.go | 49 +++++++++++++++++++++++++++++++++++++++ webapi/File IO.go | 2 +- 3 files changed, 53 insertions(+), 33 deletions(-) create mode 100644 protocol/File Transfer.go diff --git a/Transfer UDT.go b/Transfer UDT.go index a942566..b41ce01 100644 --- a/Transfer UDT.go +++ b/Transfer UDT.go @@ -3,19 +3,12 @@ File Name: Transfer UDT.go Copyright: 2021 Peernet s.r.o. Author: Peter Kleissner -Each transfer over UDT starts with a header: -Offset Size Info -0 8 Total File Size. -8 8 Transfer Size. - TODO: Add timeouts for listening and sending. - */ package core import ( - "encoding/binary" "errors" "net" "time" @@ -62,15 +55,8 @@ func (peer *PeerInfo) startFileTransferUDT(hash []byte, fileSize uint64, offset, defer udtConn.Close() - // Start by sending the header: Total File Size and Transfer Size. - header := make([]byte, 16) - binary.LittleEndian.PutUint64(header[0:8], fileSize) - binary.LittleEndian.PutUint64(header[8:16], limit) - if n, err := udtConn.Write(header); err != nil { - return err - } else if n != len(header) { - return errors.New("error sending header") - } + // First send the header (Total File Size, Transfer Size) and then the file data. + protocol.FileTransferWriteHeader(udtConn, fileSize, limit) _, _, err = UserWarehouse.ReadFile(hash, int64(offset), int64(limit), udtConn) @@ -79,6 +65,7 @@ func (peer *PeerInfo) startFileTransferUDT(hash []byte, fileSize uint64, offset, // FileTransferRequestUDT creates a UDT server listening for incoming data transfer and requests a file transfer from a remote peer. // The caller must call udtConn.Close() when done. Do not use any of the closing functions of virtualConn. +// Limit is optional. 0 means the entire file. func (peer *PeerInfo) FileTransferRequestUDT(hash []byte, offset, limit uint64) (udtConn net.Conn, virtualConn *virtualPacketConn, err error) { virtualConn = newVirtualPacketConn(peer, 0, hash, offset, limit) @@ -110,19 +97,3 @@ func (peer *PeerInfo) FileTransferRequestUDT(hash []byte, offset, limit uint64) return udtConn, virtualConn, nil } - -// FileTransferReadHeaderUDT starts reading a file via UDT. It will only read the header and keeps the connection open. -func FileTransferReadHeaderUDT(udtConn net.Conn) (fileSize, transferSize uint64, err error) { - // read the header - header := make([]byte, 16) - if n, err := udtConn.Read(header); err != nil { - return 0, 0, err - } else if n != len(header) { - return 0, 0, errors.New("error reading header") - } - - fileSize = binary.LittleEndian.Uint64(header[0:8]) - transferSize = binary.LittleEndian.Uint64(header[8:16]) - - return fileSize, transferSize, nil -} diff --git a/protocol/File Transfer.go b/protocol/File Transfer.go new file mode 100644 index 0000000..50c8456 --- /dev/null +++ b/protocol/File Transfer.go @@ -0,0 +1,49 @@ +/* +File Name: File Transfer.go +Copyright: 2021 Peernet s.r.o. +Author: Peter Kleissner + +Encoding of file transfer protocol. Each transfer starts with a header: +Offset Size Info +0 8 Total File Size +8 8 Transfer Size +*/ + +package protocol + +import ( + "encoding/binary" + "errors" + "io" +) + +// FileTransferWriteHeader starts writing the header for a file transfer. +func FileTransferWriteHeader(writer io.Writer, fileSize, transferSize uint64) (err error) { + // Send the header: Total File Size and Transfer Size. + header := make([]byte, 16) + binary.LittleEndian.PutUint64(header[0:8], fileSize) + binary.LittleEndian.PutUint64(header[8:16], transferSize) + if n, err := writer.Write(header); err != nil { + return err + } else if n != len(header) { + return errors.New("error sending header") + } + + return nil +} + +// FileTransferReadHeader starts reading the header for a file transfer. It will only read the header and keeps the connection open. +func FileTransferReadHeader(reader io.Reader) (fileSize, transferSize uint64, err error) { + // read the header + header := make([]byte, 16) + if n, err := reader.Read(header); err != nil { + return 0, 0, err + } else if n != len(header) { + return 0, 0, errors.New("error reading header") + } + + fileSize = binary.LittleEndian.Uint64(header[0:8]) + transferSize = binary.LittleEndian.Uint64(header[8:16]) + + return fileSize, transferSize, nil +} diff --git a/webapi/File IO.go b/webapi/File IO.go index 8b8b303..ddf3d3d 100644 --- a/webapi/File IO.go +++ b/webapi/File IO.go @@ -285,7 +285,7 @@ func FileStartReader(peer *core.PeerInfo, hash []byte, offset, limit uint64, can }() } - fileSize, transferSize, err = core.FileTransferReadHeaderUDT(udtConn) + fileSize, transferSize, err = protocol.FileTransferReadHeader(udtConn) if err != nil { udtConn.Close() return nil, 0, 0, err