aboutsummaryrefslogtreecommitdiff
path: root/src/http/async_socket.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/async_socket.zig')
-rw-r--r--src/http/async_socket.zig85
1 files changed, 43 insertions, 42 deletions
diff --git a/src/http/async_socket.zig b/src/http/async_socket.zig
index 43ac9f860..205940b2d 100644
--- a/src/http/async_socket.zig
+++ b/src/http/async_socket.zig
@@ -38,7 +38,7 @@ read_completion: AsyncIO.Completion = undefined,
connect_completion: AsyncIO.Completion = undefined,
close_completion: AsyncIO.Completion = undefined,
-const ConnectError = AsyncIO.ConnectError || std.os.SocketError || std.os.SetSockOptError || error{UnknownHostName};
+const ConnectError = AsyncIO.ConnectError || std.os.SocketError || std.os.SetSockOptError || error{ UnknownHostName, FailedToOpenSocket };
pub fn init(io: *AsyncIO, socket: std.os.socket_t, allocator: std.mem.Allocator) !AsyncSocket {
var head = AsyncMessage.get(allocator);
@@ -55,13 +55,18 @@ fn on_connect(this: *AsyncSocket, _: *Completion, err: ConnectError!void) void {
}
fn connectToAddress(this: *AsyncSocket, address: std.net.Address) ConnectError!void {
- const sockfd = AsyncIO.openSocket(address.any.family, OPEN_SOCKET_FLAGS | std.os.SOCK.STREAM, std.os.IPPROTO.TCP) catch |err| {
- if (extremely_verbose) {
- Output.prettyErrorln("openSocket error: {s}", .{@errorName(err)});
- }
+ const sockfd = if (this.socket > 0)
+ this.socket
+ else
+ AsyncIO.openSocket(address.any.family, OPEN_SOCKET_FLAGS | std.os.SOCK.STREAM, std.os.IPPROTO.TCP) catch |err| {
+ if (extremely_verbose) {
+ Output.prettyErrorln("openSocket error: {s}", .{@errorName(err)});
+ }
+ this.socket = 0;
- return error.ConnectionRefused;
- };
+ return error.FailedToOpenSocket;
+ };
+ this.socket = sockfd;
this.io.connect(*AsyncSocket, this, on_connect, &this.connect_completion, sockfd, address);
suspend {
@@ -71,9 +76,6 @@ fn connectToAddress(this: *AsyncSocket, address: std.net.Address) ConnectError!v
if (this.err) |e| {
return @errSetCast(ConnectError, e);
}
-
- this.socket = sockfd;
- return;
}
fn on_close(this: *AsyncSocket, _: *Completion, _: AsyncIO.CloseError!void) void {
@@ -82,58 +84,39 @@ fn on_close(this: *AsyncSocket, _: *Completion, _: AsyncIO.CloseError!void) void
pub fn close(this: *AsyncSocket) void {
if (this.socket == 0) return;
- this.io.close(*AsyncSocket, this, on_close, &this.close_completion, this.socket);
+ const to_close = this.socket;
+ this.socket = 0;
+ this.io.close(*AsyncSocket, this, on_close, &this.close_completion, to_close);
suspend {
this.close_frame = @frame().*;
}
- this.socket = 0;
}
pub fn connect(this: *AsyncSocket, name: []const u8, port: u16) ConnectError!void {
- this.socket = 0;
+ this.close();
+
outer: while (true) {
// on macOS, getaddrinfo() is very slow
// If you send ~200 network requests, about 1.5s is spent on getaddrinfo()
// So, we cache this.
- var address_list = NetworkThread.getAddressList(getAllocator(), name, port) catch |err| {
+ var list = NetworkThread.getAddressList(getAllocator(), name, port) catch |err| {
return @errSetCast(ConnectError, err);
};
- const list = address_list.address_list;
if (list.addrs.len == 0) return error.ConnectionRefused;
- try_cached_index: {
- if (address_list.index) |i| {
- const address = list.addrs[i];
- if (address_list.invalidated) continue :outer;
-
- this.connectToAddress(address) catch |err| {
- if (err == error.ConnectionRefused) {
- address_list.index = null;
- break :try_cached_index;
- }
-
- address_list.invalidate();
- continue :outer;
- };
- }
- }
-
- for (list.addrs) |address, i| {
- if (address_list.invalidated) continue :outer;
+ for (list.addrs) |address| {
this.connectToAddress(address) catch |err| {
+ this.close();
+
if (err == error.ConnectionRefused) continue;
- address_list.invalidate();
if (err == error.AddressNotAvailable or err == error.UnknownHostName) continue :outer;
- return err;
};
- address_list.index = @truncate(u32, i);
return;
}
- if (address_list.invalidated) continue :outer;
+ this.close();
- address_list.invalidate();
return error.ConnectionRefused;
}
}
@@ -201,6 +184,7 @@ pub fn deinit(this: *AsyncSocket) void {
this.sent = 0;
this.read_context = &[_]u8{};
this.read_offset = 0;
+ this.socket = 0;
}
pub fn send(this: *AsyncSocket) SendError!usize {
@@ -423,6 +407,16 @@ pub const SSL = struct {
}
pub fn close(this: *SSL) void {
+ if (this.ssl_loaded) {
+ this.ssl.shutdown();
+ this.ssl.deinit();
+ this.ssl_loaded = false;
+ }
+
+ if (this.ssl_bio_loaded) {
+ this.ssl_bio.socket_fd = 0;
+ }
+
this.socket.close();
}
@@ -796,7 +790,7 @@ pub const SSL = struct {
this.socket.deinit();
if (this.ssl_loaded) {
- _ = boring.SSL_shutdown(this.ssl);
+ this.ssl.shutdown();
this.ssl.deinit();
this.ssl_loaded = false;
}
@@ -805,13 +799,18 @@ pub const SSL = struct {
this.ssl_bio_loaded = false;
if (this.ssl_bio.recv_buffer) |recv| {
recv.release();
- this.ssl_bio.recv_buffer = null;
}
+ this.ssl_bio.recv_buffer = null;
if (this.ssl_bio.send_buffer) |recv| {
recv.release();
- this.ssl_bio.send_buffer = null;
}
+ this.ssl_bio.send_buffer = null;
+
+ if (this.ssl_bio.bio) |bio| {
+ bio.deinit();
+ }
+ this.ssl_bio.bio = null;
this.ssl_bio.pending_reads = 0;
this.ssl_bio.pending_sends = 0;
@@ -824,6 +823,8 @@ pub const SSL = struct {
this.ssl_bio.socket_fd = 0;
this.ssl_bio.onReady = null;
+ } else {
+ this.ssl_bio = undefined;
}
this.handshake_complete = false;