probe/ping/ping.go
2018-08-15 16:46:52 +09:00

100 lines
1.8 KiB
Go

package ping
import (
"crypto/tls"
"fmt"
"net"
"strings"
"time"
csm "git.loafle.net/overflow/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)
}