refactor connection timeout, attempt to improve connection speed, attempt to improve speed of scan cancellation

This commit is contained in:
kayos 2021-06-15 19:42:53 -07:00
parent 8f63a56d67
commit 877557553c
6 changed files with 56 additions and 80 deletions

27
main.go

@ -83,20 +83,23 @@ func cliFlags() {
func sigHandler() { func sigHandler() {
c := make(chan os.Signal) c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM) signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() { for {
for { select {
select { case <-c:
log.Warn().
case <-c: Msg("Interrupt detected, stopping scan...")
log.Warn().Msg("Interrupt detected, stopping scan...") for _, scan := range protogen.ScanMgr.Scans {
for _, scan := range protogen.ScanMgr.Scans { projVars.TrackingMode = false
projVars.TrackingMode = false projVars.AttackMode = false
projVars.AttackMode = false for _, dev := range scan.Device {
scan.Stop() if dev.Connected {
dev.Conn.Disconnect()
}
} }
scan.Stop()
} }
} }
}() }
} }
func init() { func init() {
@ -116,7 +119,7 @@ func init() {
loginit() loginit()
cliFlags() cliFlags()
sigHandler() go sigHandler()
log.Debug().Msg("Logging initialized") log.Debug().Msg("Logging initialized")

@ -31,7 +31,7 @@ var (
// exploits will hold details about exploits to be used against BLE devices // exploits will hold details about exploits to be used against BLE devices
// services will hold definitions of various bluetook services and will ultimately be updated via an HTTP repository // services will hold definitions of various bluetook services and will ultimately be updated via an HTTP repository
// manufacturers will hold manufacturer to UUID correlations // manufacturers will hold manufacturer to UUID correlations
dbs = []string { dbs = []string{
"devices", "devices",
"exploits", "exploits",
"services", "services",
@ -66,6 +66,14 @@ func (manuf *Manufacturer) IngestUUID(uuid bluetooth.UUID) bool {
return true return true
} }
func (d *Device) ConnectHandler(target bluetooth.Addresser, c bool) {
if c {
d.Connected = true
} else {
d.Connected = false
}
}
// ManufLoad loads data from a json file containing UUID manufacturer associations // ManufLoad loads data from a json file containing UUID manufacturer associations
func ManufLoad() { func ManufLoad() {
path := projVars.ManuFile path := projVars.ManuFile

@ -79,4 +79,7 @@ type Device struct {
Discovered time.Time Discovered time.Time
// Seen - timestamp from when the device was last seen // Seen - timestamp from when the device was last seen
Seen time.Time Seen time.Time
Connected bool
Conn *bluetooth.Device
} }

@ -40,23 +40,23 @@ func (m *Meta) NewScan() *Scan {
} }
scan := m.Scans[newid] scan := m.Scans[newid]
scan.Devices = make(map[int]*eros.Device) scan.Device = make(map[int]*eros.Device)
m.Count = len(m.Scans) m.Count = len(m.Scans)
return scan return scan
} }
func (s *Scan) NewDevice(name string, addr string, manuf string, rssi int16) *eros.Device { func (s *Scan) NewDevice(name string, addr string, manuf string, rssi int16) *eros.Device {
newid := len(s.Devices) newid := len(s.Device)
s.Devices[newid] = &eros.Device{ s.Device[newid] = &eros.Device{
Name: name, Name: name,
Addr: addr, Addr: addr,
Manufacturer: manuf, Manufacturer: manuf,
RSSIlast: rssi, RSSIlast: rssi,
} }
s.Count = len(s.Devices) s.Count = len(s.Device)
return s.Devices[newid] return s.Device[newid]
} }
/* /*
@ -93,12 +93,6 @@ func ManfCheck(TargetAdvertData bluetooth.AdvertisementPayload) string {
func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.ScanResult) { func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.ScanResult) {
var sublog zerolog.Logger var sublog zerolog.Logger
projVars.ScanAdapter.SetConnectHandler(func(Result bluetooth.Addresser, connected bool) {
// It seems that because this is a callback that the library calls itself that it is passing us "connected" as an argument
// therefore I think what we're supposed to do is store that boolean so we can then reference it later
projVars.ConnectedToTarget = connected
})
payload := result.AdvertisementPayload payload := result.AdvertisementPayload
addr := result.Address.String() addr := result.Address.String()
lname := result.LocalName() lname := result.LocalName()
@ -165,7 +159,7 @@ func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.Sc
// Skipping duplicate results unless tracking mode enabled (to store RSSI as devices move) // Skipping duplicate results unless tracking mode enabled (to store RSSI as devices move)
if projVars.TrackingMode == false { if projVars.TrackingMode == false {
for _, dev := range s.Devices { for _, dev := range s.Device {
if addr == dev.Addr { if addr == dev.Addr {
return return
} }
@ -175,6 +169,7 @@ func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.Sc
// Upon finding new and valid info we update the time for last activity // Upon finding new and valid info we update the time for last activity
s.Activity = time.Now() s.Activity = time.Now()
dev := s.NewDevice(lname, addr, EnumedManuf, rssi) dev := s.NewDevice(lname, addr, EnumedManuf, rssi)
projVars.ScanAdapter.SetConnectHandler(dev.ConnectHandler)
// Record all the services advertised, append them into the nested struct within Device // Record all the services advertised, append them into the nested struct within Device
for _, uuid := range uuids { for _, uuid := range uuids {
@ -198,53 +193,24 @@ func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.Sc
sublog.Info().Str("Adapter", "Attempting Connection").Msg("ADAPTER_STATUS") sublog.Info().Str("Adapter", "Attempting Connection").Msg("ADAPTER_STATUS")
// TODO: re-assess the timeout mechanism var connErr error
// this is largely going to depend on how concurrent we can get (at least with only one ble adapter) var err error
timeout := bluetooth.NewDuration(time.Duration(5) * time.Second)
dev.Conn, connErr = projVars.ScanAdapter.Connect(result.Address, bluetooth.ConnectionParams{ConnectionTimeout: timeout})
// creates a new timer of d (time.Duration) if connErr != nil {
// outputs time on {timer_Name}.C chan sublog.Error().Err(connErr).Msg("CONNECT_ERROR")
// can then be checked against tick (time.Time) layToRest(dev)
TimerCounts := time.NewTimer(10 * time.Millisecond) return
}
var (
conTimeOut time.Duration
//tick <-chan time.Time
//not needed?
//tock <-chan time.Timer
err error
)
TargetDevice, connectError := projVars.ScanAdapter.Connect(result.Address, bluetooth.ConnectionParams{})
var targetServices []bluetooth.DeviceService var targetServices []bluetooth.DeviceService
sublog.Info(). sublog.Info().
Str("status", "Attempting to Read Target Services"). Str("status", "Connected, attempting to Read Target Services").
Msg("ADAPTER_STATUS") Msg("ADAPTER_STATUS")
// TODO: this will be running concurrently in a goroutine, if !dev.Connected {
// so rather than set out timeout to be egregiously low we will just let it take its time
conTimeOut = 50 * time.Millisecond
//attempted to fix but probably didnt help anything
if TimerCounts.C == nil {
endTime := time.After(conTimeOut)
select {
case <-endTime:
sublog.Error().Str("Adapter", "Connection Timeout").Msg("ADAPTER_STATUS")
TargetDevice.Disconnect()
endTime = nil
default:
if connectError != nil {
sublog.Error().Err(connectError).Msg("CONNECT_ERROR")
layToRest(dev)
return
}
sublog.Debug().Str("Status", "Connecting...").Msg("ADAPTER_STATUS")
}
}
if !projVars.ConnectedToTarget {
layToRest(dev) layToRest(dev)
return return
} }
@ -252,7 +218,7 @@ func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.Sc
//ServBuf := make([]byte, 255) //ServBuf := make([]byte, 255)
Charbuf := make([]byte, 255) Charbuf := make([]byte, 255)
targetServices, err = TargetDevice.DiscoverServices(nil) targetServices, err = dev.Conn.DiscoverServices(nil)
if err != nil { if err != nil {
sublog.Error().Err(err).Msg("DISCOVER_SERVICE_ERROR") sublog.Error().Err(err).Msg("DISCOVER_SERVICE_ERROR")
} }
@ -288,10 +254,9 @@ func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.Sc
} }
// finished with this device // finished with this device
dev.Conn.Disconnect()
TargetDevice.Disconnect() dev.Connected = false
sublog.Info().Str("Adapter", "Successfully Disconnected From Target").Msg("ADAPTER_STATUS") sublog.Info().Str("Adapter", "Successfully Disconnected From Target").Msg("ADAPTER_STATUS")
projVars.ConnectedToTarget = false
layToRest(dev) layToRest(dev)

@ -1,8 +1,9 @@
package protogen package protogen
import ( import (
"time" bluetooth "git.tcp.direct/kayos/prototooth"
"protomolecule/src/eros" "protomolecule/src/eros"
"time"
) )
/* /*
@ -42,16 +43,16 @@ type Postcard struct {
// Arguments - augmenting arguments to the command // Arguments - augmenting arguments to the command
Arguments []string Arguments []string
} }
// Instance of a BLE scan // Instance of a BLE scan
type Scan struct { type Scan struct {
Count int Count int
// The ID is how we will refer back to running scans during IPC to react or cancel a scan // The ID is how we will refer back to running scans during IPC to react or cancel a scan
ID int ID int
Started time.Time Started time.Time
Activity time.Time Activity time.Time
Devices map[int]*eros.Device Device map[int]*eros.Device
Connection map[int]*bluetooth.Connection
} }

@ -25,8 +25,6 @@ var AdapterInUse = *&bluetooth.Adapter{}
var AttackMode bool = false var AttackMode bool = false
var TrackingMode bool = false var TrackingMode bool = false
var ConnectedToTarget bool = false
//var SrvcUUIDList map[uint32]string //var SrvcUUIDList map[uint32]string
//hold the values for the initial ble scan results.. //hold the values for the initial ble scan results..
@ -52,8 +50,6 @@ var Debug bool = false
//flag.Parse() //flag.Parse()
//var attacker bluetooth.Addresser //var attacker bluetooth.Addresser
//var connected bool
//var disconnected bool = true
var log *zerolog.Logger var log *zerolog.Logger