Package net.i2p.router.client
Class ClientConnectionRunner
java.lang.Object
net.i2p.router.client.ClientConnectionRunner
- Direct Known Subclasses:
QueuedClientConnectionRunner
class ClientConnectionRunner extends Object
Bridge the router and the client - managing state for a client.
As of release 0.9.21, multiple sessions are supported on a single
I2CP connection. These sessions share tunnels and some configuration.
- Author:
- jrandom
-
Field Summary
Fields Modifier and Type Field Description protected RouterContext
_context
protected Log
_log
protected ClientManager
_manager
protected I2CPMessageReader
_reader
thingy that does stuff -
Constructor Summary
Constructors Constructor Description ClientConnectionRunner(RouterContext context, ClientManager manager, Socket socket)
Create a new runner against the given socket -
Method Summary
Modifier and Type Method Description (package private) void
ackSendMessage(SessionId sid, MessageId id, long nonce)
Send a notification to the client that their message (id specified) was accepted for delivery (but not necessarily delivered) Doesn't do anything if i2cp.messageReliability = "none" or if the nonce is 0.protected I2CPMessageReader.I2CPMessageEventListener
createListener()
Allow override for testing(package private) void
disconnectClient(String reason)
Send a DisconnectMessage and log with level Log.ERROR.(package private) void
disconnectClient(String reason, int logLevel)
(package private) void
disconnected()
(package private) MessageId
distributeMessage(SendMessageMessage message)
Distribute the message.(package private) void
doSend(I2CPMessage msg)
Actually send the I2CPMessage to the peer through the socketvoid
failLeaseRequest(LeaseRequestState req)
String
getClientVersion()
The client version.SessionConfig
getConfig(Hash h)
Current client's config, will be null if session not found IS subsession aware.SessionConfig
getConfig(SessionId id)
Current client's config, will be null if session not found IS subsession aware.Hash
getDestHash()
Equivalent to getConfig().getDestination().calculateHash(); will be null before session is established Not subsession aware.Hash
getDestHash(SessionId id)
Return the hash for the given IDDestination
getDestination(SessionId id)
Return the dest for the given ID(package private) List<Destination>
getDestinations()
Subsession aware.(package private) boolean
getIsDead()
(package private) LeaseRequestState
getLeaseRequest(Hash h)
Data for the current leaseRequest, or null if there is no active leaseSet request.LeaseSet
getLeaseSet(Hash h)
Currently allocated leaseSet.int
getNextMessageId()
(package private) Payload
getPayload(MessageId id)
Only call if _dontSendMSMOnReceive is false, otherwise will always be nullSessionConfig
getPrimaryConfig()
Primary client's config, will be null if session not set up(package private) SessionId
getSessionId(Hash h)
Subsession aware.(package private) List<SessionId>
getSessionIds()
Subsession aware.SessionKeyManager
getSessionKeyManager()
The current client's SessionKeyManager.(package private) boolean
isDead()
already closed?(package private) void
leaseSetCreated(LeaseSet ls)
called after a new leaseSet is granted by the client, the NetworkDb has been updated.(package private) boolean
receiveMessage(Destination toDest, Destination fromDest, Payload payload)
Synchronously deliver the message to the current runner Failure indication is available as of 0.9.29.(package private) boolean
receiveMessage(Hash toHash, Destination fromDest, Payload payload)
Synchronously deliver the message to the current runner Failure indication is available as of 0.9.29.boolean
registerEncryptedLS(Hash hash)
Call after destinationEstablished(), when an encrypted leaseset is created, so we know it's local.(package private) void
removePayload(MessageId id)
Only call if _dontSendMSMOnReceive is false(package private) void
removeSession(SessionId id)
Kill the session.void
reportAbuse(Destination dest, String reason, int severity)
Send async abuse message to the client(package private) void
requestLeaseSet(Hash h, LeaseSet set, long expirationTime, Job onCreateJob, Job onFailedJob)
Request that a particular client authorize the Leases contained in the LeaseSet, after which the onCreateJob is queued up.int
sessionEstablished(SessionConfig config)
Caller must send a SessionStatusMessage to the client with the returned code.void
setClientVersion(String version)
The client version.(package private) void
setPayload(MessageId id, Payload payload)
Only call if _dontSendMSMOnReceive is false(package private) void
setSessionId(Hash hash, SessionId id)
To be called only by ClientManager.void
startRunning()
Actually run the connection - listen for I2CP messages and respond.void
stopRunning()
Die a horrible death.(package private) void
updateMessageDeliveryStatus(Destination dest, MessageId id, long messageNonce, int status)
Send a notification to the client that their message (id specified) was delivered (or failed delivery) Note that this sends the Guaranteed status codes, even though we only support best effort.(package private) void
writeMessage(I2CPMessage msg)
Not thread-safe.
-
Field Details
-
Constructor Details
-
ClientConnectionRunner
Create a new runner against the given socket
-
-
Method Details
-
startRunning
Actually run the connection - listen for I2CP messages and respond. This is the main driver for this class, though it gets all its meat from theI2CPMessageReader
- Throws:
IOException
-
createListener
Allow override for testing- Since:
- 0.9.8
-
stopRunning
public void stopRunning()Die a horrible death. Cannot be restarted. -
getConfig
Current client's config, will be null if session not found IS subsession aware.- Since:
- 0.9.21 added hash param
-
getConfig
Current client's config, will be null if session not found IS subsession aware. Returns null if id is null.- Since:
- 0.9.21 added id param
-
getPrimaryConfig
Primary client's config, will be null if session not set up- Since:
- 0.9.21
-
setClientVersion
The client version.- Since:
- 0.9.7
-
getClientVersion
The client version.- Returns:
- null if unknown or less than 0.8.7
- Since:
- 0.9.7
-
getSessionKeyManager
The current client's SessionKeyManager. As of 0.9.44, returned implementation varies based on supported encryption types. -
getLeaseSet
Currently allocated leaseSet. IS subsession aware. Returns primary leaseset only.- Returns:
- leaseSet or null if not yet set or unknown hash
- Since:
- 0.9.21 added hash parameter
-
getDestHash
Equivalent to getConfig().getDestination().calculateHash(); will be null before session is established Not subsession aware. Returns primary session hash. Don't use if you can help it.- Returns:
- primary hash or null if not yet set
-
getDestHash
Return the hash for the given ID- Returns:
- hash or null if unknown
- Since:
- 0.9.21
-
getDestination
Return the dest for the given ID- Returns:
- dest or null if unknown
- Since:
- 0.9.21
-
getSessionId
Subsession aware.- Parameters:
h
- the local target- Returns:
- current client's sessionId or null if not yet set or not a valid hash
- Since:
- 0.9.21
-
getSessionIds
Subsession aware.- Returns:
- all current client's sessionIds, non-null
- Since:
- 0.9.21
-
getDestinations
List<Destination> getDestinations()Subsession aware.- Returns:
- all current client's destinations, non-null
- Since:
- 0.9.21
-
setSessionId
To be called only by ClientManager.- Parameters:
hash
- for the session- Throws:
IllegalStateException
- if already set- Since:
- 0.9.21 added hash param
-
removeSession
Kill the session. Caller must kill runner if none left.- Since:
- 0.9.21
-
getLeaseRequest
Data for the current leaseRequest, or null if there is no active leaseSet request. Not subsession aware. Returns primary ID only.- Since:
- 0.9.21 added hash param
-
failLeaseRequest
- Parameters:
req
- non-null
-
isDead
boolean isDead()already closed? -
getPayload
Only call if _dontSendMSMOnReceive is false, otherwise will always be null -
setPayload
Only call if _dontSendMSMOnReceive is false -
removePayload
Only call if _dontSendMSMOnReceive is false -
sessionEstablished
Caller must send a SessionStatusMessage to the client with the returned code. Caller must call disconnectClient() on failure. Side effect: Sets the session ID.- Returns:
- SessionStatusMessage return code, 1 for success, != 1 for failure
-
updateMessageDeliveryStatus
Send a notification to the client that their message (id specified) was delivered (or failed delivery) Note that this sends the Guaranteed status codes, even though we only support best effort. Doesn't do anything if i2cp.messageReliability = "none" Do not use for status = STATUS_SEND_ACCEPTED; use ackSendMessage() for that.- Parameters:
dest
- the clientid
- the router's ID for this messagemessageNonce
- the client's ID for this message, greater than zerostatus
- see I2CP MessageStatusMessage for success/failure codes
-
leaseSetCreated
called after a new leaseSet is granted by the client, the NetworkDb has been updated. This takes care of all the LeaseRequestState stuff (including firing any jobs)- Parameters:
ls
- if encrypted, the encrypted LS, not the decrypted one
-
registerEncryptedLS
Call after destinationEstablished(), when an encrypted leaseset is created, so we know it's local. Add to the clients list. Check for a dup hash. Caller must call runner.disconnectClient() on failure.- Parameters:
hash
- the location of the encrypted LS, will change every day- Returns:
- success, false on dup
- Since:
- 0.9.39
-
disconnectClient
Send a DisconnectMessage and log with level Log.ERROR. This is always bad. See ClientMessageEventListener.handleCreateSession() for why we don't send a SessionStatusMessage when we do this.- Parameters:
reason
- will be truncated to 255 bytes
-
disconnectClient
- Parameters:
reason
- will be truncated to 255 byteslogLevel
- e.g. Log.WARN- Since:
- 0.8.2
-
distributeMessage
Distribute the message. If the dest is local, it blocks until its passed to the target ClientConnectionRunner (which then fires it into a MessageReceivedJob). If the dest is remote, it blocks until it is added into the ClientMessagePool -
ackSendMessage
Send a notification to the client that their message (id specified) was accepted for delivery (but not necessarily delivered) Doesn't do anything if i2cp.messageReliability = "none" or if the nonce is 0.- Parameters:
id
- OUR id for the messagenonce
- HIS id for the message
-
receiveMessage
Synchronously deliver the message to the current runner Failure indication is available as of 0.9.29. Fails on e.g. queue overflow to client, client dead, etc.- Parameters:
toDest
- non-nullfromDest
- generally null when from remote, non-null if from local- Returns:
- success
-
receiveMessage
Synchronously deliver the message to the current runner Failure indication is available as of 0.9.29. Fails on e.g. queue overflow to client, client dead, etc.- Parameters:
toHash
- non-nullfromDest
- generally null when from remote, non-null if from local- Returns:
- success
- Since:
- 0.9.21
-
reportAbuse
Send async abuse message to the client -
requestLeaseSet
Request that a particular client authorize the Leases contained in the LeaseSet, after which the onCreateJob is queued up. If that doesn't occur within the timeout specified, queue up the onFailedJob. This call does not block. Job args are always null, may need some fixups if we start using them.- Parameters:
h
- the Destination's hashset
- LeaseSet with requested leases - this object must be updated to contain the signed version (as well as any changed/added/removed Leases) The LeaseSet contains Leases only, it is unsigned. Must be unique for this hash, do not reuse for subsessions.expirationTime
- ms to wait before failingonCreateJob
- Job to run after the LeaseSet is authorized, null OKonFailedJob
- Job to run after the timeout passes without receiving authorization, null OK
-
disconnected
void disconnected() -
getIsDead
boolean getIsDead() -
writeMessage
Not thread-safe. Blocking. Only used for external sockets. ClientWriterRunner thread is the only caller. Others must use doSend(). -
doSend
Actually send the I2CPMessage to the peer through the socket- Throws:
I2CPMessageException
-
getNextMessageId
public int getNextMessageId()
-