2020-08-12 23:30:16 +02:00
/ *
2024-02-05 21:57:40 +01:00
* Copyright 2024 dorkbox , llc
2020-08-12 23:30:16 +02:00
*
* 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 dorkbox.network
2023-08-21 02:20:41 +02:00
import dorkbox.hex.toHexString
2023-09-03 21:17:37 +02:00
import dorkbox.network.aeron.*
2023-08-11 04:01:05 +02:00
import dorkbox.network.connection.*
2023-06-14 23:35:03 +02:00
import dorkbox.network.connection.IpInfo.Companion.IpListenType
2023-06-30 00:06:53 +02:00
import dorkbox.network.connection.ListenerManager.Companion.cleanStackTrace
2023-10-28 20:54:09 +02:00
import dorkbox.network.connection.buffer.BufferManager
2020-09-09 01:33:09 +02:00
import dorkbox.network.exceptions.ServerException
2020-08-12 23:30:16 +02:00
import dorkbox.network.handshake.ServerHandshake
2022-05-30 02:45:50 +02:00
import dorkbox.network.handshake.ServerHandshakePollers
2023-03-17 15:06:50 +01:00
import dorkbox.network.ipFilter.IpFilterRule
2021-07-06 15:38:53 +02:00
import dorkbox.network.rmi.RmiSupportServer
2023-09-13 16:57:32 +02:00
import org.slf4j.LoggerFactory
2023-10-28 20:54:09 +02:00
import java.net.InetAddress
2022-03-08 08:41:06 +01:00
import java.util.concurrent.*
2020-08-12 23:30:16 +02:00
/ * *
* The server can only be accessed in an ASYNC manner . This means that the server can only be used in RESPONSE to events . If you access the
* server OUTSIDE of events , you will get inaccurate information from the server ( such as getConnections ( ) )
*
2022-06-11 23:53:39 +02:00
* To put it bluntly , ONLY have the server do work inside a listener !
2021-07-09 15:16:12 +02:00
*
* @param config these are the specific connection options
* @param connectionFunc allows for custom connection implementations defined as a unit function
2022-05-28 12:15:45 +02:00
* @param loggerName allows for a custom logger name for this endpoint ( for when there are multiple endpoints )
2020-08-12 23:30:16 +02:00
* /
2023-09-17 02:36:45 +02:00
open class Server < CONNECTION : Connection > ( config : ServerConfiguration = ServerConfiguration ( ) , loggerName : String = Server :: class . java . simpleName )
: EndPoint < CONNECTION > ( config , loggerName ) {
2022-05-28 12:15:45 +02:00
2020-08-12 23:30:16 +02:00
companion object {
/ * *
* Gets the version number .
* /
2023-09-04 00:47:46 +02:00
const val version = Configuration . version
2020-08-12 23:30:16 +02:00
2023-05-08 09:58:24 +02:00
/ * *
* Ensures that an endpoint ( using the specified configuration ) is NO LONGER running .
*
* NOTE : This method should only be used to check if a server is running for a DIFFERENT configuration than the currently running server
*
* By default , we will wait the [ Configuration . connectionCloseTimeoutInSeconds ] * 2 amount of time before returning .
*
* @return true if the media driver is STOPPED .
* /
2023-09-04 14:23:06 +02:00
fun ensureStopped ( configuration : ServerConfiguration ) : Boolean {
2023-05-08 09:58:24 +02:00
val timeout = TimeUnit . SECONDS . toMillis ( configuration . connectionCloseTimeoutInSeconds . toLong ( ) * 2 )
2023-09-13 16:57:32 +02:00
val logger = LoggerFactory . getLogger ( Server :: class . java . simpleName )
2023-09-04 14:23:06 +02:00
return AeronDriver . ensureStopped ( configuration . copy ( ) , logger , timeout )
2023-05-08 09:58:24 +02:00
}
2020-08-12 23:30:16 +02:00
/ * *
* Checks to see if a server ( using the specified configuration ) is running .
*
2023-05-08 09:58:24 +02:00
* NOTE : This method should only be used to check if a server is running for a DIFFERENT configuration than the currently running server
*
* @return true if the media driver is active and running
2020-08-12 23:30:16 +02:00
* /
2023-09-04 14:23:06 +02:00
fun isRunning ( configuration : ServerConfiguration ) : Boolean {
2023-09-13 16:57:32 +02:00
val logger = LoggerFactory . getLogger ( Server :: class . java . simpleName )
2023-09-04 14:23:06 +02:00
return AeronDriver . isRunning ( configuration . copy ( ) , logger )
2020-08-12 23:30:16 +02:00
}
2021-04-09 20:24:45 +02:00
init {
// Add this project to the updates system, which verifies this class + UUID + version information
dorkbox . updates . Updates . add ( Server :: class . java , " 90a2c3b1e4fa41ea90d31fbdf8b2c6ef " , version )
}
2020-08-12 23:30:16 +02:00
}
2021-07-06 15:38:53 +02:00
/ * *
* Methods supporting Remote Method Invocation and Objects for GLOBAL scope objects ( different than CONNECTION scope objects )
* /
val rmiGlobal = RmiSupportServer ( logger , rmiGlobalSupport )
2023-11-27 11:12:53 +01:00
// /**
// * Maintains a thread-safe collection of rules used to define the connection type with this server.
// */
// private val connectionRules = CopyOnWriteArrayList<ConnectionRule>()
2020-08-12 23:30:16 +02:00
2020-09-10 00:24:41 +02:00
/ * *
2023-06-14 23:35:03 +02:00
* the IP address information , if available .
2020-09-10 00:24:41 +02:00
* /
2023-06-14 23:35:03 +02:00
internal val ipInfo = IpInfo ( config )
2020-08-15 13:21:20 +02:00
2023-06-25 12:21:21 +02:00
@Volatile
internal lateinit var handshake : ServerHandshake < CONNECTION >
2023-10-28 20:54:09 +02:00
/ * *
* Different connections ( to the same client ) can be " buffered " , meaning that if they " go down " because of a network glitch -- the data
* being sent is not lost ( it is buffered ) and then re - sent once the new connection is established . References to the old connection
* will also redirect to the new connection .
* /
internal val bufferedManager : BufferManager < CONNECTION >
2023-07-02 21:59:45 +02:00
private val string0 : String by lazy {
2023-08-21 02:20:41 +02:00
" EndPoint [Server: ${storage.publicKey.toHexString()} ] "
2023-07-02 21:59:45 +02:00
}
2023-09-21 12:53:47 +02:00
init {
2023-10-28 20:54:09 +02:00
bufferedManager = BufferManager ( config , listenerManager , aeronDriver , config . bufferedConnectionTimeoutSeconds )
2023-09-21 12:53:47 +02:00
}
2020-09-25 14:49:17 +02:00
final override fun newException ( message : String , cause : Throwable ? ) : Throwable {
2023-06-30 00:06:53 +02:00
// +2 because we do not want to see the stack for the abstract `newException`
val serverException = ServerException ( message , cause )
serverException . cleanStackTrace ( 2 )
return serverException
2020-08-12 23:30:16 +02:00
}
/ * *
2023-07-11 00:11:58 +02:00
* Binds the server IPC only , using the previously set AERON configuration
* /
fun bindIpc ( ) {
2023-09-07 12:23:47 +02:00
if ( ! config . enableIpc ) {
2023-09-13 16:57:32 +02:00
logger . warn ( " IPC explicitly requested, but not enabled. Enabling IPC... " )
2023-09-07 12:23:47 +02:00
// we explicitly requested IPC, make sure it's enabled
config . contextDefined = false
config . enableIpc = true
config . contextDefined = true
}
2023-07-11 00:11:58 +02:00
2023-09-13 16:57:32 +02:00
if ( config . enableIPv4 ) { logger . warn ( " IPv4 is enabled, but only IPC will be used. " ) }
if ( config . enableIPv6 ) { logger . warn ( " IPv6 is enabled, but only IPC will be used. " ) }
2023-07-11 00:11:58 +02:00
2023-10-26 14:57:48 +02:00
internalBind ( port1 = 0 , port2 = 0 , onlyBindIpc = true , runShutdownCheck = true )
2023-07-11 00:11:58 +02:00
}
/ * *
* Binds the server to UDP ports , using the previously set AERON configuration
2023-06-26 19:28:55 +02:00
*
2023-07-11 00:11:58 +02:00
* @param port1 this is the network port which will be listening for incoming connections
* @param port2 this is the network port that the server will use to work around NAT firewalls . By default , this is port1 + 1 , but
* can also be configured independently . This is required , and must be different from port1 .
2020-08-12 23:30:16 +02:00
* /
2020-08-25 17:45:08 +02:00
@Suppress ( " DuplicatedCode " )
2023-09-04 14:23:06 +02:00
fun bind ( port1 : Int , port2 : Int = port1 + 1 ) {
2023-07-11 00:11:58 +02:00
if ( config . enableIPv4 || config . enableIPv6 ) {
require ( port1 != port2 ) { " port1 cannot be the same as port2 " }
require ( port1 > 0 ) { " port1 must be > 0 " }
require ( port2 > 0 ) { " port2 must be > 0 " }
require ( port1 < 65535 ) { " port1 must be < 65535 " }
require ( port2 < 65535 ) { " port2 must be < 65535 " }
}
2022-07-29 04:52:11 +02:00
2023-10-26 14:57:48 +02:00
internalBind ( port1 = port1 , port2 = port2 , onlyBindIpc = false , runShutdownCheck = true )
2023-09-06 16:22:37 +02:00
}
2023-06-26 19:28:55 +02:00
2023-09-06 16:22:37 +02:00
@Suppress ( " DuplicatedCode " )
2023-10-26 14:57:48 +02:00
private fun internalBind ( port1 : Int , port2 : Int , onlyBindIpc : Boolean , runShutdownCheck : Boolean ) {
2023-06-25 12:13:52 +02:00
// the lifecycle of a server is the ENDPOINT (measured via the network event poller)
if ( endpointIsRunning . value ) {
listenerManager . notifyError ( ServerException ( " Unable to start, the server is already running! " ) )
2023-09-04 14:23:06 +02:00
return
2023-06-25 12:13:52 +02:00
}
2023-10-26 14:57:48 +02:00
if ( runShutdownCheck && ! waitForEndpointShutdown ( ) ) {
2023-06-25 12:13:52 +02:00
listenerManager . notifyError ( ServerException ( " Unable to start the server! " ) )
2023-09-04 14:23:06 +02:00
return
2020-08-12 23:30:16 +02:00
}
2021-07-06 15:38:53 +02:00
try {
2022-08-02 13:10:06 +02:00
startDriver ( )
2023-06-25 12:21:21 +02:00
initializeState ( )
2023-08-10 05:07:16 +02:00
}
catch ( e : Exception ) {
2023-06-25 12:13:52 +02:00
resetOnError ( )
listenerManager . notifyError ( ServerException ( " Unable to start the server! " , e ) )
2023-09-04 14:23:06 +02:00
return
2021-07-06 15:38:53 +02:00
}
2020-08-12 23:30:16 +02:00
2023-07-11 00:11:58 +02:00
this @Server . port1 = port1
this @Server . port2 = port2
2020-08-12 23:30:16 +02:00
2023-06-26 19:28:55 +02:00
config as ServerConfiguration
2022-07-29 04:52:11 +02:00
2020-09-15 12:01:05 +02:00
// we are done with initial configuration, now initialize aeron and the general state of this endpoint
2020-08-12 23:30:16 +02:00
2022-07-15 14:15:40 +02:00
val server = this @Server
2023-10-26 14:57:48 +02:00
handshake = ServerHandshake ( config , listenerManager , aeronDriver , eventDispatch )
2023-06-14 23:35:03 +02:00
2023-09-06 16:22:37 +02:00
val ipcPoller : AeronPoller = if ( config . enableIpc || onlyBindIpc ) {
2023-06-14 23:35:03 +02:00
ServerHandshakePollers . ipc ( server , handshake )
2021-04-30 16:01:25 +02:00
} else {
2023-06-14 23:35:03 +02:00
ServerHandshakePollers . disabled ( " IPC Disabled " )
2021-04-30 16:01:25 +02:00
}
2020-09-15 12:01:05 +02:00
2023-09-06 16:22:37 +02:00
val ipPoller = if ( onlyBindIpc ) {
ServerHandshakePollers . disabled ( " IPv4/6 Disabled " )
} else {
when ( ipInfo . ipType ) {
// IPv6 will bind to IPv4 wildcard as well, so don't bind both!
IpListenType . IPWildcard -> ServerHandshakePollers . ip6Wildcard ( server , handshake )
IpListenType . IPv4Wildcard -> ServerHandshakePollers . ip4 ( server , handshake )
IpListenType . IPv6Wildcard -> ServerHandshakePollers . ip6 ( server , handshake )
IpListenType . IPv4 -> ServerHandshakePollers . ip4 ( server , handshake )
IpListenType . IPv6 -> ServerHandshakePollers . ip6 ( server , handshake )
IpListenType . IPC -> ServerHandshakePollers . disabled ( " IPv4/6 Disabled " )
}
2023-06-14 23:35:03 +02:00
}
2023-09-06 16:22:37 +02:00
2023-09-13 16:57:32 +02:00
logger . info ( ipcPoller . info )
logger . info ( ipPoller . info )
2022-05-30 02:45:50 +02:00
2023-09-08 13:21:12 +02:00
// if we shutdown/close before the poller starts, we don't want to block forever
pollerClosedLatch = CountDownLatch ( 1 )
2023-05-24 09:21:39 +02:00
networkEventPoller . submit (
2023-09-03 21:17:37 +02:00
action = object : EventActionOperator {
override fun invoke ( ) : Int {
return if ( ! shutdownEventPoller ) {
// NOTE: regarding fragment limit size. Repeated calls to '.poll' will reassemble a fragment.
// `.poll(handler, 4)` == `.poll(handler, 2)` + `.poll(handler, 2)`
// this checks to see if there are NEW clients to handshake with
var pollCount = ipcPoller . poll ( ) + ipPoller . poll ( )
// this manages existing clients (for cleanup + connection polling). This has a concurrent iterator,
// so we can modify this as we go
connections . forEach { connection ->
2023-10-26 21:19:36 +02:00
if ( connection . canPoll ( ) ) {
2023-09-03 21:17:37 +02:00
// Otherwise, poll the connection for messages
pollCount += connection . poll ( )
} else {
// If the connection has either been closed, or has expired, it needs to be cleaned-up/deleted.
2023-09-13 16:01:14 +02:00
if ( logger . isDebugEnabled ) {
2023-09-13 16:57:32 +02:00
logger . debug ( " [ ${connection} ] connection expired (cleanup) " )
2023-09-13 16:01:14 +02:00
}
2023-09-03 21:17:37 +02:00
// the connection MUST be removed in the same thread that is processing events (it will be removed again in close, and that is expected)
removeConnection ( connection )
2023-09-04 14:23:06 +02:00
// we already removed the connection, we can call it again without side effects
connection . close ( )
2023-09-03 21:17:37 +02:00
}
2020-09-11 11:06:53 +02:00
}
2020-09-09 01:33:09 +02:00
2023-09-03 21:17:37 +02:00
pollCount
} else {
// remove ourselves from processing
EventPoller . REMOVE
}
2023-03-01 22:39:03 +01:00
}
} ,
2023-09-03 21:17:37 +02:00
onClose = object : EventCloseOperator {
2023-09-04 14:23:06 +02:00
override fun invoke ( ) {
2023-09-03 21:17:37 +02:00
val mustRestartDriverOnError = aeronDriver . internal . mustRestartDriverOnError
2023-09-13 16:57:32 +02:00
logger . debug ( " Server event dispatch closing... " )
2023-09-03 21:17:37 +02:00
ipcPoller . close ( )
ipPoller . close ( )
// clear all the handshake info
handshake . clear ( )
// we only need to run shutdown methods if there was a network outage or D/C
if ( ! shutdownInProgress . value ) {
// this is because we restart automatically on driver errors
2023-10-26 14:57:48 +02:00
this @Server . close ( closeEverything = false , sendDisconnectMessage = true , releaseWaitingThreads = ! mustRestartDriverOnError )
2023-09-03 21:17:37 +02:00
}
2023-08-11 04:01:05 +02:00
2023-09-03 21:17:37 +02:00
if ( mustRestartDriverOnError ) {
2023-09-13 16:57:32 +02:00
logger . error ( " Critical driver error detected, restarting server. " )
2023-08-11 04:01:05 +02:00
2023-10-26 08:05:08 +02:00
eventDispatch . CLOSE . launch {
2023-09-03 21:17:37 +02:00
waitForEndpointShutdown ( )
2023-08-11 04:01:05 +02:00
2023-09-03 21:17:37 +02:00
// also wait for everyone else to shutdown!!
aeronDriver . internal . endPointUsages . forEach {
2023-10-26 08:05:08 +02:00
if ( it !== this @Server ) {
it . waitForEndpointShutdown ( )
}
2023-09-03 21:17:37 +02:00
}
2023-08-11 04:01:05 +02:00
2023-09-03 21:17:37 +02:00
// if we restart/reconnect too fast, errors from the previous run will still be present!
aeronDriver . delayLingerTimeout ( )
2023-08-11 04:01:05 +02:00
2023-09-03 21:17:37 +02:00
val p1 = this @Server . port1
val p2 = this @Server . port2
2023-08-11 04:01:05 +02:00
2023-09-03 21:17:37 +02:00
if ( p1 == 0 && p2 == 0 ) {
2023-10-26 14:57:48 +02:00
internalBind ( port1 = 0 , port2 = 0 , onlyBindIpc = true , runShutdownCheck = false )
2023-09-03 21:17:37 +02:00
} else {
2023-10-26 14:57:48 +02:00
internalBind ( port1 = p1 , port2 = p2 , onlyBindIpc = false , runShutdownCheck = false )
2023-09-03 21:17:37 +02:00
}
2023-08-11 04:01:05 +02:00
}
}
2023-09-03 21:17:37 +02:00
// we can now call bind again
endpointIsRunning . lazySet ( false )
2023-10-26 14:57:48 +02:00
logger . debug ( " Closed the Network Event Poller task. " )
2023-09-03 21:17:37 +02:00
pollerClosedLatch . countDown ( )
}
2023-03-01 22:39:03 +01:00
} )
2020-08-12 23:30:16 +02:00
}
2023-06-25 12:21:21 +02:00
2023-11-27 11:12:53 +01:00
// /**
// * Adds an IP+subnet rule that defines what type of connection this IP+subnet should have.
// * - NOTHING : Nothing happens to the in/out bytes
// * - COMPRESS: The in/out bytes are compressed with LZ4-fast
// * - COMPRESS_AND_ENCRYPT: The in/out bytes are compressed (LZ4-fast) THEN encrypted (AES-256-GCM)
// *
// * If no rules are defined, then for LOOPBACK, it will always be `COMPRESS` and for everything else it will always be `COMPRESS_AND_ENCRYPT`.
// *
// * If rules are defined, then everything by default is `COMPRESS_AND_ENCRYPT`.
// *
// * The compression algorithm is LZ4-fast, so there is a small performance impact for a very large gain
// * Compress : 6.210 micros/op; 629.0 MB/s (output: 55.4%)
// * Uncompress : 0.641 micros/op; 6097.9 MB/s
// */
// fun addConnectionRules(vararg rules: ConnectionRule) {
// connectionRules.addAll(listOf(*rules))
// }
2020-08-12 23:30:16 +02:00
2023-03-17 15:06:50 +01:00
/ * *
* Adds an IP + subnet rule that defines if that IP + subnet is allowed / denied connectivity to this server .
*
* By default , if there are no filter rules , then all connections are allowed to connect
* If there are filter rules - then ONLY connections for the filter that returns true are allowed to connect ( all else are denied )
*
* If ANY filter rule that is applied returns true , then the connection is permitted
*
* This function will be called for * * only * * network clients ( IPC client are excluded )
2023-11-27 11:13:54 +01:00
*
* @param ipFilterRule the IpFilterRule to determine if this connection will be allowed to connect
2023-03-17 15:06:50 +01:00
* /
2023-05-28 17:03:54 +02:00
fun filter ( ipFilterRule : IpFilterRule ) {
2023-09-04 14:23:06 +02:00
listenerManager . filter ( ipFilterRule )
2023-03-17 15:06:50 +01:00
}
/ * *
* Adds a function that will be called BEFORE a client / server " connects " with each other , and used to determine if a connection
* should be allowed
*
* By default , if there are no filter rules , then all connections are allowed to connect
* If there are filter rules - then ONLY connections for the filter that returns true are allowed to connect ( all else are denied )
*
* It is the responsibility of the custom filter to write the error , if there is one
*
* If the function returns TRUE , then the connection will continue to connect .
* If the function returns FALSE , then the other end of the connection will
* receive a connection error
*
*
* If ANY filter rule that is applied returns true , then the connection is permitted
*
* This function will be called for * * only * * network clients ( IPC client are excluded )
2023-11-27 11:13:54 +01:00
*
* @param function clientAddress : UDP connection address
* tagName : the connection tag name
2023-03-17 15:06:50 +01:00
* /
2023-11-27 11:14:52 +01:00
fun filter ( function : ( clientAddress : InetAddress , tagName : String ) -> Boolean ) {
2023-09-04 14:23:06 +02:00
listenerManager . filter ( function )
2023-03-17 15:06:50 +01:00
}
2023-11-27 11:14:52 +01:00
/ * *
* Adds a function that will be called BEFORE a client / server " connects " with each other , and used to determine if buffered messages
* for a connection should be enabled
*
* By default , if there are no rules , then all connections will have buffered messages enabled
* If there are rules - then ONLY connections for the rule that returns true will have buffered messages enabled ( all else are disabled )
*
* It is the responsibility of the custom filter to write the error , if there is one
*
* If the function returns TRUE , then the buffered messages for a connection are enabled .
* If the function returns FALSE , then the buffered messages for a connection is disabled .
*
* If ANY rule that is applied returns true , then the buffered messages for a connection are enabled
*
* @param function clientAddress : not - null when UDP connection , null when IPC connection
* tagName : the connection tag name
* /
2023-11-27 14:40:09 +01:00
fun enableBufferedMessages ( function : ( clientAddress : InetAddress ? , tagName : String ) -> Boolean ) {
2023-11-27 11:14:52 +01:00
listenerManager . enableBufferedMessages ( function )
}
2020-09-22 19:39:24 +02:00
/ * *
2020-09-22 21:06:31 +02:00
* Runs an action for each connection
2020-09-22 19:39:24 +02:00
* /
fun forEachConnection ( function : ( connection : CONNECTION ) -> Unit ) {
connections . forEach {
function ( it )
}
}
2023-06-25 12:21:21 +02:00
/ * *
* Will throw an exception if there are resources that are still in use
* /
fun checkForMemoryLeaks ( ) {
AeronDriver . checkForMemoryLeaks ( )
2023-06-14 23:35:03 +02:00
2023-06-25 12:21:21 +02:00
// make sure that we have de-allocated all connection data
handshake . checkForMemoryLeaks ( )
2023-06-14 23:35:03 +02:00
}
2020-08-27 13:57:30 +02:00
/ * *
2023-06-25 17:23:44 +02:00
* By default , if you call close ( ) on the server , it will shut down all parts of the endpoint ( listeners , driver , event polling , etc ) .
*
* @param closeEverything if true , all parts of the server will be closed ( listeners , driver , event polling , etc )
2020-08-27 13:57:30 +02:00
* /
2023-06-25 17:23:44 +02:00
fun close ( closeEverything : Boolean = true ) {
2023-10-28 20:54:09 +02:00
bufferedManager . close ( )
2023-10-26 14:57:48 +02:00
close ( closeEverything = closeEverything , sendDisconnectMessage = true , releaseWaitingThreads = true )
2020-08-12 23:30:16 +02:00
}
2023-06-25 12:21:21 +02:00
override fun toString ( ) : String {
2023-07-02 21:59:45 +02:00
return string0
2023-06-25 12:21:21 +02:00
}
2023-05-08 09:58:24 +02:00
fun < R > use ( block : ( Server < CONNECTION > ) -> R ) : R {
return try {
block ( this )
} finally {
close ( )
}
}
2020-08-12 23:30:16 +02:00
2020-09-03 01:31:08 +02:00
// /**
// * Only called by the server!
// *
// * If we are loopback or the client is a specific IP/CIDR address, then we do things differently. The LOOPBACK address will never encrypt or compress the traffic.
// */
// // after the handshake, what sort of connection do we want (NONE, COMPRESS, ENCRYPT+COMPRESS)
// fun getConnectionUpgradeType(remoteAddress: InetSocketAddress): Byte {
// val address = remoteAddress.address
// val size = connectionRules.size
//
// // if it's unknown, then by default we encrypt the traffic
// var connectionType = ConnectionProperties.COMPRESS_AND_ENCRYPT
// if (size == 0 && address == IPv4.LOCALHOST) {
// // if nothing is specified, then by default localhost is compression and everything else is encrypted
// connectionType = ConnectionProperties.COMPRESS
// }
// for (i in 0 until size) {
// val rule = connectionRules[i] ?: continue
// if (rule.matches(remoteAddress)) {
// connectionType = rule.ruleType()
// break
// }
// }
// logger.debug("Validating {} Permitted type is: {}", remoteAddress, connectionType)
// return connectionType.type
// }
2020-08-12 23:30:16 +02:00
}