- All Implemented Interfaces:
Closeable, AutoCloseable, I2PSessionListener, I2PSessionMuxedListener, SAMDatagramReceiver, SAMMessageSess, SAMRawReceiver, Session
Extends SAMv3StreamSession to inherit the I2PSession setup; the streaming acceptor thread (StreamAcceptor) accepts I2P connections and dispatches them to the correct subsession by protocol and port, via SAMv3StreamSession.queueSocket(I2PSocket).
The master session itself is not directly usable for data transfer. All streaming, datagram, and raw operations are delegated to registered subsessions. Calling connectAsync(SAMv3Handler, String, Properties), accept(SAMv3Handler, boolean), or startForwardingIncoming(Properties, boolean) on this instance throws unconditionally.
Under heavy tracker traffic, the accept loop may see thousands of connections per minute. Overflow logging is rate-limited to avoid flooding the router log when subsession queues fill faster than clients can consume.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classAcceptor thread that waits for incoming I2P streaming connections and dispatches them to the appropriate subsession by matching the local port to the subsession's listen port.Nested classes/interfaces inherited from class SAMStreamSession
SAMStreamSession.DisconnectListener, SAMStreamSession.SAMStreamSessionServer, SAMStreamSession.SAMStreamSessionSocketReader, SAMStreamSession.SAMv1StreamSessionSocketReader, SAMStreamSession.StreamSenderModifier and TypeClassDescriptionprotected classCloses SAM session when the underlying I2P manager disconnects.classSAM STREAM session server, running in its own thread.static classReads bytes off one tunnel socket and pushes them to the SAM client.classSAMv1StreamSessionSocketReader.protected static classLets us push data through the stream without blocking, (even after exceeding the I2PSocket's buffer).Field Summary
FieldsModifier and TypeFieldDescriptionprivate longWhen the session overflow was last logged.private intSessions over the limit since the last log.private final SAMv3DatagramServerThe server for the datagram sessions.private final SAMv3HandlerThe handler serving the SAM sessions.private static final String[]Session options that are not allowed.private static final longLog overflow warnings at most once per 5 seconds to avoid flooding.private final Map<String, SAMMessageSess> The message sessions, by name.private final MasterSession.StreamAcceptorThe thread accepting the stream connections.Fields inherited from class SAMStreamSession
_isOwnSession, _log, canCreate, DEFAULT_FORCE_FLUSH, forceFlush, PROP_FORCE_FLUSH, recv, server, SOCKET_HANDLER_BUF_SIZE, socketMgrModifier and TypeFieldDescriptionprotected final booleanWhether this is our own session, as opposed to a remote peer's.protected final LogLogger for this session's messages.protected final booleanWhether this session may create outgoing connections.static final StringDefault forSAMStreamSession.PROP_FORCE_FLUSH.protected final booleanShould we flush every time we get a STREAM SEND, or leave that up to the streaming lib to decide?static final StringConfig key for flushing on every STREAM SEND.protected final SAMStreamReceiverThe receiver that decodes incoming SAM messages.protected final SAMStreamSession.SAMStreamSessionServerThe server this session belongs to.protected static final intRead buffer size for each socket reader.protected final I2PSocketManagerThe socket manager used for outgoing connections.Constructor Summary
ConstructorsConstructorDescriptionMasterSession(String nick, SAMv3DatagramServer dgServer, SAMv3Handler handler, Properties props) Build a Session according to information registered with the given nickname.Method Summary
Modifier and TypeMethodDescriptionvoidaccept(SAMv3Handler handler, boolean verbose) Throws, use a STREAM subsession instead.add(String nick, String style, Properties props) Add a protocol subsession (STREAM, DATAGRAM, or RAW) to this master session.voidclose()Close the master session and all registered subsessions.voidconnectAsync(SAMv3Handler handler, String dest, Properties props) Throws, use a STREAM subsession instead.voiddisconnected(I2PSession session) Called when the I2P session is disconnected, from the session muxed interface.voiderrorOccurred(I2PSession session, String message, Throwable error) Called when an I2P error occurs.intGet the port for this session's listener.int// SAMMessageSess interfacevoidmessageAvailable(I2PSession session, int msgId, long size) Called when a message is available (unmuxed).voidmessageAvailable(I2PSession session, int msgId, long size, int proto, int fromPort, int toPort) Called when a muxed message is available.private voidmessageReceived(byte[] msg, int proto, int fromPort, int toPort) Handle a received message.voidreceiveDatagramBytes(Destination sender, byte[] data, int proto, int fromPort, int toPort) ThrowsIOException— the master session does not handle datagram data directly; use a DATAGRAM subsession instead.voidreceiveRawBytes(byte[] data, int proto, int fromPort, int toPort) ThrowsIOException— the master session does not handle raw data directly; use a RAW subsession instead.remove(String nick, Properties props) Remove a protocol subsession by nickname.voidreportAbuse(I2PSession session, int severity) Called when abuse is reported on the session.voidstart()Start the stream acceptor thread.voidstartForwardingIncoming(Properties props, boolean sendPorts) Throws, use a STREAM subsession instead.voidNo-op — master delegates datagram handling to subsessions.voidDoes nothing.voidNo-op, the master session does not receive raw data.Methods inherited from class SAMv3StreamSession
getAcceptQueueSize, getDB, getNick, getSocketServer, queueSocketModifier and TypeMethodDescriptionintReturn how many accepted sockets are waiting to be handed to the client.static SessionsDBgetDB()Get the global sessions database shared by all SAM handlers.getNick()Return the nickname this session is registered under.protected I2PServerSocketReturn the server socket this session accepts incoming I2P connections on.booleanqueueSocket(I2PSocket sock) Put a socket on the accept queue.Methods inherited from class SAMStreamSession
checkSocketHandlerId, closeConnection, connect, createSocketHandler, getDestination, getSocketReader, isDestroyed, lookupDest, newSAMStreamSessionSocketReader, newStreamSender, removeSocketHandler, sendBytes, sendBytes, sendBytes, setReceiveLimitModifier and TypeMethodDescriptionprotected booleancheckSocketHandlerId(int id) Check whether a SAM STREAM session socket handler id is still in use.booleancloseConnection(int id) Close a connection managed by the SAM STREAM session.booleanconnect(int id, String dest, Properties props) Connect the SAM STREAM session to the specified Destination.protected intcreateSocketHandler(I2PSocket s, int id) Create a new SAM STREAM session socket handler, detaching its thread.Get the SAM STREAM session Destination.getSocketReader(int id) Get a SAM STREAM session socket handler.booleanIs the underlying streaming socket manager destroyed?lookupDest(String name) Lookup a destination through the I2CP session.newSAMStreamSessionSocketReader(I2PSocket s, int id) Create a new SAM STREAM session socket reader.protected SAMStreamSession.StreamSendernewStreamSender(I2PSocket s, int id) Creates the sender that writes this socket's outgoing data.protected voidremoveSocketHandler(int id) Remove and gracefully close a SAM STREAM session socket handler.booleansendBytes(int id, InputStream in, int size) Send bytes through a SAM STREAM session.booleanSending bytes is not supported in a STREAM or MASTER session; always throws.booleansendBytes(String s, byte[] b, int pr, int fp, int tp, boolean sendLeaseSet, int sendTags, int tagThreshold, int expiration) Sending bytes is not supported in a STREAM or MASTER session; always throws.(package private) booleansetReceiveLimit(int id, long limit, boolean nolimit) Set a receive limit for a stream.
Field Details
handler
The handler serving the SAM sessions.dgs
The server for the datagram sessions.sessions
The message sessions, by name.streamAcceptor
The thread accepting the stream connections.INVALID_OPTS
Session options that are not allowed.OVERFLOW_LOG_INTERVAL_MS
private static final long OVERFLOW_LOG_INTERVAL_MSLog overflow warnings at most once per 5 seconds to avoid flooding.- See Also:
_lastOverflowLog
private volatile long _lastOverflowLogWhen the session overflow was last logged._overflowCount
private volatile int _overflowCountSessions over the limit since the last log.
Constructor Details
MasterSession
public MasterSession(String nick, SAMv3DatagramServer dgServer, SAMv3Handler handler, Properties props) throws IOException, DataFormatException, SAMException Build a Session according to information registered with the given nickname.Caller MUST call
start().- Parameters:
nick- nickname of the sessiondgServer- the datagram server that raw and datagram subsessions register withhandler- the SAMv3 handler this session answers commands fromprops- the MASTER session options, which may not include any of the subsession-only keys such as PORT or PROTOCOL- Throws:
IOException- declared by the SAMv3StreamSession constructor called here, but not raised by this bodyDataFormatException- likewise declared but not raised by this bodySAMException- if props names an option that only a subsession may set
Method Details
start
public void start()Start the stream acceptor thread. Must be called after construction.- Specified by:
startin interfaceSAMMessageSess- Overrides:
startin classSAMStreamSession
add
Add a protocol subsession (STREAM, DATAGRAM, or RAW) to this master session. The subsession gets its own protocol/port binding and is registered in the global sessions database so incoming connections can be dispatched to it.Sessions are mutually exclusive on (protocol, port) — two subsessions may not listen on the same protocol and port.
- Parameters:
nick- unique nickname for this subsessionstyle- protocol style: "STREAM", "DATAGRAM", or "RAW"props- session properties (PORT required for DATAGRAM/RAW; LISTEN_PORT, LISTEN_PROTOCOL optional)- Returns:
- null on success, or a descriptive error message
remove
Remove a protocol subsession by nickname. The session is closed, removed from the global sessions database, and its port binding is released.- Parameters:
nick- nickname of the subsession to removeprops- session properties (unused, may be null)- Returns:
- null on success, or a descriptive error message
receiveDatagramBytes
public void receiveDatagramBytes(Destination sender, byte[] data, int proto, int fromPort, int toPort) throws IOException ThrowsIOException— the master session does not handle datagram data directly; use a DATAGRAM subsession instead.- Specified by:
receiveDatagramBytesin interfaceSAMDatagramReceiver- Parameters:
sender- the destination the datagram arrived fromdata- Byte array to be receivedproto- I2CP protocolfromPort- I2CP from porttoPort- I2CP to port- Throws:
IOException- always, on every call
stopDatagramReceiving
public void stopDatagramReceiving()No-op — master delegates datagram handling to subsessions.- Specified by:
stopDatagramReceivingin interfaceSAMDatagramReceiver
receiveRawBytes
ThrowsIOException— the master session does not handle raw data directly; use a RAW subsession instead.- Specified by:
receiveRawBytesin interfaceSAMRawReceiver- Parameters:
data- Byte array to be receivedproto- I2CP protocolfromPort- I2CP from porttoPort- I2CP to port- Throws:
IOException- always, on every call
stopRawReceiving
public void stopRawReceiving()No-op, the master session does not receive raw data.- Specified by:
stopRawReceivingin interfaceSAMRawReceiver
connectAsync
public void connectAsync(SAMv3Handler handler, String dest, Properties props) throws DataFormatException Throws, use a STREAM subsession instead.- Overrides:
connectAsyncin classSAMv3StreamSession- Parameters:
handler- handler whose socket becomes the I2P data pipedest- the Base64-encoded destination to connect toprops- the connection options read from the STREAM CONNECT command- Throws:
DataFormatException- always, the master session does not connect
accept
Throws, use a STREAM subsession instead.- Overrides:
acceptin classSAMv3StreamSession- Parameters:
handler- handler whose socket becomes the I2P data pipeverbose- if true, send peer Destination as first line- Throws:
SAMException- always, the master session does not do this
startForwardingIncoming
Throws, use a STREAM subsession instead.- Overrides:
startForwardingIncomingin classSAMv3StreamSession- Parameters:
props- session properties supplying HOST, PORT, SSL, and SILENTsendPorts- true to report the local port back to the client- Throws:
SAMException- always, the master session does not do this
stopForwardingIncoming
public void stopForwardingIncoming()Does nothing.- Overrides:
stopForwardingIncomingin classSAMv3StreamSession
getListenProtocol
public int getListenProtocol()// SAMMessageSess interface- Specified by:
getListenProtocolin interfaceSAMMessageSess- Overrides:
getListenProtocolin classSAMStreamSession- Returns:
- the I2CP protocol
getListenPort
public int getListenPort()Description copied from class:SAMStreamSessionGet the port for this session's listener.- Specified by:
getListenPortin interfaceSAMMessageSess- Overrides:
getListenPortin classSAMStreamSession- Returns:
- the listen port
close
public void close()Close the master session and all registered subsessions. Stops the stream acceptor thread, removes all subsessions from the global sessions database, and destroys the underlying I2PSocketManager.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Specified by:
closein interfaceSAMMessageSess- Overrides:
closein classSAMv3StreamSession
disconnected
Called when the I2P session is disconnected, from the session muxed interface.- Specified by:
disconnectedin interfaceI2PSessionListener- Specified by:
disconnectedin interfaceI2PSessionMuxedListener- Parameters:
session- the disconnected session
errorOccurred
Called when an I2P error occurs.- Specified by:
errorOccurredin interfaceI2PSessionListener- Specified by:
errorOccurredin interfaceI2PSessionMuxedListener- Parameters:
session- the session that reported the errormessage- human-readable description of the failure, loggederror- the exception, if any
messageAvailable
Called when a message is available (unmuxed).- Specified by:
messageAvailablein interfaceI2PSessionListener- Specified by:
messageAvailablein interfaceI2PSessionMuxedListener- Parameters:
session- the session the message arrived onmsgId- the message IDsize- the message size
messageAvailable
public void messageAvailable(I2PSession session, int msgId, long size, int proto, int fromPort, int toPort) Called when a muxed message is available.- Specified by:
messageAvailablein interfaceI2PSessionMuxedListener- Parameters:
session- the session the muxed message arrived onmsgId- the message IDsize- the message sizeproto- the protocol numberfromPort- the source porttoPort- the destination port
reportAbuse
Called when abuse is reported on the session.- Specified by:
reportAbusein interfaceI2PSessionListener- Specified by:
reportAbusein interfaceI2PSessionMuxedListener- Parameters:
session- the session the abuse was reported onseverity- the abuse severity level
messageReceived
private void messageReceived(byte[] msg, int proto, int fromPort, int toPort) Handle a received message. Logs a warning for unhandled messages.- Parameters:
msg- the message bytesproto- the protocol numberfromPort- the source porttoPort- the destination port