88from  nettacker  import  logger 
99from  nettacker .config  import  Config 
1010from  nettacker .core .messages  import  messages  as  _ 
11+ from  nettacker .core .queue_manager  import  thread_pool 
1112from  nettacker .core .template  import  TemplateLoader 
1213from  nettacker .core .utils .common  import  expand_module_steps , wait_for_threads_to_finish 
1314from  nettacker .database .db  import  find_events 
@@ -118,26 +119,44 @@ def generate_loops(self):
118119        self .module_content ["payloads" ] =  expand_module_steps (self .module_content ["payloads" ])
119120
120121    def  sort_loops (self ):
121-         steps  =  []
122+         """ 
123+         Sort loops to optimize dependency resolution: 
124+         1. Independent steps first 
125+         2. Steps that generate dependencies (save_to_temp_events_only) 
126+         3. Steps that consume dependencies (dependent_on_temp_event) 
127+         """ 
122128        for  index  in  range (len (self .module_content ["payloads" ])):
123-             for   step   in   copy . deepcopy ( self . module_content [ "payloads" ][ index ][ "steps" ]): 
124-                  if   "dependent_on_temp_event"   not   in   step [ 0 ][ "response" ]: 
125-                      steps . append ( step ) 
129+             independent_steps   =  [] 
130+             dependency_generators   =  [] 
131+             dependency_consumers   =  [] 
126132
127133            for  step  in  copy .deepcopy (self .module_content ["payloads" ][index ]["steps" ]):
128-                 if  (
129-                     "dependent_on_temp_event"  in  step [0 ]["response" ]
130-                     and  "save_to_temp_events_only"  in  step [0 ]["response" ]
131-                 ):
132-                     steps .append (step )
134+                 step_response  =  step [0 ]["response" ] if  step  and  len (step ) >  0  else  {}
135+ 
136+                 has_dependency  =  "dependent_on_temp_event"  in  step_response 
137+                 generates_dependency  =  "save_to_temp_events_only"  in  step_response 
138+ 
139+                 if  not  has_dependency  and  not  generates_dependency :
140+                     independent_steps .append (step )
141+                 elif  generates_dependency  and  not  has_dependency :
142+                     dependency_generators .append (step )
143+                 elif  generates_dependency  and  has_dependency :
144+                     dependency_generators .append (step )  # Generator first 
145+                 elif  has_dependency  and  not  generates_dependency :
146+                     dependency_consumers .append (step )
147+                 else :
148+                     independent_steps .append (step )  # Fallback 
133149
134-             for  step  in  copy .deepcopy (self .module_content ["payloads" ][index ]["steps" ]):
135-                 if  (
136-                     "dependent_on_temp_event"  in  step [0 ]["response" ]
137-                     and  "save_to_temp_events_only"  not  in step [0 ]["response" ]
138-                 ):
139-                     steps .append (step )
140-             self .module_content ["payloads" ][index ]["steps" ] =  steps 
150+             # Combine in optimal order 
151+             sorted_steps  =  independent_steps  +  dependency_generators  +  dependency_consumers 
152+             self .module_content ["payloads" ][index ]["steps" ] =  sorted_steps 
153+ 
154+             log .verbose_info (
155+                 f"Sorted { len (sorted_steps )}  
156+                 f"{ len (independent_steps )}  
157+                 f"{ len (dependency_generators )}  
158+                 f"{ len (dependency_consumers )}  
159+             )
141160
142161    def  start (self ):
143162        active_threads  =  []
@@ -158,11 +177,14 @@ def start(self):
158177                importlib .import_module (f"nettacker.core.lib.{ library .lower ()}  ),
159178                f"{ library .capitalize ()}  ,
160179            )()
180+ 
161181            for  step  in  payload ["steps" ]:
162182                for  sub_step  in  step :
163-                     thread  =  Thread (
164-                         target = engine .run ,
165-                         args = (
183+                     # Try to use shared thread pool if available, otherwise use local threads 
184+                     if  thread_pool  and  hasattr (thread_pool , "submit_task" ):
185+                         # Submit to shared thread pool 
186+                         thread_pool .submit_task (
187+                             engine .run ,
166188                            sub_step ,
167189                            self .module_name ,
168190                            self .target ,
@@ -173,9 +195,35 @@ def start(self):
173195                            self .total_module_thread_number ,
174196                            request_number_counter ,
175197                            total_number_of_requests ,
176-                         ),
177-                     )
178-                     thread .name  =  f"{ self .target } { self .module_name } { sub_step }  
198+                         )
199+                     else :
200+                         # Use local thread (fallback to original behavior) 
201+                         thread  =  Thread (
202+                             target = engine .run ,
203+                             args = (
204+                                 sub_step ,
205+                                 self .module_name ,
206+                                 self .target ,
207+                                 self .scan_id ,
208+                                 self .module_inputs ,
209+                                 self .process_number ,
210+                                 self .module_thread_number ,
211+                                 self .total_module_thread_number ,
212+                                 request_number_counter ,
213+                                 total_number_of_requests ,
214+                             ),
215+                         )
216+                         thread .name  =  f"{ self .target } { self .module_name } { sub_step }  
217+                         thread .start ()
218+                         active_threads .append (thread )
219+ 
220+                         # Manage local thread pool size 
221+                         wait_for_threads_to_finish (
222+                             active_threads ,
223+                             maximum = self .module_inputs ["thread_per_host" ],
224+                             terminable = True ,
225+                         )
226+ 
179227                    request_number_counter  +=  1 
180228                    log .verbose_event_info (
181229                        _ ("sending_module_request" ).format (
@@ -188,13 +236,8 @@ def start(self):
188236                            total_number_of_requests ,
189237                        )
190238                    )
191-                     thread .start ()
192239                    time .sleep (self .module_inputs ["time_sleep_between_requests" ])
193-                     active_threads .append (thread )
194-                     wait_for_threads_to_finish (
195-                         active_threads ,
196-                         maximum = self .module_inputs ["thread_per_host" ],
197-                         terminable = True ,
198-                     )
199240
200-         wait_for_threads_to_finish (active_threads , maximum = None , terminable = True )
241+         # Wait for any remaining local threads to finish 
242+         if  active_threads :
243+             wait_for_threads_to_finish (active_threads , maximum = None , terminable = True )
0 commit comments