1//
2// NTPClient.cpp
3//
4// Library: Net
5// Package: NTP
6// Module: NTPClient
7//
8// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Net/SocketAddress.h"
16#include "Poco/Net/NTPClient.h"
17#include "Poco/Net/NTPPacket.h"
18#include "Poco/Net/DatagramSocket.h"
19#include "Poco/Net/NetException.h"
20
21
22using Poco::TimeoutException;
23
24
25namespace Poco {
26namespace Net {
27
28
29NTPClient::NTPClient(IPAddress::Family family, int timeout):
30 _family(family), _timeout(timeout)
31{
32}
33
34
35NTPClient::~NTPClient()
36{
37}
38
39
40int NTPClient::request(const std::string& address) const
41{
42 SocketAddress addr(address, 123);
43 return request(addr);
44}
45
46
47int NTPClient::request(SocketAddress& address) const
48{
49 SocketAddress sa;
50 DatagramSocket ntpSocket(_family);
51 ntpSocket.setReceiveTimeout(_timeout);
52 ntpSocket.bind(sa);
53
54 SocketAddress returnAddress;
55
56 NTPEventArgs eventArgs(address);
57
58 NTPPacket packet;
59 Poco::UInt8 p[1024];
60 packet.packet(&p[0]);
61
62 ntpSocket.sendTo(p, 48, address);
63
64 int received = 0;
65 Timestamp start;
66 while (true)
67 {
68 try
69 {
70 int n = ntpSocket.receiveFrom(p, sizeof(p) - 1, sa);
71 if (sa != address) // reply mixup, try until timeout ...
72 {
73 if ((Timestamp() - start) < _timeout) continue;
74 break;
75 }
76 if (n < 48) // NTP packet must have at least 48 bytes
77 throw Poco::Net::NTPException("Invalid response received");
78
79 packet.setPacket(p);
80 eventArgs.setPacket(packet);
81 ++received;
82 response.notify(this, eventArgs);
83 break;
84 }
85 catch (Poco::TimeoutException &)
86 {
87 break;
88 }
89 }
90
91 return received;
92}
93
94
95} } // namespace Poco::Net
96