@@ -12,13 +12,15 @@ import (
1212 "os"
1313 "path/filepath"
1414 "strings"
15+ "sync"
1516 "time"
1617
1718 "github.com/google/uuid"
1819 "github.com/owasp-amass/amass/v5/config"
1920 "github.com/owasp-amass/amass/v5/engine/pubsub"
2021 "github.com/owasp-amass/amass/v5/engine/sessions/scope"
2122 et "github.com/owasp-amass/amass/v5/engine/types"
23+ amassnet "github.com/owasp-amass/amass/v5/internal/net"
2224 assetdb "github.com/owasp-amass/asset-db"
2325 "github.com/owasp-amass/asset-db/repository"
2426 "github.com/owasp-amass/asset-db/repository/neo4j"
@@ -29,47 +31,54 @@ import (
2931)
3032
3133type Session struct {
32- id uuid.UUID
33- ctx context.Context
34- cancel context.CancelFunc
35- log * slog.Logger
36- ps * pubsub.Logger
37- cfg * config.Config
38- scope et.Scope
39- start time.Time
40- db repository.Repository
41- backlog * sessionBacklog
42- pipelines et.SessionPipelines
43- dsn string
44- dbtype string
45- ranger cidranger.Ranger
46- tmpdir string
47- stats * et.SessionStats
48- done chan struct {}
49- finished bool
34+ id uuid.UUID
35+ mgr * manager
36+ ctx context.Context
37+ cancel context.CancelFunc
38+ log * slog.Logger
39+ ps * pubsub.Logger
40+ cfg * config.Config
41+ scope et.Scope
42+ start time.Time
43+ db repository.Repository
44+ backlog * sessionBacklog
45+ pipelines et.SessionPipelines
46+ dsn string
47+ dbtype string
48+ ranger cidranger.Ranger
49+ tmpdir string
50+ stats * et.SessionStats
51+ done chan struct {}
52+ finished bool
53+ numOfSess int
54+ netSemaphore * sessSemaphore
5055}
5156
5257// CreateSession initializes a new Session object based on the provided configuration.
5358// The session object represents the state of an active engine enumeration.
54- func CreateSession (reg et.Registry , cfg * config.Config ) (et.Session , error ) {
59+ func CreateSession (mgr * manager , reg et.Registry , cfg * config.Config ) (et.Session , error ) {
5560 // Use default configuration if none is provided
5661 if cfg == nil {
5762 cfg = config .NewConfig ()
5863 }
5964
6065 startTime := time .Now ()
66+ numOfSessions := mgr .NumOfSessions () + 1
6167 ctx , cancel := context .WithCancel (context .Background ())
6268 // Create a new session object
6369 s := & Session {
64- id : uuid .New (),
65- ctx : ctx ,
66- cancel : cancel ,
67- cfg : cfg ,
68- start : startTime ,
69- ranger : NewAmassRanger (),
70- ps : pubsub .NewLogger (),
71- stats : new (et.SessionStats ),
72- done : make (chan struct {}),
70+ id : uuid .New (),
71+ mgr : mgr ,
72+ ctx : ctx ,
73+ cancel : cancel ,
74+ cfg : cfg ,
75+ start : startTime ,
76+ ranger : NewAmassRanger (),
77+ ps : pubsub .NewLogger (),
78+ stats : new (et.SessionStats ),
79+ done : make (chan struct {}),
80+ numOfSess : numOfSessions ,
81+ netSemaphore : NewSessSemaphore (amassnet .MaxNetworkConns / numOfSessions ),
7382 }
7483 s .scope = scope .CreateFromConfigScope (s )
7584 s .log = slog .New (slog .NewJSONHandler (s .ps , nil )).With ("session" , s .id )
@@ -102,6 +111,7 @@ func CreateSession(reg et.Registry, cfg *config.Config) (et.Session, error) {
102111 s .log .Info ("Temporary directory created" , slog .String ("dir" , s .tmpdir ))
103112 s .log .Info ("Database connection established" , slog .String ("dsn" , s .dsn ))
104113 go s .updateStats ()
114+ go s .updateSessionSemaphore ()
105115 return s , nil
106116}
107117
@@ -121,6 +131,10 @@ func (s *Session) PubSub() *pubsub.Logger {
121131 return s .ps
122132}
123133
134+ func (s * Session ) NetSem () et.SessionSemaphone {
135+ return s .netSemaphore
136+ }
137+
124138func (s * Session ) Config () * config.Config {
125139 return s .cfg
126140}
@@ -298,3 +312,66 @@ func (s *Session) calculateStats() {
298312 ss .WorkItemsCompleted = completed
299313 ss .Unlock ()
300314}
315+
316+ type sessSemaphore struct {
317+ sync.Mutex
318+ sem amassnet.Semaphore
319+ }
320+
321+ func NewSessSemaphore (limit int ) * sessSemaphore {
322+ return & sessSemaphore {sem : amassnet .NewSemaphore (limit )}
323+ }
324+
325+ func (ss * sessSemaphore ) Acquire () {
326+ ss .Lock ()
327+ defer ss .Unlock ()
328+
329+ ss .sem .Acquire ()
330+ }
331+
332+ func (ss * sessSemaphore ) Release () {
333+ ss .Lock ()
334+ defer ss .Unlock ()
335+
336+ ss .sem .Release ()
337+ }
338+
339+ func (s * Session ) updateSessionSemaphore () {
340+ tick := time .NewTicker (10 * time .Second )
341+ defer tick .Stop ()
342+
343+ for {
344+ select {
345+ case <- s .done :
346+ return
347+ case <- tick .C :
348+ if num := s .mgr .NumOfSessions (); num != s .numOfSess {
349+ s .numOfSess = num
350+ s .buildNewSessionSemaphore ()
351+ }
352+ }
353+ }
354+ }
355+
356+ func (s * Session ) buildNewSessionSemaphore () {
357+ s .netSemaphore .Lock ()
358+ defer s .netSemaphore .Unlock ()
359+
360+ limit := amassnet .MaxNetworkConns / s .numOfSess
361+ sem := amassnet .NewSemaphore (limit )
362+ loop:
363+ for range limit {
364+ select {
365+ case s .netSemaphore .sem <- struct {}{}:
366+ select {
367+ case <- sem :
368+ default :
369+ break loop
370+ }
371+ default :
372+ break loop
373+ }
374+ }
375+
376+ s .netSemaphore .sem = sem
377+ }
0 commit comments