feat: add NTP; fix networking bugs/regressions

This commit is contained in:
2026-07-29 16:32:18 +01:00
parent a288dee7df
commit d99dab45e5
26 changed files with 809 additions and 47 deletions
+1 -1
View File
@@ -12,4 +12,4 @@
#pragma once
#define MONTAUK_BUILD_NUMBER 8
#define MONTAUK_BUILD_NUMBER 17
+5
View File
@@ -12,6 +12,7 @@
#include <Timekeeping/ApicTimer.hpp>
#include <Net/Icmp.hpp>
#include <Net/Dns.hpp>
#include <Net/Ipv4.hpp>
#include <Net/Socket.hpp>
#include <Net/NetConfig.hpp>
#include <Drivers/Net/E1000.hpp>
@@ -82,6 +83,10 @@ namespace montauk::abi {
static int Sys_RecvFrom(int fd, uint8_t* buf, uint32_t maxLen,
uint32_t* srcIp, uint16_t* srcPort) {
// A preceding UDP send may be queued while ARP resolves the next hop.
// Drive the pending IPv4 queue on each non-blocking receive so a lost
// initial ARP request is retried without unrelated network traffic.
Net::Ipv4::FlushPending();
return Net::Socket::RecvFrom(fd, buf, maxLen, srcIp, srcPort, Sched::GetCurrentPid());
}
+3 -1
View File
@@ -174,6 +174,8 @@ namespace montauk::abi {
if (!UserMemory::Writable<DateTime>(frame->arg1)) return -1;
Sys_GetTime((DateTime*)frame->arg1);
return 0;
case SYS_SETUNIXTIME:
return Sys_SetUnixTime((int64_t)frame->arg1);
case SYS_SOCKET:
return (int64_t)Sys_Socket((int)frame->arg1);
case SYS_CONNECT:
@@ -556,7 +558,7 @@ namespace montauk::abi {
Hal::WriteMSR(Hal::IA32_FMASK, 0x200);
Kt::KernelLogStream(Kt::OK, "Syscall") << "SYSCALL/SYSRET initialized (LSTAR="
<< kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", 124 syscall slots)";
<< kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", 154 syscall slots)";
}
}
+1
View File
@@ -287,6 +287,7 @@ namespace montauk::abi {
// Path metadata (size, timestamps, mode). (const char* path, FileStat* out) -> 0, -1 on error/unsupported.
static constexpr uint64_t SYS_STAT = 152;
static constexpr uint64_t SYS_SETUNIXTIME = 153;
// Tunable parameters (for SYS_SDR_SETPARAM / SYS_SDR_GETPARAM).
static constexpr int SDR_PARAM_FREQ = 0; // center frequency, Hz
+5 -1
View File
@@ -38,4 +38,8 @@ namespace montauk::abi {
static int64_t Sys_GetTZ() {
return (int64_t)Timekeeping::GetTZOffset();
}
};
static int64_t Sys_SetUnixTime(int64_t unixSeconds) {
return Timekeeping::SetUnixTimestamp(unixSeconds) ? 0 : -1;
}
};
+4 -1
View File
@@ -250,7 +250,10 @@ namespace Drivers::Net::E1000 {
KernelLogStream(INFO, "E1000") << "Link status change: " << (linkUp ? "UP" : "DOWN");
}
if (icr & ICR_RXT0) {
// Both receive-timer and descriptor-threshold causes mean completed
// RX descriptors may be waiting. ICR is clear-on-read, so ignoring
// RXDMT0 can strand a lone packet until unrelated traffic arrives.
if (icr & (ICR_RXT0 | ICR_RXDMT0)) {
// Process received packets
while (true) {
uint32_t nextIdx = (g_rxTail + 1) % RX_DESC_COUNT;
+4 -1
View File
@@ -477,7 +477,10 @@ namespace Drivers::Net::E1000E {
KernelLogStream(INFO, "E1000E") << "Link status change: " << (linkUp ? "UP" : "DOWN");
}
if (icr & ICR_RXT0) {
// Both receive-timer and descriptor-threshold causes mean completed
// RX descriptors may be waiting. ICR is clear-on-read, so ignoring
// RXDMT0 can strand a lone packet until unrelated traffic arrives.
if (icr & (ICR_RXT0 | ICR_RXDMT0)) {
while (true) {
uint32_t nextIdx = (g_rxTail + 1) % RX_DESC_COUNT;
RxDescriptor& desc = g_rxDescs[nextIdx];
+11 -1
View File
@@ -8,6 +8,7 @@
#include <Net/Udp.hpp>
#include <Net/ByteOrder.hpp>
#include <Net/NetConfig.hpp>
#include <Net/Ipv4.hpp>
#include <Libraries/Memory.hpp>
#include <Libraries/String.hpp>
#include <Timekeeping/ApicTimer.hpp>
@@ -409,12 +410,21 @@ namespace Net::Dns {
// Wait for response with timeout
uint64_t start = Timekeeping::GetMilliseconds();
uint64_t lastPendingService = start;
while (!query->gotResponse) {
if (Timekeeping::GetMilliseconds() - start >= timeoutMs) {
uint64_t now = Timekeeping::GetMilliseconds();
if (now - start >= timeoutMs) {
Net::Udp::Unbind(query->localPort);
query->active = false;
return 0;
}
// Ipv4::Send may have queued this DNS datagram while resolving the
// gateway MAC. Drive that pending queue here so ARP coalescing can
// retry a lost initial request without requiring unrelated traffic.
if (now - lastPendingService >= 100) {
Net::Ipv4::FlushPending();
lastPendingService = now;
}
Sched::Schedule();
}
+8 -1
View File
@@ -84,6 +84,13 @@ int64_t Timekeeping::GetUnixTimestamp() {
return g_bootEpoch + (int64_t)(Timekeeping::GetMilliseconds() / 1000);
}
bool Timekeeping::SetUnixTimestamp(int64_t unixSeconds) {
if (unixSeconds < 0 || unixSeconds > 4102444799LL)
return false;
g_bootEpoch = unixSeconds - (int64_t)(Timekeeping::GetMilliseconds() / 1000);
return true;
}
Timekeeping::DateTime Timekeeping::GetDateTime() {
return EpochToDate(GetUnixTimestamp() + (int64_t)g_tzOffsetMinutes * 60);
}
@@ -94,4 +101,4 @@ void Timekeeping::SetTZOffset(int totalMinutes) {
int Timekeeping::GetTZOffset() {
return g_tzOffsetMinutes;
}
}
+1
View File
@@ -53,6 +53,7 @@ namespace Timekeeping {
void Init(uint16_t Year, uint8_t Month, uint8_t Day, uint8_t Hour, uint8_t Minute, uint8_t Second);
int64_t GetUnixTimestamp();
DateTime GetDateTime();
bool SetUnixTimestamp(int64_t unixSeconds);
void SetTZOffset(int totalMinutes);
int GetTZOffset();