javadoc
This commit is contained in:
@ -6,6 +6,11 @@ import net.i2p.I2PAppContext;
|
|||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Receive data from the MessageOutputStream, build a packet,
|
||||||
|
* and send it through a connection. The write calls on this
|
||||||
|
* do NOT block, but they also do not necessary imply immediate
|
||||||
|
* delivery, or even the generation of a new packet. This class
|
||||||
|
* is the only one that builds useful outbound Packet objects.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||||
@ -21,6 +26,17 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
|||||||
_dummyStatus = new DummyStatus();
|
_dummyStatus = new DummyStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send some data through the connection, or if there is no new data, this
|
||||||
|
* may generate a packet with a plain ACK/NACK or CLOSE, or nothing whatsoever
|
||||||
|
* if there's nothing new to send.
|
||||||
|
*
|
||||||
|
* @param buf data to be sent - may be null
|
||||||
|
* @param off offset into the buffer to start writing from
|
||||||
|
* @param size how many bytes of the buffer to write (may be 0)
|
||||||
|
* @return an object to allow optional blocking for data acceptance or
|
||||||
|
* delivery.
|
||||||
|
*/
|
||||||
public MessageOutputStream.WriteStatus writeData(byte[] buf, int off, int size) {
|
public MessageOutputStream.WriteStatus writeData(byte[] buf, int off, int size) {
|
||||||
boolean doSend = true;
|
boolean doSend = true;
|
||||||
if ( (size <= 0) && (_connection.getLastSendId() >= 0) ) {
|
if ( (size <= 0) && (_connection.getLastSendId() >= 0) ) {
|
||||||
@ -54,12 +70,25 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send some data through the connection, attaching any appropriate flags
|
||||||
|
* onto the packet.
|
||||||
|
*
|
||||||
|
* @param buf data to be sent - may be null
|
||||||
|
* @param off offset into the buffer to start writing from
|
||||||
|
* @param size how many bytes of the buffer to write (may be 0)
|
||||||
|
* @return the packet sent
|
||||||
|
*/
|
||||||
public PacketLocal send(byte buf[], int off, int size) {
|
public PacketLocal send(byte buf[], int off, int size) {
|
||||||
return send(buf, off, size, false);
|
return send(buf, off, size, false);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
* @param buf data to be sent - may be null
|
||||||
|
* @param off offset into the buffer to start writing from
|
||||||
|
* @param size how many bytes of the buffer to write (may be 0)
|
||||||
* @param forceIncrement even if the buffer is empty, increment the packetId
|
* @param forceIncrement even if the buffer is empty, increment the packetId
|
||||||
* so we get an ACK back
|
* so we get an ACK back
|
||||||
|
* @return the packet sent
|
||||||
*/
|
*/
|
||||||
public PacketLocal send(byte buf[], int off, int size, boolean forceIncrement) {
|
public PacketLocal send(byte buf[], int off, int size, boolean forceIncrement) {
|
||||||
PacketLocal packet = buildPacket(buf, off, size, forceIncrement);
|
PacketLocal packet = buildPacket(buf, off, size, forceIncrement);
|
||||||
@ -123,7 +152,9 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used if no new packet was sent.
|
||||||
|
*/
|
||||||
private static final class DummyStatus implements MessageOutputStream.WriteStatus {
|
private static final class DummyStatus implements MessageOutputStream.WriteStatus {
|
||||||
public final void waitForAccept(int maxWaitMs) { return; }
|
public final void waitForAccept(int maxWaitMs) { return; }
|
||||||
public final void waitForCompletion(int maxWaitMs) { return; }
|
public final void waitForCompletion(int maxWaitMs) { return; }
|
||||||
|
@ -50,6 +50,14 @@ class ConnectionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive an incoming connection (built from a received SYN)
|
||||||
|
*
|
||||||
|
* @param timeoutMs max amount of time to wait for a connection (if less
|
||||||
|
* than 1ms, wait indefinitely)
|
||||||
|
* @return connection received, or null if there was a timeout or the
|
||||||
|
* handler was shut down
|
||||||
|
*/
|
||||||
public Connection accept(long timeoutMs) {
|
public Connection accept(long timeoutMs) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Accept("+ timeoutMs+") called");
|
_log.debug("Accept("+ timeoutMs+") called");
|
||||||
|
@ -91,6 +91,7 @@ public class ConnectionManager {
|
|||||||
public void setAllowIncomingConnections(boolean allow) {
|
public void setAllowIncomingConnections(boolean allow) {
|
||||||
_connectionHandler.setActive(allow);
|
_connectionHandler.setActive(allow);
|
||||||
}
|
}
|
||||||
|
/** should we acceot connections, or just reject everyone? */
|
||||||
public boolean getAllowIncomingConnections() {
|
public boolean getAllowIncomingConnections() {
|
||||||
return _connectionHandler.getActive();
|
return _connectionHandler.getActive();
|
||||||
}
|
}
|
||||||
@ -262,6 +263,10 @@ public class ConnectionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop the (already closed) connection on the floor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public void removeConnection(Connection con) {
|
public void removeConnection(Connection con) {
|
||||||
boolean removed = false;
|
boolean removed = false;
|
||||||
synchronized (_connectionLock) {
|
synchronized (_connectionLock) {
|
||||||
@ -287,6 +292,7 @@ public class ConnectionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** return a set of Connection objects */
|
||||||
public Set listConnections() {
|
public Set listConnections() {
|
||||||
synchronized (_connectionLock) {
|
synchronized (_connectionLock) {
|
||||||
return new HashSet(_connectionByInboundId.values());
|
return new HashSet(_connectionByInboundId.values());
|
||||||
|
@ -7,6 +7,8 @@ import net.i2p.client.I2PSessionException;
|
|||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Receive raw information from the I2PSession and turn it into
|
||||||
|
* Packets, if we can.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MessageHandler implements I2PSessionListener {
|
public class MessageHandler implements I2PSessionListener {
|
||||||
|
@ -10,7 +10,9 @@ import net.i2p.util.ByteCache;
|
|||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A stream that we can shove data into that fires off those bytes
|
||||||
|
* on flush or when the buffer is full. It also blocks according
|
||||||
|
* to the data receiver's needs.
|
||||||
*/
|
*/
|
||||||
public class MessageOutputStream extends OutputStream {
|
public class MessageOutputStream extends OutputStream {
|
||||||
private I2PAppContext _context;
|
private I2PAppContext _context;
|
||||||
@ -104,6 +106,13 @@ public class MessageOutputStream extends OutputStream {
|
|||||||
throwAnyError();
|
throwAnyError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush the data already queued up, blocking until it has been
|
||||||
|
* delivered.
|
||||||
|
*
|
||||||
|
* @throws IOException if the write fails
|
||||||
|
* @throws InterruptedIOException if the write times out
|
||||||
|
*/
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
WriteStatus ws = null;
|
WriteStatus ws = null;
|
||||||
synchronized (_dataLock) {
|
synchronized (_dataLock) {
|
||||||
@ -148,6 +157,7 @@ public class MessageOutputStream extends OutputStream {
|
|||||||
_dataCache.release(ba);
|
_dataCache.release(ba);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** nonblocking close */
|
||||||
public void closeInternal() {
|
public void closeInternal() {
|
||||||
_closed = true;
|
_closed = true;
|
||||||
_streamError = new IOException("Closed internally");
|
_streamError = new IOException("Closed internally");
|
||||||
@ -217,6 +227,7 @@ public class MessageOutputStream extends OutputStream {
|
|||||||
_dataReceiver = null;
|
_dataReceiver = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Define a component to receive data flushed from this stream */
|
||||||
public interface DataReceiver {
|
public interface DataReceiver {
|
||||||
/**
|
/**
|
||||||
* Nonblocking write
|
* Nonblocking write
|
||||||
@ -224,6 +235,7 @@ public class MessageOutputStream extends OutputStream {
|
|||||||
public WriteStatus writeData(byte buf[], int off, int size);
|
public WriteStatus writeData(byte buf[], int off, int size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Define a way to detect the status of a write */
|
||||||
public interface WriteStatus {
|
public interface WriteStatus {
|
||||||
/** wait until the data written either fails or succeeds */
|
/** wait until the data written either fails or succeeds */
|
||||||
public void waitForCompletion(int maxWaitMs);
|
public void waitForCompletion(int maxWaitMs);
|
||||||
|
@ -13,6 +13,10 @@ import net.i2p.util.ByteCache;
|
|||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Queue out packets to be sent through the session.
|
||||||
|
* Well, thats the theory at least... in practice we just
|
||||||
|
* send them immediately with no blocking, since the
|
||||||
|
* mode=bestEffort doesnt block in the SDK.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class PacketQueue {
|
class PacketQueue {
|
||||||
|
Reference in New Issue
Block a user