preparing TCP and UPD pingers to be terminatable during the scan, moving socket closing their close() methods

This commit is contained in:
Anton Keks 2012-12-15 20:26:58 +02:00
parent 2cb8cfc93b
commit d6c858137e
6 changed files with 73 additions and 63 deletions

View File

@ -26,18 +26,18 @@ public class Scanner {
/**
* Executes all registered fetchers for the current IP address.
* @param scanningSubject containing the IP address to scan
* @param subject containing the IP address to scan
* @param result where the results are injected
*/
public void scan(ScanningSubject scanningSubject, ScanningResult result) {
public void scan(ScanningSubject subject, ScanningResult result) {
// populate results
int fetcherIndex = 0;
boolean isScanningInterrupted = false;
for (Fetcher fetcher : fetcherRegistry.getSelectedFetchers()) {
Object value = NotScanned.VALUE;
if (!scanningSubject.isAddressAborted() && !isScanningInterrupted) {
if (!subject.isAddressAborted() && !isScanningInterrupted) {
// run the fetcher
value = fetcher.scan(scanningSubject);
value = fetcher.scan(subject);
// check if scanning was interrupted
isScanningInterrupted = Thread.currentThread().isInterrupted();
if (value == null)
@ -48,7 +48,7 @@ public class Scanner {
fetcherIndex++;
}
result.setType(scanningSubject.getResultType());
result.setType(subject.getResultType());
}
/**

View File

@ -5,20 +5,22 @@
*/
package net.azib.ipscan.core;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import net.azib.ipscan.config.ScannerConfig;
import net.azib.ipscan.core.state.ScanningState;
import net.azib.ipscan.core.state.StateMachine;
import net.azib.ipscan.core.state.StateTransitionListener;
import net.azib.ipscan.core.state.StateMachine.Transition;
import net.azib.ipscan.core.state.StateTransitionListener;
import net.azib.ipscan.feeders.Feeder;
import net.azib.ipscan.util.InetAddressUtils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.concurrent.TimeUnit.*;
import static net.azib.ipscan.core.state.ScanningState.*;
/**
* Main scanning thread that spawns other threads.
*
@ -78,7 +80,7 @@ public class ScannerDispatcherThread extends Thread implements ThreadFactory, St
try {
ScanningSubject subject = null;
while(feeder.hasNext() && stateMachine.inState(ScanningState.SCANNING)) {
while(feeder.hasNext() && stateMachine.inState(SCANNING)) {
// make a small delay between thread creation
Thread.sleep(config.threadDelay);
@ -121,7 +123,7 @@ public class ScannerDispatcherThread extends Thread implements ThreadFactory, St
try {
// now wait for all threads, which are still running
while (!threadPool.awaitTermination(UI_UPDATE_INTERVAL_MS, TimeUnit.MILLISECONDS)) {
while (!threadPool.awaitTermination(UI_UPDATE_INTERVAL_MS, MILLISECONDS)) {
progressCallback.updateProgress(null, numActiveThreads.intValue(), 100);
}
}
@ -145,7 +147,7 @@ public class ScannerDispatcherThread extends Thread implements ThreadFactory, St
* Currently used to kill all running threads if user says so.
*/
public void transitionTo(ScanningState state, Transition transition) {
if (state == ScanningState.KILLING) {
if (state == KILLING) {
// try to interrupt all threads if we get to killing state
threadGroup.interrupt();
}

View File

@ -5,15 +5,17 @@
*/
package net.azib.ipscan.core.net;
import net.azib.ipscan.core.ScanningSubject;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.azib.ipscan.core.ScanningSubject;
import static java.util.logging.Level.*;
import static net.azib.ipscan.util.IOUtils.*;
/**
* TCP Pinger. Uses a TCP port to ping, doesn't require root privileges.
@ -21,15 +23,15 @@ import net.azib.ipscan.core.ScanningSubject;
* @author Anton Keks
*/
public class TCPPinger implements Pinger {
static final Logger LOG = Logger.getLogger(TCPPinger.class.getName());
// try different ports in sequence, starting with 80 (which is most probably not filtered)
private static final int[] PROBE_TCP_PORTS = {80, 80, 443, 8080, 22, 7};
private int timeout;
public TCPPinger(int timeout) {
private Socket socket;
private int timeout;
public TCPPinger(int timeout) {
// use increased timeout, because TCP connect() produces more packets (roundtrips)
this.timeout = timeout + timeout/2;
}
@ -39,7 +41,7 @@ public class TCPPinger implements Pinger {
int workingPort = -1;
for (int i = 0; i < count && !Thread.currentThread().isInterrupted(); i++) {
Socket socket = new Socket();
socket = new Socket();
long startTime = System.currentTimeMillis();
try {
// cycle through different ports until a working one is found
@ -52,7 +54,7 @@ public class TCPPinger implements Pinger {
// set some optimization options
socket.setReuseAddress(true);
socket.setReceiveBufferSize(32);
socket.connect(new InetSocketAddress(subject.getAddress(), probePort), timeout);
socket.connect(new InetSocketAddress(subject.getAddress(), probePort), timeout);
if (socket.isConnected()) {
// it worked - success
success(result, startTime);
@ -60,7 +62,7 @@ public class TCPPinger implements Pinger {
workingPort = probePort;
}
}
catch (SocketTimeoutException e) {
catch (SocketTimeoutException ignore) {
}
catch (NoRouteToHostException e) {
// this means that the host is down
@ -82,14 +84,11 @@ public class TCPPinger implements Pinger {
}
else {
// something unknown
LOG.log(Level.FINER, subject.toString(), e);
LOG.log(FINER, subject.toString(), e);
}
}
finally {
try {
socket.close();
}
catch (Exception e) {}
closeQuietly(socket);
}
}
@ -103,6 +102,6 @@ public class TCPPinger implements Pinger {
}
public void close() throws IOException {
// nothing to do here
closeQuietly(socket);
}
}

View File

@ -5,17 +5,14 @@
*/
package net.azib.ipscan.core.net;
import net.azib.ipscan.core.ScanningSubject;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.NoRouteToHostException;
import java.net.PortUnreachableException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.logging.Level;
import java.net.*;
import java.util.logging.Logger;
import net.azib.ipscan.core.ScanningSubject;
import static java.util.logging.Level.*;
import static net.azib.ipscan.util.IOUtils.*;
/**
* UDP Pinger. Uses an UDP port to ping, doesn't require root privileges.
@ -23,21 +20,21 @@ import net.azib.ipscan.core.ScanningSubject;
* @author Anton Keks
*/
public class UDPPinger implements Pinger {
static final Logger LOG = Logger.getLogger(UDPPinger.class.getName());
private static final int PROBE_UDP_PORT = 33381;
private int timeout;
public UDPPinger(int timeout) {
private DatagramSocket socket;
private int timeout;
public UDPPinger(int timeout) {
this.timeout = timeout;
}
public PingResult ping(ScanningSubject subject, int count) throws IOException {
PingResult result = new PingResult(subject.getAddress());
DatagramSocket socket = new DatagramSocket();
socket = new DatagramSocket();
socket.setSoTimeout(timeout);
socket.connect(subject.getAddress(), PROBE_UDP_PORT);
@ -51,7 +48,7 @@ public class UDPPinger implements Pinger {
catch (PortUnreachableException e) {
result.addReply(System.currentTimeMillis()-startTime);
}
catch (SocketTimeoutException e) {
catch (SocketTimeoutException ignore) {
}
catch (NoRouteToHostException e) {
// this means that the host is down
@ -64,16 +61,13 @@ public class UDPPinger implements Pinger {
}
}
catch (IOException e) {
LOG.log(Level.FINER, subject.toString(), e);
LOG.log(FINER, subject.toString(), e);
}
}
socket.close();
return result;
}
public void close() throws IOException {
// nothing to do here
}
closeQuietly(socket);
}
}

View File

@ -4,20 +4,20 @@
*/
package net.azib.ipscan.fetchers;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.azib.ipscan.config.LoggerFactory;
import net.azib.ipscan.config.ScannerConfig;
import net.azib.ipscan.core.ScanningSubject;
import net.azib.ipscan.core.ScanningResult.ResultType;
import net.azib.ipscan.core.ScanningSubject;
import net.azib.ipscan.core.net.PingResult;
import net.azib.ipscan.core.net.Pinger;
import net.azib.ipscan.core.net.PingerRegistry;
import net.azib.ipscan.core.values.IntegerWithUnit;
import net.azib.ipscan.gui.fetchers.PingFetcherPrefs;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* PingFetcher is able to ping IP addresses.
* It returns the average round trip time of all pings sent.
@ -95,15 +95,11 @@ public class PingFetcher extends AbstractFetcher {
public void cleanup() {
try {
if (pinger != null) {
pinger.close();
}
if (pinger != null) pinger.close();
}
catch (IOException e) {
throw new FetcherException(e);
}
pinger = null;
}
}

View File

@ -0,0 +1,19 @@
package net.azib.ipscan.util;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.Socket;
public class IOUtils {
public static void closeQuietly(Socket socket) {
try {
if (socket != null) socket.close();
}
catch (IOException ignore) {
}
}
public static void closeQuietly(DatagramSocket socket) {
if (socket != null) socket.close();
}
}