]> Cypherpunks.ru repositories - nncp.git/commitdiff
Merge branch 'develop' v8.7.0
authorSergey Matveev <stargrave@stargrave.org>
Fri, 4 Mar 2022 13:51:18 +0000 (16:51 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Fri, 4 Mar 2022 13:51:18 +0000 (16:51 +0300)
15 files changed:
doc/cmd/nncp-ack.texi
doc/cmd/nncp-cfgdir.texi
doc/cmd/nncp-hash.texi
doc/cmd/nncp-rm.texi
doc/download.texi
doc/news.ru.texi
doc/news.texi
ports/nncp/Makefile
src/cmd/nncp-ack/main.go
src/cmd/nncp-rm/main.go
src/cmd/nncp-trns/main.go
src/nncp.go
src/toss.go
src/tx.go
src/tx_test.go

index 5635cc15c27158f9e15677165b2ff1626650dcbb..a3b374da2c6f65bcc297c24161d5279dadef579e 100644 (file)
@@ -7,6 +7,8 @@
 $ nncp-ack [options] -all
 $ nncp-ack [options] -node NODE[,@dots{}]
 $ nncp-ack [options] -node NODE -pkt PKT
+
+$ nncp-ack [@dots{}] 4>&1 >&2 | nncp-rm [@dots{}] -pkt
 @end example
 
 Send acknowledgement of successful @option{PKT} (Base32-encoded hash)
@@ -14,6 +16,11 @@ packet receipt from @option{NODE} node. If no @option{-pkt} is
 specified, then acknowledge all packet in node's @code{rx} outbound
 spool. If @option{-all} is specified, then do that for all nodes.
 
+That commands outputs list of created encrypted ACK packets
+(@code{NODE/PKT}) to @strong{4}th file descriptor. That output can be
+passed for example to @command{@ref{nncp-rm}} to remove them after
+transmission to not wait for acknowledgement and retransmission.
+
 General workflow with acknowledgement is following, assuming that
 Alice has some outbound packets for Bob:
 
@@ -33,16 +40,24 @@ bob$ nncp-xfer -rx /mnt/shared
 
 That will also check if copied packets checksum is not mismatched.
 
-@item Create ACK packets of received ones:
+@item Create ACK packets of received ones, saving the list of encrypted
+    ACK packets:
 
 @example
-bob$ nncp-ack -node alice
+bob$ nncp-ack -node alice 4>acks
 @end example
 
 @item Send those newly created packets back to Alice:
 
 @example
-bob$ nncp-xfer -tx /mnt/shared
+bob$ nncp-xfer [-keep] -tx /mnt/shared
+@end example
+
+@item Remove them from outbound spool, because we expect no
+    acknowledgement for them:
+
+@example
+bob$ nncp-rm -node alice -pkt <acks
 @end example
 
 @item Get those acknowledgement packets and @ref{nncp-toss, toss} them:
index 853dd107aa99e0837214af7e55aa73f2d57a7f4d..0750ade2538953e824362257e696ad04dce5dcca 100644 (file)
@@ -10,4 +10,4 @@ $ nncp-cfgdir [options] -load /path/to/dir > cfg.hjson
 @option{-dump} option dumps current configuration file to the
 @ref{Configuration directory, directory layout} at @file{/path/to/dir}.
 @option{-load} loads it and parses, outputing the resulting Hjson to
-stdout.
+@code{stdout}.
index afed745b6c2e07caab82d5ddd7bd6c3b55b882b7..17987e0965081b98a7e334fde23ee2a06b997fca 100644 (file)
@@ -6,7 +6,7 @@
 $ nncp-hash [-file @dots{}] [-seek X] [-debug] [-progress]
 @end example
 
-Calculate @ref{MTH} hash of either stdin, or @option{-file} if
+Calculate @ref{MTH} hash of either @code{stdin}, or @option{-file} if
 specified.
 
 You can optionally force seeking the file first, reading only part of
index 4c74f0aa1fb5b0bd12b1ec605c99ba4a581dc26a..02676732165fcc136374e3163dc3f7640d061113 100644 (file)
@@ -11,7 +11,12 @@ $ nncp-rm [options] @{-all|-node NODE@} -nock
 $ nncp-rm [options] @{-all|-node NODE@} -hdr
 $ nncp-rm [options] @{-all|-node NODE@} -area
 $ nncp-rm [options] @{-all|-node NODE@} [-rx] [-tx]
-$ nncp-rm [options] @{-all|-node NODE@} -pkt PKT
+$ nncp-rm [options] @{-all|-node NODE@} -pkt <<EOF
+PKT1
+PKT2
+NODEx/PKT3
+@dots{}
+EOF
 @end example
 
 This command is aimed to delete various files from your spool directory:
@@ -25,9 +30,10 @@ commands like @command{@ref{nncp-file}} fail for some reason.
 @item If @option{-lock} option is specified, then all @file{.lock} files
 will be deleted in your spool directory.
 
-@item If @option{-pkt} option is specified, then @file{PKT} packet (its
-Base32 name) will be deleted. This is useful when you see some packet
-failing to be processed.
+@item If @option{-pkt} option is specified, then list of packets (Base32
+names) toe be deleted is read from @code{stdin}. This could be useful
+when you see some packet failing to be processed. Packet identifiers
+could have "directories" prepended, that are ignored.
 
 @item When either @option{-rx} or @option{-tx} options are specified
 (maybe both of them), then delete all packets from that given queues.
index f6c259e79b94b927b5073aabcba4b220bbb4f7f7..3b9c704d99748998574156580aa19130f59a0e50 100644 (file)
@@ -49,6 +49,13 @@ And additional ones for Yggdrasil support:
 @multitable {XXXXX} {XXXX-XX-XX} {XXXX KiB} {meta4 link sig} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
 @headitem Version @tab Date @tab Size @tab Tarball @tab SHA256 checksum
 
+@item @ref{Release 8_6_0, 8.6.0} @tab 2022-03-02 @tab 1670 KiB
+@tab
+    @url{download/nncp-8.6.0.tar.xz.meta4, meta4}
+    @url{download/nncp-8.6.0.tar.xz, link}
+    @url{download/nncp-8.6.0.tar.xz.sig, sig}
+@tab @code{AE16F0A0 9C1B7D1D A3767E1C 0F410D9C 29ACCAE6 32A448A9 55DB4A0F 15BF838F}
+
 @item @ref{Release 8_5_0, 8.5.0} @tab 2022-01-26 @tab 1685 KiB
 @tab
     @url{download/nncp-8.5.0.tar.xz.meta4, meta4}
index eae883ac2d992af1a8cc5b07710f31b20f3a9735..28ce8a0f72ac9568de0f03940b8f7025ea683404 100644 (file)
@@ -1,6 +1,28 @@
 @node Новости
 @section Новости
 
+@node Релиз 8.7.0
+@subsection Релиз 8.7.0
+@itemize
+
+@item
+@command{nncp-ack} не подтверждает ACK-пакеты, предотвращая бесконечную
+петлю из ACK-ов.
+
+@item
+В прошлом, @command{nncp-ack} не удаляла соответствующие @file{hdr/} файлы.
+
+@item
+@command{nncp-rm} теперь берёт список пакетов из @code{stdin}, при
+использовании @option{-pkt} опции.
+
+@item
+@command{nncp-ack} теперь генерирует список ACK пакетов, которые были
+созданы, что может использоваться в качестве ввода для @command{nncp-rm}
+команды, чтобы удалить исходящие ACK пакеты.
+
+@end itemize
+
 @node Релиз 8.6.0
 @subsection Релиз 8.6.0
 @itemize
@@ -345,7 +367,7 @@ NNCP собирается на NetBSD.
 
 @item
 Исправлена работоспособность @command{nncp-file} и @command{nncp-exec}
-команд использующих временный файл (stdin и @option{-use-tmp}).
+команд использующих временный файл (@code{stdin} и @option{-use-tmp}).
 
 @item
 Исправлен пропадающий плохой код возврата в @command{nncp-exec} команде.
index 884a91e1d971ac2b2a16bba0f905fd7d44950b8f..e18445adaa0e7deca5a1e2119b5a83d5b79954d3 100644 (file)
@@ -4,6 +4,28 @@
 
 See also this page @ref{Новости, on russian}.
 
+@node Release 8_7_0
+@section Release 8.7.0
+@itemize
+
+@item
+@command{nncp-ack} does not acknowledge ACK-packets, preventing an
+endless loop of ACKs.
+
+@item
+@command{nncp-ack} previously did not remove corresponding @file{hdr/} files.
+
+@item
+@command{nncp-rm} now takes list of packet from @code{stdin} when
+@option{-pkt} option is used.
+
+@item
+@command{nncp-ack} now generates list of ACK packets it created, that
+could be used as an input to @command{nncp-rm} to remove outbound ACK
+packets.
+
+@end itemize
+
 @node Release 8_6_0
 @section Release 8.6.0
 @itemize
@@ -338,7 +360,7 @@ plain packet type with @command{nncp-toss}, @command{nncp-file} and
 
 @item
 Fixed workability of @command{nncp-file} and @command{nncp-exec}
-commands, that use temporary file (stdin and @option{-use-tmp}).
+commands, that use temporary file (@code{stdin} and @option{-use-tmp}).
 
 @item
 Fixed disappearing bad return code in @command{nncp-exec} command.
index 05c0ad1bdaa4a3bab031dea295487e4ae90a2600..b959a327403aae08a2adb851089394f402e50723 100644 (file)
@@ -1,5 +1,5 @@
 PORTNAME=      nncp
-DISTVERSION=   8.6.0
+DISTVERSION=   8.7.0
 CATEGORIES=    net
 MASTER_SITES=  http://www.nncpgo.org/download/
 
index e97202811230ac269fd321cd6e9d4d0c2c7aa816..d7e8f0185697ba364298f1d5aba10535c46ac6cc 100644 (file)
@@ -19,13 +19,17 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 package main
 
 import (
+       "bufio"
+       "errors"
        "flag"
        "fmt"
+       "io"
        "log"
        "os"
        "path/filepath"
        "strings"
 
+       xdr "github.com/davecgh/go-xdr/xdr2"
        "go.cypherpunks.ru/nncp/v8"
 )
 
@@ -33,8 +37,8 @@ func usage() {
        fmt.Fprintf(os.Stderr, nncp.UsageHeader())
        fmt.Fprintf(os.Stderr, "nncp-ack -- send packet receipt acknowledgement\n\n")
        fmt.Fprintf(os.Stderr, "Usage: %s [options] -all\n", os.Args[0])
-       fmt.Fprintf(os.Stderr, "Usage: %s           -node NODE[,...]\n", os.Args[0])
-       fmt.Fprintf(os.Stderr, "Usage: %s           -node NODE -pkt PKT\n", os.Args[0])
+       fmt.Fprintf(os.Stderr, "Usage: %s [options] -node NODE[,...]\n", os.Args[0])
+       fmt.Fprintf(os.Stderr, "Usage: %s [options] -node NODE -pkt PKT\n", os.Args[0])
        fmt.Fprintln(os.Stderr, "Options:")
        flag.PrintDefaults()
 }
@@ -115,24 +119,119 @@ func main() {
                os.Exit(1)
        }
 
+       acksCreated := os.NewFile(uintptr(4), "ACKsCreated")
+       if acksCreated == nil {
+               log.Fatalln("can not open FD:4")
+       }
+
        if *pktRaw != "" {
                if len(nodes) != 1 {
                        usage()
                        os.Exit(1)
                }
                nncp.ViaOverride(*viaOverride, ctx, nodes[0])
-               if err = ctx.TxACK(nodes[0], nice, *pktRaw, minSize); err != nil {
+               pktName, err := ctx.TxACK(nodes[0], nice, *pktRaw, minSize)
+               if err != nil {
                        log.Fatalln(err)
                }
+               acksCreated.WriteString(nodes[0].Id.String() + "/" + pktName + "\n")
                return
        }
 
+       isBad := false
        for _, node := range nodes {
                for job := range ctx.Jobs(node.Id, nncp.TRx) {
                        pktName := filepath.Base(job.Path)
-                       if err = ctx.TxACK(node, nice, pktName, minSize); err != nil {
+                       sender := ctx.Neigh[*job.PktEnc.Sender]
+                       les := nncp.LEs{
+                               {K: "Node", V: job.PktEnc.Sender},
+                               {K: "Pkt", V: pktName},
+                       }
+                       logMsg := func(les nncp.LEs) string {
+                               return fmt.Sprintf(
+                                       "ACKing %s/%s",
+                                       ctx.NodeName(job.PktEnc.Sender), pktName,
+                               )
+                       }
+                       if sender == nil {
+                               err := errors.New("unknown node")
+                               ctx.LogE("ack-read", les, err, logMsg)
+                               isBad = true
+                               continue
+                       }
+                       fd, err := os.Open(job.Path)
+                       if err != nil {
+                               ctx.LogE("ack-read-open", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": opening" + job.Path
+                               })
+                               isBad = true
+                               continue
+                       }
+                       pktEnc, _, err := ctx.HdrRead(fd)
+                       if err != nil {
+                               fd.Close()
+                               ctx.LogE("ack-read-read", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": reading" + job.Path
+                               })
+                               isBad = true
+                               continue
+                       }
+                       switch pktEnc.Magic {
+                       case nncp.MagicNNCPEv1.B:
+                               err = nncp.MagicNNCPEv1.TooOld()
+                       case nncp.MagicNNCPEv2.B:
+                               err = nncp.MagicNNCPEv2.TooOld()
+                       case nncp.MagicNNCPEv3.B:
+                               err = nncp.MagicNNCPEv3.TooOld()
+                       case nncp.MagicNNCPEv4.B:
+                               err = nncp.MagicNNCPEv4.TooOld()
+                       case nncp.MagicNNCPEv5.B:
+                               err = nncp.MagicNNCPEv5.TooOld()
+                       case nncp.MagicNNCPEv6.B:
+                       default:
+                               err = errors.New("is not an encrypted packet")
+                       }
+                       if err != nil {
+                               fd.Close()
+                               ctx.LogE("ack-read-magic", les, err, logMsg)
+                               isBad = true
+                               continue
+                       }
+                       if _, err = fd.Seek(0, io.SeekStart); err != nil {
+                               fd.Close()
+                               ctx.LogE("ack-read-seek", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": seeking"
+                               })
+                               isBad = true
+                               continue
+                       }
+                       pipeR, pipeW := io.Pipe()
+                       go nncp.PktEncRead(ctx.Self, ctx.Neigh, bufio.NewReader(fd), pipeW, true, nil)
+                       var pkt nncp.Pkt
+                       _, err = xdr.Unmarshal(pipeR, &pkt)
+                       fd.Close()
+                       pipeW.Close()
+                       if err != nil {
+                               ctx.LogE("ack-read-unmarshal", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": unmarshal"
+                               })
+                               isBad = true
+                               continue
+                       }
+                       if pkt.Type == nncp.PktTypeACK {
+                               ctx.LogI("ack-read-if-ack", les, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": it is ACK, skipping"
+                               })
+                               continue
+                       }
+                       newPktName, err := ctx.TxACK(node, nice, pktName, minSize)
+                       if err != nil {
                                log.Fatalln(err)
                        }
+                       acksCreated.WriteString(node.Id.String() + "/" + newPktName + "\n")
                }
        }
+       if isBad {
+               os.Exit(1)
+       }
 }
index 67f66574f1a9c5d48ced22f41c7a263c1861e306..814028c74cc0a23002489d9f590e43bb35bc38e3 100644 (file)
@@ -21,6 +21,7 @@ package main
 import (
        "flag"
        "fmt"
+       "io"
        "log"
        "os"
        "path/filepath"
@@ -43,7 +44,7 @@ func usage() {
        fmt.Fprintf(os.Stderr, "       %s [options] {-all|-node NODE} -hdr\n", os.Args[0])
        fmt.Fprintf(os.Stderr, "       %s [options] {-all|-node NODE} -area\n", os.Args[0])
        fmt.Fprintf(os.Stderr, "       %s [options] {-all|-node NODE} {-rx|-tx}\n", os.Args[0])
-       fmt.Fprintf(os.Stderr, "       %s [options] {-all|-node NODE} -pkt PKT\n", os.Args[0])
+       fmt.Fprintf(os.Stderr, "       %s [options] {-all|-node NODE} -pkt < ...\n", os.Args[0])
        fmt.Fprintln(os.Stderr, "-older option's time units are: (s)econds, (m)inutes, (h)ours, (d)ays")
        fmt.Fprintln(os.Stderr, "Options:")
        flag.PrintDefaults()
@@ -65,7 +66,7 @@ func main() {
                doArea    = flag.Bool("area", false, "Remove only area/* seen files")
                older     = flag.String("older", "", "XXX{smhd}: only older than XXX number of time units")
                dryRun    = flag.Bool("dryrun", false, "Do not actually remove files")
-               pktRaw    = flag.String("pkt", "", "Packet to remove")
+               doPkt     = flag.Bool("pkt", false, "Packet to remove TODO")
                spoolPath = flag.String("spool", "", "Override path to spool")
                quiet     = flag.Bool("quiet", false, "Print only errors")
                debug     = flag.Bool("debug", false, "Print debug messages")
@@ -114,6 +115,21 @@ func main() {
        }
        oldBoundary := time.Second * time.Duration(oldBoundaryRaw)
 
+       pkts := make(map[string]struct{})
+       if *doPkt {
+               raw, err := io.ReadAll(os.Stdin)
+               if err != nil {
+                       log.Fatalln("can not read -pkt from stdin:", err)
+               }
+               for _, line := range strings.Split(string(raw), "\n") {
+                       if len(line) == 0 {
+                               continue
+                       }
+                       cols := strings.Split(line, "/")
+                       pkts[cols[len(cols)-1]] = struct{}{}
+               }
+       }
+
        now := time.Now()
        if *doTmp {
                err = filepath.Walk(
@@ -215,12 +231,14 @@ func main() {
                                                }
                                                return os.Remove(path)
                                        }
-                                       if *pktRaw != "" && filepath.Base(info.Name()) == *pktRaw {
-                                               ctx.LogI("rm", nncp.LEs{{K: "File", V: path}}, logMsg)
-                                               if *dryRun {
-                                                       return nil
+                                       if len(pkts) > 0 {
+                                               if _, exists := pkts[filepath.Base(info.Name())]; exists {
+                                                       ctx.LogI("rm", nncp.LEs{{K: "File", V: path}}, logMsg)
+                                                       if *dryRun {
+                                                               return nil
+                                                       }
+                                                       return os.Remove(path)
                                                }
-                                               return os.Remove(path)
                                        }
                                        if !*doSeen && !*doNoCK && !*doHdr && !*doPart &&
                                                (*doRx || *doTx) &&
@@ -234,12 +252,12 @@ func main() {
                                        return nil
                                })
                }
-               if *pktRaw != "" || *doRx || *doNoCK || *doPart {
+               if len(pkts) > 0 || *doRx || *doNoCK || *doPart {
                        if err = remove(nncp.TRx); err != nil {
                                log.Fatalln("Can not remove:", err)
                        }
                }
-               if *pktRaw != "" || *doTx || *doHdr {
+               if len(pkts) > 0 || *doTx || *doHdr {
                        if err = remove(nncp.TTx); err != nil {
                                log.Fatalln("Can not remove:", err)
                        }
@@ -315,9 +333,12 @@ func main() {
                                                return nil
                                        }
                                        if now.Sub(info.ModTime()) < oldBoundary {
-                                               ctx.LogD("rm-skip", nncp.LEs{{K: "File", V: path}}, func(les nncp.LEs) string {
-                                                       return fmt.Sprintf("File %s: too fresh, skipping", path)
-                                               })
+                                               ctx.LogD(
+                                                       "rm-skip", nncp.LEs{{K: "File", V: path}},
+                                                       func(les nncp.LEs) string {
+                                                               return fmt.Sprintf("File %s: too fresh, skipping", path)
+                                                       },
+                                               )
                                                return nil
                                        }
                                        ctx.LogI(
index 27d9d6b9f6c58a610609ed0fd5b8396d90e89575..bd822d1a3c22309b9621933056988d27dcb92508 100644 (file)
@@ -137,7 +137,7 @@ func main() {
        if err != nil {
                panic(err)
        }
-       if _, _, err = ctx.Tx(
+       if _, _, _, err = ctx.Tx(
                node,
                pktTrns,
                nice,
index 0ae34704f120f803c720949b4cceda35dee49c9c..ff817da745fb9f77c1befa57352f07dd7116c68c 100644 (file)
@@ -40,7 +40,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.`
 const Base32Encoded32Len = 52
 
 var (
-       Version string = "8.6.0"
+       Version string = "8.7.0"
 
        Base32Codec *base32.Encoding = base32.StdEncoding.WithPadding(base32.NoPadding)
 )
index ebe20fbf0dd159c626d7b91801e814ddbc34ce0b..79cc50f496982c96b976c532fc47f327dfcdaf6c 100644 (file)
@@ -621,7 +621,7 @@ func jobProcess(
                                if err != nil {
                                        panic(err)
                                }
-                               if _, _, err = ctx.Tx(
+                               if _, _, _, err = ctx.Tx(
                                        node,
                                        pktTrns,
                                        nice,
@@ -752,7 +752,7 @@ func jobProcess(
                                }
                                if nodeId != sender.Id && nodeId != pktEnc.Sender {
                                        ctx.LogI("rx-area-echo", lesEcho, logMsgNode)
-                                       if _, _, err = ctx.Tx(
+                                       if _, _, _, err = ctx.Tx(
                                                node,
                                                &pkt,
                                                nice,
@@ -926,6 +926,8 @@ func jobProcess(
                                                return logMsg(les) + ": removing packet"
                                        })
                                        return err
+                               } else if ctx.HdrUsage {
+                                       os.Remove(JobPath2Hdr(pktPath))
                                }
                        }
                } else {
index 6e13f2ef3fbeb9e4f97fe61b99d1897f6a8f6c09..e38084e1a7a3c01390987af3da42c8667d2ee4ab 100644 (file)
--- a/src/tx.go
+++ b/src/tx.go
@@ -57,12 +57,12 @@ func (ctx *Ctx) Tx(
        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))
@@ -82,15 +82,15 @@ func (ctx *Ctx) Tx(
                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)
@@ -211,7 +211,7 @@ func (ctx *Ctx) Tx(
                r := <-results
                if r.err != nil {
                        tmp.Fd.Close()
-                       return nil, 0, r.err
+                       return nil, 0, "", r.err
                }
                if r.pktEncRaw != nil {
                        pktEncRaw = r.pktEncRaw
@@ -224,7 +224,7 @@ func (ctx *Ctx) Tx(
        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()))
@@ -255,18 +255,18 @@ func (ctx *Ctx) Tx(
                }
                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, payloadSize, err
+       return lastNode, payloadSize, tmp.Checksum(), err
 }
 
 type DummyCloser struct{}
@@ -438,7 +438,7 @@ func (ctx *Ctx) TxFile(
                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,
@@ -450,6 +450,7 @@ func (ctx *Ctx) TxFile(
                        {"Src", srcPath},
                        {"Dst", dstPath},
                        {"Size", finalSize},
+                       {"Pkt", pktName},
                }
                logMsg := func(les LEs) string {
                        return fmt.Sprintf(
@@ -480,7 +481,7 @@ func (ctx *Ctx) TxFile(
                        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),
@@ -494,6 +495,7 @@ func (ctx *Ctx) TxFile(
                        {"Src", srcPath},
                        {"Dst", path},
                        {"Size", size},
+                       {"Pkt", pktName},
                }
                logMsg := func(les LEs) string {
                        return fmt.Sprintf(
@@ -541,7 +543,7 @@ func (ctx *Ctx) TxFile(
                return err
        }
        metaPktSize := int64(buf.Len())
-       _, _, err = ctx.Tx(
+       _, _, pktName, err := ctx.Tx(
                node,
                pkt,
                nice,
@@ -555,6 +557,7 @@ func (ctx *Ctx) TxFile(
                {"Src", srcPath},
                {"Dst", path},
                {"Size", metaPktSize},
+               {"Pkt", pktName},
        }
        logMsg := func(les LEs) string {
                return fmt.Sprintf(
@@ -593,7 +596,9 @@ func (ctx *Ctx) TxFreq(
        }
        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},
@@ -601,6 +606,7 @@ func (ctx *Ctx) TxFreq(
                {"ReplyNice", int(replyNice)},
                {"Src", srcPath},
                {"Dst", dstPath},
+               {"Pkt", pktName},
        }
        logMsg := func(les LEs) string {
                return fmt.Sprintf(
@@ -657,7 +663,9 @@ func (ctx *Ctx) TxExec(
                }(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 {
@@ -672,6 +680,7 @@ func (ctx *Ctx) TxExec(
                {"ReplyNice", int(replyNice)},
                {"Dst", dst},
                {"Size", size},
+               {"Pkt", pktName},
        }
        logMsg := func(les LEs) string {
                return fmt.Sprintf(
@@ -735,25 +744,28 @@ func (ctx *Ctx) TxACK(
        nice uint8,
        hsh string,
        minSize int64,
-) error {
+) (pktName string, err error) {
        hshRaw, err := Base32Codec.DecodeString(hsh)
        if err != nil {
-               return err
+               return "", err
        }
        if len(hshRaw) != MTHSize {
-               return errors.New("Invalid packet id size")
+               return "", errors.New("Invalid packet id size")
        }
        pkt, err := NewPkt(PktTypeACK, nice, []byte(hshRaw))
        if err != nil {
-               return err
+               return "", err
        }
        src := bytes.NewReader([]byte{})
-       _, _, err = ctx.Tx(node, pkt, nice, 0, minSize, MaxFileSize, src, hsh, nil)
+       _, _, 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)
@@ -763,5 +775,5 @@ func (ctx *Ctx) TxACK(
        } else {
                ctx.LogE("tx", les, err, logMsg)
        }
-       return err
+       return
 }
index 507bc8b94e7b5ba848b39e19aeb1ebcb7fb5dd37..9f8d7506b652ee04d25dd739d8a573e0a64ca079 100644 (file)
@@ -87,7 +87,7 @@ func TestTx(t *testing.T) {
                }
                pkt, err := NewPkt(PktTypeExec, replyNice, []byte(pathSrc))
                src := bytes.NewReader(data)
-               dstNode, _, err := ctx.Tx(
+               dstNode, _, _, err := ctx.Tx(
                        nodeTgt,
                        pkt,
                        123,