@@ -14,6 +14,8 @@ use std::{
14
14
time:: Duration ,
15
15
} ;
16
16
17
+ use super :: warning;
18
+
17
19
/// The class for the scanner
18
20
/// IP is data type IpAddr and is the IP address
19
21
/// start & end is where the port scan starts and ends
@@ -26,6 +28,7 @@ pub struct Scanner {
26
28
ips : Vec < IpAddr > ,
27
29
batch_size : u16 ,
28
30
timeout : Duration ,
31
+ tries : u8 ,
29
32
greppable : bool ,
30
33
port_strategy : PortStrategy ,
31
34
accessible : bool ,
@@ -36,13 +39,20 @@ impl Scanner {
36
39
ips : & [ IpAddr ] ,
37
40
batch_size : u16 ,
38
41
timeout : Duration ,
42
+ tries : u8 ,
39
43
greppable : bool ,
40
44
port_strategy : PortStrategy ,
41
45
accessible : bool ,
42
46
) -> Self {
43
47
Self {
44
48
batch_size,
45
49
timeout,
50
+ tries : if tries == 0 {
51
+ warning ! ( "tries is 0, corrected to 1!" ) ;
52
+ 1
53
+ } else {
54
+ tries
55
+ } ,
46
56
greppable,
47
57
port_strategy,
48
58
ips : ips. iter ( ) . map ( |ip| ip. to_owned ( ) ) . collect ( ) ,
@@ -87,54 +97,72 @@ impl Scanner {
87
97
open_sockets
88
98
}
89
99
90
- /// Given a port, scan it.
100
+ /// Given a port, scan it self.tries times .
91
101
/// Turns the address into a SocketAddr
92
102
/// Deals with the <result> type
93
103
/// If it experiences error ErrorKind::Other then too many files are open and it Panics!
94
- /// ese any other error, it returns the error in Result as a string
95
- /// If no errors occur, it returns the port number in Result to signify the port is open.
104
+ /// Else any other error, it returns the error in Result as a string
105
+ /// If no errors occur, it returns the port number in Result to signify the port is open.
96
106
/// This function mainly deals with the logic of Results handling.
97
107
/// # Example
98
108
///
99
109
/// self.scan_port(10:u16)
100
110
///
101
111
/// Note: `self` must contain `self.ip`.
102
112
async fn scan_socket ( & self , socket : SocketAddr ) -> io:: Result < SocketAddr > {
103
- match self . connect ( socket) . await {
104
- Ok ( x) => {
105
- debug ! (
106
- "Connection was successful, shutting down stream {}" ,
107
- & socket
108
- ) ;
109
- match x. shutdown ( Shutdown :: Both ) {
110
- Err ( e) => debug ! ( "Shutdown stream error {}" , & e) ,
111
- _ => { }
112
- }
113
- if !self . greppable {
114
- if self . accessible {
115
- println ! ( "Open {}" , socket. to_string( ) ) ;
116
- } else {
117
- println ! ( "Open {}" , socket. to_string( ) . purple( ) ) ;
113
+ debug ! ( "self.tries: {}" , self . tries) ;
114
+ for nr_try in 1 ..=self . tries {
115
+ debug ! ( "Try number: {}" , nr_try) ;
116
+
117
+ match self . connect ( socket) . await {
118
+ Ok ( x) => {
119
+ debug ! (
120
+ "Connection was successful, shutting down stream {}" ,
121
+ & socket
122
+ ) ;
123
+ match x. shutdown ( Shutdown :: Both ) {
124
+ Err ( e) => debug ! ( "Shutdown stream error {}" , & e) ,
125
+ _ => { }
118
126
}
127
+ if !self . greppable {
128
+ if self . accessible {
129
+ println ! ( "Open {}" , socket. to_string( ) ) ;
130
+ } else {
131
+ println ! ( "Open {}" , socket. to_string( ) . purple( ) ) ;
132
+ }
133
+ }
134
+
135
+ debug ! ( "Return Ok after {} tries" , nr_try) ;
136
+ return Ok ( socket) ;
119
137
}
138
+ Err ( e) => {
139
+ let error = match e. kind ( ) {
140
+ ErrorKind :: Other => {
141
+ let error_string = e. to_string ( ) ;
142
+ if error_string. contains ( "No route to host" )
143
+ || error_string. contains ( "Network is unreachable" )
144
+ {
145
+ debug ! ( "Socket connect error: {} {}" , & e. to_string( ) , & socket) ;
146
+ Err ( io:: Error :: new ( io:: ErrorKind :: Other , e. to_string ( ) ) )
147
+ } else {
148
+ debug ! ( "Socket connect error: {} {}" , & e. to_string( ) , & socket) ;
149
+ panic ! ( "Too many open files. Please reduce batch size. The default is 5000. Try -b 2500." ) ;
150
+ }
151
+ }
152
+ _ => Err ( io:: Error :: new ( io:: ErrorKind :: Other , e. to_string ( ) ) ) ,
153
+ } ;
120
154
121
- Ok ( socket)
122
- }
123
- Err ( e) => match e. kind ( ) {
124
- ErrorKind :: Other => {
125
- if e. to_string ( ) . contains ( "No route to host" )
126
- || e. to_string ( ) . contains ( "Network is unreachable" )
127
- {
128
- debug ! ( "Socket connect error: {} {}" , & e. to_string( ) , & socket) ;
129
- Err ( io:: Error :: new ( io:: ErrorKind :: Other , e. to_string ( ) ) )
130
- } else {
131
- debug ! ( "Socket connect error: {} {}" , & e. to_string( ) , & socket) ;
132
- panic ! ( "Too many open files. Please reduce batch size. The default is 5000. Try -b 2500." ) ;
155
+ if nr_try == self . tries {
156
+ debug ! ( "Return Err after {} tries" , self . tries) ;
157
+ return error;
133
158
}
134
159
}
135
- _ => Err ( io:: Error :: new ( io:: ErrorKind :: Other , e. to_string ( ) ) ) ,
136
- } ,
160
+ } ;
137
161
}
162
+ return Err ( io:: Error :: new (
163
+ io:: ErrorKind :: Other ,
164
+ format ! ( "self.tries is {} so port scanning is not done!" , self . tries) ,
165
+ ) ) ;
138
166
}
139
167
140
168
/// Performs the connection to the socket with timeout
@@ -174,7 +202,15 @@ mod tests {
174
202
end : 1_000 ,
175
203
} ;
176
204
let strategy = PortStrategy :: pick ( Some ( range) , None , ScanOrder :: Random ) ;
177
- let scanner = Scanner :: new ( & addrs, 10 , Duration :: from_millis ( 100 ) , true , strategy, true ) ;
205
+ let scanner = Scanner :: new (
206
+ & addrs,
207
+ 10 ,
208
+ Duration :: from_millis ( 100 ) ,
209
+ 1 ,
210
+ true ,
211
+ strategy,
212
+ true ,
213
+ ) ;
178
214
block_on ( scanner. run ( ) ) ;
179
215
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
180
216
assert_eq ! ( 1 , 1 ) ;
@@ -188,7 +224,15 @@ mod tests {
188
224
end : 1_000 ,
189
225
} ;
190
226
let strategy = PortStrategy :: pick ( Some ( range) , None , ScanOrder :: Random ) ;
191
- let scanner = Scanner :: new ( & addrs, 10 , Duration :: from_millis ( 100 ) , true , strategy, true ) ;
227
+ let scanner = Scanner :: new (
228
+ & addrs,
229
+ 10 ,
230
+ Duration :: from_millis ( 100 ) ,
231
+ 1 ,
232
+ true ,
233
+ strategy,
234
+ true ,
235
+ ) ;
192
236
block_on ( scanner. run ( ) ) ;
193
237
// if the scan fails, it wouldn't be able to assert_eq! as it panicked!
194
238
assert_eq ! ( 1 , 1 ) ;
@@ -201,7 +245,15 @@ mod tests {
201
245
end : 1_000 ,
202
246
} ;
203
247
let strategy = PortStrategy :: pick ( Some ( range) , None , ScanOrder :: Random ) ;
204
- let scanner = Scanner :: new ( & addrs, 10 , Duration :: from_millis ( 100 ) , true , strategy, true ) ;
248
+ let scanner = Scanner :: new (
249
+ & addrs,
250
+ 10 ,
251
+ Duration :: from_millis ( 100 ) ,
252
+ 1 ,
253
+ true ,
254
+ strategy,
255
+ true ,
256
+ ) ;
205
257
block_on ( scanner. run ( ) ) ;
206
258
assert_eq ! ( 1 , 1 ) ;
207
259
}
@@ -213,7 +265,15 @@ mod tests {
213
265
end : 445 ,
214
266
} ;
215
267
let strategy = PortStrategy :: pick ( Some ( range) , None , ScanOrder :: Random ) ;
216
- let scanner = Scanner :: new ( & addrs, 10 , Duration :: from_millis ( 100 ) , true , strategy, true ) ;
268
+ let scanner = Scanner :: new (
269
+ & addrs,
270
+ 10 ,
271
+ Duration :: from_millis ( 100 ) ,
272
+ 1 ,
273
+ true ,
274
+ strategy,
275
+ true ,
276
+ ) ;
217
277
block_on ( scanner. run ( ) ) ;
218
278
assert_eq ! ( 1 , 1 ) ;
219
279
}
@@ -228,7 +288,15 @@ mod tests {
228
288
end : 600 ,
229
289
} ;
230
290
let strategy = PortStrategy :: pick ( Some ( range) , None , ScanOrder :: Random ) ;
231
- let scanner = Scanner :: new ( & addrs, 10 , Duration :: from_millis ( 100 ) , true , strategy, true ) ;
291
+ let scanner = Scanner :: new (
292
+ & addrs,
293
+ 10 ,
294
+ Duration :: from_millis ( 100 ) ,
295
+ 1 ,
296
+ true ,
297
+ strategy,
298
+ true ,
299
+ ) ;
232
300
block_on ( scanner. run ( ) ) ;
233
301
assert_eq ! ( 1 , 1 ) ;
234
302
}
0 commit comments