From 50bda941adfb105915c8d5d0fb30f1fdb29e5c02 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Mon, 5 Jul 2010 16:03:13 +0000
Subject: [PATCH] make most classes package local; stub out a session destroy
 message; javadoc

---
 .../i2p/router/transport/udp/ACKBitfield.java |  2 +-
 .../i2p/router/transport/udp/ACKSender.java   |  2 +-
 .../router/transport/udp/DummyThrottle.java   |  2 +-
 .../transport/udp/EstablishmentManager.java   |  2 +-
 .../transport/udp/InboundEstablishState.java  |  2 +-
 .../udp/InboundMessageFragments.java          |  2 +-
 .../transport/udp/InboundMessageState.java    |  2 +-
 .../transport/udp/IntroductionManager.java    |  2 +-
 .../router/transport/udp/MessageQueue.java    |  2 +-
 .../router/transport/udp/MessageReceiver.java |  2 +-
 .../transport/udp/OutboundEstablishState.java |  2 +-
 .../udp/OutboundMessageFragments.java         |  2 +-
 .../transport/udp/OutboundMessageState.java   |  2 +-
 .../transport/udp/OutboundRefiller.java       |  2 +-
 .../router/transport/udp/PacketBuilder.java   | 91 ++++++++++++++++++-
 .../router/transport/udp/PacketHandler.java   |  6 +-
 .../router/transport/udp/PacketPusher.java    |  2 +-
 .../i2p/router/transport/udp/PeerState.java   |  2 +-
 .../TimedWeightedPriorityMessageQueue.java    |  2 +-
 .../i2p/router/transport/udp/UDPEndpoint.java |  2 +-
 .../i2p/router/transport/udp/UDPPacket.java   |  4 +-
 .../router/transport/udp/UDPPacketReader.java |  7 +-
 .../i2p/router/transport/udp/UDPReceiver.java |  2 +-
 .../i2p/router/transport/udp/UDPSender.java   |  2 +-
 24 files changed, 121 insertions(+), 27 deletions(-)

diff --git a/router/java/src/net/i2p/router/transport/udp/ACKBitfield.java b/router/java/src/net/i2p/router/transport/udp/ACKBitfield.java
index f0201c4e8a..c8b7c96309 100644
--- a/router/java/src/net/i2p/router/transport/udp/ACKBitfield.java
+++ b/router/java/src/net/i2p/router/transport/udp/ACKBitfield.java
@@ -4,7 +4,7 @@ package net.i2p.router.transport.udp;
  * Generic means of SACK/NACK transmission for partially or fully 
  * received messages
  */
-public interface ACKBitfield {
+interface ACKBitfield {
     /** what message is this partially ACKing? */
     public long getMessageId(); 
     /** how many fragments are covered in this bitfield? */
diff --git a/router/java/src/net/i2p/router/transport/udp/ACKSender.java b/router/java/src/net/i2p/router/transport/udp/ACKSender.java
index 180232d6f2..d6035766db 100644
--- a/router/java/src/net/i2p/router/transport/udp/ACKSender.java
+++ b/router/java/src/net/i2p/router/transport/udp/ACKSender.java
@@ -15,7 +15,7 @@ import net.i2p.util.Log;
  * any outstanding ACKs.  
  *
  */
-public class ACKSender implements Runnable {
+class ACKSender implements Runnable {
     private RouterContext _context;
     private Log _log;
     private UDPTransport _transport;
diff --git a/router/java/src/net/i2p/router/transport/udp/DummyThrottle.java b/router/java/src/net/i2p/router/transport/udp/DummyThrottle.java
index 383f807c59..d2cb73934c 100644
--- a/router/java/src/net/i2p/router/transport/udp/DummyThrottle.java
+++ b/router/java/src/net/i2p/router/transport/udp/DummyThrottle.java
@@ -14,7 +14,7 @@ import net.i2p.router.OutNetMessage;
  *
  * @since 0.7.12
  */
-public class DummyThrottle implements OutboundMessageFragments.ActiveThrottle {
+class DummyThrottle implements OutboundMessageFragments.ActiveThrottle {
 
     public DummyThrottle() {
     }
diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
index 2e1fea71f4..275c200c2a 100644
--- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java
@@ -33,7 +33,7 @@ import net.i2p.util.SimpleTimer;
  * as well as to drop any failed establishment attempts.
  *
  */
-public class EstablishmentManager {
+class EstablishmentManager {
     private final RouterContext _context;
     private final Log _log;
     private final UDPTransport _transport;
diff --git a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java
index 829f62ee00..6f4f539809 100644
--- a/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java
+++ b/router/java/src/net/i2p/router/transport/udp/InboundEstablishState.java
@@ -20,7 +20,7 @@ import net.i2p.util.Log;
  * we are Bob.
  *
  */
-public class InboundEstablishState {
+class InboundEstablishState {
     private final RouterContext _context;
     private final Log _log;
     // SessionRequest message
diff --git a/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java b/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java
index ddd44b1436..bc0ddc5f5e 100644
--- a/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java
+++ b/router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java
@@ -17,7 +17,7 @@ import net.i2p.util.Log;
  * basic line of defense here).
  *
  */
-public class InboundMessageFragments /*implements UDPTransport.PartialACKSource */{
+class InboundMessageFragments /*implements UDPTransport.PartialACKSource */{
     private RouterContext _context;
     private Log _log;
     /** list of message IDs recently received, so we can ignore in flight dups */
diff --git a/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java b/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
index 3159cad873..9261dc70a3 100644
--- a/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
+++ b/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
@@ -11,7 +11,7 @@ import net.i2p.util.Log;
  * Hold the raw data fragments of an inbound message
  *
  */
-public class InboundMessageState {
+class InboundMessageState {
     private RouterContext _context;
     private Log _log;
     private long _messageId;
diff --git a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java
index 6a2707f608..c59668866b 100644
--- a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java
+++ b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java
@@ -20,7 +20,7 @@ import net.i2p.util.Log;
 /**
  *
  */
-public class IntroductionManager {
+class IntroductionManager {
     private RouterContext _context;
     private Log _log;
     private UDPTransport _transport;
diff --git a/router/java/src/net/i2p/router/transport/udp/MessageQueue.java b/router/java/src/net/i2p/router/transport/udp/MessageQueue.java
index cc38ebbafe..3d51055ca8 100644
--- a/router/java/src/net/i2p/router/transport/udp/MessageQueue.java
+++ b/router/java/src/net/i2p/router/transport/udp/MessageQueue.java
@@ -5,7 +5,7 @@ import net.i2p.router.OutNetMessage;
 /**
  * Base queue for messages not yet packetized
  */
-public interface MessageQueue {
+interface MessageQueue {
     /**
      * Get the next message, blocking until one is found or the expiration
      * reached.
diff --git a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java
index 1a95c227fe..08b6088c4f 100644
--- a/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java
+++ b/router/java/src/net/i2p/router/transport/udp/MessageReceiver.java
@@ -19,7 +19,7 @@ import net.i2p.util.Log;
  * parse 'em into I2NPMessages, and stick them on the 
  * {@link net.i2p.router.InNetMessagePool} by way of the {@link UDPTransport}.
  */
-public class MessageReceiver {
+class MessageReceiver {
     private RouterContext _context;
     private Log _log;
     private UDPTransport _transport;
diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java
index 6e3738f306..1e23a210c5 100644
--- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java
+++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java
@@ -21,7 +21,7 @@ import net.i2p.util.Log;
  * they are Bob.
  *
  */
-public class OutboundEstablishState {
+class OutboundEstablishState {
     private final RouterContext _context;
     private final Log _log;
     // SessionRequest message
diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java
index 2d4f272929..e25ab03691 100644
--- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java
+++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java
@@ -22,7 +22,7 @@ import net.i2p.util.Log;
  * message.
  *
  */
-public class OutboundMessageFragments {
+class OutboundMessageFragments {
     private RouterContext _context;
     private Log _log;
     private UDPTransport _transport;
diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java
index 877ad10b17..a545cfb062 100644
--- a/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java
+++ b/router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java
@@ -15,7 +15,7 @@ import net.i2p.util.Log;
  * Maintain the outbound fragmentation for resending
  *
  */
-public class OutboundMessageState {
+class OutboundMessageState {
     private I2PAppContext _context;
     private Log _log;
     /** may be null if we are part of the establishment */
diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java b/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java
index 841588ee45..078105a4a7 100644
--- a/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java
+++ b/router/java/src/net/i2p/router/transport/udp/OutboundRefiller.java
@@ -12,7 +12,7 @@ import net.i2p.util.Log;
  * WARNING - UNUSED since 0.6.1.11
  *
  */
-public class OutboundRefiller implements Runnable {
+class OutboundRefiller implements Runnable {
     private RouterContext _context;
     private Log _log;
     private OutboundMessageFragments _fragments;
diff --git a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java
index c0d9e22f3f..672744444e 100644
--- a/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java
+++ b/router/java/src/net/i2p/router/transport/udp/PacketBuilder.java
@@ -22,8 +22,80 @@ import net.i2p.util.Log;
  * Big ol' class to do all our packet formatting.  The UDPPackets generated are
  * fully authenticated, encrypted, and configured for delivery to the peer. 
  *
+ * The following is from udp.html on the website:
+
+<p>
+All UDP datagrams begin with a 16 byte MAC (Message Authentication Code)
+and a 16 byte IV (Initialization Vector
+followed by a variable
+size payload encrypted with the appropriate key.  The MAC used is 
+HMAC-MD5, truncated to 16 bytes, while the key is a full 32 byte AES256 
+key.  The specific construct of the MAC is the first 16 bytes from:</p>
+<pre>
+  HMAC-MD5(payload || IV || (payloadLength ^ protocolVersion), macKey)
+</pre>
+
+<p>The protocol version is currently 0.</p>
+
+<p>The payload itself is AES256/CBC encrypted with the IV and the 
+sessionKey, with replay prevention addressed within its body, 
+explained below.  The payloadLength in the MAC is a 2 byte unsigned 
+integer in 2s complement.</p>
+  
+<p>The protocolVersion is a 2 byte unsigned integer in 2s complement,
+and currently set to 0.  Peers using a different protocol version will
+not be able to communicate with this peer, though earlier versions not
+using this flag are.</p>
+
+<h2><a name="payload">Payload</a></h2>
+
+<p>Within the AES encrypted payload, there is a minimal common structure
+to the various messages - a one byte flag and a four byte sending 
+timestamp (*seconds* since the unix epoch).  The flag byte contains 
+the following bitfields:</p>
+<pre>
+  bits 0-3: payload type
+     bit 4: rekey?
+     bit 5: extended options included
+  bits 6-7: reserved
+</pre>
+
+<p>If the rekey flag is set, 64 bytes of keying material follow the 
+timestamp.  If the extended options flag is set, a one byte option 
+size value is appended to, followed by that many extended option 
+bytes, which are currently uninterpreted.</p>
+
+<p>When rekeying, the first 32 bytes of the keying material is fed 
+into a SHA256 to produce the new MAC key, and the next 32 bytes are
+fed into a SHA256 to produce the new session key, though the keys are
+not immediately used.  The other side should also reply with the 
+rekey flag set and that same keying material.  Once both sides have 
+sent and received those values, the new keys should be used and the 
+previous keys discarded.  It may be useful to keep the old keys 
+around briefly, to address packet loss and reordering.</p>
+
+<p>NOTE: Rekeying is currently unimplemented.</p>
+
+<pre>
+ Header: 37+ bytes
+ +----+----+----+----+----+----+----+----+
+ |                  MAC                  |
+ |                                       |
+ +----+----+----+----+----+----+----+----+
+ |                   IV                  |
+ |                                       |
+ +----+----+----+----+----+----+----+----+
+ |flag|        time       | (optionally  |
+ +----+----+----+----+----+              |
+ | this may have 64 byte keying material |
+ | and/or a one+N byte extended options) |
+ +---------------------------------------|
+</pre>
+
+ *
+ *
  */
-public class PacketBuilder {
+class PacketBuilder {
     private I2PAppContext _context;
     private Log _log;
     private UDPTransport _transport;
@@ -62,10 +134,16 @@ public class PacketBuilder {
         _context.statManager().createRateStat("udp.packetAuthTimeSlow", "How long it takes to encrypt and MAC a packet for sending (when its slow)", "udp", UDPTransport.RATES);
     }
     
+/****
     public UDPPacket buildPacket(OutboundMessageState state, int fragment, PeerState peer) {
         return buildPacket(state, fragment, peer, null, null);
     }
+****/
+
     /**
+     * This builds a data packet (PAYLOAD_TYPE_DATA).
+     * See the methods below for the other message types.
+     *
      * @param ackIdsRemaining list of messageIds (Long) that should be acked by this packet.  
      *                        The list itself is passed by reference, and if a messageId is
      *                        transmitted and the sender does not want the ID to be included
@@ -231,8 +309,10 @@ public class PacketBuilder {
         return packet;
     }
     
-    // We use this for keepalive purposes.
-    // It doesn't generate a reply, but that's ok.
+    /**
+     * We use this for keepalive purposes.
+     * It doesn't generate a reply, but that's ok.
+     */
     public UDPPacket buildPing(PeerState peer) {
         return buildACK(peer, Collections.EMPTY_LIST);
     }
@@ -1018,6 +1098,9 @@ public class PacketBuilder {
         return packet;
     }
     
+    /**
+     *  Sends an empty unauthenticated packet for hole punching
+     */
     public UDPPacket buildHolePunch(UDPPacketReader reader) {
         UDPPacket packet = UDPPacket.acquire(_context, false);
         byte data[] = packet.getPacket().getData();
@@ -1051,7 +1134,7 @@ public class PacketBuilder {
         return packet;
     }
     
-    private void setTo(UDPPacket packet, InetAddress ip, int port) {
+    private static void setTo(UDPPacket packet, InetAddress ip, int port) {
         packet.getPacket().setAddress(ip);
         packet.getPacket().setPort(port);
     }
diff --git a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java
index 1a35c5d195..15dc164578 100644
--- a/router/java/src/net/i2p/router/transport/udp/PacketHandler.java
+++ b/router/java/src/net/i2p/router/transport/udp/PacketHandler.java
@@ -19,7 +19,7 @@ import net.i2p.util.Log;
  * receiver's queue and pushing them as necessary.
  *
  */
-public class PacketHandler {
+class PacketHandler {
     private RouterContext _context;
     private Log _log;
     private UDPTransport _transport;
@@ -525,6 +525,10 @@ public class PacketHandler {
                     _establisher.receiveRelayResponse(from, reader);
                     _context.statManager().addRateData("udp.receivePacketSize.relayResponse", packet.getPacket().getLength(), packet.getLifetime());
                     break;
+                case UDPPacket.PAYLOAD_TYPE_SESSION_DESTROY:
+                    _state = 53;
+                    //_TODO
+                    break;
                 default:
                     _state = 52;
                     if (_log.shouldLog(Log.WARN))
diff --git a/router/java/src/net/i2p/router/transport/udp/PacketPusher.java b/router/java/src/net/i2p/router/transport/udp/PacketPusher.java
index 271e83597c..50b8d3ba78 100644
--- a/router/java/src/net/i2p/router/transport/udp/PacketPusher.java
+++ b/router/java/src/net/i2p/router/transport/udp/PacketPusher.java
@@ -9,7 +9,7 @@ import net.i2p.util.Log;
  * pool and toss 'em onto the outbound packet queue
  *
  */
-public class PacketPusher implements Runnable {
+class PacketPusher implements Runnable {
     // private RouterContext _context;
     private Log _log;
     private OutboundMessageFragments _fragments;
diff --git a/router/java/src/net/i2p/router/transport/udp/PeerState.java b/router/java/src/net/i2p/router/transport/udp/PeerState.java
index 65fb1c0147..6c1dec3e45 100644
--- a/router/java/src/net/i2p/router/transport/udp/PeerState.java
+++ b/router/java/src/net/i2p/router/transport/udp/PeerState.java
@@ -23,7 +23,7 @@ import net.i2p.util.ConcurrentHashSet;
  * Contain all of the state about a UDP connection to a peer.
  *
  */
-public class PeerState {
+class PeerState {
     private RouterContext _context;
     private Log _log;
     /**
diff --git a/router/java/src/net/i2p/router/transport/udp/TimedWeightedPriorityMessageQueue.java b/router/java/src/net/i2p/router/transport/udp/TimedWeightedPriorityMessageQueue.java
index acd0bd0b53..9721f22cce 100644
--- a/router/java/src/net/i2p/router/transport/udp/TimedWeightedPriorityMessageQueue.java
+++ b/router/java/src/net/i2p/router/transport/udp/TimedWeightedPriorityMessageQueue.java
@@ -20,7 +20,7 @@ import net.i2p.util.Log;
  * See comments in DQAT.java and mtn history ca. 2006-02-19
  *
  */
-public class TimedWeightedPriorityMessageQueue implements MessageQueue, OutboundMessageFragments.ActiveThrottle {
+class TimedWeightedPriorityMessageQueue implements MessageQueue, OutboundMessageFragments.ActiveThrottle {
     private RouterContext _context;
     private Log _log;
     /** FIFO queue of messages in a particular priority */
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
index ac9369d8eb..fc2426700e 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java
@@ -11,7 +11,7 @@ import net.i2p.util.Log;
  * Coordinate the low level datagram socket, managing the UDPSender and
  * UDPReceiver
  */
-public class UDPEndpoint {
+class UDPEndpoint {
     private RouterContext _context;
     private Log _log;
     private int _listenPort;
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java
index 5dc001e18f..1548e6036f 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPPacket.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPPacket.java
@@ -16,7 +16,7 @@ import net.i2p.util.Log;
  * of object instances to allow rapid reuse.
  *
  */
-public class UDPPacket {
+class UDPPacket {
     private I2PAppContext _context;
     private static Log _log;
     private volatile DatagramPacket _packet;
@@ -63,6 +63,8 @@ public class UDPPacket {
     public static final int PAYLOAD_TYPE_RELAY_INTRO = 5;
     public static final int PAYLOAD_TYPE_DATA = 6;
     public static final int PAYLOAD_TYPE_TEST = 7;
+    /** @since 0.8.1 */
+    public static final int PAYLOAD_TYPE_SESSION_DESTROY = 8;
     
     // various flag fields for use in the data packets
     public static final byte DATA_FLAG_EXPLICIT_ACK = (byte)(1 << 7);
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java
index 395a2fcf0e..0b65b2d47e 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPPacketReader.java
@@ -15,7 +15,7 @@ import net.i2p.util.Log;
  * elements, grab the appropriate subreader.
  *
  */
-public class UDPPacketReader {
+class UDPPacketReader {
     private I2PAppContext _context;
     private Log _log;
     private byte _message[];
@@ -125,6 +125,8 @@ public class UDPPacketReader {
                 return "Relay request packet";
             case UDPPacket.PAYLOAD_TYPE_RELAY_RESPONSE:
                 return "Relay response packet";
+            case UDPPacket.PAYLOAD_TYPE_SESSION_DESTROY:
+                return "Session destroyed packet";
             default:
                 return "Other packet type...";
         }
@@ -135,6 +137,8 @@ public class UDPPacketReader {
             buf.append(Base64.encode(_message, _payloadBeginOffset, _payloadLength));
     }
     
+    /* ------- Begin Reader Classes ------- */
+
     /** Help read the SessionRequest payload */
     public class SessionRequestReader {
         public static final int X_LENGTH = 256;
@@ -747,6 +751,7 @@ public class UDPPacketReader {
         }
     }
     
+    /* ------- End Reader Classes ------- */
     
     public static void main(String args[]) {
         I2PAppContext ctx = I2PAppContext.getGlobalContext();
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java
index 88cb207791..0a1937db10 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPReceiver.java
@@ -19,7 +19,7 @@ import net.i2p.util.SimpleTimer;
  * from the queue ASAP by a {@link PacketHandler}
  *
  */
-public class UDPReceiver {
+class UDPReceiver {
     private RouterContext _context;
     private Log _log;
     private DatagramSocket _socket;
diff --git a/router/java/src/net/i2p/router/transport/udp/UDPSender.java b/router/java/src/net/i2p/router/transport/udp/UDPSender.java
index 745b50df4b..01d10ed1c5 100644
--- a/router/java/src/net/i2p/router/transport/udp/UDPSender.java
+++ b/router/java/src/net/i2p/router/transport/udp/UDPSender.java
@@ -15,7 +15,7 @@ import net.i2p.util.Log;
  * Lowest level packet sender, pushes anything on its queue ASAP.
  *
  */
-public class UDPSender {
+class UDPSender {
     private RouterContext _context;
     private Log _log;
     private DatagramSocket _socket;
-- 
GitLab