1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-12-26 18:19:53 +03:00

Cedar/Proto_OpenVPN: remove UDP system, use the one provided by Proto

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.
This commit is contained in:
Davide Beatrici 2020-05-11 08:23:29 +02:00
parent a3aea00820
commit 27f7d43ff7
2 changed files with 67 additions and 155 deletions

View File

@ -23,6 +23,7 @@ PROTO_IMPL *OvsGetProtoImpl()
OvsName,
OvsIsPacketForMe,
OvsProcessData,
OvsProcessDatagrams,
OvsBufferLimit,
};
@ -82,14 +83,14 @@ bool OvsIsPacketForMe(const PROTO_MODE mode, const UCHAR *data, const UINT size)
return false;
}
bool OvsProcessData(void *param, TCP_RAW_DATA *received_data, FIFO *data_to_send)
bool OvsProcessData(void *param, TCP_RAW_DATA *in, FIFO *out)
{
bool ret = true;
UINT i;
OPENVPN_SERVER *server = param;
UCHAR buf[OPENVPN_TCP_MAX_PACKET_SIZE];
if (server == NULL || received_data == NULL || data_to_send == NULL)
if (server == NULL || in == NULL || out == NULL)
{
return false;
}
@ -99,7 +100,7 @@ bool OvsProcessData(void *param, TCP_RAW_DATA *received_data, FIFO *data_to_send
{
UDPPACKET *packet;
USHORT payload_size, packet_size;
FIFO *fifo = received_data->Data;
FIFO *fifo = in->Data;
const UINT fifo_size = FifoSize(fifo);
if (fifo_size < sizeof(USHORT))
@ -133,13 +134,12 @@ bool OvsProcessData(void *param, TCP_RAW_DATA *received_data, FIFO *data_to_send
}
// Insert packet into the list
packet = NewUdpPacket(&received_data->SrcIP, received_data->SrcPort, &received_data->DstIP, received_data->DstPort, Clone(buf + sizeof(USHORT), payload_size), payload_size);
packet->Type = OPENVPN_PROTOCOL_TCP;
packet = NewUdpPacket(&in->SrcIP, in->SrcPort, &in->DstIP, in->DstPort, Clone(buf + sizeof(USHORT), payload_size), payload_size);
Add(server->RecvPacketList, packet);
}
// Process the list of received datagrams
OvsRecvPacket(server, server->RecvPacketList);
OvsRecvPacket(server, server->RecvPacketList, OPENVPN_PROTOCOL_TCP);
// Release the received packet list
for (i = 0; i < LIST_NUM(server->RecvPacketList); ++i)
@ -158,10 +158,10 @@ bool OvsProcessData(void *param, TCP_RAW_DATA *received_data, FIFO *data_to_send
// Store the size in the TCP send queue first
USHORT us = Endian16((USHORT)p->Size);
WriteFifo(data_to_send, &us, sizeof(USHORT));
WriteFifo(out, &us, sizeof(USHORT));
// Write the data body
WriteFifo(data_to_send, p->Data, p->Size);
WriteFifo(out, p->Data, p->Size);
// Packet release
FreeUdpPacket(p);
@ -171,7 +171,8 @@ bool OvsProcessData(void *param, TCP_RAW_DATA *received_data, FIFO *data_to_send
if (server->Giveup <= server->Now)
{
for (UINT i = 0; i < LIST_NUM(server->SessionList); ++i)
UINT i;
for (i = 0; i < LIST_NUM(server->SessionList); ++i)
{
OPENVPN_SESSION *se = LIST_DATA(server->SessionList, i);
@ -187,6 +188,47 @@ bool OvsProcessData(void *param, TCP_RAW_DATA *received_data, FIFO *data_to_send
return ret;
}
bool OvsProcessDatagrams(void *param, LIST *in, LIST *out)
{
UINT i;
LIST *to_send;
OPENVPN_SERVER *server = param;
if (server == NULL || in == NULL || out == NULL)
{
return false;
}
OvsRecvPacket(server, in, OPENVPN_PROTOCOL_UDP);
to_send = server->SendPacketList;
for (i = 0; i < LIST_NUM(to_send); ++i)
{
Add(out, LIST_DATA(to_send, i));
}
DeleteAll(server->SendPacketList);
if (server->Giveup <= server->Now)
{
UINT i;
for (i = 0; i < LIST_NUM(server->SessionList); ++i)
{
OPENVPN_SESSION *se = LIST_DATA(server->SessionList, i);
if (se->Established)
{
return server->DisconnectCount < 1;
}
}
return false;
}
return true;
}
void OvsBufferLimit(void *param, const bool reached)
{
if (param == NULL)
@ -507,7 +549,7 @@ final:
}
// Process the received packet
void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p)
void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
{
OPENVPN_CHANNEL *c;
OPENVPN_SESSION *se;
@ -519,7 +561,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p)
}
// Search for the session
se = OvsFindOrCreateSession(s, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort, p->Type);
se = OvsFindOrCreateSession(s, &p->DstIP, p->DestPort, &p->SrcIP, p->SrcPort, protocol);
if (se == NULL)
{
return;
@ -749,8 +791,13 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN
// Create an SSL pipe
Lock(s->Cedar->lock);
{
bool cert_verify = true;
c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, cert_verify, &c->ClientCert);
if (s->Dh->Size != s->Cedar->DhParamBits)
{
DhFree(s->Dh);
s->Dh = DhNewFromBits(s->Cedar->DhParamBits);
}
c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, true, &c->ClientCert);
}
Unlock(s->Cedar->lock);
@ -2165,7 +2212,7 @@ OPENVPN_SESSION *OvsSearchSession(OPENVPN_SERVER *s, IP *server_ip, UINT server_
}
// Receive packets in the OpenVPN server
void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list)
void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{
UINT i, j;
LIST *delete_session_list = NULL;
@ -2197,7 +2244,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list)
{
UDPPACKET *p = LIST_DATA(recv_packet_list, i);
OvsProceccRecvPacket(s, p);
OvsProceccRecvPacket(s, p, protocol);
}
// Treat for all sessions and all channels
@ -2908,7 +2955,7 @@ OPENVPN_SERVER *NewOpenVpnServer(CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOC
OvsLog(s, NULL, NULL, "LO_START");
s->Dh = DhNewFromBits(DH_PARAM_BITS_DEFAULT);
s->Dh = DhNewFromBits(cedar->DhParamBits);
return s;
}
@ -2956,123 +3003,3 @@ void FreeOpenVpnServer(OPENVPN_SERVER *s)
Free(s);
}
// UDP reception procedure
void OpenVpnServerUdpListenerProc(UDPLISTENER *u, LIST *packet_list)
{
OPENVPN_SERVER_UDP *us;
// Validate arguments
if (u == NULL || packet_list == NULL)
{
return;
}
us = (OPENVPN_SERVER_UDP *)u->Param;
if (us->OpenVpnServer != NULL)
{
{
u->PollMyIpAndPort = false;
ClearStr(us->Cedar->OpenVPNPublicPorts, sizeof(us->Cedar->OpenVPNPublicPorts));
}
OvsRecvPacket(us->OpenVpnServer, packet_list);
UdpListenerSendPackets(u, us->OpenVpnServer->SendPacketList);
DeleteAll(us->OpenVpnServer->SendPacketList);
}
}
// Create an OpenVPN server (UDP mode)
OPENVPN_SERVER_UDP *NewOpenVpnServerUdp(CEDAR *cedar)
{
OPENVPN_SERVER_UDP *u;
// Validate arguments
if (cedar == NULL)
{
return NULL;
}
u = ZeroMalloc(sizeof(OPENVPN_SERVER_UDP));
u->Cedar = cedar;
AddRef(u->Cedar->ref);
// Create a UDP listener
u->UdpListener = NewUdpListenerEx(OpenVpnServerUdpListenerProc, u, &cedar->Server->ListenIP, OPENVPN_PROTOCOL_UDP);
// Create an OpenVPN server
u->OpenVpnServer = NewOpenVpnServer(cedar, u->UdpListener->Interrupts, u->UdpListener->Event);
return u;
}
void OpenVpnServerUdpSetDhParam(OPENVPN_SERVER_UDP *u, DH_CTX *dh)
{
// Validate arguments
if (u == NULL) {
return;
}
if (u->OpenVpnServer->Dh)
{
DhFree(u->OpenVpnServer->Dh);
}
u->OpenVpnServer->Dh = dh;
}
// Apply the port list to the OpenVPN server
void OvsApplyUdpPortList(OPENVPN_SERVER_UDP *u, char *port_list, IP *listen_ip)
{
LIST *o;
UINT i;
// Validate arguments
if (u == NULL)
{
return;
}
DeleteAllPortFromUdpListener(u->UdpListener);
if (u->UdpListener != NULL && listen_ip != NULL)
{
Copy(&u->UdpListener->ListenIP, listen_ip, sizeof(IP));
}
o = StrToIntList(port_list, true);
for (i = 0;i < LIST_NUM(o);i++)
{
UINT port = *((UINT *)LIST_DATA(o, i));
if (port >= 1 && port <= 65535)
{
AddPortToUdpListener(u->UdpListener, port);
}
}
ReleaseIntList(o);
}
// Release the OpenVPN server (UDP mode)
void FreeOpenVpnServerUdp(OPENVPN_SERVER_UDP *u)
{
// Validate arguments
if (u == NULL)
{
return;
}
// Stop the UDP listener
FreeUdpListener(u->UdpListener);
// Release the OpenVPN server
FreeOpenVpnServer(u->OpenVpnServer);
ReleaseCedar(u->Cedar);
Free(u);
}

View File

@ -204,15 +204,6 @@ struct OPENVPN_SERVER
UINT SessionEstablishedCount; // Number of session establishment
};
// OpenVPN server (UDP mode)
struct OPENVPN_SERVER_UDP
{
CEDAR *Cedar;
UDPLISTENER *UdpListener; // UDP listener
OPENVPN_SERVER *OpenVpnServer; // OpenVPN server
UINT64 VgsNextGetPublicPortsTick;
};
// OpenVPN Default Client Option String
#define OVPN_DEF_CLIENT_OPTION_STRING "dev-type tun,link-mtu 1500,tun-mtu 1500,cipher AES-128-CBC,auth SHA1,keysize 128,key-method 2,tls-client"
@ -222,20 +213,16 @@ bool OvsInit(void **param, CEDAR *cedar, INTERRUPT_MANAGER *im, SOCK_EVENT *se);
void OvsFree(void *param);
char *OvsName();
bool OvsIsPacketForMe(const PROTO_MODE mode, const UCHAR *data, const UINT size);
bool OvsProcessData(void *param, TCP_RAW_DATA *received_data, FIFO *data_to_send);
bool OvsProcessData(void *param, TCP_RAW_DATA *in, FIFO *out);
bool OvsProcessDatagrams(void *param, LIST *in, LIST *out);
void OvsBufferLimit(void *param, const bool reached);
bool OvsIsOk(void *param);
UINT OvsEstablishedSessions(void *param);
OPENVPN_SERVER_UDP *NewOpenVpnServerUdp(CEDAR *cedar);
void FreeOpenVpnServerUdp(OPENVPN_SERVER_UDP *u);
void OpenVpnServerUdpListenerProc(UDPLISTENER *u, LIST *packet_list);
void OvsApplyUdpPortList(OPENVPN_SERVER_UDP *u, char *port_list, IP *listen_ip);
OPENVPN_SERVER *NewOpenVpnServer(CEDAR *cedar, INTERRUPT_MANAGER *interrupt, SOCK_EVENT *sock_event);
void FreeOpenVpnServer(OPENVPN_SERVER *s);
void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list);
void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p);
void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol);
void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol);
int OvsCompareSessionList(void *p1, void *p2);
OPENVPN_SESSION *OvsSearchSession(OPENVPN_SERVER *s, IP *server_ip, UINT server_port, IP *client_ip, UINT client_port, UINT protocol);
OPENVPN_SESSION *OvsNewSession(OPENVPN_SERVER *s, IP *server_ip, UINT server_port, IP *client_ip, UINT client_port, UINT protocol);
@ -279,6 +266,4 @@ UINT OvsCalcTcpMss(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c);
CIPHER *OvsGetCipher(char *name);
MD *OvsGetMd(char *name);
void OpenVpnServerUdpSetDhParam(OPENVPN_SERVER_UDP *u, DH_CTX *dh);
#endif // PROTO_OPENVPN_H