1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * https://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 * 19 */ 20 package org.apache.directory.api.ldap.model.message.extended; 21 22 23 import org.apache.directory.api.i18n.I18n; 24 import org.apache.directory.api.ldap.model.message.AbstractExtendedResponse; 25 import org.apache.directory.api.ldap.model.message.ResultCodeEnum; 26 import org.apache.directory.api.util.Strings; 27 28 29 /** 30 * An extended operation intended for notifying clients of upcoming 31 * disconnection. Here's what <a 32 * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a> has to say about 33 * it: 34 * 35 * <pre> 36 * Section 4.1.1 (Small snippet on sending NoD) 37 * 38 * If the server receives a PDU from the client in which the LDAPMessage 39 * SEQUENCE tag cannot be recognized, the messageID cannot be parsed, 40 * the tag of the protocolOp is not recognized as a request, or the 41 * encoding structures or lengths of data fields are found to be 42 * incorrect, then the server MUST return the notice of disconnection 43 * described in section 4.4.1, with resultCode protocolError, and 44 * immediately close the connection. In other cases that the server 45 * cannot parse the request received by the client, the server MUST 46 * return an appropriate response to the request, with the resultCode 47 * set to protocolError. 48 * 49 * ... 50 * 51 * 4.4. Unsolicited Notification 52 * 53 * An unsolicited notification is an LDAPMessage sent from the server to 54 * the client which is not in response to any LDAPMessage received by 55 * the server. It is used to signal an extraordinary condition in the 56 * server or in the connection between the client and the server. The 57 * notification is of an advisory nature, and the server will not expect 58 * any response to be returned from the client. 59 * 60 * The unsolicited notification is structured as an LDAPMessage in which 61 * the messageID is 0 and protocolOp is of the extendedResp form. The 62 * responseName field of the ExtendedResponse is present. The LDAPOID 63 * value MUST be unique for this notification, and not be used in any 64 * other situation. 65 * 66 * One unsolicited notification is defined in this document. 67 * 68 * 4.4.1. Notice of Disconnection 69 * 70 * This notification may be used by the server to advise the client that 71 * the server is about to close the connection due to an error 72 * condition. Note that this notification is NOT a response to an 73 * unbind requested by the client: the server MUST follow the procedures 74 * of section 4.3. This notification is intended to assist clients in 75 * distinguishing between an error condition and a transient network 76 * failure. As with a connection close due to network failure, the 77 * client MUST NOT assume that any outstanding requests which modified 78 * the directory have succeeded or failed. 79 * 80 * The responseName is 1.3.6.1.4.1.1466.20036, the response field is 81 * absent, and the resultCode is used to indicate the reason for the 82 * disconnection. 83 * 84 * The following resultCode values are to be used in this notification: 85 * 86 * - protocolError: The server has received data from the client in 87 * which the LDAPMessage structure could not be parsed. 88 * 89 * - strongAuthRequired: The server has detected that an established 90 * underlying security association protecting communication between 91 * the client and server has unexpectedly failed or been compromised. 92 * 93 * - unavailable: This server will stop accepting new connections and 94 * operations on all existing connections, and be unavailable for an 95 * extended period of time. The client may make use of an alternative 96 * server. 97 * 98 * After sending this notice, the server MUST close the connection. 99 * After receiving this notice, the client MUST NOT transmit any further 100 * on the connection, and may abruptly close the connection. 101 * </pre> 102 * 103 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 104 */ 105 public final class NoticeOfDisconnect extends AbstractExtendedResponse 106 { 107 /** The OID of the NotiveOfDisconnect extended operation. */ 108 public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20036"; 109 110 /** The single instance with unavailable result code. */ 111 public static final NoticeOfDisconnect UNAVAILABLE = new NoticeOfDisconnect( ResultCodeEnum.UNAVAILABLE ); 112 113 /** The single instance with protocolError result code. */ 114 public static final NoticeOfDisconnect PROTOCOLERROR = new NoticeOfDisconnect( ResultCodeEnum.PROTOCOL_ERROR ); 115 116 /** The single instance with strongAuthRequired result code. */ 117 public static final NoticeOfDisconnect STRONGAUTHREQUIRED = new NoticeOfDisconnect( 118 ResultCodeEnum.STRONG_AUTH_REQUIRED ); 119 120 121 /** 122 * Creates a new instance of NoticeOfDisconnect. 123 * 124 * @param rcode The result code 125 */ 126 private NoticeOfDisconnect( ResultCodeEnum rcode ) 127 { 128 super( 0, EXTENSION_OID ); 129 130 switch ( rcode ) 131 { 132 case UNAVAILABLE: 133 break; 134 135 case PROTOCOL_ERROR: 136 break; 137 138 case STRONG_AUTH_REQUIRED: 139 break; 140 141 default: 142 throw new IllegalArgumentException( I18n.err( I18n.ERR_13503_RESULT_CODE_SHOULD_BE_IN, ResultCodeEnum.UNAVAILABLE, 143 ResultCodeEnum.PROTOCOL_ERROR, ResultCodeEnum.STRONG_AUTH_REQUIRED ) ); 144 } 145 146 super.getLdapResult().setDiagnosticMessage( rcode.toString() + ": The server will disconnect!" ); 147 super.getLdapResult().setMatchedDn( null ); 148 super.getLdapResult().setResultCode( rcode ); 149 } 150 151 152 /** 153 * Create a NoD associated with a result code enum 154 * 155 * @param rcode The result code 156 * @return The created NoticeOfDisconnect 157 */ 158 public static NoticeOfDisconnect createNoticeOfDisconnect( ResultCodeEnum rcode ) 159 { 160 NoticeOfDisconnect nod; 161 162 switch ( rcode ) 163 { 164 case UNAVAILABLE: 165 nod = UNAVAILABLE; 166 break; 167 168 case PROTOCOL_ERROR: 169 nod = PROTOCOLERROR; 170 break; 171 172 case STRONG_AUTH_REQUIRED: 173 nod = STRONGAUTHREQUIRED; 174 break; 175 176 default: 177 nod = new NoticeOfDisconnect( rcode ); 178 break; 179 } 180 181 nod.getLdapResult().setDiagnosticMessage( rcode.toString() + ": The server will disconnect!" ); 182 nod.getLdapResult().setMatchedDn( null ); 183 nod.getLdapResult().setResultCode( rcode ); 184 185 return nod; 186 } 187 188 189 // ------------------------------------------------------------------------ 190 // ExtendedResponse Interface Method Implementations 191 // ------------------------------------------------------------------------ 192 193 /** 194 * Gets the reponse OID specific encoded response values. 195 * 196 * @return the response specific encoded response values. 197 */ 198 public byte[] getResponse() 199 { 200 return Strings.EMPTY_BYTES; 201 } 202 203 204 /** 205 * Sets the response OID specific encoded response values. 206 * 207 * @param value the response specific encoded response values. 208 */ 209 public void setResponse( byte[] value ) 210 { 211 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13505_HARDCODED_ZERO_LENGTH_RESPONSE ) ); 212 } 213 214 215 /** 216 * Sets the OID uniquely identifying this extended response (a.k.a. its 217 * name). 218 * 219 * @param oid the OID of the extended response type. 220 */ 221 @Override 222 public void setResponseName( String oid ) 223 { 224 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13504_FIX_OID, EXTENSION_OID ) ); 225 } 226 227 228 /** 229 * {@inheritDoc} 230 */ 231 @Override 232 public int hashCode() 233 { 234 int hash = 37; 235 // Seems simple but look at the equals() method ... 236 hash = hash * 17 + getClass().getName().hashCode(); 237 238 return hash; 239 } 240 241 242 /** 243 * {@inheritDoc} 244 */ 245 @Override 246 public boolean equals( Object obj ) 247 { 248 if ( obj == this ) 249 { 250 return true; 251 } 252 253 return obj instanceof NoticeOfDisconnect; 254 } 255 }