From 877557553c4680be1e7c8dbe33321ecd5b9bcccb Mon Sep 17 00:00:00 2001 From: kayos Date: Tue, 15 Jun 2021 19:42:53 -0700 Subject: [PATCH] refactor connection timeout, attempt to improve connection speed, attempt to improve speed of scan cancellation --- main.go | 27 +++++++------- src/eros/eros.go | 10 +++++- src/eros/structs.go | 3 ++ src/protogen/ble_scan.go | 77 +++++++++++----------------------------- src/protogen/structs.go | 15 ++++---- src/vars/projVars.go | 4 --- 6 files changed, 56 insertions(+), 80 deletions(-) diff --git a/main.go b/main.go index 50f87d1..3ab86a6 100644 --- a/main.go +++ b/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") diff --git a/src/eros/eros.go b/src/eros/eros.go index 32ba398..e4b60f3 100644 --- a/src/eros/eros.go +++ b/src/eros/eros.go @@ -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 diff --git a/src/eros/structs.go b/src/eros/structs.go index fed5226..4a672fc 100644 --- a/src/eros/structs.go +++ b/src/eros/structs.go @@ -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 } diff --git a/src/protogen/ble_scan.go b/src/protogen/ble_scan.go index 8fcbfd2..378c9f7 100644 --- a/src/protogen/ble_scan.go +++ b/src/protogen/ble_scan.go @@ -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) diff --git a/src/protogen/structs.go b/src/protogen/structs.go index 5de1f96..b31af47 100644 --- a/src/protogen/structs.go +++ b/src/protogen/structs.go @@ -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 } diff --git a/src/vars/projVars.go b/src/vars/projVars.go index 2f4aa1d..c232185 100644 --- a/src/vars/projVars.go +++ b/src/vars/projVars.go @@ -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