2018-09-17 14:18:49 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
2018-09-21 17:52:45 +00:00
|
|
|
"crypto/tls"
|
|
|
|
"net"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
2018-09-17 14:18:49 +00:00
|
|
|
omd "git.loafle.net/overflow/model/discovery"
|
2018-09-17 16:25:56 +00:00
|
|
|
omm "git.loafle.net/overflow/model/meta"
|
|
|
|
ounp "git.loafle.net/overflow/util-go/net/ping"
|
2018-09-17 14:18:49 +00:00
|
|
|
)
|
|
|
|
|
2018-09-17 16:25:56 +00:00
|
|
|
func Ping(service *omd.Service, pingOption ounp.Option) (ounp.Result, error) {
|
|
|
|
if isDiscoveredByMatcher(service) {
|
2018-09-21 17:52:45 +00:00
|
|
|
return processPing(service, pingOption, matcherPingFunc)
|
2018-09-17 16:25:56 +00:00
|
|
|
}
|
2018-09-17 14:18:49 +00:00
|
|
|
|
2018-09-21 17:52:45 +00:00
|
|
|
return processPing(service, pingOption, connectionPingFunc)
|
2018-09-17 16:25:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func isDiscoveredByMatcher(service *omd.Service) bool {
|
|
|
|
for _, discoveredBy := range service.DiscoveredBy {
|
|
|
|
switch omm.ToMetaDiscovererTypeEnum(discoveredBy) {
|
|
|
|
case omm.MetaDiscovererTypeEnumUDPMatcher, omm.MetaDiscovererTypeEnumTCPMatcher:
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
2018-09-17 14:18:49 +00:00
|
|
|
}
|
2018-09-21 17:52:45 +00:00
|
|
|
|
|
|
|
type pingFunc func(service *omd.Service, pingOption ounp.Option) (ttl int, err error)
|
|
|
|
|
|
|
|
func processPing(service *omd.Service, pingOption ounp.Option, _pingFunc pingFunc) (ounp.Result, error) {
|
|
|
|
responses := make(map[int]ounp.Response, 0)
|
|
|
|
summary := &ounp.PingSummary{}
|
|
|
|
|
|
|
|
pingResult := &ounp.PingResult{
|
|
|
|
Responses: responses,
|
|
|
|
Summary: summary,
|
|
|
|
}
|
|
|
|
|
|
|
|
var _sum float64
|
|
|
|
var _res *ounp.PingResponse
|
|
|
|
|
|
|
|
for indexR := 0; indexR < pingOption.GetCount(); indexR++ {
|
|
|
|
summary.SendCount = summary.SendCount + 1
|
|
|
|
startTime := time.Now()
|
|
|
|
_res = &ounp.PingResponse{}
|
|
|
|
if 0 < indexR {
|
|
|
|
select {
|
|
|
|
case <-time.After(time.Duration(pingOption.GetDeadline()) * time.Second):
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ttl, err := _pingFunc(service, pingOption)
|
|
|
|
elapsedTime := time.Since(startTime).Seconds() * 1E3
|
|
|
|
|
|
|
|
if 0 == indexR {
|
|
|
|
summary.MinTime = elapsedTime
|
|
|
|
summary.MaxTime = elapsedTime
|
|
|
|
}
|
|
|
|
if nil == err {
|
|
|
|
|
|
|
|
_sum = _sum + elapsedTime
|
|
|
|
summary.ReceiveCount = summary.ReceiveCount + 1
|
|
|
|
if summary.MinTime > elapsedTime {
|
|
|
|
summary.MinTime = elapsedTime
|
|
|
|
}
|
|
|
|
|
|
|
|
if summary.MaxTime < elapsedTime {
|
|
|
|
summary.MaxTime = elapsedTime
|
|
|
|
}
|
|
|
|
_res.Time = elapsedTime
|
|
|
|
_res.TTL = ttl
|
|
|
|
} else {
|
|
|
|
_res.Error = err.Error()
|
|
|
|
}
|
|
|
|
pingResult.Responses[indexR] = _res
|
|
|
|
}
|
|
|
|
|
|
|
|
if 0 == summary.ReceiveCount {
|
|
|
|
summary.AvgTime = 0
|
|
|
|
summary.LossPercent = 100
|
|
|
|
} else {
|
|
|
|
summary.AvgTime = _sum / float64(summary.ReceiveCount)
|
|
|
|
summary.LossPercent = (float32(summary.SendCount) - float32(summary.ReceiveCount)) / float32(summary.SendCount) * float32(100)
|
|
|
|
}
|
|
|
|
|
|
|
|
return pingResult, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getConnection(service *omd.Service, pingOption ounp.Option) (net.Conn, error) {
|
|
|
|
addr := net.JoinHostPort(service.Port.Host.Address, service.Port.PortNumber.String())
|
|
|
|
portType := strings.ToLower(service.Port.MetaPortType.Key)
|
|
|
|
|
|
|
|
switch omm.ToMetaCryptoTypeEnum(service.MetaCryptoType) {
|
|
|
|
case omm.MetaCryptoTypeEnumTLS:
|
|
|
|
dialer := &net.Dialer{
|
|
|
|
Timeout: time.Duration(pingOption.GetDeadline()) * time.Second,
|
|
|
|
}
|
|
|
|
|
|
|
|
return tls.DialWithDialer(
|
|
|
|
dialer,
|
|
|
|
portType,
|
|
|
|
addr,
|
|
|
|
&tls.Config{
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
ServerName: service.Port.Host.Address,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
default:
|
|
|
|
|
|
|
|
return net.DialTimeout(portType, addr, time.Duration(pingOption.GetDeadline())*time.Second)
|
|
|
|
}
|
|
|
|
}
|