]> Cypherpunks.ru repositories - nncp.git/commitdiff
Do not ACK ACKs
authorSergey Matveev <stargrave@stargrave.org>
Fri, 4 Mar 2022 10:19:38 +0000 (13:19 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Fri, 4 Mar 2022 13:46:01 +0000 (16:46 +0300)
doc/news.ru.texi
doc/news.texi
ports/nncp/Makefile
src/cmd/nncp-ack/main.go
src/nncp.go

index e814570b6f7d7e4d3effe667c75cdd571b157c90..f4bdb57ba46e02510d0fd8156f44e3fee2d3d37f 100644 (file)
@@ -5,6 +5,10 @@
 @subsection Релиз 8.7.0
 @itemize
 
+@item
+@command{nncp-ack} не подтверждает ACK-пакеты, предотвращая бесконечную
+петлю из ACK-ов.
+
 @item
 В прошлом, @command{nncp-ack} не удаляла соответствующие @file{hdr/} файлы.
 
index 4ed60a086029d425bc633b44d1fa7b5af30a503f..33d5384fbe6db6bf0231316a820af0f767bc5c40 100644 (file)
@@ -8,6 +8,10 @@ See also this page @ref{Новости, on russian}.
 @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.
 
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..950295a7d81029f7b8b4dfc11815b454d0ea4d42 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"
 )
 
@@ -127,12 +131,98 @@ func main() {
                return
        }
 
+       isBad := false
        for _, node := range nodes {
                for job := range ctx.Jobs(node.Id, nncp.TRx) {
                        pktName := filepath.Base(job.Path)
+                       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
+                       }
                        if err = ctx.TxACK(node, nice, pktName, minSize); err != nil {
                                log.Fatalln(err)
                        }
                }
        }
+       if isBad {
+               os.Exit(1)
+       }
 }
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)
 )