Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move peer-specific data to separate struct #61

Merged
merged 1 commit into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 50 additions & 2 deletions Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* ovpn-dco-win OpenVPN protocol accelerator for Windows
*
* Copyright (C) 2020-2021 OpenVPN Inc <[email protected]>
* Copyright (C) 2023 Rubicon Communications LLC (Netgate)
*
* Author: Lev Stipakov <[email protected]>
*
Expand Down Expand Up @@ -309,8 +310,6 @@ VOID OvpnEvtFileCleanup(WDFFILEOBJECT fileObject) {
// peer might already be deleted
(VOID)OvpnPeerDel(device);

InterlockedExchange(&device->UserspacePid, 0);

if (device->Adapter != NULL) {
OvpnAdapterSetLinkState(OvpnGetAdapterContext(device->Adapter), MediaConnectStateDisconnected);
}
Expand Down Expand Up @@ -476,10 +475,59 @@ OvpnEvtDeviceAdd(WDFDRIVER wdfDriver, PWDFDEVICE_INIT deviceInit) {

GOTO_IF_NOT_NT_SUCCESS(done, status, OvpnCryptoInitAlgHandles(&device->AesAlgHandle, &device->ChachaAlgHandle));

// Initialize peers tree
RtlInitializeGenericTable(&device->Peers, OvpnPeerCompareByPeerIdRoutine, OvpnPeerAllocateRoutine, OvpnPeerFreeRoutine, NULL);

LOG_IF_NOT_NT_SUCCESS(status = OvpnAdapterCreate(device));

done:
LOG_EXIT();

return status;
}

_Use_decl_annotations_
NTSTATUS
OvpnAddPeer(POVPN_DEVICE device, OvpnPeerContext* peer)
{
NTSTATUS status;
BOOLEAN newElem;

RtlInsertElementGenericTable(&device->Peers, (PVOID)&peer, sizeof(OvpnPeerContext*), &newElem);

if (newElem) {
status = STATUS_SUCCESS;
}
else {
LOG_ERROR("Unable to add new peer");
status = STATUS_NO_MEMORY;
}
return status;
}

_Use_decl_annotations_
VOID
OvpnFlushPeers(POVPN_DEVICE device) {
OvpnCleanupPeerTable(&device->Peers);
}

_Use_decl_annotations_
VOID
OvpnCleanupPeerTable(RTL_GENERIC_TABLE* peers)
{
while (!RtlIsGenericTableEmpty(peers)) {
PVOID ptr = RtlGetElementGenericTable(peers, 0);
OvpnPeerContext* peer = *(OvpnPeerContext**)ptr;
RtlDeleteElementGenericTable(peers, ptr);

OvpnPeerCtxFree(peer);
}
}

_Use_decl_annotations_
OvpnPeerContext*
OvpnGetFirstPeer(RTL_GENERIC_TABLE* peers)
{
OvpnPeerContext** ptr = (OvpnPeerContext**)RtlGetElementGenericTable(peers, 0);
return ptr ? (OvpnPeerContext*)*ptr : NULL;
}
49 changes: 27 additions & 22 deletions Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,43 +76,48 @@ struct OVPN_DEVICE {

OVPN_STATS Stats;

// keepalive interval in seconds
_Guarded_by_(SpinLock)
LONG KeepaliveInterval;

// keepalive timeout in seconds
_Guarded_by_(SpinLock)
LONG KeepaliveTimeout;

// timer used to send periodic ping messages to the server if no data has been sent within the past KeepaliveInterval seconds
_Guarded_by_(SpinLock)
WDFTIMER KeepaliveXmitTimer;

// timer used to report keepalive timeout error to userspace when no data has been received for KeepaliveTimeout seconds
_Guarded_by_(SpinLock)
WDFTIMER KeepaliveRecvTimer;

BCRYPT_ALG_HANDLE AesAlgHandle;
BCRYPT_ALG_HANDLE ChachaAlgHandle;

// set from the userspace, defines TCP Maximum Segment Size
_Guarded_by_(SpinLock)
UINT16 MSS;

_Guarded_by_(SpinLock)
OvpnCryptoContext CryptoContext;

_Guarded_by_(SpinLock)
OvpnSocket Socket;

_Guarded_by_(SpinLock)
NETADAPTER Adapter;

// pid of userspace process which called NEW_PEER
_Interlocked_
LONG UserspacePid;
_Guarded_by_(SpinLock)
RTL_GENERIC_TABLE Peers;

SIZE_T CryptoOverhead;
};

typedef OVPN_DEVICE * POVPN_DEVICE;

WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(OVPN_DEVICE, OvpnGetDeviceContext)

static inline
BOOLEAN
OvpnHasPeers(_In_ POVPN_DEVICE device)
{
return !RtlIsGenericTableEmpty(&device->Peers);
}

struct OvpnPeerContext;

_Must_inspect_result_
NTSTATUS
OvpnAddPeer(_In_ POVPN_DEVICE device, _In_ OvpnPeerContext* PeerCtx);

VOID
OvpnFlushPeers(_In_ POVPN_DEVICE device);

VOID
OvpnCleanupPeerTable(_In_ RTL_GENERIC_TABLE*);

_Must_inspect_result_
OvpnPeerContext*
OvpnGetFirstPeer(_In_ RTL_GENERIC_TABLE*);
4 changes: 0 additions & 4 deletions crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,17 +263,13 @@ OvpnCryptoNewKey(OvpnCryptoContext* cryptoContext, POVPN_CRYPTO_DATA cryptoData,
keySlot->KeyId = cryptoData->KeyId;
keySlot->PeerId = cryptoData->PeerId;

cryptoContext->CryptoOverhead = AEAD_CRYPTO_OVERHEAD;

LOG_INFO("New key", TraceLoggingValue(cryptoData->CipherAlg == OVPN_CIPHER_ALG_AES_GCM ? "aes-gcm" : "chacha20-poly1305", "alg"),
TraceLoggingValue(cryptoData->KeyId, "KeyId"), TraceLoggingValue(cryptoData->KeyId, "PeerId"));
}
else if (cryptoData->CipherAlg == OVPN_CIPHER_ALG_NONE) {
cryptoContext->Encrypt = OvpnCryptoEncryptNone;
cryptoContext->Decrypt = OvpnCryptoDecryptNone;

cryptoContext->CryptoOverhead = NONE_CRYPTO_OVERHEAD;

LOG_INFO("Using cipher none");
}
else {
Expand Down
1 change: 1 addition & 0 deletions crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* ovpn-dco-win OpenVPN protocol accelerator for Windows
*
* Copyright (C) 2020-2021 OpenVPN Inc <[email protected]>
* Copyright (C) 2023 Rubicon Communications LLC (Netgate)
*
* Author: Lev Stipakov <[email protected]>
*
Expand Down
Loading
Loading