Commit f802a44a authored by Jan Koester's avatar Jan Koester
Browse files

initial

parents
Loading
Loading
Loading
Loading

.gitignore

0 → 100644
+4 −0
Changes for .gitignore: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
build/
*.o
*.d
__pycache__/

CMakeLists.txt

0 → 100644
+46 −0
Changes for CMakeLists.txt: 46 added lines, 0 removed lines.
Original line number Diff line number Diff line
cmake_minimum_required(VERSION 3.16)
project(ntpplus VERSION 0.1.0 LANGUAGES CXX)

# ntpplus: NTP for FenrirOS. A client that synchronizes the system clock
# with NTP servers and pools (RFC 5905: clock filter, selection of the
# truechimers, the kernel PLL via adjtimex()), and a server that hands
# the time on to the network (client requests only, access list, rate
# limit). Configured in one YAML file (libconfplus) and over sysbus as
# the service "ntpplus" (include/ntpplus/api.h) -- webctl's time page is
# its client. UDP through libnetplus.
#
#   ntpplusd   the daemon (root: it sets the clock, port 123)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()

include(GNUInstallDirs)

find_package(sysbus REQUIRED)
find_package(libnetplus REQUIRED)
find_package(libconfplus REQUIRED)
find_package(Threads REQUIRED)

set(NTPPLUS_SYSCONFDIR "/etc/ntpplus" CACHE PATH "configuration directory")

# needs <sys/timex.h> (adjtimex): glibc, musl, systempp
add_executable(ntpplusd
    src/main.cpp
    src/config.cpp
    src/client.cpp
    src/server.cpp
    src/clock.cpp
    src/ntp.cpp
)
target_include_directories(ntpplusd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_compile_definitions(ntpplusd PRIVATE NTPPLUS_CONFIG="${NTPPLUS_SYSCONFDIR}/ntpplus.yaml")
target_link_libraries(ntpplusd PRIVATE sysbus::sysbus netplus::netplus confplus::confplus Threads::Threads)

install(TARGETS ntpplusd RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
install(DIRECTORY include/ntpplus DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES dist/ntpplus.yaml DESTINATION ${NTPPLUS_SYSCONFDIR})
set(NTPPLUS_UNITDIR "/etc/syslite/services" CACHE PATH "syslite unit directory")
install(FILES dist/ntpplus.service DESTINATION ${NTPPLUS_UNITDIR})

dist/ntpplus.service

0 → 100644
+10 −0
Changes for dist/ntpplus.service: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
[Unit]
Description=ntpplus: NTP client and server

[Service]
Type=simple
ExecStart=/usr/sbin/ntpplusd
Restart=always

[Install]
WantedBy=multi-user.target

dist/ntpplus.yaml

0 → 100644
+18 −0
Changes for dist/ntpplus.yaml: 18 added lines, 0 removed lines.
Original line number Diff line number Diff line
ntpplus:
  client:
    enabled: "yes"
    sources:
      - host: pool.ntp.org
        type: pool
        iburst: "yes"
    minpoll: 6
    maxpoll: 10
    step: startup
    step_threshold: 1.0
  server:
    enabled: "no"
    listen:
      - 0.0.0.0
      - "::"
    local_stratum: 0
  drift: /var/lib/ntpplus/drift

include/ntpplus/api.h

0 → 100644
+77 −0
Changes for include/ntpplus/api.h: 77 added lines, 0 removed lines.
Original line number Diff line number Diff line
/*******************************************************************************
Copyright (c) 2026, Jan Koester jan.koester@gmx.net
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

/* ntpplus on sysbus: the service "ntpplus", reached with
 * sysbus::Client::callService(ntpplus::Service, method, fields).
 * GetSettings and GetStatus are open to every user, the rest needs root.
 * Error messages are in English, or in German if the call has a field
 * "lang" starting with "de". Flags are yes|no, times in seconds.
 *
 * ntpplus synchronizes the system clock with NTP servers (client) and
 * serves its time to the network (server), see src/config.h.
 *
 *   GetSettings -> client, minpoll, maxpoll (log2 s), step (startup|
 *       always|never), step_threshold, server, listen (repeated), allow
 *       (repeated, CIDR), local_stratum; then per source: source (host),
 *       type (server|pool), iburst
 *   SetSettings {the same} replaces them all; written to the
 *       configuration file
 *
 *   GetStatus -> time (Unix, with fraction), synchronized (ntpplus),
 *       kernel_synchronized (the kernel's STA_UNSYNC), stratum, offset,
 *       jitter, frequency (ppm), refid, sys_peer?, last_update (Unix, 0:
 *       never), poll (s), steps, leap (none|insert|delete|unsynchronized),
 *       client, server (yes: listening), answered, refused (requests
 *       served / not served), server_error?;
 *       then per source: source (host), type, resolving, error?; per
 *       peer, after its source: peer (address), state (sys_peer|candidate|
 *       falseticker|unreachable|unsynchronized|kod|error|new), note?,
 *       stratum, refid, reach (octal, 377: the last 8 polls answered),
 *       poll, when (s since its last answer, -1: never), offset, delay,
 *       jitter
 *
 *   SyncNow           asks every peer at once (a burst); the next update
 *                     may step the clock, whatever step says
 *   SetTime {time}    sets the clock by hand (Unix seconds, may have a
 *                     fraction) -- e.g. without network; the client
 *                     corrects it again if it runs */

#pragma once

namespace ntpplus {

constexpr const char *Service = "ntpplus";

namespace method {
constexpr const char *GetSettings = "GetSettings";
constexpr const char *SetSettings = "SetSettings";
constexpr const char *GetStatus = "GetStatus";
constexpr const char *SyncNow = "SyncNow";
constexpr const char *SetTime = "SetTime";
} // namespace method

} // namespace ntpplus
Loading