mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2024-11-22 17:39:53 +03:00
Cedar/Proto: introduce PROTO_CONTAINER, to store data for each implementation
ProtoImplDetect() is renamed to ProtoDetect(), because it now returns a pointer to a PROTO_CONTAINER (if successful).
This commit is contained in:
parent
cd850c07ae
commit
8685fe0da1
@ -2,21 +2,19 @@
|
|||||||
|
|
||||||
#include "Proto_OpenVPN.h"
|
#include "Proto_OpenVPN.h"
|
||||||
|
|
||||||
int ProtoImplCompare(void *p1, void *p2)
|
int ProtoContainerCompare(void *p1, void *p2)
|
||||||
{
|
{
|
||||||
PROTO_IMPL *impl_1 = p1, *impl_2 = p2;
|
PROTO_CONTAINER *container_1, *container_2;
|
||||||
|
|
||||||
if (impl_1 == NULL || impl_2 == NULL)
|
if (p1 == NULL || p2 == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return (p1 == NULL && p2 == NULL ? 0 : (p1 == NULL ? -1 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StrCmp(impl_1->Name(), impl_2->Name()) == 0)
|
container_1 = *(PROTO_CONTAINER **)p1;
|
||||||
{
|
container_2 = *(PROTO_CONTAINER **)p2;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return StrCmpi(container_1->Name, container_2->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ProtoSessionCompare(void *p1, void *p2)
|
int ProtoSessionCompare(void *p1, void *p2)
|
||||||
@ -126,15 +124,15 @@ PROTO *ProtoNew(CEDAR *cedar)
|
|||||||
|
|
||||||
proto = Malloc(sizeof(PROTO));
|
proto = Malloc(sizeof(PROTO));
|
||||||
proto->Cedar = cedar;
|
proto->Cedar = cedar;
|
||||||
proto->Impls = NewList(ProtoImplCompare);
|
proto->Containers = NewList(ProtoContainerCompare);
|
||||||
proto->Sessions = NewHashList(ProtoSessionHash, ProtoSessionCompare, 0, true);
|
proto->Sessions = NewHashList(ProtoSessionHash, ProtoSessionCompare, 0, true);
|
||||||
|
|
||||||
AddRef(cedar->ref);
|
AddRef(cedar->ref);
|
||||||
|
|
||||||
// OpenVPN
|
// OpenVPN
|
||||||
ProtoImplAdd(proto, OvsGetProtoImpl());
|
Add(proto->Containers, ProtoContainerNew(OvsGetProtoImpl()));
|
||||||
// SSTP
|
// SSTP
|
||||||
ProtoImplAdd(proto, SstpGetProtoImpl());
|
Add(proto->Containers, ProtoContainerNew(SstpGetProtoImpl()));
|
||||||
|
|
||||||
proto->UdpListener = NewUdpListener(ProtoHandleDatagrams, proto, &cedar->Server->ListenIP);
|
proto->UdpListener = NewUdpListener(ProtoHandleDatagrams, proto, &cedar->Server->ListenIP);
|
||||||
|
|
||||||
@ -156,28 +154,49 @@ void ProtoDelete(PROTO *proto)
|
|||||||
{
|
{
|
||||||
ProtoDeleteSession(LIST_DATA(proto->Sessions->AllList, i));
|
ProtoDeleteSession(LIST_DATA(proto->Sessions->AllList, i));
|
||||||
}
|
}
|
||||||
|
ReleaseHashList(proto->Sessions);
|
||||||
|
|
||||||
|
for (i = 0; i < LIST_NUM(proto->Containers); ++i)
|
||||||
|
{
|
||||||
|
ProtoContainerDelete(LIST_DATA(proto->Containers, i));
|
||||||
|
}
|
||||||
|
ReleaseList(proto->Containers);
|
||||||
|
|
||||||
FreeUdpListener(proto->UdpListener);
|
FreeUdpListener(proto->UdpListener);
|
||||||
ReleaseHashList(proto->Sessions);
|
|
||||||
ReleaseList(proto->Impls);
|
|
||||||
ReleaseCedar(proto->Cedar);
|
ReleaseCedar(proto->Cedar);
|
||||||
Free(proto);
|
Free(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProtoImplAdd(PROTO *proto, PROTO_IMPL *impl) {
|
PROTO_CONTAINER *ProtoContainerNew(const PROTO_IMPL *impl)
|
||||||
if (proto == NULL || impl == NULL)
|
{
|
||||||
|
UINT i;
|
||||||
|
PROTO_CONTAINER *container;
|
||||||
|
|
||||||
|
if (impl == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Add(proto->Impls, impl);
|
container = Malloc(sizeof(PROTO_CONTAINER));
|
||||||
|
container->Name = impl->Name();
|
||||||
|
container->Impl = impl;
|
||||||
|
|
||||||
Debug("ProtoImplAdd(): added %s\n", impl->Name());
|
Debug("ProtoContainerNew(): %s\n", container->Name);
|
||||||
|
|
||||||
return true;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
PROTO_IMPL *ProtoImplDetect(PROTO *proto, const PROTO_MODE mode, const UCHAR *data, const UINT size)
|
void ProtoContainerDelete(PROTO_CONTAINER *container)
|
||||||
|
{
|
||||||
|
if (container == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Free(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PROTO_CONTAINER *ProtoDetect(const PROTO *proto, const PROTO_MODE mode, const UCHAR *data, const UINT size)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
@ -186,45 +205,47 @@ PROTO_IMPL *ProtoImplDetect(PROTO *proto, const PROTO_MODE mode, const UCHAR *da
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < LIST_NUM(proto->Impls); ++i)
|
for (i = 0; i < LIST_NUM(proto->Containers); ++i)
|
||||||
{
|
{
|
||||||
PROTO_IMPL *impl = LIST_DATA(proto->Impls, i);
|
const PROTO_CONTAINER *container = LIST_DATA(proto->Containers, i);
|
||||||
if (impl->IsPacketForMe == NULL || impl->IsPacketForMe(mode, data, size) == false)
|
const PROTO_IMPL *impl = container->Impl;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrCmp(impl->Name(), "OpenVPN") == 0 && proto->Cedar->Server->DisableOpenVPNServer)
|
if (StrCmp(impl->Name(), "OpenVPN") == 0 && proto->Cedar->Server->DisableOpenVPNServer)
|
||||||
{
|
{
|
||||||
Debug("ProtoImplDetect(): OpenVPN detected, but it's disabled\n");
|
Debug("ProtoDetect(): OpenVPN detected, but it's disabled\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug("ProtoImplDetect(): %s detected\n", impl->Name());
|
if (impl->IsPacketForMe != NULL && impl->IsPacketForMe(mode, data, size))
|
||||||
return impl;
|
{
|
||||||
|
Debug("ProtoDetect(): %s detected\n", container->Name);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug("ProtoImplDetect(): unrecognized protocol\n");
|
Debug("ProtoDetect(): unrecognized protocol\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PROTO_SESSION *ProtoNewSession(PROTO *proto, PROTO_IMPL *impl, const IP *src_ip, const USHORT src_port, const IP *dst_ip, const USHORT dst_port)
|
PROTO_SESSION *ProtoNewSession(PROTO *proto, const PROTO_CONTAINER *container, const IP *src_ip, const USHORT src_port, const IP *dst_ip, const USHORT dst_port)
|
||||||
{
|
{
|
||||||
PROTO_SESSION *session;
|
PROTO_SESSION *session;
|
||||||
|
const PROTO_IMPL *impl;
|
||||||
|
|
||||||
if (impl == NULL || src_ip == NULL || src_port == 0 || dst_ip == NULL || dst_port == 0)
|
if (container == NULL || src_ip == NULL || src_port == 0 || dst_ip == NULL || dst_port == 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
session = ZeroMalloc(sizeof(PROTO_SESSION));
|
impl = container->Impl;
|
||||||
|
|
||||||
|
session = ZeroMalloc(sizeof(PROTO_SESSION));
|
||||||
session->SockEvent = NewSockEvent();
|
session->SockEvent = NewSockEvent();
|
||||||
session->InterruptManager = NewInterruptManager();
|
session->InterruptManager = NewInterruptManager();
|
||||||
|
|
||||||
if (impl->Init != NULL && impl->Init(&session->Param, proto->Cedar, session->InterruptManager, session->SockEvent, NULL, NULL) == false)
|
if (impl->Init != NULL && impl->Init(&session->Param, proto->Cedar, session->InterruptManager, session->SockEvent, NULL, NULL) == false)
|
||||||
{
|
{
|
||||||
Debug("ProtoNewSession(): failed to initialize %s\n", impl->Name());
|
Debug("ProtoNewSession(): failed to initialize %s\n", container->Name);
|
||||||
|
|
||||||
ReleaseSockEvent(session->SockEvent);
|
ReleaseSockEvent(session->SockEvent);
|
||||||
FreeInterruptManager(session->InterruptManager);
|
FreeInterruptManager(session->InterruptManager);
|
||||||
@ -313,7 +334,7 @@ bool ProtoSetUdpPorts(PROTO *proto, const LIST *ports)
|
|||||||
|
|
||||||
bool ProtoHandleConnection(PROTO *proto, SOCK *sock, const char *protocol)
|
bool ProtoHandleConnection(PROTO *proto, SOCK *sock, const char *protocol)
|
||||||
{
|
{
|
||||||
const PROTO_IMPL *impl = NULL;
|
const PROTO_IMPL *impl;
|
||||||
void *impl_data = NULL;
|
void *impl_data = NULL;
|
||||||
|
|
||||||
UCHAR *buf;
|
UCHAR *buf;
|
||||||
@ -327,44 +348,51 @@ bool ProtoHandleConnection(PROTO *proto, SOCK *sock, const char *protocol)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protocol != NULL)
|
|
||||||
{
|
{
|
||||||
UINT i;
|
const PROTO_CONTAINER *container = NULL;
|
||||||
for (i = 0; i < LIST_NUM(proto->Impls); ++i)
|
|
||||||
|
if (protocol != NULL)
|
||||||
{
|
{
|
||||||
const PROTO_IMPL *tmp = LIST_DATA(proto->Impls, i);
|
UINT i;
|
||||||
if (StrCmp(tmp->Name(), protocol) == 0)
|
for (i = 0; i < LIST_NUM(proto->Containers); ++i)
|
||||||
{
|
{
|
||||||
impl = tmp;
|
const PROTO_CONTAINER *tmp = LIST_DATA(proto->Containers, i);
|
||||||
break;
|
if (StrCmp(tmp->Name, protocol) == 0)
|
||||||
|
{
|
||||||
|
impl = container->Impl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
UCHAR tmp[PROTO_CHECK_BUFFER_SIZE];
|
||||||
UCHAR tmp[PROTO_CHECK_BUFFER_SIZE];
|
|
||||||
if (Peek(sock, tmp, sizeof(tmp)) == 0)
|
if (Peek(sock, tmp, sizeof(tmp)) == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
container = ProtoDetect(proto, PROTO_MODE_TCP, tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl = ProtoImplDetect(proto, PROTO_MODE_TCP, tmp, sizeof(tmp));
|
impl = container->Impl;
|
||||||
}
|
|
||||||
|
|
||||||
if (impl == NULL)
|
im = NewInterruptManager();
|
||||||
{
|
se = NewSockEvent();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
im = NewInterruptManager();
|
if (impl->Init != NULL && impl->Init(&impl_data, proto->Cedar, im, se, sock->CipherName, sock->RemoteHostname) == false)
|
||||||
se = NewSockEvent();
|
{
|
||||||
|
Debug("ProtoHandleConnection(): failed to initialize %s\n", container->Name);
|
||||||
if (impl->Init != NULL && impl->Init(&impl_data, proto->Cedar, im, se, sock->CipherName, sock->RemoteHostname) == false)
|
FreeInterruptManager(im);
|
||||||
{
|
ReleaseSockEvent(se);
|
||||||
Debug("ProtoHandleConnection(): failed to initialize %s\n", impl->Name());
|
return false;
|
||||||
FreeInterruptManager(im);
|
}
|
||||||
ReleaseSockEvent(se);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetTimeout(sock, TIMEOUT_INFINITE);
|
SetTimeout(sock, TIMEOUT_INFINITE);
|
||||||
@ -484,13 +512,13 @@ void ProtoHandleDatagrams(UDPLISTENER *listener, LIST *datagrams)
|
|||||||
session = SearchHash(sessions, &tmp);
|
session = SearchHash(sessions, &tmp);
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
{
|
{
|
||||||
tmp.Impl = ProtoImplDetect(proto, PROTO_MODE_UDP, datagram->Data, datagram->Size);
|
const PROTO_CONTAINER *container = ProtoDetect(proto, PROTO_MODE_UDP, datagram->Data, datagram->Size);
|
||||||
if (tmp.Impl == NULL)
|
if (container == NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
session = ProtoNewSession(proto, tmp.Impl, &tmp.SrcIp, tmp.SrcPort, &tmp.DstIp, tmp.DstPort);
|
session = ProtoNewSession(proto, container, &tmp.SrcIp, tmp.SrcPort, &tmp.DstIp, tmp.DstPort);
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -539,7 +567,7 @@ void ProtoSessionThread(THREAD *thread, void *param)
|
|||||||
bool ok;
|
bool ok;
|
||||||
UINT interval;
|
UINT interval;
|
||||||
void *param = session->Param;
|
void *param = session->Param;
|
||||||
PROTO_IMPL *impl = session->Impl;
|
const PROTO_IMPL *impl = session->Impl;
|
||||||
LIST *received = session->DatagramsIn;
|
LIST *received = session->DatagramsIn;
|
||||||
LIST *to_send = session->DatagramsOut;
|
LIST *to_send = session->DatagramsOut;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ typedef enum PROTO_MODE
|
|||||||
typedef struct PROTO
|
typedef struct PROTO
|
||||||
{
|
{
|
||||||
CEDAR *Cedar;
|
CEDAR *Cedar;
|
||||||
LIST *Impls;
|
LIST *Containers;
|
||||||
HASH_LIST *Sessions;
|
HASH_LIST *Sessions;
|
||||||
UDPLISTENER *UdpListener;
|
UDPLISTENER *UdpListener;
|
||||||
} PROTO;
|
} PROTO;
|
||||||
@ -32,11 +32,17 @@ typedef struct PROTO_IMPL
|
|||||||
bool (*ProcessDatagrams)(void *param, LIST *in, LIST *out);
|
bool (*ProcessDatagrams)(void *param, LIST *in, LIST *out);
|
||||||
} PROTO_IMPL;
|
} PROTO_IMPL;
|
||||||
|
|
||||||
|
typedef struct PROTO_CONTAINER
|
||||||
|
{
|
||||||
|
const char *Name;
|
||||||
|
const PROTO_IMPL *Impl;
|
||||||
|
} PROTO_CONTAINER;
|
||||||
|
|
||||||
typedef struct PROTO_SESSION
|
typedef struct PROTO_SESSION
|
||||||
{
|
{
|
||||||
void *Param;
|
void *Param;
|
||||||
PROTO *Proto;
|
const PROTO *Proto;
|
||||||
PROTO_IMPL *Impl;
|
const PROTO_IMPL *Impl;
|
||||||
IP SrcIp;
|
IP SrcIp;
|
||||||
USHORT SrcPort;
|
USHORT SrcPort;
|
||||||
IP DstIp;
|
IP DstIp;
|
||||||
@ -50,7 +56,7 @@ typedef struct PROTO_SESSION
|
|||||||
volatile bool Halt;
|
volatile bool Halt;
|
||||||
} PROTO_SESSION;
|
} PROTO_SESSION;
|
||||||
|
|
||||||
int ProtoImplCompare(void *p1, void *p2);
|
int ProtoContainerCompare(void *p1, void *p2);
|
||||||
int ProtoSessionCompare(void *p1, void *p2);
|
int ProtoSessionCompare(void *p1, void *p2);
|
||||||
|
|
||||||
UINT ProtoSessionHash(void *p);
|
UINT ProtoSessionHash(void *p);
|
||||||
@ -58,10 +64,12 @@ UINT ProtoSessionHash(void *p);
|
|||||||
PROTO *ProtoNew(CEDAR *cedar);
|
PROTO *ProtoNew(CEDAR *cedar);
|
||||||
void ProtoDelete(PROTO *proto);
|
void ProtoDelete(PROTO *proto);
|
||||||
|
|
||||||
bool ProtoImplAdd(PROTO *proto, PROTO_IMPL *impl);
|
PROTO_CONTAINER *ProtoContainerNew(const PROTO_IMPL *impl);
|
||||||
PROTO_IMPL *ProtoImplDetect(PROTO *proto, const PROTO_MODE mode, const UCHAR *data, const UINT size);
|
void ProtoContainerDelete(PROTO_CONTAINER *container);
|
||||||
|
|
||||||
PROTO_SESSION *ProtoNewSession(PROTO *proto, PROTO_IMPL *impl, const IP *src_ip, const USHORT src_port, const IP *dst_ip, const USHORT dst_port);
|
const PROTO_CONTAINER *ProtoDetect(const PROTO *proto, const PROTO_MODE mode, const UCHAR *data, const UINT size);
|
||||||
|
|
||||||
|
PROTO_SESSION *ProtoNewSession(PROTO *proto, const PROTO_CONTAINER *container, const IP *src_ip, const USHORT src_port, const IP *dst_ip, const USHORT dst_port);
|
||||||
void ProtoDeleteSession(PROTO_SESSION *session);
|
void ProtoDeleteSession(PROTO_SESSION *session);
|
||||||
|
|
||||||
bool ProtoSetListenIP(PROTO *proto, const IP *ip);
|
bool ProtoSetListenIP(PROTO *proto, const IP *ip);
|
||||||
|
Loading…
Reference in New Issue
Block a user