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 * http://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.ExtendedResponseImpl; 25 import org.apache.directory.api.ldap.model.message.ResultCodeEnum; 26 27 28 /** 29 * An extended operation intended for notifying clients of upcoming 30 * disconnection. Here's what <a 31 * href="http://www.faqs.org/rfcs/rfc2251.html">RFC 2251</a> has to say about 32 * it: 33 * 34 * <pre> 35 * Section 4.1.1 (Small snippet on sending NoD) 36 * 37 * If the server receives a PDU from the client in which the LDAPMessage 38 * SEQUENCE tag cannot be recognized, the messageID cannot be parsed, 39 * the tag of the protocolOp is not recognized as a request, or the 40 * encoding structures or lengths of data fields are found to be 41 * incorrect, then the server MUST return the notice of disconnection 42 * described in section 4.4.1, with resultCode protocolError, and 43 * immediately close the connection. In other cases that the server 44 * cannot parse the request received by the client, the server MUST 45 * return an appropriate response to the request, with the resultCode 46 * set to protocolError. 47 * 48 * ... 49 * 50 * 4.4. Unsolicited Notification 51 * 52 * An unsolicited notification is an LDAPMessage sent from the server to 53 * the client which is not in response to any LDAPMessage received by 54 * the server. It is used to signal an extraordinary condition in the 55 * server or in the connection between the client and the server. The 56 * notification is of an advisory nature, and the server will not expect 57 * any response to be returned from the client. 58 * 59 * The unsolicited notification is structured as an LDAPMessage in which 60 * the messageID is 0 and protocolOp is of the extendedResp form. The 61 * responseName field of the ExtendedResponse is present. The LDAPOID 62 * value MUST be unique for this notification, and not be used in any 63 * other situation. 64 * 65 * One unsolicited notification is defined in this document. 66 * 67 * 4.4.1. Notice of Disconnection 68 * 69 * This notification may be used by the server to advise the client that 70 * the server is about to close the connection due to an error 71 * condition. Note that this notification is NOT a response to an 72 * unbind requested by the client: the server MUST follow the procedures 73 * of section 4.3. This notification is intended to assist clients in 74 * distinguishing between an error condition and a transient network 75 * failure. As with a connection close due to network failure, the 76 * client MUST NOT assume that any outstanding requests which modified 77 * the directory have succeeded or failed. 78 * 79 * The responseName is 1.3.6.1.4.1.1466.20036, the response field is 80 * absent, and the resultCode is used to indicate the reason for the 81 * disconnection. 82 * 83 * The following resultCode values are to be used in this notification: 84 * 85 * - protocolError: The server has received data from the client in 86 * which the LDAPMessage structure could not be parsed. 87 * 88 * - strongAuthRequired: The server has detected that an established 89 * underlying security association protecting communication between 90 * the client and server has unexpectedly failed or been compromised. 91 * 92 * - unavailable: This server will stop accepting new connections and 93 * operations on all existing connections, and be unavailable for an 94 * extended period of time. The client may make use of an alternative 95 * server. 96 * 97 * After sending this notice, the server MUST close the connection. 98 * After receiving this notice, the client MUST NOT transmit any further 99 * on the connection, and may abruptly close the connection. 100 * </pre> 101 * 102 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 103 */ 104 public final class NoticeOfDisconnect extends ExtendedResponseImpl 105 { 106 /** The OID of the NotiveOfDisconnect extended operation. */ 107 public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20036"; 108 109 /** The empty response */ 110 private static final byte[] EMPTY_RESPONSE = new byte[0]; 111 112 /** The single instance with unavailable result code. */ 113 public static final NoticeOfDisconnect UNAVAILABLE = new NoticeOfDisconnect( ResultCodeEnum.UNAVAILABLE ); 114 115 /** The single instance with protocolError result code. */ 116 public static final NoticeOfDisconnect PROTOCOLERROR = new NoticeOfDisconnect( ResultCodeEnum.PROTOCOL_ERROR ); 117 118 /** The single instance with strongAuthRequired result code. */ 119 public static final NoticeOfDisconnect STRONGAUTHREQUIRED = new NoticeOfDisconnect( 120 ResultCodeEnum.STRONG_AUTH_REQUIRED ); 121 122 123 /** 124 * Creates a new instance of NoticeOfDisconnect. 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_04166, 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 // ExtendedResponse Interface Method Implementations 154 // ------------------------------------------------------------------------ 155 156 /** 157 * Gets the reponse OID specific encoded response values. 158 * 159 * @return the response specific encoded response values. 160 */ 161 public byte[] getResponse() 162 { 163 return EMPTY_RESPONSE; 164 } 165 166 167 /** 168 * Sets the response OID specific encoded response values. 169 * 170 * @param value the response specific encoded response values. 171 */ 172 public void setResponse( byte[] value ) 173 { 174 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04173 ) ); 175 } 176 177 178 /** 179 * Gets the OID uniquely identifying this extended response (a.k.a. its 180 * name). 181 * 182 * @return the OID of the extended response type. 183 */ 184 public String getResponseName() 185 { 186 return EXTENSION_OID; 187 } 188 189 190 /** 191 * Sets the OID uniquely identifying this extended response (a.k.a. its 192 * name). 193 * 194 * @param oid 195 * the OID of the extended response type. 196 */ 197 public void setResponseName( String oid ) 198 { 199 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04168, EXTENSION_OID ) ); 200 } 201 202 203 /** 204 * {@inheritDoc} 205 */ 206 @Override 207 public int hashCode() 208 { 209 int hash = 37; 210 // Seems simple but look at the equals() method ... 211 hash = hash * 17 + getClass().getName().hashCode(); 212 213 return hash; 214 } 215 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override 221 public boolean equals( Object obj ) 222 { 223 if ( obj == this ) 224 { 225 return true; 226 } 227 228 return ( obj instanceof NoticeOfDisconnect ); 229 } 230 }