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

@ -31,7 +31,7 @@ var (
// 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
// manufacturers will hold manufacturer to UUID correlations
dbs = []string {
dbs = []string{
"devices",
"exploits",
"services",
@ -66,6 +66,14 @@ func (manuf *Manufacturer) IngestUUID(uuid bluetooth.UUID) bool {
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
func ManufLoad() {
path := projVars.ManuFile

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

@ -40,23 +40,23 @@ func (m *Meta) NewScan() *Scan {
}
scan := m.Scans[newid]
scan.Devices = make(map[int]*eros.Device)
scan.Device = make(map[int]*eros.Device)
m.Count = len(m.Scans)
return scan
}
func (s *Scan) NewDevice(name string, addr string, manuf string, rssi int16) *eros.Device {
newid := len(s.Devices)
s.Devices[newid] = &eros.Device{
newid := len(s.Device)
s.Device[newid] = &eros.Device{
Name: name,
Addr: addr,
Manufacturer: manuf,
RSSIlast: rssi,
}
s.Count = len(s.Devices)
return s.Devices[newid]
s.Count = len(s.Device)
return s.Device[newid]
}
/*
@ -93,12 +93,6 @@ func ManfCheck(TargetAdvertData bluetooth.AdvertisementPayload) string {
func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.ScanResult) {
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
addr := result.Address.String()
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)
if projVars.TrackingMode == false {
for _, dev := range s.Devices {
for _, dev := range s.Device {
if addr == dev.Addr {
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
s.Activity = time.Now()
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
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")
// TODO: re-assess the timeout mechanism
// this is largely going to depend on how concurrent we can get (at least with only one ble adapter)
var connErr error
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)
// outputs time on {timer_Name}.C chan
// can then be checked against tick (time.Time)
TimerCounts := time.NewTimer(10 * time.Millisecond)
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{})
if connErr != nil {
sublog.Error().Err(connErr).Msg("CONNECT_ERROR")
layToRest(dev)
return
}
var targetServices []bluetooth.DeviceService
sublog.Info().
Str("status", "Attempting to Read Target Services").
Str("status", "Connected, attempting to Read Target Services").
Msg("ADAPTER_STATUS")
// TODO: this will be running concurrently in a goroutine,
// 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 {
if !dev.Connected {
layToRest(dev)
return
}
@ -252,7 +218,7 @@ func (s *Scan) resultHandler(scanAdapter *bluetooth.Adapter, result bluetooth.Sc
//ServBuf := make([]byte, 255)
Charbuf := make([]byte, 255)
targetServices, err = TargetDevice.DiscoverServices(nil)
targetServices, err = dev.Conn.DiscoverServices(nil)
if err != nil {
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
TargetDevice.Disconnect()
dev.Conn.Disconnect()
dev.Connected = false
sublog.Info().Str("Adapter", "Successfully Disconnected From Target").Msg("ADAPTER_STATUS")
projVars.ConnectedToTarget = false
layToRest(dev)

@ -1,8 +1,9 @@
package protogen
import (
"time"
bluetooth "git.tcp.direct/kayos/prototooth"
"protomolecule/src/eros"
"time"
)
/*
@ -42,16 +43,16 @@ type Postcard struct {
// Arguments - augmenting arguments to the command
Arguments []string
}
// Instance of a BLE scan
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
ID int
Started time.Time
Activity time.Time
Devices map[int]*eros.Device
ID int
Started time.Time
Activity time.Time
Device map[int]*eros.Device
Connection map[int]*bluetooth.Connection
}

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