diff --git a/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java b/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java index 32611065da..ce3c1803c3 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMDatagramSession.java @@ -80,9 +80,10 @@ class SAMDatagramSession extends SAMMessageSession { * @param data Bytes to be sent * * @return True if the data was sent, false otherwise - * @throws DataFormatException + * @throws DataFormatException on unknown / bad dest + * @throws I2PSessionException on serious error, probably session closed */ - public boolean sendBytes(String dest, byte[] data) throws DataFormatException { + public boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException { if (data.length > DGRAM_SIZE_MAX) throw new DataFormatException("Datagram size exceeded (" + data.length + ")"); byte[] dgram ; diff --git a/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java b/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java index 54569a09d8..dbeec9eda7 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMMessageSession.java @@ -92,9 +92,10 @@ abstract class SAMMessageSession { * @param data Bytes to be sent * * @return True if the data was sent, false otherwise - * @throws DataFormatException + * @throws DataFormatException on unknown / bad dest + * @throws I2PSessionException on serious error, probably session closed */ - public abstract boolean sendBytes(String dest, byte[] data) throws DataFormatException; + public abstract boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException; /** * Actually send bytes through the SAM message-based session I2PSession @@ -108,21 +109,18 @@ abstract class SAMMessageSession { * * @return True if the data was sent, false otherwise * @throws DataFormatException on unknown / bad dest + * @throws I2PSessionException on serious error, probably session closed */ protected boolean sendBytesThroughMessageSession(String dest, byte[] data, - int proto, int fromPort, int toPort) throws DataFormatException { + int proto, int fromPort, int toPort) + throws DataFormatException, I2PSessionException { Destination d = SAMUtils.getDest(dest); if (_log.shouldLog(Log.DEBUG)) { _log.debug("Sending " + data.length + " bytes to " + dest); } - try { - return session.sendMessage(d, data, proto, fromPort, toPort); - } catch (I2PSessionException e) { - _log.error("I2PSessionException while sending data", e); - return false; - } + return session.sendMessage(d, data, proto, fromPort, toPort); } /** diff --git a/apps/sam/java/src/net/i2p/sam/SAMRawSession.java b/apps/sam/java/src/net/i2p/sam/SAMRawSession.java index 01cbde75a7..e3c4216083 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMRawSession.java +++ b/apps/sam/java/src/net/i2p/sam/SAMRawSession.java @@ -69,9 +69,10 @@ class SAMRawSession extends SAMMessageSession { * @param data Bytes to be sent * * @return True if the data was sent, false otherwise - * @throws DataFormatException + * @throws DataFormatException on unknown / bad dest + * @throws I2PSessionException on serious error, probably session closed */ - public boolean sendBytes(String dest, byte[] data) throws DataFormatException { + public boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException { if (data.length > RAW_SIZE_MAX) throw new DataFormatException("Data size limit exceeded (" + data.length + ")"); // TODO pass ports through diff --git a/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java b/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java index 25a90cc708..3189f87e36 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv1Handler.java @@ -466,6 +466,8 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece if (!getDatagramSession().sendBytes(dest, data)) { _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; } @@ -485,6 +487,9 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece _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)) @@ -546,6 +551,8 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece if (!getRawSession().sendBytes(dest, data)) { _log.error("RAW 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; } @@ -565,6 +572,9 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece _log.debug("Invalid key specified with RAW SEND message", e); return false; + } catch (I2PSessionException e) { + _log.error("Session error with RAW SEND message", e); + return false; } } else { if (_log.shouldLog(Log.DEBUG)) @@ -646,6 +656,8 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece if (!getStreamSession().sendBytes(id, getClientSocket().socket().getInputStream(), size)) { // data)) { if (_log.shouldLog(Log.WARN)) _log.warn("STREAM SEND [" + size + "] failed"); + // a message send failure is no reason to drop the SAM session + // for style=stream, tell the client the stream failed, and kill the virtual connection.. boolean rv = writeString("STREAM CLOSED RESULT=CANT_REACH_PEER ID=" + id + " MESSAGE=\"Send of " + size + " bytes failed\"\n"); getStreamSession().closeConnection(id); return rv; diff --git a/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java b/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java index 062e5f9fb4..fd3b44a205 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java +++ b/apps/sam/java/src/net/i2p/sam/SAMv3Handler.java @@ -55,7 +55,7 @@ class SAMv3Handler extends SAMv1Handler interface Session { String getNick(); void close(); - boolean sendBytes(String dest, byte[] data) throws DataFormatException; + boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException; } /** diff --git a/history.txt b/history.txt index 9a826aaf90..5390110852 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,6 @@ 2015-05-07 zzz + * SAM: Close datagram or raw session when underlying + I2P session closes (ticket #1563) * Update: Add support for su3-signed development builds (ticket #1381) 2015-05-06 zzz diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 8ab24107c9..80cfb9c849 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 17; + public final static long BUILD = 18; /** for example "-test" */ public final static String EXTRA = "";