protocol and ports for outgoing datagrams

This commit is contained in:
zzz
2015-06-26 23:12:01 +00:00
parent 49e68bcc86
commit 12385f04ec
6 changed files with 159 additions and 58 deletions

View File

@ -12,7 +12,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.client.datagram.I2PDatagramDissector;
import net.i2p.client.datagram.I2PDatagramMaker;
@ -83,16 +82,15 @@ class SAMDatagramSession extends SAMMessageSession {
* @throws DataFormatException on unknown / bad dest
* @throws I2PSessionException on serious error, probably session closed
*/
public boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException {
public boolean sendBytes(String dest, byte[] data, int proto,
int fromPort, int toPort) 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);
}
// TODO pass ports through
return sendBytesThroughMessageSession(dest, dgram, I2PSession.PROTO_DATAGRAM,
I2PSession.PORT_UNSPECIFIED, I2PSession.PORT_UNSPECIFIED);
return sendBytesThroughMessageSession(dest, dgram, proto, fromPort, toPort);
}
protected void messageReceived(byte[] msg, int proto, int fromPort, int toPort) {

View File

@ -96,7 +96,8 @@ abstract class SAMMessageSession {
* @throws DataFormatException on unknown / bad dest
* @throws I2PSessionException on serious error, probably session closed
*/
public abstract boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException;
public abstract boolean sendBytes(String dest, byte[] data, int proto,
int fromPort, int toPort) throws DataFormatException, I2PSessionException;
/**
* Actually send bytes through the SAM message-based session I2PSession

View File

@ -12,7 +12,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.data.DataFormatException;
import net.i2p.util.Log;
@ -72,12 +71,11 @@ class SAMRawSession extends SAMMessageSession {
* @throws DataFormatException on unknown / bad dest
* @throws I2PSessionException on serious error, probably session closed
*/
public boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException {
public boolean sendBytes(String dest, byte[] data, int proto,
int fromPort, int toPort) throws DataFormatException, I2PSessionException {
if (data.length > RAW_SIZE_MAX)
throw new DataFormatException("Data size limit exceeded (" + data.length + ")");
// TODO pass ports through
return sendBytesThroughMessageSession(dest, data, I2PSession.PROTO_DATAGRAM_RAW,
I2PSession.PORT_UNSPECIFIED, I2PSession.PORT_UNSPECIFIED);
return sendBytesThroughMessageSession(dest, data, proto, fromPort, toPort);
}
protected void messageReceived(byte[] msg, int proto, int fromPort, int toPort) {

View File

@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicLong;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.crypto.SigType;
import net.i2p.data.Base64;
@ -438,25 +439,44 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
}
int size;
{
String strsize = props.getProperty("SIZE");
if (strsize == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Size not specified in DATAGRAM SEND message");
return false;
}
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 {
size = Integer.parseInt(strsize);
fromPort = Integer.parseInt(s);
} catch (NumberFormatException e) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Invalid DATAGRAM SEND size specified: " + strsize);
return false;
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid DATAGRAM SEND port specified: " + s);
}
if (!checkDatagramSize(size)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Specified size (" + size
+ ") is out of protocol limits");
return false;
}
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);
}
}
@ -466,7 +486,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
in.readFully(data);
if (!getDatagramSession().sendBytes(dest, data)) {
if (!getDatagramSession().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
@ -523,25 +543,53 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
}
int size;
{
String strsize = props.getProperty("SIZE");
if (strsize == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Size not specified in RAW SEND message");
return false;
}
String strsize = props.getProperty("SIZE");
if (strsize == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Size not specified in RAW 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);
return false;
}
if (!checkSize(size)) {
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 {
size = Integer.parseInt(strsize);
proto = Integer.parseInt(s);
} catch (NumberFormatException e) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Invalid RAW SEND size specified: " + strsize);
return false;
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid RAW SEND protocol specified: " + s);
}
if (!checkSize(size)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Specified size (" + size
+ ") is out of protocol limits");
return false;
}
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);
}
}
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);
}
}
@ -551,7 +599,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
in.readFully(data);
if (!getRawSession().sendBytes(dest, data)) {
if (!getRawSession().sendBytes(dest, data, proto, fromPort, toPort)) {
_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

View File

@ -28,6 +28,7 @@ import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.crypto.SigType;
import net.i2p.data.Base64;
@ -56,7 +57,8 @@ class SAMv3Handler extends SAMv1Handler
interface Session {
String getNick();
void close();
boolean sendBytes(String dest, byte[] data) throws DataFormatException, I2PSessionException;
boolean sendBytes(String dest, byte[] data, int proto,
int fromPort, int toPort) throws DataFormatException, I2PSessionException;
}
/**
@ -189,14 +191,16 @@ class SAMv3Handler extends SAMv1Handler
try {
String header = DataHelper.readLine(is).trim();
StringTokenizer tok = new StringTokenizer(header, " ");
if (tok.countTokens() != 3) {
if (tok.countTokens() < 3) {
// This is not a correct message, for sure
//_log.debug("Error in message format");
// FIXME log? throw?
warn("Bad datagram header received");
return;
}
String version = tok.nextToken();
if (!"3.0".equals(version)) return ;
if (!version.startsWith("3")) {
warn("Bad datagram header received");
return;
}
String nick = tok.nextToken();
String dest = tok.nextToken();
@ -204,18 +208,66 @@ class SAMv3Handler extends SAMv1Handler
is.read(data);
SessionRecord rec = sSessionsHash.get(nick);
if (rec!=null) {
rec.getHandler().session.sendBytes(dest,data);
Properties sprops = rec.getProps();
String pr = sprops.getProperty("PROTOCOL");
String fp = sprops.getProperty("FROM_PORT");
String tp = sprops.getProperty("TO_PORT");
while (tok.hasMoreTokens()) {
String t = tok.nextToken();
if (t.startsWith("PROTOCOL="))
pr = t.substring("PROTOTCOL=".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());
}
int proto = I2PSession.PROTO_UNSPECIFIED;
int fromPort = I2PSession.PORT_UNSPECIFIED;
int toPort = I2PSession.PORT_UNSPECIFIED;
if (pr != null) {
try {
proto = Integer.parseInt(pr);
} catch (NumberFormatException nfe) {
warn("Bad datagram header received");
return;
}
}
if (fp != null) {
try {
fromPort = Integer.parseInt(fp);
} catch (NumberFormatException nfe) {
warn("Bad datagram header received");
return;
}
}
if (tp != null) {
try {
toPort = Integer.parseInt(tp);
} catch (NumberFormatException nfe) {
warn("Bad datagram header received");
return;
}
}
rec.getHandler().session.sendBytes(dest,data, proto, fromPort, toPort);
} else {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(SAMv3Handler.class);
if (log.shouldLog(Log.WARN))
log.warn("Dropping datagram, no session for " + nick);
warn("Dropping datagram, no session for " + nick);
}
} catch (Exception e) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(SAMv3Handler.class);
if (log.shouldLog(Log.WARN))
log.warn("Error handling datagram", e);
warn("Error handling datagram", e);
}
}
/** @since 0.9.22 */
private static void warn(String s) {
warn(s, null);
}
/** @since 0.9.22 */
private static void warn(String s, Throwable t) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(SAMv3Handler.class);
if (log.shouldLog(Log.WARN))
log.warn(s, t);
}
}
/**

View File

@ -415,7 +415,11 @@ class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handler.Sessi
socketMgr.destroySocketManager();
}
public boolean sendBytes(String s, byte[] b) throws DataFormatException
/**
* Unsupported
* @throws DataFormatException always
*/
public boolean sendBytes(String s, byte[] b, int pr, int fp, int tp) throws DataFormatException
{
throw new DataFormatException(null);
}