java.lang.Object
net.i2p.router.transport.udp.IntroductionManager
Keep track of inbound and outbound introductions. See http://i2p-projekt.i2p/spec/ssu2 for documentation.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classWait for a relay request, then relay the RouterInfo.private classSimple fix for RI DSM getting there before RelayIntro.private static classSo we can sort them.private static classFor picking introducers.Field Summary
Modifier and TypeFieldDescriptionprivate final PacketBuilder2Builder for the SSU2 packets.private final RouterContextThe router context.Map of relay tag to Bob PeerState who have given us introduction tags (we are Charlie).private longWhen the hole punch set was last cleaned.private final LogLogger for the SSU introductions.private final ConcurrentHashMap<Long, PeerState2> Map of relay nonce to Alice PeerState who requested it.Map of relay tag to Charlie PeerState that should receive the introduction (we are Bob).Hole punch nonces recently sent.Relay requests recently handled as Bob.private final UDPTransportThe SSU transport we serve.private static final ObjectPlaceholder value for the relay map.private static final longTime an introducer stays valid.private static final intLimit since we ping to keep the conn open.static final intThis is enforced inEstablishmentManager.private static final intHole punches remembered at once.private static final longMaximum clock skew accepted in an introduction.private static final StringFirst version supporting IPv6 introducers.private static final longInterval between hole punch cleanups.Constructor Summary
ConstructorsConstructorDescriptionIntroductionManager(RouterContext ctx, UDPTransport transport) Creates the introduction manager.Method Summary
Modifier and TypeMethodDescriptionvoidRegister the peer's relay tags.voidcleanup()Loop and cleanup _nonceToAlice Called from EstablishmentManager doFailSafe() so we don't need a cleaner timer here.private RouterAddressgetAddress(RouterInfo ri, boolean isIPv6) Address out of a RouterInfo.(package private) intCombined IPv4 and IPv6.(package private) intintroducerCount(boolean ipv6) Not as elaborate as pickInbound() above.booleanisInboundTagValid(long tag) Is this inbound tag currently valid, i.e.private booleanisValid(byte[] ip, int port, boolean allowIPv6) Are IP and port valid?intpickInbound(RouterAddress current, boolean ipv6, Properties ssuOptions, int howMany) Grab a bunch of peers who are willing to be introducers for us that are locally known (duh) and have published their own SSU address (duh^2).voidWas part ofpickInbound(RouterAddress, boolean, Properties, int), moved out so we can call it more often.(package private) voidreceiveHolePunch(RemoteHostId charlie, byte[] data) We are Alice and we got this from Charlie.(package private) voidreceiveRelayIntro(PeerState2 bob, Hash alice, byte[] data) Processes a relay introduction message received from another peer.private booleanreceiveRelayIntro(PeerState2 bob, Hash alice, byte[] data, int retryCount) We are Charlie and we got this from Bob.private booleanreceiveRelayIntro(PeerState2 bob, Hash alice, byte[] data, RouterInfo aliceRI) We are Charlie and we got this from Bob.(package private) voidreceiveRelayRequest(PeerState2 alice, byte[] data) We are Bob and we got this from Alice.(package private) voidreceiveRelayResponse(PeerState2 peer, int status, byte[] data) We are Bob and we got this from Charlie, OR we are Alice and we got this from Bob.voidUnregister the peer's relay tags.voidreset()Clear all introduction mappings.private voidsendRelayRejectLimit(PeerState2 bob, byte[] data) Sends a relay reject when Bob is over the limit.
Field Details
_context
The router context._log
Logger for the SSU introductions._transport
The SSU transport we serve._builder2
Builder for the SSU2 packets._outbound
_inbound
_nonceToAlice
Map of relay nonce to Alice PeerState who requested it._recentHolePunches
_lastHolePunchClean
private long _lastHolePunchCleanWhen the hole punch set was last cleaned._recentRelaysAsBob
DUMMY
Placeholder value for the relay map.MAX_INBOUND
private static final int MAX_INBOUNDLimit since we ping to keep the conn open.- See Also:
MAX_OUTBOUND
INTRODUCER_EXPIRATION
private static final long INTRODUCER_EXPIRATIONTime an introducer stays valid.- See Also:
MIN_IPV6_INTRODUCER_VERSION
First version supporting IPv6 introducers.- See Also:
MAX_SKEW
private static final long MAX_SKEWMaximum clock skew accepted in an introduction.- See Also:
PUNCH_CLEAN_TIME
private static final long PUNCH_CLEAN_TIMEInterval between hole punch cleanups.- See Also:
MAX_PUNCHES
Constructor Details
IntroductionManager
Creates the introduction manager.- Parameters:
ctx- the router contexttransport- the UDP transport it serves
Method Details
reset
public void reset()Clear all introduction mappings.add
Register the peer's relay tags.- Parameters:
peer- the peer whose tags are being registered
remove
Unregister the peer's relay tags.- Parameters:
peer- the peer whose tags are being dropped
isInboundTagValid
public boolean isInboundTagValid(long tag) Is this inbound tag currently valid, i.e. is the peer still connected?- Parameters:
tag- the relay tag to look up- Returns:
- whether inbound tag valid
pickInbound
Grab a bunch of peers who are willing to be introducers for us that are locally known (duh) and have published their own SSU address (duh^2). The picked peers have their info tacked on to the ssuOptions parameter for use in the SSU RouterAddress.Try to use "good" peers (i.e. reachable, active)
Also, ping all idle peers that were introducers in the last 2 hours, to keep the connection up, since the netDb can have quite stale information, and we want to keep our introducers valid.
- Parameters:
current- current router address, may be nullipv6- what type is the current address we need introducers for?ssuOptions- out parameter, options are addedhowMany- the most introducers to return- Returns:
- number of introducers added
pingIntroducers
public void pingIntroducers()Was part ofpickInbound(RouterAddress, boolean, Properties, int), moved out so we can call it more often.introducerCount
int introducerCount(boolean ipv6) Not as elaborate as pickInbound() above. Just a quick check to see how many volunteers we know, which the Transport uses to see if we need more.- Parameters:
ipv6- what type of address are they introducing us for- Returns:
- number of peers that have volunteered to introduce us
introducedCount
int introducedCount()Combined IPv4 and IPv6.- Returns:
- number of peers we have volunteered to introduce
receiveRelayRequest
We are Bob and we got this from Alice. Send Alice's RI and a RelayIntro to Charlie, or reject with a RelayResponse to Alice. We should already have a session with Charlie and definitely with Alice.SSU 2 only.
- Parameters:
alice- the peer that asked us to relaydata- the encrypted request, with the timestamp in the first 4 bytes
receiveRelayIntro
Processes a relay introduction message received from another peer.This method is responsible for initiating a HolePunch to the specified destination peer ('Alice') and preparing a RelayResponse to be sent back to the originating peer ('Bob'). It is designed for use with the SSU 2 protocol.
- Parameters:
bob- the PeerState2 instance representing the peer that sent the relay introduction messagealice- the Hash object identifying the destination peer ('Alice') to which a HolePunch will be initiateddata- the byte array containing the data payload of the relay introduction message
sendRelayRejectLimit
Sends a relay reject when Bob is over the limit.- Parameters:
bob- Bob's peer statedata- the relay request data
receiveRelayIntro
We are Charlie and we got this from Bob. Bob should have sent us the RI, but maybe it's in the block after this, or maybe it's in a different packet. Check for RI, if not found, return true to retry, unless retryCount is at the limit. Creates the timer if retryCount == 0.SSU 2 only.
- Parameters:
bob- the peer that relayed the introduction to usalice- the hash of the peer being introduceddata- the relay intro payload to forward once Alice's RI is knownretryCount- the number of retries so far, 0 on first receipt, retried up to 5 times- Returns:
- false if Alice's RouterInfo is not yet available and the intro should be retried, true if the intro was processed
receiveRelayIntro
We are Charlie and we got this from Bob. Send a HolePunch to Alice, who will soon be sending us a SessionRequest. And send a RelayResponse to bob.SSU 2 only.
- Parameters:
bob- the peer that relayed the introduction to usalice- the hash of the peer being introduceddata- the signed relay intro payload to validatealiceRI- Alice's router info, or null if Bob did not deliver it- Returns:
- true if a RelayResponse was sent to Bob, false if the intro was invalid or the reply could not be built
receiveRelayResponse
We are Bob and we got this from Charlie, OR we are Alice and we got this from Bob.If we are Bob, send to Alice. If we are Alice, send a SessionRequest to Charlie. We should already have a session with Charlie, but not necessarily with Alice.
SSU 2 only.
- Parameters:
peer- the peer that answered our relay requeststatus- the status code the peer replied withdata- the encrypted response, with the nonce and timestamp first
receiveHolePunch
We are Alice and we got this from Charlie. Send a SessionRequest to Charlie, whether or not we got the Relay Response already.SSU 2 only, out-of-session.
- Parameters:
charlie- the peer we were relaying todata- the encrypted response, with the nonce and timestamp first
getAddress
Address out of a RouterInfo. SSU2 only.- Parameters:
ri- the router info to take the address fromisIPv6- true to select an IPv6 address, false for IPv4- Returns:
- address or null
isValid
private boolean isValid(byte[] ip, int port, boolean allowIPv6) Are IP and port valid?- Parameters:
ip- the address bytes to checkport- the port to checkallowIPv6- whether a 16-byte IPv6 address is acceptable- Returns:
- true if the address and port form an acceptable introduction target
cleanup
public void cleanup()Loop and cleanup _nonceToAlice Called from EstablishmentManager doFailSafe() so we don't need a cleaner timer here.