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:
Jarred Sumner
2023-09-30 22:59:42 -07:00
committed by GitHub
parent 8775d37559
commit e020ecec15
2 changed files with 46 additions and 19 deletions

View File

@@ -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;
}

View File

@@ -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;