This is an automated email from the ASF dual-hosted git repository. elecharny pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mina-site.git
commit 65ba3cb8366c307e29d49e8ea3597fb1ca6a0df5 Author: emmanuel lecharny <elecha...@apache.org> AuthorDate: Sun Apr 28 06:15:39 2024 +0200 Many text proofing, some TLS addition --- .../ch1-getting-started/ch1.1-nio-overview.md | 6 +- .../ch1-getting-started/ch1.2-why-mina.md | 8 +-- .../ch1-getting-started/ch1.3-features.md | 2 +- .../ch1-getting-started/ch1.4-first-steps.md | 10 +-- .../ch2-basics/ch2.1-application-architecture.md | 14 ++--- .../ch2-basics/ch2.1.1-server-architecture.md | 2 +- .../ch2-basics/ch2.2-sample-tcp-server.md | 4 +- .../userguide/ch4-session/ch4-session.md | 15 ++++- .../userguide/ch5-filters/ch5.19-ssl-filter.md | 73 +++++++++++++++++----- 9 files changed, 96 insertions(+), 38 deletions(-) diff --git a/source/mina-project/userguide/ch1-getting-started/ch1.1-nio-overview.md b/source/mina-project/userguide/ch1-getting-started/ch1.1-nio-overview.md index 88b725795..a9d7dc331 100644 --- a/source/mina-project/userguide/ch1-getting-started/ch1.1-nio-overview.md +++ b/source/mina-project/userguide/ch1-getting-started/ch1.1-nio-overview.md @@ -35,10 +35,10 @@ This user guide will thus focus on everything built on top of those internal com # NIO vs BIO -It's important to understand the difference between those two APIs. **BIO**, or **Blocking** **IO**, relies on plain sockets used in a blocking mode : when you read, write or do whatever operation on a socket, the called operation will block the caller until the operation is completed. +It's important to understand the difference between those two APIs. **BIO**, or **Blocking** **IO**, relies on plain sockets used in a blocking mode: when you read, write or do whatever operation on a socket, the called operation will block the caller until the operation is completed. -In some cases, it's critical to be able to call the operation, and to expect the called operation to inform the caller when the operation is done : the caller can then do something else in the mean time. +In some cases, it's critical to be able to call the operation, and to expect the called operation to inform the caller when the operation is done: the caller can then do something else in the mean time. -This is also where **NIO** offers a better way to handle **IO** when you have numerous connected sockets : you dn't have to create a specific thread for each connection, you can just use a few threads to do the same job. +This is also where **NIO** offers a better way to handle **IO** when you have numerous connected sockets: you don't have to create a specific thread for each connection, you can just use a few threads to do the same job. If you want to get more information about what covers **NIO**, there is a lot of good articles around the web, and a few books covering this matter. diff --git a/source/mina-project/userguide/ch1-getting-started/ch1.2-why-mina.md b/source/mina-project/userguide/ch1-getting-started/ch1.2-why-mina.md index b785fd321..683aa5d7b 100644 --- a/source/mina-project/userguide/ch1-getting-started/ch1.2-why-mina.md +++ b/source/mina-project/userguide/ch1-getting-started/ch1.2-why-mina.md @@ -9,13 +9,13 @@ navNext: ch1.3-features.html navNextText: 1.3 - Features --- -# Why MINA ? +# Why MINA? Writing network applications are generally seen as a burden and perceived as low level development. It is an area which is not frequently studied or known by developers, either because it has been studied in school a long time ago and everything has been forgotten, or because the complexity of the network layer is frequently hidden by higher level layers, so you never get deep into it. Added to that (when it comes to asynchronous IO) an extra layer of complexity comes into play: time. -The big difference between **BIO** (Blocking IO) and **NIO** (Non-Blocking IO) is that in **BIO**, you send a request, and you wait until you get the response. On the server side, it means one thread wil be associated with any incoming connection, so you won't have to deal with the complexity of multiplexing the connections. In **NIO**, on the other hand, you have to deal with the synchronous nature of a non-blocking system, which means that your application will be invoked when some ev [...] +The big difference between **BIO** (Blocking IO) and **NIO** (Non-Blocking IO) is that in **BIO**, you send a request, and you wait until you get the response. On the server side, it means one thread will be associated with any incoming connection, so you won't have to deal with the complexity of multiplexing the connections. In **NIO**, on the other hand, you have to deal with the synchronous nature of a non-blocking system, which means that your application will be invoked when some e [...] ## The need of a framework @@ -27,9 +27,9 @@ But **MINA** does more. It provides a common IO vision to an application that ne Last but not least, **MINA** is a network framework that has been specifically designed to work on both the client side and server side. Writing a server makes it critical to have a scalable system, which is tunable to fit the server needs, in terms of performance and memory usage. This is what **MINA** is good for, making it easy to develop you server. -## When to use MINA ? +## When to use MINA? -This is a interesting question! **MINA** does not expect to be the best possible choice in all cases. There are a few elements to take into account when considering using **MINA**. Let's list them: +This is an interesting question! **MINA** does not expect to be the best possible choice in all cases. There are a few elements to take into account when considering using **MINA**. Let's list them: * Ease of use When you have no special performance requirements, **MINA** is probably a good choice as it allows you to develop a server or a client easily, without having to deal with the various parameters and use cases to handle when writing the same application on top of **BIO** or **NIO**. You could probably write your server with only a few lines of code, and there are less pitfalls in which you are likely to fall. diff --git a/source/mina-project/userguide/ch1-getting-started/ch1.3-features.md b/source/mina-project/userguide/ch1-getting-started/ch1.3-features.md index 56a17de0e..43bace108 100644 --- a/source/mina-project/userguide/ch1-getting-started/ch1.3-features.md +++ b/source/mina-project/userguide/ch1-getting-started/ch1.3-features.md @@ -29,7 +29,7 @@ MINA is a simple yet full-featured network application framework which provides: * Out-of-the-box SSL {{< html "·" >}} TLS {{< html "·" >}} StartTLS support using Java 5 SSLEngine * Overload shielding & traffic throttling * Unit testability using mock objects -* JMX managability +* JMX manageability * Stream-based I/O support via StreamIoHandler * Integration with well known containers such as PicoContainer and Spring * Smooth migration from Netty, an ancestor of Apache MINA. diff --git a/source/mina-project/userguide/ch1-getting-started/ch1.4-first-steps.md b/source/mina-project/userguide/ch1-getting-started/ch1.4-first-steps.md index 969f93baf..1e3de4fb2 100644 --- a/source/mina-project/userguide/ch1-getting-started/ch1.4-first-steps.md +++ b/source/mina-project/userguide/ch1-getting-started/ch1.4-first-steps.md @@ -19,17 +19,17 @@ The first thing you have to do is to setup your environment when you want to use First, you have to download the latest **MINA** release from [MINA 2.0 Downloads Section](../../downloads_2_0.html) or [MINA 2.1 Downloads Section](../../downloads_2_1.html). Just take the latest version, unless you have very good reasons not to do so... -Generally speaking, if you are going to use **Maven** to build your project, you won't even have to download anything, as soon as you will depend on a repository which already contains the **MINA** libraries : you just tell your **Maven** poms that you want to use the **MINA** jars you need. +Generally speaking, if you are going to use **Maven** to build your project, you won't even have to download anything, as soon as you will depend on a repository which already contains the **MINA** libraries: you just tell your **Maven** poms that you want to use the **MINA** jars you need. ## What's inside After the download is complete, extract the content of _tar.gz_ or _zip_ file to local hard drive. The downloaded compressed file has following contents -On UNIX system, type : +On UNIX system, type: $ tar xzpf apache-mina-2.0.7-tar.gz -In the _apache-mina-2.0.7_ directory, you will get : +In the _apache-mina-2.0.7_ directory, you will get: | +- dist @@ -55,7 +55,7 @@ Additional to these, the base directory has couple of license and notice files Well, we have downloaded the release, let's run our first **MINA** example, shipped with the release. -Put the following jars in the classpath +Put the following jars in the class path * mina-core-2.0.7.jar * mina-example-2.0.7.jar @@ -78,7 +78,7 @@ If you don't need a logging framework you can use <em>slf4j-nop.jar</em> for no very basic logging. </div> -On the command prompt, issue the following command : +On the command prompt, issue the following command: $ java org.apache.mina.example.gettingstarted.timeserver.MinaTimeServer diff --git a/source/mina-project/userguide/ch2-basics/ch2.1-application-architecture.md b/source/mina-project/userguide/ch2-basics/ch2.1-application-architecture.md index 8ffc41e78..d327341d0 100644 --- a/source/mina-project/userguide/ch2-basics/ch2.1-application-architecture.md +++ b/source/mina-project/userguide/ch2-basics/ch2.1-application-architecture.md @@ -14,17 +14,17 @@ navNextText: 2.2 - Sample TCP Server # 2.1 - MINA based Application Architecture -It's the question most asked : 'How does a **MINA** based application look like'? In this article lets see what's the architecture of MINA based application. Have tried to gather the information from presentations based on **MINA**. +It's the question most asked: 'How does a **MINA** based application look like'? In this article lets see what's the architecture of MINA based application. Have tried to gather the information from presentations based on **MINA**. -A Bird's Eye View : +A Bird's Eye View:  Here, we can see that **MINA** is the glue between your application (be it a client or a server) and the underlying network layer, which can be based on TCP, UDP, in-VM communication or even a RS-232C serial protocol for a client. -You just have to design your application on top of MINA without having to handle all the complexity of the newtork layer. +You just have to design your application on top of MINA without having to handle all the complexity of the network layer. -Lets take a deeper dive into the details now. The following image shows a bit more the internal of **MINA**, and what are each of the **MINA** components doing : +Lets take a deeper dive into the details now. The following image shows a bit more the internal of **MINA**, and what are each of the **MINA** components doing:  @@ -36,15 +36,15 @@ Broadly, MINA based applications are divided into 3 layers * I/O Filter Chain - Filters/Transforms bytes into desired Data Structures and vice-versa * I/O Handler - Here resides the actual business logic -So, in order to create a MINA based Application, you have to : +So, in order to create a MINA based Application, you have to: -1. Create an I/O service - Choose from already available Services (*Acceptor) or create your own +1. Create an I/O service - Choose from already available Services (*Acceptor*) or create your own 2. Create a Filter Chain - Choose from already existing Filters or create a custom Filter for transforming request/response 3. Create an I/O Handler - Write business logic, on handling different messages This is pretty much it. -You can get a bit deeper by reading those two pages : +You can get a bit deeper by reading those two pages: * [2.1.1 - Server Architecture](ch2.1.1-server-architecture.html) * [2.1.2 - Client Architecture](ch2.1.2-client-architecture.html) diff --git a/source/mina-project/userguide/ch2-basics/ch2.1.1-server-architecture.md b/source/mina-project/userguide/ch2-basics/ch2.1.1-server-architecture.md index 260562c68..b65ab8625 100644 --- a/source/mina-project/userguide/ch2-basics/ch2.1.1-server-architecture.md +++ b/source/mina-project/userguide/ch2-basics/ch2.1.1-server-architecture.md @@ -22,7 +22,7 @@ We have exposed the **MINA** Application Architecture in the previous section. L ## Session creation -Whenever a client connects on a MINA server, we will create a new session to store persistent data into it. Even if the protocol is not connected, this session will be created. The following schema shows how **MINA** handles incoming connections : +Whenever a client connects on a MINA server, we will create a new session to store persistent data into it. Even if the protocol is not connected, this session will be created. The following schema shows how **MINA** handles incoming connections:  diff --git a/source/mina-project/userguide/ch2-basics/ch2.2-sample-tcp-server.md b/source/mina-project/userguide/ch2-basics/ch2.2-sample-tcp-server.md index 72b31624c..f0830a676 100644 --- a/source/mina-project/userguide/ch2-basics/ch2.2-sample-tcp-server.md +++ b/source/mina-project/userguide/ch2-basics/ch2.2-sample-tcp-server.md @@ -19,7 +19,7 @@ This tutorial will walk you through the process of building a MINA based program * __Log4J 1.2__ users: slf4j-api.jar, slf4j-log4j12.jar, and [Log4J](http://logging.apache.org/log4j/1.2/) 1.2.x * __Log4J 1.3__ users: slf4j-api.jar, slf4j-log4j13.jar, and [Log4J](http://logging.apache.org/log4j/1.2/) 1.3.x * __java.util.logging__ users: slf4j-api.jar and slf4j-jdk14.jar - * __IMPORTANT__: Please make sure you are using the right slf4j-*.jar that matches to your logging framework. + * __IMPORTANT__: Please make sure you are using the right slf4j-\*.jar that matches to your logging framework. For instance, slf4j-log4j12.jar and log4j-1.3.x.jar can not be used together, and will malfunction. @@ -51,7 +51,7 @@ public class MinaTimeServer } ``` -With the NioSocketAcceptor class in place, we can go ahead and define the handler class and bind the NioSocketAcceptor to a port : +With the NioSocketAcceptor class in place, we can go ahead and define the handler class and bind the NioSocketAcceptor to a port: ```java import java.net.InetSocketAddress; diff --git a/source/mina-project/userguide/ch4-session/ch4-session.md b/source/mina-project/userguide/ch4-session/ch4-session.md index 4f5c70669..7e6e4a399 100644 --- a/source/mina-project/userguide/ch4-session/ch4-session.md +++ b/source/mina-project/userguide/ch4-session/ch4-session.md @@ -32,12 +32,16 @@ In other words, don't call session.read(). Never. A session has a state, which will evolve during time. +* Created : the session has just been created * Connected : the session has been created and is available * Idle : the session hasn't processed any request for at least a period of time (this period is configurable) * Idle for read : no read has actually been made for a period of time * Idle for write : no write has actually been made for a period of time * Idle for both : no read nor write for a period of time +* Secured : the TLS layer has been initialised +* Unsecured : The TLS layer has been shut down * Closing : the session is being closed (the remaining messages are being flushed, cleaning up is not terminated) +* Input closed : the input part of the socket has been closed * Closed : The session is now closed, nothing else can be done to revive it. This is actually not a real state : when teh session is closed, it's removed. The following state diagram exposes all the possible states and transitions : @@ -49,8 +53,17 @@ We have a set of methods to get some information about the session status. Session status : * isActive() : tells if the session is valid (it might mean different things depending on the implementation) +* isBothIdle() : tells if the session is idling on reads and writes * isClosing() : tells if the session is already being closed * isConnected() : tells if the session is active (ie, not in the closing mode) +* isIdle( idling status ) : tells if the session is idling on a specific state (read or write) +* isReadIdle() : tells if the session is idling on reads +* isReadSuspended() : tells if the session is not allowed to read messsages +* isScheduledForFlush() : tells if the session has pending messages that are to be written +* isSecured() : tells if teh TLS layer is active and initialized +* isServer() : tells if the session is on the server side +* isWriteIdle() : tells if the session is idling on writes +* isWriteSuspended() : tells if the session is not allowed to write messsages ## Opening a session @@ -81,7 +94,7 @@ session = connector.connect(address).getSession(); ## Initialization -When a new session is created, it has to be initialized. This is done using the default IoService configuration, bt you can update this configuration later on. Actually, when the session is created, we internally create a copy of the default IoService configuration that is stored within the session, and this is this configuration instance that will be used (and that can be modified). +When a new session is created, it has to be initialized. This is done using the default IoService configuration, but you can update this configuration later on. Actually, when the session is created, we internally create a copy of the default IoService configuration that is stored within the session, and this is this configuration instance that will be used (and that can be modified). This initialization will also starts the statistics counters, create the Attributes container, associate a write queue to to the session (this is where the messages will be enqueued until they have been sent), and ultimately, would you have provided a specific task to do during this phase, it will call it. diff --git a/source/mina-project/userguide/ch5-filters/ch5.19-ssl-filter.md b/source/mina-project/userguide/ch5-filters/ch5.19-ssl-filter.md index 931007c9f..b3b33fd74 100644 --- a/source/mina-project/userguide/ch5-filters/ch5.19-ssl-filter.md +++ b/source/mina-project/userguide/ch5-filters/ch5.19-ssl-filter.md @@ -19,7 +19,7 @@ In **MINA**, we do that with the **SslFilter**. The idea is to add this _Filter_ The thing to remember is that the **TLS** protocol works in two steps: * First there is a negociation part (the _Handshake_) -* Then once the _Handshake_ is completed, all the data will be encrypted before being sent. +* Then once the _Handshake_ is completed, all the data will be encrypted before being sent, and decryptd when received. We just have to add the filter in the chain like this: @@ -32,30 +32,75 @@ We just have to add the filter in the chain like this: ``` -The _chain_ is the instance of **IoFilterChainBuilder** class that is associated with either the _Connector_ or the _Acceptor_ instances (wether we are using a client or a server). +The _chain_ is the instance of **IoFilterChainBuilder** class that is associated with either the _Connector_ or the _Acceptor_ instances (wether we are using a client or a server). It will be used when a connection is set to define the filter chain this connected session will use. <div class="note" markdown="1"> -Usually the **SSLFilyter** is always set at the first position in the chain. The rationnal is that it will receive and send encrypted data, so there is little use of having a functionnal filter between the head of the chain and the **SslFilter**. However, if such a filter is to be used, make sure it does not interfere with the data being exchanged with the remote peer. +Usually the **SSLFilter** is always set at the first position in the chain. The rationnal is that it will receive and send encrypted data, so there is little use of having a functionnal filter between the head of the chain and the **SslFilter**. However, if such a filter is to be used, make sure it does not interfere with the data being exchanged with the remote peer. </div> -The missing part here is the _sslContext_ which has to be defined. It's an instande of the **SSLContext** class, where you define a **TrustManager**, a **KeyManager** and a **Securerandom**. +The missing part here is the _sslContext_ which has to be defined. It's an instance of the **SSLContext** class, where you define a **TrustManager**, a **KeyManager** and a **Securerandom**. <div class="note" markdown="1"> This part is strandard Java security. You'll find plenty of pages on internet explaining you to set up a proper _SSLContext_ instance. </div> +The filter can be added either _before_ the connection has been established, or _after_ the connection has been established. +In the first case, it's easy, the filter initialisation will be done when the connection is created. The second is a bit more complex, as we will have to deal with ongoing messages. + +### Initialization + +When a connection is created, the filter chain is created, and the **SslFilter** is added to this chain, which intializes it. The filter's _onPreAdd_ method is called, which will only check if the filter has already been added (we can't have the **SslFilter** twice in the chain). + +The filter's _onPostAdd_ method is then called, and if the _autostart_ flag is set to _true_ and the session is connected (which should be the case...), then the _onConnected_ method is called. + +<div class="note" markdown="1"> + The _autostart_ flag can be set when creating the **SslFilter**. It indicates that the filter will be initialized immediatly on a new connection. Otherwise the filter will be initialized later on when the session will have been opened. +</div> + +The **SslHandler** will then be created, which will contain a newly created **SslEngine**. This is the place where the **TLS** parameters will be set: +* The authentication **WANT** or **NEED** flags +* The cipher suite +* The enabled protocols +* The endpoint identification algorithms +* and finally the flag indicating if it's for a server or a client + +All those flags are optionnal but the last one. + +The newly created **SslHandler** instance will be added into the session's attributes, under the _org.apache.mina.filter.ssl.SslHandler.handler@<ID>_ key (The **ID** part is unique). + +Last, not least, the **SslHandler** instance is opened. If we are on the client side, the **TLS** _Handshake_ will be started, otherwise a flag will be set to indicate we are expecting a _Handshake_ on the server side. + +We are all set and ready for the _Handshake_ to be processed! + ### Handshake -The **Handshake** is automatically initiated by the server when the connection is created. The **SslFilter** has a _onPostAdd_ method which create a **SSLEngine** instance based on the provided **SSLContext**. +The _Handshake_ must be done as soon as the **TLS** layer is activated. It's initiated by the client, which must send a _CLIENT_HELLO_ message (see the [Client Hello](https://tls13.xargs.org/#client-hello) description), but the server must be ready to accept this message. + +We will consider two use cases: the **Client** side and the **Server** side (as **Mina** can handle both sides, but could work with a peer written using a different implementation) + +#### Initial Handshake message + +The first _Handshake_ message to be processed is the **CLIENT HELLO** **TLS** message. + +##### Server side + +The _Handshake_ is initiated by a **CLIENT_HELLO** **TLS** request which is sent by the client, the server is waiting for it. There starts a serie of **TLS** messages exchanged between the cleint and the server, at the end of which the session is secured, and data can be exchanged encrypted. + +What is important to note here is that during the _Handshake_ exchanges, no application data can be sent, and the **SslFilter** is handling the whole process, before returning the hand to the application. That means messages emitted by the application will be stacked until the session is secured. + +##### Client side + +The client is the initiator of the _Handshake_ exchange. The difference with the server is that the client **SSLhandler** will generate the inital _Handshake_ message (**CLIENT HELLO**) and send it to the server + +#### Follow up Handshake messages -It sets the **SSLEngine** characteristics: -* Whether the client authentication is requested or required (_needClientAuth_ and _wantClientAuth_ flags) -* Sets the enabled cipher suites -* Sets the enabled protocols +Once the _Handshake_ has been initiated, the dance keeps going until the _Handshake_ is either done or fails: +* The client sends _Handshake_ requests +* The server sends _Handshake_ responses -Last, not least, the **CLIENT_HELLO** **TLS** request is sent by the client side, the server is waiting for it. There starts a serie of **TLS** messages exchanged between the cleint and the server, at teh end of which the session is secured, and data can be exchanged encrypted. +This dance can use many steps. -What is important to note here is that during the **Handshake** exchanges, no application data can be sent, and the **SslFilter** is handling the whole process, before returning the hand to the application. +It ends with both side send a _finished_ message, and has verified that it's valid. ### Session secured @@ -78,15 +123,15 @@ That is what the **startTLS** command is used for that purpose. Here are a list * [**NNTP**](https://datatracker.ietf.org/doc/html/rfc4642) * [**LDAP**](https://datatracker.ietf.org/doc/html/rfc4513) -The way it works is that at some point of a clear text established connection, the client sends a **STARTLS** command, which forces the **TLS** handshake to start to establish a secured connection. When the secured connection is established, the client and the server exchanges will be encrypted. +The way it works is that at some point of a clear text established connection, the client sends a **STARTLS** command, which forces the **TLS** _Handshake_ to start to establish a secured connection. When the secured connection is established, the client and the server exchanges will be encrypted. Now, that is a bit tricky to implement, because both the client *and* the server must block the exchange of messages during the establishement of the **TLS** session. As the client is the initiator of the command, it's easy, but on the server side, we must pass a response to the original command **in clear text** informing the client that the command has been received and processed. ``` (C) The client sends a **StartTLS** command (S) The server receives the command, initialize the **TLS** layer, and send back a response to the client, bypassing the **TLS** layer. -(C) The client received the server response to the command, and setup the **TLS** layer, and initiates the **TLS** handshake -(S/C) The Handshake is processed +(C) The client received the server response to the command, and setup the **TLS** layer, and initiates the **TLS** _Handshake_ +(S/C) The _Handshake_ is processed (S/C) The session is secured on both side (S/C) at this point, every message exchanged are encrypted. ```