OpenVPN Optimization-Establishment of TLS handshake Control CHannel
An optimization of the OpenVPN data tunnel is in progress. After referring to the concept and idea of the "giant frame", I carefully considered the design and implementation of the TCP/IP protocol stack, so I come up with a possible error, but at least it is very practical in my scenario: although the upper-layer protocol sends data, it doesn't matter the data size. If it really needs to be split, it should be done by the lower layer.
A counterexample of this conclusion is the data segment of the TCP protocol, which perceives the MTU of the transmission link, maybe in the early network, IP segment reorganization does affect the end-to-end traffic control and congestion control of TCP, and may also cause difficulties for the status firewall. But now, it is no longer the case. If MTU is perceived at the application layer, the increased processing complexity completely offsets the benefits of avoiding IP fragmentation.
OpenVPN protocol analysis
I analyzed the OpenVPN protocol word by word three years ago. At that time, almost no one analyzed the OpenVPN protocol, and my analysis was only due to interest. It was useless. Looking at the messy code generation of OpenVPN, it was so painful to use the packet capture analysis protocol. At that time, I had the urge to write the Wireshark plug-in of OpenVPN protocol, if it was not restricted by the Windows and Gnome/QT programming environments, I may have implemented it for a long time, and I don't like or turn to IDE. The old dream made me eager to use time quickly on the problem itself rather than anything else. Although the current programming tool, the Framework almost claims to "let you focus on your own logic without having to care about XXYYOO", I cannot see this, the high learning cost will offset your attention to the periphery. Raising a cow for a cup of milk is a silly idea.
Wireshark's support for the OpenVPN protocol eventually came, but it was too late.
Capture the data packets during the establishment of the OpenVPN tunnel and confirm how SSL is encapsulated in the OpenVPN protocol. Obviously, the SSL handshake protocol needs to be encapsulated in the OpenVPN protocol. The packet capture result is as follows:
This figure shows the ClienHello encapsulation,? No, but it is ClientHello. You can see the first few bytes of data: 16030100... If you see the SSL protocol or the SSL protocol cruelly broken, you will lose your temper. But why is this ClientHello not resolved in OpenVPN? Because it is segmented... Does ClientHello have to be segmented? Yes, too! The OpenVPN protocol header occupies some space. With ClientHello itself, we can see that the length of the OpenVPN data is 100, and the other part of it is in the Data Segment 29, so let's take a look at 29:
Indeed, CIDR Block 28 and CIDR Block 29 are merged into ClientHello. Is that true? Of course!
Why is a ClientHello split into 100 bytes? As early as 3 years ago, I wrote in an article, "in this way, even if a 1000-byte SSL handshake message is sent, the reliable layer can split it into 10 UDP packets of over 100 bytes, after the data arrives at the peer end, each 100-byte UDP packet enters its ssl bio memory BIO. The implementation of the SSL protocol is responsible for reorganizing the data. "The article is" OpenVPN Protocol Resolution-handshake packet analysis ", and there was no reason for the effort.
A ClientHello must be separated. What if ServerHello and the Certificate? Of course, it must be separated. Let's take a look at this exaggerated package, which has been divided into so many sections:
Handshake performance in UDP
From the packet capture analysis, we can see that an SSL handshake is going to interact with so many packets, and each packet must be confirmed on the Reliability layer, which will greatly affect the efficiency. Why not hand over the splitting process to the lower layer? The IP layer or network card will do better. Even if you do not do well, you do not have to work overtime to debug your programs and troubleshooting. For protocol stack faults, you only need to browse Maillist and update the driver...
Before testing, I need to find out where to set the length of the sending segment to 100. For OpenVPN, there are two frames, one of which is the data channel and the other is the control channel. This time, we only focus on the control channel. This frame is in the tls_options field of tls_multi. Its Initialization is in tls_init_control_channel_frame_parameters:
Static void
Tls_init_control_channel_frame_parameters (const struct frame * data_channel_frame,
Struct frame * frame)
{
...
/* Set dynamic link MTU to minimum value * // WHY? WHY? How many times have the MTU at both ends be consistent! This is the most likely to be consistent! After all, the control channel is not set up and everything cannot be negotiated!
Frame_set_mtu_dynamic (frame, 0, SET_MTU_TUN );
}
We can change the value 0 in the last call to 1500 or greater! It directly affects the tls_process process. In tls_process, SSL handshake messages are stored in the memory, and the granularity of each IO is PAYLOAD_SIZE_DYNAMIC (& multi-> opt. frame), and it is the result set by frame_set_mtu_dynamic.
After the MTU of the control channel is modified, the number of data packets is almost the number of data packets of the SSL handshake! Compare the performance before and after the modification. The modification is almost doubled! My test method is simple, that is, adding a counter in x_msg to get the millisecond value. The time difference is calculated after the SSL handshake is complete.
Why does the native code set the MTU of the control channel to 100? Because the MTU values at both ends must be consistent, there is no way to negotiate before the control channel is established.
Discussion during testing
I use OpenVPN to transmit big data and aim to calculate a performance value. In comparison, I disabled the OpenVPN process but did not remove the machine. Previously, the machine running OpenVPN only used forward, transmit the same big data. At this time, someone spoke, and there were more than one person. They had to remove two machines that were originally running OpenVPN and directly connect the testing machine to the network cable! Is this necessary? Is your data still expected to be able to fill the router? If the forwarding mechanism in Linux can make a distinction between your data, how many devices will be removed from the shelf in the world! Don't you know how many or fewer devices in the world are directly connected to a network cable in the real environment? Is the invention of a vro or vswitch an error?
I understand the psychology of non-R & D personnel. Of course, they need to pick out even a few of your faults. After all, they have to face customers directly. This is also a good thing for R & D, and they can keep improving, the reason for removing the device for direct connection is that they want to make the biggest difference. But it is also difficult to be professional. If you do not know the pure forwarding performance of a device, you should not always yell at it as a bottleneck. If a software has a problem, it can be seen with the naked eye, if it is not an error, but an improvement, please give data. If you really want to make a difference, don't always use virtual machines. I hate virtual machines very much, especially during stress testing.
While clamoring for the removal of high-end pure forward devices, while still insisting on running several virtual machines in the notebook for testing... alas
Blind socket code writing
Dare to ask who can not read man, not google, not baidu ,... write a TCP socket server directly without using select/poll. If you can, try to write a select, then poll, and finally epoll... neither can I...
OpenVPN client configuration tutorial in Ubuntu
Build OpenVPN in Ubuntu 10.04
Ubuntu 13.04 VPN (OpenVPN) configuration and connection cannot access the Intranet and Internet at the same time
How to build a secure remote network architecture using OpenVPN in Linux
Setting up an OpenVPN Server on Ubuntu Server 14.04 to protect your privacy
This article permanently updates the link address: