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-19 11:36:56 +00:00
hostIP := port . Host . IP
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
}