parent
c2325053a8
commit
f4d8dc278b
|
@ -46,6 +46,9 @@ pub const Address = extern union {
|
||||||
.path = undefined,
|
.path = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this enables us to have the proper length of the socket in getOsSockLen
|
||||||
|
mem.zero(&sock_addr.path);
|
||||||
|
|
||||||
if (path.len > sock_addr.path.len) return error.NameTooLong;
|
if (path.len > sock_addr.path.len) return error.NameTooLong;
|
||||||
mem.copy(u8, &sock_addr.path, path);
|
mem.copy(u8, &sock_addr.path, path);
|
||||||
|
|
||||||
|
@ -344,6 +347,10 @@ pub const Address = extern union {
|
||||||
switch (self.any.family) {
|
switch (self.any.family) {
|
||||||
os.AF_INET => return @sizeOf(os.sockaddr_in),
|
os.AF_INET => return @sizeOf(os.sockaddr_in),
|
||||||
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
|
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
|
||||||
|
os.AF_UNIX => blk: {
|
||||||
|
const path_len = std.mem.len(self.un.path.len);
|
||||||
|
break :blk @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
|
||||||
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1264,7 +1271,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const TcpServer = struct {
|
pub const StreamServer = struct {
|
||||||
/// Copied from `Options` on `init`.
|
/// Copied from `Options` on `init`.
|
||||||
kernel_backlog: u32,
|
kernel_backlog: u32,
|
||||||
|
|
||||||
|
@ -1282,21 +1289,21 @@ pub const TcpServer = struct {
|
||||||
|
|
||||||
/// After this call succeeds, resources have been acquired and must
|
/// After this call succeeds, resources have been acquired and must
|
||||||
/// be released with `deinit`.
|
/// be released with `deinit`.
|
||||||
pub fn init(options: Options) TcpServer {
|
pub fn init(options: Options) StreamServer {
|
||||||
return TcpServer{
|
return StreamServer{
|
||||||
.sockfd = null,
|
.sockfd = null,
|
||||||
.kernel_backlog = options.kernel_backlog,
|
.kernel_backlog = options.kernel_backlog,
|
||||||
.listen_address = undefined,
|
.listen_address = undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release all resources. The `TcpServer` memory becomes `undefined`.
|
/// Release all resources. The `StreamServer` memory becomes `undefined`.
|
||||||
pub fn deinit(self: *TcpServer) void {
|
pub fn deinit(self: *StreamServer) void {
|
||||||
self.close();
|
self.close();
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listen(self: *TcpServer, address: Address) !void {
|
pub fn listen(self: *StreamServer, address: Address) !void {
|
||||||
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
|
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
|
||||||
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
|
const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
|
||||||
const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP);
|
const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP);
|
||||||
|
@ -1315,7 +1322,7 @@ pub const TcpServer = struct {
|
||||||
/// Stop listening. It is still necessary to call `deinit` after stopping listening.
|
/// Stop listening. It is still necessary to call `deinit` after stopping listening.
|
||||||
/// Calling `deinit` will automatically call `close`. It is safe to call `close` when
|
/// Calling `deinit` will automatically call `close`. It is safe to call `close` when
|
||||||
/// not listening.
|
/// not listening.
|
||||||
pub fn close(self: *TcpServer) void {
|
pub fn close(self: *StreamServer) void {
|
||||||
if (self.sockfd) |fd| {
|
if (self.sockfd) |fd| {
|
||||||
os.close(fd);
|
os.close(fd);
|
||||||
self.sockfd = null;
|
self.sockfd = null;
|
||||||
|
@ -1343,7 +1350,7 @@ pub const TcpServer = struct {
|
||||||
} || os.UnexpectedError;
|
} || os.UnexpectedError;
|
||||||
|
|
||||||
/// If this function succeeds, the returned `fs.File` is a caller-managed resource.
|
/// If this function succeeds, the returned `fs.File` is a caller-managed resource.
|
||||||
pub fn accept(self: *TcpServer) AcceptError!fs.File {
|
pub fn accept(self: *StreamServer) AcceptError!fs.File {
|
||||||
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
|
const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
|
||||||
const accept_flags = nonblock | os.SOCK_CLOEXEC;
|
const accept_flags = nonblock | os.SOCK_CLOEXEC;
|
||||||
var accepted_addr: Address = undefined;
|
var accepted_addr: Address = undefined;
|
||||||
|
|
|
@ -93,7 +93,7 @@ test "listen on a port, send bytes, receive bytes" {
|
||||||
// TODO doing this at comptime crashed the compiler
|
// TODO doing this at comptime crashed the compiler
|
||||||
const localhost = net.Address.parseIp("127.0.0.1", 0);
|
const localhost = net.Address.parseIp("127.0.0.1", 0);
|
||||||
|
|
||||||
var server = net.TcpServer.init(net.TcpServer.Options{});
|
var server = net.StreamServer.init(net.StreamServer.Options{});
|
||||||
defer server.deinit();
|
defer server.deinit();
|
||||||
try server.listen(localhost);
|
try server.listen(localhost);
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ fn testClient(addr: net.Address) anyerror!void {
|
||||||
testing.expect(mem.eql(u8, msg, "hello from server\n"));
|
testing.expect(mem.eql(u8, msg, "hello from server\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testServer(server: *net.TcpServer) anyerror!void {
|
fn testServer(server: *net.StreamServer) anyerror!void {
|
||||||
var client_file = try server.accept();
|
var client_file = try server.accept();
|
||||||
|
|
||||||
const stream = &client_file.outStream().stream;
|
const stream = &client_file.outStream().stream;
|
||||||
|
|
Loading…
Reference in New Issue