use of net.i2p.data.TunnelId in project i2p.i2p by i2p.
the class DatabaseLookupMessage method readMessage.
public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException {
if (type != MESSAGE_TYPE)
throw new I2NPMessageException("Message type is incorrect for this message");
int curIndex = offset;
// byte keyData[] = new byte[Hash.HASH_LENGTH];
// System.arraycopy(data, curIndex, keyData, 0, Hash.HASH_LENGTH);
_key = Hash.create(data, curIndex);
curIndex += Hash.HASH_LENGTH;
// _key = new Hash(keyData);
// byte fromData[] = new byte[Hash.HASH_LENGTH];
// System.arraycopy(data, curIndex, fromData, 0, Hash.HASH_LENGTH);
_fromHash = Hash.create(data, curIndex);
curIndex += Hash.HASH_LENGTH;
// _fromHash = new Hash(fromData);
// as of 0.9.6, ignore other 7 bits of the flag byte
// TODO store the whole flag byte
boolean tunnelSpecified = (data[curIndex] & FLAG_TUNNEL) != 0;
boolean replyKeySpecified = (data[curIndex] & FLAG_ENCRYPT) != 0;
switch(data[curIndex] & FLAG_TYPE_MASK) {
case FLAG_TYPE_LS:
_type = Type.LS;
break;
case FLAG_TYPE_RI:
_type = Type.RI;
break;
case FLAG_TYPE_EXPL:
_type = Type.EXPL;
break;
case FLAG_TYPE_ANY:
default:
_type = Type.ANY;
break;
}
curIndex++;
if (tunnelSpecified) {
_replyTunnel = new TunnelId(DataHelper.fromLong(data, curIndex, 4));
curIndex += 4;
}
int numPeers = (int) DataHelper.fromLong(data, curIndex, 2);
curIndex += 2;
if ((numPeers < 0) || (numPeers > MAX_NUM_PEERS))
throw new I2NPMessageException("Invalid number of peers - " + numPeers);
List<Hash> peers = numPeers > 0 ? new ArrayList<Hash>(numPeers) : null;
for (int i = 0; i < numPeers; i++) {
// byte peer[] = new byte[Hash.HASH_LENGTH];
// System.arraycopy(data, curIndex, peer, 0, Hash.HASH_LENGTH);
Hash p = Hash.create(data, curIndex);
curIndex += Hash.HASH_LENGTH;
peers.add(p);
}
_dontIncludePeers = peers;
if (replyKeySpecified) {
byte[] rk = new byte[SessionKey.KEYSIZE_BYTES];
System.arraycopy(data, curIndex, rk, 0, SessionKey.KEYSIZE_BYTES);
_replyKey = new SessionKey(rk);
curIndex += SessionKey.KEYSIZE_BYTES;
// number of tags, assume always 1 for now
curIndex++;
byte[] rt = new byte[SessionTag.BYTE_LENGTH];
System.arraycopy(data, curIndex, rt, 0, SessionTag.BYTE_LENGTH);
_replyTag = new SessionTag(rt);
}
}
use of net.i2p.data.TunnelId in project i2p.i2p by i2p.
the class RequestLeaseSetMessage method doWriteMessage.
@Override
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
if (_sessionId == null)
throw new I2CPMessageException("Unable to write out the message as there is not enough data");
ByteArrayOutputStream os = new ByteArrayOutputStream(256);
try {
_sessionId.writeBytes(os);
DataHelper.writeLong(os, 1, _endpoints.size());
for (int i = 0; i < _endpoints.size(); i++) {
Hash router = getRouter(i);
router.writeBytes(os);
TunnelId tunnel = getTunnelId(i);
tunnel.writeBytes(os);
}
DataHelper.writeDate(os, _end);
} catch (DataFormatException dfe) {
throw new I2CPMessageException("Error writing out the message data", dfe);
}
return os.toByteArray();
}
use of net.i2p.data.TunnelId in project i2p.i2p by i2p.
the class SearchJob method sendLeaseSearch.
/**
* we're (probably) searching for a LeaseSet, so to be (overly) cautious, we're sending
* the request out through a tunnel w/ reply back through another tunnel.
*/
protected void sendLeaseSearch(RouterInfo router) {
Hash to = router.getIdentity().getHash();
TunnelInfo inTunnel = getContext().tunnelManager().selectInboundExploratoryTunnel(to);
if (inTunnel == null) {
_log.warn("No tunnels to get search replies through!");
getContext().jobQueue().addJob(new FailedJob(getContext(), router));
return;
}
TunnelId inTunnelId = inTunnel.getReceiveTunnelId(0);
// this will fail if we've banlisted our inbound gateway, but the gw may not necessarily
// be banlisted by whomever needs to contact them, so we don't need to check this
// RouterInfo inGateway = getContext().netDb().lookupRouterInfoLocally(inTunnel.getPeer(0));
// if (inGateway == null) {
// _log.error("We can't find the gateway to our inbound tunnel?!");
// getContext().jobQueue().addJob(new FailedJob(getContext(), router));
// return;
// }
int timeout = getPerPeerTimeoutMs(to);
long expiration = getContext().clock().now() + timeout;
I2NPMessage msg = buildMessage(inTunnelId, inTunnel.getPeer(0), expiration, router);
if (msg == null) {
getContext().jobQueue().addJob(new FailedJob(getContext(), router));
return;
}
TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundExploratoryTunnel(to);
if (outTunnel == null) {
_log.warn("No tunnels to send search out through! Impossible?");
getContext().jobQueue().addJob(new FailedJob(getContext(), router));
return;
}
TunnelId outTunnelId = outTunnel.getSendTunnelId(0);
if (_log.shouldLog(Log.DEBUG))
_log.debug(getJobId() + ": Sending search to " + to + " for " + getState().getTarget() + " w/ replies through " + inTunnel.getPeer(0) + " via tunnel " + inTunnelId);
SearchMessageSelector sel = new SearchMessageSelector(getContext(), router, _expiration, _state);
SearchUpdateReplyFoundJob reply = new SearchUpdateReplyFoundJob(getContext(), router, _state, _facade, this, outTunnel, inTunnel);
if (FloodfillNetworkDatabaseFacade.isFloodfill(router))
_floodfillSearchesOutstanding++;
getContext().messageRegistry().registerPending(sel, reply, new FailedJob(getContext(), router));
// TODO pass a priority to the dispatcher
getContext().tunnelDispatcher().dispatchOutbound(msg, outTunnelId, to);
}
use of net.i2p.data.TunnelId in project i2p.i2p by i2p.
the class StoreJob method sendStoreThroughGarlic.
/**
* This is misnamed, it means sending it out through an exploratory tunnel,
* with the reply to come back through an exploratory tunnel.
* There is no garlic encryption added.
*/
private void sendStoreThroughGarlic(DatabaseStoreMessage msg, RouterInfo peer, long expiration) {
long token = 1 + getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
Hash to = peer.getIdentity().getHash();
TunnelInfo replyTunnel = getContext().tunnelManager().selectInboundExploratoryTunnel(to);
if (replyTunnel == null) {
_log.warn("No reply inbound tunnels available!");
return;
}
TunnelId replyTunnelId = replyTunnel.getReceiveTunnelId(0);
msg.setReplyToken(token);
msg.setReplyTunnel(replyTunnelId);
msg.setReplyGateway(replyTunnel.getPeer(0));
if (_log.shouldLog(Log.DEBUG))
_log.debug(getJobId() + ": send store thru expl. tunnel to " + peer.getIdentity().getHash() + " w/ token expected " + token);
_state.addPending(to);
TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundExploratoryTunnel(to);
if (outTunnel != null) {
// if (_log.shouldLog(Log.DEBUG))
// _log.debug(getJobId() + ": Sending tunnel message out " + outTunnelId + " to "
// + peer.getIdentity().getHash().toBase64());
// TunnelId targetTunnelId = null; // not needed
// Job onSend = null; // not wanted
SendSuccessJob onReply = new SendSuccessJob(getContext(), peer, outTunnel, msg.getMessageSize());
FailedJob onFail = new FailedJob(getContext(), peer, getContext().clock().now());
StoreMessageSelector selector = new StoreMessageSelector(getContext(), getJobId(), peer, token, expiration);
if (_log.shouldLog(Log.DEBUG))
_log.debug("sending store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + msg);
getContext().messageRegistry().registerPending(selector, onReply, onFail);
getContext().tunnelDispatcher().dispatchOutbound(msg, outTunnel.getSendTunnelId(0), null, to);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("No outbound tunnels to send a dbStore out!");
fail();
}
}
use of net.i2p.data.TunnelId in project i2p.i2p by i2p.
the class BuildMessageTestStandalone method configOutbound.
private TunnelCreatorConfig configOutbound(I2PAppContext ctx) {
_peers = new Hash[4];
_pubKeys = new PublicKey[_peers.length];
_privKeys = new PrivateKey[_peers.length];
for (int i = 0; i < _peers.length; i++) {
byte[] buf = new byte[Hash.HASH_LENGTH];
// consistent for repeatability
Arrays.fill(buf, (byte) i);
Hash h = new Hash(buf);
_peers[i] = h;
Object[] kp = ctx.keyGenerator().generatePKIKeypair();
_pubKeys[i] = (PublicKey) kp[0];
_privKeys[i] = (PrivateKey) kp[1];
}
TunnelCreatorConfig cfg = new TunnelCreatorConfig(null, _peers.length, false);
long now = ctx.clock().now();
// peers[] is ordered endpoint first, but cfg.getPeer() is ordered gateway first
for (int i = 0; i < _peers.length; i++) {
cfg.setPeer(i, _peers[i]);
HopConfig hop = cfg.getConfig(i);
hop.setExpiration(now + 10 * 60 * 1000);
hop.setIVKey(ctx.keyGenerator().generateSessionKey());
hop.setLayerKey(ctx.keyGenerator().generateSessionKey());
hop.setReplyKey(ctx.keyGenerator().generateSessionKey());
byte[] iv = new byte[BuildRequestRecord.IV_SIZE];
// consistent for repeatability
Arrays.fill(iv, (byte) i);
hop.setReplyIV(iv);
hop.setReceiveTunnelId(new TunnelId(i + 1));
}
return cfg;
}
Aggregations