Field Summary
FieldsModifier and TypeFieldDescriptionprivate final I2PAppContextThe app context.private final ReentrantLockThe lock guarding the send state.private final LogThe log for the producer.private intThe send rate limit, zero for none.private longWhen the current send period began.private intBytes allowed in the current send period.private final ConditionSignalled when the send period refills.private static final String[]The I2CP options set by the client side, not the ones listed for both the client and the server side.private static final intSmallest send rate limit allowed.private static final StringConfig key of the send rate limit.private static final intSee ConnectionOptions in streaming - MTU + streaming overhead + gzip overhead.Constructor Summary
ConstructorsConstructorDescriptionI2CPMessageProducer(I2PAppContext context) Create a message producer for the given context.Method Summary
Modifier and TypeMethodDescriptionvoidconnect(I2PSessionImpl session) Send all the messages that a client needs to send to a router to establish a new session.voidcreateLeaseSet(I2PSessionImpl session, LeaseSet leaseSet, SigningPrivateKey signingPriv, List<PrivateKey> privs) In response to a RequestLeaseSet Message from the router, send a CreateLeaseset Message back to the router.private static PayloadcreatePayload(byte[] payload) Create a new payload.voiddisconnect(I2PSessionImpl session) Send a message to the router destroying the session, which could be a subsession.private PropertiesgetRouterOptions(I2PSessionImpl session) Strip out the client-side options from the session options.voidreportAbuse(I2PSessionImpl session, int msgId, int severity) Send an abuse message to the router.voidsendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, long expires, int flags) Package up and send the payload to the router for delivery.voidsendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SendMessageOptions options) Package up and send the payload to the router for delivery.voidsendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SessionTag tag, SessionKey key, Set<SessionTag> tags, SessionKey newKey, long expires) Package up and send the payload to the router for delivery.voidupdateBandwidth(I2PSessionImpl session) Update bandwidth limits from session options.private booleanupdateBps(int len, long expires) Super-simple bandwidth throttler.voidupdateTunnels(I2PSessionImpl session, int tunnels) Update number of tunnels.
Field Details
_log
The log for the producer._context
The app context._maxBytesPerSecond
private volatile int _maxBytesPerSecondThe send rate limit, zero for none._sendPeriodBytes
private volatile int _sendPeriodBytesBytes allowed in the current send period._sendPeriodBeginTime
private volatile long _sendPeriodBeginTimeWhen the current send period began._lock
The lock guarding the send state._throttleCondition
Signalled when the send period refills.PROP_MAX_BW
Config key of the send rate limit.- See Also:
TYP_SIZE
private static final int TYP_SIZESee ConnectionOptions in streaming - MTU + streaming overhead + gzip overhead.- See Also:
MIN_RATE
CLIENT_SIDE_OPTIONS
The I2CP options set by the client side, not the ones listed for both the client and the server side. See also: the I2CP protocol
Constructor Details
I2CPMessageProducer
Create a message producer for the given context.- Parameters:
context- the router context
Method Details
updateBandwidth
Update bandwidth limits from session options.- Parameters:
session- the session whose PROP_MAX_BW option supplies the new limit
getRouterOptions
Strip out the client-side options from the session options.- Parameters:
session- the session whose options are copied and filtered- Returns:
- a new copy, may be modified
connect
Send all the messages that a client needs to send to a router to establish a new session.- Parameters:
session- the session to create the CreateSessionMessage for- Throws:
I2PSessionException- if the session's offline signature has expired, if the session config cannot be signed, or if the message cannot be queued
disconnect
Send a message to the router destroying the session, which could be a subsession. This does NOT close the socket.- Parameters:
session- the session or subsession to destroy, ignored if already closed- Throws:
I2PSessionException- if the message cannot be queued to the router
sendMessage
public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SessionTag tag, SessionKey key, Set<SessionTag> tags, SessionKey newKey, long expires) throws I2PSessionException Package up and send the payload to the router for delivery.- Parameters:
session- the session to send the message ondest- the destination to deliver the message tononce- 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessagepayload- the unencrypted message datatag- unused - no end-to-end cryptokey- unused - no end-to-end cryptotags- unused - no end-to-end cryptonewKey- unused - no end-to-end cryptoexpires- message expiration in milliseconds since the epoch, 0 for none- Throws:
I2PSessionException- if the payload is null or the message cannot be queued
sendMessage
public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, long expires, int flags) throws I2PSessionException Package up and send the payload to the router for delivery.- Parameters:
session- the session to send the message ondest- the destination to deliver the message tononce- 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessagepayload- the unencrypted message dataexpires- message expiration in milliseconds since the epoch, 0 for noneflags- the raw flag bitmask to pass to the router, 0 for the defaults- Throws:
I2PSessionException- if the payload is null or the message cannot be queued
sendMessage
public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SendMessageOptions options) throws I2PSessionException Package up and send the payload to the router for delivery.- Parameters:
session- the session to send the message ondest- the destination to deliver the message tononce- 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessagepayload- the unencrypted message dataoptions- the expiration, flags, tags and reliability to send with the message- Throws:
I2PSessionException- if the payload is null or the message cannot be queued
updateBps
private boolean updateBps(int len, long expires) Super-simple bandwidth throttler. We only calculate on a one-second basis, so large messages (compared to the one-second limit) may exceed the limits. Tuned for streaming, may not work well for large datagrams.This does poorly with low rate limits since it doesn't credit bandwidth across two periods. So the limit is rounded up, and the min limit is set to 2x the typ size, above.
Blocking so this could be very bad for retransmissions, as it could clog StreamingTimer. Waits are somewhat "fair" using
ReentrantLock. While out-of-order transmission is acceptable, fairness reduces the chance of starvation. ReentrantLock does not guarantee in-order execution due to thread priority issues, so out-of-order may still occur. But shouldn't happen within the same thread anyway... Also note that small messages may go ahead of large ones that are waiting for the next window. Also, threads waiting a second time go to the back of the line.Since this is at the I2CP layer, it includes streaming overhead, streaming acks and retransmissions, gzip overhead (or "underhead" for compression), repliable datagram overhead, etc. However, it does not, of course, include the substantial overhead imposed by the router for the leaseset, tags, encryption, and fixed-size tunnel messages.
- Parameters:
len- the size of the message in bytes, counted against the throttleexpires- if $gt; 0, an expiration date- Returns:
- true if we should send the message, false to drop it
createPayload
Create a new payload. No more end-to-end encryption, just set the "encrypted" data to the payload.- Parameters:
payload- the message data, must not be null- Returns:
- a Payload wrapping a copy of the supplied data, unencrypted
- Throws:
I2PSessionException- if the payload is null
reportAbuse
Send an abuse message to the router.- Parameters:
session- the session on whose behalf the abuse is reportedmsgId- the message ID the abuse refers toseverity- the abuse severity level, larger numbers being more severe- Throws:
I2PSessionException- if the message cannot be queued to the router
createLeaseSet
public void createLeaseSet(I2PSessionImpl session, LeaseSet leaseSet, SigningPrivateKey signingPriv, List<PrivateKey> privs) throws I2PSessionException In response to a RequestLeaseSet Message from the router, send a CreateLeaseset Message back to the router. This method is misnamed, it does not create the LeaseSet, the caller does that.- Parameters:
session- the session on whose behalf the LeaseSet is createdleaseSet- the LeaseSet to send, of type 0, 1 or 3signingPriv- unused for LS2 lease setsprivs- the private keys to encrypt the LeaseSet with, the first entry being the signing key for type 0 and 1 LeaseSets- Throws:
I2PSessionException- if the session is closed
updateTunnels
Update number of tunnels.- Parameters:
session- the session to reconfiguretunnels- 0 for original configured number- Throws:
I2PSessionException- if the session configuration cannot be signed