container_discovery/internal/discoverer/ipv4/service_tcp.go

250 lines
7.8 KiB
Go
Raw Normal View History

2018-04-19 11:36:56 +00:00
package ipv4
import (
"fmt"
"net"
2018-04-27 15:33:22 +00:00
"time"
2018-04-19 11:36:56 +00:00
"git.loafle.net/commons/logging-go"
csm "git.loafle.net/commons/service_matcher-go"
cuej "git.loafle.net/commons/util-go/encoding/json"
occc "git.loafle.net/overflow/commons-go/core/constants"
2018-04-26 09:00:24 +00:00
ocmd "git.loafle.net/overflow/commons-go/model/discovery"
2018-04-19 11:36:56 +00:00
"git.loafle.net/overflow/container_discovery/internal/matcher"
)
2018-04-27 16:20:01 +00:00
func scanServiceTCP(port *ocmd.Port, ds *ocmd.DiscoverService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) bool {
2018-04-27 16:56:47 +00:00
hostIP := port.Host.IPV4
2018-04-19 11:36:56 +00:00
portNumber, err := cuej.NumberToInt(port.PortNumber)
if err != nil {
errChan <- fmt.Errorf("Discovery: Service scan on %s:%s error has occurred %v ", hostIP, port.PortNumber, err)
return false
}
info := csm.NewMatchInfo(hostIP, portNumber)
2018-04-26 09:00:24 +00:00
var s *ocmd.Service
2018-04-19 11:36:56 +00:00
scs := []serviceConnector{
&normalServiceConn{
2018-04-27 15:33:22 +00:00
cryptoType: occc.CryptoTypeNONE.String(),
2018-04-19 11:36:56 +00:00
},
&tlsServiceConn{
2018-04-27 15:33:22 +00:00
cryptoType: occc.CryptoTypeTLS.String(),
2018-04-19 11:36:56 +00:00
},
}
2018-04-27 15:33:22 +00:00
LOOP:
2018-04-19 11:36:56 +00:00
for i := 0; i < len(scs); i++ {
sc := scs[i]
conn, err := sc.Dial(hostIP, portNumber)
if err != nil {
2018-04-27 15:33:22 +00:00
errChan <- fmt.Errorf("Discovery: Service scan[%s] on %s:%d error has occurred %v ", sc.CryptoType(), hostIP, portNumber, err)
return false
2018-04-19 11:36:56 +00:00
}
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan connected[%s:%d] %s", hostIP, portNumber, sc.CryptoType())
2018-04-19 11:36:56 +00:00
buf := make([]byte, 1024)
2018-04-27 15:33:22 +00:00
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
logging.Logger().Debugf("Discovery: cannot set readdeadline connected[%s:%d] %s", hostIP, portNumber, sc.CryptoType())
return false
}
2018-04-19 11:36:56 +00:00
rn, err := conn.Read(buf)
if err != nil {
rn = 0
}
if rn != 0 {
s = hadlePrePacket(info, sc, conn, csm.NewPacket(buf, rn))
} else {
conn.Close()
s = hadlePostPacket(info, sc)
}
if nil != s {
2018-04-27 15:33:22 +00:00
break LOOP
2018-04-19 11:36:56 +00:00
}
select {
case <-stopChan:
2018-04-27 15:33:22 +00:00
return false
default:
2018-04-19 11:36:56 +00:00
}
}
if nil != s {
s.Port = port
resultChan <- s
return true
}
return false
}
2018-04-26 09:00:24 +00:00
func hadlePrePacket(info csm.MatchInfo, sc serviceConnector, conn net.Conn, packet *csm.Packet) *ocmd.Service {
2018-04-19 11:36:56 +00:00
defer func() {
conn.Close()
}()
// logging.Logger().Debugf("Discovery: Service scan pre packet length[%d], buf[%v]", packet.Len, packet.Buffer)
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d pre packet length[%d]", sc.CryptoType(), info.IP(), info.Port(), packet.Len)
2018-04-19 11:36:56 +00:00
ms := matcher.GetTCPMatchers(true)
buf := make([]byte, 1024)
2018-04-26 09:00:24 +00:00
var s *ocmd.Service
2018-04-19 11:36:56 +00:00
2018-04-27 15:33:22 +00:00
LOOP:
2018-04-19 11:36:56 +00:00
for i := 0; i < len(ms); i++ {
m := ms[i]
if m.Match(info, 0, packet) {
packetCount := m.PacketCount()
if 0 == packetCount {
2018-04-26 09:00:24 +00:00
s = &ocmd.Service{
2018-04-19 11:36:56 +00:00
ServiceName: m.Name(),
2018-04-27 15:33:22 +00:00
CryptoType: occc.ToCryptoType(sc.CryptoType()),
2018-04-19 11:36:56 +00:00
}
2018-04-27 15:33:22 +00:00
break LOOP
2018-04-19 11:36:56 +00:00
}
found := false
for j := 0; j < packetCount; j++ {
tPacket := m.Packet(j)
// logging.Logger().Debugf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer)
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d]", sc.CryptoType(), info.IP(), info.Port(), tPacket.Len)
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
logging.Logger().Debugf("Discovery: cannot set writeDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.CryptoType(), info.IP(), info.Port(), tPacket.Len)
break LOOP
}
2018-04-19 11:36:56 +00:00
wn, err := conn.Write(tPacket.Buffer)
if nil != err {
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet error %v", sc.CryptoType(), info.IP(), info.Port(), err)
continue LOOP
2018-04-19 11:36:56 +00:00
}
if wn != tPacket.Len {
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d", sc.CryptoType(), info.IP(), info.Port(), wn, tPacket.Len)
continue LOOP
2018-04-19 11:36:56 +00:00
}
2018-04-27 15:33:22 +00:00
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
logging.Logger().Debugf("Discovery: cannot set readDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.CryptoType(), info.IP(), info.Port(), tPacket.Len)
break LOOP
}
2018-04-19 11:36:56 +00:00
rn, err := conn.Read(buf)
if nil != err {
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive packet error %v", sc.CryptoType(), info.IP(), info.Port(), err)
break LOOP
2018-04-19 11:36:56 +00:00
}
if m.Match(info, j+1, csm.NewPacket(buf, rn)) {
// logging.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive match length[%d]", sc.CryptoType(), info.IP(), info.Port(), rn)
2018-04-19 11:36:56 +00:00
found = true
} else {
// logging.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive not match length[%d]", sc.CryptoType(), info.IP(), info.Port(), rn)
2018-04-19 11:36:56 +00:00
found = false
2018-04-27 15:33:22 +00:00
continue LOOP
2018-04-19 11:36:56 +00:00
}
}
if found {
2018-04-26 09:00:24 +00:00
s = &ocmd.Service{
2018-04-19 11:36:56 +00:00
ServiceName: m.Name(),
2018-04-27 15:33:22 +00:00
CryptoType: occc.ToCryptoType(sc.CryptoType()),
2018-04-19 11:36:56 +00:00
}
2018-04-27 15:33:22 +00:00
break LOOP
2018-04-19 11:36:56 +00:00
}
}
}
return s
}
2018-04-26 09:00:24 +00:00
func hadlePostPacket(info csm.MatchInfo, sc serviceConnector) *ocmd.Service {
2018-04-27 15:33:22 +00:00
defer func() {
}()
2018-04-19 11:36:56 +00:00
ms := matcher.GetTCPMatchers(false)
buf := make([]byte, 1024)
2018-04-26 09:00:24 +00:00
var s *ocmd.Service
2018-04-19 11:36:56 +00:00
2018-04-27 15:33:22 +00:00
LOOP:
2018-04-19 11:36:56 +00:00
for i := 0; i < len(ms); i++ {
m := ms[i]
conn, err := sc.Dial(info.IP(), info.Port())
if err != nil {
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d socket dial error %v", sc.CryptoType(), info.IP(), info.Port(), err)
break LOOP
2018-04-19 11:36:56 +00:00
}
packetCount := m.PacketCount()
for j := 0; j < packetCount; j++ {
tPacket := m.Packet(j)
// logging.Logger().Debugf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer)
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d]", sc.CryptoType(), info.IP(), info.Port(), tPacket.Len)
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
logging.Logger().Debugf("Discovery: cannot set writeDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.CryptoType(), info.IP(), info.Port(), tPacket.Len)
break
}
2018-04-19 11:36:56 +00:00
wn, err := conn.Write(tPacket.Buffer)
if nil != err {
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet error %v", sc.CryptoType(), info.IP(), info.Port(), err)
2018-04-19 11:36:56 +00:00
break
}
if wn != tPacket.Len {
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d", sc.CryptoType(), info.IP(), info.Port(), wn, tPacket.Len)
2018-04-19 11:36:56 +00:00
break
}
2018-04-27 15:33:22 +00:00
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
logging.Logger().Debugf("Discovery: cannot set readDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.CryptoType(), info.IP(), info.Port(), tPacket.Len)
break
}
2018-04-19 11:36:56 +00:00
rn, err := conn.Read(buf)
if nil != err {
if !m.HasResponse(j) {
2018-04-26 09:00:24 +00:00
s = &ocmd.Service{
2018-04-19 11:36:56 +00:00
ServiceName: m.Name(),
2018-04-27 15:33:22 +00:00
CryptoType: occc.ToCryptoType(sc.CryptoType()),
2018-04-19 11:36:56 +00:00
}
break
}
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive packet error %v", sc.CryptoType(), info.IP(), info.Port(), err)
2018-04-19 11:36:56 +00:00
break
}
if m.Match(info, j, csm.NewPacket(buf, rn)) {
if packetCount-1 == j {
2018-04-26 09:00:24 +00:00
s = &ocmd.Service{
2018-04-19 11:36:56 +00:00
ServiceName: m.Name(),
2018-04-27 15:33:22 +00:00
CryptoType: occc.ToCryptoType(sc.CryptoType()),
2018-04-19 11:36:56 +00:00
}
break
}
// logging.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive match length[%d]", sc.CryptoType(), info.IP(), info.Port(), rn)
2018-04-19 11:36:56 +00:00
continue
} else {
// logging.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
2018-04-27 15:33:22 +00:00
logging.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive not match length[%d]", sc.CryptoType(), info.IP(), info.Port(), rn)
2018-04-19 11:36:56 +00:00
break
}
}
conn.Close()
if nil != s {
2018-04-27 15:33:22 +00:00
break LOOP
2018-04-19 11:36:56 +00:00
}
}
return s
}