mirror of
https://github.com/angryip/ipscan.git
synced 2025-10-26 11:18:17 +00:00
can't store sockets in fields because Pinger instances are reused between threads - ThreadResourceBinder introduced instead
This commit is contained in:
parent
d6c858137e
commit
cafde6229f
@ -6,6 +6,7 @@
|
||||
package net.azib.ipscan.core.net;
|
||||
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
import net.azib.ipscan.util.ThreadResourceBinder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
@ -15,7 +16,6 @@ import java.net.SocketTimeoutException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
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.
|
||||
@ -28,7 +28,7 @@ public class TCPPinger implements Pinger {
|
||||
// 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 Socket socket;
|
||||
private ThreadResourceBinder<Socket> sockets = new ThreadResourceBinder<Socket>();
|
||||
private int timeout;
|
||||
|
||||
public TCPPinger(int timeout) {
|
||||
@ -39,9 +39,10 @@ public class TCPPinger implements Pinger {
|
||||
public PingResult ping(ScanningSubject subject, int count) throws IOException {
|
||||
PingResult result = new PingResult(subject.getAddress());
|
||||
int workingPort = -1;
|
||||
|
||||
|
||||
Socket socket;
|
||||
for (int i = 0; i < count && !Thread.currentThread().isInterrupted(); i++) {
|
||||
socket = new Socket();
|
||||
socket = sockets.bind(new Socket());
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
// cycle through different ports until a working one is found
|
||||
@ -78,7 +79,7 @@ public class TCPPinger implements Pinger {
|
||||
}
|
||||
else
|
||||
// this should result in NoRouteToHostException or ConnectException, but not all Java implementation respect that
|
||||
if (msg.contains(/*No*/"route to host") || msg.contains(/*Host is*/"down") || msg.contains(/*Network*/"unreachable")) {
|
||||
if (msg.contains(/*No*/"route to host") || msg.contains(/*Host is*/"down") || msg.contains(/*Network*/"unreachable") || msg.contains(/*Socket*/"closed")) {
|
||||
// host is down
|
||||
break;
|
||||
}
|
||||
@ -88,7 +89,7 @@ public class TCPPinger implements Pinger {
|
||||
}
|
||||
}
|
||||
finally {
|
||||
closeQuietly(socket);
|
||||
sockets.closeAndUnbind(socket);
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +103,6 @@ public class TCPPinger implements Pinger {
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
closeQuietly(socket);
|
||||
sockets.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
package net.azib.ipscan.core.net;
|
||||
|
||||
import net.azib.ipscan.core.ScanningSubject;
|
||||
import net.azib.ipscan.util.ThreadResourceBinder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
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.
|
||||
@ -24,8 +24,8 @@ public class UDPPinger implements Pinger {
|
||||
|
||||
private static final int PROBE_UDP_PORT = 33381;
|
||||
|
||||
private DatagramSocket socket;
|
||||
private int timeout;
|
||||
private ThreadResourceBinder<DatagramSocket> sockets = new ThreadResourceBinder<DatagramSocket>();
|
||||
|
||||
public UDPPinger(int timeout) {
|
||||
this.timeout = timeout;
|
||||
@ -34,7 +34,7 @@ public class UDPPinger implements Pinger {
|
||||
public PingResult ping(ScanningSubject subject, int count) throws IOException {
|
||||
PingResult result = new PingResult(subject.getAddress());
|
||||
|
||||
socket = new DatagramSocket();
|
||||
DatagramSocket socket = sockets.bind(new DatagramSocket());
|
||||
socket.setSoTimeout(timeout);
|
||||
socket.connect(subject.getAddress(), PROBE_UDP_PORT);
|
||||
|
||||
@ -68,6 +68,6 @@ public class UDPPinger implements Pinger {
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
closeQuietly(socket);
|
||||
sockets.close();
|
||||
}
|
||||
}
|
||||
|
||||
34
src/net/azib/ipscan/util/ThreadResourceBinder.java
Normal file
34
src/net/azib/ipscan/util/ThreadResourceBinder.java
Normal file
@ -0,0 +1,34 @@
|
||||
package net.azib.ipscan.util;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static net.azib.ipscan.util.IOUtils.*;
|
||||
|
||||
public class ThreadResourceBinder<T> {
|
||||
private Map<Long, T> resources = new ConcurrentHashMap<Long, T>(256);
|
||||
|
||||
public T bind(T resource) {
|
||||
resources.put(Thread.currentThread().getId(), resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
for (T resource : resources.values()) close(resource);
|
||||
resources.clear();
|
||||
}
|
||||
|
||||
private void close(T resource) {
|
||||
if (resource instanceof DatagramSocket) closeQuietly((DatagramSocket) resource);
|
||||
else if (resource instanceof Socket) closeQuietly((Socket) resource);
|
||||
else if (resource instanceof Closeable) closeQuietly((Closeable) resource);
|
||||
}
|
||||
|
||||
public void closeAndUnbind(T resource) {
|
||||
close(resource);
|
||||
resources.remove(Thread.currentThread().getId());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user