From: Sergey Matveev Date: Mon, 26 Jul 2021 12:44:56 +0000 (+0300) Subject: nncp-call -ucspi X-Git-Tag: v7.5.0^2~6 X-Git-Url: http://www.git.cypherpunks.ru/?p=nncp.git;a=commitdiff_plain;h=bd98bc071da6b50d20ddf1df02af69111df4831c nncp-call -ucspi --- diff --git a/doc/cmd/nncp-call.texi b/doc/cmd/nncp-call.texi index 9dc32bd..86516a9 100644 --- a/doc/cmd/nncp-call.texi +++ b/doc/cmd/nncp-call.texi @@ -12,6 +12,7 @@ $ nncp-call [options] [-txrate INT] [-autotoss*] [-nock] + [-ucspi] NODE[:ADDR] [FORCEADDR] @end example @@ -42,6 +43,10 @@ success. Optionally you can force @option{FORCEADDR} address usage, instead of addresses taken from configuration file. You can specify both @verb{|host:port|} and @verb{#|some command#} formats. +If you specify @option{-ucspi} option, then it is assumed that you run +@command{nncp-call} command under some UCSPI-TCP compatible utility, +that provides read/write channels through 6/7 file descriptors. + @option{-autotoss} option runs tosser on node's spool every second during the call. All @option{-autotoss-*} options is the same as in @ref{nncp-toss} command. diff --git a/doc/news.ru.texi b/doc/news.ru.texi index 25af628..3f7d2df 100644 --- a/doc/news.ru.texi +++ b/doc/news.ru.texi @@ -11,6 +11,10 @@ совместимой утилитой). Желательно применять @option{-ucspi} опцию вместо @option{-inetd}. +@item +@command{nncp-call} может быть UCSPI-TCP клиентом, используя +@option{-ucspi} опцию. + @end itemize @node Релиз 7.4.0 diff --git a/doc/news.texi b/doc/news.texi index 1d8a3ee..6707c6f 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -12,6 +12,9 @@ See also this page @ref{Новости, on russian}. will contain remote side's address (when running under appropriate utility). @option{-ucspi} option should be used instead of @option{-inetd}. +@item +@command{nncp-call} can be UCSPI-TCP client, using @option{-ucspi} option. + @end itemize @node Release 7_4_0 diff --git a/src/call.go b/src/call.go index 1e20aa2..e8b3f76 100644 --- a/src/call.go +++ b/src/call.go @@ -18,8 +18,10 @@ along with this program. If not, see . package nncp import ( + "errors" "fmt" "net" + "os" "time" "github.com/dustin/go-humanize" @@ -68,6 +70,19 @@ func (ctx *Ctx) CallNode( var err error if addr[0] == '|' { conn, err = NewPipeConn(addr[1:]) + } else if addr == UCSPITCPClient { + ucspiConn := UCSPIConn{R: os.NewFile(6, "R"), W: os.NewFile(7, "W")} + if ucspiConn.R == nil { + err = errors.New("no 6 file descriptor") + } + if ucspiConn.W == nil { + err = errors.New("no 7 file descriptor") + } + conn = ucspiConn + addr = UCSPITCPRemoteAddr() + if addr == "" { + addr = UCSPITCPClient + } } else { conn, err = net.Dial("tcp", addr) } diff --git a/src/cmd/nncp-call/main.go b/src/cmd/nncp-call/main.go index 09c3e18..7d12066 100644 --- a/src/cmd/nncp-call/main.go +++ b/src/cmd/nncp-call/main.go @@ -40,6 +40,7 @@ func usage() { func main() { var ( cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file") + ucspi = flag.Bool("ucspi", false, "Is it started as UCSPI-TCP client") niceRaw = flag.String("nice", nncp.NicenessFmt(255), "Minimal required niceness") rxOnly = flag.Bool("rx", false, "Only receive packets") txOnly = flag.Bool("tx", false, "Only transmit packets") @@ -133,7 +134,9 @@ func main() { } var addrs []string - if flag.NArg() == 2 { + if *ucspi { + addrs = append(addrs, nncp.UCSPITCPClient) + } else if flag.NArg() == 2 { addrs = append(addrs, flag.Arg(1)) } else if len(splitted) == 2 { addr, known := ctx.Neigh[*node.Id].Addrs[splitted[1]] diff --git a/src/cmd/nncp-daemon/main.go b/src/cmd/nncp-daemon/main.go index f27c2a3..485199c 100644 --- a/src/cmd/nncp-daemon/main.go +++ b/src/cmd/nncp-daemon/main.go @@ -40,35 +40,6 @@ func usage() { flag.PrintDefaults() } -type UCSPIConn struct { - r *os.File - w *os.File -} - -func (c UCSPIConn) Read(p []byte) (n int, err error) { - return c.r.Read(p) -} - -func (c UCSPIConn) Write(p []byte) (n int, err error) { - return c.w.Write(p) -} - -func (c UCSPIConn) SetReadDeadline(t time.Time) error { - return c.r.SetReadDeadline(t) -} - -func (c UCSPIConn) SetWriteDeadline(t time.Time) error { - return c.w.SetWriteDeadline(t) -} - -func (c UCSPIConn) Close() error { - if err := c.r.Close(); err != nil { - c.w.Close() // #nosec G104 - return err - } - return c.w.Close() -} - func performSP( ctx *nncp.Ctx, conn nncp.ConnDeadlined, @@ -198,16 +169,11 @@ func main() { if *ucspi { os.Stderr.Close() // #nosec G104 - conn := &UCSPIConn{os.Stdin, os.Stdout} + conn := &nncp.UCSPIConn{R: os.Stdin, W: os.Stdout} nodeIdC := make(chan *nncp.NodeId) - addr := "PIPE" - if proto := os.Getenv("PROTO"); proto == "TCP" { - port := os.Getenv("TCPREMOTEPORT") - if host := os.Getenv("TCPREMOTEHOST"); host == "" { - addr = fmt.Sprintf("[%s]:%s", os.Getenv("TCPREMOTEIP"), port) - } else { - addr = fmt.Sprintf("%s:%s", host, port) - } + addr := nncp.UCSPITCPRemoteAddr() + if addr == "" { + addr = "PIPE" } go performSP(ctx, conn, addr, nice, *noCK, nodeIdC) nodeId := <-nodeIdC diff --git a/src/ucspi.go b/src/ucspi.go new file mode 100644 index 0000000..33e265d --- /dev/null +++ b/src/ucspi.go @@ -0,0 +1,67 @@ +/* +NNCP -- Node to Node copy, utilities for store-and-forward data exchange +Copyright (C) 2016-2021 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 +the Free Software Foundation, version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package nncp + +import ( + "fmt" + "os" + "time" +) + +const UCSPITCPClient = "UCSPI-TCP-CLIENT" + +type UCSPIConn struct { + R *os.File + W *os.File +} + +func (c UCSPIConn) Read(p []byte) (n int, err error) { + return c.R.Read(p) +} + +func (c UCSPIConn) Write(p []byte) (n int, err error) { + return c.W.Write(p) +} + +func (c UCSPIConn) SetReadDeadline(t time.Time) error { + return c.R.SetReadDeadline(t) +} + +func (c UCSPIConn) SetWriteDeadline(t time.Time) error { + return c.W.SetWriteDeadline(t) +} + +func (c UCSPIConn) Close() error { + if err := c.R.Close(); err != nil { + c.W.Close() + return err + } + return c.W.Close() +} + +func UCSPITCPRemoteAddr() (addr string) { + if proto := os.Getenv("PROTO"); proto == "TCP" { + port := os.Getenv("TCPREMOTEPORT") + if host := os.Getenv("TCPREMOTEHOST"); host == "" { + addr = fmt.Sprintf("[%s]:%s", os.Getenv("TCPREMOTEIP"), port) + } else { + addr = fmt.Sprintf("%s:%s", host, port) + } + } + return +}