doc/cfg/general.texi | 12 ++++++------ doc/cmd/nncp-call.texi | 5 +++++ doc/cmd/nncp-file.texi | 17 ++++++++++------- doc/contacts.texi | 3 +++ doc/download.texi | 7 +++++++ doc/news.ru.texi | 20 ++++++++++++++++++++ doc/news.texi | 19 +++++++++++++++++++ src/cmd/nncp-call/main.go | 38 ++++++++++++++++++++++++++++++++++++++ src/cmd/nncp-caller/main.go | 20 +++++++++++++++++--- src/cmd/nncp-cfgnew/main.go | 9 +++++---- src/cmd/nncp-daemon/main.go | 40 ++++++++++++++++++++++++++++++---------- src/nncp.go | 2 +- src/tx.go | 6 +++--- diff --git a/doc/cfg/general.texi b/doc/cfg/general.texi index a8c890d76737ebd9179c7a476c887385943882e6f12c731aa97c9acb1e763e79..bf50c7535c6b880856e0e3ef7e444d114c05d71162b42cc119bdeda12e278007 100644 --- a/doc/cfg/general.texi +++ b/doc/cfg/general.texi @@ -13,8 +13,8 @@ noprogress: true nohdr: true # MultiCast Discovery -mcd-listen: ["em0", "igb1"] -mcd-send: {em0: 60, igb1: 5} +mcd-listen: ["em[0-3]", "igb_.*"] +mcd-send: {"em[0-3]": 60, igb_.*: 5} # Yggdrasil aliases yggdrasil-aliases: { @@ -52,12 +52,12 @@ @table @code @anchor{CfgMCDListen} @item mcd-listen -Specifies list of network interfaces @ref{nncp-caller} will listen for -incoming @ref{MCD} announcements. +Specifies list of network interfaces regular expression +@ref{nncp-caller} will listen for incoming @ref{MCD} announcements. @anchor{CfgMCDSend} @item mcd-send -Specifies list of network interfaces, and intervals in seconds, where -@ref{nncp-daemon} will send @ref{MCD} announcements. +Specifies list of network interfaces regular expressions, and intervals +in seconds, where @ref{nncp-daemon} will send @ref{MCD} announcements. @end table @anchor{CfgYggdrasilAliases} diff --git a/doc/cmd/nncp-call.texi b/doc/cmd/nncp-call.texi index e492857506af41d1a30362ef2ca516a795958d071ecce6863f01cc1fad7f1861..850d2d4fd450e66107ddebf2de5c55b0de1cec44da928554b5ccb296ef51f94f 100644 --- a/doc/cmd/nncp-call.texi +++ b/doc/cmd/nncp-call.texi @@ -13,6 +13,7 @@ [-txrate INT] [-autotoss*] [-nock] [-ucspi] + [-mcd-wait INT] NODE[:ADDR] [FORCEADDR] @end example @@ -47,6 +48,10 @@ 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{-mcd-wait} options tells to wait up to specified number of +seconds for the @ref{MCD} packet from the specified @code{NODE}. When +the packet is received, initiate a call. @option{-autotoss} option runs tosser on node's spool every second during the call. All @option{-autotoss-*} options is the same as in diff --git a/doc/cmd/nncp-file.texi b/doc/cmd/nncp-file.texi index c9b7fac8f22b0842664bc0fa78857c55b7d3c64349a7529b7dc5007b346074e2..bc7774d74082332fe69d8cd4a058c5ab0fb59e09763796647d976edc5dc4d1e3 100644 --- a/doc/cmd/nncp-file.texi +++ b/doc/cmd/nncp-file.texi @@ -18,13 +18,16 @@ If @file{SRC} equals to @file{-}, to data is read from @code{stdin}. If @file{SRC} points to directory, then -@url{https://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_01, pax archive} -will be created on the fly with directory contents and destination -filename @file{.tar} appended. It @strong{won't} contain any entities -metainformation, but modification time with the names. UID/GID are set -to zero. Directories have 777 permissions, files have 666, for being -friendly with @command{umask}. Also each entity will have comment like -@verb{|Autogenerated by NNCP version X.Y.Z built with goXXX|}. +@url{https://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_01, +pax archive} will be created on the fly with directory contents and +destination filename @file{.tar} appended. It @strong{won't} contain any +entities metainformation, except for modification time with the names. +UID/GID are set to zero. Directories have 777 permissions, files have +666, for being friendly with @command{umask}. Everything except +directories and regulars files is skipped. Also each entity will have +comment like @verb{|Autogenerated by NNCP version X.Y.Z built with goXXX|}. +For more precise metainformation and various file objects storage use +external @command{tar} command piped in. If @option{-chunked} is specified, then source file will be split @ref{Chunked, on chunks}. @option{INT} is the desired chunk size in diff --git a/doc/contacts.texi b/doc/contacts.texi index 4c2a432adfe1a34146602e481bda82031cd3281d2e4241bcf4350697106b9261..d5f25adb74662a72482ca77eac0d4f86119b491fea55d3e65c5b953be72e2a5e 100644 --- a/doc/contacts.texi +++ b/doc/contacts.texi @@ -5,4 +5,7 @@ Please send questions regarding the use of NNCP, bug reports and patches to @url{http://lists.cypherpunks.ru/nncp_002ddevel.html, nncp-devel} mailing list. Announcements also go to this mailing list. +There are also community-supported @code{#nncp:matrix.org} Matrix +channel and @code{irc://irc.oftc.net/nncp} IRC channel bridged to it. + Official website is @url{http://www.nncpgo.org/}. diff --git a/doc/download.texi b/doc/download.texi index d653d88bc2983ac627c3210b418ef673752ebf54d6d63d8c804d3eb7fb61d380..1a153576b7ec8a87a2c04351357be1afb2f7803fd6efffb83463990fa7606764 100644 --- a/doc/download.texi +++ b/doc/download.texi @@ -45,6 +45,13 @@ @multitable {XXXXX} {XXXX-XX-XX} {XXXX KiB} {meta4 link sig} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} @headitem Version @tab Date @tab Size @tab Tarball @tab SHA256 checksum +@item @ref{Release 8_3_0, 8.3.0} @tab 2022-01-23 @tab 1682 KiB +@tab + @url{download/nncp-8.3.0.tar.xz.meta4, meta4} + @url{download/nncp-8.3.0.tar.xz, link} + @url{download/nncp-8.3.0.tar.xz.sig, sig} +@tab @code{6C14887A 9EF686D6 112F2096 ED1DA56B AABE5FEB 4BA92573 89ACC6B2 6D0A23EA} + @item @ref{Release 8_2_0, 8.2.0} @tab 2022-01-20 @tab 1669 KiB @tab @url{download/nncp-8.2.0.tar.xz.meta4, meta4} diff --git a/doc/news.ru.texi b/doc/news.ru.texi index 96bce4691a9de987f53e70e2e4ab86b6e781866257aa5c2491c56522116a74be..45c83ecc78f05fa87498bd0147d513f24974d976b143e6695f3953cf2e2cd748 100644 --- a/doc/news.ru.texi +++ b/doc/news.ru.texi @@ -1,6 +1,26 @@ @node Новости @section Новости +@node Релиз 8.4.0 +@subsection Релиз 8.4.0 +@itemize + +@item +Имена интерфейсов относящихся к multicast (@code{mcd-listen} и +@code{mcd-send} опции конфигурации) теперь являются регулярными +выражениями. По умолчанию @command{nncp-cfgnew} не комментирует +их теперь и прописывает @code{.*} имя интерфейса. + +@item +У @command{nncp-call} команды появился @option{-mcd-wait} аргумент, +позволяющий дожидаться multicast сообщения об адресе ноды. + +@item +@command{nncp-file} команда пропускает всё что не является регулярным +файлом или директорией во время создания pax-архива. + +@end itemize + @node Релиз 8.3.0 @subsection Релиз 8.3.0 @itemize diff --git a/doc/news.texi b/doc/news.texi index e10dcc92141fa1c8e83d71bcdf06fb5cc0c43b1625a25255b0992b328ba2fb55..ad1a4baf643b85a9d5374f781894f1a994bced322ab506311c7100db23b07052 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -3,6 +3,25 @@ @unnumbered News See also this page @ref{Новости, on russian}. +@node Release 8_4_0 +@section Release 8.4.0 +@itemize + +@item +Multicast related interface names (@code{mcd-listen} and @code{mcd-send} +configuration options) are now regular expressions. By default +@command{nncp-cfgnew} uncomments them now with @code{.*} interface name. + +@item +@command{nncp-call} command has @option{-mcd-wait} option to wait for +multicast packet about node's address. + +@item +@command{nncp-file} command skips everything that is neither regular +file nor directory during pax-archive creation. + +@end itemize + @node Release 8_3_0 @section Release 8.3.0 @itemize diff --git a/src/cmd/nncp-call/main.go b/src/cmd/nncp-call/main.go index 7cc4d0a7aae004db1ddf7583babd95eedf80f7a24c4f5569998243d18fef61d2..7e799117e28d893d476d6eef41c5c01d11fc82b9bf49f279f2b62fdcdb8097a9 100644 --- a/src/cmd/nncp-call/main.go +++ b/src/cmd/nncp-call/main.go @@ -22,7 +22,9 @@ import ( "flag" "fmt" "log" + "net" "os" + "regexp" "strings" "time" @@ -47,6 +49,7 @@ txOnly = flag.Bool("tx", false, "Only transmit packets") listOnly = flag.Bool("list", false, "Only list remote packets") noCK = flag.Bool("nock", false, "Do no checksum checking") onlyPktsRaw = flag.String("pkts", "", "Recieve only that packets, comma separated") + mcdWait = flag.Uint("mcd-wait", 60, "Wait for MCD for specified number of seconds") rxRate = flag.Int("rxrate", 0, "Maximal receive rate, pkts/sec") txRate = flag.Int("txrate", 0, "Maximal transmit rate, pkts/sec") spoolPath = flag.String("spool", "", "Override path to spool") @@ -147,6 +150,41 @@ addrs = append(addrs, addr) } else { for _, addr := range ctx.Neigh[*node.Id].Addrs { addrs = append(addrs, addr) + } + } + + if *mcdWait > 0 { + ifis, err := net.Interfaces() + if err != nil { + log.Fatalln("Can not get network interfaces list:", err) + } + for _, ifiReString := range ctx.MCDRxIfis { + ifiRe, err := regexp.CompilePOSIX(ifiReString) + if err != nil { + log.Fatalf("Can not compile POSIX regexp \"%s\": %s", ifiReString, err) + } + for _, ifi := range ifis { + if ifiRe.MatchString(ifi.Name) { + if err = ctx.MCDRx(ifi.Name); err != nil { + log.Printf("Can not run MCD reception on %s: %s", ifi.Name, err) + } + } + } + } + addrs = nil + for i := int(*mcdWait); i > 0; i-- { + nncp.MCDAddrsM.RLock() + for _, mcdAddr := range nncp.MCDAddrs[*node.Id] { + addrs = append(addrs, mcdAddr.Addr.String()) + } + if len(addrs) > 0 { + break + } + nncp.MCDAddrsM.RUnlock() + time.Sleep(time.Second) + } + if len(addrs) == 0 { + log.Fatalf("No MCD packets from the node during %d seconds", *mcdWait) } } diff --git a/src/cmd/nncp-caller/main.go b/src/cmd/nncp-caller/main.go index 5db9169a1792b3fe1272542837a33b6f6e78e5c8739177926d10ccdf86746cd4..8319f4eba451165fa07985a48c2793657faf20046ba229dd744b275d2a1c5ce5 100644 --- a/src/cmd/nncp-caller/main.go +++ b/src/cmd/nncp-caller/main.go @@ -23,7 +23,9 @@ "errors" "flag" "fmt" "log" + "net" "os" + "regexp" "sync" "time" @@ -125,9 +127,21 @@ nodes = append(nodes, node) } } - for _, ifiName := range ctx.MCDRxIfis { - if err = ctx.MCDRx(ifiName); err != nil { - log.Printf("Can not run MCD reception on %s: %s", ifiName, err) + ifis, err := net.Interfaces() + if err != nil { + log.Fatalln("Can not get network interfaces list:", err) + } + for _, ifiReString := range ctx.MCDRxIfis { + ifiRe, err := regexp.CompilePOSIX(ifiReString) + if err != nil { + log.Fatalf("Can not compile POSIX regexp \"%s\": %s", ifiReString, err) + } + for _, ifi := range ifis { + if ifiRe.MatchString(ifi.Name) { + if err = ctx.MCDRx(ifi.Name); err != nil { + log.Printf("Can not run MCD reception on %s: %s", ifi.Name, err) + } + } } } diff --git a/src/cmd/nncp-cfgnew/main.go b/src/cmd/nncp-cfgnew/main.go index 1f56fac7a6c28238fd86e8835045edb5d77f462cc92ed112dbc32b4cd288abac..f15e7147b45bd7aae20c6e54777691c0905dc246f2e0891bc441f0f38443eb32 100644 --- a/src/cmd/nncp-cfgnew/main.go +++ b/src/cmd/nncp-cfgnew/main.go @@ -198,10 +198,11 @@ # Do not use hdr/ files # nohdr: true # MultiCast Discovery: - # List of interfaces where to listen for MCD announcements - # mcd-listen: ["em0", "igb1"] - # Interfaces and intervals (in seconds) where to send MCD announcements - # mcd-send: {em0: 60, igb1: 5} + # List of interface regular expressions where to listen for MCD announcements + mcd-listen: [".*"] + # Interfaces regular expressions and intervals (in seconds) where to send + # MCD announcements + mcd-send: {.*: 10} # Yggdrasil related aliases: # yggdrasil-aliases: { diff --git a/src/cmd/nncp-daemon/main.go b/src/cmd/nncp-daemon/main.go index 831efb71458745f1c90b79dcdc0838153fd8e13c004073a046b09fe3a87e05d7..95ab9b06ddb2628b7133b167ef8169f4d52a6fbb99ea53e7cab376b9bc930fae 100644 --- a/src/cmd/nncp-daemon/main.go +++ b/src/cmd/nncp-daemon/main.go @@ -24,6 +24,7 @@ "fmt" "log" "net" "os" + "regexp" "strconv" "strings" "time" @@ -105,6 +106,31 @@ } close(nodeIdC) } +func startMCDTx(ctx *nncp.Ctx, port int, zeroInterval bool) error { + ifis, err := net.Interfaces() + if err != nil { + return err + } + for ifiReString, secs := range ctx.MCDTxIfis { + ifiRe, err := regexp.CompilePOSIX(ifiReString) + if err != nil { + return err + } + var interval time.Duration + if !zeroInterval { + interval = time.Duration(secs) * time.Second + } + for _, ifi := range ifis { + if ifiRe.MatchString(ifi.Name) { + if err = ctx.MCDTx(ifi.Name, port, interval); err != nil { + return err + } + } + } + } + return nil +} + func main() { var ( cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file") @@ -211,10 +237,8 @@ log.Fatalln("Can not parse port:", err) } if *mcdOnce { - for ifiName := range ctx.MCDTxIfis { - if err = ctx.MCDTx(ifiName, port, 0); err != nil { - log.Fatalln("Can not do MCD transmission:", err) - } + if err = startMCDTx(ctx, port, true); err != nil { + log.Fatalln("Can not do MCD transmission:", err) } return } @@ -223,13 +247,9 @@ ln, err := net.Listen("tcp", *bind) if err != nil { log.Fatalln("Can not listen:", err) } - - for ifiName, secs := range ctx.MCDTxIfis { - if err = ctx.MCDTx(ifiName, port, time.Duration(secs)*time.Second); err != nil { - log.Fatalln("Can not run MCD transmission:", err) - } + if err = startMCDTx(ctx, port, false); err != nil { + log.Fatalln("Can not do MCD transmission:", err) } - ln = netutil.LimitListener(ln, *maxConn) go func() { for { diff --git a/src/nncp.go b/src/nncp.go index 6e98846ed8a5722cb77a873f479c769573e96acd9fde639b2b7e8509b10738ba..5915a2ad91dd289c966dfdcb215eabd5c927be23c70841bd4b56a15d78110302 100644 --- a/src/nncp.go +++ b/src/nncp.go @@ -40,7 +40,7 @@ const Base32Encoded32Len = 52 var ( - Version string = "8.3.0" + Version string = "8.4.0" Base32Codec *base32.Encoding = base32.StdEncoding.WithPadding(base32.NoPadding) ) diff --git a/src/tx.go b/src/tx.go index 762f1e165fec997f6024cd4bab8f3d9b3b502f74593a4396dba5e912078304e7..fe339de18d8f2af94ce7ba6ed8e7a4166add5666ff2023bc027586b41ba7bab1 100644 --- a/src/tx.go +++ b/src/tx.go @@ -211,7 +211,7 @@ for i := 0; i <= wrappers; i++ { r := <-results if r.err != nil { tmp.Fd.Close() - return nil, 0, err + return nil, 0, r.err } if r.pktEncRaw != nil { pktEncRaw = r.pktEncRaw @@ -330,11 +330,11 @@ rerr = filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error { if err != nil { return err } - if info.IsDir() { + if info.Mode().IsDir() { // directory header, PAX record header+contents srcSize += TarBlockSize + 2*TarBlockSize dirs = append(dirs, einfo{path: path, modTime: info.ModTime()}) - } else { + } else if info.Mode().IsRegular() { // file header, PAX record header+contents, file content srcSize += TarBlockSize + 2*TarBlockSize + info.Size() if n := info.Size() % TarBlockSize; n != 0 {