Package net.i2p.client.streaming.impl
Class Connection
- java.lang.Object
-
- net.i2p.client.streaming.impl.Connection
-
class Connection extends Object
Maintain the state controlling a streaming connection between two destinations.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) class
Connection.ConEvent
fired to reschedule event notification(package private) class
Connection.ResendPacketEvent
This is not normally scheduled.(package private) class
Connection.RetransmitEvent
A single retransmit timer for all packets.
-
Field Summary
Fields Modifier and Type Field Description static int
DEFAULT_CONNECT_TIMEOUT
static int
DISCONNECT_TIMEOUT
Wait up to 5 minutes after disconnection so we can ack/close packets.(package private) static int
FAST_RETRANSMIT_THRESHOLD
If we have been explicitly NACKed three times, retransmit the packet even if there are other packets in flight.static int
MAX_RESEND_DELAY
static int
MAX_WINDOW_SIZE
static int
MIN_RESEND_DELAY
-
Constructor Summary
Constructors Constructor Description Connection(I2PAppContext ctx, ConnectionManager manager, I2PSession session, SchedulerChooser chooser, SimpleTimer2 timer, PacketQueue queue, ConnectionPacketHandler handler, ConnectionOptions opts, boolean isInbound)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) void
ackImmediately()
List<PacketLocal>
ackPackets(long ackThrough, long[] nacks)
Process the acks and nacks received in a packetvoid
closeReceived()
Notify that a close was received.void
disconnect(boolean cleanDisconnect)
Must be called when we are done with this connection.void
disconnect(boolean cleanDisconnect, boolean removeFromConMgr)
Must be called when we are done with this connection.void
disconnectComplete()
Must be called when we are done with this connection.(package private) void
eventOccurred()
long
getAckedPackets()
how many packets have we sent and the other side has ACKed?long
getCloseReceivedOn()
long
getCloseSentOn()
long
getCongestionWindowEnd()
String
getConnectionError()
ConnectionManager
getConnectionManager()
long
getCreatedOn()
long
getDisconnectScheduledOn()
boolean
getHardDisconnected()
long
getHighestAckedThrough()
MessageInputStream
getInputStream()
stream that the local peer receives data onboolean
getIsConnected()
Always true at the start, even if we haven't gotten a reply on an outbound connection.long
getLastActivityOn()
long
getLastSendId()
What was the last packet Id sent to the peer?long
getLastSendTime()
When did we last send anything to the peer?long
getLifetime()
long
getLifetimeBytesReceived()
long
getLifetimeBytesSent()
long
getLifetimeDupMessagesReceived()
long
getLifetimeDupMessagesSent()
int
getLocalPort()
long
getNextOutboundPacketNum()
long
getNextSendTime()
Time when the scheduler next want to send a packet, or -1 if never.ConnectionOptions
getOptions()
Retrieve the current ConnectionOptions.MessageOutputStream
getOutputStream()
stream that the local peer sends data to the remote peer onConnectionPacketHandler
getPacketHandler()
int
getPort()
The remote port.long
getReceiveStreamId()
The stream ID of a peer connection that sends data to us, or zero if unknown.Destination
getRemotePeer()
who are we talking withSigningPublicKey
getRemoteSPK()
The key to verify signatures with.boolean
getResetReceived()
boolean
getResetSent()
long
getResetSentOn()
long
getSendStreamId()
What stream do we send data to the peer on?I2PSession
getSession()
I2PSocketFull
getSocket()
(package private) int
getSSThresh()
int
getUnackedPacketsReceived()
int
getUnackedPacketsSent()
how many packets have we sent but not yet received an ACK for?void
incrementBytesReceived(int bytes)
void
incrementBytesSent(int bytes)
void
incrementDupMessagesReceived(int msgs)
void
incrementDupMessagesSent(int msgs)
void
incrementUnackedPacketsReceived()
boolean
isChoked()
Is the other side choking us?boolean
isInbound()
(package private) Connection.ResendPacketEvent
newResendPacketEvent(PacketLocal packet)
A new ResendPacketEvent.void
notifyCloseSent()
Notify that a close was sent.void
notifyLastPacketAcked()
Notify that a close that we sent, and all previous packets, were acked.(package private) void
packetReceived()
boolean
packetSendChoke(long timeoutMs)
This doesn't "send a choke".void
resetReceived()
Notify that a reset was received.void
schedule(SimpleTimer.TimedEvent event, long msToWait)
Schedule something on our timer.void
scheduleConnectionEvent(long msToWait)
Called from SchedulerImpl(package private) void
sendAvailable()
Flush any data that we can.(package private) void
sendPacket(PacketLocal packet)
This sends all 'normal' packets (acks and data) for the first time.void
setChoked(boolean on)
Set or clear if we are being choked by the other side.void
setChoking(boolean on)
Set or clear if we are choking the other side.void
setCongestionWindowEnd(long endMsg)
void
setConnectionError(String err)
void
setLastSendId(long id)
Set the packet Id that was sent to a peer.void
setNextSendTime(long when)
If the next send time is currently >= 0 (i.e.void
setOptions(ConnectionOptions opts)
Set the ConnectionOptions.void
setReceiveStreamId(long id)
void
setRemotePeer(Destination peer)
void
setRemoteTransientSPK(SigningPublicKey transientSPK)
void
setSendStreamId(long id)
void
setSocket(I2PSocketFull socket)
String
toString()
void
updateShareOpts()
(package private) void
waitForConnect()
wait until a connection is made or the connection fails within the timeout period, setting the error accordingly.(package private) void
windowAdjusted()
Notify all threads waiting in packetSendChoke()
-
-
-
Field Detail
-
MAX_RESEND_DELAY
public static final int MAX_RESEND_DELAY
- See Also:
- Constant Field Values
-
MIN_RESEND_DELAY
public static final int MIN_RESEND_DELAY
- See Also:
- Constant Field Values
-
DISCONNECT_TIMEOUT
public static final int DISCONNECT_TIMEOUT
Wait up to 5 minutes after disconnection so we can ack/close packets. Roughly equal to the TIME-WAIT time in RFC 793, where the recommendation is 4 minutes (2 * MSL)- See Also:
- Constant Field Values
-
DEFAULT_CONNECT_TIMEOUT
public static final int DEFAULT_CONNECT_TIMEOUT
- See Also:
- Constant Field Values
-
MAX_WINDOW_SIZE
public static final int MAX_WINDOW_SIZE
- See Also:
- Constant Field Values
-
FAST_RETRANSMIT_THRESHOLD
static final int FAST_RETRANSMIT_THRESHOLD
If we have been explicitly NACKed three times, retransmit the packet even if there are other packets in flight.- See Also:
- Constant Field Values
-
-
Constructor Detail
-
Connection
public Connection(I2PAppContext ctx, ConnectionManager manager, I2PSession session, SchedulerChooser chooser, SimpleTimer2 timer, PacketQueue queue, ConnectionPacketHandler handler, ConnectionOptions opts, boolean isInbound)
- Parameters:
opts
- may be null
-
-
Method Detail
-
getSSThresh
int getSSThresh()
- Since:
- 0.9.46
-
getNextOutboundPacketNum
public long getNextOutboundPacketNum()
-
packetSendChoke
public boolean packetSendChoke(long timeoutMs) throws IOException, InterruptedException
This doesn't "send a choke". Rather, it blocks if the outbound window is full, thus choking the sender that calls this. Block until there is an open outbound packet slot or the write timeout expires. PacketLocal is the only caller, generally with -1.- Parameters:
timeoutMs
- 0 or negative means wait forever, 5 minutes max- Returns:
- true if the packet should be sent, false for a fatal error will return false after 5 minutes even if timeoutMs is <= 0.
- Throws:
IOException
InterruptedException
-
windowAdjusted
void windowAdjusted()
Notify all threads waiting in packetSendChoke()
-
ackImmediately
void ackImmediately()
-
sendAvailable
void sendAvailable()
Flush any data that we can. Non-blocking.
-
sendPacket
void sendPacket(PacketLocal packet)
This sends all 'normal' packets (acks and data) for the first time. Retransmits are done in ResendPacketEvent below. Resets, pings, and pongs are done elsewhere in this class, or in ConnectionManager or ConnectionHandler.
-
ackPackets
public List<PacketLocal> ackPackets(long ackThrough, long[] nacks)
Process the acks and nacks received in a packet- Returns:
- List of packets acked for the first time, or null if none
-
eventOccurred
void eventOccurred()
-
notifyCloseSent
public void notifyCloseSent()
Notify that a close was sent. Called by CPH. May be called multiple times... but shouldn't be.
-
closeReceived
public void closeReceived()
Notify that a close was received. Called by CPH. May be called multiple times.
-
notifyLastPacketAcked
public void notifyLastPacketAcked()
Notify that a close that we sent, and all previous packets, were acked. Called by CPH. Only call this once.- Since:
- 0.9.9
-
resetReceived
public void resetReceived()
Notify that a reset was received. May be called multiple times.
-
getResetReceived
public boolean getResetReceived()
-
isInbound
public boolean isInbound()
-
getIsConnected
public boolean getIsConnected()
Always true at the start, even if we haven't gotten a reply on an outbound connection. Only set to false on disconnect. For outbound, use getHighestAckedThrough() >= 0 also, to determine if the connection is up. In general, this is true until either: - CLOSE received and CLOSE sent and our CLOSE is acked - RESET received or sent - closed on the socket side
-
getHardDisconnected
public boolean getHardDisconnected()
-
getResetSent
public boolean getResetSent()
-
getResetSentOn
public long getResetSentOn()
- Returns:
- 0 if not sent
-
getDisconnectScheduledOn
public long getDisconnectScheduledOn()
- Returns:
- 0 if not scheduled
-
disconnect
public void disconnect(boolean cleanDisconnect)
Must be called when we are done with this connection. Enters TIME-WAIT if necessary, and removes from connection manager. May be called multiple times. This closes the socket side. In normal operation, this is called when a CLOSE has been received, AND a CLOSE has been sent, AND EITHER: received close before sent close AND our CLOSE has been acked OR received close after sent close.- Parameters:
cleanDisconnect
- if true, normal close; if false, send a RESET
-
disconnect
public void disconnect(boolean cleanDisconnect, boolean removeFromConMgr)
Must be called when we are done with this connection. May be called multiple times. This closes the socket side. In normal operation, this is called when a CLOSE has been received, AND a CLOSE has been sent, AND EITHER: received close before sent close AND our CLOSE has been acked OR received close after sent close.- Parameters:
cleanDisconnect
- if true, normal close; if false, send a RESETremoveFromConMgr
- if true, enters TIME-WAIT if necessary. if false, MUST call disconnectComplete() later. Should always be true unless called from ConnectionManager.
-
disconnectComplete
public void disconnectComplete()
Must be called when we are done with this connection. Final disconnect. Remove from conn manager. May be called multiple times.
-
scheduleConnectionEvent
public void scheduleConnectionEvent(long msToWait)
Called from SchedulerImpl- Since:
- 0.9.23 moved here so we can use our timer
-
schedule
public void schedule(SimpleTimer.TimedEvent event, long msToWait)
Schedule something on our timer.- Since:
- 0.9.23
-
getRemotePeer
public Destination getRemotePeer()
who are we talking with- Returns:
- peer Destination or null if unset
-
setRemotePeer
public void setRemotePeer(Destination peer)
- Parameters:
peer
- non-null
-
getRemoteSPK
public SigningPublicKey getRemoteSPK()
The key to verify signatures with. The transient SPK if previously received, else getRemotePeer().getSigningPublicKey() if previously received, else null.- Returns:
- peer Destination or null if unset
- Since:
- 0.9.39
-
setRemoteTransientSPK
public void setRemoteTransientSPK(SigningPublicKey transientSPK)
- Parameters:
transientSPK
- null ok- Since:
- 0.9.39
-
getSendStreamId
public long getSendStreamId()
What stream do we send data to the peer on?- Returns:
- non-global stream sending ID, or 0 if unknown
-
setSendStreamId
public void setSendStreamId(long id)
- Parameters:
id
- 0 to 0xffffffff- Throws:
IllegalStateException
- if already set to nonzero
-
getReceiveStreamId
public long getReceiveStreamId()
The stream ID of a peer connection that sends data to us, or zero if unknown.- Returns:
- receive stream ID, or 0 if unknown
-
setReceiveStreamId
public void setReceiveStreamId(long id)
- Parameters:
id
- 0 to 0xffffffff- Throws:
IllegalStateException
- if already set to nonzero
-
getLastSendTime
public long getLastSendTime()
When did we last send anything to the peer?- Returns:
- Last time we sent data
-
getLastSendId
public long getLastSendId()
What was the last packet Id sent to the peer?- Returns:
- The last sent packet ID
-
setLastSendId
public void setLastSendId(long id)
Set the packet Id that was sent to a peer.- Parameters:
id
- The packet ID
-
getOptions
public ConnectionOptions getOptions()
Retrieve the current ConnectionOptions.- Returns:
- the current ConnectionOptions, non-null
-
setOptions
public void setOptions(ConnectionOptions opts)
Set the ConnectionOptions.- Parameters:
opts
- ConnectionOptions non-null
-
getConnectionManager
public ConnectionManager getConnectionManager()
- Since:
- 0.9.21
-
getSession
public I2PSession getSession()
-
getSocket
public I2PSocketFull getSocket()
-
setSocket
public void setSocket(I2PSocketFull socket)
-
getPort
public int getPort()
The remote port.- Returns:
- Default I2PSession.PORT_UNSPECIFIED (0) or PORT_ANY (0)
- Since:
- 0.8.9
-
getLocalPort
public int getLocalPort()
- Returns:
- Default I2PSession.PORT_UNSPECIFIED (0) or PORT_ANY (0)
- Since:
- 0.8.9
-
getConnectionError
public String getConnectionError()
-
setConnectionError
public void setConnectionError(String err)
-
getLifetime
public long getLifetime()
-
getPacketHandler
public ConnectionPacketHandler getPacketHandler()
-
getLifetimeBytesSent
public long getLifetimeBytesSent()
-
getLifetimeBytesReceived
public long getLifetimeBytesReceived()
-
getLifetimeDupMessagesSent
public long getLifetimeDupMessagesSent()
-
getLifetimeDupMessagesReceived
public long getLifetimeDupMessagesReceived()
-
incrementBytesSent
public void incrementBytesSent(int bytes)
-
incrementDupMessagesSent
public void incrementDupMessagesSent(int msgs)
-
incrementBytesReceived
public void incrementBytesReceived(int bytes)
-
incrementDupMessagesReceived
public void incrementDupMessagesReceived(int msgs)
-
getNextSendTime
public long getNextSendTime()
Time when the scheduler next want to send a packet, or -1 if never. This should be set when we want to send on timeout, for instance, or want to delay an ACK.- Returns:
- the next time the scheduler will want to send a packet, or -1 if never.
-
setNextSendTime
public void setNextSendTime(long when)
If the next send time is currently >= 0 (i.e. not "never"), this may make the next time sooner but will not make it later. If the next send time is currently < 0 (i.e. "never"), this will set it to the time specified, but not later than options.getSendAckDelay() from now (1000 ms)
-
setChoking
public void setChoking(boolean on)
Set or clear if we are choking the other side. If on is true or the value has changed, this will call ackImmediately().- Parameters:
on
- true for choking- Since:
- 0.9.29
-
setChoked
public void setChoked(boolean on)
Set or clear if we are being choked by the other side.- Parameters:
on
- true for choked- Since:
- 0.9.29
-
isChoked
public boolean isChoked()
Is the other side choking us?- Returns:
- if choked
- Since:
- 0.9.29
-
getAckedPackets
public long getAckedPackets()
how many packets have we sent and the other side has ACKed?- Returns:
- Count of how many packets ACKed.
-
getCreatedOn
public long getCreatedOn()
-
getCloseSentOn
public long getCloseSentOn()
- Returns:
- 0 if not sent
-
getCloseReceivedOn
public long getCloseReceivedOn()
- Returns:
- 0 if not received
-
updateShareOpts
public void updateShareOpts()
-
incrementUnackedPacketsReceived
public void incrementUnackedPacketsReceived()
-
getUnackedPacketsReceived
public int getUnackedPacketsReceived()
-
getUnackedPacketsSent
public int getUnackedPacketsSent()
how many packets have we sent but not yet received an ACK for?- Returns:
- Count of packets in-flight.
-
getCongestionWindowEnd
public long getCongestionWindowEnd()
-
setCongestionWindowEnd
public void setCongestionWindowEnd(long endMsg)
-
getHighestAckedThrough
public long getHighestAckedThrough()
- Returns:
- the highest outbound packet we have recieved an ack for
-
getLastActivityOn
public long getLastActivityOn()
-
packetReceived
void packetReceived()
-
waitForConnect
void waitForConnect()
wait until a connection is made or the connection fails within the timeout period, setting the error accordingly.
-
getInputStream
public MessageInputStream getInputStream()
stream that the local peer receives data on- Returns:
- the inbound message stream, non-null
-
getOutputStream
public MessageOutputStream getOutputStream()
stream that the local peer sends data to the remote peer on- Returns:
- the outbound message stream, non-null
-
newResendPacketEvent
Connection.ResendPacketEvent newResendPacketEvent(PacketLocal packet)
A new ResendPacketEvent.- Since:
- 0.9.46
-
-