/*
* Copyright (C) 2005-2008 Jive Software, 2017-2026 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire;
import org.dom4j.Namespace;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.session.LocalSession;
import org.jivesoftware.openfire.spi.ConnectionConfiguration;
import org.xmpp.packet.Packet;
import org.xmpp.packet.StreamError;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.Closeable;
import java.net.UnknownHostException;
import java.security.cert.Certificate;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletionStage;
/**
* Represents a connection on the server.
*
* @author Iain Shigeoka
*/
public interface Connection extends Closeable {
/**
* Verifies that the connection is still live. Typically, this is done by
* sending a whitespace character between packets.
*
* @return true if the socket remains valid, false otherwise.
*/
boolean validate();
/**
* Initializes the connection with it's owning session. Allows the
* connection class to configure itself with session related information
* (e.g. stream ID).
*
* @param session the session that owns this connection
*/
void init( LocalSession session );
/**
* Reinitializes the connection to switch to a different session. This allows for
* XEP-0198 resumption and transport-switching.
*
* @param session The new session now owning the connection.
*/
void reinit( LocalSession session );
/**
* Checks if the connection has finished initialization.
*
* @return true if connection has finished initialization.
*/
boolean isInitialized();
/**
* Returns the raw IP address of this InetAddress
* object. The result is in network byte order: the highest order
* byte of the address is in getAddress()[0].
*
* @return the raw IP address of this object.
* @throws java.net.UnknownHostException if IP address of host could not be determined.
*/
byte[] getAddress() throws UnknownHostException;
/**
* Returns the IP address string in textual presentation.
*
* @return the raw IP address in a string format.
* @throws java.net.UnknownHostException if IP address of host could not be determined.
*/
String getHostAddress() throws UnknownHostException;
/**
* Gets the host name for this IP address.
*
*
If this InetAddress was created with a host name, * this host name will be remembered and returned; * otherwise, a reverse name lookup will be performed * and the result will be returned based on the system * configured name lookup service. If a lookup of the name service * is required, call * {@link java.net.InetAddress#getCanonicalHostName() getCanonicalHostName}. * *
If there is a security manager, its
* checkConnect method is first called
* with the hostname and -1
* as its arguments to see if the operation is allowed.
* If the operation is not allowed, it will return
* the textual representation of the IP address.
*
* @return the host name for this IP address, or if the operation
* is not allowed by the security check, the textual
* representation of the IP address.
* @throws java.net.UnknownHostException if IP address of host could not be determined.
*
* @see java.net.InetAddress#getCanonicalHostName
* @see SecurityManager#checkConnect
*/
String getHostName() throws UnknownHostException;
/**
* Returns the local underlying {@link javax.security.cert.X509Certificate}
* chain for the connection.
*
* @return an ordered array of certificates, with the local certificate
* first followed by any certificate authorities. If no certificates
* is present for the connection, then {@code null} is returned.
*/
Certificate[] getLocalCertificates();
/**
* Returns the underlying {@link javax.security.cert.X509Certificate} for
* the connection of the peer.
*
* @return an ordered array of peer certificates, with the peer's own
* certificate first followed by any certificate authorities.
*/
Certificate[] getPeerCertificates();
/**
* Returns channel binding data for this connection, as defined by the provided type.
*
* Channel binding data is used to bind higher-level authentication to the underlying transport layer, improving
* security against man-in-the-middle attacks.
*
* The type, identified by a unique prefix that's typically defined in an RFC, determines which channel binding
* mechanism is used, such as:
*
tls-exporter: TLS exporter-based channel binding.tls-server-end-point: Uses the hash of the server certificate (RFC 5929).socket.send(packet.getWriteBuffer()).
*
* Use with caution! This code is unlikely to be called directly. Instead, ensure
* that data sent to the entities is sent through the appropriate LocalSession object.
* For clients, this prevents, for example, synchronisation issues with stanza counts
* related to Stream Management (XEP-0198).
*
* @param packet the packet to deliver.
* @throws org.jivesoftware.openfire.auth.UnauthorizedException if a permission error was detected.
*/
void deliver( Packet packet ) throws UnauthorizedException;
/**
* Delivers raw text to this connection. This is a very low level way for sending
* XML stanzas to the client. This method should not be used unless you have very
* good reasons for not using {@link #deliver(org.xmpp.packet.Packet)}.
*
* This method avoids having to get the writer of this connection and mess directly
* with the writer. Therefore, this method ensures a correct delivery of the stanza
* even if other threads were sending data concurrently.
*
* @param text the XML stanzas represented kept in a String.
*/
void deliverRawText( String text );
/**
* Returns the major version of XMPP being used by this connection
* (major_version.minor_version. In most cases, the version should be
* "1.0". However, older clients using the "Jabber" protocol do not set a
* version. In that case, the version is "0.0".
*
* @return the major XMPP version being used by this connection.
*/
int getMajorXMPPVersion();
/**
* Returns the minor version of XMPP being used by this connection
* (major_version.minor_version. In most cases, the version should be
* "1.0". However, older clients using the "Jabber" protocol do not set a
* version. In that case, the version is "0.0".
*
* @return the minor XMPP version being used by this connection.
*/
int getMinorXMPPVersion();
/**
* Sets the XMPP version information. In most cases, the version should be "1.0".
* However, older clients using the "Jabber" protocol do not set a version. In that
* case, the version is "0.0".
*
* @param majorVersion the major version.
* @param minorVersion the minor version.
*/
void setXMPPVersion( int majorVersion, int minorVersion );
/**
* Returns true if the connection is using compression.
*
* @return true if the connection is using compression.
*/
boolean isCompressed();
/**
* Returns the TLS protocol name used by the connection of the session, if any.
*
* @return a TLS protocol (version) name.
*/
Optional
*
* In the case of client-2-server the XMPP server must pass true in the {@code clientMode} parameter and the server
* receiving the TLS request must pass false in the {@code clientMode} parameter.false in the
* {@code clientMode} parameter since it will behave as the server in the TLS negotiation.
*
* @param clientMode boolean indicating if this entity is a client or a server in the TLS negotiation.
* @param directTLS boolean indicating if the negotiation is directTLS (true) or startTLS (false).
* @throws Exception if an error occurred while encrypting the connection.
*/
void startTLS(boolean clientMode, boolean directTLS) throws Exception;
/**
* Adds the compression filter to the connection but only filter incoming traffic. Do not filter
* outgoing traffic since we still need to send an uncompressed stanza to the client indicating
* that he can start compressing the traffic. After we sent the uncompresses stanza we can
* start compression outgoing traffic as well.
*/
void addCompression();
/**
* Start compressing outgoing traffic for this connection. Compression will only be available after
* TLS has been negotiated. This means that a connection can never be using compression before
* TLS. However, it is possible to use compression without TLS.
*/
void startCompression();
/**
* Returns a representation of the desired state for this connection. Note that this is different from the current
* state of the connection. For example, TLS can be required by configuration, but while the connection has yet to
* be fully initialized, the current state might not be TLS-encrypted.
*
* @return The desired configuration for the connection (never null).
*/
ConnectionConfiguration getConfiguration();
/**
* When a connection is used to transmit an XML data, the root element of that data can define XML namespaces other
* than the ones that are default (eg: 'jabber:client', 'jabber:server', etc). For an XML parser to be able to parse
* stanzas or other elements that are defined in that namespace (eg: are prefixed), these namespaces are recorded
* here.
*
* @return A collection that contains all non-default namespaces that the peer defined when last opening a new stream.
*/
Set