mirror of
https://github.com/oven-sh/bun
synced 2026-02-13 20:39:05 +00:00
Fix bug causing "Connection Refused" errors (#6206)
* Loop through the return values of getaddrinfo * Remove incorrect assertion * Remove extra check * Remove extra check * Update bsd.c * More consistent --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
@@ -665,9 +665,39 @@ int bsd_udp_packet_buffer_ecn(void *msgvec, int index) {
|
||||
return 0; // no ecn defaults to 0
|
||||
}
|
||||
|
||||
static int bsd_do_connect(struct addrinfo *result, int fd)
|
||||
static int bsd_do_connect_raw(struct addrinfo *rp, int fd)
|
||||
{
|
||||
return connect(fd, result->ai_addr, (socklen_t) result->ai_addrlen);
|
||||
do {
|
||||
if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0 || errno == EINPROGRESS) {
|
||||
return 0;
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
|
||||
return LIBUS_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
static int bsd_do_connect(struct addrinfo *rp, int *fd)
|
||||
{
|
||||
while (rp != NULL) {
|
||||
if (bsd_do_connect_raw(rp, *fd) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
rp = rp->ai_next;
|
||||
bsd_close_socket(*fd);
|
||||
|
||||
if (rp == NULL) {
|
||||
return LIBUS_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
int resultFd = bsd_create_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (resultFd < 0) {
|
||||
return LIBUS_SOCKET_ERROR;
|
||||
}
|
||||
*fd = resultFd;
|
||||
}
|
||||
|
||||
return LIBUS_SOCKET_ERROR;
|
||||
}
|
||||
|
||||
LIBUS_SOCKET_DESCRIPTOR bsd_create_connect_socket(const char *host, int port, const char *source_host, int options) {
|
||||
@@ -700,18 +730,21 @@ LIBUS_SOCKET_DESCRIPTOR bsd_create_connect_socket(const char *host, int port, co
|
||||
return LIBUS_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if (bsd_do_connect(result, fd) != 0 && errno != EINPROGRESS) {
|
||||
|
||||
if (bsd_do_connect_raw(result, fd) != 0) {
|
||||
bsd_close_socket(fd);
|
||||
freeaddrinfo(result);
|
||||
return LIBUS_SOCKET_ERROR;
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
|
||||
} else {
|
||||
if (bsd_do_connect(result, &fd) != 0) {
|
||||
freeaddrinfo(result);
|
||||
return LIBUS_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
@@ -1343,7 +1343,7 @@ pub const InternalState = struct {
|
||||
return this.transfer_encoding == Encoding.chunked;
|
||||
}
|
||||
|
||||
pub fn reset(this: *InternalState, buffering: bool, allocator: std.mem.Allocator) void {
|
||||
pub fn reset(this: *InternalState, allocator: std.mem.Allocator) void {
|
||||
this.compressed_body.deinit();
|
||||
this.response_message_buffer.deinit();
|
||||
|
||||
@@ -1354,12 +1354,6 @@ pub const InternalState = struct {
|
||||
reader.deinit();
|
||||
}
|
||||
|
||||
if (!buffering) {
|
||||
// if we are holding a cloned_metadata we need to deinit it
|
||||
// this should never happen because we should always return the metadata to the user
|
||||
std.debug.assert(this.cloned_metadata == null);
|
||||
}
|
||||
|
||||
// just in case we check and free to avoid leaks
|
||||
if (this.cloned_metadata != null) {
|
||||
this.cloned_metadata.?.deinit(allocator);
|
||||
@@ -2186,7 +2180,7 @@ pub fn doRedirect(this: *HTTPClient) void {
|
||||
this.fail(error.TooManyRedirects);
|
||||
return;
|
||||
}
|
||||
this.state.reset(this.signals.isEmpty(), this.allocator);
|
||||
this.state.reset(this.allocator);
|
||||
// also reset proxy to redirect
|
||||
this.proxy_tunneling = false;
|
||||
if (this.proxy_tunnel != null) {
|
||||
@@ -2907,7 +2901,7 @@ fn fail(this: *HTTPClient, err: anyerror) void {
|
||||
_ = socket_async_http_abort_tracker.swapRemove(this.async_http_id);
|
||||
}
|
||||
|
||||
this.state.reset(this.signals.isEmpty(), this.allocator);
|
||||
this.state.reset(this.allocator);
|
||||
this.proxy_tunneling = false;
|
||||
|
||||
this.state.request_stage = .fail;
|
||||
@@ -2993,7 +2987,7 @@ pub fn progressUpdate(this: *HTTPClient, comptime is_ssl: bool, ctx: *NewHTTPCon
|
||||
socket.close(0, null);
|
||||
}
|
||||
|
||||
this.state.reset(this.signals.isEmpty(), this.allocator);
|
||||
this.state.reset(this.allocator);
|
||||
this.state.response_stage = .done;
|
||||
this.state.request_stage = .done;
|
||||
this.state.stage = .done;
|
||||
|
||||
Reference in New Issue
Block a user