@@ -121,10 +121,24 @@ fn main() {
121121 println ! ( "Sending {} ARP requests (waiting at least {}ms, {}ms request interval)" , network_size, scan_options. timeout_ms, scan_options. interval_ms) ;
122122 }
123123
124+ let finish_sleep = Arc :: new ( AtomicBool :: new ( false ) ) ;
125+ let cloned_finish_sleep = Arc :: clone ( & finish_sleep) ;
126+
127+ ctrlc:: set_handler ( move || {
128+ cloned_finish_sleep. store ( true , Ordering :: Relaxed ) ;
129+ } ) . unwrap_or_else ( |err| {
130+ eprintln ! ( "Could not set CTRL+C handler ({})" , err) ;
131+ process:: exit ( 1 ) ;
132+ } ) ;
133+
124134 // The retry count does right now use a 'brute-force' strategy without
125135 // synchronization process with the already known hosts.
126136 for _ in 0 ..scan_options. retry_count {
127137
138+ if finish_sleep. load ( Ordering :: Relaxed ) {
139+ break ;
140+ }
141+
128142 // The random approach has one major drawback, compared with the native
129143 // network iterator exposed by 'ipnetwork': memory usage. Instead of
130144 // using a small memory footprint iterator, we have to store all IP
@@ -141,6 +155,10 @@ fn main() {
141155
142156 for ip_address in ip_addresses {
143157
158+ if finish_sleep. load ( Ordering :: Relaxed ) {
159+ break ;
160+ }
161+
144162 if let IpAddr :: V4 ( ipv4_address) = ip_address {
145163 network:: send_arp_request ( & mut tx, selected_interface, & ip_network, ipv4_address, Arc :: clone ( & scan_options) ) ;
146164 thread:: sleep ( Duration :: from_millis ( scan_options. interval_ms ) ) ;
@@ -151,7 +169,12 @@ fn main() {
151169 // Once the ARP packets are sent, the main thread will sleep for T seconds
152170 // (where T is the timeout option). After the sleep phase, the response
153171 // thread will receive a stop request through the 'timed_out' mutex.
154- thread:: sleep ( Duration :: from_millis ( scan_options. timeout_ms ) ) ;
172+ let mut sleep_ms_mount: u64 = 0 ;
173+ while finish_sleep. load ( Ordering :: Relaxed ) == false && sleep_ms_mount < scan_options. timeout_ms {
174+
175+ thread:: sleep ( Duration :: from_millis ( 500 ) ) ;
176+ sleep_ms_mount = sleep_ms_mount + 500 ;
177+ }
155178 timed_out. store ( true , Ordering :: Relaxed ) ;
156179
157180 let ( response_summary, target_details) = arp_responses. join ( ) . unwrap_or_else ( |error| {
0 commit comments