package service import ( "fmt" "net" "time" omd "git.loafle.net/overflow/model/discovery" osm "git.loafle.net/overflow/service_matcher-go" ouej "git.loafle.net/overflow/util-go/encoding/json" ounp "git.loafle.net/overflow/util-go/net/ping" "git.loafle.net/overflow_scanner/probe/internal/matcher" ) func matcherPingFunc(service *omd.Service, pingOption ounp.Option) (ttl int, err error) { var portNumber int portNumber, err = ouej.NumberToInt(service.Port.PortNumber) if nil != err { return } matchCtx := osm.NewMatchCtx(service.Port.Host.Address, portNumber) _matcher := matcher.GetMatcherByKey(service.Key) if _matcher.IsPrePacket() { return processPrepacket(service, pingOption, matchCtx, _matcher) } return processPostpacket(service, pingOption, matchCtx, _matcher) } func processPrepacket(service *omd.Service, pingOption ounp.Option, matchCtx *osm.MatchCtx, _matcher osm.Matcher) (ttl int, err error) { var conn net.Conn var bufLen int buf := make([]byte, 1024) conn, err = getConnection(service, pingOption) if nil != err { return } defer conn.Close() err = conn.SetReadDeadline(time.Now().Add(time.Duration(pingOption.GetDeadline()) * time.Second)) if nil != err { return } bufLen, err = conn.Read(buf) if nil != err { return } err = _matcher.Match(matchCtx, 0, osm.NewPacket(buf, bufLen)) if nil != err { return } packetCount := _matcher.PacketCount(matchCtx) if 0 == packetCount { return } for indexM := 0; indexM < packetCount; indexM++ { _packet := _matcher.Packet(matchCtx, indexM) err = conn.SetWriteDeadline(time.Now().Add(time.Duration(pingOption.GetDeadline()) * time.Second)) if nil != err { return } _, err = conn.Write(_packet.Buffer) if nil != err { return } err = conn.SetReadDeadline(time.Now().Add(time.Duration(pingOption.GetDeadline()) * time.Second)) if nil != err { return } bufLen, err = conn.Read(buf) if nil != err { return } err = _matcher.Match(matchCtx, indexM+1, osm.NewPacket(buf, bufLen)) if nil != err { err = fmt.Errorf("Protocol not match") return } } return } func processPostpacket(service *omd.Service, pingOption ounp.Option, matchCtx *osm.MatchCtx, _matcher osm.Matcher) (ttl int, err error) { var conn net.Conn var bufLen int buf := make([]byte, 1024) packetCount := _matcher.PacketCount(matchCtx) if 0 == packetCount { err = fmt.Errorf("Protocol not match") return } conn, err = getConnection(service, pingOption) if nil != err { return } defer conn.Close() for indexM := 0; indexM < packetCount; indexM++ { _packet := _matcher.Packet(matchCtx, indexM) err = conn.SetWriteDeadline(time.Now().Add(time.Duration(pingOption.GetDeadline()) * time.Second)) if nil != err { return } _, err = conn.Write(_packet.Buffer) if nil != err { return } err = conn.SetReadDeadline(time.Now().Add(time.Duration(pingOption.GetDeadline()) * time.Second)) if nil != err { return } bufLen, err = conn.Read(buf) if nil != err { return } err = _matcher.Match(matchCtx, indexM+1, osm.NewPacket(buf, bufLen)) if nil != err { return } if packetCount-1 == indexM { return } } return }