feat: add NTP; fix networking bugs/regressions
This commit is contained in:
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 8
|
||||
#define MONTAUK_BUILD_NUMBER 17
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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)";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user