use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class Packet method readPacket.
/**
* Read the packet from the buffer (starting at the offset) and return
* the number of bytes read.
*
* @param buffer packet buffer containing the data
* @param offset index into the buffer to start readign
* @param length how many bytes within the buffer past the offset are
* part of the packet?
*
* @throws IllegalArgumentException if the data is b0rked
*/
public void readPacket(byte[] buffer, int offset, int length) throws IllegalArgumentException {
if (buffer.length - offset < length)
throw new IllegalArgumentException("len=" + buffer.length + " off=" + offset + " length=" + length);
if (// min header size
length < 22)
throw new IllegalArgumentException("Too small: len=" + buffer.length);
int cur = offset;
setSendStreamId(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
setReceiveStreamId(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
setSequenceNum(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
setAckThrough(DataHelper.fromLong(buffer, cur, 4));
cur += 4;
int numNacks = buffer[cur] & 0xff;
cur++;
if (length < 22 + numNacks * 4)
throw new IllegalArgumentException("Too small with " + numNacks + " nacks: " + length);
if (numNacks > 0) {
long[] nacks = new long[numNacks];
for (int i = 0; i < numNacks; i++) {
nacks[i] = DataHelper.fromLong(buffer, cur, 4);
cur += 4;
}
setNacks(nacks);
} else {
setNacks(null);
}
setResendDelay(buffer[cur] & 0xff);
cur++;
setFlags((int) DataHelper.fromLong(buffer, cur, 2));
cur += 2;
int optionSize = (int) DataHelper.fromLong(buffer, cur, 2);
cur += 2;
if (length < 22 + numNacks * 4 + optionSize)
throw new IllegalArgumentException("Too small with " + numNacks + " nacks and " + optionSize + " options: " + length);
int payloadBegin = cur + optionSize;
int payloadSize = length - payloadBegin;
if ((payloadSize < 0) || (payloadSize > MAX_PAYLOAD_SIZE))
throw new IllegalArgumentException("length: " + length + " offset: " + offset + " begin: " + payloadBegin);
// skip ahead to the payload
// _payload = new ByteArray(new byte[payloadSize]);
_payload = new ByteArray(buffer, payloadBegin, payloadSize);
// ok now lets go back and deal with the options
if (isFlagSet(FLAG_DELAY_REQUESTED)) {
setOptionalDelay((int) DataHelper.fromLong(buffer, cur, 2));
cur += 2;
}
if (isFlagSet(FLAG_FROM_INCLUDED)) {
ByteArrayInputStream bais = new ByteArrayInputStream(buffer, cur, length - cur);
try {
Destination optionFrom = Destination.create(bais);
cur += optionFrom.size();
_optionFrom = optionFrom;
} catch (IOException ioe) {
throw new IllegalArgumentException("Bad from field", ioe);
} catch (DataFormatException dfe) {
throw new IllegalArgumentException("Bad from field", dfe);
}
}
if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED)) {
setOptionalMaxSize((int) DataHelper.fromLong(buffer, cur, 2));
cur += 2;
}
if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) {
Signature optionSignature;
Destination from = getOptionalFrom();
if (from != null) {
optionSignature = new Signature(from.getSigningPublicKey().getType());
} else {
// super cheat for now, look for correct type,
// assume no more options. If we add to the options
// we will have to ask the manager.
// We will get this wrong for Ed25519, same length as P256...
// See verifySignature() below where we will recast the signature to
// the correct type if necessary
int siglen = payloadBegin - cur;
SigType type = null;
for (SigType t : SigType.values()) {
if (t.getSigLen() == siglen) {
type = t;
break;
}
}
if (type == null) {
if (siglen < Signature.SIGNATURE_BYTES)
throw new IllegalArgumentException("unknown sig type len=" + siglen);
// Hope it's the default type with some unknown options following;
// if not the sig will fail later
type = SigType.DSA_SHA1;
siglen = Signature.SIGNATURE_BYTES;
}
optionSignature = new Signature(type);
}
byte[] buf = new byte[optionSignature.length()];
System.arraycopy(buffer, cur, buf, 0, buf.length);
optionSignature.setData(buf);
setOptionalSignature(optionSignature);
cur += buf.length;
}
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SAMv1Handler method execNamingMessage.
/* Parse and execute a NAMING message */
protected boolean execNamingMessage(String opcode, Properties props) {
if (opcode.equals("LOOKUP")) {
String name = props.getProperty("NAME");
if (name == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Name to resolve not specified in NAMING message");
return writeString("NAMING REPLY RESULT=KEY_NOT_FOUND NAME=\"\" MESSAGE=\"Must specify NAME\"\n");
}
Destination dest = null;
if (name.equals("ME")) {
if (rawSession != null) {
dest = rawSession.getDestination();
} else if (streamSession != null) {
dest = streamSession.getDestination();
} else if (datagramSession != null) {
dest = datagramSession.getDestination();
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Lookup for SESSION destination, but session is null");
return false;
}
} else {
try {
dest = SAMUtils.getDest(name);
} catch (DataFormatException e) {
}
}
if (dest == null) {
return writeString("NAMING REPLY RESULT=KEY_NOT_FOUND NAME=" + name + "\n");
}
return writeString("NAMING REPLY RESULT=OK NAME=" + name + " VALUE=" + dest.toBase64() + "\n");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized NAMING message opcode: \"" + opcode + "\"");
return false;
}
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SAMv1Handler method execSessionMessage.
/* Parse and execute a SESSION message */
protected boolean execSessionMessage(String opcode, Properties props) {
String dest = "BUG!";
try {
if (opcode.equals("CREATE")) {
if ((rawSession != null) || (datagramSession != null) || (streamSession != null)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Trying to create a session, but one still exists");
return writeString(SESSION_ERROR, "Session already exists");
}
if (props.isEmpty()) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("No parameters specified in SESSION CREATE message");
return writeString(SESSION_ERROR, "No parameters for SESSION CREATE");
}
dest = (String) props.remove("DESTINATION");
if (dest == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION DESTINATION parameter not specified");
return writeString(SESSION_ERROR, "DESTINATION not specified");
}
String destKeystream = null;
if (dest.equals("TRANSIENT")) {
_log.debug("TRANSIENT destination requested");
ByteArrayOutputStream priv = new ByteArrayOutputStream(640);
SAMUtils.genRandomKey(priv, null);
destKeystream = Base64.encode(priv.toByteArray());
} else {
destKeystream = bridge.getKeystream(dest);
if (destKeystream == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Custom destination specified [" + dest + "] but it isn't known, creating a new one");
ByteArrayOutputStream baos = new ByteArrayOutputStream(640);
SAMUtils.genRandomKey(baos, null);
destKeystream = Base64.encode(baos.toByteArray());
bridge.addKeystream(dest, destKeystream);
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Custom destination specified [" + dest + "] and it is already known");
}
}
String style = (String) props.remove("STYLE");
if (style == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION STYLE parameter not specified");
return writeString(SESSION_ERROR, "No SESSION STYLE specified");
}
// Unconditionally override what the client may have set
// (iMule sets BestEffort) as None is more efficient
// and the client has no way to access delivery notifications
props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
if (style.equals("RAW")) {
rawSession = new SAMRawSession(destKeystream, props, this);
rawSession.start();
} else if (style.equals("DATAGRAM")) {
datagramSession = new SAMDatagramSession(destKeystream, props, this);
datagramSession.start();
} else if (style.equals("STREAM")) {
String dir = (String) props.remove("DIRECTION");
if (dir == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("No DIRECTION parameter in STREAM session, defaulting to BOTH");
dir = "BOTH";
} else if (!dir.equals("CREATE") && !dir.equals("RECEIVE") && !dir.equals("BOTH")) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unknown DIRECTION parameter value: [" + dir + "]");
return writeString(SESSION_ERROR, "Unknown DIRECTION parameter");
}
streamSession = newSAMStreamSession(destKeystream, dir, props);
streamSession.start();
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized SESSION STYLE: \"" + style + "\"");
return writeString(SESSION_ERROR, "Unrecognized SESSION STYLE");
}
return writeString("SESSION STATUS RESULT=OK DESTINATION=" + dest + "\n");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized SESSION message opcode: \"" + opcode + "\"");
return writeString(SESSION_ERROR, "Unrecognized opcode");
}
} catch (DataFormatException e) {
_log.error("Invalid SAM destination specified", e);
return writeString("SESSION STATUS RESULT=INVALID_KEY", e.getMessage());
} catch (I2PSessionException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
} catch (SAMException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
} catch (IOException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
}
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SAMDatagramSession method messageReceived.
protected void messageReceived(byte[] msg, int proto, int fromPort, int toPort) {
byte[] payload;
Destination sender;
try {
synchronized (dgramDissector) {
dgramDissector.loadI2PDatagram(msg);
sender = dgramDissector.getSender();
payload = dgramDissector.extractPayload();
}
} catch (DataFormatException e) {
if (_log.shouldLog(Log.DEBUG)) {
_log.debug("Dropping ill-formatted I2P repliable datagram", e);
}
return;
} catch (I2PInvalidDatagramException e) {
if (_log.shouldLog(Log.DEBUG)) {
_log.debug("Dropping ill-signed I2P repliable datagram", e);
}
return;
}
try {
recv.receiveDatagramBytes(sender, payload, proto, fromPort, toPort);
} catch (IOException e) {
_log.error("Error forwarding message to receiver", e);
close();
}
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SAMUtils method getDest.
/**
* Resolve the destination from a key or a hostname
*
* @param s Hostname or key to be resolved
*
* @return the Destination for the specified hostname, non-null
* @throws DataFormatException on bad Base 64 or name not found
*/
public static Destination getDest(String s) throws DataFormatException {
// NamingService caches b64 so just use it for everything
// TODO: Add a static local cache here so SAM doesn't flush the
// NamingService cache
Destination d = lookupHost(s);
if (d == null) {
String msg;
if (s.length() >= 516)
msg = "Bad Base64 dest: ";
else if (s.length() == 60 && s.endsWith(".b32.i2p"))
msg = "Lease set not found: ";
else
msg = "Host name not found: ";
throw new DataFormatException(msg + s);
}
return d;
}
Aggregations