From 8e0725db1c6f0da90e4611e97be43e9ab6c2b536 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 8 Dec 2016 11:29:13 +1100 Subject: [PATCH] Issue #123 Make sync on id generation more tightly scoped. --- .../session/DefaultSessionIdManager.java | 128 +++++++++--------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java index c69130c9d6a..ef63c232451 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java @@ -30,7 +30,6 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.SessionIdManager; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -209,33 +208,32 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi @Override public String newSessionId(HttpServletRequest request, long created) { - synchronized (this) + if (request==null) + return newSessionId(created); + + // A requested session ID can only be used if it is in use already. + String requested_id=request.getRequestedSessionId(); + if (requested_id!=null) { - if (request==null) - return newSessionId(created); - - // A requested session ID can only be used if it is in use already. - String requested_id=request.getRequestedSessionId(); - if (requested_id!=null) - { - String cluster_id=getId(requested_id); - if (isIdInUse(cluster_id)) - return cluster_id; - } - - - // Else reuse any new session ID already defined for this request. - String new_id=(String)request.getAttribute(__NEW_SESSION_ID); - if (new_id!=null&&isIdInUse(new_id)) - return new_id; - - // pick a new unique ID! - String id = newSessionId(request.hashCode()); - - request.setAttribute(__NEW_SESSION_ID,id); - return id; + String cluster_id=getId(requested_id); + if (isIdInUse(cluster_id)) + return cluster_id; } + + + // Else reuse any new session ID already defined for this request. + String new_id=(String)request.getAttribute(__NEW_SESSION_ID); + if (new_id!=null&&isIdInUse(new_id)) + return new_id; + + // pick a new unique ID! + String id = newSessionId(request.hashCode()); + + request.setAttribute(__NEW_SESSION_ID,id); + return id; } + + /* ------------------------------------------------------------ */ /** @@ -246,45 +244,49 @@ public class DefaultSessionIdManager extends ContainerLifeCycle implements Sessi { // pick a new unique ID! String id=null; - while (id==null||id.length()==0) - { - long r0=_weakRandom - ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32)) - :_random.nextLong(); - if (r0<0) - r0=-r0; - - // random chance to reseed - if (_reseed>0 && (r0%_reseed)== 1L) - { - if (LOG.isDebugEnabled()) - LOG.debug("Reseeding {}",this); - if (_random instanceof SecureRandom) - { - SecureRandom secure = (SecureRandom)_random; - secure.setSeed(secure.generateSeed(8)); - } - else - { - _random.setSeed(_random.nextLong()^System.currentTimeMillis()^seedTerm^Runtime.getRuntime().freeMemory()); - } - } - - long r1=_weakRandom - ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32)) - :_random.nextLong(); - if (r1<0) - r1=-r1; - - id=Long.toString(r0,36)+Long.toString(r1,36); - //add in the id of the node to ensure unique id across cluster - //NOTE this is different to the node suffix which denotes which node the request was received on - if (_workerName!=null) - id=_workerName + id; - - id = id+Long.toString(COUNTER.getAndIncrement()); - + synchronized (_random) + { + while (id==null||id.length()==0) + { + long r0=_weakRandom + ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32)) + :_random.nextLong(); + if (r0<0) + r0=-r0; + + // random chance to reseed + if (_reseed>0 && (r0%_reseed)== 1L) + { + if (LOG.isDebugEnabled()) + LOG.debug("Reseeding {}",this); + if (_random instanceof SecureRandom) + { + SecureRandom secure = (SecureRandom)_random; + secure.setSeed(secure.generateSeed(8)); + } + else + { + _random.setSeed(_random.nextLong()^System.currentTimeMillis()^seedTerm^Runtime.getRuntime().freeMemory()); + } + } + + long r1=_weakRandom + ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32)) + :_random.nextLong(); + if (r1<0) + r1=-r1; + + id=Long.toString(r0,36)+Long.toString(r1,36); + + //add in the id of the node to ensure unique id across cluster + //NOTE this is different to the node suffix which denotes which node the request was received on + if (_workerName!=null) + id=_workerName + id; + + id = id+Long.toString(COUNTER.getAndIncrement()); + + } } return id; }