net.i2p.router.transport.udp
Class UDPTransport

java.lang.Object
  extended by net.i2p.router.transport.TransportImpl
      extended by net.i2p.router.transport.udp.UDPTransport
All Implemented Interfaces:
Transport, TimedWeightedPriorityMessageQueue.FailedListener

public class UDPTransport
extends TransportImpl
implements TimedWeightedPriorityMessageQueue.FailedListener

The SSU transport


Nested Class Summary
 
Nested classes/interfaces inherited from interface net.i2p.router.transport.Transport
Transport.AddressSource
 
Field Summary
static int DEFAULT_COST
           
static int DEFAULT_INTERNAL_PORT
          Deprecated. unused
static String DEFAULT_SOURCES
           
static int EXPIRE_TIMEOUT
           
static int MIN_EXPIRE_TIMEOUT
           
static String PROP_ALLOW_DIRECT
          do we allow direct SSU connections, sans introducers?
static String PROP_BIND_INTERFACE
          this is rarely if ever used, default is to bind to wildcard address
static String PROP_EXTERNAL_HOST
          define this to explicitly set an external IP address
static String PROP_EXTERNAL_PORT
          define this to explicitly set an external port
static String PROP_FORCE_INTRODUCERS
          do we require introducers, regardless of our status?
static String PROP_INTERNAL_PORT
           
static String PROP_IP
          remember IP changes
static String PROP_IP_CHANGE
           
static String PROP_LAPTOP_MODE
           
static String PROP_PREFER_UDP
          If i2np.udp.preferred is set to "always", the UDP bids will always be under the bid from the TCP transport - even if a TCP connection already exists.
static String PROP_SOURCES
          allowed sources of address updates
static int PUBLIC_RELAY_COUNT
          how many relays offered to us will we use at a time?
(package private) static long[] RATES
           
static String STYLE
           
 
Fields inherited from class net.i2p.router.transport.TransportImpl
_context, _currentAddresses, ADJUST_COST, CONGESTION_COST_ADJUSTMENT
 
Constructor Summary
UDPTransport(RouterContext ctx, DHSessionKeyBuilder.Factory dh)
           
 
Method Summary
(package private)  boolean addRemotePeerState(PeerState peer)
          add the peer info, returning true if it went in properly, false if it was rejected (causes include peer ident already connected, or no remote host info known
 boolean allowConnection()
           
(package private)  boolean allowLocal()
          Are we allowed to connect to local addresses?
 TransportBid bid(RouterInfo toAddress, long dataSize)
           
(package private)  boolean canIntroduce()
          For EstablishmentManager
(package private)  void changePeerPort(PeerState peer, int newPort)
          Remove and add to peersByRemoteHost map
 int countActivePeers()
          How many peers are we currently connected to, that we have sent a message to or received a message from in the last five minutes.
 int countActiveSendPeers()
          How many peers are we currently connected to, that we have sent a message to in the last minute.
 int countPeers()
          How many peers are we connected to?
(package private)  void dropPeer(Hash peer, boolean shouldBanlist, String why)
          This does not send a session destroy, caller must do that if desired.
(package private)  void dropPeer(PeerState peer, boolean shouldBanlist, String why)
          This does not send a session destroy, caller must do that if desired.
(package private)  void externalAddressReceived(Hash from, byte[] ourIP, int ourPort)
          Someone we tried to contact gave us what they think our IP address is.
 void externalAddressReceived(Transport.AddressSource source, byte[] ip, int port)
          From config, UPnP, local i/f, ...
 void fail(UDPEndpoint endpoint)
          The endpoint has failed.
 void failed(OutboundMessageState msg)
           
(package private)  void failed(OutboundMessageState msg, boolean allowPeerFailure)
           
 void failed(OutNetMessage msg, String reason)
           
 void forwardPortStatus(byte[] ip, int port, int externalPort, boolean success, String reason)
          Callback from UPnP.
 Vector<Long> getClockSkews()
          Return our peer clock skews on this transport.
(package private)  DHSessionKeyBuilder getDHBuilder()
           
(package private)  DHSessionKeyBuilder.Factory getDHFactory()
           
(package private)  EstablishmentManager getEstablisher()
          For IntroductionManager
(package private)  byte[] getExternalIP()
          IPv4 only
(package private)  int getExternalPort(boolean ipv6)
           
(package private)  SessionKey getIntroKey()
          Introduction key that people should use to contact us
(package private)  int getMTU(boolean ipv6)
          The MTU for the socket interface.
(package private)  PacketHandler getPacketHandler()
           
(package private)  String getPacketHandlerStatus()
           
(package private)  PeerState getPeerState(Hash remotePeer)
          get the state for the peer with the given ident, or null if no state exists
(package private)  PeerState getPeerState(RemoteHostId hostInfo)
          get the state for the peer at the given remote host/port, or null if no state exists
(package private)  List<PeerState> getPeerStatesByIP(RemoteHostId hostInfo)
          Get the states for all peers at the given remote host, ignoring port.
 CommSystemFacade.Status getReachabilityStatus()
          Previously returned short, now enum as of 0.9.20
 int getRequestedPort()
          The current or configured internal IPv4 port.
 String getStyle()
          The unique identity of this Transport
(package private)  RouterAddress getTargetAddress(RouterInfo target)
          Get first available address we can use.
(package private)  void inboundConnectionReceived(boolean isIPv6)
           
 boolean introducersRequired()
          Do we require introducers?
 boolean isBacklogged(Hash dest)
           
 boolean isEstablished(Hash dest)
           
(package private)  boolean isInDropList(RemoteHostId peer)
           
(package private)  boolean isTooClose(byte[] ip)
          Is this IP too close to ours to trust it for things like relaying?
 boolean isValid(byte[] addr)
          An IPv6 address is only valid if we are configured to support IPv6 AND we have a public IPv6 address.
 void messageReceived(I2NPMessage inMsg, RouterIdentity remoteIdent, Hash remoteIdentHash, long msToReceive, int bytesReceived)
          infinite loop public RouterAddress getCurrentAddress() { if (needsRebuild()) rebuildExternalAddress(false); return super.getCurrentAddress(); }
protected  void outboundMessageReady()
          This message is called whenever a new message is added to the send pool, and it should not block Only used by NTCP.
(package private)  PeerState pickTestPeer(PeerTestState.Role peerRole, RemoteHostId dontInclude)
          Pick a Bob (if we are Alice) or a Charlie (if we are Bob).
 void recheckReachability()
          Deprecated. unused
protected  void removeAddress(boolean ipv6)
          Remove then tell NTCP that we changed.
protected  void removeAddress(RouterAddress address)
          Remove then tell NTCP that we changed.
 void renderStatusHTML(Writer out, String urlBase, int sortFlags)
           
protected  void replaceAddress(RouterAddress address)
          Replace then tell NTCP that we changed.
(package private)  void send(I2NPMessage msg, PeerState peer)
          "injected" message from the EstablishmentManager
 void send(OutNetMessage msg)
          Asynchronously send the message as requested in the message and, if the send is successful, queue up any msg.getOnSendJob job, and register it with the OutboundMessageRegistry (if it has a reply selector).
(package private)  void send(UDPPacket packet)
          This sends it directly out, bypassing OutboundMessageFragments.
(package private)  void sendDestroy(PeerState peer)
          Send a session destroy message, bypassing OMF and PacketPusher.
(package private)  void sendIfEstablished(OutNetMessage msg)
          Send only if established, otherwise fail immediately.
(package private)  void setReachabilityStatus(CommSystemFacade.Status status)
           
 void shutdown()
           
 void startListening()
           
 void stopListening()
           
 void succeeded(OutboundMessageState msg)
           
 List<RouterAddress> updateAddress()
          Rebuild to get updated cost and introducers.
 
Methods inherited from class net.i2p.router.transport.TransportImpl
_, _, afterSend, afterSend, afterSend, afterSend, externalAddressRemoved, getCurrentAddress, getCurrentAddresses, getIP, getIPv6Config, getMaxConnections, getMostRecentErrorMessages, getNextMessage, getSavedLocalAddresses, getTargetAddresses, hasCurrentAddress, haveCapacity, haveCapacity, isIPv4Firewalled, isPubliclyRoutable, isUnreachable, markReachable, markUnreachable, ngettext, renderStatusHTML, saveLocalAddress, setIP, setListener, wasUnreachable
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

STYLE

public static final String STYLE
See Also:
Constant Field Values

PROP_INTERNAL_PORT

public static final String PROP_INTERNAL_PORT
See Also:
Constant Field Values

DEFAULT_INTERNAL_PORT

public static final int DEFAULT_INTERNAL_PORT
Deprecated. unused
now unused, we pick a random port

See Also:
Constant Field Values

PROP_EXTERNAL_HOST

public static final String PROP_EXTERNAL_HOST
define this to explicitly set an external IP address

See Also:
Constant Field Values

PROP_EXTERNAL_PORT

public static final String PROP_EXTERNAL_PORT
define this to explicitly set an external port

See Also:
Constant Field Values

PROP_PREFER_UDP

public static final String PROP_PREFER_UDP
If i2np.udp.preferred is set to "always", the UDP bids will always be under the bid from the TCP transport - even if a TCP connection already exists. If it is set to "true", it will prefer UDP unless no UDP session exists and a TCP connection already exists. If it is set to "false" (the default), it will prefer TCP unless no TCP session exists and a UDP connection already exists.

See Also:
Constant Field Values

PROP_SOURCES

public static final String PROP_SOURCES
allowed sources of address updates

See Also:
Constant Field Values

DEFAULT_SOURCES

public static final String DEFAULT_SOURCES

PROP_IP

public static final String PROP_IP
remember IP changes

See Also:
Constant Field Values

PROP_IP_CHANGE

public static final String PROP_IP_CHANGE
See Also:
Constant Field Values

PROP_LAPTOP_MODE

public static final String PROP_LAPTOP_MODE
See Also:
Constant Field Values

PROP_FORCE_INTRODUCERS

public static final String PROP_FORCE_INTRODUCERS
do we require introducers, regardless of our status?

See Also:
Constant Field Values

PROP_ALLOW_DIRECT

public static final String PROP_ALLOW_DIRECT
do we allow direct SSU connections, sans introducers?

See Also:
Constant Field Values

PROP_BIND_INTERFACE

public static final String PROP_BIND_INTERFACE
this is rarely if ever used, default is to bind to wildcard address

See Also:
Constant Field Values

PUBLIC_RELAY_COUNT

public static final int PUBLIC_RELAY_COUNT
how many relays offered to us will we use at a time?

See Also:
Constant Field Values

DEFAULT_COST

public static final int DEFAULT_COST
See Also:
Constant Field Values

RATES

static final long[] RATES

EXPIRE_TIMEOUT

public static final int EXPIRE_TIMEOUT
See Also:
Constant Field Values

MIN_EXPIRE_TIMEOUT

public static final int MIN_EXPIRE_TIMEOUT
See Also:
Constant Field Values
Constructor Detail

UDPTransport

public UDPTransport(RouterContext ctx,
                    DHSessionKeyBuilder.Factory dh)
Method Detail

shutdown

public void shutdown()

fail

public void fail(UDPEndpoint endpoint)
The endpoint has failed. Remove it.

Since:
0.9.16

getIntroKey

SessionKey getIntroKey()
Introduction key that people should use to contact us


getExternalPort

int getExternalPort(boolean ipv6)

getExternalIP

byte[] getExternalIP()
IPv4 only

Returns:
IP or null
Since:
0.9.2

isTooClose

boolean isTooClose(byte[] ip)
Is this IP too close to ours to trust it for things like relaying?

Parameters:
ip - IPv4 or IPv6
Since:
IPv6

getRequestedPort

public int getRequestedPort()
The current or configured internal IPv4 port. UDPEndpoint should always be instantiated (and a random port picked if not configured) before this is called, so the returned value should be > 0 unless the endpoint failed to bind.

Specified by:
getRequestedPort in interface Transport
Overrides:
getRequestedPort in class TransportImpl
Returns:
port or -1 for none or 0 for any

getMTU

int getMTU(boolean ipv6)
The MTU for the socket interface. To be used as the "large" MTU.

Returns:
limited to range PeerState.MIN_MTU to PeerState.LARGE_MTU.
Since:
0.9.2

inboundConnectionReceived

void inboundConnectionReceived(boolean isIPv6)

externalAddressReceived

public void externalAddressReceived(Transport.AddressSource source,
                                    byte[] ip,
                                    int port)
From config, UPnP, local i/f, ... Not for info received from peers - see externalAddressReceived(Hash, ip, port)

Specified by:
externalAddressReceived in interface Transport
Overrides:
externalAddressReceived in class TransportImpl
Parameters:
source - as defined in Transport.SOURCE_xxx
ip - publicly routable IPv4 or IPv6, null ok
port - 0 if unknown

forwardPortStatus

public void forwardPortStatus(byte[] ip,
                              int port,
                              int externalPort,
                              boolean success,
                              String reason)
Callback from UPnP. If we we have an IP address and UPnP claims success, believe it. If this is wrong, the peer test will figure it out and change the status. Don't do anything if UPnP claims failure.

Specified by:
forwardPortStatus in interface Transport
Overrides:
forwardPortStatus in class TransportImpl
Parameters:
ip - may be null
port - the internal port
externalPort - the external port, which for now should always be the same as the internal port if the forwarding was successful.

externalAddressReceived

void externalAddressReceived(Hash from,
                             byte[] ourIP,
                             int ourPort)
Someone we tried to contact gave us what they think our IP address is. Right now, we just blindly trust them, changing our IP and port on a whim. this is not good ;) Slight enhancement - require two different peers in a row to agree Todo: - Much better tracking of troublemakers - Disable if we have good local address or UPnP - This gets harder if and when we publish multiple addresses, or IPv6

Parameters:
from - Hash of inbound destination
ourIP - publicly routable IPv4 only
ourPort - >= 1024

isValid

public final boolean isValid(byte[] addr)
An IPv6 address is only valid if we are configured to support IPv6 AND we have a public IPv6 address.

Parameters:
addr - may be null, returns false

allowLocal

boolean allowLocal()
Are we allowed to connect to local addresses?

Since:
IPv6

getPeerState

PeerState getPeerState(RemoteHostId hostInfo)
get the state for the peer at the given remote host/port, or null if no state exists


getPeerStatesByIP

List<PeerState> getPeerStatesByIP(RemoteHostId hostInfo)
Get the states for all peers at the given remote host, ignoring port. Used for a last-chance search for a peer that changed port, by PacketHandler. Always returns empty list for IPv6 hostInfo.

Since:
0.9.3

getPeerState

PeerState getPeerState(Hash remotePeer)
get the state for the peer with the given ident, or null if no state exists


changePeerPort

void changePeerPort(PeerState peer,
                    int newPort)
Remove and add to peersByRemoteHost map

Since:
0.9.3

getEstablisher

EstablishmentManager getEstablisher()
For IntroductionManager

Returns:
may be null if not started
Since:
0.9.2

addRemotePeerState

boolean addRemotePeerState(PeerState peer)
add the peer info, returning true if it went in properly, false if it was rejected (causes include peer ident already connected, or no remote host info known


messageReceived

public void messageReceived(I2NPMessage inMsg,
                            RouterIdentity remoteIdent,
                            Hash remoteIdentHash,
                            long msToReceive,
                            int bytesReceived)
infinite loop public RouterAddress getCurrentAddress() { if (needsRebuild()) rebuildExternalAddress(false); return super.getCurrentAddress(); }

Overrides:
messageReceived in class TransportImpl
Parameters:
inMsg - non-null
remoteIdent - may be null
remoteIdentHash - may be null, calculated from remoteIdent if null

isInDropList

boolean isInDropList(RemoteHostId peer)

dropPeer

void dropPeer(Hash peer,
              boolean shouldBanlist,
              String why)
This does not send a session destroy, caller must do that if desired.

Parameters:
shouldBanlist - doesn't really, only sets unreachable

dropPeer

void dropPeer(PeerState peer,
              boolean shouldBanlist,
              String why)
This does not send a session destroy, caller must do that if desired.

Parameters:
shouldBanlist - doesn't really, only sets unreachable

send

void send(UDPPacket packet)
This sends it directly out, bypassing OutboundMessageFragments. The only queueing is for the bandwidth limiter. BLOCKING if OB queue is full.


sendDestroy

void sendDestroy(PeerState peer)
Send a session destroy message, bypassing OMF and PacketPusher. BLOCKING if OB queue is full.

Since:
0.8.9

bid

public TransportBid bid(RouterInfo toAddress,
                        long dataSize)
Specified by:
bid in interface Transport

getTargetAddress

RouterAddress getTargetAddress(RouterInfo target)
Get first available address we can use.

Returns:
address or null
Since:
0.9.6

getStyle

public String getStyle()
Description copied from interface: Transport
The unique identity of this Transport

Specified by:
getStyle in interface Transport

send

public void send(OutNetMessage msg)
Description copied from class: TransportImpl
Asynchronously send the message as requested in the message and, if the send is successful, queue up any msg.getOnSendJob job, and register it with the OutboundMessageRegistry (if it has a reply selector). If the send fails, queue up any msg.getOnFailedSendJob Only used by NTCP. SSU overrides. Note that this adds to the queue and then takes it back off in the same thread, so it actually blocks, and we don't need a big queue. TODO: Override in NTCP also and get rid of queue?

Specified by:
send in interface Transport
Overrides:
send in class TransportImpl

sendIfEstablished

void sendIfEstablished(OutNetMessage msg)
Send only if established, otherwise fail immediately. Never queue with the establisher.

Since:
0.9.2

send

void send(I2NPMessage msg,
          PeerState peer)
"injected" message from the EstablishmentManager


outboundMessageReady

protected void outboundMessageReady()
Description copied from class: TransportImpl
This message is called whenever a new message is added to the send pool, and it should not block Only used by NTCP. SSU throws UOE.

Specified by:
outboundMessageReady in class TransportImpl

startListening

public void startListening()
Specified by:
startListening in interface Transport

stopListening

public void stopListening()
Specified by:
stopListening in interface Transport

updateAddress

public List<RouterAddress> updateAddress()
Rebuild to get updated cost and introducers. Do not tell the router (he is the one calling this)

Specified by:
updateAddress in interface Transport
Overrides:
updateAddress in class TransportImpl
Returns:
all addresses, non-null
Since:
0.7.12

replaceAddress

protected void replaceAddress(RouterAddress address)
Replace then tell NTCP that we changed.

Overrides:
replaceAddress in class TransportImpl
Parameters:
address - the new address or null to remove all

removeAddress

protected void removeAddress(RouterAddress address)
Remove then tell NTCP that we changed.

Overrides:
removeAddress in class TransportImpl
Since:
0.9.20

removeAddress

protected void removeAddress(boolean ipv6)
Remove then tell NTCP that we changed.

Overrides:
removeAddress in class TransportImpl
Parameters:
ipv6 - true to remove all IPv6 addresses, false to remove all IPv4 addresses
Since:
0.9.20

introducersRequired

public boolean introducersRequired()
Do we require introducers?


canIntroduce

boolean canIntroduce()
For EstablishmentManager

Since:
0.9.3

getPacketHandlerStatus

String getPacketHandlerStatus()

getPacketHandler

PacketHandler getPacketHandler()
Since:
IPv6

failed

public void failed(OutboundMessageState msg)

failed

void failed(OutboundMessageState msg,
            boolean allowPeerFailure)

failed

public void failed(OutNetMessage msg,
                   String reason)
Specified by:
failed in interface TimedWeightedPriorityMessageQueue.FailedListener

succeeded

public void succeeded(OutboundMessageState msg)

countPeers

public int countPeers()
Description copied from class: TransportImpl
How many peers are we connected to?

Specified by:
countPeers in interface Transport
Specified by:
countPeers in class TransportImpl

countActivePeers

public int countActivePeers()
Description copied from class: TransportImpl
How many peers are we currently connected to, that we have sent a message to or received a message from in the last five minutes.

Specified by:
countActivePeers in interface Transport
Specified by:
countActivePeers in class TransportImpl

countActiveSendPeers

public int countActiveSendPeers()
Description copied from class: TransportImpl
How many peers are we currently connected to, that we have sent a message to in the last minute. Unused for anything, to be removed.

Specified by:
countActiveSendPeers in interface Transport
Specified by:
countActiveSendPeers in class TransportImpl

isEstablished

public boolean isEstablished(Hash dest)
Specified by:
isEstablished in interface Transport
Overrides:
isEstablished in class TransportImpl

isBacklogged

public boolean isBacklogged(Hash dest)
Specified by:
isBacklogged in interface Transport
Overrides:
isBacklogged in class TransportImpl
Since:
0.9.3

allowConnection

public boolean allowConnection()

getClockSkews

public Vector<Long> getClockSkews()
Return our peer clock skews on this transport. Vector composed of Long, each element representing a peer skew in seconds. A positive number means our clock is ahead of theirs.

Specified by:
getClockSkews in interface Transport
Overrides:
getClockSkews in class TransportImpl

getDHBuilder

DHSessionKeyBuilder getDHBuilder()
Returns:
a new DHSessionKeyBuilder
Since:
0.9

getDHFactory

DHSessionKeyBuilder.Factory getDHFactory()
Returns:
the factory
Since:
0.9.2

renderStatusHTML

public void renderStatusHTML(Writer out,
                             String urlBase,
                             int sortFlags)
                      throws IOException
Specified by:
renderStatusHTML in interface Transport
Overrides:
renderStatusHTML in class TransportImpl
Throws:
IOException

setReachabilityStatus

void setReachabilityStatus(CommSystemFacade.Status status)

getReachabilityStatus

public CommSystemFacade.Status getReachabilityStatus()
Previously returned short, now enum as of 0.9.20

Specified by:
getReachabilityStatus in interface Transport
Specified by:
getReachabilityStatus in class TransportImpl

recheckReachability

public void recheckReachability()
Deprecated. unused

Specified by:
recheckReachability in interface Transport
Overrides:
recheckReachability in class TransportImpl

pickTestPeer

PeerState pickTestPeer(PeerTestState.Role peerRole,
                       RemoteHostId dontInclude)
Pick a Bob (if we are Alice) or a Charlie (if we are Bob). For Bob (as called from PeerTestEvent below), returns an established IPv4 peer. While the protocol allows Alice to select an unestablished Bob, we don't support that. For Charlie (as called from PeerTestManager), returns an established IPv4 or IPv6 peer. (doesn't matter how Bob and Charlie communicate) Any returned peer must advertise an IPv4 address to prove it is IPv4-capable.

Parameters:
peerRole - BOB or CHARLIE only
dontInclude - may be null
Returns:
IPv4 peer or null