use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class I2PSessionImpl method lookupDest.
/**
* Blocking.
* @param maxWait ms
* @since 0.8.3
* @return null on failure
*/
public Destination lookupDest(Hash h, long maxWait) throws I2PSessionException {
synchronized (_lookupCache) {
Destination rv = _lookupCache.get(h);
if (rv != null)
return rv;
}
synchronized (_stateLock) {
// not before GOTDATE
if (_state == State.CLOSED || _state == State.INIT || _state == State.OPENING) {
if (_log.shouldLog(Log.INFO))
_log.info("Session closed, cannot lookup " + h);
return null;
}
}
LookupWaiter waiter;
long nonce;
if (_routerSupportsHostLookup) {
nonce = _lookupID.incrementAndGet() & 0x7fffffff;
waiter = new LookupWaiter(h, nonce);
} else {
// won't be used
nonce = 0;
waiter = new LookupWaiter(h);
}
_pendingLookups.offer(waiter);
Destination rv = null;
try {
if (_routerSupportsHostLookup) {
if (_log.shouldLog(Log.INFO))
_log.info("Sending HostLookup for " + h);
SessionId id = _sessionId;
if (id == null)
id = new SessionId(65535);
sendMessage_unchecked(new HostLookupMessage(id, h, nonce, maxWait));
} else {
if (_log.shouldLog(Log.INFO))
_log.info("Sending DestLookup for " + h);
sendMessage_unchecked(new DestLookupMessage(h));
}
try {
synchronized (waiter) {
waiter.wait(maxWait);
rv = waiter.destination;
}
} catch (InterruptedException ie) {
throw new I2PSessionException("Interrupted", ie);
}
} finally {
_pendingLookups.remove(waiter);
}
return rv;
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class I2PSessionImpl method messageReceived.
/**
* The I2CPMessageEventListener callback.
* Recieve notification of some I2CP message and handle it if possible.
*
* We route the message based on message type AND session ID.
*
* The following types never contain a session ID and are not routable to
* a subsession:
* BandwidthLimitsMessage, DestReplyMessage
*
* The following types may not contain a valid session ID
* even when intended for a subsession, so we must take special care:
* SessionStatusMessage
*
* @param reader unused
*/
public void messageReceived(I2CPMessageReader reader, I2CPMessage message) {
int type = message.getType();
SessionId id = message.sessionId();
SessionId currId = _sessionId;
if (id == null || id.equals(currId) || (currId == null && id != null && type == SessionStatusMessage.MESSAGE_TYPE) || ((id == null || id.getSessionId() == 65535) && (type == HostReplyMessage.MESSAGE_TYPE || type == DestReplyMessage.MESSAGE_TYPE))) {
// it's for us
I2CPMessageHandler handler = _handlerMap.getHandler(type);
if (handler != null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Message received of type " + type + " to be handled by " + handler.getClass().getSimpleName());
handler.handleMessage(message, this);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix() + "Unknown message or unhandleable message received: type = " + type);
}
} else {
SubSession sub = _subsessionMap.get(id);
if (sub != null) {
// it's for a subsession
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Message received of type " + type + " to be handled by " + sub);
sub.messageReceived(reader, message);
} else if (id != null && type == SessionStatusMessage.MESSAGE_TYPE) {
// look for a subsession without a session
synchronized (_subsessionLock) {
for (SubSession sess : _subsessions) {
if (sess.getSessionId() == null) {
sess.messageReceived(reader, message);
id = sess.getSessionId();
if (id != null) {
if (id.equals(_sessionId)) {
// shouldnt happen
sess.setSessionId(null);
if (_log.shouldLog(Log.WARN))
_log.warn("Dup or our session id " + id);
} else {
SubSession old = _subsessionMap.putIfAbsent(id, sess);
if (old != null) {
// shouldnt happen
sess.setSessionId(null);
if (_log.shouldLog(Log.WARN))
_log.warn("Dup session id " + id);
}
}
}
return;
}
if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix() + "No session " + id + " to handle message: type = " + type);
}
}
} else {
// it's for nobody
if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix() + "No session " + id + " to handle message: type = " + type);
}
}
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class I2PSessionImpl method removeSubsession.
/**
* @since 0.9.21
*/
public void removeSubsession(I2PSession session) {
if (!(session instanceof SubSession))
return;
synchronized (_subsessionLock) {
_subsessions.remove(session);
SessionId id = ((SubSession) session).getSessionId();
if (id != null)
_subsessionMap.remove(id);
// / tell the subsession
try {
// doesn't really throw
session.destroySession();
} catch (I2PSessionException ise) {
}
}
// do we need this here? subsession.destroySession() calls primary
Destination d = session.getMyDestination();
if (d != null)
_context.keyRing().remove(d.calculateHash());
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class RequestLeaseSetJob method runJob.
public void runJob() {
if (_runner.isDead())
return;
LeaseSet requested = _requestState.getRequested();
long endTime = requested.getEarliestLeaseDate();
// Add a small number of ms (0 to MAX_FUDGE) that increases as we approach the expire time.
// Since the earliest date functions as a version number,
// this will force the floodfill to flood each new version;
// otherwise it won't if the earliest time hasn't changed.
long fudge = MAX_FUDGE - ((endTime - getContext().clock().now()) / (10 * 60 * 1000 / MAX_FUDGE));
// if (_log.shouldLog(Log.DEBUG))
// _log.debug("Adding fudge " + fudge);
endTime += fudge;
SessionId id = _runner.getSessionId(requested.getDestination().calculateHash());
if (id == null) {
_runner.failLeaseRequest(_requestState);
return;
}
I2CPMessage msg;
if (getContext().getProperty(PROP_VARIABLE, DFLT_VARIABLE) && (_runner instanceof QueuedClientConnectionRunner || RequestVariableLeaseSetMessage.isSupported(_runner.getClientVersion()))) {
// new style - leases will have individual expirations
RequestVariableLeaseSetMessage rmsg = new RequestVariableLeaseSetMessage();
rmsg.setSessionId(id);
for (int i = 0; i < requested.getLeaseCount(); i++) {
Lease lease = requested.getLease(i);
if (lease.getEndDate().getTime() < endTime) {
// don't modify old object, we don't know where it came from
Lease nl = new Lease();
nl.setGateway(lease.getGateway());
nl.setTunnelId(lease.getTunnelId());
nl.setEndDate(new Date(endTime));
lease = nl;
// if (_log.shouldLog(Log.INFO))
// _log.info("Adjusted end date to " + endTime + " for " + lease);
}
rmsg.addEndpoint(lease);
}
msg = rmsg;
} else {
// old style - all leases will have same expiration
RequestLeaseSetMessage rmsg = new RequestLeaseSetMessage();
Date end = new Date(endTime);
rmsg.setEndDate(end);
rmsg.setSessionId(id);
for (int i = 0; i < requested.getLeaseCount(); i++) {
Lease lease = requested.getLease(i);
rmsg.addEndpoint(lease.getGateway(), lease.getTunnelId());
}
msg = rmsg;
}
try {
// _runner.setLeaseRequest(state);
_runner.doSend(msg);
getContext().jobQueue().addJob(new CheckLeaseRequestStatus());
} catch (I2CPMessageException ime) {
getContext().statManager().addRateData("client.requestLeaseSetDropped", 1);
_log.error("Error sending I2CP message requesting the lease set", ime);
_requestState.setIsSuccessful(false);
if (_requestState.getOnFailed() != null)
RequestLeaseSetJob.this.getContext().jobQueue().addJob(_requestState.getOnFailed());
_runner.failLeaseRequest(_requestState);
// Don't disconnect, the tunnel will retry
// _runner.disconnectClient("I2CP error requesting leaseSet");
}
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class ClientManager method locked_getNextSessionId.
/**
* Generate a new random, unused sessionId. Caller must synch on _runners.
* @return null on failure
* @since 0.9.12
*/
private SessionId locked_getNextSessionId() {
int max = Math.max(1, Math.min(2048, _ctx.getProperty(PROP_MAX_SESSIONS, DEFAULT_MAX_SESSIONS)));
if (_runnerSessionIds.size() >= max) {
_log.logAlways(Log.WARN, "Session refused, max is " + max + ", increase " + PROP_MAX_SESSIONS);
return null;
}
for (int i = 0; i < 100; i++) {
SessionId id = new SessionId(_ctx.random().nextInt(MAX_SESSION_ID + 1));
if (_runnerSessionIds.add(id))
return id;
}
_log.logAlways(Log.WARN, "Session refused, can't find id slot");
return null;
}
Aggregations