001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.core; 028 import org.opends.messages.Message; 029 030 031 032 import org.opends.server.admin.std.server.ConnectionHandlerCfg; 033 import org.opends.server.api.ClientConnection; 034 import org.opends.server.api.ConnectionHandler; 035 import org.opends.server.api.DirectoryThread; 036 import org.opends.server.api.ServerShutdownListener; 037 import org.opends.server.loggers.debug.DebugTracer; 038 import org.opends.server.types.DebugLogLevel; 039 import org.opends.server.types.DisconnectReason; 040 041 import static org.opends.server.loggers.debug.DebugLogger.*; 042 import org.opends.server.loggers.ErrorLogger; 043 import static org.opends.messages.CoreMessages.*; 044 045 import static org.opends.server.util.StaticUtils.*; 046 047 048 049 /** 050 * This class defines a thread that will be used to terminate client 051 * connections if they have been idle for too long. 052 */ 053 public class IdleTimeLimitThread 054 extends DirectoryThread 055 implements ServerShutdownListener 056 { 057 /** 058 * The debug log tracer for this object. 059 */ 060 private static final DebugTracer TRACER = getTracer(); 061 062 063 064 // Indicates whether a shutdown request has been received. 065 private boolean shutdownRequested; 066 067 068 069 /** 070 * Creates a new instance of this idle time limit thread. 071 */ 072 public IdleTimeLimitThread() 073 { 074 super("Idle Time Limit Thread"); 075 setDaemon(true); 076 077 shutdownRequested = false; 078 DirectoryServer.registerShutdownListener(this); 079 } 080 081 082 083 /** 084 * Operates in a loop, teriminating any client connections that have been idle 085 * for too long. 086 */ 087 public void run() 088 { 089 Message disconnectMessage = INFO_IDLETIME_LIMIT_EXCEEDED.get(); 090 091 long sleepTime = 5000L; 092 093 while (! shutdownRequested) 094 { 095 try 096 { 097 try 098 { 099 sleep(sleepTime); 100 } catch (InterruptedException ie) {} 101 102 sleepTime = 5000L; 103 for (ConnectionHandler ch : DirectoryServer.getConnectionHandlers()) 104 { 105 ConnectionHandler<? extends ConnectionHandlerCfg> connHandler = 106 (ConnectionHandler<? extends ConnectionHandlerCfg>) ch; 107 for (ClientConnection c : connHandler.getClientConnections()) 108 { 109 long idleTime = c.getIdleTime(); 110 if (idleTime > 0) 111 { 112 long idleTimeLimit = c.getIdleTimeLimit(); 113 if (idleTimeLimit > 0) 114 { 115 if (idleTime > idleTimeLimit) 116 { 117 if (debugEnabled()) 118 { 119 TRACER.debugInfo("Terminating client connection " + 120 c.getConnectionID() + 121 " due to the idle time limit"); 122 } 123 124 try 125 { 126 c.disconnect(DisconnectReason.IDLE_TIME_LIMIT_EXCEEDED, 127 true, disconnectMessage); 128 } 129 catch (Exception e) 130 { 131 if (debugEnabled()) 132 { 133 TRACER.debugCaught(DebugLogLevel.ERROR, e); 134 } 135 136 Message message = ERR_IDLETIME_DISCONNECT_ERROR.get( 137 c.getConnectionID(), 138 stackTraceToSingleLineString(e) 139 ); 140 ErrorLogger.logError(message); 141 } 142 } 143 else 144 { 145 long shouldSleepTime = idleTimeLimit - idleTime; 146 if (shouldSleepTime < sleepTime) 147 { 148 sleepTime = shouldSleepTime; 149 } 150 } 151 } 152 } 153 } 154 } 155 } 156 catch (Exception e) 157 { 158 if (debugEnabled()) 159 { 160 TRACER.debugCaught(DebugLogLevel.ERROR, e); 161 } 162 163 Message message = 164 ERR_IDLETIME_UNEXPECTED_ERROR.get(stackTraceToSingleLineString(e)); 165 ErrorLogger.logError(message); 166 } 167 } 168 } 169 170 171 172 /** 173 * {@inheritDoc} 174 */ 175 public String getShutdownListenerName() 176 { 177 return "Idle Time Limit Thread"; 178 } 179 180 181 182 /** 183 * {@inheritDoc} 184 */ 185 public void processServerShutdown(Message reason) 186 { 187 shutdownRequested = true; 188 } 189 } 190