2017-11-22 10:04:04 +00:00
package ipv4
import (
"fmt"
"net"
"git.loafle.net/commons_go/logging"
2017-12-04 09:37:39 +00:00
cnsm "git.loafle.net/commons_go/network_service_matcher"
cuej "git.loafle.net/commons_go/util/encoding/json"
oocmd "git.loafle.net/overflow/overflow_commons_go/modules/discovery"
discoveryM "git.loafle.net/overflow/overflow_commons_go/modules/discovery/model"
"git.loafle.net/overflow/overflow_discovery/matcher"
2017-11-22 10:04:04 +00:00
)
2017-12-04 09:37:39 +00:00
func scanServiceTCP ( port * discoveryM . Port , ds * discoveryM . DiscoveryService , resultChan chan interface { } , errChan chan error , stopChan chan struct { } ) bool {
2017-11-22 10:04:04 +00:00
hostIP := port . Host . IP
2017-12-04 09:37:39 +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 := cnsm . NewMatchInfo ( hostIP , portNumber )
var s * discoveryM . Service
2017-11-22 10:04:04 +00:00
scs := [ ] serviceConnector {
& normalServiceConn {
2017-12-04 09:37:39 +00:00
t : oocmd . PortTypeTCP ,
2017-11-22 10:04:04 +00:00
} ,
& tlsServiceConn {
2017-12-04 09:37:39 +00:00
t : oocmd . CryptoTypeTLS ,
2017-11-22 10:04:04 +00:00
} ,
}
for i := 0 ; i < len ( scs ) ; i ++ {
sc := scs [ i ]
conn , err := sc . Dial ( hostIP , portNumber )
if err != nil {
errChan <- fmt . Errorf ( "Discovery: Service scan[%s] on %s:%d error has occurred %v " , sc . Type ( ) , hostIP , portNumber , err )
break
}
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan connected[%s:%d] %s" , hostIP , portNumber , sc . Type ( ) ) )
2017-11-22 10:04:04 +00:00
buf := make ( [ ] byte , 1024 )
rn , err := conn . Read ( buf )
if err != nil {
rn = 0
}
if rn != 0 {
2017-12-04 09:37:39 +00:00
s = hadlePrePacket ( info , sc , conn , cnsm . NewPacket ( buf , rn ) )
2017-11-22 10:04:04 +00:00
} else {
conn . Close ( )
s = hadlePostPacket ( info , sc )
}
if nil != s {
break
}
2017-11-23 09:34:07 +00:00
select {
case <- stopChan :
return true
}
2017-11-22 10:04:04 +00:00
}
if nil != s {
s . Port = port
resultChan <- s
return true
}
return false
}
2017-12-04 09:37:39 +00:00
func hadlePrePacket ( info cnsm . MatchInfo , sc serviceConnector , conn net . Conn , packet * cnsm . Packet ) * discoveryM . Service {
2017-11-22 10:04:04 +00:00
defer func ( ) {
conn . Close ( )
} ( )
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan pre packet length[%d], buf[%v]", packet.Len, packet.Buffer))
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d pre packet length[%d]" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , packet . Len ) )
2017-11-22 10:04:04 +00:00
2017-12-04 09:37:39 +00:00
ms := matcher . GetTCPMatchers ( true )
2017-11-22 10:04:04 +00:00
buf := make ( [ ] byte , 1024 )
2017-12-04 09:37:39 +00:00
var s * discoveryM . Service
2017-11-22 10:04:04 +00:00
Loop :
for i := 0 ; i < len ( ms ) ; i ++ {
m := ms [ i ]
if m . Match ( info , 0 , packet ) {
packetCount := m . PacketCount ( )
if 0 == packetCount {
2017-12-04 09:37:39 +00:00
s = & discoveryM . Service {
2017-11-22 10:04:04 +00:00
ServiceName : m . ServiceName ( ) ,
CryptoType : sc . Type ( ) ,
}
break Loop
}
found := false
for j := 0 ; j < packetCount ; j ++ {
tPacket := m . Packet ( j )
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer))
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d]" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , tPacket . Len ) )
2017-11-22 10:04:04 +00:00
wn , err := conn . Write ( tPacket . Buffer )
if nil != err {
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d send packet error %v" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , err ) )
2017-11-22 10:04:04 +00:00
break
}
if wn != tPacket . Len {
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , wn , tPacket . Len ) )
2017-11-22 10:04:04 +00:00
break
}
rn , err := conn . Read ( buf )
if nil != err {
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d receive packet error %v" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , err ) )
2017-11-22 10:04:04 +00:00
break
}
2017-12-04 09:37:39 +00:00
if m . Match ( info , j + 1 , cnsm . NewPacket ( buf , rn ) ) {
2017-11-22 10:04:04 +00:00
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf))
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d receive match length[%d]" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , rn ) )
2017-11-22 10:04:04 +00:00
found = true
} else {
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf))
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d receive not match length[%d]" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , rn ) )
2017-11-22 10:04:04 +00:00
found = false
break
}
}
if found {
2017-12-04 09:37:39 +00:00
s = & discoveryM . Service {
2017-11-22 10:04:04 +00:00
ServiceName : m . ServiceName ( ) ,
CryptoType : sc . Type ( ) ,
}
break Loop
}
}
}
return s
}
2017-12-04 09:37:39 +00:00
func hadlePostPacket ( info cnsm . MatchInfo , sc serviceConnector ) * discoveryM . Service {
ms := matcher . GetTCPMatchers ( false )
2017-11-22 10:04:04 +00:00
buf := make ( [ ] byte , 1024 )
2017-12-04 09:37:39 +00:00
var s * discoveryM . Service
2017-11-22 10:04:04 +00:00
Loop :
for i := 0 ; i < len ( ms ) ; i ++ {
m := ms [ i ]
conn , err := sc . Dial ( info . IP ( ) , info . Port ( ) )
if err != nil {
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d socket dial error %v" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , err ) )
2017-11-22 10:04:04 +00:00
break Loop
}
packetCount := m . PacketCount ( )
for j := 0 ; j < packetCount ; j ++ {
tPacket := m . Packet ( j )
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer))
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d]" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , tPacket . Len ) )
2017-11-22 10:04:04 +00:00
wn , err := conn . Write ( tPacket . Buffer )
if nil != err {
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d send packet error %v" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , err ) )
2017-11-22 10:04:04 +00:00
break
}
if wn != tPacket . Len {
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , wn , tPacket . Len ) )
2017-11-22 10:04:04 +00:00
break
}
rn , err := conn . Read ( buf )
if nil != err {
if ! m . HasResponse ( j ) {
2017-12-04 09:37:39 +00:00
s = & discoveryM . Service {
2017-11-22 10:04:04 +00:00
ServiceName : m . ServiceName ( ) ,
CryptoType : sc . Type ( ) ,
}
break
}
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d receive packet error %v" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , err ) )
2017-11-22 10:04:04 +00:00
break
}
2017-12-04 09:37:39 +00:00
if m . Match ( info , j , cnsm . NewPacket ( buf , rn ) ) {
2017-11-22 10:04:04 +00:00
if packetCount - 1 == j {
2017-12-04 09:37:39 +00:00
s = & discoveryM . Service {
2017-11-22 10:04:04 +00:00
ServiceName : m . ServiceName ( ) ,
CryptoType : sc . Type ( ) ,
}
break
}
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf))
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d receive match length[%d]" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , rn ) )
2017-11-22 10:04:04 +00:00
continue
} else {
// logging.Logger().Debug(fmt.Sprintf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf))
2017-11-22 10:45:25 +00:00
logging . Logger ( ) . Debug ( fmt . Sprintf ( "Discovery: Service scan[%s] on %s:%d receive not match length[%d]" , sc . Type ( ) , info . IP ( ) , info . Port ( ) , rn ) )
2017-11-22 10:04:04 +00:00
break
}
}
conn . Close ( )
if nil != s {
break Loop
}
}
return s
}