NNCP (Node to Node copy) это набор утилит упрощающий безопасный обмен
-файлами и почтой в режиме сохранить-и-переслать.
+файлами, почтой и командами в режиме сохранить-и-переслать.
Эти утилиты предназначены помочь с построением одноранговых устойчивых к
разрывам сетей небольшого размера (дюжины узлов), в режиме друг-к-другу
@section Подробнее об утилитах NNCP
@strong{NNCP} (Node to Node copy) это набор утилит упрощающий безопасный
-обмен файлами и почтой в режиме сохранить-и-переслать.
+обмен файлами, почтой и командами в режиме сохранить-и-переслать.
Эти утилиты предназначены помочь с построением однораговых
@url{https://ru.wikipedia.org/wiki/DTN, устойчивых к разрывам} сетей
@strong{NNCP} (Node to Node copy) is a collection of utilities
-simplifying secure store-and-forward files and mail exchanging.
+simplifying secure store-and-forward files, mail and command exchanging.
See also this page @ref{Об утилитах, on russian}.
@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
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
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.
+successful tossing of @file{XXX} packet. @ref{nncp-xfer},
+@ref{nncp-bundle}, @ref{nncp-daemon} and @ref{nncp-call} commands skip
+inbound packets that has been already seen, processed and tossed. This
+is helpful to prevent duplicates.
@option{-nofile}, @option{-nofreq}, @option{-nomail}, @option{-notrns}
options allow to disable any kind of packet types processing.
@multitable {XXXXX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@headitem Version @tab Size @tab Tarball @tab SHA256 checksum
+@item @ref{Release 3.3, 3.3} @tab 1152 KiB
+@tab @url{download/nncp-3.3.tar.xz, link} @url{download/nncp-3.3.tar.xz.sig, sign}
+@tab @code{1F8FA9B4 6125D8A9 0608298B A1ED87E1 12DB2D8B 81C766DE F4DFE191 C7B1BFC2}
+
@item @ref{Release 3.2, 3.2} @tab 1147 KiB
@tab @url{download/nncp-3.2.tar.xz, link} @url{download/nncp-3.2.tar.xz.sig, sign}
@tab @code{BE76802F 1E273D1D E91F0648 A7CB23C5 989F5390 A36F2D0C FD873046 51B9141E}
@itemize
@item @url{https://www.freshports.org/net/nncp/, FreeBSD ports}
-@item @url{https://github.com/voidlinux/void-packages/blob/master/srcpkgs/nncp/template, Void Linux}
+@item @url{https://github.com/void-linux/void-packages/blob/master/srcpkgs/nncp/template, Void Linux}
@end itemize
NNCP should run on any POSIX-compatible operating system.
@node Новости
@section Новости
+@node Релиз 3.4
+@subsection Релиз 3.4
+@itemize
+@item
+@command{nncp-daemon} может быть запущен как @command{inetd}-служба.
+@end itemize
+
@node Релиз 3.3
@subsection Релиз 3.3
@itemize
@subsection Релиз 0.11
@itemize
@item
-Вывод команды @command{nncp-stat} отсортирован по имены ноды.
+Вывод команды @command{nncp-stat} отсортирован по имени ноды.
@end itemize
@node Релиз 0.10
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
(@command{nncp-daemon}, @command{nncp-call}, @command{nncp-caller}).
@item
Ability to specify niceness with symbolic notation:
-@verb{|NORMAL|}, @verb{|BULK+10|}, @verb{|PRIORITY-5|}, итд.
+@verb{|NORMAL|}, @verb{|BULK+10|}, @verb{|PRIORITY-5|}, etc.
@item
Changed default niceness levels:
for @command{nncp-exec} from 64 to 96,
@option{-notrns}.
@item
@command{nncp-file} command uses
-@option{FreqMinSize}/@option{FreqChunked} conifiguration file options
+@option{FreqMinSize}/@option{FreqChunked} configuration file options
for @option{-minsize}/@option{-chunked} by default. You can turn this
off by specifying zero value.
@end itemize
golang.org/x/crypto/curve25519
golang.org/x/crypto/ed25519
golang.org/x/crypto/internal/chacha20
+golang.org/x/crypto/internal/subtle
golang.org/x/crypto/nacl
golang.org/x/crypto/poly1305
golang.org/x/crypto/salsa20
"net"
"os"
"strconv"
+ "time"
"cypherpunks.ru/nncp"
"golang.org/x/net/netutil"
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")
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)
}
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)
}
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}
}
func (ctx *Ctx) StartI(
- conn net.Conn,
+ conn ConnDeadlined,
nodeId *NodeId,
nice uint8,
xxOnly TRxTx,
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,
}
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))}
-Subproject commit 8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9
+Subproject commit a49355c7e3f8fe157a85be2f77e6e269a0f89602
-Subproject commit 1e491301e022f8f977054da4c2d852decd59571f
+Subproject commit 32a936f46389aa10549d60bd7833e54b01685d09
-Subproject commit 9527bec2660bd847c050fda93a0f0c6dee0800bb
+Subproject commit 3c6ecd8f22c6f40fbeec94c000a069d7d87c7624