diff --git a/apps/sam/java/src/net/i2p/sam/MasterSession.java b/apps/sam/java/src/net/i2p/sam/MasterSession.java index 9c301ae566..67ff566b56 100644 --- a/apps/sam/java/src/net/i2p/sam/MasterSession.java +++ b/apps/sam/java/src/net/i2p/sam/MasterSession.java @@ -42,7 +42,8 @@ class MasterSession extends SAMv3StreamSession implements SAMDatagramReceiver, S private final SAMv3DatagramServer dgs; private final Map sessions; private final StreamAcceptor streamAcceptor; - private static final String[] INVALID_OPTS = { "PORT", "HOST", "FROM_PORT", "TO_PORT", "PROTOCOL" }; + private static final String[] INVALID_OPTS = { "PORT", "HOST", "FROM_PORT", "TO_PORT", + "PROTOCOL", "LISTEN_PORT", "LISTEN_PROTOCOL" }; /** * Build a Session according to information diff --git a/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java b/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java index e9f289e360..baef6f454c 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java @@ -32,7 +32,6 @@ class SAMDatagramSession extends SAMMessageSession { // FIXME make final after fixing SAMv3DatagramSession override protected SAMDatagramReceiver recv; - private final I2PDatagramMaker dgramMaker; private final I2PDatagramDissector dgramDissector = new I2PDatagramDissector(); @@ -50,7 +49,6 @@ class SAMDatagramSession extends SAMMessageSession { SAMDatagramReceiver recv) throws IOException, DataFormatException, I2PSessionException { super(dest, props); - this.recv = recv; dgramMaker = new I2PDatagramMaker(getI2PSession()); } @@ -71,7 +69,6 @@ class SAMDatagramSession extends SAMMessageSession { SAMDatagramReceiver recv) throws IOException, DataFormatException, I2PSessionException { super(destStream, props); - this.recv = recv; dgramMaker = new I2PDatagramMaker(getI2PSession()); } @@ -79,13 +76,13 @@ class SAMDatagramSession extends SAMMessageSession { /** * Create a new SAM DATAGRAM session on an existing I2P session. * + * @param props unused for now * @since 0.9.25 */ - protected SAMDatagramSession(I2PSession sess, int listenPort, + protected SAMDatagramSession(I2PSession sess, Properties props, int listenPort, SAMDatagramReceiver recv) throws IOException, DataFormatException, I2PSessionException { super(sess, I2PSession.PROTO_DATAGRAM, listenPort); - this.recv = recv; dgramMaker = new I2PDatagramMaker(getI2PSession()); } @@ -107,11 +104,31 @@ class SAMDatagramSession extends SAMMessageSession { throw new DataFormatException("Datagram size exceeded (" + data.length + ")"); byte[] dgram ; synchronized (dgramMaker) { - dgram = dgramMaker.makeI2PDatagram(data); + dgram = dgramMaker.makeI2PDatagram(data); } return sendBytesThroughMessageSession(dest, dgram, I2PSession.PROTO_DATAGRAM, fromPort, toPort); } + /** + * Send bytes through a SAM DATAGRAM session. + * + * @since 0.9.25 + */ + public boolean sendBytes(String dest, byte[] data, int proto, + int fromPort, int toPort, + boolean sendLeaseSet, int sendTags, + int tagThreshold, int expiration) + throws DataFormatException, I2PSessionException { + if (data.length > DGRAM_SIZE_MAX) + throw new DataFormatException("Datagram size exceeded (" + data.length + ")"); + byte[] dgram ; + synchronized (dgramMaker) { + dgram = dgramMaker.makeI2PDatagram(data); + } + return sendBytesThroughMessageSession(dest, dgram, I2PSession.PROTO_DATAGRAM, fromPort, toPort, + sendLeaseSet, sendTags,tagThreshold, expiration); + } + protected void messageReceived(byte[] msg, int proto, int fromPort, int toPort) { byte[] payload; Destination sender; diff --git a/apps/sam/java/src/net/i2p/sam/SAMMessageSess.java b/apps/sam/java/src/net/i2p/sam/SAMMessageSess.java index 189a8f6de3..2fc45431f9 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMMessageSess.java +++ b/apps/sam/java/src/net/i2p/sam/SAMMessageSess.java @@ -46,6 +46,17 @@ interface SAMMessageSess extends Closeable { public boolean sendBytes(String dest, byte[] data, int proto, int fromPort, int toPort) throws DataFormatException, I2PSessionException; + /** + * Send bytes through a SAM message-based session. + * + * @since 0.9.25 + */ + public boolean sendBytes(String dest, byte[] data, int proto, + int fromPort, int toPort, + boolean sendLeaseSet, int sendTags, + int tagThreshold, int expiration) + throws DataFormatException, I2PSessionException; + public int getListenProtocol(); public int getListenPort(); diff --git a/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java b/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java index cabed8059d..0bbecb77c7 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java @@ -37,6 +37,7 @@ abstract class SAMMessageSession implements SAMMessageSess { protected final Log _log; private final I2PSession session; + protected final boolean _isOwnSession; private final SAMMessageSessionHandler handler; private final int listenProtocol; private final int listenPort; @@ -69,6 +70,7 @@ abstract class SAMMessageSession implements SAMMessageSess { _log.debug("Initializing SAM message-based session"); listenProtocol = I2PSession.PROTO_ANY; listenPort = I2PSession.PORT_ANY; + _isOwnSession = true; handler = new SAMMessageSessionHandler(destStream, props); session = handler.getSession(); } @@ -90,6 +92,7 @@ abstract class SAMMessageSession implements SAMMessageSess { _log.debug("Initializing SAM message-based session"); this.listenProtocol = listenProtocol; this.listenPort = listenPort; + _isOwnSession = false; session = sess; handler = new SAMMessageSessionHandler(session); } @@ -165,14 +168,19 @@ abstract class SAMMessageSession implements SAMMessageSess { } /** - * Actually send bytes through the SAM message-based session I2PSession. - * TODO unused, umimplemented in the sessions and handlers + * Actually send bytes through the SAM message-based session I2PSession, + * using per-message extended options. + * For efficiency, use the method without all the extra options if they are all defaults. * * @param dest Destination * @param data Bytes to be sent * @param proto I2CP protocol * @param fromPort I2CP from port * @param toPort I2CP to port + * @param sendLeaseSet true is the usual setting and the I2CP default + * @param sendTags 0 to leave as default + * @param tagThreshold 0 to leave as default + * @param expiration SECONDS from now, NOT absolute time, 0 to leave as default * * @return True if the data was sent, false otherwise * @throws DataFormatException on unknown / bad dest @@ -182,7 +190,7 @@ abstract class SAMMessageSession implements SAMMessageSess { protected boolean sendBytesThroughMessageSession(String dest, byte[] data, int proto, int fromPort, int toPort, boolean sendLeaseSet, int sendTags, - int tagThreshold, long expires) + int tagThreshold, int expiration) throws DataFormatException, I2PSessionException { Destination d = SAMUtils.getDest(dest); @@ -190,10 +198,14 @@ abstract class SAMMessageSession implements SAMMessageSess { _log.debug("Sending " + data.length + " bytes to " + dest); } SendMessageOptions opts = new SendMessageOptions(); - opts.setSendLeaseSet(sendLeaseSet); - opts.setTagsToSend(sendTags); - opts.setTagThreshold(tagThreshold); - opts.setDate(expires); + if (!sendLeaseSet) + opts.setSendLeaseSet(false); + if (sendTags > 0) + opts.setTagsToSend(sendTags); + if (tagThreshold > 0) + opts.setTagThreshold(tagThreshold); + if (expiration > 0) + opts.setDate(I2PAppContext.getGlobalContext().clock().now() + (expiration * 1000)); return session.sendMessage(d, data, 0, data.length, proto, fromPort, toPort, opts); } @@ -234,7 +246,6 @@ abstract class SAMMessageSession implements SAMMessageSess { private class SAMMessageSessionHandler implements Runnable, I2PSessionMuxedListener { private final I2PSession _session; - private final boolean _isOwnSession; private final Object runningLock = new Object(); private volatile boolean stillRunning = true; @@ -254,7 +265,6 @@ abstract class SAMMessageSession implements SAMMessageSess { props.setProperty("inbound.nickname", "SAM UDP Client"); props.setProperty("outbound.nickname", "SAM UDP Client"); } - _isOwnSession = true; _session = client.createSession(destStream, props); if (_log.shouldLog(Log.DEBUG)) @@ -272,7 +282,6 @@ abstract class SAMMessageSession implements SAMMessageSess { * @since 0.9.25 */ public SAMMessageSessionHandler(I2PSession sess) throws I2PSessionException { - _isOwnSession = false; _session = sess; _session.addMuxedSessionListener(this, listenProtocol, listenPort); } diff --git a/apps/sam/java/src/net/i2p/sam/SAMRawSession.java b/apps/sam/java/src/net/i2p/sam/SAMRawSession.java index fa2fef9151..3857f92c75 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMRawSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMRawSession.java @@ -42,7 +42,6 @@ class SAMRawSession extends SAMMessageSession { protected SAMRawSession(String dest, Properties props, SAMRawReceiver recv) throws IOException, DataFormatException, I2PSessionException { super(dest, props); - this.recv = recv; } @@ -61,16 +60,16 @@ class SAMRawSession extends SAMMessageSession { public SAMRawSession(InputStream destStream, Properties props, SAMRawReceiver recv) throws IOException, DataFormatException, I2PSessionException { super(destStream, props); - this.recv = recv; } /** * Create a new SAM RAW session on an existing I2P session. * + * @param props unused for now * @since 0.9.25 */ - protected SAMRawSession(I2PSession sess, int listenProtocol, int listenPort, + protected SAMRawSession(I2PSession sess, Properties props, int listenProtocol, int listenPort, SAMRawReceiver recv) throws IOException, DataFormatException, I2PSessionException { super(sess, listenProtocol, listenPort); @@ -96,6 +95,24 @@ class SAMRawSession extends SAMMessageSession { return sendBytesThroughMessageSession(dest, data, proto, fromPort, toPort); } + /** + * Send bytes through a SAM RAW session. + * + * @since 0.9.25 + */ + public boolean sendBytes(String dest, byte[] data, int proto, + int fromPort, int toPort, + boolean sendLeaseSet, int sendTags, + int tagThreshold, int expiration) + throws DataFormatException, I2PSessionException { + if (data.length > RAW_SIZE_MAX) + throw new DataFormatException("Data size limit exceeded (" + data.length + ")"); + if (proto == I2PSession.PROTO_UNSPECIFIED) + proto = I2PSession.PROTO_DATAGRAM_RAW; + return sendBytesThroughMessageSession(dest, data, proto, fromPort, toPort, + sendLeaseSet, sendTags,tagThreshold, expiration); + } + protected void messageReceived(byte[] msg, int proto, int fromPort, int toPort) { try { recv.receiveRawBytes(msg, proto, fromPort, toPort); diff --git a/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java b/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java index 969dc5a31f..8cc9b56620 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMStreamSession.java @@ -372,7 +372,19 @@ class SAMStreamSession implements SAMMessageSess { * @since 0.9.25 moved from subclass SAMv3StreamSession to implement SAMMessageSess */ public boolean sendBytes(String s, byte[] b, int pr, int fp, int tp) throws I2PSessionException { - throw new I2PSessionException("Unsupported in STREAM or MASTER session"); + throw new I2PSessionException("Unsupported in STREAM or MASTER session"); + } + + /** + * Unsupported + * @throws I2PSessionException always + * @since 0.9.25 + */ + public boolean sendBytes(String s, byte[] b, int pr, int fp, int tp, + boolean sendLeaseSet, int sendTags, + int tagThreshold, int expiration) + throws I2PSessionException { + throw new I2PSessionException("Unsupported in STREAM or MASTER session"); } /** diff --git a/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java b/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java index 2a7f80fd1f..73192da826 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java @@ -419,102 +419,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece _log.error("DATAGRAM message received, but no DATAGRAM session exists"); return false; } - - if (opcode.equals("SEND")) { - if (props.isEmpty()) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("No parameters specified in DATAGRAM SEND message"); - return false; - } - - String dest = props.getProperty("DESTINATION"); - if (dest == null) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Destination not specified in DATAGRAM SEND message"); - return false; - } - - int size; - String strsize = props.getProperty("SIZE"); - if (strsize == null) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Size not specified in DATAGRAM SEND message"); - return false; - } - try { - size = Integer.parseInt(strsize); - } catch (NumberFormatException e) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Invalid DATAGRAM SEND size specified: " + strsize); - return false; - } - if (!checkDatagramSize(size)) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Specified size (" + size - + ") is out of protocol limits"); - return false; - } - int proto = I2PSession.PROTO_DATAGRAM; - int fromPort = I2PSession.PORT_UNSPECIFIED; - int toPort = I2PSession.PORT_UNSPECIFIED; - String s = props.getProperty("FROM_PORT"); - if (s != null) { - try { - fromPort = Integer.parseInt(s); - } catch (NumberFormatException e) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Invalid DATAGRAM SEND port specified: " + s); - } - } - s = props.getProperty("TO_PORT"); - if (s != null) { - try { - toPort = Integer.parseInt(s); - } catch (NumberFormatException e) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Invalid RAW SEND port specified: " + s); - } - } - - try { - DataInputStream in = new DataInputStream(getClientSocket().socket().getInputStream()); - byte[] data = new byte[size]; - - in.readFully(data); - - if (!datagramSession.sendBytes(dest, data, proto, fromPort, toPort)) { - _log.error("DATAGRAM SEND failed"); - // a message send failure is no reason to drop the SAM session - // for raw and repliable datagrams, just carry on our merry way - return true; - } - - return true; - } catch (EOFException e) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Too few bytes with DATAGRAM SEND message (expected: " - + size); - return false; - } catch (IOException e) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Caught IOException while parsing DATAGRAM SEND message", - e); - return false; - } catch (DataFormatException e) { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Invalid key specified with DATAGRAM SEND message", - e); - return false; - } catch (I2PSessionException e) { - _log.error("Session error with DATAGRAM SEND message", e); - return false; - } - } else { - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Unrecognized DATAGRAM message opcode: \"" - + opcode + "\""); - return false; - } + return execDgOrRawMessage(false, opcode, props); } /* Parse and execute a RAW message */ @@ -523,18 +428,33 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece _log.error("RAW message received, but no RAW session exists"); return false; } + return execDgOrRawMessage(true, opcode, props); + } + + /* + * Parse and execute a RAW or DATAGRAM SEND message. + * This is for v1/v2 compatible sending only. + * For v3 sending, see SAMv3DatagramServer. + * + * Note that props are from the command line only. + * Session defaults from CREATE are NOT honored here. + * FIXME if we care, but nobody's probably using v3.2 options for v1/v2 sending. + * + * @since 0.9.25 consolidated from execDatagramMessage() and execRawMessage() + */ + private boolean execDgOrRawMessage(boolean isRaw, String opcode, Properties props) { if (opcode.equals("SEND")) { if (props.isEmpty()) { if (_log.shouldLog(Log.DEBUG)) - _log.debug("No parameters specified in RAW SEND message"); + _log.debug("No parameters specified in SEND message"); return false; } String dest = props.getProperty("DESTINATION"); if (dest == null) { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Destination not specified in RAW SEND message"); + _log.debug("Destination not specified in SEND message"); return false; } @@ -542,41 +462,47 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece String strsize = props.getProperty("SIZE"); if (strsize == null) { if (_log.shouldLog(Log.WARN)) - _log.warn("Size not specified in RAW SEND message"); + _log.warn("Size not specified in SEND message"); return false; } try { size = Integer.parseInt(strsize); } catch (NumberFormatException e) { if (_log.shouldLog(Log.WARN)) - _log.warn("Invalid RAW SEND size specified: " + strsize); + _log.warn("Invalid SEND size specified: " + strsize); return false; } - if (!checkSize(size)) { + boolean ok = isRaw ? checkSize(size) : checkDatagramSize(size); + if (!ok) { if (_log.shouldLog(Log.WARN)) _log.warn("Specified size (" + size + ") is out of protocol limits"); return false; } - int proto = I2PSession.PROTO_DATAGRAM_RAW; int fromPort = I2PSession.PORT_UNSPECIFIED; int toPort = I2PSession.PORT_UNSPECIFIED; - String s = props.getProperty("PROTOCOL"); - if (s != null) { - try { - proto = Integer.parseInt(s); - } catch (NumberFormatException e) { - if (_log.shouldLog(Log.WARN)) - _log.warn("Invalid RAW SEND protocol specified: " + s); + int proto; + if (isRaw) { + proto = I2PSession.PROTO_DATAGRAM_RAW; + String s = props.getProperty("PROTOCOL"); + if (s != null) { + try { + proto = Integer.parseInt(s); + } catch (NumberFormatException e) { + if (_log.shouldLog(Log.WARN)) + _log.warn("Invalid SEND protocol specified: " + s); + } } + } else { + proto = I2PSession.PROTO_DATAGRAM; } - s = props.getProperty("FROM_PORT"); + String s = props.getProperty("FROM_PORT"); if (s != null) { try { fromPort = Integer.parseInt(s); } catch (NumberFormatException e) { if (_log.shouldLog(Log.WARN)) - _log.warn("Invalid RAW SEND port specified: " + s); + _log.warn("Invalid SEND port specified: " + s); } } s = props.getProperty("TO_PORT"); @@ -585,7 +511,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece toPort = Integer.parseInt(s); } catch (NumberFormatException e) { if (_log.shouldLog(Log.WARN)) - _log.warn("Invalid RAW SEND port specified: " + s); + _log.warn("Invalid SEND port specified: " + s); } } @@ -595,8 +521,9 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece in.readFully(data); - if (!rawSession.sendBytes(dest, data, proto, fromPort, toPort)) { - _log.error("RAW SEND failed"); + SAMMessageSess sess = isRaw ? rawSession : datagramSession; + if (sess.sendBytes(dest, data, proto, fromPort, toPort)) { + _log.error("SEND failed"); // a message send failure is no reason to drop the SAM session // for raw and repliable datagrams, just carry on our merry way return true; @@ -605,26 +532,26 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece return true; } catch (EOFException e) { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Too few bytes with RAW SEND message (expected: " + _log.debug("Too few bytes with SEND message (expected: " + size); return false; } catch (IOException e) { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Caught IOException while parsing RAW SEND message", + _log.debug("Caught IOException while parsing SEND message", e); return false; } catch (DataFormatException e) { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Invalid key specified with RAW SEND message", + _log.debug("Invalid key specified with SEND message", e); return false; } catch (I2PSessionException e) { - _log.error("Session error with RAW SEND message", e); + _log.error("Session error with SEND message", e); return false; } } else { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Unrecognized RAW message opcode: \"" + _log.debug("Unrecognized message opcode: \"" + opcode + "\""); return false; } @@ -645,7 +572,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece return execStreamClose(props); } else { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Unrecognized RAW message opcode: \"" + _log.debug("Unrecognized STREAM message opcode: \"" + opcode + "\""); return false; } diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3DatagramServer.java b/apps/sam/java/src/net/i2p/sam/SAMv3DatagramServer.java index 6e87852fec..03655d0c73 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv3DatagramServer.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv3DatagramServer.java @@ -163,54 +163,79 @@ class SAMv3DatagramServer implements Handler { SessionRecord rec = SAMv3Handler.sSessionsHash.get(nick); if (rec!=null) { Properties sprops = rec.getProps(); + // 3.2 props String pr = sprops.getProperty("PROTOCOL"); String fp = sprops.getProperty("FROM_PORT"); String tp = sprops.getProperty("TO_PORT"); + // 3.3 props + String st = sprops.getProperty("SEND_TAGS"); + String tt = sprops.getProperty("TAG_THRESHOLD"); + String ex = sprops.getProperty("EXPIRES"); + String sl = sprops.getProperty("SEND_LEASESET"); while (tok.hasMoreTokens()) { String t = tok.nextToken(); + // 3.2 props if (t.startsWith("PROTOCOL=")) pr = t.substring("PROTOCOL=".length()); else if (t.startsWith("FROM_PORT=")) fp = t.substring("FROM_PORT=".length()); else if (t.startsWith("TO_PORT=")) tp = t.substring("TO_PORT=".length()); + // 3.3 props + else if (t.startsWith("SEND_TAGS=")) + st = t.substring("SEND_TAGS=".length()); + else if (t.startsWith("TAG_THRESHOLD=")) + tt = t.substring("TAG_THRESHOLD=".length()); + else if (t.startsWith("EXPIRES=")) + ex = t.substring("EXPIRES=".length()); + else if (t.startsWith("SEND_LEASESET=")) + sl = t.substring("SEND_LEASESET=".length()); } + // 3.2 props int proto = I2PSession.PROTO_UNSPECIFIED; int fromPort = I2PSession.PORT_UNSPECIFIED; int toPort = I2PSession.PORT_UNSPECIFIED; - if (pr != null) { - try { + // 3.3 props + int sendTags = 0; + int tagThreshold = 0; + int expires = 0; + boolean sendLeaseSet = true; + try { + // 3.2 props + if (pr != null) proto = Integer.parseInt(pr); - } catch (NumberFormatException nfe) { - warn("Bad datagram header received"); - return; - } - } - if (fp != null) { - try { + if (fp != null) fromPort = Integer.parseInt(fp); - } catch (NumberFormatException nfe) { - warn("Bad datagram header received"); - return; - } - } - if (tp != null) { - try { + if (tp != null) toPort = Integer.parseInt(tp); - } catch (NumberFormatException nfe) { - warn("Bad datagram header received"); - return; - } + // 3.3 props + if (st != null) + sendTags = Integer.parseInt(st); + if (tt != null) + tagThreshold = Integer.parseInt(tt); + if (ex != null) + expires = Integer.parseInt(ex); + if (sl != null) + sendLeaseSet = Boolean.parseBoolean(sl); + } catch (NumberFormatException nfe) { + warn("Bad datagram header received"); + return; } // TODO too many allocations and copies. One here and one in Listener above. byte[] data = new byte[is.available()]; is.read(data); Session sess = rec.getHandler().getSession(); - if (sess != null) - sess.sendBytes(dest, data, proto, fromPort, toPort); - else + if (sess != null) { + if (sendTags > 0 || tagThreshold > 0 || expires > 0 || !sendLeaseSet) { + sess.sendBytes(dest, data, proto, fromPort, toPort, + sendLeaseSet, sendTags, tagThreshold, expires); + } else { + sess.sendBytes(dest, data, proto, fromPort, toPort); + } + } else { warn("Dropping datagram, no session for " + nick); + } } else { warn("Dropping datagram, no session for " + nick); } diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3DatagramSession.java b/apps/sam/java/src/net/i2p/sam/SAMv3DatagramSession.java index c118e3dba2..979d467ff2 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv3DatagramSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv3DatagramSession.java @@ -74,7 +74,7 @@ class SAMv3DatagramSession extends SAMDatagramSession implements Session, SAMDat public SAMv3DatagramSession(String nick, Properties props, SAMv3Handler handler, I2PSession isess, int listenPort, SAMv3DatagramServer dgServer) throws IOException, DataFormatException, I2PSessionException { - super(isess, listenPort, null); // to be replaced by this + super(isess, props, listenPort, null); // to be replaced by this this.nick = nick ; this.recv = this ; // replacement this.server = dgServer; diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java b/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java index 5ce5c06f69..9cbd4f489a 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv3RawSession.java @@ -75,7 +75,7 @@ class SAMv3RawSession extends SAMRawSession implements Session, SAMRawReceiver { public SAMv3RawSession(String nick, Properties props, SAMv3Handler handler, I2PSession isess, int listenProtocol, int listenPort, SAMv3DatagramServer dgServer) throws IOException, DataFormatException, I2PSessionException { - super(isess, listenProtocol, listenPort, null); // to be replace by this + super(isess, props, listenProtocol, listenPort, null); // to be replaced by this this.nick = nick ; this.recv = this ; // replacement this.server = dgServer; diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java b/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java index becd68f382..ffeb7142a6 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv3StreamSession.java @@ -131,6 +131,7 @@ class SAMv3StreamSession extends SAMStreamSession implements Session if (_acceptQueue == null) throw new IllegalStateException(); try { + // TODO there's no CoDel or expiration in this queue return _acceptQueue.take(); } catch (InterruptedException ie) { ConnectException ce = new ConnectException("interrupted"); diff --git a/apps/sam/java/src/net/i2p/sam/Session.java b/apps/sam/java/src/net/i2p/sam/Session.java index 3df52450f9..b3c13adf94 100644 --- a/apps/sam/java/src/net/i2p/sam/Session.java +++ b/apps/sam/java/src/net/i2p/sam/Session.java @@ -1,25 +1,11 @@ package net.i2p.sam; -/* - * free (adj.): unencumbered; not under the control of others - * Written by human in 2004 and released into the public domain - * with no warranty of any kind, either expressed or implied. - * It probably won't make your computer catch on fire, or eat - * your children, but it might. Use at your own risk. - * - */ - -import net.i2p.client.I2PSessionException; -import net.i2p.data.DataFormatException; /** * A V3 session. * * @since 0.9.25 moved from SAMv3Handler */ -interface Session { +interface Session extends SAMMessageSess { String getNick(); - void close(); - boolean sendBytes(String dest, byte[] data, int proto, - int fromPort, int toPort) throws DataFormatException, I2PSessionException; }