make pinger every,timeout and count configurable

This commit is contained in:
Martin/Geno 2019-06-05 12:00:11 +02:00 committed by genofire
parent aa2917b1a0
commit 4f346355d4
7 changed files with 163 additions and 142 deletions

View File

@ -49,3 +49,12 @@ ifname = "wlp4s0"
# Local UDP port where Yanic will listen for response packets. Default: a dynamically selected port # Local UDP port where Yanic will listen for response packets. Default: a dynamically selected port
# (note: request packets to nodes will always be sent to port 1001, regardless of this setting) # (note: request packets to nodes will always be sent to port 1001, regardless of this setting)
# port = 1001 # port = 1001
# nodes will pinged periodically
[pinger]
# if true, nodes will pinged periodically. default: false
enable = true
every = "1s"
timeout = "1s"
count = 1

View File

@ -1,6 +1,6 @@
package data package data
type PingResult struct { type PingResult struct {
True []string `json:"true"` True []string `json:"true"`
False []string `json:"false"` False []string `json:"false"`
} }

11
main.go
View File

@ -56,12 +56,13 @@ func main() {
ws := websocket.NewWebsocketServer(config.Secret, config.SSHIPAddressPrefix, db, config.BlacklistFor.Duration, nodesYanic) ws := websocket.NewWebsocketServer(config.Secret, config.SSHIPAddressPrefix, db, config.BlacklistFor.Duration, nodesYanic)
yanic := runtime.NewYanicDB(db, sshmanager, config.BlacklistFor.Duration, ws.SendNode, ws.SendStats, config.SSHIPAddressPrefix) yanic := runtime.NewYanicDB(db, sshmanager, config.BlacklistFor.Duration, ws.SendNode, ws.SendStats, config.SSHIPAddressPrefix)
if config.Pinger.Enable {
pinger, err := runtime.NewPinger(db, config.BlacklistFor.Duration, ws.SendPing) pinger, err := runtime.NewPinger(db, &config.Pinger, config.BlacklistFor.Duration, ws.SendPing)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
}
go pinger.Start()
} }
go pinger.Start()
if config.YanicEnable { if config.YanicEnable {
if duration := config.YanicSynchronize.Duration; duration > 0 { if duration := config.YanicSynchronize.Duration; duration > 0 {

View File

@ -16,71 +16,71 @@ var (
ChannelEU = true ChannelEU = true
ChannelList = map[uint32]*Channel{ ChannelList = map[uint32]*Channel{
1: &Channel{Frequency: 2412, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 1: {Frequency: 2412, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
2: &Channel{Frequency: 2417, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 2: {Frequency: 2417, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
3: &Channel{Frequency: 2422, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 3: {Frequency: 2422, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
4: &Channel{Frequency: 2427, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 4: {Frequency: 2427, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
5: &Channel{Frequency: 2432, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 5: {Frequency: 2432, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
6: &Channel{Frequency: 2437, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 6: {Frequency: 2437, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
7: &Channel{Frequency: 2442, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 7: {Frequency: 2442, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
8: &Channel{Frequency: 2447, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 8: {Frequency: 2447, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
9: &Channel{Frequency: 2452, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 9: {Frequency: 2452, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
10: &Channel{Frequency: 2457, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 10: {Frequency: 2457, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
11: &Channel{Frequency: 2462, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 11: {Frequency: 2462, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
12: &Channel{Frequency: 2467, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 12: {Frequency: 2467, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
13: &Channel{Frequency: 2472, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 13: {Frequency: 2472, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
14: &Channel{Frequency: 2484, AllowedInEU: false, DFS: false, Indoor: false, SDR: false}, 14: {Frequency: 2484, AllowedInEU: false, DFS: false, Indoor: false, SDR: false},
32: &Channel{Frequency: 5160, AllowedInEU: true, DFS: false, Indoor: false, SDR: false}, 32: {Frequency: 5160, AllowedInEU: true, DFS: false, Indoor: false, SDR: false},
34: &Channel{Frequency: 5170, AllowedInEU: false, DFS: false, Indoor: true, SDR: false}, 34: {Frequency: 5170, AllowedInEU: false, DFS: false, Indoor: true, SDR: false},
36: &Channel{Frequency: 5180, AllowedInEU: true, DFS: false, Indoor: true, SDR: false}, 36: {Frequency: 5180, AllowedInEU: true, DFS: false, Indoor: true, SDR: false},
38: &Channel{Frequency: 5190, AllowedInEU: false, DFS: false, Indoor: true, SDR: false}, 38: {Frequency: 5190, AllowedInEU: false, DFS: false, Indoor: true, SDR: false},
40: &Channel{Frequency: 5200, AllowedInEU: true, DFS: false, Indoor: true, SDR: false}, 40: {Frequency: 5200, AllowedInEU: true, DFS: false, Indoor: true, SDR: false},
42: &Channel{Frequency: 5210, AllowedInEU: false, DFS: false, Indoor: true, SDR: false}, 42: {Frequency: 5210, AllowedInEU: false, DFS: false, Indoor: true, SDR: false},
44: &Channel{Frequency: 5220, AllowedInEU: true, DFS: false, Indoor: true, SDR: false}, 44: {Frequency: 5220, AllowedInEU: true, DFS: false, Indoor: true, SDR: false},
46: &Channel{Frequency: 5230, AllowedInEU: false, DFS: false, Indoor: true, SDR: false}, 46: {Frequency: 5230, AllowedInEU: false, DFS: false, Indoor: true, SDR: false},
48: &Channel{Frequency: 5240, AllowedInEU: true, DFS: false, Indoor: true, SDR: false}, 48: {Frequency: 5240, AllowedInEU: true, DFS: false, Indoor: true, SDR: false},
50: &Channel{Frequency: 5250, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 50: {Frequency: 5250, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
52: &Channel{Frequency: 5260, AllowedInEU: true, DFS: true, Indoor: true, SDR: false}, 52: {Frequency: 5260, AllowedInEU: true, DFS: true, Indoor: true, SDR: false},
54: &Channel{Frequency: 5270, AllowedInEU: false, DFS: true, Indoor: true, SDR: false}, 54: {Frequency: 5270, AllowedInEU: false, DFS: true, Indoor: true, SDR: false},
56: &Channel{Frequency: 5280, AllowedInEU: true, DFS: true, Indoor: true, SDR: false}, 56: {Frequency: 5280, AllowedInEU: true, DFS: true, Indoor: true, SDR: false},
58: &Channel{Frequency: 5290, AllowedInEU: false, DFS: true, Indoor: true, SDR: false}, 58: {Frequency: 5290, AllowedInEU: false, DFS: true, Indoor: true, SDR: false},
60: &Channel{Frequency: 5300, AllowedInEU: true, DFS: true, Indoor: true, SDR: false}, 60: {Frequency: 5300, AllowedInEU: true, DFS: true, Indoor: true, SDR: false},
62: &Channel{Frequency: 5310, AllowedInEU: false, DFS: true, Indoor: true, SDR: false}, 62: {Frequency: 5310, AllowedInEU: false, DFS: true, Indoor: true, SDR: false},
64: &Channel{Frequency: 5320, AllowedInEU: true, DFS: true, Indoor: true, SDR: false}, 64: {Frequency: 5320, AllowedInEU: true, DFS: true, Indoor: true, SDR: false},
68: &Channel{Frequency: 5340, AllowedInEU: true, DFS: true, Indoor: true, SDR: false}, 68: {Frequency: 5340, AllowedInEU: true, DFS: true, Indoor: true, SDR: false},
96: &Channel{Frequency: 5480, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 96: {Frequency: 5480, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
100: &Channel{Frequency: 5500, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 100: {Frequency: 5500, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
102: &Channel{Frequency: 5510, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 102: {Frequency: 5510, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
104: &Channel{Frequency: 5520, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 104: {Frequency: 5520, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
106: &Channel{Frequency: 5530, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 106: {Frequency: 5530, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
108: &Channel{Frequency: 5540, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 108: {Frequency: 5540, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
110: &Channel{Frequency: 5550, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 110: {Frequency: 5550, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
112: &Channel{Frequency: 5560, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 112: {Frequency: 5560, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
114: &Channel{Frequency: 5570, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 114: {Frequency: 5570, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
116: &Channel{Frequency: 5580, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 116: {Frequency: 5580, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
118: &Channel{Frequency: 5590, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 118: {Frequency: 5590, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
120: &Channel{Frequency: 5600, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 120: {Frequency: 5600, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
122: &Channel{Frequency: 5610, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 122: {Frequency: 5610, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
124: &Channel{Frequency: 5620, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 124: {Frequency: 5620, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
126: &Channel{Frequency: 5630, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 126: {Frequency: 5630, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
128: &Channel{Frequency: 5640, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 128: {Frequency: 5640, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
132: &Channel{Frequency: 5660, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 132: {Frequency: 5660, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
134: &Channel{Frequency: 5670, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 134: {Frequency: 5670, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
136: &Channel{Frequency: 5680, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 136: {Frequency: 5680, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
138: &Channel{Frequency: 5690, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 138: {Frequency: 5690, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
140: &Channel{Frequency: 5700, AllowedInEU: true, DFS: true, Indoor: false, SDR: false}, 140: {Frequency: 5700, AllowedInEU: true, DFS: true, Indoor: false, SDR: false},
142: &Channel{Frequency: 5710, AllowedInEU: false, DFS: true, Indoor: false, SDR: false}, 142: {Frequency: 5710, AllowedInEU: false, DFS: true, Indoor: false, SDR: false},
144: &Channel{Frequency: 5720, AllowedInEU: true, DFS: true, Indoor: false, SDR: true}, 144: {Frequency: 5720, AllowedInEU: true, DFS: true, Indoor: false, SDR: true},
149: &Channel{Frequency: 5745, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 149: {Frequency: 5745, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
151: &Channel{Frequency: 5755, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 151: {Frequency: 5755, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
153: &Channel{Frequency: 5765, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 153: {Frequency: 5765, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
155: &Channel{Frequency: 5775, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 155: {Frequency: 5775, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
157: &Channel{Frequency: 5785, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 157: {Frequency: 5785, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
159: &Channel{Frequency: 5795, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 159: {Frequency: 5795, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
161: &Channel{Frequency: 5805, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 161: {Frequency: 5805, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
165: &Channel{Frequency: 5825, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 165: {Frequency: 5825, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
169: &Channel{Frequency: 5845, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 169: {Frequency: 5845, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
173: &Channel{Frequency: 5865, AllowedInEU: true, DFS: false, Indoor: false, SDR: true}, 173: {Frequency: 5865, AllowedInEU: true, DFS: false, Indoor: false, SDR: true},
} }
) )

View File

@ -27,6 +27,9 @@ type Config struct {
SSHIPAddressPrefix string `toml:"ssh_ipaddress_prefix"` SSHIPAddressPrefix string `toml:"ssh_ipaddress_prefix"`
SSHTimeout duration.Duration `toml:"ssh_timeout"` SSHTimeout duration.Duration `toml:"ssh_timeout"`
// Pinger
Pinger PingerConfig `toml:"pinger"`
// yanic socket // yanic socket
YanicEnable bool `toml:"yanic_enable"` YanicEnable bool `toml:"yanic_enable"`
YanicSynchronize duration.Duration `toml:"yanic_synchronize"` YanicSynchronize duration.Duration `toml:"yanic_synchronize"`

View File

@ -1,104 +1,112 @@
package runtime package runtime
import ( import (
"net" "net"
"time" "sync"
"sync" "time"
log "github.com/sirupsen/logrus" "github.com/FreifunkBremen/yanic/lib/duration"
"github.com/digineo/go-ping" "github.com/digineo/go-ping"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
log "github.com/sirupsen/logrus"
"github.com/FreifunkBremen/freifunkmanager/data" "github.com/FreifunkBremen/freifunkmanager/data"
) )
type PingerConfig struct {
Enable bool `toml:"enable"`
Every duration.Duration `toml:"every"`
Timeout duration.Duration `toml:"timeout"`
Count int `toml:"count"`
}
type Pinger struct { type Pinger struct {
db *gorm.DB db *gorm.DB
blacklistFor time.Duration config *PingerConfig
blacklistFor time.Duration
sendResult func(*data.PingResult) sendResult func(*data.PingResult)
stop bool
stop bool wg sync.WaitGroup
wg sync.WaitGroup p *ping.Pinger
p *ping.Pinger
pingTimeout time.Duration
pingCount int
} }
func NewPinger(db *gorm.DB, blacklistFor time.Duration, sendResult func(*data.PingResult)) (*Pinger, error) { func NewPinger(db *gorm.DB, config *PingerConfig, blacklistFor time.Duration, sendResult func(*data.PingResult)) (*Pinger, error) {
ping, err := ping.New("", "::") ping, err := ping.New("", "::")
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Pinger{ return &Pinger{
db: db, db: db,
blacklistFor: blacklistFor, config: config,
blacklistFor: blacklistFor,
sendResult: sendResult, sendResult: sendResult,
stop: false,
stop: false, p: ping,
p: ping,
pingTimeout: time.Duration(time.Second),
pingCount: 2,
}, nil }, nil
} }
func (pinger *Pinger) Start() { func (pinger *Pinger) Start() {
pinger.wg.Add(1) pinger.wg.Add(1)
for !pinger.stop { timer := time.NewTimer(pinger.config.Every.Duration)
pinger.run() for !pinger.stop {
} select {
pinger.wg.Done() case <-timer.C:
pinger.run()
timer.Reset(pinger.config.Every.Duration)
}
}
timer.Stop()
pinger.wg.Done()
} }
func (pinger *Pinger) Stop() { func (pinger *Pinger) Stop() {
pinger.stop = true pinger.stop = true
pinger.wg.Wait() pinger.wg.Wait()
} }
func (pinger *Pinger) run() { func (pinger *Pinger) run() {
result := &data.PingResult{} result := &data.PingResult{}
now := time.Now() now := time.Now()
count := 0 count := 0
var nodes []*Node var nodes []*Node
pinger.db.Find(&nodes).Count(&count) pinger.db.Find(&nodes).Count(&count)
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
wg.Add(count) wg.Add(count)
for _, node := range nodes { for _, node := range nodes {
go func(n *Node) { go func(n *Node) {
defer wg.Done() defer wg.Done()
if n.Blacklist.After(now.Add(-pinger.blacklistFor)) { if n.Blacklist.After(now.Add(-pinger.blacklistFor)) {
return return
} }
addr, err := net.ResolveIPAddr("ip6", n.Address) addr, err := net.ResolveIPAddr("ip6", n.Address)
if err != nil { if err != nil {
return return
} }
_, err = pinger.p.PingAttempts(addr, pinger.pingTimeout, pinger.pingCount) _, err = pinger.p.PingAttempts(addr, pinger.config.Timeout.Duration, pinger.config.Count)
if err == nil { if err == nil {
result.True = append(result.True, n.NodeID) result.True = append(result.True, n.NodeID)
} else { } else {
result.False = append(result.False, n.NodeID) result.False = append(result.False, n.NodeID)
} }
}(node) }(node)
} }
wg.Wait() wg.Wait()
log.WithFields(map[string]interface{}{ log.WithFields(map[string]interface{}{
"count": count, "count": count,
"count_skipped": count - (len(result.True) + len(result.False)), "count_skipped": count - (len(result.True) + len(result.False)),
"count_false": len(result.False), "count_false": len(result.False),
"count_true": len(result.True), "count_true": len(result.True),
}).Debug("pinger complete") }).Debug("pinger complete")
pinger.sendResult(result) pinger.sendResult(result)
} }

View File

@ -5,8 +5,8 @@ import (
yanicRuntime "github.com/FreifunkBremen/yanic/runtime" yanicRuntime "github.com/FreifunkBremen/yanic/runtime"
"github.com/FreifunkBremen/freifunkmanager/runtime"
"github.com/FreifunkBremen/freifunkmanager/data" "github.com/FreifunkBremen/freifunkmanager/data"
"github.com/FreifunkBremen/freifunkmanager/runtime"
) )
func (ws *WebsocketServer) SendNode(node *runtime.Node) { func (ws *WebsocketServer) SendNode(node *runtime.Node) {