001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.message.extended;
021
022
023 import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
024 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
025
026
027 /**
028 * An extended operation intended for notifying clients of upcoming
029 * disconnection. Here's what <a
030 * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a> has to say about
031 * it:
032 *
033 * <pre>
034 * Section 4.1.1 (Small snippet on sending NoD)
035 *
036 * If the server receives a PDU from the client in which the LDAPMessage
037 * SEQUENCE tag cannot be recognized, the messageID cannot be parsed,
038 * the tag of the protocolOp is not recognized as a request, or the
039 * encoding structures or lengths of data fields are found to be
040 * incorrect, then the server MUST return the notice of disconnection
041 * described in section 4.4.1, with resultCode protocolError, and
042 * immediately close the connection. In other cases that the server
043 * cannot parse the request received by the client, the server MUST
044 * return an appropriate response to the request, with the resultCode
045 * set to protocolError.
046 *
047 * ...
048 *
049 * 4.4. Unsolicited Notification
050 *
051 * An unsolicited notification is an LDAPMessage sent from the server to
052 * the client which is not in response to any LDAPMessage received by
053 * the server. It is used to signal an extraordinary condition in the
054 * server or in the connection between the client and the server. The
055 * notification is of an advisory nature, and the server will not expect
056 * any response to be returned from the client.
057 *
058 * The unsolicited notification is structured as an LDAPMessage in which
059 * the messageID is 0 and protocolOp is of the extendedResp form. The
060 * responseName field of the ExtendedResponse is present. The LDAPOID
061 * value MUST be unique for this notification, and not be used in any
062 * other situation.
063 *
064 * One unsolicited notification is defined in this document.
065 *
066 * 4.4.1. Notice of Disconnection
067 *
068 * This notification may be used by the server to advise the client that
069 * the server is about to close the connection due to an error
070 * condition. Note that this notification is NOT a response to an
071 * unbind requested by the client: the server MUST follow the procedures
072 * of section 4.3. This notification is intended to assist clients in
073 * distinguishing between an error condition and a transient network
074 * failure. As with a connection close due to network failure, the
075 * client MUST NOT assume that any outstanding requests which modified
076 * the directory have succeeded or failed.
077 *
078 * The responseName is 1.3.6.1.4.1.1466.20036, the response field is
079 * absent, and the resultCode is used to indicate the reason for the
080 * disconnection.
081 *
082 * The following resultCode values are to be used in this notification:
083 *
084 * - protocolError: The server has received data from the client in
085 * which the LDAPMessage structure could not be parsed.
086 *
087 * - strongAuthRequired: The server has detected that an established
088 * underlying security association protecting communication between
089 * the client and server has unexpectedly failed or been compromised.
090 *
091 * - unavailable: This server will stop accepting new connections and
092 * operations on all existing connections, and be unavailable for an
093 * extended period of time. The client may make use of an alternative
094 * server.
095 *
096 * After sending this notice, the server MUST close the connection.
097 * After receiving this notice, the client MUST NOT transmit any further
098 * on the connection, and may abruptly close the connection.
099 * </pre>
100 *
101 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
102 * @version $Rev: 692922 $
103 */
104 public class NoticeOfDisconnect extends ExtendedResponseImpl
105 {
106 private static final long serialVersionUID = -4682291068700593492L;
107
108 public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20036";
109
110 private static final byte[] EMPTY_RESPONSE = new byte[0];
111
112 public static final NoticeOfDisconnect UNAVAILABLE = new NoticeOfDisconnect( ResultCodeEnum.UNAVAILABLE );
113
114 public static final NoticeOfDisconnect PROTOCOLERROR = new NoticeOfDisconnect( ResultCodeEnum.PROTOCOL_ERROR );
115
116 public static final NoticeOfDisconnect STRONGAUTHREQUIRED = new NoticeOfDisconnect( ResultCodeEnum.STRONG_AUTH_REQUIRED );
117
118
119 private NoticeOfDisconnect( ResultCodeEnum rcode )
120 {
121 super( 0, EXTENSION_OID );
122
123 switch ( rcode )
124 {
125 case UNAVAILABLE :
126 break;
127
128 case PROTOCOL_ERROR :
129 break;
130
131 case STRONG_AUTH_REQUIRED :
132 break;
133
134 default:
135 throw new IllegalArgumentException( "The result code can only be one of: " + ResultCodeEnum.UNAVAILABLE
136 + ", " + ResultCodeEnum.PROTOCOL_ERROR + ", " + ResultCodeEnum.STRONG_AUTH_REQUIRED );
137 }
138
139 super.getLdapResult().setErrorMessage( rcode.toString() + ": The server will disconnect!" );
140 super.getLdapResult().setMatchedDn( null );
141 super.getLdapResult().setResultCode( rcode );
142 }
143
144
145 // ------------------------------------------------------------------------
146 // ExtendedResponse Interface Method Implementations
147 // ------------------------------------------------------------------------
148
149
150 /**
151 * Gets the reponse OID specific encoded response values.
152 *
153 * @return the response specific encoded response values.
154 */
155 public byte[] getResponse()
156 {
157 return EMPTY_RESPONSE;
158 }
159
160
161 /**
162 * Sets the reponse OID specific encoded response values.
163 *
164 * @param value
165 * the response specific encoded response values.
166 */
167 public void setResponse( byte[] value )
168 {
169 throw new UnsupportedOperationException( "the response is hardcoded as zero length array" );
170 }
171
172
173 /**
174 * Gets the OID uniquely identifying this extended response (a.k.a. its
175 * name).
176 *
177 * @return the OID of the extended response type.
178 */
179 public String getResponseName()
180 {
181 return EXTENSION_OID;
182 }
183
184
185 /**
186 * Sets the OID uniquely identifying this extended response (a.k.a. its
187 * name).
188 *
189 * @param oid
190 * the OID of the extended response type.
191 */
192 public void setResponseName( String oid )
193 {
194 throw new UnsupportedOperationException( "the OID is fixed: " + EXTENSION_OID );
195 }
196
197
198 public boolean equals( Object obj )
199 {
200 if ( obj == this )
201 {
202 return true;
203 }
204
205 if ( obj instanceof NoticeOfDisconnect )
206 {
207 return true;
208 }
209
210 return false;
211 }
212 }