41 #if defined(__MINGW32__)
42 const IN_ADDR in4addr_any = { 0 };
51 for (
int i = 0; i < 20; ++i)
53 MIB_IPINTERFACE_ROW row = { .InterfaceIndex = idx, .Family = AF_INET };
54 if (GetIpInterfaceEntry(&row) != ERROR_NOT_FOUND)
79 HANDLE h = CreateFile(
"\\\\.\\ovpn-dco-ver", GENERIC_READ,
80 0, NULL, OPEN_EXISTING, 0, NULL);
82 if (h == INVALID_HANDLE_VALUE)
85 h = CreateFile(
"\\\\.\\ovpn-dco", GENERIC_READ,
86 0, NULL, OPEN_EXISTING, 0, NULL);
89 if (h == INVALID_HANDLE_VALUE)
94 DWORD bytes_returned = 0;
96 version,
sizeof(*version), &bytes_returned, NULL))
104 if (h != INVALID_HANDLE_VALUE)
126 ASSERT(dco->ifmode == DCO_MODE_UNINIT);
127 dco->ifmode = DCO_MODE_MP;
132 dco->ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
133 if (dco->ov.hEvent == NULL)
135 msg(
M_ERR,
"Error: ovpn_dco_init: CreateEvent failed");
138 dco->rwhandle.read = dco->ov.hEvent;
142 const char *device_guid;
148 DWORD bytes_returned = 0;
149 if (!DeviceIoControl(dco->tt->hand,
OVPN_IOCTL_SET_MODE, &m,
sizeof(m), NULL, 0, &bytes_returned, NULL))
151 msg(
M_ERR,
"DeviceIoControl(OVPN_IOCTL_SET_MODE) failed");
168 DWORD bytes_returned = 0;
171 msg(
M_ERR,
"DeviceIoControl(OVPN_IOCTL_START_VPN) failed");
196 dco->ifmode = DCO_MODE_P2P;
223 typedef BOOL (WINAPI *get_overlapped_result_ex_t)(HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL);
224 get_overlapped_result_ex_t get_overlapped_result_ex =
225 (get_overlapped_result_ex_t)GetProcAddress(GetModuleHandle(
"Kernel32.dll"),
226 "GetOverlappedResultEx");
228 if (get_overlapped_result_ex == NULL)
230 msg(
M_ERR,
"Failed to load GetOverlappedResult()");
233 DWORD timeout_msec = timeout * 1000;
234 const int poll_interval_ms = 50;
236 while (timeout_msec > 0)
238 timeout_msec -= poll_interval_ms;
241 if (get_overlapped_result_ex(handle, ov, &transferred, poll_interval_ms, FALSE) != 0)
247 DWORD err = GetLastError();
248 if ((err != WAIT_TIMEOUT) && (err != ERROR_IO_INCOMPLETE))
257 if (*signal_received)
286 struct addrinfo *cur = NULL;
288 for (cur = local; cur; cur = cur->ai_next)
290 if (cur->ai_family == ai_family)
297 msg(
M_FATAL,
"%s: Socket bind failed: Addr to bind has no %s record",
303 if (ai_family == AF_INET)
315 DWORD bytes_returned = 0;
317 &bytes_returned, NULL))
319 msg(
M_ERR,
"DeviceIoControl(OVPN_IOCTL_MP_START_VPN) failed");
332 struct sockaddr *local = NULL;
333 struct sockaddr *remote = remoteaddr->ai_addr;
335 if (remoteaddr->ai_protocol == IPPROTO_TCP
336 || remoteaddr->ai_socktype == SOCK_STREAM)
349 while (bind && !local)
351 if (bind->ai_family == remote->sa_family)
353 local = bind->ai_addr;
355 bind = bind->ai_next;
361 msg(
M_FATAL,
"DCO: Socket bind failed: Address to bind lacks %s record",
365 if (remote->sa_family == AF_INET6)
367 peer.
Remote.
Addr6 = *((SOCKADDR_IN6 *)(remoteaddr->ai_addr));
379 else if (remote->sa_family == AF_INET)
381 peer.
Remote.
Addr4 = *((SOCKADDR_IN *)(remoteaddr->ai_addr));
398 OVERLAPPED ov = { 0 };
399 if (!DeviceIoControl(handle,
OVPN_IOCTL_NEW_PEER, &peer,
sizeof(peer), NULL, 0, NULL, &ov))
401 DWORD err = GetLastError();
402 if (err != ERROR_IO_PENDING)
404 msg(
M_ERR,
"DeviceIoControl(OVPN_IOCTL_NEW_PEER) failed");
415 struct sockaddr *localaddr,
struct sockaddr *remoteaddr,
416 struct in_addr *vpn_ipv4,
struct in6_addr *vpn_ipv6)
420 if (dco->ifmode == DCO_MODE_P2P)
431 newPeer.
Local.
Addr4.sin_family = remoteaddr->sa_family;
433 if (remoteaddr->sa_family == AF_INET)
435 memcpy(&newPeer.
Remote.
Addr4, remoteaddr,
sizeof(
struct sockaddr_in));
439 memcpy(&newPeer.
Remote.
Addr6, remoteaddr,
sizeof(
struct sockaddr_in6));
456 if (!DeviceIoControl(dco->tt->hand,
OVPN_IOCTL_MP_NEW_PEER, &newPeer,
sizeof(newPeer), NULL, 0, &bytesReturned, NULL))
458 msg(
M_ERR,
"DeviceIoControl(OVPN_IOCTL_MP_NEW_PEER) failed");
474 if (dco->ifmode == DCO_MODE_MP)
478 len =
sizeof(del_peer);
481 DWORD bytes_returned = 0;
482 if (!DeviceIoControl(dco->tt->hand, ioctl, buf, len, NULL, 0, &bytes_returned, NULL))
492 int keepalive_interval,
int keepalive_timeout,
int mss)
494 msg(
D_DCO_DEBUG,
"%s: peer-id %d, keepalive %d/%d, mss %d", __func__,
495 peerid, keepalive_interval, keepalive_timeout, mss);
497 OVPN_MP_SET_PEER mp_peer = { peerid, keepalive_interval, keepalive_timeout, mss };
498 OVPN_SET_PEER peer = { keepalive_interval, keepalive_timeout, mss };
503 if (dco->ifmode == DCO_MODE_MP)
514 DWORD bytes_returned = 0;
515 if (!DeviceIoControl(dco->tt->hand, ioctl, buf, len, NULL, 0, &bytes_returned, NULL))
527 const uint8_t *encrypt_key,
const uint8_t *encrypt_iv,
528 const uint8_t *decrypt_key,
const uint8_t *decrypt_iv,
529 const char *ciphername)
532 __func__, slot, keyid, peerid, ciphername);
534 const int nonce_len = 8;
538 ZeroMemory(&crypto_data,
sizeof(crypto_data));
540 crypto_data.
CipherAlg = dco_get_cipher(ciphername);
541 crypto_data.
KeyId = keyid;
542 crypto_data.
PeerId = peerid;
545 CopyMemory(crypto_data.
Encrypt.
Key, encrypt_key, key_len);
549 CopyMemory(crypto_data.
Decrypt.
Key, decrypt_key, key_len);
555 DWORD bytes_returned = 0;
558 sizeof(crypto_data), NULL, 0, &bytes_returned, NULL))
560 msg(
M_ERR,
"DeviceIoControl(OVPN_IOCTL_NEW_KEY) failed");
568 msg(
D_DCO,
"%s: peer-id %d, slot %d called but ignored", __func__, peerid,
584 if (dco->ifmode == DCO_MODE_MP)
591 DWORD bytes_returned = 0;
592 if (!DeviceIoControl(dco->tt->hand, ioctl, buf, len, NULL, 0, &bytes_returned, NULL))
594 msg(
M_ERR,
"DeviceIoControl(OVPN_IOCTL_SWAP_KEYS) failed");
604 HANDLE h = CreateFile(
"\\\\.\\ovpn-dco", GENERIC_READ | GENERIC_WRITE,
605 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL);
607 if (h != INVALID_HANDLE_VALUE)
613 DWORD err = GetLastError();
614 if (err == ERROR_ACCESS_DENIED)
623 msg(msglevel,
"Note: ovpn-dco-win driver is missing, disabling data channel offload.");
657 DWORD bytes_read = 0;
658 BOOL res = GetOverlappedResult(dco->tt->hand, &dco->ov, &bytes_read, FALSE);
661 msg(
D_DCO_DEBUG,
"%s: completion%s success [%ld]", __func__, queued ?
"" :
" non-queued", bytes_read);
663 dco->dco_message_peer_id = dco->notif_buf.PeerId;
664 dco->dco_message_type = dco->notif_buf.Cmd;
665 dco->dco_del_peer_reason = dco->notif_buf.DelPeerReason;
676 if (dco->ifmode != DCO_MODE_MP)
681 dco->dco_message_peer_id = -1;
682 dco->dco_message_type = 0;
684 switch (dco->iostate)
689 ASSERT(ResetEvent(dco->ov.hEvent));
696 ASSERT(ResetEvent(dco->ov.hEvent));
698 if (dco->ov_ret == ERROR_SUCCESS)
704 SetLastError(dco->ov_ret);
716 const bool raise_sigusr1_on_err)
735 DWORD bytes_returned = 0;
737 &stats,
sizeof(stats), &bytes_returned, NULL))
754 if (
dco->ifmode != DCO_MODE_MP)
769 DWORD err = GetLastError();
770 if (err == ERROR_IO_PENDING)
773 dco->ov_ret = ERROR_SUCCESS;
791 dco->ov_ret = ERROR_SUCCESS;
808 NTSTATUS
status = BCryptOpenAlgorithmProvider(&h, L
"CHACHA20_POLY1305", NULL, 0);
809 if (BCRYPT_SUCCESS(
status))
811 BCryptCloseAlgorithmProvider(h, 0);
812 return "AES-128-GCM:AES-256-GCM:AES-192-GCM:CHACHA20-POLY1305";
816 return "AES-128-GCM:AES-256-GCM:AES-192-GCM";
832 OVPN_MP_IROUTE route = {.Addr.Addr4.S_un.S_addr = dst, .Netbits = netbits, .PeerId = peer_id, .IPv6 = 0};
836 DWORD bytes_returned = 0;
838 sizeof(
route), NULL, 0, &bytes_returned, NULL))
851 OVPN_MP_IROUTE route = { .Addr.Addr6 = dst, .Netbits = netbits, .PeerId = peer_id, .IPv6 = 1 };
855 DWORD bytes_returned = 0;
857 sizeof(
route), NULL, 0, &bytes_returned, NULL))
870 OVPN_MP_IROUTE route = { .Addr.Addr4.S_un.S_addr = dst, .Netbits = netbits, .PeerId = -1, .IPv6 = 0 };
874 DWORD bytes_returned = 0;
876 sizeof(
route), NULL, 0, &bytes_returned, NULL))
893 DWORD bytes_returned = 0;
895 sizeof(
route), NULL, 0, &bytes_returned, NULL))