Originally, StrToPortList() returned NULL when it encountered a number equal to 0 or higher than 65535.
This commit adds a new parameter to the function called "limit_range":
- When its value is true, the function retains the original behavior.
- When its value is false, the function doesn't check whether the number is in the network port number range (1-65535).
The change is required because the command to set the UDP ports will allow to remove all ports by specifying "0" as the port number.
Now that Proto supports UDP, the server can handle multiple protocols on each UDP port.
The UDP ports are specified by the "OpenVPN_UdpPortList" configuration setting, because:
- OpenVPN is currently the only UDP protocol supported by SoftEther VPN to allow a custom port number.
- Before Proto was introduced, a unified interface for the protocols didn't exist; each protocol implementation had to create its own listener.
In preparation for the upcoming WireGuard implementation, this commit renames "OpenVPN_UdpPortList" to "PortsUDP", which should clarify that the setting is global.
The change is reflected in the code. Also, the ports are now stored in a LIST rather than a string. The conversion between string and LIST only happens when loading/saving the configuration.
The default UDP ports are now the same as the TCP ones (443, 992, 1194, 5555).
*** CID 358434: Null pointer dereferences (REVERSE_INULL)
/src/Cedar/Proto.c: 451 in ProtoHandleDatagrams()
445 void ProtoHandleDatagrams(UDPLISTENER *listener, LIST *datagrams)
446 {
447 UINT i;
448 HASH_LIST *sessions;
449 PROTO *proto = listener->Param;
450
>>> CID 358434: Null pointer dereferences (REVERSE_INULL)
>>> Null-checking "listener" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
451 if (proto == NULL || listener == NULL || datagrams == NULL)
452 {
453 return;
454 }
455
456 sessions = proto->Sessions;
As a side effect, the DH parameter is now applied to the TCP server as well.
Previously, the default value was always used, ignoring the one from the configuration.
When a datagram is received, the matching session is looked up in a hash list; if it's not found, a new session is created.
This method allows to use a single UDP port for multiple protocols, as we do with TCP.
Also, each session has its own dedicated thread, used to process the received datagrams and generate the ones that are then sent through the UDP listener.
In addition to guaranteeing constant performance, separate threads also prevent a single one from blocking all sessions.
This allows to stop a UDP listener without deleting it.
It's especially useful when no datagrams should be received anymore, but there are other threads accessing the listener.
- An additional parameter is added to IsPacketForMe(), used to specify the protocol type (currently either TCP or UDP).
- SupportedModes() is dropped because it's now redundant.
- IsOk() and EstablishedSessions() are dropped because error checking should be handled by the implementation.
- ProtoImplDetect() now takes a buffer and its size rather than a SOCK, so that it can be used to detect UDP protocols.
- The OpenVPN toggle check is moved to ProtoImplDetect(), so that we don't have to duplicate it once UDP support is implemented.
The PROTO structure is now used to identify the system as a whole, rather than a single protocol. It's stored and initialized in Server.
ProtoCompare(), ProtoAdd() and ProtoDetected() are renamed to make the difference between PROTO and PROTO_IMPL more clear.
ProtoGet() and ProtoNum() are removed because the related list can now be accessed directly by Server.