diff --git a/.gitignore b/.gitignore index cfa6940..45c6531 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target CLAUDE.md +docs diff --git a/Dockerfile b/Dockerfile index 9b0a102..0af2ee3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,17 @@ -FROM rust:1.85-alpine AS builder -RUN apk add --no-cache musl-dev +FROM rust:1.88-alpine AS builder +RUN apk add --no-cache musl-dev cmake make perl WORKDIR /app COPY Cargo.toml Cargo.lock ./ RUN mkdir src && echo 'fn main() {}' > src/main.rs && echo '' > src/lib.rs RUN cargo build --release 2>/dev/null || true RUN rm -rf src COPY src/ src/ +COPY site/ site/ +COPY numa.toml com.numa.dns.plist numa.service ./ RUN touch src/main.rs src/lib.rs RUN cargo build --release -FROM scratch -COPY --from=builder /app/target/release/numa /numa -EXPOSE 53/udp 5380/tcp -ENTRYPOINT ["/numa"] +FROM alpine:3.20 +COPY --from=builder /app/target/release/numa /usr/local/bin/numa +EXPOSE 53/udp 80/tcp 443/tcp 5380/tcp +ENTRYPOINT ["numa"] diff --git a/Makefile b/Makefile index c83f5aa..5b0165c 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,11 @@ clean: deploy: cargo build --release sudo cp target/release/numa /usr/local/bin/numa +ifeq ($(shell uname -s),Darwin) sudo codesign -f -s - /usr/local/bin/numa sudo kill $$(pgrep -f /usr/local/bin/numa) 2>/dev/null || true +else + sudo systemctl restart numa 2>/dev/null || sudo kill $$(pgrep -f /usr/local/bin/numa) 2>/dev/null || true +endif @sleep 1 @dig @127.0.0.1 google.com +short +time=3 > /dev/null && echo "Service restarted successfully" || echo "Warning: DNS not responding yet" diff --git a/README.md b/README.md index e474159..7ba4813 100644 --- a/README.md +++ b/README.md @@ -230,11 +230,8 @@ Zero external DNS libraries. RFC 1035 wire protocol parsed by hand. Dependencies - [x] System DNS auto-discovery — Tailscale, VPN split-DNS - [x] System DNS auto-configuration — `numa install` / `numa uninstall` - [x] Local service proxy — `.numa` domains with HTTP/HTTPS reverse proxy, auto TLS, WebSocket -- [ ] pkarr integration — resolve Ed25519 keys via Mainline DHT (15M nodes) +- [ ] pkarr integration — self-sovereign DNS via Mainline DHT (15M nodes) - [ ] Global `.numa` names — self-publish, DHT-backed, first-come-first-served -- [ ] Audit protocol — challenge-based verification of resolver honesty -- [ ] Numa Network — proof-of-service consensus, NUMA token, paid `.numa` domains -- [ ] `.onion` bridge — human-readable `.numa` names for Tor hidden services ## License diff --git a/src/ctx.rs b/src/ctx.rs index 18b00ec..cf485bd 100644 --- a/src/ctx.rs +++ b/src/ctx.rs @@ -150,8 +150,17 @@ pub async fn handle_query( ); let mut resp_buffer = BytePacketBuffer::new(); - response.write(&mut resp_buffer)?; - ctx.socket.send_to(resp_buffer.filled(), src_addr).await?; + if response.write(&mut resp_buffer).is_err() { + // Response too large for UDP — set TC bit and send header + question only + debug!("response too large, setting TC bit for {}", qname); + let mut tc_response = DnsPacket::response_from(&query, response.header.rescode); + tc_response.header.truncated_message = true; + let mut tc_buffer = BytePacketBuffer::new(); + tc_response.write(&mut tc_buffer)?; + ctx.socket.send_to(tc_buffer.filled(), src_addr).await?; + } else { + ctx.socket.send_to(resp_buffer.filled(), src_addr).await?; + } // Record stats and query log { diff --git a/src/forward.rs b/src/forward.rs index 63de394..5f8d25f 100644 --- a/src/forward.rs +++ b/src/forward.rs @@ -21,7 +21,11 @@ pub async fn forward_query( socket.send_to(send_buffer.filled(), upstream).await?; let mut recv_buffer = BytePacketBuffer::new(); - timeout(timeout_duration, socket.recv_from(&mut recv_buffer.buf)).await??; + let (size, _) = timeout(timeout_duration, socket.recv_from(&mut recv_buffer.buf)).await??; + + if size >= recv_buffer.buf.len() { + log::debug!("upstream response truncated ({} bytes, buffer {})", size, recv_buffer.buf.len()); + } DnsPacket::from_buffer(&mut recv_buffer) }