net.i2p.router.tunnel
Class TunnelDispatcher
java.lang.Object
net.i2p.router.tunnel.TunnelDispatcher
- All Implemented Interfaces:
- Service
public class TunnelDispatcher
- extends java.lang.Object
- implements Service
Handle the actual processing and forwarding of messages through the
various tunnels.
Method Summary |
void |
dispatch(TunnelDataMessage msg,
Hash recvFrom)
We are participating in a tunnel (perhaps we're even the endpoint), so
take the message and do what it says. |
void |
dispatch(TunnelGatewayMessage msg)
We are the inbound tunnel gateway, so encrypt it as necessary and forward
it on. |
void |
dispatchOutbound(I2NPMessage msg,
TunnelId outboundTunnel,
Hash targetPeer)
We are the outbound tunnel gateway (we created it), so wrap up this message
with instructions to be forwarded to the targetPeer when it reaches the
endpoint. |
void |
dispatchOutbound(I2NPMessage msg,
TunnelId outboundTunnel,
TunnelId targetTunnel,
Hash targetPeer)
We are the outbound tunnel gateway (we created it), so wrap up this message
with instructions to be forwarded to the targetTunnel on the targetPeer when
it reaches the endpoint. |
long |
getLastParticipatingExpiration()
what is the date/time on which the last non-locally-created tunnel expires? |
int |
getParticipatingCount()
|
void |
joinInbound(TunnelCreatorConfig cfg)
We are the inbound endpoint - we created this tunnel |
void |
joinInboundGateway(HopConfig cfg)
We are the inbound gateway in this tunnel, and did not create it |
void |
joinOutbound(TunnelCreatorConfig cfg)
We are the outbound gateway - we created this tunnel |
void |
joinOutboundEndpoint(HopConfig cfg)
We are the outbound endpoint in this tunnel, and did not create it |
void |
joinParticipant(HopConfig cfg)
We are a participant in this tunnel, but not as the endpoint or gateway |
java.util.List<HopConfig> |
listParticipatingTunnels()
|
void |
remove(HopConfig cfg)
No longer participate in the tunnel that someone asked us to be a member of |
void |
remove(TunnelCreatorConfig cfg)
We no longer want to participate in this tunnel that we created |
void |
renderStatusHTML(java.io.Writer out)
Deprecated. moved to router console |
void |
restart()
Perform a soft restart. |
boolean |
shouldDropParticipatingMessage(java.lang.String type,
int length)
Implement random early discard (RED) to enforce the share bandwidth limit. |
void |
shutdown()
Instruct the service that the router is shutting down and that it should do
whatever is necessary to go down gracefully. |
void |
startup()
public void dropBiggestParticipating() {
List partTunnels = listParticipatingTunnels();
if ((partTunnels == null) || (partTunnels.isEmpty())) {
if (_log.shouldLog(Log.ERROR))
_log.error("Not dropping tunnel, since partTunnels was null or had 0 items!");
return;
}
long periodWithoutDrop = _context.clock().now() - _lastDropTime;
if (periodWithoutDrop < DROP_BASE_INTERVAL) {
if (_log.shouldLog(Log.WARN))
_log.warn("Not dropping tunnel, since last drop was " + periodWithoutDrop + " ms ago!");
return;
}
HopConfig biggest = null;
HopConfig current = null;
long biggestMessages = 0;
long biggestAge = -1;
double biggestRate = 0;
for (int i=0; i 20) && ((biggest == null) || (currentRate > biggestRate))) {
// Update our profile of the biggest
biggest = current;
biggestMessages = currentMessages;
biggestAge = currentAge;
biggestRate = currentRate;
}
}
if (biggest == null) {
if (_log.shouldLog(Log.ERROR))
_log.error("Not dropping tunnel, since no suitable tunnel was found.");
return;
}
if (_log.shouldLog(Log.WARN))
_log.warn("Dropping tunnel with " + biggestRate + " messages/s and " + biggestMessages +
" messages, last drop was " + (periodWithoutDrop / 1000) + " s ago.");
remove(biggest);
_lastDropTime = _context.clock().now() + _context.random().nextInt(DROP_RANDOM_BOOST);
} |
void |
updateParticipatingStats(int ms)
Generate a current estimate of usage per-participating-tunnel lifetime. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
TunnelDispatcher
public TunnelDispatcher(RouterContext ctx)
- Creates a new instance of TunnelDispatcher
joinOutbound
public void joinOutbound(TunnelCreatorConfig cfg)
- We are the outbound gateway - we created this tunnel
joinInbound
public void joinInbound(TunnelCreatorConfig cfg)
- We are the inbound endpoint - we created this tunnel
joinParticipant
public void joinParticipant(HopConfig cfg)
- We are a participant in this tunnel, but not as the endpoint or gateway
joinOutboundEndpoint
public void joinOutboundEndpoint(HopConfig cfg)
- We are the outbound endpoint in this tunnel, and did not create it
joinInboundGateway
public void joinInboundGateway(HopConfig cfg)
- We are the inbound gateway in this tunnel, and did not create it
getParticipatingCount
public int getParticipatingCount()
getLastParticipatingExpiration
public long getLastParticipatingExpiration()
- what is the date/time on which the last non-locally-created tunnel expires?
remove
public void remove(TunnelCreatorConfig cfg)
- We no longer want to participate in this tunnel that we created
remove
public void remove(HopConfig cfg)
- No longer participate in the tunnel that someone asked us to be a member of
dispatch
public void dispatch(TunnelDataMessage msg,
Hash recvFrom)
- We are participating in a tunnel (perhaps we're even the endpoint), so
take the message and do what it says. If there are later hops, that
means encrypt a layer and forward it on. If there aren't later hops,
how we handle it depends upon whether we created it or not. If we didn't,
simply honor the instructions. If we did, unwrap all the layers of
encryption and honor those instructions (within reason).
dispatch
public void dispatch(TunnelGatewayMessage msg)
- We are the inbound tunnel gateway, so encrypt it as necessary and forward
it on.
dispatchOutbound
public void dispatchOutbound(I2NPMessage msg,
TunnelId outboundTunnel,
Hash targetPeer)
- We are the outbound tunnel gateway (we created it), so wrap up this message
with instructions to be forwarded to the targetPeer when it reaches the
endpoint.
- Parameters:
msg
- raw message to deliver to the target peeroutboundTunnel
- tunnel to send the message outtargetPeer
- peer to receive the message
dispatchOutbound
public void dispatchOutbound(I2NPMessage msg,
TunnelId outboundTunnel,
TunnelId targetTunnel,
Hash targetPeer)
- We are the outbound tunnel gateway (we created it), so wrap up this message
with instructions to be forwarded to the targetTunnel on the targetPeer when
it reaches the endpoint.
- Parameters:
msg
- raw message to deliver to the targetTunnel on the targetPeeroutboundTunnel
- tunnel to send the message outtargetTunnel
- tunnel on the targetPeer to deliver the message totargetPeer
- gateway to the tunnel to receive the message
listParticipatingTunnels
public java.util.List<HopConfig> listParticipatingTunnels()
updateParticipatingStats
public void updateParticipatingStats(int ms)
- Generate a current estimate of usage per-participating-tunnel lifetime.
The router code calls this every 'ms' millisecs.
This is better than waiting until the tunnel expires to update the rate,
as we want this to be current because it's an important part of
the throttle code.
Stay a little conservative by taking the counts only for tunnels 1-10m old
and computing the average from that.
shouldDropParticipatingMessage
public boolean shouldDropParticipatingMessage(java.lang.String type,
int length)
- Implement random early discard (RED) to enforce the share bandwidth limit.
For now, this does not enforce the available bandwidth,
we leave that to Throttle.
This is similar to the code in ../RouterThrottleImpl.java
We drop in proportion to how far over the limit we are.
Perhaps an exponential function would be better?
The drop probability is adjusted for the size of the message.
At this stage, participants and IBGWs see a standard 1024 byte message.
OBEPs however may see a wide variety of sizes.
Network-wise, it's most efficient to drop OBEP messages, because they
are unfragmented and we know their size. Therefore we drop the big ones
and we drop a single wrapped I2CP message, not a fragment of one or more messages.
Also, the OBEP is the earliest identifiable hop in the message's path
(a plain participant could be earlier or later, but on average is later)
- Parameters:
type
- message hop location and typelength
- the length of the message
startup
public void startup()
- public void dropBiggestParticipating() {
List partTunnels = listParticipatingTunnels();
if ((partTunnels == null) || (partTunnels.isEmpty())) {
if (_log.shouldLog(Log.ERROR))
_log.error("Not dropping tunnel, since partTunnels was null or had 0 items!");
return;
}
long periodWithoutDrop = _context.clock().now() - _lastDropTime;
if (periodWithoutDrop < DROP_BASE_INTERVAL) {
if (_log.shouldLog(Log.WARN))
_log.warn("Not dropping tunnel, since last drop was " + periodWithoutDrop + " ms ago!");
return;
}
HopConfig biggest = null;
HopConfig current = null;
long biggestMessages = 0;
long biggestAge = -1;
double biggestRate = 0;
for (int i=0; i 20) && ((biggest == null) || (currentRate > biggestRate))) {
// Update our profile of the biggest
biggest = current;
biggestMessages = currentMessages;
biggestAge = currentAge;
biggestRate = currentRate;
}
}
if (biggest == null) {
if (_log.shouldLog(Log.ERROR))
_log.error("Not dropping tunnel, since no suitable tunnel was found.");
return;
}
if (_log.shouldLog(Log.WARN))
_log.warn("Dropping tunnel with " + biggestRate + " messages/s and " + biggestMessages +
" messages, last drop was " + (periodWithoutDrop / 1000) + " s ago.");
remove(biggest);
_lastDropTime = _context.clock().now() + _context.random().nextInt(DROP_RANDOM_BOOST);
}
- Specified by:
startup
in interface Service
shutdown
public void shutdown()
- Description copied from interface:
Service
- Instruct the service that the router is shutting down and that it should do
whatever is necessary to go down gracefully. It should not depend on other
components at this point. This call DOES block.
- Specified by:
shutdown
in interface Service
restart
public void restart()
- Description copied from interface:
Service
- Perform a soft restart.
- Specified by:
restart
in interface Service
renderStatusHTML
public void renderStatusHTML(java.io.Writer out)
throws java.io.IOException
- Deprecated. moved to router console
- Specified by:
renderStatusHTML
in interface Service
- Throws:
java.io.IOException