2017-11-22 10:04:04 +00:00
package ipv4
import (
"fmt"
"net"
"git.loafle.net/commons_go/logging"
"git.loafle.net/overflow/overflow_discovery/api/module/discovery/model"
"git.loafle.net/overflow/overflow_discovery/service"
"git.loafle.net/overflow/overflow_discovery/service/matcher"
)
func scanServiceTCP ( port * model . Port , ds * model . DiscoveryService , resultChan chan interface { } , errChan chan error , stopChan chan struct { } ) bool {
hostIP := port . Host . IP
portNumber := port . PortNumber
info := matcher . NewMatchInfo ( hostIP , portNumber )
var s * model . Service
scs := [ ] serviceConnector {
& normalServiceConn {
t : model . PortTypeTCP ,
} ,
& tlsServiceConn {
t : model . CryptoTypeTLS ,
} ,
}
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 {
s = hadlePrePacket ( info , sc , conn , matcher . NewPacket ( buf , rn ) )
} else {
conn . Close ( )
s = hadlePostPacket ( info , sc )
}
if nil != s {
break
}
}
if nil != s {
s . Port = port
resultChan <- s
return true
}
return false
}
func hadlePrePacket ( info matcher . MatchInfo , sc serviceConnector , conn net . Conn , packet * matcher . Packet ) * model . Service {
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
ms := service . GetTCPMatchers ( true )
buf := make ( [ ] byte , 1024 )
var s * model . Service
Loop :
for i := 0 ; i < len ( ms ) ; i ++ {
m := ms [ i ]
if m . Match ( info , 0 , packet ) {
packetCount := m . PacketCount ( )
if 0 == packetCount {
s = & model . Service {
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
}
if m . Match ( info , j + 1 , matcher . NewPacket ( buf , rn ) ) {
// 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 {
s = & model . Service {
ServiceName : m . ServiceName ( ) ,
CryptoType : sc . Type ( ) ,
}
break Loop
}
}
}
return s
}
func hadlePostPacket ( info matcher . MatchInfo , sc serviceConnector ) * model . Service {
ms := service . GetTCPMatchers ( false )
buf := make ( [ ] byte , 1024 )
var s * model . Service
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 ) {
s = & model . Service {
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
}
if m . Match ( info , j , matcher . NewPacket ( buf , rn ) ) {
if packetCount - 1 == j {
s = & model . Service {
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
}