X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=src%2Fcheck.go;h=bd191034fe5191c5bf5136eabf377713792d7206;hb=ffe4b2fbf50c031e9c002f2395957859cb4787cc;hp=4a1be889cb4a1777f7d6670afa483e2805b0bb5d;hpb=1c773d7a2acd7fef4b7b1567b59e1601a79d55fe;p=nncp.git diff --git a/src/check.go b/src/check.go index 4a1be88..bd19103 100644 --- a/src/check.go +++ b/src/check.go @@ -1,6 +1,6 @@ /* NNCP -- Node to Node copy, utilities for store-and-forward data exchange -Copyright (C) 2016-2021 Sergey Matveev +Copyright (C) 2016-2022 Sergey Matveev 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 @@ -21,18 +21,27 @@ import ( "bufio" "bytes" "errors" + "fmt" "io" - "log" - - "golang.org/x/crypto/blake2b" + "os" + "path/filepath" ) -func Check(src io.Reader, checksum []byte, sds SDS, showPrgrs bool) (bool, error) { - hsh, err := blake2b.New256(nil) - if err != nil { - log.Fatalln(err) - } - if _, err = CopyProgressed(hsh, bufio.NewReader(src), "check", sds, showPrgrs); err != nil { +const NoCKSuffix = ".nock" + +func Check( + src io.Reader, + size int64, + checksum []byte, + les LEs, + showPrgrs bool, +) (bool, error) { + hsh := MTHNew(size, 0) + if _, err := CopyProgressed( + hsh, + bufio.NewReaderSize(src, MTHBlockSize), + "check", les, showPrgrs, + ); err != nil { return false, err } return bytes.Compare(hsh.Sum(nil), checksum) == 0, nil @@ -41,21 +50,30 @@ func Check(src io.Reader, checksum []byte, sds SDS, showPrgrs bool) (bool, error func (ctx *Ctx) checkXxIsBad(nodeId *NodeId, xx TRxTx) bool { isBad := false for job := range ctx.Jobs(nodeId, xx) { - sds := SDS{ - "xx": string(xx), - "node": nodeId, - "pkt": Base32Codec.EncodeToString(job.HshValue[:]), - "fullsize": job.Size, + pktName := Base32Codec.EncodeToString(job.HshValue[:]) + les := LEs{ + {"XX", string(xx)}, + {"Node", nodeId}, + {"Pkt", pktName}, + {"FullSize", job.Size}, } - gut, err := Check(job.Fd, job.HshValue[:], sds, ctx.ShowPrgrs) - job.Fd.Close() // #nosec G104 + logMsg := func(les LEs) string { + return fmt.Sprintf("Checking: %s/%s/%s", nodeId, string(xx), pktName) + } + fd, err := os.Open(job.Path) if err != nil { - ctx.LogE("check", sds, err, "") + ctx.LogE("checking", les, err, logMsg) + return true + } + gut, err := Check(fd, job.Size, job.HshValue[:], les, ctx.ShowPrgrs) + fd.Close() + if err != nil { + ctx.LogE("checking", les, err, logMsg) return true } if !gut { isBad = true - ctx.LogE("check", sds, errors.New("bad"), "") + ctx.LogE("checking", les, errors.New("bad"), logMsg) } } return isBad @@ -64,3 +82,59 @@ func (ctx *Ctx) checkXxIsBad(nodeId *NodeId, xx TRxTx) bool { func (ctx *Ctx) Check(nodeId *NodeId) bool { return !(ctx.checkXxIsBad(nodeId, TRx) || ctx.checkXxIsBad(nodeId, TTx)) } + +func (ctx *Ctx) CheckNoCK(nodeId *NodeId, hshValue *[MTHSize]byte, mth MTH) (int64, error) { + dirToSync := filepath.Join(ctx.Spool, nodeId.String(), string(TRx)) + pktName := Base32Codec.EncodeToString(hshValue[:]) + pktPath := filepath.Join(dirToSync, pktName) + fd, err := os.Open(pktPath + NoCKSuffix) + if err != nil { + return 0, err + } + defer fd.Close() + fi, err := fd.Stat() + if err != nil { + return 0, err + } + size := fi.Size() + les := LEs{ + {"XX", string(TRx)}, + {"Node", nodeId}, + {"Pkt", pktName}, + {"FullSize", size}, + } + var gut bool + if mth == nil { + gut, err = Check(fd, size, hshValue[:], les, ctx.ShowPrgrs) + } else { + if _, err = mth.PreaddFrom( + bufio.NewReaderSize(fd, MTHBlockSize), + pktName, ctx.ShowPrgrs, + ); err != nil { + return 0, err + } + if bytes.Compare(mth.Sum(nil), hshValue[:]) == 0 { + gut = true + } + } + if err != nil || !gut { + return 0, errors.New("checksum mismatch") + } + if err = os.Rename(pktPath+NoCKSuffix, pktPath); err != nil { + return 0, err + } + if err = DirSync(dirToSync); err != nil { + return size, err + } + if ctx.HdrUsage { + if _, err = fd.Seek(0, io.SeekStart); err != nil { + return size, err + } + _, pktEncRaw, err := ctx.HdrRead(fd) + if err != nil { + return size, err + } + ctx.HdrWrite(pktEncRaw, pktPath) + } + return size, err +}