diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92167d7..366ab3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v4 - uses: goto-bus-stop/setup-zig@v2 with: - version: master + version: 0.12.0 - run: zig fmt --check *.zig src/*.zig test: @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v4 - uses: goto-bus-stop/setup-zig@v2 with: - version: master + version: 0.12.0 - run: zig build test macos-with-openssl: diff --git a/README.md b/README.md index ef56b98..b12f941 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # tls13-zig -The first TLS1.3 implementation in Zig(master/HEAD) only with std. +The first TLS1.3 implementation in Zig(0.12.0) only with std. This repository is an experimental implementation and is not intended for production use. diff --git a/examples/proxy/build.zig b/examples/proxy/build.zig index c23b48e..db493f2 100644 --- a/examples/proxy/build.zig +++ b/examples/proxy/build.zig @@ -18,8 +18,9 @@ pub fn build(b: *std.Build) void { .target = target, .optimize = optimize, }); - exe.addAnonymousModule("tls13-server", .{ - .source_file = .{ .path = "../../src/server.zig" }, + + exe.root_module.addAnonymousImport("tls13-server", .{ + .root_source_file = .{ .path = "../../src/server.zig" }, }); // This declares intent for the executable to be installed into the // standard location when the user invokes the "install" step (the default diff --git a/examples/proxy/src/main.zig b/examples/proxy/src/main.zig index 5083b05..e5b1de7 100644 --- a/examples/proxy/src/main.zig +++ b/examples/proxy/src/main.zig @@ -1,7 +1,7 @@ const std = @import("std"); const net = std.net; const io = std.io; -const os = std.os; +const posix = std.posix; const allocator = std.heap.page_allocator; const server = @import("tls13-server"); @@ -9,12 +9,12 @@ const log = server.log; pub fn main() !void { // ignore SIGCHLD - var act = os.Sigaction{ - .handler = .{ .handler = os.SIG.IGN }, - .mask = os.empty_sigset, - .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND), + var act = posix.Sigaction{ + .handler = .{ .handler = posix.SIG.IGN }, + .mask = posix.empty_sigset, + .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND), }; - try os.sigaction(os.SIG.CHLD, &act, null); + try posix.sigaction(posix.SIG.CHLD, &act, null); const key_file = try getenvWithError("PROXY_TLS_KEYFILE"); const cert_file = try getenvWithError("PROXY_TLS_CERTFILE"); @@ -34,7 +34,7 @@ pub fn main() !void { while (true) { var con = try tls_server.accept(); defer con.deinit(); - const fork_pid = std.os.fork() catch { + const fork_pid = posix.fork() catch { log.err("fork failed", .{}); return; }; @@ -55,15 +55,15 @@ pub fn main() !void { var conStream = try net.tcpConnectToHost(allocator, upstream_host, upstream_port); defer conStream.close(); - var fds: [2]std.os.pollfd = undefined; + var fds: [2]posix.pollfd = undefined; fds[0] = .{ .fd = con.tcp_conn.?.stream.handle, - .events = std.os.POLL.IN, + .events = posix.POLL.IN, .revents = undefined, }; fds[1] = .{ .fd = conStream.handle, - .events = std.os.POLL.IN, + .events = posix.POLL.IN, .revents = undefined, }; @@ -71,12 +71,12 @@ pub fn main() !void { var req_done = false; var sendBuf = std.io.bufferedWriter(conStream.writer()); while (true) { - _ = try std.os.poll(&fds, -1); + _ = try posix.poll(&fds, -1); log.debug("poll done", .{}); var recv_bytes: [16 * 1024]u8 = undefined; var tmp_buf: [16 * 1024]u8 = undefined; - if ((fds[0].revents & std.os.POLL.IN) > 0) { + if ((fds[0].revents & posix.POLL.IN) > 0) { while (true) { const line = con.tlsReader().readUntilDelimiter(&tmp_buf, '\n') catch |err| { log.err("failed to read({})", .{err}); @@ -116,7 +116,7 @@ pub fn main() !void { try sendBuf.flush(); req_done = false; } - } else if ((fds[1].revents & std.os.POLL.IN) > 0) { + } else if ((fds[1].revents & posix.POLL.IN) > 0) { const recv_size = try conStream.read(&recv_bytes); if (recv_size == 0) { log.info("upstream connection closed", .{}); @@ -133,7 +133,7 @@ pub fn main() !void { } fn getenvWithError(key: []const u8) ![]const u8 { - const res = std.os.getenv(key); + const res = posix.getenv(key); if (res) |r| { return r; } else { diff --git a/install_zig.sh b/install_zig.sh index 98bd59b..35113e4 100755 --- a/install_zig.sh +++ b/install_zig.sh @@ -10,18 +10,19 @@ case "$unames" in *) echo "Unknown HOST_ARCH=$(uname -s)"; exit 1;; esac +ZIG_VERSION=0.12.0 ZIG_VERSIONS=$(curl https://ziglang.org/download/index.json) -ZIG_MASTER_TAR=$(echo $ZIG_VERSIONS | jq -r ".master.\"$HOST_ARCH\".tarball") -ZIG_MASTER_SHA256=$(echo $ZIG_VERSIONS | jq -r ".master.\"$HOST_ARCH\".shasum") +ZIG_MASTER_TAR=$(echo $ZIG_VERSIONS | jq -r ".\"$ZIG_VERSION\".\"$HOST_ARCH\".tarball") +ZIG_MASTER_SHA256=$(echo $ZIG_VERSIONS | jq -r ".\"$ZIG_VERSION\".\"$HOST_ARCH\".shasum") -ZIG_TAR_NAME="zig-master.tar.xz" +ZIG_TAR_NAME="zig-$ZIG_VERSION.tar.xz" if [ -e $ZIG_TAR_NAME ]; then rm $ZIG_TAR_NAME fi -curl $ZIG_MASTER_TAR -o zig-master.tar.xz +curl $ZIG_MASTER_TAR -o $ZIG_TAR_NAME TAR_SHA256=$(shasum -a 256 $ZIG_TAR_NAME | awk '{print $1}') if [ "$TAR_SHA256" != "$ZIG_MASTER_SHA256" ]; then echo "Invalid SHASUM!" diff --git a/src/client.zig b/src/client.zig index d415c89..59f2271 100644 --- a/src/client.zig +++ b/src/client.zig @@ -254,7 +254,7 @@ pub fn TLSClientImpl(comptime ReaderType: type, comptime WriterType: type, compt p.deinit(); } if (self.tcp_client) |tc| { - std.os.shutdown(tc.handle, .both) catch |err| { + std.posix.shutdown(tc.handle, .both) catch |err| { log.warn("failed to shutdown tcp client err={}", .{err}); }; } @@ -373,7 +373,7 @@ pub fn TLSClientImpl(comptime ReaderType: type, comptime WriterType: type, compt if (list.addrs.len == 0) return error.UnknownHostName; for (list.addrs) |addr| { - if (addr.any.family != std.os.AF.INET) { + if (addr.any.family != std.posix.AF.INET) { continue; } // TODO: ipv6 @@ -391,7 +391,7 @@ pub fn TLSClientImpl(comptime ReaderType: type, comptime WriterType: type, compt return; } - return std.os.ConnectError.ConnectionRefused; + return std.posix.ConnectError.ConnectionRefused; } pub fn connect(self: *Self, host: []const u8, port: u16) !void { @@ -531,7 +531,7 @@ pub fn TLSClientImpl(comptime ReaderType: type, comptime WriterType: type, compt pub fn close(self: *Self) !void { defer { if (self.tcp_client) |tc| { - std.os.shutdown(tc.handle, .both) catch { + std.posix.shutdown(tc.handle, .both) catch { //TODO Error handle }; } diff --git a/src/main_test_server.zig b/src/main_test_server.zig index 70bace4..ce86a2a 100644 --- a/src/main_test_server.zig +++ b/src/main_test_server.zig @@ -1,6 +1,6 @@ const std = @import("std"); const log = @import("log.zig"); -const os = std.os; +const posix = std.posix; const server = @import("server.zig"); @@ -15,12 +15,12 @@ fn handler_sigchld(signum: c_int) callconv(.C) void { pub fn do(fork: bool, allocator: std.mem.Allocator) !void { // ignore SIGCHLD - var act = os.Sigaction{ + var act = posix.Sigaction{ .handler = .{ .handler = handler_sigchld }, - .mask = os.empty_sigset, - .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND), + .mask = posix.empty_sigset, + .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND), }; - try os.sigaction(os.SIG.CHLD, &act, null); + try posix.sigaction(posix.SIG.CHLD, &act, null); log.info("started.", .{}); @@ -41,7 +41,7 @@ pub fn do(fork: bool, allocator: std.mem.Allocator) !void { var con = try tls_server.accept(); defer con.deinit(); if (fork) { - const fork_pid = std.os.fork() catch { + const fork_pid = std.posix.fork() catch { log.err("fork failed", .{}); return; }; diff --git a/src/server.zig b/src/server.zig index 3ea39f2..4955dce 100644 --- a/src/server.zig +++ b/src/server.zig @@ -1,6 +1,6 @@ const std = @import("std"); const io = std.io; -const os = std.os; +const posix = std.posix; const net = std.net; const dh = std.crypto.dh; const expect = std.testing.expect; @@ -58,7 +58,7 @@ pub fn TLSServerImpl(comptime ReaderType: type, comptime WriterType: type, compt _ = WriterType; return struct { // io - tcp_listener: ?std.net.StreamServer = null, + tcp_listener: ?std.net.Server = null, // host host: []u8 = &([_]u8{}), @@ -95,12 +95,12 @@ pub fn TLSServerImpl(comptime ReaderType: type, comptime WriterType: type, compt pub fn init(key_path: []const u8, cert_path: []const u8, ca_path: ?[]const u8, host: ?[]const u8, allocator: std.mem.Allocator) !Self { // ignore SIGPIPE - var act = os.Sigaction{ - .handler = .{ .handler = os.SIG.IGN }, - .mask = os.empty_sigset, - .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND), + var act = posix.Sigaction{ + .handler = .{ .handler = posix.SIG.IGN }, + .mask = posix.empty_sigset, + .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND), }; - try os.sigaction(os.SIG.PIPE, &act, null); + try posix.sigaction(posix.SIG.PIPE, &act, null); const cert = try certificate.CertificateEntry.fromFile(cert_path, allocator); errdefer cert.deinit(); @@ -146,17 +146,12 @@ pub fn TLSServerImpl(comptime ReaderType: type, comptime WriterType: type, compt @memcpy(res.host, h); } - if (is_tcp) { - res.tcp_listener = std.net.StreamServer.init(.{}); - res.tcp_listener.?.reuse_address = true; - } - return res; } pub fn deinit(self: *Self) void { if (self.tcp_listener) |_| { - self.tcp_listener.?.close(); + self.tcp_listener.?.deinit(); } if (self.host.len != 0) { self.allocator.free(self.host); @@ -171,7 +166,9 @@ pub fn TLSServerImpl(comptime ReaderType: type, comptime WriterType: type, compt pub fn listen(self: *Self, port: u16) !void { if (is_tcp) { - try self.tcp_listener.?.listen(try std.net.Address.parseIp("0.0.0.0", port)); + const listen_addr = try std.net.Address.parseIp("0.0.0.0", port); + const listen_opts = std.net.Address.ListenOptions{ .reuse_address = true }; + self.tcp_listener = try listen_addr.listen(listen_opts); } } @@ -199,7 +196,7 @@ pub fn TLSStreamImpl(comptime ReaderType: type, comptime WriterType: type, compt reader: ReaderType, writer: WriterType, write_buffer: io.BufferedWriter(4096, WriterType), - tcp_conn: ?std.net.StreamServer.Connection = null, + tcp_conn: ?std.net.Server.Connection = null, // session related random: [32]u8, @@ -275,7 +272,7 @@ pub fn TLSStreamImpl(comptime ReaderType: type, comptime WriterType: type, compt return .{ .context = self }; } - pub fn init(server: TLSServerType, tcp_conn: std.net.StreamServer.Connection, allocator: std.mem.Allocator) !Self { + pub fn init(server: TLSServerType, tcp_conn: std.net.Server.Connection, allocator: std.mem.Allocator) !Self { if (!is_tcp) { return Error.NotTCP; } diff --git a/src/utils.zig b/src/utils.zig index 276168f..be2669a 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -27,10 +27,10 @@ test "intToEnum" { } pub fn setReadTimeout(self: std.net.Stream, milliseconds: usize) !void { - const timeout = std.os.timeval{ + const timeout = std.posix.timeval{ .tv_sec = @as(i32, @intCast(milliseconds / std.time.ms_per_s)), .tv_usec = @as(i32, @intCast((milliseconds % std.time.ms_per_s) * std.time.us_per_ms)), }; - return std.os.setsockopt(self.handle, std.os.SOL.SOCKET, std.os.SO.RCVTIMEO, std.mem.asBytes(&timeout)); + return std.posix.setsockopt(self.handle, std.posix.SOL.SOCKET, std.posix.SO.RCVTIMEO, std.mem.asBytes(&timeout)); }