This repository has been archived by the owner on Apr 3, 2022. It is now read-only.
/
ping.go
111 lines (95 loc) · 2.2 KB
/
ping.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package v2gen
import (
"fmt"
"iochen.com/v2gen/app/ping"
"iochen.com/v2gen/app/ping/icmpping"
"iochen.com/v2gen/app/ping/vmessping"
"iochen.com/v2gen/infra/mean"
"iochen.com/v2gen/infra/vmess"
"time"
)
type NodePingStatus struct {
Index int
PingStat *ping.Status
Result ping.Duration
Err error
}
type NodeStatusList []NodePingStatus
func (sList *NodeStatusList) Len() int {
return len(*sList)
}
func (sList *NodeStatusList) Less(i, j int) bool {
if (*sList)[i].PingStat.ErrCounter != (*sList)[j].PingStat.ErrCounter {
return (*sList)[i].PingStat.ErrCounter < (*sList)[j].PingStat.ErrCounter
}
return (*sList)[i].Result < (*sList)[j].Result
}
func (sList *NodeStatusList) Swap(i, j int) {
(*sList)[i], (*sList)[j] = (*sList)[j], (*sList)[i]
}
func PingNodes(lks *[]vmess.Link, print bool) *NodeStatusList {
var npList NodeStatusList
npCh := make(chan NodePingStatus)
max := *FlagThreads
go func() {
var doneCh = make(chan bool)
var waitList int
for k, v := range *lks {
for {
if waitList >= max {
<-doneCh
} else {
break
}
}
waitList++
go MakeNode(k, v, &waitList, npCh, doneCh)
}
}()
for i := 0; i < len(*lks); i++ {
select {
case np := <-npCh:
var result mean.Value
if *FlagMedian {
result = mean.Median(np.PingStat.Durations)
} else {
result = mean.ArithmeticMean(np.PingStat.Durations)
}
if result != nil {
np.Result = result.(ping.Duration)
}
npList = append(npList, np)
if print {
PrintNode(i, lks, &np)
} else {
fmt.Printf("\rPinging %d", i)
}
}
}
fmt.Print("\r")
return &npList
}
func MakeNode(k int, v vmess.Link, waitList *int, npCh chan NodePingStatus, doneCh chan bool) {
ps, err := Ping(&v)
np := NodePingStatus{
Index: k,
PingStat: ps,
Err: err,
}
npCh <- np
*waitList--
doneCh <- true
}
func Ping(lk *vmess.Link) (*ping.Status, error) {
ps := &ping.Status{
Durations: &ping.DurationList{},
}
var err error
if *FlagICMP {
ps, err = icmpping.Ping(lk, *FlagCount, time.Duration(*FlagTTO), time.Duration(*FlagETO))
} else {
ps, err = vmessping.VmessPing(lk, *FlagCount, *FlagDest,
time.Duration(*FlagTTO), time.Duration(*FlagETO), false)
}
return ps, err
}