use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.
the class EstablishmentManager method getOurInfo.
/**
**
* private void sendOurInfo(PeerState peer, boolean isInbound) {
* if (_log.shouldLog(Log.INFO))
* _log.info("Publishing to the peer after confirm: " +
* (isInbound ? " inbound con from " + peer : "outbound con to " + peer));
* DatabaseStoreMessage m = getOurInfo();
* _transport.send(m, peer);
* }
***
*/
/**
* A database store message with our router info
* @return non-null
* @since 0.9.24 split from sendOurInfo()
*/
private DatabaseStoreMessage getOurInfo() {
DatabaseStoreMessage m = new DatabaseStoreMessage(_context);
m.setEntry(_context.router().getRouterInfo());
m.setMessageExpiration(_context.clock().now() + DATA_MESSAGE_TIMEOUT);
return m;
}
use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.
the class EstablishmentManager method handleCompletelyEstablished.
/**
* ok, fully received, add it to the established cons and send any
* queued messages
*
* @return the new PeerState
*/
private PeerState handleCompletelyEstablished(OutboundEstablishState state) {
if (state.complete()) {
RouterIdentity rem = state.getRemoteIdentity();
if (rem != null)
return _transport.getPeerState(rem.getHash());
}
long now = _context.clock().now();
RouterIdentity remote = state.getRemoteIdentity();
// only if == state
RemoteHostId claimed = state.getClaimedAddress();
if (claimed != null)
_outboundByClaimedAddress.remove(claimed, state);
_outboundByHash.remove(remote.calculateHash(), state);
PeerState peer = new PeerState(_context, _transport, state.getSentIP(), state.getSentPort(), remote.calculateHash(), false);
peer.setCurrentCipherKey(state.getCipherKey());
peer.setCurrentMACKey(state.getMACKey());
peer.setTheyRelayToUsAs(state.getReceivedRelayTag());
int mtu = state.getRemoteAddress().getMTU();
if (mtu > 0)
peer.setHisMTU(mtu);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Handle completely established (outbound): " + state + " - " + peer.getRemotePeer());
_transport.addRemotePeerState(peer);
_transport.setIP(remote.calculateHash(), state.getSentIP());
_context.statManager().addRateData("udp.outboundEstablishTime", state.getLifetime());
DatabaseStoreMessage dbsm = null;
if (!state.isFirstMessageOurDSM()) {
dbsm = getOurInfo();
} else if (_log.shouldLog(Log.INFO)) {
_log.info("Skipping publish: " + state);
}
List<OutNetMessage> msgs = new ArrayList<OutNetMessage>(8);
OutNetMessage msg;
while ((msg = state.getNextQueuedMessage()) != null) {
if (now - Router.CLOCK_FUDGE_FACTOR > msg.getExpiration()) {
msg.timestamp("took too long but established...");
_transport.failed(msg, "Took too long to establish, but it was established");
} else {
msg.timestamp("session fully established and sent");
msgs.add(msg);
}
}
_transport.send(dbsm, msgs, peer);
return peer;
}
use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.
the class HandleFloodfillDatabaseStoreMessageJob method sendAck.
private void sendAck(Hash storedKey) {
DeliveryStatusMessage msg = new DeliveryStatusMessage(getContext());
msg.setMessageId(_message.getReplyToken());
// Randomize for a little protection against clock-skew fingerprinting.
// But the "arrival" isn't used for anything, right?
// TODO just set to 0?
// TODO we have no session to garlic wrap this with, needs new message
msg.setArrival(getContext().clock().now() - getContext().random().nextInt(3 * 1000));
// may be null
TunnelId replyTunnel = _message.getReplyTunnel();
// A store of our own RI, only if we are not FF
DatabaseStoreMessage msg2;
if ((getContext().netDb().floodfillEnabled() && !getContext().router().gracefulShutdownInProgress()) || storedKey.equals(getContext().routerHash())) {
// don't send our RI if the store was our RI (from PeerTestJob)
msg2 = null;
} else {
// we aren't ff, send a go-away message
msg2 = new DatabaseStoreMessage(getContext());
RouterInfo me = getContext().router().getRouterInfo();
msg2.setEntry(me);
if (_log.shouldWarn())
_log.warn("Got a store w/ reply token, but we aren't ff: from: " + _from + " fromHash: " + _fromHash + " msg: " + _message, new Exception());
}
Hash toPeer = _message.getReplyGateway();
boolean toUs = getContext().routerHash().equals(toPeer);
// else through an exploratory tunnel.
if (toUs && replyTunnel != null) {
// if we are the gateway, act as if we received it
TunnelGatewayMessage tgm = new TunnelGatewayMessage(getContext());
tgm.setMessage(msg);
tgm.setTunnelId(replyTunnel);
tgm.setMessageExpiration(msg.getMessageExpiration());
getContext().tunnelDispatcher().dispatch(tgm);
if (msg2 != null) {
TunnelGatewayMessage tgm2 = new TunnelGatewayMessage(getContext());
tgm2.setMessage(msg2);
tgm2.setTunnelId(replyTunnel);
tgm2.setMessageExpiration(msg.getMessageExpiration());
getContext().tunnelDispatcher().dispatch(tgm2);
}
} else if (toUs || getContext().commSystem().isEstablished(toPeer)) {
Job send = new SendMessageDirectJob(getContext(), msg, toPeer, REPLY_TIMEOUT, MESSAGE_PRIORITY);
send.runJob();
if (msg2 != null) {
Job send2 = new SendMessageDirectJob(getContext(), msg2, toPeer, REPLY_TIMEOUT, MESSAGE_PRIORITY);
send2.runJob();
}
} else {
// pick tunnel with endpoint closest to toPeer
TunnelInfo outTunnel = getContext().tunnelManager().selectOutboundExploratoryTunnel(toPeer);
if (outTunnel == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("No outbound tunnel could be found");
return;
}
getContext().tunnelDispatcher().dispatchOutbound(msg, outTunnel.getSendTunnelId(0), replyTunnel, toPeer);
if (msg2 != null)
getContext().tunnelDispatcher().dispatchOutbound(msg2, outTunnel.getSendTunnelId(0), replyTunnel, toPeer);
}
}
use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.
the class FloodfillNetworkDatabaseFacade method flood.
/**
* Send to a subset of all floodfill peers.
* We do this to implement Kademlia within the floodfills, i.e.
* we flood to those closest to the key.
*/
public void flood(DatabaseEntry ds) {
Hash key = ds.getHash();
RouterKeyGenerator gen = _context.routerKeyGenerator();
Hash rkey = gen.getRoutingKey(key);
FloodfillPeerSelector sel = (FloodfillPeerSelector) getPeerSelector();
List<Hash> peers = sel.selectFloodfillParticipants(rkey, MAX_TO_FLOOD, getKBuckets());
// todo key cert skip?
long until = gen.getTimeTillMidnight();
if (until < NEXT_RKEY_LS_ADVANCE_TIME || (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO && until < NEXT_RKEY_RI_ADVANCE_TIME)) {
// to avoid lookup faulures after midnight, also flood to some closest to the
// next routing key for a period of time before midnight.
Hash nkey = gen.getNextRoutingKey(key);
List<Hash> nextPeers = sel.selectFloodfillParticipants(nkey, NEXT_FLOOD_QTY, getKBuckets());
int i = 0;
for (Hash h : nextPeers) {
// But other implementations may not...
if (h.equals(key))
continue;
// todo key cert skip?
if (!peers.contains(h)) {
peers.add(h);
i++;
}
}
if (i > 0 && _log.shouldLog(Log.INFO))
_log.info("Flooding the entry for " + key + " to " + i + " more, just before midnight");
}
int flooded = 0;
for (int i = 0; i < peers.size(); i++) {
Hash peer = peers.get(i);
RouterInfo target = lookupRouterInfoLocally(peer);
if ((target == null) || (_context.banlist().isBanlisted(peer)))
continue;
// But other implementations may not...
if (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO && peer.equals(key))
continue;
if (peer.equals(_context.routerHash()))
continue;
DatabaseStoreMessage msg = new DatabaseStoreMessage(_context);
msg.setEntry(ds);
OutNetMessage m = new OutNetMessage(_context, msg, _context.clock().now() + FLOOD_TIMEOUT, FLOOD_PRIORITY, target);
Job floodFail = new FloodFailedJob(_context, peer);
m.setOnFailedSendJob(floodFail);
// we want to give credit on success, even if we aren't sure,
// because otherwise no use noting failure
Job floodGood = new FloodSuccessJob(_context, peer);
m.setOnSendJob(floodGood);
_context.commSystem().processMessage(m);
flooded++;
if (_log.shouldLog(Log.INFO))
_log.info("Flooding the entry for " + key.toBase64() + " to " + peer.toBase64());
}
if (_log.shouldLog(Log.INFO))
_log.info("Flooded the data to " + flooded + " of " + peers.size() + " peers");
}
use of net.i2p.data.i2np.DatabaseStoreMessage in project i2p.i2p by i2p.
the class OutboundClientMessageJobHelper method buildLeaseSetClove.
/**
* Build a clove that stores the leaseSet locally
*/
private static PayloadGarlicConfig buildLeaseSetClove(RouterContext ctx, long expiration, LeaseSet replyLeaseSet) {
PayloadGarlicConfig clove = new PayloadGarlicConfig();
clove.setCertificate(Certificate.NULL_CERT);
clove.setDeliveryInstructions(DeliveryInstructions.LOCAL);
clove.setExpiration(expiration);
clove.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
DatabaseStoreMessage msg = new DatabaseStoreMessage(ctx);
msg.setEntry(replyLeaseSet);
msg.setMessageExpiration(expiration);
clove.setPayload(msg);
return clove;
}
Aggregations