in source/posix/socket.c [268:392]
static int s_on_connection_success(struct aws_socket *socket) {
struct aws_event_loop *event_loop = socket->event_loop;
struct posix_socket *socket_impl = socket->impl;
if (socket_impl->currently_subscribed) {
aws_event_loop_unsubscribe_from_io_events(socket->event_loop, &socket->io_handle);
socket_impl->currently_subscribed = false;
}
socket->event_loop = NULL;
int connect_result;
socklen_t result_length = sizeof(connect_result);
if (getsockopt(socket->io_handle.data.fd, SOL_SOCKET, SO_ERROR, &connect_result, &result_length) < 0) {
AWS_LOGF_ERROR(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: failed to determine connection error %d",
(void *)socket,
socket->io_handle.data.fd,
errno);
int aws_error = s_determine_socket_error(errno);
aws_raise_error(aws_error);
s_on_connection_error(socket, aws_error);
return AWS_OP_ERR;
}
if (connect_result) {
AWS_LOGF_ERROR(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: connection error %d",
(void *)socket,
socket->io_handle.data.fd,
connect_result);
int aws_error = s_determine_socket_error(connect_result);
aws_raise_error(aws_error);
s_on_connection_error(socket, aws_error);
return AWS_OP_ERR;
}
AWS_LOGF_INFO(AWS_LS_IO_SOCKET, "id=%p fd=%d: connection success", (void *)socket, socket->io_handle.data.fd);
struct sockaddr_storage address;
AWS_ZERO_STRUCT(address);
socklen_t address_size = sizeof(address);
if (!getsockname(socket->io_handle.data.fd, (struct sockaddr *)&address, &address_size)) {
uint16_t port = 0;
if (address.ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in *)&address;
port = ntohs(s->sin_port);
/* this comes straight from the kernal. a.) they won't fail. b.) even if they do, it's not fatal
* once we add logging, we can log this if it fails. */
if (inet_ntop(
AF_INET, &s->sin_addr, socket->local_endpoint.address, sizeof(socket->local_endpoint.address))) {
AWS_LOGF_DEBUG(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: local endpoint %s:%d",
(void *)socket,
socket->io_handle.data.fd,
socket->local_endpoint.address,
port);
} else {
AWS_LOGF_WARN(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: determining local endpoint failed",
(void *)socket,
socket->io_handle.data.fd);
}
} else if (address.ss_family == AF_INET6) {
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&address;
port = ntohs(s->sin6_port);
/* this comes straight from the kernal. a.) they won't fail. b.) even if they do, it's not fatal
* once we add logging, we can log this if it fails. */
if (inet_ntop(
AF_INET6, &s->sin6_addr, socket->local_endpoint.address, sizeof(socket->local_endpoint.address))) {
AWS_LOGF_DEBUG(
AWS_LS_IO_SOCKET,
"id=%p fd %d: local endpoint %s:%d",
(void *)socket,
socket->io_handle.data.fd,
socket->local_endpoint.address,
port);
} else {
AWS_LOGF_WARN(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: determining local endpoint failed",
(void *)socket,
socket->io_handle.data.fd);
}
}
socket->local_endpoint.port = port;
} else {
AWS_LOGF_ERROR(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: getsockname() failed with error %d",
(void *)socket,
socket->io_handle.data.fd,
errno);
int aws_error = s_determine_socket_error(errno);
aws_raise_error(aws_error);
s_on_connection_error(socket, aws_error);
return AWS_OP_ERR;
}
socket->state = CONNECTED_WRITE | CONNECTED_READ;
if (aws_socket_assign_to_event_loop(socket, event_loop)) {
AWS_LOGF_ERROR(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: assignment to event loop %p failed with error %d",
(void *)socket,
socket->io_handle.data.fd,
(void *)event_loop,
aws_last_error());
s_on_connection_error(socket, aws_last_error());
return AWS_OP_ERR;
}
socket->connection_result_fn(socket, AWS_ERROR_SUCCESS, socket->connect_accept_user_data);
return AWS_OP_SUCCESS;
}