use of net.i2p.data.Hash in project i2p.i2p by i2p.
the class StoreJob method sendStoreThroughClient.
/**
* Send a leaseset store message out the client tunnel,
* with the reply to come back through a client tunnel.
* Stores are garlic encrypted to hide the identity from the OBEP.
*
* This makes it harder for an exploratory OBEP or IBGW to correlate it
* with one or more destinations. Since we are publishing the leaseset,
* it's easy to find out that an IB tunnel belongs to this dest, and
* it isn't much harder to do the same for an OB tunnel.
*
* As a side benefit, client tunnels should be faster and more reliable than
* exploratory tunnels.
*
* @param msg must contain a leaseset
* @since 0.7.10
*/
private void sendStoreThroughClient(DatabaseStoreMessage msg, RouterInfo peer, long expiration) {
long token = 1 + getContext().random().nextLong(I2NPMessage.MAX_ID_VALUE);
Hash client = msg.getKey();
Hash to = peer.getIdentity().getHash();
TunnelInfo replyTunnel = getContext().tunnelManager().selectInboundTunnel(client, to);
if (replyTunnel == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("No reply inbound tunnels available!");
fail();
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(dbStore) w/ token expected " + token);
TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundTunnel(client, to);
if (outTunnel != null) {
I2NPMessage sent;
boolean shouldEncrypt = supportsEncryption(peer);
if (shouldEncrypt) {
// garlic encrypt
MessageWrapper.WrappedMessage wm = MessageWrapper.wrap(getContext(), msg, client, peer);
if (wm == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Fail garlic encrypting from: " + client);
fail();
return;
}
sent = wm.getMessage();
_state.addPending(to, wm);
} else {
_state.addPending(to);
// now that almost all floodfills are at 0.7.10,
// just refuse to store unencrypted to older ones.
_state.replyTimeout(to);
getContext().jobQueue().addJob(new WaitJob(getContext()));
return;
}
SendSuccessJob onReply = new SendSuccessJob(getContext(), peer, outTunnel, sent.getMessageSize());
FailedJob onFail = new FailedJob(getContext(), peer, getContext().clock().now());
StoreMessageSelector selector = new StoreMessageSelector(getContext(), getJobId(), peer, token, expiration);
if (_log.shouldLog(Log.DEBUG)) {
if (shouldEncrypt)
_log.debug("sending encrypted store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + sent);
else
_log.debug("sending store to " + peer.getIdentity().getHash() + " through " + outTunnel + ": " + sent);
// _log.debug("Expiration is " + new Date(sent.getMessageExpiration()));
}
getContext().messageRegistry().registerPending(selector, onReply, onFail);
getContext().tunnelDispatcher().dispatchOutbound(sent, outTunnel.getSendTunnelId(0), null, to);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("No outbound tunnels to send a dbStore out - delaying...");
// continueSending() above did an addPending() so remove it here.
// This means we will skip the peer next time, can't be helped for now
// without modding StoreState
_state.replyTimeout(to);
Job waiter = new WaitJob(getContext());
waiter.getTiming().setStartAfter(getContext().clock().now() + 3 * 1000);
getContext().jobQueue().addJob(waiter);
// fail();
}
}
use of net.i2p.data.Hash in project i2p.i2p by i2p.
the class StoreJob method getClosestFloodfillRouters.
/**
* Set of Hash structures for routers we want to send the data to next. This is the
* 'interesting' part of the algorithm. DBStore isn't usually as time sensitive as
* it is reliability sensitive, so lets delegate it off to the PeerSelector via
* selectNearestExplicit, which is currently O(n*log(n))
*
* @return ordered list of Hash objects
*/
/**
***
* private List<Hash> getClosestRouters(Hash key, int numClosest, Set<Hash> alreadyChecked) {
* Hash rkey = getContext().routingKeyGenerator().getRoutingKey(key);
* //if (_log.shouldLog(Log.DEBUG))
* // _log.debug(getJobId() + ": Current routing key for " + key + ": " + rkey);
*
* KBucketSet ks = _facade.getKBuckets();
* if (ks == null) return new ArrayList();
* return _peerSelector.selectNearestExplicit(rkey, numClosest, alreadyChecked, ks);
* }
****
*/
/**
* used for routerinfo stores, prefers those already connected
*/
/**
***
* private List<Hash> getMostReliableRouters(Hash key, int numClosest, Set<Hash> alreadyChecked) {
* Hash rkey = getContext().routingKeyGenerator().getRoutingKey(key);
* KBucketSet ks = _facade.getKBuckets();
* if (ks == null) return new ArrayList();
* return _peerSelector.selectMostReliablePeers(rkey, numClosest, alreadyChecked, ks);
* }
****
*/
private List<Hash> getClosestFloodfillRouters(Hash key, int numClosest, Set<Hash> alreadyChecked) {
Hash rkey = getContext().routingKeyGenerator().getRoutingKey(key);
KBucketSet<Hash> ks = _facade.getKBuckets();
if (ks == null)
return new ArrayList<Hash>();
return ((FloodfillPeerSelector) _peerSelector).selectFloodfillParticipants(rkey, numClosest, alreadyChecked, ks);
}
use of net.i2p.data.Hash in project i2p.i2p by i2p.
the class GetBidsJob method getBids.
static void getBids(RouterContext context, TransportManager tmgr, OutNetMessage msg) {
Log log = context.logManager().getLog(GetBidsJob.class);
Hash to = msg.getTarget().getIdentity().getHash();
msg.timestamp("bid");
if (context.banlist().isBanlisted(to)) {
if (log.shouldLog(Log.WARN))
log.warn("Attempt to send a message to a banlisted peer - " + to);
// context.messageRegistry().peerFailed(to);
context.statManager().addRateData("transport.bidFailBanlisted", msg.getLifetime());
fail(context, msg);
return;
}
Hash us = context.routerHash();
if (to.equals(us)) {
if (log.shouldLog(Log.ERROR))
log.error("send a message to ourselves? nuh uh. msg = " + msg);
context.statManager().addRateData("transport.bidFailSelf", msg.getLifetime());
fail(context, msg);
return;
}
TransportBid bid = tmgr.getNextBid(msg);
if (bid == null) {
int failedCount = msg.getFailedTransports().size();
if (failedCount == 0) {
context.statManager().addRateData("transport.bidFailNoTransports", msg.getLifetime());
// This used to be "no common transports" but it is almost always no transports at all
context.banlist().banlistRouter(to, _x("No transports (hidden or starting up?)"));
} else if (failedCount >= tmgr.getTransportCount()) {
context.statManager().addRateData("transport.bidFailAllTransports", msg.getLifetime());
// fail after all transports were unsuccessful
context.netDb().fail(to);
}
fail(context, msg);
} else {
if (log.shouldLog(Log.INFO))
log.info("Attempting to send on transport " + bid.getTransport().getStyle() + ": " + bid);
bid.getTransport().send(msg);
}
}
use of net.i2p.data.Hash in project i2p.i2p by i2p.
the class StoreState method toString.
@Override
public String toString() {
StringBuilder buf = new StringBuilder(256);
buf.append("Storing ").append(_key);
buf.append(" ");
if (_completed <= 0)
buf.append(" completed? false ");
else
buf.append(" completed on ").append(new Date(_completed));
buf.append(" Attempted: ");
synchronized (_attemptedPeers) {
buf.append(_attemptedPeers.size()).append(' ');
for (Hash peer : _attemptedPeers) {
buf.append(peer.toBase64()).append(" ");
}
}
buf.append(" Pending: ");
synchronized (_pendingPeers) {
buf.append(_pendingPeers.size()).append(' ');
for (Hash peer : _pendingPeers) {
buf.append(peer.toBase64()).append(" ");
}
}
buf.append(" Failed: ");
synchronized (_failedPeers) {
buf.append(_failedPeers.size()).append(' ');
for (Hash peer : _failedPeers) {
buf.append(peer.toBase64()).append(" ");
}
}
buf.append(" Successful: ");
synchronized (_successfulPeers) {
buf.append(_successfulPeers.size()).append(' ');
for (Hash peer : _successfulPeers) {
buf.append(peer.toBase64()).append(" ");
}
}
/**
**
* buf.append(" Successful Exploratory: ");
* synchronized (_successfulExploratoryPeers) {
* buf.append(_successfulExploratoryPeers.size()).append(' ');
* for (Iterator<Hash> iter = _successfulExploratoryPeers.iterator(); iter.hasNext(); ) {
* Hash peer = iter.next();
* buf.append(peer.toBase64()).append(" ");
* }
* }
***
*/
return buf.toString();
}
use of net.i2p.data.Hash in project i2p.i2p-bote by i2p.
the class KademliaDHT method createRandomHash.
/**
* Returns a random value <code>r</code> such that <code>min <= r < max</code>.
* @param min
* @param max
*/
private Hash createRandomHash(BigInteger min, BigInteger max) {
BigInteger hashValue;
if (min.compareTo(max) >= 0)
hashValue = min;
else {
// a random number between 0 and 2^256-1
hashValue = new BigInteger(Hash.HASH_LENGTH * 8, RandomSource.getInstance());
// a random number equal to or greater than min, and less than max
hashValue = min.add(hashValue.mod(max.subtract(min)));
}
byte[] hashArray = hashValue.toByteArray();
if (// it's okay for the array length to be Hash.HASH_LENGTH if the zeroth byte only contains the sign bit
hashArray.length > Hash.HASH_LENGTH + 1 || (hashArray.length == Hash.HASH_LENGTH + 1 && hashArray[0] != 0))
log.error("Hash value too big to fit in " + Hash.HASH_LENGTH + " bytes: " + hashValue);
byte[] hashArrayPadded = new byte[Hash.HASH_LENGTH];
if (hashArray.length == Hash.HASH_LENGTH + 1)
System.arraycopy(hashArray, 1, hashArrayPadded, 0, Hash.HASH_LENGTH);
else
System.arraycopy(hashArray, 0, hashArrayPadded, Hash.HASH_LENGTH - hashArray.length, hashArray.length);
return new Hash(hashArrayPadded);
}
Aggregations