string hosts in net.*

This commit is contained in:
2026-06-07 09:33:26 +02:00
parent a727a52ffb
commit a9bd4fe9f9
8 changed files with 109 additions and 71 deletions

View File

@@ -10,7 +10,7 @@ const DNS_TYPE_A = 1
const DNS_CLASS_IN = 1
const DNS_RECURSION_DESIRED = 256
func net.listen[packed_host: i64, port: i64] : i64, bool
func net.listen[host: str, port: i64] : i64, bool
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
if s < 0
return -1, false
@@ -19,6 +19,10 @@ func net.listen[packed_host: i64, port: i64] : i64, bool
if _builtin_syscall(SYS_setsockopt, s, SOL_SOCKET, SO_REUSEADDR, ^optval, 8) < 0
_builtin_syscall(SYS_close, s)
return -1, false
~packed_host, ok := net.resolve(host)
if !ok
return -1, false
sa := _stackalloc(16)
net._build_sa(sa, packed_host, port)
@@ -33,10 +37,14 @@ func net.listen[packed_host: i64, port: i64] : i64, bool
return s, true
func net.connect[packed_host: i64, port: i64] : i64, bool
func net.connect[host: str, port: i64] : i64, bool
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
if s < 0
return -1, false
~packed_host, ok := net.resolve(host)
if !ok
return -1, false
sa := _stackalloc(16)
net._build_sa(sa, packed_host, port)
@@ -91,22 +99,26 @@ func net.UDPSocket.receive[s: net.UDPSocket, size: i64] : net.UDPPacket
func net.UDPSocket.close_and_free[s: net.UDPSocket] : void
_builtin_syscall(SYS_close, s->fd)
s->addr->free()
(s as ptr)->free()
mem.free(s)
func net.create_udp_client[packed_host: i64, port: i64] : net.UDPSocket, bool
func net.create_udp_client[host: str, port: i64] : net.UDPSocket, bool
s := new* net.UDPSocket
~packed_host, ok := net.resolve(host)
if !ok
return 0 as net.UDPSocket, false
s->fd = _builtin_syscall(SYS_socket, AF_INET, SOCK_DGRAM, 0)
if s->fd < 0
s->close_and_free()
mem.free(s)
return 0 as net.UDPSocket, false
s->addr = mem.alloc(16)
net._build_sa(s->addr, packed_host, port)
return s, true
func net.create_udp_server[packed_host: i64, port: i64] : net.UDPSocket, bool
~s, ok := net.create_udp_client(packed_host, port)
func net.create_udp_server[host: str, port: i64] : net.UDPSocket, bool
~s, ok := net.create_udp_client(host, port)
if !ok
return 0 as net.UDPSocket, false
@@ -127,7 +139,61 @@ struct net.UDPPacket
func net.UDPPacket.free[pkt: net.UDPPacket] : void
pkt->data->free()
pkt->source_addr->free()
(pkt as ptr)->free()
mem.free(pkt)
func net.resolve[domain: str] : i64, bool
// if domain is already an ip, skip dns resolution
parts := domain->split(".")
if parts->size == 4
valid := true
for i in 0..4
p := parts->nth(i) as str
if p->len() < 1 || p->len() > 3
valid = false
break
for j in 0..p->len()
if !p[j]->is_digit()
valid = false
break
if !valid
break
if valid
a := (parts->nth(0) as str)->parse_i64()
b := (parts->nth(1) as str)->parse_i64()
c := (parts->nth(2) as str)->parse_i64()
d := (parts->nth(3) as str)->parse_i64()
if a >= 0 && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0 && d <= 255
parts->free_with_items()
return net.pack_addr(a, b, c, d), true
parts->free_with_items()
query := net.build_dns_query(domain, DNS_TYPE_A)
// TODO: this probably shouldnt be hardcoded
~s, ok := net.create_udp_client("1.1.1.1", 53)
if !ok
query->free()
return -1, false
s->send_to(s->addr, query->data, query->size)
query->free()
pkt := s->receive(1024)
s->close_and_free()
// TODO: do actual parsing
pos := 12 // skip header (12 bytes)
while pkt->data[pos] != 0
pos += pkt->data[pos] + 1 // skip question
pos += 5 // skip null byte, type(2), class(2)
pos += 12 // skip name(2), type(2), class(2), ttl(4), rdlength(2)
out := net.pack_addr(pkt->data[pos] as i64, pkt->data[pos+1] as i64, pkt->data[pos+2] as i64, pkt->data[pos+3] as i64)
pkt->free()
return out, true
func net.encode_dns_name[domain: str] : Blob
domain_len := domain->len()
@@ -168,33 +234,3 @@ func net.build_dns_query[domain_name: str, record_type: i64] : Blob
name->free()
return out
// TODO: dont resolve if its already an IP
func net.resolve[domain: str] : i64, bool
query := net.build_dns_query(domain, DNS_TYPE_A)
// TODO: this probably shouldnt be hardcoded
~s, ok := net.create_udp_client(net.pack_addr(1, 1, 1, 1), 53)
if !ok
query->free()
return -1, false
s->send_to(s->addr, query->data, query->size)
query->free()
pkt := s->receive(1024)
s->close_and_free()
// TODO: do actual parsing
pos := 12 // skip header (12 bytes)
while pkt->data[pos] != 0
pos += pkt->data[pos] + 1 // skip question
pos += 5 // skip null byte, type(2), class(2)
pos += 12 // skip name(2), type(2), class(2), ttl(4), rdlength(2)
out := net.pack_addr(pkt->data[pos] as i64, pkt->data[pos+1] as i64, pkt->data[pos+2] as i64, pkt->data[pos+3] as i64)
pkt->free()
return out, true