Time Shield Library
C++ library for working with time
Toggle main menu visibility
Loading...
Searching...
No Matches
udp_transport_win.hpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: MIT
2
#pragma once
3
#ifndef TIME_SHIELD_HEADER_TIME_SHIELD_NTP_CLIENT_UDP_TRANSPORT_WIN_HPP_INCLUDED
4
#define TIME_SHIELD_HEADER_TIME_SHIELD_NTP_CLIENT_UDP_TRANSPORT_WIN_HPP_INCLUDED
5
6
#if TIME_SHIELD_PLATFORM_WINDOWS
7
8
#include "
wsa_guard.hpp
"
9
#include "
udp_transport.hpp
"
10
11
#include <winsock2.h>
12
#include <ws2tcpip.h>
13
#include <cstring>
14
15
namespace
time_shield
{
16
namespace
detail
{
17
19
class
UdpTransportWin
:
public
IUdpTransport
{
20
public
:
22
bool
transact
(
const
UdpRequest
& req,
int
& out_error_code)
noexcept
override
{
23
out_error_code = 0;
24
if
(!
WsaGuard::instance
().success()) {
25
out_error_code =
WsaGuard::instance
().
ret_code
();
26
return
false
;
27
}
28
29
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
30
if
(sock == INVALID_SOCKET) {
31
out_error_code = WSAGetLastError();
32
return
false
;
33
}
34
35
sockaddr_in addr{};
36
addr.sin_family = AF_INET;
37
addr.sin_port = htons(
static_cast<
u_short
>
(req.port));
38
39
addrinfo hints{}, *res =
nullptr
;
40
hints.ai_family = AF_INET;
41
hints.ai_socktype = SOCK_DGRAM;
42
hints.ai_protocol = IPPROTO_UDP;
43
44
if
(getaddrinfo(req.host.c_str(),
nullptr
, &hints, &res) != 0 || !res) {
45
out_error_code = WSAGetLastError();
46
closesocket(sock);
47
return
false
;
48
}
49
addr.sin_addr =
reinterpret_cast<
sockaddr_in*
>
(res->ai_addr)->sin_addr;
50
51
const
int
timeout_ms = req.timeout_ms > 0 ? req.timeout_ms : 5000;
52
DWORD timeout =
static_cast<
DWORD
>
(timeout_ms);
53
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
reinterpret_cast<
const
char
*
>
(&timeout),
sizeof
(timeout));
54
55
const
int
send_res = sendto(sock,
56
static_cast<
const
char
*
>
(req.send_data),
57
static_cast<
int
>
(req.send_size),
58
0,
59
reinterpret_cast<
sockaddr*
>
(&addr),
60
sizeof
(addr));
61
if
(send_res == SOCKET_ERROR ||
static_cast<
std::size_t
>
(send_res) != req.send_size) {
62
out_error_code = WSAGetLastError();
63
freeaddrinfo(res);
64
closesocket(sock);
65
return
false
;
66
}
67
68
sockaddr_in from{};
69
int
from_len =
sizeof
(from);
70
const
int
recv_res = recvfrom(sock,
71
static_cast<
char
*
>
(req.recv_data),
72
static_cast<
int
>
(req.recv_size),
73
0,
74
reinterpret_cast<
sockaddr*
>
(&from),
75
&from_len);
76
77
if
(recv_res == SOCKET_ERROR ||
static_cast<
std::size_t
>
(recv_res) != req.recv_size) {
78
out_error_code = WSAGetLastError();
79
freeaddrinfo(res);
80
closesocket(sock);
81
return
false
;
82
}
83
84
freeaddrinfo(res);
85
closesocket(sock);
86
return
true
;
87
}
88
};
89
90
}
// namespace detail
91
}
// namespace time_shield
92
93
#endif
// _TIME_SHIELD_PLATFORM_WINDOWS
94
95
#endif
// TIME_SHIELD_HEADER_TIME_SHIELD_NTP_CLIENT_UDP_TRANSPORT_WIN_HPP_INCLUDED
time_shield::WsaGuard::ret_code
int ret_code() const noexcept
Returns the result code from WSAStartup.
Definition
wsa_guard.hpp:44
time_shield::WsaGuard::instance
static const WsaGuard & instance()
Returns the singleton instance, initializing WSA if needed.
Definition
wsa_guard.hpp:33
time_shield::detail::IUdpTransport
Abstract UDP transport interface for NTP queries.
Definition
udp_transport.hpp:24
time_shield::detail::UdpTransportWin
Windows UDP transport for NTP queries.
Definition
udp_transport_win.hpp:19
time_shield::detail::UdpTransportWin::transact
bool transact(const UdpRequest &req, int &out_error_code) noexcept override
Send request and receive response over UDP.
Definition
udp_transport_win.hpp:22
time_shield::detail
Definition
fast_date.hpp:14
time_shield
Main namespace for the Time Shield library.
time_shield::detail::UdpRequest
UDP request parameters for NTP transactions.
Definition
udp_transport.hpp:13
udp_transport.hpp
wsa_guard.hpp
Singleton guard for WinSock initialization.
include
time_shield
ntp_client
udp_transport_win.hpp
Generated by
1.17.0