1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-22 17:39:53 +03:00

Merge PR #1108: Cedar: various improvements to Proto

This commit is contained in:
Davide Beatrici 2020-05-02 19:52:31 +02:00 committed by GitHub
commit e6803a1fab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 102 deletions

View File

@ -1606,9 +1606,6 @@ void InitCedar()
// Initialize protocol module // Initialize protocol module
InitProtocol(); InitProtocol();
// Initialize third-party protocol interface
ProtoInit();
} }
// Free Cedar communication module // Free Cedar communication module
@ -1619,9 +1616,6 @@ void FreeCedar()
return; return;
} }
// Free third-party protocol interface
ProtoFree();
// Free protocol module // Free protocol module
FreeProtocol(); FreeProtocol();
} }

View File

@ -2935,10 +2935,10 @@ void ConnectionAccept(CONNECTION *c)
{ {
if (c->Cedar != NULL && c->Cedar->Server != NULL) if (c->Cedar != NULL && c->Cedar->Server != NULL)
{ {
c->Type = CONNECTION_TYPE_OTHER; PROTO *proto = c->Cedar->Server->Proto;
if (proto && ProtoHandleConnection(proto, s) == true)
if (ProtoHandleConnection(c->Cedar, s) == true)
{ {
c->Type = CONNECTION_TYPE_OTHER;
goto FINAL; goto FINAL;
} }
} }

View File

@ -2,21 +2,16 @@
#include "Proto_OpenVPN.h" #include "Proto_OpenVPN.h"
static LIST *protocols = NULL; int ProtoImplCompare(void *p1, void *p2)
int ProtoCompare(void *p1, void *p2)
{ {
PROTO *proto_1, *proto_2; PROTO_IMPL *impl_1 = p1, *impl_2 = p2;
if (p1 == NULL || p2 == NULL) if (impl_1 == NULL || impl_2 == NULL)
{ {
return 0; return 0;
} }
proto_1 = (PROTO *)p1; if (StrCmp(impl_1->Name(), impl_2->Name()) == 0)
proto_2 = (PROTO *)p2;
if (StrCmp(proto_1->impl->Name(), proto_2->impl->Name()) == 0)
{ {
return true; return true;
} }
@ -24,70 +19,58 @@ int ProtoCompare(void *p1, void *p2)
return false; return false;
} }
void ProtoInit() PROTO *ProtoNew(CEDAR *cedar)
{
if (protocols != NULL)
{
ProtoFree();
}
protocols = NewList(ProtoCompare);
// OpenVPN
ProtoAdd(OvsGetProtoImpl());
}
void ProtoFree()
{
UINT i;
PROTO_IMPL *impl;
for (i = 0; i < ProtoNum(); ++i)
{
PROTO *proto = ProtoGet(i);
impl = proto->impl;
Free(proto);
}
ReleaseList(protocols);
protocols = NULL;
}
bool ProtoAdd(PROTO_IMPL *impl)
{ {
PROTO *proto; PROTO *proto;
if (protocols == NULL || impl == NULL) if (cedar == NULL)
{
return NULL;
}
proto = Malloc(sizeof(PROTO));
proto->Cedar = cedar;
proto->Impls = NewList(ProtoImplCompare);
AddRef(cedar->ref);
// OpenVPN
ProtoImplAdd(proto, OvsGetProtoImpl());
return proto;
}
void ProtoDelete(PROTO *proto)
{
if (proto == NULL)
{
return;
}
ReleaseList(proto->Impls);
ReleaseCedar(proto->Cedar);
Free(proto);
}
bool ProtoImplAdd(PROTO *proto, PROTO_IMPL *impl) {
if (proto == NULL || impl == NULL)
{ {
return false; return false;
} }
proto = Malloc(sizeof(PROTO)); Add(proto->Impls, impl);
proto->impl = impl;
Add(protocols, proto); Debug("ProtoImplAdd(): added %s\n", impl->Name());
Debug("ProtoAdd(): added %s\n", proto->impl->Name());
return true; return true;
} }
UINT ProtoNum() PROTO_IMPL *ProtoImplDetect(PROTO *proto, SOCK *sock)
{
return LIST_NUM(protocols);
}
PROTO *ProtoGet(const UINT index)
{
return LIST_DATA(protocols, index);
}
PROTO *ProtoDetect(SOCK *sock)
{ {
UCHAR buf[PROTO_CHECK_BUFFER_SIZE]; UCHAR buf[PROTO_CHECK_BUFFER_SIZE];
UINT i; UINT i;
if (sock == NULL) if (proto == NULL || sock == NULL)
{ {
return NULL; return NULL;
} }
@ -97,24 +80,23 @@ PROTO *ProtoDetect(SOCK *sock)
return false; return false;
} }
for (i = 0; i < ProtoNum(); ++i) for (i = 0; i < LIST_NUM(proto->Impls); ++i)
{ {
PROTO *p = ProtoGet(i); PROTO_IMPL *impl = LIST_DATA(proto->Impls, i);
if (p->impl->IsPacketForMe(buf, sizeof(buf))) if (impl->IsPacketForMe(buf, sizeof(buf)))
{ {
Debug("ProtoDetect(): %s detected\n", p->impl->Name()); Debug("ProtoImplDetect(): %s detected\n", impl->Name());
return p; return impl;
} }
} }
return NULL; return NULL;
} }
bool ProtoHandleConnection(CEDAR *cedar, SOCK *sock) bool ProtoHandleConnection(PROTO *proto, SOCK *sock)
{ {
void *impl_data; void *impl_data = NULL;
const PROTO_IMPL *impl; const PROTO_IMPL *impl;
const PROTO *proto;
UCHAR *buf; UCHAR *buf;
TCP_RAW_DATA *recv_raw_data; TCP_RAW_DATA *recv_raw_data;
@ -124,22 +106,19 @@ bool ProtoHandleConnection(CEDAR *cedar, SOCK *sock)
const UINT64 giveup = Tick64() + (UINT64)OPENVPN_NEW_SESSION_DEADLINE_TIMEOUT; const UINT64 giveup = Tick64() + (UINT64)OPENVPN_NEW_SESSION_DEADLINE_TIMEOUT;
if (cedar == NULL || sock == NULL) if (proto == NULL || sock == NULL)
{ {
return false; return false;
} }
proto = ProtoDetect(sock); impl = ProtoImplDetect(proto, sock);
if (impl == NULL)
if (proto == NULL)
{ {
Debug("ProtoHandleConnection(): unrecognized protocol\n"); Debug("ProtoHandleConnection(): unrecognized protocol\n");
return false; return false;
} }
impl = proto->impl; if (StrCmp(impl->Name(), "OpenVPN") == 0 && proto->Cedar->Server->DisableOpenVPNServer == true)
if (StrCmp(impl->Name(), "OpenVPN") == 0 && cedar->Server->DisableOpenVPNServer == true)
{ {
Debug("ProtoHandleConnection(): OpenVPN detected, but it's disabled\n"); Debug("ProtoHandleConnection(): OpenVPN detected, but it's disabled\n");
return false; return false;
@ -153,7 +132,7 @@ bool ProtoHandleConnection(CEDAR *cedar, SOCK *sock)
im = NewInterruptManager(); im = NewInterruptManager();
se = NewSockEvent(); se = NewSockEvent();
if (impl->Init != NULL && impl->Init(&impl_data, cedar, im, se) == false) if (impl->Init != NULL && impl->Init(&impl_data, proto->Cedar, im, se) == false)
{ {
Debug("ProtoHandleConnection(): failed to initialize %s\n", impl->Name()); Debug("ProtoHandleConnection(): failed to initialize %s\n", impl->Name());
FreeInterruptManager(im); FreeInterruptManager(im);

View File

@ -10,6 +10,12 @@
#define PROTO_MODE_TCP 1 #define PROTO_MODE_TCP 1
#define PROTO_MODE_UDP 2 #define PROTO_MODE_UDP 2
typedef struct PROTO
{
CEDAR *Cedar;
LIST *Impls;
} PROTO;
typedef struct PROTO_IMPL typedef struct PROTO_IMPL
{ {
bool (*Init)(void **param, CEDAR *cedar, INTERRUPT_MANAGER *im, SOCK_EVENT *se); bool (*Init)(void **param, CEDAR *cedar, INTERRUPT_MANAGER *im, SOCK_EVENT *se);
@ -23,22 +29,14 @@ typedef struct PROTO_IMPL
UINT (*EstablishedSessions)(void *param); UINT (*EstablishedSessions)(void *param);
} PROTO_IMPL; } PROTO_IMPL;
typedef struct PROTO int ProtoImplCompare(void *p1, void *p2);
{
PROTO_IMPL *impl;
} PROTO;
int ProtoCompare(void *p1, void *p2); PROTO *ProtoNew(CEDAR *cedar);
void ProtoDelete(PROTO *proto);
void ProtoInit(); bool ProtoImplAdd(PROTO *proto, PROTO_IMPL *impl);
void ProtoFree(); PROTO_IMPL *ProtoImplDetect(PROTO *proto, SOCK *sock);
bool ProtoAdd(PROTO_IMPL *impl); bool ProtoHandleConnection(PROTO *proto, SOCK *sock);
UINT ProtoNum();
PROTO *ProtoGet(const UINT index);
PROTO *ProtoDetect(SOCK *sock);
bool ProtoHandleConnection(CEDAR *cedar, SOCK *sock);
#endif #endif

View File

@ -2623,15 +2623,13 @@ void SiInitConfiguration(SERVER *s)
s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT; s->AutoSaveConfigSpan = SERVER_FILE_SAVE_INTERVAL_DEFAULT;
s->BackupConfigOnlyWhenModified = true; s->BackupConfigOnlyWhenModified = true;
if (s->Cedar->Bridge == false)
{
// Protocols handler
s->Proto = ProtoNew(s->Cedar);
// IPsec server // IPsec server
if (s->Cedar->Bridge == false)
{
s->IPsecServer = NewIPsecServer(s->Cedar); s->IPsecServer = NewIPsecServer(s->Cedar);
}
// OpenVPN server (UDP) // OpenVPN server (UDP)
if (s->Cedar->Bridge == false)
{
s->OpenVpnServerUdp = NewOpenVpnServerUdp(s->Cedar); s->OpenVpnServerUdp = NewOpenVpnServerUdp(s->Cedar);
} }
@ -6538,6 +6536,11 @@ void SiFreeConfiguration(SERVER *s)
s->SaveHaltEvent = NULL; s->SaveHaltEvent = NULL;
s->SaveThread = NULL; s->SaveThread = NULL;
// Stop the protocols handler
if (s->Proto != NULL)
{
ProtoDelete(s->Proto);
}
// Stop the IPsec server // Stop the IPsec server
if (s->IPsecServer != NULL) if (s->IPsecServer != NULL)

View File

@ -242,6 +242,7 @@ struct SERVER
volatile bool HaltDeadLockThread; // Halting flag volatile bool HaltDeadLockThread; // Halting flag
EVENT *DeadLockWaitEvent; // Waiting Event EVENT *DeadLockWaitEvent; // Waiting Event
PROTO *Proto; // Protocols handler
IPSEC_SERVER *IPsecServer; // IPsec server function IPSEC_SERVER *IPsecServer; // IPsec server function
OPENVPN_SERVER_UDP *OpenVpnServerUdp; // OpenVPN server function OPENVPN_SERVER_UDP *OpenVpnServerUdp; // OpenVPN server function
char OpenVpnServerUdpPorts[MAX_SIZE]; // UDP port list string char OpenVpnServerUdpPorts[MAX_SIZE]; // UDP port list string