]> Cypherpunks.ru repositories - nncp.git/blobdiff - src/cmd/nncp-xfer/main.go
Fix encrypted packet magic number check
[nncp.git] / src / cmd / nncp-xfer / main.go
index f451b10c1ef920f527b45fc4de2bfd4eb77886bc..41e8c61c8e157f087d9fa5096990d92231bf316d 100644 (file)
@@ -1,6 +1,6 @@
 /*
 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
-Copyright (C) 2016-2020 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
@@ -28,8 +28,8 @@ import (
        "os"
        "path/filepath"
 
-       xdr "github.com/davecgh/go-xdr/xdr2"
-       "go.cypherpunks.ru/nncp/v5"
+       "github.com/dustin/go-humanize"
+       "go.cypherpunks.ru/nncp/v8"
 )
 
 func usage() {
@@ -57,6 +57,7 @@ func main() {
                version   = flag.Bool("version", false, "Print version information")
                warranty  = flag.Bool("warranty", false, "Print warranty information")
        )
+       log.SetFlags(log.Lshortfile)
        flag.Usage = usage
        flag.Parse()
        if *warranty {
@@ -105,32 +106,46 @@ func main() {
        isBad := false
        var dir *os.File
        var fis []os.FileInfo
-       sds := nncp.SDS{}
+       var les nncp.LEs
+       var logMsg func(les nncp.LEs) string
        if *txOnly {
                goto Tx
        }
-       sds["xx"] = string(nncp.TRx)
-       sds["dir"] = selfPath
-       ctx.LogD("nncp-xfer", sds, "self")
+       les = nncp.LEs{
+               {K: "XX", V: string(nncp.TRx)},
+               {K: "Dir", V: selfPath},
+       }
+       logMsg = func(les nncp.LEs) string {
+               return "Packet transfer, received from self"
+       }
+       ctx.LogD("xfer-self", les, logMsg)
        if _, err = os.Stat(selfPath); err != nil {
                if os.IsNotExist(err) {
-                       ctx.LogD("nncp-xfer", sds, "no dir")
+                       ctx.LogD("xfer-self-no-dir", les, func(les nncp.LEs) string {
+                               return logMsg(les) + ": no directory"
+                       })
                        goto Tx
                }
-               ctx.LogE("nncp-xfer", sds, err, "stat")
+               ctx.LogE("xfer-self-stat", les, err, func(les nncp.LEs) string {
+                       return logMsg(les) + ": stating"
+               })
                isBad = true
                goto Tx
        }
        dir, err = os.Open(selfPath)
        if err != nil {
-               ctx.LogE("nncp-xfer", sds, err, "open")
+               ctx.LogE("xfer-self-open", les, err, func(les nncp.LEs) string {
+                       return logMsg(les) + ": opening"
+               })
                isBad = true
                goto Tx
        }
        fis, err = dir.Readdir(0)
        dir.Close()
        if err != nil {
-               ctx.LogE("nncp-xfer", sds, err, "read")
+               ctx.LogE("xfer-self-read", les, err, func(les nncp.LEs) string {
+                       return logMsg(les) + ": reading"
+               })
                isBad = true
                goto Tx
        }
@@ -139,29 +154,42 @@ func main() {
                        continue
                }
                nodeId, err := nncp.NodeIdFromString(fi.Name())
-               sds["node"] = fi.Name()
+               les := append(les, nncp.LE{K: "Node", V: fi.Name()})
+               logMsg := func(les nncp.LEs) string {
+                       return "Packet transfer, received from " + ctx.NodeName(nodeId)
+               }
                if err != nil {
-                       ctx.LogD("nncp-xfer", sds, "is not NodeId")
+                       ctx.LogD("xfer-rx-not-node", les, func(les nncp.LEs) string {
+                               return logMsg(les) + ": is not NodeId"
+                       })
                        continue
                }
                if nodeOnly != nil && *nodeId != *nodeOnly.Id {
-                       ctx.LogD("nncp-xfer", sds, "skip")
+                       ctx.LogD("xfer-rx-skip", les, func(les nncp.LEs) string {
+                               return logMsg(les) + ": skipping"
+                       })
                        continue
                }
                if _, known := ctx.Neigh[*nodeId]; !known {
-                       ctx.LogD("nncp-xfer", sds, "unknown")
+                       ctx.LogD("xfer-rx-unknown", les, func(les nncp.LEs) string {
+                               return logMsg(les) + ": unknown"
+                       })
                        continue
                }
                dir, err = os.Open(filepath.Join(selfPath, fi.Name()))
                if err != nil {
-                       ctx.LogE("nncp-xfer", sds, err, "open")
+                       ctx.LogE("xfer-rx-open", les, err, func(les nncp.LEs) string {
+                               return logMsg(les) + ": opening"
+                       })
                        isBad = true
                        continue
                }
                fisInt, err := dir.Readdir(0)
                dir.Close()
                if err != nil {
-                       ctx.LogE("nncp-xfer", sds, err, "read")
+                       ctx.LogE("xfer-rx-read", les, err, func(les nncp.LEs) string {
+                               return logMsg(les) + ": reading"
+                       })
                        isBad = true
                        continue
                }
@@ -174,33 +202,73 @@ func main() {
                                continue
                        }
                        filename := filepath.Join(dir.Name(), fiInt.Name())
-                       sds["file"] = filename
-                       delete(sds, "size")
+                       les := append(les, nncp.LE{K: "File", V: filename})
+                       logMsg := func(les nncp.LEs) string {
+                               return fmt.Sprintf(
+                                       "Packet transfer, received from %s: %s",
+                                       ctx.NodeName(nodeId), filename,
+                               )
+                       }
                        fd, err := os.Open(filename)
                        if err != nil {
-                               ctx.LogE("nncp-xfer", sds, err, "open")
+                               ctx.LogE("xfer-rx-open", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": opening"
+                               })
                                isBad = true
                                continue
                        }
-                       var pktEnc nncp.PktEnc
-                       _, err = xdr.Unmarshal(fd, &pktEnc)
-                       if err != nil || pktEnc.Magic != nncp.MagicNNCPEv4 {
-                               ctx.LogD("nncp-xfer", sds, "is not a packet")
+                       pktEnc, pktEncRaw, err := ctx.HdrRead(fd)
+                       if err == nil {
+                               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 {
+                               ctx.LogD(
+                                       "xfer-rx-not-packet",
+                                       append(les, nncp.LE{K: "Err", V: err}),
+                                       func(les nncp.LEs) string {
+                                               return logMsg(les) + ": not valid packet: " + err.Error()
+                                       },
+                               )
                                fd.Close()
                                continue
                        }
                        if pktEnc.Nice > nice {
-                               ctx.LogD("nncp-xfer", sds, "too nice")
+                               ctx.LogD("xfer-rx-too-nice", les, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": too nice"
+                               })
                                fd.Close()
                                continue
                        }
-                       sds["size"] = fiInt.Size()
+                       les = append(les, nncp.LE{K: "Size", V: fiInt.Size()})
+                       logMsg = func(les nncp.LEs) string {
+                               return fmt.Sprintf(
+                                       "Packet transfer, received from %s: %s (%s)",
+                                       ctx.NodeName(nodeId), filename,
+                                       humanize.IBytes(uint64(fiInt.Size())),
+                               )
+                       }
                        if !ctx.IsEnoughSpace(fiInt.Size()) {
-                               ctx.LogE("nncp-xfer", sds, errors.New("is not enough space"), "")
+                               ctx.LogE("xfer-rx", les, errors.New("is not enough space"), logMsg)
                                fd.Close()
                                continue
                        }
-                       fd.Seek(0, 0)
+                       if _, err = fd.Seek(0, 0); err != nil {
+                               log.Fatalln(err)
+                       }
                        tmp, err := ctx.NewTmpFileWHash()
                        if err != nil {
                                log.Fatalln(err)
@@ -209,21 +277,23 @@ func main() {
                        go func() {
                                _, err := io.CopyN(w, bufio.NewReader(fd), fiInt.Size())
                                if err == nil {
-                                       w.Close()
-                                       return
+                                       err = w.Close()
+                               }
+                               if err != nil {
+                                       ctx.LogE("xfer-rx", les, err, logMsg)
+                                       w.CloseWithError(err)
                                }
-                               ctx.LogE("nncp-xfer", sds, err, "copy")
-                               w.CloseWithError(err)
                        }()
                        if _, err = nncp.CopyProgressed(
                                tmp.W, r, "Rx",
-                               nncp.SdsAdd(sds, nncp.SDS{
-                                       "pkt":      filename,
-                                       "fullsize": sds["size"],
-                               }),
+                               append(
+                                       les,
+                                       nncp.LE{K: "Pkt", V: filename},
+                                       nncp.LE{K: "FullSize", V: fiInt.Size()},
+                               ),
                                ctx.ShowPrgrs,
                        ); err != nil {
-                               ctx.LogE("nncp-xfer", sds, err, "copy")
+                               ctx.LogE("xfer-rx", les, err, logMsg)
                                isBad = true
                        }
                        fd.Close()
@@ -238,13 +308,21 @@ func main() {
                        )); err != nil {
                                log.Fatalln(err)
                        }
-                       ctx.LogI("nncp-xfer", sds, "")
+                       ctx.LogI("xfer-rx", les, logMsg)
                        if !*keep {
                                if err = os.Remove(filename); err != nil {
-                                       ctx.LogE("nncp-xfer", sds, err, "remove")
+                                       ctx.LogE("xfer-rx-remove", les, err, logMsg)
                                        isBad = true
                                }
                        }
+                       if ctx.HdrUsage {
+                               ctx.HdrWrite(pktEncRaw, filepath.Join(
+                                       ctx.Spool,
+                                       nodeId.String(),
+                                       string(nncp.TRx),
+                                       tmp.Checksum(),
+                               ))
+                       }
                }
        }
 
@@ -255,129 +333,196 @@ Tx:
                }
                return
        }
-       sds["xx"] = string(nncp.TTx)
-       for nodeId, _ := range ctx.Neigh {
-               sds["node"] = nodeId
+       for nodeId := range ctx.Neigh {
+               les := nncp.LEs{{K: "XX", V: string(nncp.TTx)}, {K: "Node", V: nodeId}}
+               logMsg := func(les nncp.LEs) string {
+                       return "Packet transfer, sent to " + ctx.NodeName(&nodeId)
+               }
                if nodeOnly != nil && nodeId != *nodeOnly.Id {
-                       ctx.LogD("nncp-xfer", sds, "skip")
+                       ctx.LogD("xfer-tx-skip", les, func(les nncp.LEs) string {
+                               return logMsg(les) + ": skipping"
+                       })
                        continue
                }
-               dirLock, err := ctx.LockDir(&nodeId, nncp.TTx)
+               dirLock, err := ctx.LockDir(&nodeId, string(nncp.TTx))
                if err != nil {
                        continue
                }
                nodePath := filepath.Join(flag.Arg(0), nodeId.String())
-               sds["dir"] = nodePath
+               les = append(les, nncp.LE{K: "Dir", V: nodePath})
+               logMsg = func(les nncp.LEs) string {
+                       return fmt.Sprintf(
+                               "Packet transfer, sent to %s: directory %s",
+                               ctx.NodeName(&nodeId), nodePath,
+                       )
+               }
                _, err = os.Stat(nodePath)
                if err != nil {
                        if os.IsNotExist(err) {
-                               ctx.LogD("nncp-xfer", sds, "does not exist")
+                               ctx.LogD("xfer-tx-not-exist", les, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": does not exist"
+                               })
                                if !*mkdir {
                                        ctx.UnlockDir(dirLock)
                                        continue
                                }
                                if err = os.Mkdir(nodePath, os.FileMode(0777)); err != nil {
                                        ctx.UnlockDir(dirLock)
-                                       ctx.LogE("nncp-xfer", sds, err, "mkdir")
+                                       ctx.LogE("xfer-tx-mkdir", les, err, logMsg)
                                        isBad = true
                                        continue
                                }
                        } else {
                                ctx.UnlockDir(dirLock)
-                               ctx.LogE("nncp-xfer", sds, err, "stat")
+                               ctx.LogE("xfer-tx", les, err, logMsg)
                                isBad = true
                                continue
                        }
                }
                dstPath := filepath.Join(nodePath, ctx.SelfId.String())
-               sds["dir"] = dstPath
+               les[len(les)-1].V = dstPath
+               logMsg = func(les nncp.LEs) string {
+                       return fmt.Sprintf(
+                               "Packet transfer, sent to %s: directory %s",
+                               ctx.NodeName(&nodeId), dstPath,
+                       )
+               }
                _, err = os.Stat(dstPath)
                if err != nil {
                        if os.IsNotExist(err) {
                                if err = os.Mkdir(dstPath, os.FileMode(0777)); err != nil {
                                        ctx.UnlockDir(dirLock)
-                                       ctx.LogE("nncp-xfer", sds, err, "mkdir")
+                                       ctx.LogE("xfer-tx-mkdir", les, err, logMsg)
                                        isBad = true
                                        continue
                                }
                        } else {
                                ctx.UnlockDir(dirLock)
-                               ctx.LogE("nncp-xfer", sds, err, "stat")
+                               ctx.LogE("xfer-tx", les, err, logMsg)
                                isBad = true
                                continue
                        }
                }
-               delete(sds, "dir")
+               les = les[:len(les)-1]
                for job := range ctx.Jobs(&nodeId, nncp.TTx) {
-                       pktName := filepath.Base(job.Fd.Name())
-                       sds["pkt"] = pktName
+                       pktName := filepath.Base(job.Path)
+                       les := append(les, nncp.LE{K: "Pkt", V: pktName})
+                       logMsg = func(les nncp.LEs) string {
+                               return fmt.Sprintf(
+                                       "Packet transfer, sent to %s: %s",
+                                       ctx.NodeName(&nodeId), pktName,
+                               )
+                       }
                        if job.PktEnc.Nice > nice {
-                               ctx.LogD("nncp-xfer", sds, "too nice")
-                               job.Fd.Close()
+                               ctx.LogD("xfer-tx-too-nice", les, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": too nice"
+                               })
                                continue
                        }
                        if _, err = os.Stat(filepath.Join(dstPath, pktName)); err == nil || !os.IsNotExist(err) {
-                               ctx.LogD("nncp-xfer", sds, "already exists")
-                               job.Fd.Close()
+                               ctx.LogD("xfer-tx-exists", les, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": already exists"
+                               })
                                continue
                        }
-                       if _, err = os.Stat(filepath.Join(dstPath, pktName+nncp.SeenSuffix)); err == nil || !os.IsNotExist(err) {
-                               ctx.LogD("nncp-xfer", sds, "already exists")
-                               job.Fd.Close()
+                       if _, err = os.Stat(filepath.Join(
+                               dstPath, nncp.SeenDir, pktName,
+                       )); err == nil || !os.IsNotExist(err) {
+                               ctx.LogD("xfer-tx-seen", les, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": already seen"
+                               })
                                continue
                        }
                        tmp, err := nncp.TempFile(dstPath, "xfer")
                        if err != nil {
-                               ctx.LogE("nncp-xfer", sds, err, "mktemp")
-                               job.Fd.Close()
+                               ctx.LogE("xfer-tx-mktemp", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": mktemp"
+                               })
                                isBad = true
                                break
                        }
-                       sds["tmp"] = tmp.Name()
-                       ctx.LogD("nncp-xfer", sds, "created")
+                       les = append(les, nncp.LE{K: "Tmp", V: tmp.Name()})
+                       ctx.LogD("xfer-tx-tmp-create", les, func(les nncp.LEs) string {
+                               return fmt.Sprintf("%s: temporary %s created", logMsg(les), tmp.Name())
+                       })
+                       fd, err := os.Open(job.Path)
+                       if err != nil {
+                               ctx.LogE("xfer-tx-open", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": opening"
+                               })
+                               tmp.Close()
+                               isBad = true
+                               continue
+                       }
                        bufW := bufio.NewWriter(tmp)
                        copied, err := nncp.CopyProgressed(
-                               bufW, bufio.NewReader(job.Fd), "Tx",
-                               nncp.SdsAdd(sds, nncp.SDS{"fullsize": job.Size}),
+                               bufW, bufio.NewReader(fd), "Tx",
+                               append(les, nncp.LE{K: "FullSize", V: job.Size}),
                                ctx.ShowPrgrs,
                        )
-                       job.Fd.Close()
+                       fd.Close()
                        if err != nil {
-                               ctx.LogE("nncp-xfer", sds, err, "copy")
+                               ctx.LogE("xfer-tx-copy", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": copying"
+                               })
                                tmp.Close()
                                isBad = true
                                continue
                        }
                        if err = bufW.Flush(); err != nil {
                                tmp.Close()
-                               ctx.LogE("nncp-xfer", sds, err, "flush")
+                               ctx.LogE("xfer-tx-flush", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": flushing"
+                               })
                                isBad = true
                                continue
                        }
                        if err = tmp.Sync(); err != nil {
                                tmp.Close()
-                               ctx.LogE("nncp-xfer", sds, err, "sync")
+                               ctx.LogE("xfer-tx-sync", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": syncing"
+                               })
                                isBad = true
                                continue
                        }
-                       tmp.Close()
+                       if err = tmp.Close(); err != nil {
+                               ctx.LogE("xfer-tx-close", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": closing"
+                               })
+                       }
                        if err = os.Rename(tmp.Name(), filepath.Join(dstPath, pktName)); err != nil {
-                               ctx.LogE("nncp-xfer", sds, err, "rename")
+                               ctx.LogE("xfer-tx-rename", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": renaming"
+                               })
                                isBad = true
                                continue
                        }
                        if err = nncp.DirSync(dstPath); err != nil {
-                               ctx.LogE("nncp-xfer", sds, err, "sync")
+                               ctx.LogE("xfer-tx-dirsync", les, err, func(les nncp.LEs) string {
+                                       return logMsg(les) + ": dirsyncing"
+                               })
                                isBad = true
                                continue
                        }
                        os.Remove(filepath.Join(dstPath, pktName+".part"))
-                       delete(sds, "tmp")
-                       ctx.LogI("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"size": copied}), "")
+                       les = les[:len(les)-1]
+                       ctx.LogI(
+                               "xfer-tx",
+                               append(les, nncp.LE{K: "Size", V: copied}),
+                               func(les nncp.LEs) string {
+                                       return fmt.Sprintf(
+                                               "%s (%s)", logMsg(les), humanize.IBytes(uint64(copied)),
+                                       )
+                               },
+                       )
                        if !*keep {
-                               if err = os.Remove(job.Fd.Name()); err != nil {
-                                       ctx.LogE("nncp-xfer", sds, err, "remove")
+                               if err = os.Remove(job.Path); err != nil {
+                                       ctx.LogE("xfer-tx-remove", les, err, func(les nncp.LEs) string {
+                                               return logMsg(les) + ": removing"
+                                       })
                                        isBad = true
+                               } else if ctx.HdrUsage {
+                                       os.Remove(nncp.JobPath2Hdr(job.Path))
                                }
                        }
                }