VERSION | 2 +- doc/download.texi | 4 ++++ doc/news.ru.texi | 8 ++++++++ doc/news.texi | 8 ++++++++ ports/nncp/Makefile | 2 +- src/cypherpunks.ru/nncp/call.go | 2 +- src/cypherpunks.ru/nncp/cfg.go | 21 ++++++++++----------- src/cypherpunks.ru/nncp/cmd/nncp-call/main.go | 2 +- src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go | 2 +- src/cypherpunks.ru/nncp/humanizer.go | 2 ++ src/cypherpunks.ru/nncp/lockdir.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cypherpunks.ru/nncp/node.go | 2 +- src/cypherpunks.ru/nncp/sp.go | 52 +++++++++++++++++++++++++++------------------------- src/cypherpunks.ru/nncp/toss.go | 34 ---------------------------------- diff --git a/VERSION b/VERSION index 2d248fd4cf9384b50fffabb409a4e83eafbf7e9f362fd1340d50bf6280a3e8be..b2d9c79b0847f7dcf450448ffd8a3942113d33acc6bcbbbd7d4be79aab4940c3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8 +0.9 diff --git a/doc/download.texi b/doc/download.texi index 77d92133c4a198924137c1e24a1e27a418c9689681bcf27b34952ffec0974444..ce45e4ba93f8ecb050cea677b20c0dc30b5c6fc335534c359deddcdaf239ad1b 100644 --- a/doc/download.texi +++ b/doc/download.texi @@ -24,6 +24,10 @@ @multitable {XXXXX} {XXXX KiB} {link sign} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx} @headitem Version @tab Size @tab Tarball @tab SHA256 checksum +@item @ref{Release 0.8, 0.8} @tab 932 KiB +@tab @url{download/nncp-0.8.tar.xz, link} @url{download/nncp-0.8.tar.xz.sig, sign} +@tab @code{9BD607D5 C5551857 B7E9277D 0E857936 1DB7353A E0F1556E EA9B1D91 8305B184} + @item @ref{Release 0.7, 0.7} @tab 783 KiB @tab @url{download/nncp-0.7.tar.xz, link} @url{download/nncp-0.7.tar.xz.sig, sign} @tab @code{D3407323 F89296DD 743FA764 51964B43 794E61BE 0E1D2DD4 ABD02042 B94FFC4F} diff --git a/doc/news.ru.texi b/doc/news.ru.texi index b73f2b973dfd64b027b17d9eee0779c493f13322bcf45b4762eaaf6ddd6e6aa1..cf65a2d2e84e5103675558641c70992d8f66c58f1d34f0cb7fbef8bfd9c7868d 100644 --- a/doc/news.ru.texi +++ b/doc/news.ru.texi @@ -1,6 +1,14 @@ @node Новости @section Новости +@node Релиз 0.9 +@subsection Релиз 0.9 +@itemize +@item +Исправлена обработка @option{-rx}/@option{-tx} опций @command{nncp-call} +команды. Они игнорировались. +@end itemize + @node Релиз 0.8 @subsection Релиз 0.8 @itemize diff --git a/doc/news.texi b/doc/news.texi index eb39f1590f3582b97947400f4adcd4cb02e81833b8fa9bf56d93cd9bc0b9b9ef..7bce2b5213bc2c15d6edc6f02f53c88a86ccaa45961a5ead0a8be07013bb069b 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -3,6 +3,14 @@ @unnumbered News See also this page @ref{Новости, on russian}. +@node Release 0.9 +@section Release 0.9 +@itemize +@item +Fix @option{-rx}/@option{-tx} arguments processing in +@command{nncp-call} command. They were ignored. +@end itemize + @node Release 0.8 @section Release 0.8 @itemize diff --git a/ports/nncp/Makefile b/ports/nncp/Makefile index 7093333615cad1907c513fe5aa398bb1679b5f307dd662387331816f1f11bf16..dc6c3dce8c744957caefc2ab4b36b3ea2c1a4d0ea896148c3f2a9ac577d263bf 100644 --- a/ports/nncp/Makefile +++ b/ports/nncp/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ PORTNAME= nncp -PORTVERSION= 0.8 +PORTVERSION= 0.9 CATEGORIES= net MASTER_SITES= http://www.nncpgo.org/download/ \ http://sourceforge.net/projects/nncp/files/ diff --git a/src/cypherpunks.ru/nncp/call.go b/src/cypherpunks.ru/nncp/call.go index 93c78239097e0a74f7125780d256552dceaeb55f2536f01dd01e4d9d7cfc550d..730f2ebf5512baa0b292f01cef0d9cb9b79517048baff499e2d7c95a95edcf34 100644 --- a/src/cypherpunks.ru/nncp/call.go +++ b/src/cypherpunks.ru/nncp/call.go @@ -23,7 +23,7 @@ "net" "strconv" ) -func (ctx *Ctx) CallNode(node *Node, addrs []string, nice uint8, xxOnly *TRxTx, onlineDeadline, maxOnlineTime uint) (isGood bool) { +func (ctx *Ctx) CallNode(node *Node, addrs []string, nice uint8, xxOnly TRxTx, onlineDeadline, maxOnlineTime uint) (isGood bool) { for _, addr := range addrs { sds := SDS{"node": node.Id, "addr": addr} ctx.LogD("call", sds, "dialing") diff --git a/src/cypherpunks.ru/nncp/cfg.go b/src/cypherpunks.ru/nncp/cfg.go index 5aeae975d38b3f524792d3a1217d3ffa53642370a2a36112abb494b4668857b4..345b8809183e74f5e2a9972941f5c7201976370ae42197ac3fa01e65af736601 100644 --- a/src/cypherpunks.ru/nncp/cfg.go +++ b/src/cypherpunks.ru/nncp/cfg.go @@ -64,7 +64,7 @@ type CallYAML struct { Cron string Nice *int `nice,omitempty` - Xx *string `xx,omitempty` + Xx string `xx,omitempty` Addr *string `addr,omitempty` OnlineDeadline *uint `onlinedeadline,omitempty` MaxOnlineTime *uint `maxonlinetime,omitempty` @@ -187,15 +187,14 @@ } nice = uint8(*callYml.Nice) } var xx TRxTx - if callYml.Xx != nil { - switch *callYml.Xx { - case "rx": - xx = TRx - case "tx": - xx = TTx - default: - return nil, errors.New("xx field must be either \"rx\" or \"tx\"") - } + switch callYml.Xx { + case "rx": + xx = TRx + case "tx": + xx = TTx + case "": + default: + return nil, errors.New("xx field must be either \"rx\" or \"tx\"") } var addr *string if callYml.Addr != nil { @@ -219,7 +218,7 @@ } calls = append(calls, &Call{ Cron: expr, Nice: nice, - Xx: &xx, + Xx: xx, Addr: addr, OnlineDeadline: onlineDeadline, MaxOnlineTime: maxOnlineTime, diff --git a/src/cypherpunks.ru/nncp/cmd/nncp-call/main.go b/src/cypherpunks.ru/nncp/cmd/nncp-call/main.go index feaf876dbfb1afdfad7343a96a5aed12fa59c5d5aae07c01243ca861fbb95dae..4d85a99c4f357459a3eee80f70a3c8a03c4e9c29d0617b2834acb723889a787c 100644 --- a/src/cypherpunks.ru/nncp/cmd/nncp-call/main.go +++ b/src/cypherpunks.ru/nncp/cmd/nncp-call/main.go @@ -126,7 +126,7 @@ addrs = append(addrs, addr) } } - if !ctx.CallNode(node, addrs, nice, &xxOnly, *onlineDeadline, *maxOnlineTime) { + if !ctx.CallNode(node, addrs, nice, xxOnly, *onlineDeadline, *maxOnlineTime) { os.Exit(1) } } diff --git a/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go b/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go index cdb4f56338d4af5bc08453443a2ce2c048f5d3d3c57467a97e6068a6b96412fb..0687adf6c31815461a625285ee2d0a12d71189f06c942adaff13d6d8d31823a9 100644 --- a/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go +++ b/src/cypherpunks.ru/nncp/cmd/nncp-daemon/main.go @@ -91,7 +91,7 @@ log.Fatalln("Can not accept connection:", err) } ctx.LogD("daemon", nncp.SDS{"addr": conn.RemoteAddr()}, "accepted") go func(conn net.Conn) { - state, err := ctx.StartR(conn, nice, nil) + state, err := ctx.StartR(conn, nice, "") if err == nil { ctx.LogI("call-start", nncp.SDS{"node": state.Node.Id}, "connected") state.Wait() diff --git a/src/cypherpunks.ru/nncp/humanizer.go b/src/cypherpunks.ru/nncp/humanizer.go index 3a3ab292cd9e1a5a7339e523be4d3c2e0136eb56a5cc8306415fd376fefa100b..265ca4d185685d6bea833bf93719cc2645c826e296aa94a941e255ca8e319c7d 100644 --- a/src/cypherpunks.ru/nncp/humanizer.go +++ b/src/cypherpunks.ru/nncp/humanizer.go @@ -237,6 +237,8 @@ } if err, exists := sds["err"]; exists { msg += ": " + err } + case "lockdir": + msg = fmt.Sprintf("Acquire lock for %s: %s", sds["path"], sds["err"]) default: return s } diff --git a/src/cypherpunks.ru/nncp/lockdir.go b/src/cypherpunks.ru/nncp/lockdir.go new file mode 100644 index 0000000000000000000000000000000000000000..02c6cda04041e5db052a86249617eecf3d637932705aaee653ae6c2a2cd0945d --- /dev/null +++ b/src/cypherpunks.ru/nncp/lockdir.go @@ -0,0 +1,54 @@ +/* +NNCP -- Node to Node copy, utilities for store-and-forward data exchange +Copyright (C) 2016-2017 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, either version 3 of the License, or +(at your option) any later version. + +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 ( + "os" + "path/filepath" + + "golang.org/x/sys/unix" +) + +func (ctx *Ctx) LockDir(nodeId *NodeId, xx TRxTx) (*os.File, error) { + ctx.ensureRxDir(nodeId) + lockPath := filepath.Join(ctx.Spool, nodeId.String(), string(xx)) + ".lock" + dirLock, err := os.OpenFile( + lockPath, + os.O_CREATE|os.O_WRONLY, + os.FileMode(0600), + ) + if err != nil { + ctx.LogE("lockdir", SDS{"path": lockPath, "err": err}, "") + return nil, err + } + err = unix.Flock(int(dirLock.Fd()), unix.LOCK_EX|unix.LOCK_NB) + if err != nil { + ctx.LogE("lockdir", SDS{"path": lockPath, "err": err}, "") + dirLock.Close() + return nil, err + } + return dirLock, nil +} + +func (ctx *Ctx) UnlockDir(fd *os.File) { + if fd != nil { + unix.Flock(int(fd.Fd()), unix.LOCK_UN) + fd.Close() + } +} diff --git a/src/cypherpunks.ru/nncp/node.go b/src/cypherpunks.ru/nncp/node.go index 37a2645a7f9cffd267f3b8f0710b46ac165a4bb75e7df891b0bc164e2f63f3c7..e6ee0b862b969f746125771cff94ebdba24a11d5fe37572074120a54844f4535 100644 --- a/src/cypherpunks.ru/nncp/node.go +++ b/src/cypherpunks.ru/nncp/node.go @@ -70,7 +70,7 @@ type Call struct { Cron *cronexpr.Expression Nice uint8 - Xx *TRxTx + Xx TRxTx Addr *string OnlineDeadline uint MaxOnlineTime uint diff --git a/src/cypherpunks.ru/nncp/sp.go b/src/cypherpunks.ru/nncp/sp.go index 6fc777884dc41a3f4474fc5c574e7b274ec04073e451b8d7c436fc56be5c9161..cfc5007bae0177257835bdf8011539b507506efdd0121a02e91d18a5d102b8a3 100644 --- a/src/cypherpunks.ru/nncp/sp.go +++ b/src/cypherpunks.ru/nncp/sp.go @@ -180,7 +180,7 @@ RxSpeed int64 TxSpeed int64 rxLock *os.File txLock *os.File - xxOnly *TRxTx + xxOnly TRxTx isDead bool sync.RWMutex } @@ -264,20 +264,20 @@ } return payloadsSplit(payloads) } -func (ctx *Ctx) StartI(conn net.Conn, nodeId *NodeId, nice uint8, xxOnly *TRxTx, onlineDeadline, maxOnlineTime uint) (*SPState, error) { +func (ctx *Ctx) StartI(conn net.Conn, nodeId *NodeId, nice uint8, xxOnly TRxTx, onlineDeadline, maxOnlineTime uint) (*SPState, error) { err := ctx.ensureRxDir(nodeId) if err != nil { return nil, err } var rxLock *os.File - if xxOnly != nil && *xxOnly == TRx { + if xxOnly == "" || xxOnly == TRx { rxLock, err = ctx.LockDir(nodeId, TRx) if err != nil { return nil, err } } var txLock *os.File - if xxOnly != nil && *xxOnly == TTx { + if xxOnly == "" || xxOnly == TTx { txLock, err = ctx.LockDir(nodeId, TTx) if err != nil { return nil, err @@ -312,7 +312,7 @@ xxOnly: xxOnly, } var infosPayloads [][]byte - if xxOnly == nil || *xxOnly != TTx { + if xxOnly == "" || xxOnly == TTx { infosPayloads = ctx.infosOur(nodeId, nice, &state.infosOurSeen) } var firstPayload []byte @@ -358,7 +358,7 @@ } return &state, err } -func (ctx *Ctx) StartR(conn net.Conn, nice uint8, xxOnly *TRxTx) (*SPState, error) { +func (ctx *Ctx) StartR(conn net.Conn, nice uint8, xxOnly TRxTx) (*SPState, error) { started := time.Now() conf := noise.Config{ CipherSuite: NoiseCipherSuite, @@ -417,7 +417,7 @@ if ctx.ensureRxDir(node.Id); err != nil { return nil, err } var rxLock *os.File - if xxOnly != nil && *xxOnly == TRx { + if xxOnly == "" || xxOnly == TRx { rxLock, err = ctx.LockDir(node.Id, TRx) if err != nil { return nil, err @@ -425,7 +425,7 @@ } } state.rxLock = rxLock var txLock *os.File - if xxOnly != nil && *xxOnly == TTx { + if xxOnly == "" || xxOnly == TTx { txLock, err = ctx.LockDir(node.Id, TTx) if err != nil { return nil, err @@ -434,7 +434,7 @@ } state.txLock = txLock var infosPayloads [][]byte - if xxOnly == nil || *xxOnly != TTx { + if xxOnly == "" || xxOnly == TTx { infosPayloads = ctx.infosOur(node.Id, nice, &state.infosOurSeen) } var firstPayload []byte @@ -499,22 +499,24 @@ state.payloads <- reply } }() - go func() { - for range time.Tick(time.Second) { - for _, payload := range state.ctx.infosOur( - state.Node.Id, - state.nice, - &state.infosOurSeen, - ) { - state.ctx.LogD( - "sp-work", - SdsAdd(sds, SDS{"size": strconv.Itoa(len(payload))}), - "queuing new info", - ) - state.payloads <- payload + if state.xxOnly == "" || state.xxOnly == TTx { + go func() { + for range time.Tick(time.Second) { + for _, payload := range state.ctx.infosOur( + state.Node.Id, + state.nice, + &state.infosOurSeen, + ) { + state.ctx.LogD( + "sp-work", + SdsAdd(sds, SDS{"size": strconv.Itoa(len(payload))}), + "queuing new info", + ) + state.payloads <- payload + } } - } - }() + }() + } state.wg.Add(1) go func() { @@ -737,7 +739,7 @@ state.ctx.LogD("sp-process", sdsp, "too nice") continue } state.ctx.LogD("sp-process", sdsp, "received") - if state.xxOnly != nil && *state.xxOnly == TTx { + if state.xxOnly == TTx { continue } state.Lock() diff --git a/src/cypherpunks.ru/nncp/toss.go b/src/cypherpunks.ru/nncp/toss.go index 06953eb0f8a2efbdf42425700fe4b063da58412af4c9751d3361bd6d31a540d5..adb2139accb679fef5832b9790726f0343b22ddef4445a176fc4c9b685d316ad 100644 --- a/src/cypherpunks.ru/nncp/toss.go +++ b/src/cypherpunks.ru/nncp/toss.go @@ -36,7 +36,6 @@ "github.com/davecgh/go-xdr/xdr2" "github.com/dustin/go-humanize" "golang.org/x/crypto/blake2b" - "golang.org/x/sys/unix" ) func newNotification(fromTo *FromToYAML, subject string) io.Reader { @@ -48,40 +47,7 @@ mime.BEncoding.Encode("UTF-8", subject), )) } -func (ctx *Ctx) LockDir(nodeId *NodeId, xx TRxTx) (*os.File, error) { - ctx.ensureRxDir(nodeId) - lockPath := filepath.Join(ctx.Spool, nodeId.String(), string(xx)) + ".lock" - dirLock, err := os.OpenFile( - lockPath, - os.O_CREATE|os.O_WRONLY, - os.FileMode(0600), - ) - if err != nil { - ctx.LogE("lockdir", SDS{"path": lockPath, "err": err}, "") - return nil, err - } - err = unix.Flock(int(dirLock.Fd()), unix.LOCK_EX|unix.LOCK_NB) - if err != nil { - ctx.LogE("lockdir", SDS{"path": lockPath, "err": err}, "") - dirLock.Close() - return nil, err - } - return dirLock, nil -} - -func (ctx *Ctx) UnlockDir(fd *os.File) { - if fd != nil { - unix.Flock(int(fd.Fd()), unix.LOCK_UN) - fd.Close() - } -} - func (ctx *Ctx) Toss(nodeId *NodeId, nice uint8, dryRun bool) bool { - dirLock, err := ctx.LockDir(nodeId, TRx) - if err != nil { - return false - } - defer ctx.UnlockDir(dirLock) isBad := false for job := range ctx.Jobs(nodeId, TRx) { pktName := filepath.Base(job.Fd.Name())