2018-08-13 07:19:59 +00:00
package ipv4
import (
"fmt"
"net"
"time"
logging "git.loafle.net/commons/logging-go"
cuej "git.loafle.net/commons/util-go/encoding/json"
omd "git.loafle.net/overflow/model/discovery"
omm "git.loafle.net/overflow/model/meta"
omu "git.loafle.net/overflow/model/util"
2018-08-15 07:46:52 +00:00
osm "git.loafle.net/overflow/service_matcher-go"
2018-08-13 07:19:59 +00:00
"git.loafle.net/overflow_scanner/probe/matcher"
)
func scanServiceTCP ( port * omd . Port , ds * omd . DiscoverService , resultChan chan interface { } , errChan chan error , stopChan chan struct { } ) bool {
hostIP := port . Host . Address
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
}
2018-08-15 07:46:52 +00:00
info := osm . NewMatchInfo ( hostIP , portNumber )
2018-08-13 07:19:59 +00:00
var s * omd . Service
scs := [ ] serviceConnector {
& normalServiceConn {
metaCryptoType : omm . ToMetaCryptoType ( omm . MetaCryptoTypeEnumNONE ) ,
} ,
& tlsServiceConn {
metaCryptoType : omm . ToMetaCryptoType ( omm . MetaCryptoTypeEnumTLS ) ,
} ,
}
LOOP :
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 . MetaCryptoType ( ) . Key , hostIP , portNumber , err )
return false
}
logging . Logger ( ) . Debugf ( "Discovery: Service scan connected[%s:%d] %s" , hostIP , portNumber , sc . MetaCryptoType ( ) . Key )
buf := make ( [ ] byte , 1024 )
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 . MetaCryptoType ( ) . Key )
return false
}
rn , err := conn . Read ( buf )
if err != nil {
rn = 0
}
if rn != 0 {
2018-08-15 07:46:52 +00:00
s = hadlePrePacket ( info , sc , conn , osm . NewPacket ( buf , rn ) )
2018-08-13 07:19:59 +00:00
} else {
conn . Close ( )
2018-08-16 04:17:38 +00:00
s = hadlePostPacket ( info , sc , nil )
2018-08-13 07:19:59 +00:00
}
if nil != s {
2018-08-16 04:17:38 +00:00
if s . Key == "HTTP" {
hsm := matcher . GetHTTPSubMatchers ( )
if ss := hadlePostPacket ( info , sc , hsm ) ; ss != nil {
s = ss
}
}
2018-08-13 07:19:59 +00:00
break LOOP
}
select {
case <- stopChan :
return false
default :
}
}
if nil != s {
s . Port = port
resultChan <- s
return true
}
return false
}
2018-08-15 07:46:52 +00:00
func hadlePrePacket ( info osm . MatchInfo , sc serviceConnector , conn net . Conn , packet * osm . Packet ) * omd . Service {
2018-08-13 07:19:59 +00:00
defer func ( ) {
conn . Close ( )
} ( )
// logging.Logger().Debugf("Discovery: Service scan pre packet length[%d], buf[%v]", packet.Len, packet.Buffer)
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d pre packet length[%d]" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , packet . Len )
ms := matcher . GetTCPMatchers ( true )
buf := make ( [ ] byte , 1024 )
var s * omd . Service
LOOP :
for i := 0 ; i < len ( ms ) ; i ++ {
m := ms [ i ]
if err := m . Match ( info , 0 , packet ) ; err == nil {
packetCount := m . PacketCount ( )
if 0 == packetCount {
2018-08-15 07:46:52 +00:00
s = discoveredService ( m , sc )
2018-08-13 07:19:59 +00:00
break LOOP
}
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)
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d]" , sc . MetaCryptoType ( ) . Key , 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 . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , tPacket . Len )
break LOOP
}
wn , err := conn . Write ( tPacket . Buffer )
if nil != err {
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d send packet error %v" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , err )
continue LOOP
}
if wn != tPacket . Len {
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , wn , tPacket . Len )
continue LOOP
}
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 . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , tPacket . Len )
break LOOP
}
rn , err := conn . Read ( buf )
if nil != err {
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d receive packet error %v" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , err )
break LOOP
}
2018-08-15 07:46:52 +00:00
if err := m . Match ( info , j + 1 , osm . NewPacket ( buf , rn ) ) ; err == nil {
2018-08-13 07:19:59 +00:00
// logging.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d receive match length[%d]" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , rn )
found = true
} else {
// logging.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d receive not match length[%d]" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , rn )
found = false
continue LOOP
}
}
if found {
2018-08-15 07:46:52 +00:00
s = discoveredService ( m , sc )
2018-08-13 07:19:59 +00:00
break LOOP
}
}
}
return s
}
2018-08-16 04:17:38 +00:00
func hadlePostPacket ( info osm . MatchInfo , sc serviceConnector , limitedMatchers [ ] osm . Matcher ) * omd . Service {
2018-08-13 07:19:59 +00:00
defer func ( ) {
} ( )
ms := matcher . GetTCPMatchers ( false )
2018-08-16 04:17:38 +00:00
if limitedMatchers != nil {
ms = limitedMatchers
}
2018-08-13 07:19:59 +00:00
buf := make ( [ ] byte , 1024 )
var s * omd . Service
LOOP :
for i := 0 ; i < len ( ms ) ; i ++ {
m := ms [ i ]
conn , err := sc . Dial ( info . IP ( ) , info . Port ( ) )
if err != nil {
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d socket dial error %v" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , err )
break LOOP
}
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)
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d]" , sc . MetaCryptoType ( ) . Key , 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 . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , tPacket . Len )
break
}
wn , err := conn . Write ( tPacket . Buffer )
if nil != err {
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d send packet error %v" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , err )
break
}
if wn != tPacket . Len {
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , wn , tPacket . Len )
break
}
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 . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , tPacket . Len )
break
}
rn , err := conn . Read ( buf )
if nil != err {
if ! m . HasResponse ( j ) {
2018-08-15 07:46:52 +00:00
s = discoveredService ( m , sc )
2018-08-13 07:19:59 +00:00
break
}
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d receive packet error %v" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , err )
break
}
2018-08-15 07:46:52 +00:00
if err := m . Match ( info , j , osm . NewPacket ( buf , rn ) ) ; err == nil {
2018-08-13 07:19:59 +00:00
if packetCount - 1 == j {
2018-08-15 07:46:52 +00:00
s = discoveredService ( m , sc )
2018-08-13 07:19:59 +00:00
break
}
// logging.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d receive match length[%d]" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , rn )
continue
} else {
// logging.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
logging . Logger ( ) . Debugf ( "Discovery: Service scan[%s] on %s:%d receive not match length[%d]" , sc . MetaCryptoType ( ) . Key , info . IP ( ) , info . Port ( ) , rn )
break
}
}
conn . Close ( )
if nil != s {
break LOOP
}
}
return s
}
2018-08-15 07:46:52 +00:00
func discoveredService ( m osm . Matcher , sc serviceConnector ) * omd . Service {
return & omd . Service {
Key : m . Key ( ) ,
MetaCryptoType : sc . MetaCryptoType ( ) ,
DiscoveredDate : omu . NowPtr ( ) ,
Metadata : m . Meta ( ) ,
Name : m . Name ( ) ,
}
}