Skip to content

Commit

Permalink
Merge pull request #17 from robgonnella/improve-performance
Browse files Browse the repository at this point in the history
Drastically improve performance
  • Loading branch information
robgonnella authored Dec 26, 2023
2 parents f8fd2f0 + 4064d8a commit 10839c4
Show file tree
Hide file tree
Showing 13 changed files with 435 additions and 210 deletions.
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# go-lanscan
![Coverage](https://img.shields.io/badge/Coverage-91.2%25-brightgreen)
![Coverage](https://img.shields.io/badge/Coverage-91.8%25-brightgreen)

A network cli and golang package that allows you to perform arp and syn
scanning on a local area network.
Expand Down Expand Up @@ -84,12 +84,10 @@ First you must install the following dependencies

You can provide the following options to all scanners

- Provide callback for notifications when packet requests are sent to target
- Provide channel for notifications when packet requests are sent to target

```go
callback := func(request *scanner.Request) {
fmt.Printf("syn packet sent to %s on port %s", request.IP, request.Port)
}
requests := make(chan *scanner.Request)

synScanner := scanner.NewSynScanner(
targets,
Expand All @@ -98,15 +96,15 @@ You can provide the following options to all scanners
listenPort,
synResults,
synDone,
scanner.WithRequestNotifications(callback),
scanner.WithRequestNotifications(requests),
)

// or
option := scanner.WithRequestNotifications(callback)
option(synScanner)
option := scanner.WithRequestNotifications(requests)
option(requests)

// or
synScanner.SetRequestNotifications(callback)
synScanner.SetRequestNotifications(requests)
```

- Provide your own idle timeout. If no packets are received from our targets
Expand Down
117 changes: 59 additions & 58 deletions internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,27 @@ func (r *Results) MarshalJSON() ([]byte, error) {
}

type Core struct {
arpOnly bool
printJson bool
noProgress bool
outFile string
portLen int
results *Results
pw progress.Writer
arpTracker *progress.Tracker
synTracker *progress.Tracker
errorChan chan error
scanner scanner.Scanner
mux *sync.RWMutex
log logger.Logger
arpOnly bool
printJson bool
noProgress bool
outFile string
portLen int
results *Results
pw progress.Writer
arpTracker *progress.Tracker
synTracker *progress.Tracker
requestNotifier chan *scanner.Request
errorChan chan error
scanner scanner.Scanner
mux *sync.RWMutex
log logger.Logger
}

func New() *Core {
return &Core{
mux: &sync.RWMutex{},
log: logger.New(),
requestNotifier: make(chan *scanner.Request),
mux: &sync.RWMutex{},
log: logger.New(),
}
}

Expand All @@ -102,7 +104,7 @@ func (c *Core) Initialize(
if noProgress {
logger.SetGlobalLevel(zerolog.Disabled)
} else {
coreScanner.SetRequestNotifications(c.requestCallback)
coreScanner.SetRequestNotifications(c.requestNotifier)
}

c.scanner = coreScanner
Expand All @@ -122,11 +124,11 @@ func (c *Core) Run() error {
start := time.Now()

if !c.noProgress {
c.pw.AppendTracker(c.arpTracker)
go c.monitorRequestNotifications()
go c.pw.Render()
}

c.pw.AppendTracker(c.arpTracker)

// run in go routine so we can process in results in parallel
go func() {
if err := c.scanner.Scan(); err != nil {
Expand Down Expand Up @@ -157,8 +159,6 @@ OUTER:
}
}

c.scanner.Stop()

c.log.Info().Str("duration", time.Since(start).String()).Msg("go-lanscan complete")

return nil
Expand Down Expand Up @@ -252,44 +252,6 @@ func (c *Core) processArpDone() {
}
}

func (c *Core) requestCallback(r *scanner.Request) {
switch r.Type {
case scanner.ArpRequest:
c.arpTracker.Increment(1)

message := fmt.Sprintf("arp - scanning %s", r.IP)

if c.arpTracker.IsDone() {
message = "arp - scan complete"
// delay to print line after message is updated
time.AfterFunc(time.Millisecond*100, func() {
c.log.Info().Msg("compiling arp results...")
})
}

c.arpTracker.Message = message
case scanner.SynRequest:
c.synTracker.Increment(1)

message := fmt.Sprintf(
"syn - scanning port %d on %s",
r.Port,
r.IP,
)

if c.synTracker.IsDone() {
message = "syn - scan complete"
// delay to print line after message is updated
time.AfterFunc(time.Millisecond*100, func() {
c.log.Info().Msg("compiling syn results...")
})
}

c.synTracker.Message = message

}
}

func (c *Core) printArpResults() {
c.mux.RLock()
defer c.mux.RUnlock()
Expand Down Expand Up @@ -387,6 +349,45 @@ func (c *Core) printSynResults() {
}
}

func (c *Core) monitorRequestNotifications() {
for r := range c.requestNotifier {
switch r.Type {
case scanner.ArpRequest:
c.arpTracker.Increment(1)

message := fmt.Sprintf("arp - scanning %s", r.IP)

if c.arpTracker.IsDone() {
message = "arp - scan complete"
// delay to print line after message is updated
time.AfterFunc(time.Millisecond*100, func() {
c.log.Info().Msg("compiling arp results...")
})
}

c.arpTracker.Message = message
case scanner.SynRequest:
c.synTracker.Increment(1)

message := fmt.Sprintf(
"syn - scanning port %d on %s",
r.Port,
r.IP,
)

if c.synTracker.IsDone() {
message = "syn - scan complete"
// delay to print line after message is updated
time.AfterFunc(time.Millisecond*100, func() {
c.log.Info().Msg("compiling syn results...")
})
}

c.synTracker.Message = message
}
}
}

// helpers
func progressWriter() progress.Writer {
pw := progress.NewWriter()
Expand Down
Loading

0 comments on commit 10839c4

Please sign in to comment.