11package goctopus
22
33import (
4+ "context"
45 "sync"
56
67 "github.com/Escape-Technologies/goctopus/internal/utils"
@@ -9,18 +10,20 @@ import (
910 "github.com/Escape-Technologies/goctopus/pkg/endpoint"
1011 "github.com/Escape-Technologies/goctopus/pkg/output"
1112 log "github.com/sirupsen/logrus"
13+ "golang.org/x/sync/semaphore"
1214)
1315
14- func worker (addresses chan string , output chan * output.FingerprintOutput , workerId int , wg * sync.WaitGroup ) {
15- defer wg .Done ()
16+ func worker (addresses chan string , output chan * output.FingerprintOutput , workerId int , sem * semaphore.Weighted ) {
1617 log .Debugf ("Worker %d instantiated" , workerId )
1718 for address := range addresses {
19+ sem .Acquire (context .Background (), 1 )
1820 log .Debugf ("Worker %d started on: %v" , workerId , address )
1921 res , err := FingerprintAddress (address )
2022 if err == nil {
2123 log .Debugf ("Worker %d found endpoint: %v" , workerId , res )
2224 output <- res
2325 }
26+ sem .Release (1 )
2427 }
2528 log .Debugf ("Worker %d finished" , workerId )
2629}
@@ -34,36 +37,51 @@ func FingerprintAddress(address string) (*output.FingerprintOutput, error) {
3437 }
3538}
3639
40+ func asyncEnumeration (address string , enumeratedAddresses chan string , threads int , sem * semaphore.Weighted , wg * sync.WaitGroup ) {
41+ defer wg .Done ()
42+ defer sem .Release (int64 (threads ))
43+ if err := domain .EnumerateSubdomains (address , enumeratedAddresses , threads ); err != nil {
44+ log .Errorf ("Error enumerating subdomains for %v: %v" , address , err )
45+ }
46+ }
47+
3748// An addresses can be a domain or an url
3849func FingerprintAddresses (addresses chan string , output chan * output.FingerprintOutput ) {
3950
4051 maxWorkers := config .Get ().MaxWorkers
4152 enumeratedAddresses := make (chan string , config .Get ().MaxWorkers )
4253
43- workersWg := sync.WaitGroup {}
44- workersWg .Add (maxWorkers )
54+ sem := semaphore .NewWeighted (int64 (maxWorkers ))
55+ enumerationWg := sync.WaitGroup {}
56+ enumerationThreads := utils .MinInt (maxWorkers , 10 )
4557
4658 for i := 0 ; i < maxWorkers ; i ++ {
47- go worker (enumeratedAddresses , output , i , & workersWg )
59+ go worker (enumeratedAddresses , output , i , sem )
4860 }
4961
5062 i := 1
5163 for address := range addresses {
5264 log .Debugf ("(%d) Adding %v to the queue" , i , address )
5365 // If the domain is a url, we don't need to crawl it
5466 if utils .IsUrl (address ) {
67+ sem .Acquire (context .Background (), 1 )
5568 enumeratedAddresses <- address
5669 } else {
57- if err := domain .EnumerateSubdomains (address , enumeratedAddresses ); err != nil {
58- log .Errorf ("Error enumerating subdomains for %v: %v" , address , err )
59- }
70+ // 10 threads for subdomain enumeration, unless maxWorkers is less than 10
71+ enumerationWg .Add (1 )
72+ sem .Acquire (context .Background (), int64 (enumerationThreads ))
73+ log .Errorf ("%v" , address )
74+ go asyncEnumeration (address , enumeratedAddresses , enumerationThreads , sem , & enumerationWg )
6075 }
6176 i ++
6277 }
6378
79+ log .Error ("here" )
80+ enumerationWg .Wait ()
81+ log .Error ("here 2" )
6482 close (enumeratedAddresses )
6583 log .Debugf ("Waiting for workers to finish..." )
66- workersWg . Wait ( )
84+ sem . Acquire ( context . Background (), int64 ( maxWorkers ) )
6785 close (output )
6886 log .Debugf ("All workers finished" )
6987}
0 commit comments