package ping import ( "crypto/tls" "fmt" "net" "strings" "time" csm "git.loafle.net/commons/service_matcher-go" opm "git.loafle.net/overflow_scanner/probe/matcher" ) type Res struct { Matcher csm.Matcher Error error } func Ping(ch chan Res, ip string, port int, tls bool, portType, key string) { go func() { conn, err := getConnection(ip, port, portType, tls) if err != nil { ch <- Res{nil, err} close(ch) } defer conn.Close() m := opm.GetMatcherByKey(key) if m.IsPrePacket() { processPrepacket(ch, conn, m) } processPostpacket(ch, conn, m) }() } func processPrepacket(ch chan Res, conn net.Conn, m csm.Matcher) { for i := 0; i < m.PacketCount(); i++ { bytes := make([]byte, 1024) n, _ := conn.Read(bytes) p := csm.NewPacket(bytes, n) _, err := conn.Write(m.Packet(i).Buffer) if err != nil { ch <- Res{nil, err} close(ch) } if err := m.Match(nil, i, p); err != nil { ch <- Res{nil, err} close(ch) } } ch <- Res{m, nil} close(ch) } func processPostpacket(ch chan Res, conn net.Conn, m csm.Matcher) { for i := 0; i < m.PacketCount(); i++ { _, err := conn.Write(m.Packet(i).Buffer) if err != nil { ch <- Res{nil, err} close(ch) } bytes := make([]byte, 1024) n, _ := conn.Read(bytes) p := csm.NewPacket(bytes, n) if err := m.Match(nil, i, p); err != nil { ch <- Res{nil, err} close(ch) } } ch <- Res{m, nil} close(ch) } func getConnection(ip string, port int, portType string, isTLS bool) (net.Conn, error) { addr := fmt.Sprintf("%s:%d", ip, port) portType = strings.ToLower(portType) if isTLS { dialer := &net.Dialer{ Timeout: 5 * time.Second, } return tls.DialWithDialer( dialer, portType, addr, &tls.Config{ InsecureSkipVerify: true, ServerName: ip, }, ) } return net.Dial(portType, addr) }