/*
NNCP -- Node to Node copy, utilities for store-and-forward data exchange
-Copyright (C) 2016-2021 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2016-2022 Sergey Matveev <stargrave@stargrave.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
src io.Reader,
pktName string,
areaId *AreaId,
-) (*Node, int64, error) {
+) (*Node, int64, string, error) {
var area *Area
if areaId != nil {
area = ctx.AreaId2Area[*areaId]
if area.Prv == nil {
- return nil, 0, errors.New("area has no encryption keys")
+ return nil, 0, "", errors.New("area has no encryption keys")
}
}
hops := make([]*Node, 0, 1+len(node.Via))
expectedSize += sizePadCalc(expectedSize, minSize, wrappers)
expectedSize = PktEncOverhead + sizeWithTags(expectedSize)
if maxSize != 0 && expectedSize > maxSize {
- return nil, 0, TooBig
+ return nil, 0, "", TooBig
}
if !ctx.IsEnoughSpace(expectedSize) {
- return nil, 0, errors.New("is not enough space")
+ return nil, 0, "", errors.New("is not enough space")
}
}
tmp, err := ctx.NewTmpFileWHash()
if err != nil {
- return nil, 0, err
+ return nil, 0, "", err
}
results := make(chan PktEncWriteResult)
}()
var pktEncRaw []byte
var pktEncMsg []byte
+ var payloadSize int64
if area != nil {
- pktEncMsg = (<-results).pktEncRaw
+ r := <-results
+ payloadSize = r.size
+ pktEncMsg = r.pktEncRaw
+ wrappers--
}
- var finalSize int64
for i := 0; i <= wrappers; i++ {
r := <-results
if r.err != nil {
tmp.Fd.Close()
- return nil, 0, err
+ return nil, 0, "", r.err
}
if r.pktEncRaw != nil {
- finalSize = r.size
pktEncRaw = r.pktEncRaw
+ if payloadSize == 0 {
+ payloadSize = r.size
+ }
}
}
nodePath := filepath.Join(ctx.Spool, lastNode.Id.String())
err = tmp.Commit(filepath.Join(nodePath, string(TTx)))
os.Symlink(nodePath, filepath.Join(ctx.Spool, lastNode.Name))
if err != nil {
- return lastNode, 0, err
+ return lastNode, 0, "", err
}
if ctx.HdrUsage {
ctx.HdrWrite(pktEncRaw, filepath.Join(nodePath, string(TTx), tmp.Checksum()))
}
if err = ensureDir(seenDir); err != nil {
ctx.LogE("tx-mkdir", les, err, logMsg)
- return lastNode, 0, err
+ return lastNode, 0, "", err
}
if fd, err := os.Create(seenPath); err == nil {
fd.Close()
if err = DirSync(seenDir); err != nil {
ctx.LogE("tx-dirsync", les, err, logMsg)
- return lastNode, 0, err
+ return lastNode, 0, "", err
}
}
ctx.LogI("tx-area", les, logMsg)
}
- return lastNode, finalSize, err
+ return lastNode, payloadSize, tmp.Checksum(), err
}
type DummyCloser struct{}
if err != nil {
return err
}
- if info.IsDir() {
+ if info.Mode().IsDir() {
// directory header, PAX record header+contents
srcSize += TarBlockSize + 2*TarBlockSize
dirs = append(dirs, einfo{path: path, modTime: info.ModTime()})
- } else {
+ } else if info.Mode().IsRegular() {
// file header, PAX record header+contents, file content
srcSize += TarBlockSize + 2*TarBlockSize + info.Size()
if n := info.Size() % TarBlockSize; n != 0 {
if err != nil {
return err
}
- _, finalSize, err := ctx.Tx(
+ _, finalSize, pktName, err := ctx.Tx(
node, pkt, nice,
srcSize, minSize, maxSize,
bufio.NewReader(reader), dstPath, areaId,
{"Src", srcPath},
{"Dst", dstPath},
{"Size", finalSize},
+ {"Pkt", pktName},
}
logMsg := func(les LEs) string {
return fmt.Sprintf(
- "File %s (%s) sent to %s:%s",
+ "File %s (%s) is sent to %s:%s",
srcPath,
humanize.IBytes(uint64(finalSize)),
ctx.NodeName(node.Id),
return err
}
hsh := MTHNew(0, 0)
- _, size, err := ctx.Tx(
+ _, size, pktName, err := ctx.Tx(
node, pkt, nice,
0, minSize, maxSize,
io.TeeReader(lr, hsh),
{"Src", srcPath},
{"Dst", path},
{"Size", size},
+ {"Pkt", pktName},
}
logMsg := func(les LEs) string {
return fmt.Sprintf(
- "File %s (%s) sent to %s:%s",
+ "File %s (%s) is sent to %s:%s",
srcPath,
humanize.IBytes(uint64(size)),
ctx.NodeName(node.Id),
return err
}
metaPktSize := int64(buf.Len())
- _, _, err = ctx.Tx(
+ _, _, pktName, err := ctx.Tx(
node,
pkt,
nice,
{"Src", srcPath},
{"Dst", path},
{"Size", metaPktSize},
+ {"Pkt", pktName},
}
logMsg := func(les LEs) string {
return fmt.Sprintf(
- "File %s (%s) sent to %s:%s",
+ "File %s (%s) is sent to %s:%s",
srcPath,
humanize.IBytes(uint64(metaPktSize)),
ctx.NodeName(node.Id),
}
src := strings.NewReader(dstPath)
size := int64(src.Len())
- _, _, err = ctx.Tx(node, pkt, nice, size, minSize, MaxFileSize, src, srcPath, nil)
+ _, _, pktName, err := ctx.Tx(
+ node, pkt, nice, size, minSize, MaxFileSize, src, srcPath, nil,
+ )
les := LEs{
{"Type", "freq"},
{"Node", node.Id},
{"ReplyNice", int(replyNice)},
{"Src", srcPath},
{"Dst", dstPath},
+ {"Pkt", pktName},
}
logMsg := func(les LEs) string {
return fmt.Sprintf(
- "File request from %s:%s to %s sent",
+ "File request from %s:%s to %s is sent",
ctx.NodeName(node.Id), srcPath,
dstPath,
)
}(in)
in = pr
}
- _, size, err := ctx.Tx(node, pkt, nice, 0, minSize, maxSize, in, handle, areaId)
+ _, size, pktName, err := ctx.Tx(
+ node, pkt, nice, 0, minSize, maxSize, in, handle, areaId,
+ )
if !noCompress {
e := <-compressErr
if err == nil {
{"ReplyNice", int(replyNice)},
{"Dst", dst},
{"Size", size},
+ {"Pkt", pktName},
}
logMsg := func(les LEs) string {
return fmt.Sprintf(
- "Exec sent to %s@%s (%s)",
+ "Exec is sent to %s@%s (%s)",
ctx.NodeName(node.Id), dst, humanize.IBytes(uint64(size)),
)
}
os.Symlink(nodePath, filepath.Join(ctx.Spool, node.Name))
return err
}
+
+func (ctx *Ctx) TxACK(
+ node *Node,
+ nice uint8,
+ hsh string,
+ minSize int64,
+) (pktName string, err error) {
+ hshRaw, err := Base32Codec.DecodeString(hsh)
+ if err != nil {
+ return "", err
+ }
+ if len(hshRaw) != MTHSize {
+ return "", errors.New("Invalid packet id size")
+ }
+ pkt, err := NewPkt(PktTypeACK, nice, []byte(hshRaw))
+ if err != nil {
+ return "", err
+ }
+ src := bytes.NewReader([]byte{})
+ _, _, pktName, err = ctx.Tx(
+ node, pkt, nice, 0, minSize, MaxFileSize, src, hsh, nil,
+ )
+ les := LEs{
+ {"Type", "ack"},
+ {"Node", node.Id},
+ {"Nice", int(nice)},
+ {"Pkt", hsh},
+ {"NewPkt", pktName},
+ }
+ logMsg := func(les LEs) string {
+ return fmt.Sprintf("ACK to %s of %s is sent", ctx.NodeName(node.Id), hsh)
+ }
+ if err == nil {
+ ctx.LogI("tx", les, logMsg)
+ } else {
+ ctx.LogE("tx", les, err, logMsg)
+ }
+ return
+}