onlinedeadline: 1800
maxonlinetime: 1750
nice: 64
+ rxrate: 10
+ txrate: 20
-
cron: "0 * * * SAT,SUN"
xx: rx
@ref{CfgAddrs, @emph{addrs}} configuration option. It can be either key
from @emph{addrs} dictionary, or an ordinary @option{addr:port}.
+@item rxrate/txrate
+Optional. Override @ref{CfgXxRate, @emph{rxrate/txrate}} configuration
+option when calling.
+
@item onlinedeadline
Optional. Override @ref{CfgOnlineDeadline, @emph{onlinedeadline}}
configuration option when calling.
freqchunked: 1024
freqminsize: 2048
via: [alice]
+ rxrate: 10
+ txrate: 20
@end verbatim
@strong{spool} field contains an absolute path to @ref{Spool, spool}
if either no direct connection exists, or @ref{nncp-call} is used with
forced address specifying.
+@anchor{CfgXxRate}
+@item rxrate/txrate
+If greater than zero, then at most *rate packets per second will be
+sent/received after the handshake. It could be used as crude bandwidth
+traffic shaper: each packet has at most 64 KiB payload size. Could be
+omitted at all -- no rate limits.
+
@anchor{CfgOnlineDeadline}
@item onlinedeadline
Online connection deadline of node inactivity in seconds. It is the time
@section nncp-call
@verbatim
-% nncp-call [options] [-onlinedeadline INT] [-maxonlinetime INT] [-rx|-tx]
- NODE[:ADDR] [FORCEADDR]
+% nncp-call [options]
+ [-onlinedeadline INT]
+ [-maxonlinetime INT]
+ [-rx|-tx]
+ [-rxrate INT]
+ [-txrate INT]
+ NODE[:ADDR] [FORCEADDR]
@end verbatim
Call (connect to) specified @option{NODE} and run @ref{Sync,
only outbound transmission is performed. @option{-onlinedeadline}
overrides @ref{CfgOnlineDeadline, @emph{onlinedeadline}}.
@option{-maxonlinetime} overrides @ref{CfgMaxOnlineTime,
-@emph{maxonlinetime}}.
+@emph{maxonlinetime}}. @option{-rxrate}/@option{-txrate} override
+@ref{CfgXxRate, rxrate/txrate}.
@node nncp-caller
@section nncp-caller
Если более высокоприоритетный пакет попадает в спул, то
@command{nncp-daemon} добавит его в очередь отправки первым, прерывая
низкоприоритетные передачи.
+@item
+К средствам связанным с online-соединениями (@command{nncp-daemon},
+@command{nncp-call}, @command{nncp-caller}) добавлен простой
+ограничитель скорости.
@end itemize
@node Релиз 3.2
@item
If higher priority packet is spooled, then @command{nncp-daemon} will
queue its sending first, interrupting lower priority transmissions.
+@item
+Simple packet rate limiter added to online-related tools
+(@command{nncp-daemon}, @command{nncp-call}, @command{nncp-caller}).
@end itemize
@node Release 3.2
import (
"net"
"strconv"
+
+ "github.com/gorhill/cronexpr"
)
-func (ctx *Ctx) CallNode(node *Node, addrs []string, nice uint8, xxOnly TRxTx, onlineDeadline, maxOnlineTime uint) (isGood bool) {
+type Call struct {
+ Cron *cronexpr.Expression
+ Nice uint8
+ Xx TRxTx
+ RxRate int
+ TxRate int
+ Addr *string
+ OnlineDeadline uint
+ MaxOnlineTime uint
+}
+
+func (ctx *Ctx) CallNode(node *Node, addrs []string, nice uint8, xxOnly TRxTx, rxRate, txRate int, onlineDeadline, maxOnlineTime uint) (isGood bool) {
for _, addr := range addrs {
sds := SDS{"node": node.Id, "addr": addr}
ctx.LogD("call", sds, "dialing")
node.Id,
nice,
xxOnly,
+ rxRate,
+ txRate,
onlineDeadline,
maxOnlineTime,
)
Addrs map[string]string `yaml:"addrs,omitempty"`
+ RxRate *int `yaml:"rxrate,omitempty"`
+ TxRate *int `yaml:"txrate,omitempty"`
OnlineDeadline *uint `yaml:"onlinedeadline,omitempty"`
MaxOnlineTime *uint `yaml:"maxonlinetime,omitempty"`
}
Cron string
Nice *int `yaml:"nice,omitempty"`
Xx string `yaml:"xx,omitempty"`
+ RxRate *int `yaml:"rxrate,omitempty"`
+ TxRate *int `yaml:"txrate,omitempty"`
Addr *string `yaml:"addr,omitempty"`
OnlineDeadline *uint `yaml:"onlinedeadline,omitempty"`
MaxOnlineTime *uint `yaml:"maxonlinetime,omitempty"`
freqMinSize = int64(*yml.FreqMinSize) * 1024
}
+ defRxRate := 0
+ if yml.RxRate != nil && *yml.RxRate > 0 {
+ defRxRate = *yml.RxRate
+ }
+ defTxRate := 0
+ if yml.TxRate != nil && *yml.TxRate > 0 {
+ defTxRate = *yml.TxRate
+ }
+
defOnlineDeadline := uint(DefaultDeadline)
if yml.OnlineDeadline != nil {
if *yml.OnlineDeadline <= 0 {
if err != nil {
return nil, err
}
+
nice := uint8(255)
if callYml.Nice != nil {
if *callYml.Nice < 1 || *callYml.Nice > 255 {
}
nice = uint8(*callYml.Nice)
}
+
var xx TRxTx
switch callYml.Xx {
case "rx":
default:
return nil, errors.New("xx field must be either \"rx\" or \"tx\"")
}
+
+ rxRate := 0
+ if callYml.RxRate != nil && *callYml.RxRate > 0 {
+ rxRate = *callYml.RxRate
+ }
+ txRate := 0
+ if callYml.TxRate != nil && *callYml.TxRate > 0 {
+ txRate = *callYml.TxRate
+ }
+
var addr *string
if callYml.Addr != nil {
if a, exists := yml.Addrs[*callYml.Addr]; exists {
addr = callYml.Addr
}
}
+
onlineDeadline := defOnlineDeadline
if callYml.OnlineDeadline != nil {
if *callYml.OnlineDeadline == 0 {
}
onlineDeadline = *callYml.OnlineDeadline
}
+
var maxOnlineTime uint
if callYml.MaxOnlineTime != nil {
maxOnlineTime = *callYml.MaxOnlineTime
}
+
calls = append(calls, &Call{
Cron: expr,
Nice: nice,
Xx: xx,
+ RxRate: rxRate,
+ TxRate: txRate,
Addr: addr,
OnlineDeadline: onlineDeadline,
MaxOnlineTime: maxOnlineTime,
FreqMinSize: freqMinSize,
Calls: calls,
Addrs: yml.Addrs,
+ RxRate: defRxRate,
+ TxRate: defTxRate,
OnlineDeadline: defOnlineDeadline,
MaxOnlineTime: defMaxOnlineTime,
}
cfgPath = flag.String("cfg", nncp.DefaultCfgPath, "Path to configuration file")
niceRaw = flag.Int("nice", 255, "Minimal required niceness")
rxOnly = flag.Bool("rx", false, "Only receive packets")
- txOnly = flag.Bool("tx", false, "Only transfer packets")
+ txOnly = flag.Bool("tx", false, "Only transmit packets")
+ 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")
logPath = flag.String("log", "", "Override path to logfile")
quiet = flag.Bool("quiet", false, "Print only errors")
}
}
- if !ctx.CallNode(node, addrs, nice, xxOnly, *onlineDeadline, *maxOnlineTime) {
+ if !ctx.CallNode(
+ node,
+ addrs,
+ nice,
+ xxOnly,
+ *rxRate,
+ *txRate,
+ *onlineDeadline,
+ *maxOnlineTime,
+ ) {
os.Exit(1)
}
}
addrs,
call.Nice,
call.Xx,
+ call.RxRate,
+ call.TxRate,
call.OnlineDeadline,
call.MaxOnlineTime,
)
"sync"
"github.com/flynn/noise"
- "github.com/gorhill/cronexpr"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/nacl/box"
FreqMinSize int64
Via []*NodeId
Addrs map[string]string
+ RxRate int
+ TxRate int
OnlineDeadline uint
MaxOnlineTime uint
Calls []*Call
NoisePrv *[32]byte
}
-type Call struct {
- Cron *cronexpr.Expression
- Nice uint8
- Xx TRxTx
- Addr *string
- OnlineDeadline uint
- MaxOnlineTime uint
-}
-
func NewNodeGenerate() (*NodeOur, error) {
exchPub, exchPrv, err := box.GenerateKey(rand.Reader)
if err != nil {
rxLock *os.File
txLock *os.File
xxOnly TRxTx
+ rxRate int
+ txRate int
isDead bool
sync.RWMutex
}
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, rxRate, txRate int, onlineDeadline, maxOnlineTime uint) (*SPState, error) {
err := ctx.ensureRxDir(nodeId)
if err != nil {
return nil, err
rxLock: rxLock,
txLock: txLock,
xxOnly: xxOnly,
+ rxRate: rxRate,
+ txRate: txRate,
}
var infosPayloads [][]byte
return nil, errors.New("Unknown peer: " + peerId)
}
state.Node = node
+ state.rxRate = node.RxRate
+ state.txRate = node.TxRate
state.onlineDeadline = node.OnlineDeadline
state.maxOnlineTime = node.MaxOnlineTime
sds := SDS{"node": node.Id, "nice": strconv.Itoa(int(nice))}
}
freq := state.queueTheir[0].freq
state.RUnlock()
+
+ if state.txRate > 0 {
+ time.Sleep(time.Second / time.Duration(state.txRate))
+ }
+
sdsp := SdsAdd(sds, SDS{
"xx": string(TTx),
"hash": ToBase32(freq.Hash[:]),
state.payloads <- reply
}
}()
+ if state.rxRate > 0 {
+ time.Sleep(time.Second / time.Duration(state.rxRate))
+ }
}
}()