-
Notifications
You must be signed in to change notification settings - Fork 0
/
go-ping.go
117 lines (107 loc) · 2.81 KB
/
go-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
112
113
114
115
116
117
package main
import (
"flag"
"fmt"
"math"
"net"
"sort"
"time"
"net/http"
"github.com/tatsushid/go-fastping"
"encoding/json"
)
type PingResult struct {
Loss *float64 `json:"loss"`
Min *float64 `json:"min"`
Max *float64 `json:"max"`
Avg *float64 `json:"avg"`
Mean *float64 `json:"mean"`
Mdev *float64 `json:"mdev"`
Error *string `json:"error"`
}
const count = 5
func main() {
http.HandleFunc("/", handler)
var port int
flag.IntVar(&port, "p", 8080, "tcp port to listen on")
flag.Parse()
fmt.Println("Go-Ping server starting up.")
http.ListenAndServe(fmt.Sprintf("127.0.0.1:%d", port), nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
ipaddr := r.URL.Path[1:]
result := pingHost(ipaddr)
json, err := json.Marshal(result)
if err != nil {
fmt.Println("failed to convert to json.")
fmt.Println(err)
w.WriteHeader(500)
w.Write([]byte("could not marshal payload to json"))
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
return
}
func pingHost(ipaddr string) *PingResult {
p := fastping.NewPinger()
results := make([]float64, count)
result := PingResult{}
if err := p.AddIP(ipaddr); err != nil {
msg := "invalid IP address"
result.Error = &msg
return &result
}
for i := 0; i < count; i++ {
p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
//fmt.Printf("IP Addr: %s receive, RTT: %v\n", addr.String(), rtt)
results[i] = rtt.Seconds()*1000
}
err := p.Run()
if err != nil {
fmt.Println(err)
}
}
failCount := 0.0
totalCount := len(results)
tsum := 0.0
tsum2 := 0.0
min := math.Inf(1)
max := 0.0
successfullResults := make([]float64, 0)
for _, r := range results {
if r == 0 {
failCount++
continue
}
if r > max {
max = r
}
if r < min {
min = r
}
tsum += r
tsum2 += (r * r)
successfullResults = append(successfullResults, r)
}
successCount := len(successfullResults)
if successCount > 0 {
avg := tsum/float64(successCount)
result.Avg = &avg
root := math.Sqrt((tsum2/float64(successCount)) - ((tsum/float64(successCount)) *(tsum/float64(successCount))))
result.Mdev = &root
sort.Float64s(successfullResults)
mean := successfullResults[successCount/2]
result.Mean = &mean
result.Min = &min
result.Max = &max
}
if failCount == 0 {
loss := 0.0
result.Loss = &loss
} else {
loss := 100.0 * (failCount/float64(totalCount))
result.Loss = &loss
}
return &result
}