]> Cypherpunks.ru repositories - nncp.git/commitdiff
Ability to create and deal with .seen files after tossing
authorSergey Matveev <stargrave@stargrave.org>
Sat, 18 Nov 2017 20:27:19 +0000 (23:27 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 19 Nov 2017 13:35:20 +0000 (16:35 +0300)
doc/cmds.texi
doc/news.ru.texi
doc/news.texi
doc/spool.texi
src/cypherpunks.ru/nncp/cmd/nncp-bundle/main.go
src/cypherpunks.ru/nncp/cmd/nncp-toss/main.go
src/cypherpunks.ru/nncp/cmd/nncp-xfer/main.go
src/cypherpunks.ru/nncp/toss.go
src/cypherpunks.ru/nncp/toss_test.go

index f1a029aabb6fa6b246e19d2afc9da563a2ecc5c8..b5db1c09243771dd88d501a4dc76933ed6f8e371 100644 (file)
@@ -418,7 +418,7 @@ queues.
 @section nncp-toss
 
 @verbatim
-% nncp-toss [options] [-dryrun] [-cycle INT]
+% nncp-toss [options] [-dryrun] [-cycle INT] [-seen]
 @end verbatim
 
 Perform "tossing" operation on all inbound packets. This is the tool
@@ -433,6 +433,11 @@ tells what it will do.
 @option{INT} seconds in an infinite loop. That can be useful when
 running this command as a daemon.
 
+@option{-seen} option creates empty @file{XXX.seen} file after
+successful tossing of @file{XXX} packet. @ref{nncp-xfer} and
+@ref{nncp-bundle} commands skip inbound packets that has been already
+seen, processed and tossed. This is helpful to defeat duplicates.
+
 @node nncp-xfer
 @section nncp-xfer
 
index f0a2b6f111f24ef6380d4da05be5acd57f6eec9e..dd3e0a8f5ec5d65e55e32fa9f77bff39704342f1 100644 (file)
@@ -13,6 +13,9 @@
 методах передачи (например запись на CD-ROM без создания промежуточного
 подготовленного ISO образа или работа с ленточными накопителями).
 @item
+@command{nncp-toss} команда может создавать @file{.seen} файлы,
+предотвращая приём дублированных пакетов.
+@item
 В команде @command{nncp-call} разрешается иметь только одного
 обработчика контрольной суммы в фоне. Это полезно когда тысячи маленьких
 входящих пакетов могут создать много горутин.
index 190d04a8d93ad71947e135ccb72ffddb097d418a..aa89c7df563259c017e078ba5c8555b119a09a35 100644 (file)
@@ -15,6 +15,9 @@ packets, or digest it. It is useful when dealing with stdin/stdout based
 transmission methods (like writing to CD-ROM without intermediate
 prepared ISO image and working with tape drives).
 @item
+@command{nncp-toss} is able to create @file{.seen} files preventing
+duplicate packets receiving.
+@item
 Single background checksum verifier worker is allowed in
 @command{nncp-call}. This is helpful when thousands of small inbound
 packets could create many goroutines.
index 53ea301cdc0f9b3f782df70a4ad7f4b5c377d622..a5db2dc877f8b72c9977d0616b1f4a682bcda426 100644 (file)
@@ -13,7 +13,9 @@ spool/2WHB...OABQ/tx.lock
 spool/BYRR...CG6Q/rx.lock
 spool/BYRR...CG6Q/rx/
 spool/BYRR...CG6Q/tx.lock
+spool/BYRR...CG6Q/tx/AQUT...DGNT.seen
 spool/BYRR...CG6Q/tx/NSYY...ZUU6
+spool/BYRR...CG6Q/tx/VCSR...3VXX.seen
 spool/BYRR...CG6Q/tx/ZI5U...5RRQ
 @end verbatim
 
@@ -30,5 +32,9 @@ partly received file from @file{2WHB...OABQ} node. @file{tx} directory
 can not contain partly written files -- they are moved atomically from
 @file{tmp}.
 
+When @ref{nncp-toss} utility is called with @option{-seen} option, it
+will create empty @file{XXX.seen} files, telling that some kind of
+packet already was tossed sometime.
+
 Only one process can work with @file{rx}/@file{tx} directories at once,
 so there are corresponding lock files.
index 36c9cc99ec6f34704abda611ab73b7814f87a23b..210a14024dfe464669bf4ae5a6a65a8fdbd6c803 100644 (file)
@@ -264,6 +264,10 @@ func main() {
                                ctx.LogD("nncp-bundle", sds, "Packet already exists")
                                continue
                        }
+                       if _, err = os.Stat(dstPath + nncp.SeenPostfix); err == nil || !os.IsNotExist(err) {
+                               ctx.LogD("nncp-bundle", sds, "Packet already exists")
+                               continue
+                       }
                        if *doCheck {
                                tmp, err := ctx.NewTmpFileWHash()
                                if err != nil {
index 71a15ee87561742e0aeb1d985661bbdb10bec2fc..12dc214d8a4b7e77029dcfb6034640ae8edbaffe 100644 (file)
@@ -43,6 +43,7 @@ func main() {
                nodeRaw  = flag.String("node", "", "Process only that node")
                niceRaw  = flag.Int("nice", 255, "Minimal required niceness")
                dryRun   = flag.Bool("dryrun", false, "Do not actually write any tossed data")
+               doSeen   = flag.Bool("seen", false, "Create .seen files")
                cycle    = flag.Uint("cycle", 0, "Repeat tossing after N seconds in infinite loop")
                quiet    = flag.Bool("quiet", false, "Print only errors")
                debug    = flag.Bool("debug", false, "Print debug messages")
@@ -92,7 +93,7 @@ Cycle:
                if nodeOnly != nil && nodeId != *nodeOnly.Id {
                        continue
                }
-               isBad = ctx.Toss(node.Id, nice, *dryRun)
+               isBad = ctx.Toss(node.Id, nice, *dryRun, *doSeen)
        }
        if *cycle > 0 {
                time.Sleep(time.Duration(*cycle) * time.Second)
index 5abac1f02db6789aad34d628cb9b5acdd7c1662e..05a37489b8299a5de76e47b52e422d96661cf28e 100644 (file)
@@ -285,6 +285,16 @@ Tx:
                                job.Fd.Close()
                                continue
                        }
+                       if _, err = os.Stat(filepath.Join(dstPath, pktName)); err == nil || !os.IsNotExist(err) {
+                               ctx.LogD("nncp-xfer", sds, "already exists")
+                               job.Fd.Close()
+                               continue
+                       }
+                       if _, err = os.Stat(filepath.Join(dstPath, pktName+nncp.SeenPostfix)); err == nil || !os.IsNotExist(err) {
+                               ctx.LogD("nncp-xfer", sds, "already exists")
+                               job.Fd.Close()
+                               continue
+                       }
                        tmp, err := ioutil.TempFile(dstPath, "nncp-xfer")
                        if err != nil {
                                ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "mktemp")
index bdd7da40d70a26bc8b0dee824077d54e56db7cac..a1fa8f38c8cee8b78e4fed104334a581e0e0947a 100644 (file)
@@ -38,6 +38,10 @@ import (
        "golang.org/x/crypto/blake2b"
 )
 
+const (
+       SeenPostfix = ".seen"
+)
+
 func newNotification(fromTo *FromToYAML, subject string) io.Reader {
        return strings.NewReader(fmt.Sprintf(
                "From: %s\nTo: %s\nSubject: %s\n",
@@ -47,7 +51,7 @@ func newNotification(fromTo *FromToYAML, subject string) io.Reader {
        ))
 }
 
-func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun bool) bool {
+func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun, doSeen bool) bool {
        isBad := false
        for job := range ctx.Jobs(nodeId, TRx) {
                pktName := filepath.Base(job.Fd.Name())
@@ -123,6 +127,11 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun bool) bool {
                        }
                        ctx.LogI("rx", sds, "")
                        if !dryRun {
+                               if doSeen {
+                                       if fd, err := os.Create(job.Fd.Name() + SeenPostfix); err == nil {
+                                               fd.Close()
+                                       }
+                               }
                                if err = os.Remove(job.Fd.Name()); err != nil {
                                        ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "remove")
                                        isBad = true
@@ -189,6 +198,11 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun bool) bool {
                        }
                        ctx.LogI("rx", sds, "")
                        if !dryRun {
+                               if doSeen {
+                                       if fd, err := os.Create(job.Fd.Name() + SeenPostfix); err == nil {
+                                               fd.Close()
+                                       }
+                               }
                                if err = os.Remove(job.Fd.Name()); err != nil {
                                        ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "remove")
                                        isBad = true
@@ -258,6 +272,11 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun bool) bool {
                        }
                        ctx.LogI("rx", sds, "")
                        if !dryRun {
+                               if doSeen {
+                                       if fd, err := os.Create(job.Fd.Name() + SeenPostfix); err == nil {
+                                               fd.Close()
+                                       }
+                               }
                                if err = os.Remove(job.Fd.Name()); err != nil {
                                        ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "remove")
                                        isBad = true
@@ -297,6 +316,11 @@ func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun bool) bool {
                        }
                        ctx.LogI("rx", sds, "")
                        if !dryRun {
+                               if doSeen {
+                                       if fd, err := os.Create(job.Fd.Name() + SeenPostfix); err == nil {
+                                               fd.Close()
+                                       }
+                               }
                                if err = os.Remove(job.Fd.Name()); err != nil {
                                        ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "remove")
                                        isBad = true
index c40c9d8628779ffe5b5855f0922b05575d930c3c..47a4ba48a0e5b18ada946cbb250c35520e4bbe73 100644 (file)
@@ -105,12 +105,12 @@ func TestTossEmail(t *testing.T) {
                        if len(dirFiles(rxPath)) == 0 {
                                continue
                        }
-                       ctx.Toss(ctx.Self.Id, DefaultNiceMail-1, false)
+                       ctx.Toss(ctx.Self.Id, DefaultNiceMail-1, false, false)
                        if len(dirFiles(rxPath)) == 0 {
                                return false
                        }
                        ctx.Neigh[*nodeOur.Id].Sendmail = []string{"/bin/sh", "-c", "false"}
-                       ctx.Toss(ctx.Self.Id, DefaultNiceMail, false)
+                       ctx.Toss(ctx.Self.Id, DefaultNiceMail, false, false)
                        if len(dirFiles(rxPath)) == 0 {
                                return false
                        }
@@ -118,7 +118,7 @@ func TestTossEmail(t *testing.T) {
                                "/bin/sh", "-c",
                                fmt.Sprintf("cat >> %s", filepath.Join(spool, "mbox")),
                        }
-                       ctx.Toss(ctx.Self.Id, DefaultNiceMail, false)
+                       ctx.Toss(ctx.Self.Id, DefaultNiceMail, false, false)
                        if len(dirFiles(rxPath)) != 0 {
                                return false
                        }
@@ -190,12 +190,12 @@ func TestTossFile(t *testing.T) {
                }
                rxPath := filepath.Join(spool, ctx.Self.Id.String(), string(TRx))
                os.Rename(filepath.Join(spool, ctx.Self.Id.String(), string(TTx)), rxPath)
-               ctx.Toss(ctx.Self.Id, DefaultNiceFile, false)
+               ctx.Toss(ctx.Self.Id, DefaultNiceFile, false, false)
                if len(dirFiles(rxPath)) == 0 {
                        return false
                }
                ctx.Neigh[*nodeOur.Id].Incoming = &incomingPath
-               ctx.Toss(ctx.Self.Id, DefaultNiceFile, false)
+               ctx.Toss(ctx.Self.Id, DefaultNiceFile, false, false)
                if len(dirFiles(rxPath)) != 0 {
                        return false
                }
@@ -262,7 +262,7 @@ func TestTossFileSameName(t *testing.T) {
                rxPath := filepath.Join(spool, ctx.Self.Id.String(), string(TRx))
                os.Rename(filepath.Join(spool, ctx.Self.Id.String(), string(TTx)), rxPath)
                ctx.Neigh[*nodeOur.Id].Incoming = &incomingPath
-               ctx.Toss(ctx.Self.Id, DefaultNiceFile, false)
+               ctx.Toss(ctx.Self.Id, DefaultNiceFile, false, false)
                expected := make(map[string]struct{})
                expected["samefile"] = struct{}{}
                for i := 0; i < files-1; i++ {
@@ -330,12 +330,12 @@ func TestTossFreq(t *testing.T) {
                txPath := filepath.Join(spool, ctx.Self.Id.String(), string(TTx))
                os.Rename(txPath, rxPath)
                os.MkdirAll(txPath, os.FileMode(0700))
-               ctx.Toss(ctx.Self.Id, DefaultNiceFreq, false)
+               ctx.Toss(ctx.Self.Id, DefaultNiceFreq, false, false)
                if len(dirFiles(txPath)) != 0 || len(dirFiles(rxPath)) == 0 {
                        return false
                }
                ctx.Neigh[*nodeOur.Id].Freq = &spool
-               ctx.Toss(ctx.Self.Id, DefaultNiceFreq, false)
+               ctx.Toss(ctx.Self.Id, DefaultNiceFreq, false, false)
                if len(dirFiles(txPath)) != 0 || len(dirFiles(rxPath)) == 0 {
                        return false
                }
@@ -348,7 +348,7 @@ func TestTossFreq(t *testing.T) {
                                panic(err)
                        }
                }
-               ctx.Toss(ctx.Self.Id, DefaultNiceFreq, false)
+               ctx.Toss(ctx.Self.Id, DefaultNiceFreq, false, false)
                if len(dirFiles(txPath)) == 0 || len(dirFiles(rxPath)) != 0 {
                        return false
                }
@@ -441,7 +441,7 @@ func TestTossTrns(t *testing.T) {
                                panic(err)
                        }
                }
-               ctx.Toss(ctx.Self.Id, 123, false)
+               ctx.Toss(ctx.Self.Id, 123, false, false)
                if len(dirFiles(rxPath)) != 0 {
                        return false
                }