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);


Reply via email to