From c9c269bb811cb22fe06254eac567c1921390bc37 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sun, 8 Jul 2018 14:59:35 +0300 Subject: [PATCH] nncp-daemon can be run under inetd --- VERSION | 2 +- doc/cmds.texi | 9 ++- doc/news.ru.texi | 7 ++ doc/news.texi | 7 ++ .../nncp/cmd/nncp-daemon/main.go | 72 ++++++++++++++----- src/cypherpunks.ru/nncp/sp.go | 12 +++- 6 files changed, 85 insertions(+), 24 deletions(-) diff --git a/VERSION b/VERSION index eb39e53..2f4b607 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3 +3.4 diff --git a/doc/cmds.texi b/doc/cmds.texi index afc5091..2f6f386 100644 --- a/doc/cmds.texi +++ b/doc/cmds.texi @@ -230,7 +230,7 @@ not used often in practice, if ever. @section nncp-daemon @verbatim -% nncp-daemon [options] [-maxconn INT] [-bind ADDR] +% nncp-daemon [options] [-maxconn INT] [-bind ADDR] [-inetd] @end verbatim Start listening TCP daemon, wait for incoming connections and run @@ -242,6 +242,13 @@ time to time. can handle. @option{-bind} option specifies @option{addr:port} it must bind to and listen. +It could be run as @command{inetd} service, by specifying +@option{-inetd} option. Example inetd-entry: + +@verbatim +uucp stream tcp6 nowait nncpuser /usr/local/bin/nncp-daemon nncp-daemon -inetd +@end verbatim + @node nncp-exec @section nncp-exec diff --git a/doc/news.ru.texi b/doc/news.ru.texi index 2e64801..46e6357 100644 --- a/doc/news.ru.texi +++ b/doc/news.ru.texi @@ -1,6 +1,13 @@ @node Новости @section Новости +@node Релиз 3.4 +@subsection Релиз 3.4 +@itemize +@item +@command{nncp-daemon} может быть запущен как @command{inetd}-служба. +@end itemize + @node Релиз 3.3 @subsection Релиз 3.3 @itemize diff --git a/doc/news.texi b/doc/news.texi index 3a9308d..16f1d6f 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -3,6 +3,13 @@ See also this page @ref{Новости, on russian}. +@node Release 3.4 +@section Release 3.4 +@itemize +@item +@command{nncp-daemon} can be run as @command{inetd}-service. +@end itemize + @node Release 3.3 @section Release 3.3 @itemize diff --git a/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go b/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go index ba2d602..7705568 100644 --- a/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go +++ b/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go @@ -26,6 +26,7 @@ import ( "net" "os" "strconv" + "time" "cypherpunks.ru/nncp" "golang.org/x/net/netutil" @@ -38,11 +39,55 @@ func usage() { flag.PrintDefaults() } +type InetdConn struct { + r *os.File + w *os.File +} + +func (ic *InetdConn) Read(p []byte) (n int, err error) { + return ic.r.Read(p) +} + +func (ic *InetdConn) Write(p []byte) (n int, err error) { + return ic.w.Write(p) +} + +func (ic *InetdConn) SetReadDeadline(t time.Time) error { + return ic.r.SetReadDeadline(t) +} + +func (ic *InetdConn) SetWriteDeadline(t time.Time) error { + return ic.w.SetWriteDeadline(t) +} + +func performSP(ctx *nncp.Ctx, conn nncp.ConnDeadlined, nice uint8) { + state, err := ctx.StartR(conn, nice, "") + if err == nil { + ctx.LogI("call-start", nncp.SDS{"node": state.Node.Id}, "connected") + state.Wait() + ctx.LogI("call-finish", nncp.SDS{ + "node": state.Node.Id, + "duration": strconv.FormatInt(int64(state.Duration.Seconds()), 10), + "rxbytes": strconv.FormatInt(state.RxBytes, 10), + "txbytes": strconv.FormatInt(state.TxBytes, 10), + "rxspeed": strconv.FormatInt(state.RxSpeed, 10), + "txspeed": strconv.FormatInt(state.TxSpeed, 10), + }, "") + } else { + nodeId := "unknown" + if state != nil && state.Node != nil { + nodeId = state.Node.Id.String() + } + ctx.LogE("call-start", nncp.SDS{"node": nodeId, "err": err}, "") + } +} + func main() { var ( cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file") niceRaw = flag.String("nice", nncp.NicenessFmt(255), "Minimal required niceness") bind = flag.String("bind", "[::]:5400", "Address to bind to") + inetd = flag.Bool("inetd", false, "Is it started as inetd service") maxConn = flag.Int("maxconn", 128, "Maximal number of simultaneous connections") spoolPath = flag.String("spool", "", "Override path to spool") logPath = flag.String("log", "", "Override path to logfile") @@ -74,6 +119,13 @@ func main() { log.Fatalln("Config lacks private keys") } + if *inetd { + os.Stderr.Close() + conn := &InetdConn{os.Stdin, os.Stdout} + performSP(ctx, conn, nice) + return + } + ln, err := net.Listen("tcp", *bind) if err != nil { log.Fatalln("Can not listen:", err) @@ -86,25 +138,7 @@ func main() { } ctx.LogD("daemon", nncp.SDS{"addr": conn.RemoteAddr()}, "accepted") go func(conn net.Conn) { - state, err := ctx.StartR(conn, nice, "") - if err == nil { - ctx.LogI("call-start", nncp.SDS{"node": state.Node.Id}, "connected") - state.Wait() - ctx.LogI("call-finish", nncp.SDS{ - "node": state.Node.Id, - "duration": strconv.FormatInt(int64(state.Duration.Seconds()), 10), - "rxbytes": strconv.FormatInt(state.RxBytes, 10), - "txbytes": strconv.FormatInt(state.TxBytes, 10), - "rxspeed": strconv.FormatInt(state.RxSpeed, 10), - "txspeed": strconv.FormatInt(state.TxSpeed, 10), - }, "") - } else { - nodeId := "unknown" - if state != nil && state.Node != nil { - nodeId = state.Node.Id.String() - } - ctx.LogE("call-start", nncp.SDS{"node": nodeId, "err": err}, "") - } + performSP(ctx, conn, nice) conn.Close() }(conn) } diff --git a/src/cypherpunks.ru/nncp/sp.go b/src/cypherpunks.ru/nncp/sp.go index 957dec9..d3ffb9f 100644 --- a/src/cypherpunks.ru/nncp/sp.go +++ b/src/cypherpunks.ru/nncp/sp.go @@ -104,6 +104,12 @@ type FreqWithNice struct { nice uint8 } +type ConnDeadlined interface { + io.ReadWriter + SetReadDeadline(t time.Time) error + SetWriteDeadline(t time.Time) error +} + func init() { var buf bytes.Buffer spHead := SPHead{Type: SPTypeHalt} @@ -275,7 +281,7 @@ func (ctx *Ctx) infosOur(nodeId *NodeId, nice uint8, seen *map[[32]byte]uint8) [ } func (ctx *Ctx) StartI( - conn net.Conn, + conn ConnDeadlined, nodeId *NodeId, nice uint8, xxOnly TRxTx, @@ -384,7 +390,7 @@ func (ctx *Ctx) StartI( return &state, err } -func (ctx *Ctx) StartR(conn net.Conn, nice uint8, xxOnly TRxTx) (*SPState, error) { +func (ctx *Ctx) StartR(conn ConnDeadlined, nice uint8, xxOnly TRxTx) (*SPState, error) { started := time.Now() conf := noise.Config{ CipherSuite: NoiseCipherSuite, @@ -499,7 +505,7 @@ func (ctx *Ctx) StartR(conn net.Conn, nice uint8, xxOnly TRxTx) (*SPState, error } func (state *SPState) StartWorkers( - conn net.Conn, + conn ConnDeadlined, infosPayloads [][]byte, payload []byte) error { sds := SDS{"node": state.Node.Id, "nice": strconv.Itoa(int(state.nice))} -- 2.44.0