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