Opened 3 years ago

Closed 3 years ago

#1854 closed enhancement (fixed)

RFC: Count Total NTCP/UDP IPv4 and IPv6 Incomming Connections

Reported by: Obscuratus Owned by: zzz
Priority: minor Milestone: 0.9.28
Component: router/transport Version: 0.9.26
Keywords: Cc:
Parent Tickets:

Description

With the upcoming changes in IPv6 Peer Testing in version 0.9.27, I'd like to submit the following debugging patch as a request for consideration (RFC).

With this patch, you will be able to look at your logs for a count of incoming NTCP and UDP connections broken down by IPv4 and IPv6 (when the NTCP and UDP Transports are set to 'debug' level of logging).

I'm seeing some intermittent false positives while testing IPv6 Peer Testing. If users report issues with their IPv6 connection being firewalled, the information provided in this patch would give us some clues as to whether they are actually firewalled, or just seeing a false-positive.

The patch is not a perfect indicator of IPv6 connectivity. I see about 1/1000 UDP IPv6 incoming connections if I have recently disconnected a UDP Peer, but still have a hole punched in my firewall allowing an incoming connection.

However, I've never seen an incoming NTCP IPv6 connection when firewalled (hole punching does not work on NTCP).

I've been testing this patch for a few months, and have not seen any adverse issues or regressions.

From a4e387ddaf94ce995981bd96e1b76a1f7c140101 Mon Sep 17 00:00:00 2001
From: obscuratus <obscuratus@mail.i2p>
Date: Wed, 4 May 2016 08:49:55 -0500
Subject: i2p/router: Count Total NTCP/UDP IPv4 and IPv6 Incomming Connections.

Implement counters to track incoming IPv4 and IPv6 connections
on NTCP and UDP.  Counters can be examined by setting logging to
debug for the NTCP and UDP transports.

Signed-off-by: obscuratus <obscuratus@mail.i2p>
---
 .../src/net/i2p/router/transport/ntcp/NTCPTransport.java     | 12 ++++++++++--
 .../java/src/net/i2p/router/transport/udp/UDPTransport.java  | 11 +++++++++--
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java
index 13cba50..fede430 100644
--- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java
+++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java
@@ -86,6 +86,8 @@ public class NTCPTransport extends TransportImpl {
     private boolean _haveIPv6Address;
     private long _lastInboundIPv4;
     private long _lastInboundIPv6;
+    private long _totalInboundNTCPIPv4conn = 0;
+    private long _totalInboundNTCPIPv6conn = 0;
 
     public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
     public final static String PROP_I2NP_NTCP_PORT = "i2np.ntcp.port";
@@ -213,10 +215,16 @@ public class NTCPTransport extends TransportImpl {
         synchronized (_conLock) {
             old = _conByIdent.put(peer, con);
         }
-        if (con.isIPv6())
+        if (con.isIPv6()) {
             _lastInboundIPv6 = con.getCreated();
-        else
+            _totalInboundNTCPIPv6conn++;
+        } else {
             _lastInboundIPv4 = con.getCreated();
+            _totalInboundNTCPIPv4conn++;
+        }
+        if (_log.shouldLog(Log.DEBUG))
+            _log.debug("NTCP Incoming: IPv4: " + _totalInboundNTCPIPv4conn +
+                       "; IPv6: " + _totalInboundNTCPIPv6conn);
         return old;
     }
 
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
index 22a6e75..714491d 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
@@ -97,7 +97,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
      */
     private volatile boolean _haveIPv6Address;
     private long _lastInboundIPv6;
-    
+    private long _totalInboundUDPIPv4conn = 0;
+    private long _totalInboundUDPIPv6conn = 0;
+
     /** do we need to rebuild our external router address asap? */
     private boolean _needsRebuild;
     private final Object _rebuildLock = new Object();
@@ -772,6 +774,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
     void inboundConnectionReceived(boolean isIPv6) {
         if (isIPv6) {
             _lastInboundIPv6 = _context.clock().now();
+            _totalInboundUDPIPv6conn++;
             // former workaround for lack of IPv6 peer testing
             //if (_currentOurV6Address != null)
             //    setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK, true);
@@ -779,8 +782,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
             // Introduced connections are still inbound, this is not evidence
             // that we are not firewalled.
             // use OS clock since its an ordering thing, not a time thing
-            _lastInboundReceivedOn = System.currentTimeMillis(); 
+            _lastInboundReceivedOn = System.currentTimeMillis();
+            _totalInboundUDPIPv4conn++;
         }
+        if (_log.shouldLog(Log.DEBUG))
+            _log.debug("UDP Incoming: IPv4: " + _totalInboundUDPIPv4conn +
+                       "; IPv6: " + _totalInboundUDPIPv6conn);
     }
     
     // temp prevent multiples
-- 
2.7.3

Subtickets

Change History (3)

comment:1 Changed 3 years ago by zzz

  • Status changed from new to infoneeded_new

nack.

Using the statistics system would be much better than debug logging. With stats you get current and historical counts, and graphs. I'm sure there are already stats for incoming NTCP and SSU connections; enable full stats on /configstats, restart, and look around. Find where the createRateStat() and addRateData() calls for those are, and add separate ones for v4/v6.

Your analysis of "false positives" for SSU (and lack of them for NTCP) is correct.

comment:2 Changed 3 years ago by Obscuratus

  • Status changed from infoneeded_new to new

Yeah, you're right. Using the existing statistics system was pretty easy.

I don't know why I put off looking at it.

i2p/router: Collect Stats on Inbound Connections.

Use the statManager to collect the number of inbound IPv4 and IPv6
connections on the NTCP and UDP transports.

Signed-off-by: obscuratus <obscuratus@mail.i2p>
---
 router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java | 9 +++++++--
 router/java/src/net/i2p/router/transport/udp/UDPTransport.java   | 4 ++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java
index 13cba50..db5cad6 100644
--- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java
+++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java
@@ -150,6 +150,8 @@ public class NTCPTransport extends TransportImpl {
         //_context.statManager().createRateStat("ntcp.inboundCheckConnection", "", "ntcp", RATES);
         _context.statManager().createRateStat("ntcp.inboundEstablished", "", "ntcp", RATES);
         _context.statManager().createRateStat("ntcp.inboundEstablishedDuplicate", "", "ntcp", RATES);
+        _context.statManager().createRateStat("ntcp.inboundIPv4Conn", "Inbound IPv4 NTCP connection", "ntcp", RATES);
+        _context.statManager().createRateStat("ntcp.inboundIPv6Conn", "Inbound IPv6 NTCP connection", "ntcp", RATES);
         //_context.statManager().createRateStat("ntcp.infoMessageEnqueued", "", "ntcp", RATES);
         //_context.statManager().createRateStat("ntcp.floodInfoMessageEnqueued", "", "ntcp", RATES);
         _context.statManager().createRateStat("ntcp.invalidDH", "", "ntcp", RATES);
@@ -213,10 +215,13 @@ public class NTCPTransport extends TransportImpl {
         synchronized (_conLock) {
             old = _conByIdent.put(peer, con);
         }
-        if (con.isIPv6())
+        if (con.isIPv6()) {
             _lastInboundIPv6 = con.getCreated();
-        else
+            _context.statManager().addRateData("ntcp.inboundIPv6Conn", 1);
+        } else {
             _lastInboundIPv4 = con.getCreated();
+            _context.statManager().addRateData("ntcp.inboundIPv4Conn", 1);
+        }
         return old;
     }
 
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
index 24dfee1..eee1797 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java
@@ -291,6 +291,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
         _context.statManager().createRateStat("udp.proactiveReestablish", "How long a session was idle for when we proactively reestablished it", "udp", RATES);
         _context.statManager().createRateStat("udp.dropPeerDroplist", "How many peers currently have their packets dropped outright when a new peer is added to the list?", "udp", RATES);
         _context.statManager().createRateStat("udp.dropPeerConsecutiveFailures", "How many consecutive failed sends to a peer did we attempt before giving up and reestablishing a new session (lifetime is inactivity perood)", "udp", RATES);
+        _context.statManager().createRateStat("udp.inboundIPv4Conn", "Inbound IPv4 UDP Connection", "udp", RATES);
+        _context.statManager().createRateStat("udp.inboundIPv6Conn", "Inbound IPv4 UDP Connection", "udp", RATES);
         // following are for PacketBuider
         //_context.statManager().createRateStat("udp.packetAuthTime", "How long it takes to encrypt and MAC a packet for sending", "udp", RATES);
         //_context.statManager().createRateStat("udp.packetAuthTimeSlow", "How long it takes to encrypt and MAC a packet for sending (when its slow)", "udp", RATES);
@@ -782,6 +784,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
     void inboundConnectionReceived(boolean isIPv6) {
         if (isIPv6) {
             _lastInboundIPv6 = _context.clock().now();
+            _context.statManager().addRateData("udp.inboundIPv6Conn", 1);
             // former workaround for lack of IPv6 peer testing
             //if (_currentOurV6Address != null)
             //    setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK, true);
@@ -790,6 +793,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
             // that we are not firewalled.
             // use OS clock since its an ordering thing, not a time thing
             _lastInboundReceivedOn = System.currentTimeMillis(); 
+            _context.statManager().addRateData("udp.inboundIPv4Conn", 1);
         }
     }
     
-- 
2.7.3

comment:3 Changed 3 years ago by zzz

  • Milestone changed from undecided to 0.9.28
  • Resolution set to fixed
  • Status changed from new to closed

In 7bca246c8494c50a81c21cbce5dc69fa93f27eea 0.9.27-8
thank you

Note: See TracTickets for help on using tickets.