"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "zxingorg/src/main/java/com/google/zxing/web/DoSTracker.java" between
zxing-zxing-3.4.0.tar.gz and zxing-zxing-3.4.1.tar.gz

About: ZXing ("zebra crossing") is a multi-format 1D/2D barcode image processing library implemented in Java, with ports to other languages.

DoSTracker.java  (zxing-zxing-3.4.0):DoSTracker.java  (zxing-zxing-3.4.1)
skipping to change at line 19 skipping to change at line 19
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.zxing.web; package com.google.zxing.web;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* Simple class which tracks a number of actions that happen per time and can fl ag when an action has * Simple class which tracks a number of actions that happen per time and can fl ag when an action has
* happened too frequently recently. This can be used for example to track and t emporarily block access * happened too frequently recently. This can be used for example to track and t emporarily block access
* from certain IPs or to certain hosts. * from certain IPs or to certain hosts.
*/ */
final class DoSTracker { final class DoSTracker {
private static final Logger log = Logger.getLogger(DoSTracker.class.getName()) ; private static final Logger log = Logger.getLogger(DoSTracker.class.getName()) ;
private final long maxAccessesPerTime; private volatile int maxAccessesPerTime;
private final Map<String,AtomicLong> numRecentAccesses; private final Map<String,AtomicInteger> numRecentAccesses;
DoSTracker(Timer timer, final String name, final int maxAccessesPerTime, long /**
accessTimeMS, int maxEntries) { * @param timer {@link Timer} to use for scheduling update tasks
* @param name identifier for this tracker
* @param maxAccessesPerTime maximum number of accesses allowed from one sourc
e per {@code accessTimeMS}
* @param accessTimeMS interval in milliseconds over which up to {@code maxAcc
essesPerTime} accesses are allowed
* @param maxEntries maximum number of source entries to track before forgetti
ng least recent ones
* @param maxLoad if set, dynamically adjust {@code maxAccessesPerTime} downwa
rds when average load per core
* exceeds this value, and upwards when below this value
*/
DoSTracker(Timer timer,
final String name,
final int maxAccessesPerTime,
long accessTimeMS,
int maxEntries,
Double maxLoad) {
this.maxAccessesPerTime = maxAccessesPerTime; this.maxAccessesPerTime = maxAccessesPerTime;
this.numRecentAccesses = new LRUMap<>(maxEntries); this.numRecentAccesses = new LRUMap<>(maxEntries);
timer.schedule(new TimerTask() { timer.schedule(new TrackerTask(name, maxLoad), accessTimeMS, accessTimeMS);
@Override
public void run() {
synchronized (numRecentAccesses) {
Iterator<Map.Entry<String,AtomicLong>> accessIt = numRecentAccesses.en
trySet().iterator();
while (accessIt.hasNext()) {
Map.Entry<String,AtomicLong> entry = accessIt.next();
AtomicLong count = entry.getValue();
// If number of accesses is below the threshold, remove it entirely
if (count.get() <= maxAccessesPerTime) {
accessIt.remove();
} else {
// Else it exceeded the max, so log it (again)
log.warning(name + ": Blocking " + entry.getKey() + " (" + count +
" outstanding)");
// Reduce count of accesses held against the host
count.getAndAdd(-maxAccessesPerTime);
}
}
}
}
}, accessTimeMS, accessTimeMS);
} }
boolean isBanned(String event) { boolean isBanned(String event) {
if (event == null) { if (event == null) {
return true; return true;
} }
AtomicLong count; AtomicInteger count;
synchronized (numRecentAccesses) { synchronized (numRecentAccesses) {
count = numRecentAccesses.get(event); count = numRecentAccesses.get(event);
if (count == null) { if (count == null) {
numRecentAccesses.put(event, new AtomicLong(1)); numRecentAccesses.put(event, new AtomicInteger(1));
return false; return false;
} }
} }
return count.incrementAndGet() > maxAccessesPerTime; return count.incrementAndGet() > maxAccessesPerTime;
} }
private final class TrackerTask extends TimerTask {
private final String name;
private final Double maxLoad;
private TrackerTask(String name, Double maxLoad) {
this.name = name;
this.maxLoad = maxLoad;
}
@Override
public void run() {
// largest count <= maxAccessesPerTime
int maxAllowedCount = 1;
// smallest count > maxAccessesPerTime
int minDisallowedCount = Integer.MAX_VALUE;
int localMAPT = maxAccessesPerTime;
synchronized (numRecentAccesses) {
Iterator<Map.Entry<String,AtomicInteger>> accessIt = numRecentAccesses.e
ntrySet().iterator();
while (accessIt.hasNext()) {
Map.Entry<String,AtomicInteger> entry = accessIt.next();
AtomicInteger atomicCount = entry.getValue();
int count = atomicCount.get();
// If number of accesses is below the threshold, remove it entirely
if (count <= localMAPT) {
accessIt.remove();
maxAllowedCount = Math.max(maxAllowedCount, count);
} else {
// Else it exceeded the max, so log it (again)
log.warning(name + ": Blocking " + entry.getKey() + " (" + count + "
outstanding)");
// Reduce count of accesses held against the host
atomicCount.getAndAdd(-localMAPT);
minDisallowedCount = Math.min(minDisallowedCount, count);
}
}
}
if (maxLoad != null) {
OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBea
n();
if (mxBean == null) {
log.warning("Could not obtain OperatingSystemMXBean; ignoring load");
} else {
double loadAvg = mxBean.getSystemLoadAverage();
if (loadAvg >= 0.0) {
int cores = mxBean.getAvailableProcessors();
double loadRatio = loadAvg / cores;
log.info(name + ": Load ratio: " + loadRatio + " (" + loadAvg + '/'
+ cores + ") vs " + maxLoad);
maxAccessesPerTime = loadRatio > maxLoad ?
Math.min(maxAllowedCount, maxAccessesPerTime) :
Math.max(minDisallowedCount, maxAccessesPerTime);
log.info(name + ": New maxAccessesPerTime: " + maxAccessesPerTime);
}
}
}
}
}
} }
 End of changes. 8 change blocks. 
31 lines changed or deleted 88 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)