Author: toad
Date: 2007-11-19 19:19:15 +0000 (Mon, 19 Nov 2007)
New Revision: 15845
Added:
trunk/freenet/src/freenet/io/AddressTracker.java
trunk/freenet/src/freenet/io/AddressTrackerItem.java
trunk/freenet/src/freenet/io/InetAddressAddressTrackerItem.java
trunk/freenet/src/freenet/io/PeerAddressTrackerItem.java
Modified:
trunk/freenet/src/freenet/io/comm/UdpSocketHandler.java
Log:
AddressTracker: Track time of receiving packets, number of packets received,
and the last time we know we hadn't received any, by IP and Peer (IP:port).
Infrastructure for port forward detection.
Added: trunk/freenet/src/freenet/io/AddressTracker.java
===================================================================
--- trunk/freenet/src/freenet/io/AddressTracker.java
(rev 0)
+++ trunk/freenet/src/freenet/io/AddressTracker.java 2007-11-19 19:19:15 UTC
(rev 15845)
@@ -0,0 +1,89 @@
+/* Copyright 2007 Freenet Project Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package freenet.io;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+
+import freenet.io.comm.Peer;
+
+/**
+ * Track packet traffic to/from specific peers and IP addresses, in order to
+ * determine whether we are open to the internet.
+ *
+ * Normally there would be one tracker per port i.e. per UdpSocketHandler.
+ * @author toad
+ */
+public class AddressTracker {
+
+ /** PeerAddressTrackerItem's by Peer */
+ private HashMap peerTrackers;
+
+ /** InetAddressAddressTrackerItem's by InetAddress */
+ private HashMap ipTrackers;
+
+ /** Maximum number of Item's of either type */
+ static final int MAX_ITEMS = 1000;
+
+ private long timeDefinitelyNoPackets;
+
+ public AddressTracker() {
+ timeDefinitelyNoPackets = System.currentTimeMillis();
+ }
+
+ public void sentPacketTo(Peer peer) {
+ packetTo(peer, true);
+ }
+
+ public void receivedPacketFrom(Peer peer) {
+ packetTo(peer, false);
+ }
+
+ void packetTo(Peer peer, boolean sent) {
+ InetAddress ip = peer.getAddress();
+ long now = System.currentTimeMillis();
+ synchronized(this) {
+ PeerAddressTrackerItem peerItem =
(PeerAddressTrackerItem) peerTrackers.get(peer);
+ if(peerItem == null) {
+ peerItem = new
PeerAddressTrackerItem(timeDefinitelyNoPackets, peer);
+ if(peerTrackers.size() > MAX_ITEMS) {
+ peerTrackers.clear();
+ ipTrackers.clear();
+ timeDefinitelyNoPackets = now;
+ }
+ peerTrackers.put(peer, peerItem);
+ }
+ if(sent)
+ peerItem.sentPacket(now);
+ else
+ peerItem.receivedPacket(now);
+ InetAddressAddressTrackerItem ipItem =
(InetAddressAddressTrackerItem) ipTrackers.get(ip);
+ if(ipItem == null) {
+ ipItem = new
InetAddressAddressTrackerItem(timeDefinitelyNoPackets, ip);
+ if(ipTrackers.size() > MAX_ITEMS) {
+ peerTrackers.clear();
+ ipTrackers.clear();
+ timeDefinitelyNoPackets = now;
+ }
+ ipTrackers.put(ip, ipItem);
+ }
+ if(sent)
+ ipItem.sentPacket(now);
+ else
+ ipItem.receivedPacket(now);
+ }
+ }
+}
Added: trunk/freenet/src/freenet/io/AddressTrackerItem.java
===================================================================
--- trunk/freenet/src/freenet/io/AddressTrackerItem.java
(rev 0)
+++ trunk/freenet/src/freenet/io/AddressTrackerItem.java 2007-11-19
19:19:15 UTC (rev 15845)
@@ -0,0 +1,94 @@
+/* Copyright 2007 Freenet Project Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package freenet.io;
+
+/**
+ * Tracks communication to/from a specific address. That address can be a
specific IP:port, a specific IP,
+ * or some completely different type of address, so we don't store it in this
class; subclasses will do.
+ * @author toad
+ */
+public class AddressTrackerItem {
+
+ /** The time at which the first packet was received from this address.
*/
+ private long timeFirstReceivedPacket;
+ /** The time at which the first packet was sent to this address. */
+ private long timeFirstSentPacket;
+ /** The earliest time, before timeFirstReceivedPacket, at which we know
for
+ * certain that there was no packet sent or received. This may be the
+ * startup time of the node, or it may be later, if we have had to
clear
+ * the tracker cache. */
+ private long timeDefinitelyNoPackets;
+ /** The time at which we received the most recent packet */
+ private long timeLastReceivedPacket;
+ /** The time at which we sent the most recent packet */
+ private long timeLastSentPacket;
+ /** The total number of packets sent to this address */
+ private long packetsSent;
+ /** The total number of packets received from this address */
+ private long packetsReceived;
+
+ public AddressTrackerItem(long timeDefinitelyNoPackets) {
+ timeFirstReceivedPacket = -1;
+ timeFirstSentPacket = -1;
+ timeLastReceivedPacket = -1;
+ timeLastSentPacket = -1;
+ packetsSent = 0;
+ packetsReceived = 0;
+ this.timeDefinitelyNoPackets = timeDefinitelyNoPackets;
+ }
+
+ public synchronized void sentPacket(long now) {
+ packetsSent++;
+ if(timeFirstSentPacket < 0)
+ timeFirstSentPacket = now;
+ timeLastSentPacket = now;
+ }
+
+ public synchronized void receivedPacket(long now) {
+ packetsReceived++;
+ if(timeFirstReceivedPacket < 0)
+ timeFirstReceivedPacket = now;
+ timeLastReceivedPacket = now;
+ }
+
+ public synchronized long firstReceivedPacket() {
+ return timeFirstReceivedPacket;
+ }
+
+ public synchronized long firstSentPacket() {
+ return timeFirstSentPacket;
+ }
+
+ public synchronized long lastReceivedPacket() {
+ return timeLastReceivedPacket;
+ }
+
+ public synchronized long lastSentPacket() {
+ return timeLastSentPacket;
+ }
+
+ public synchronized long timeDefinitelyNoPackets() {
+ return timeDefinitelyNoPackets;
+ }
+
+ public synchronized long packetsSent() {
+ return packetsSent;
+ }
+
+ public synchronized long packetsReceived() {
+ return packetsReceived;
+ }
+}
Added: trunk/freenet/src/freenet/io/InetAddressAddressTrackerItem.java
===================================================================
--- trunk/freenet/src/freenet/io/InetAddressAddressTrackerItem.java
(rev 0)
+++ trunk/freenet/src/freenet/io/InetAddressAddressTrackerItem.java
2007-11-19 19:19:15 UTC (rev 15845)
@@ -0,0 +1,29 @@
+/* Copyright 2007 Freenet Project Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package freenet.io;
+
+import java.net.InetAddress;
+
+public class InetAddressAddressTrackerItem extends AddressTrackerItem {
+
+ public InetAddressAddressTrackerItem(long timeDefinitelyNoPackets,
InetAddress addr) {
+ super(timeDefinitelyNoPackets);
+ this.addr = addr;
+ }
+
+ public final InetAddress addr;
+
+}
Added: trunk/freenet/src/freenet/io/PeerAddressTrackerItem.java
===================================================================
--- trunk/freenet/src/freenet/io/PeerAddressTrackerItem.java
(rev 0)
+++ trunk/freenet/src/freenet/io/PeerAddressTrackerItem.java 2007-11-19
19:19:15 UTC (rev 15845)
@@ -0,0 +1,29 @@
+/* Copyright 2007 Freenet Project Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+package freenet.io;
+
+import freenet.io.comm.Peer;
+
+public class PeerAddressTrackerItem extends AddressTrackerItem {
+
+ public final Peer peer;
+
+ public PeerAddressTrackerItem(long timeDefinitelyNoPackets, Peer peer) {
+ super(timeDefinitelyNoPackets);
+ this.peer = peer;
+ }
+
+}
Modified: trunk/freenet/src/freenet/io/comm/UdpSocketHandler.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/UdpSocketHandler.java 2007-11-19
19:10:52 UTC (rev 15844)
+++ trunk/freenet/src/freenet/io/comm/UdpSocketHandler.java 2007-11-19
19:19:15 UTC (rev 15845)
@@ -11,6 +11,7 @@
import org.tanukisoftware.wrapper.WrapperManager;
+import freenet.io.AddressTracker;
import freenet.io.comm.Peer.LocalAddressException;
import freenet.node.LoggingConfigHandler;
import freenet.node.Node;
@@ -23,6 +24,7 @@
private final DatagramSocket _sock;
private final InetAddress _bindTo;
+ private final AddressTracker tracker;
private IncomingPacketFilter lowLevelFilter;
/** RNG for debugging, used with _dropProbability.
* NOT CRYPTO SAFE. DO NOT USE FOR THINGS THAT NEED CRYPTO SAFE RNG!
@@ -60,6 +62,7 @@
// Only used for debugging, no need to seed from Yarrow
dropRandom = new Random();
logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ tracker = new AddressTracker();
}
/** Must be called, or we will NPE in run() */
@@ -138,6 +141,7 @@
if (gotPacket) {
long startTime = System.currentTimeMillis();
Peer peer = new Peer(packet.getAddress(),
packet.getPort());
+ tracker.receivedPacketFrom(peer);
long endTime = System.currentTimeMillis();
if(endTime - startTime > 50) {
if(endTime-startTime > 3000)
@@ -219,6 +223,7 @@
// TODO: keep?
// packet.length() is simply the size of the buffer, it knows
nothing of UDP headers
IOStatisticCollector.addInfo(address + ":" + port, 0,
blockToSend.length + UDP_HEADERS_LENGTH);
+ tracker.sentPacketTo(destination);
try {
_sock.send(packet);