in source/posix/socket.c [876:1005]
static void s_socket_accept_event(
struct aws_event_loop *event_loop,
struct aws_io_handle *handle,
int events,
void *user_data) {
(void)event_loop;
struct aws_socket *socket = user_data;
struct posix_socket *socket_impl = socket->impl;
AWS_LOGF_DEBUG(
AWS_LS_IO_SOCKET, "id=%p fd=%d: listening event received", (void *)socket, socket->io_handle.data.fd);
if (socket_impl->continue_accept && events & AWS_IO_EVENT_TYPE_READABLE) {
int in_fd = 0;
while (socket_impl->continue_accept && in_fd != -1) {
struct sockaddr_storage in_addr;
socklen_t in_len = sizeof(struct sockaddr_storage);
in_fd = accept(handle->data.fd, (struct sockaddr *)&in_addr, &in_len);
if (in_fd == -1) {
int error = errno;
if (error == EAGAIN || error == EWOULDBLOCK) {
break;
}
int aws_error = aws_socket_get_error(socket);
aws_raise_error(aws_error);
s_on_connection_error(socket, aws_error);
break;
}
AWS_LOGF_DEBUG(
AWS_LS_IO_SOCKET, "id=%p fd=%d: incoming connection", (void *)socket, socket->io_handle.data.fd);
struct aws_socket *new_sock = aws_mem_acquire(socket->allocator, sizeof(struct aws_socket));
if (!new_sock) {
close(in_fd);
s_on_connection_error(socket, aws_last_error());
continue;
}
if (s_socket_init(new_sock, socket->allocator, &socket->options, in_fd)) {
aws_mem_release(socket->allocator, new_sock);
s_on_connection_error(socket, aws_last_error());
continue;
}
new_sock->local_endpoint = socket->local_endpoint;
new_sock->state = CONNECTED_READ | CONNECTED_WRITE;
uint16_t port = 0;
/* get the info on the incoming socket's address */
if (in_addr.ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in *)&in_addr;
port = ntohs(s->sin_port);
/* this came from the kernel, a.) it won't fail. b.) even if it does
* its not fatal. come back and add logging later. */
if (!inet_ntop(
AF_INET,
&s->sin_addr,
new_sock->remote_endpoint.address,
sizeof(new_sock->remote_endpoint.address))) {
AWS_LOGF_WARN(
AWS_LS_IO_SOCKET,
"id=%p fd=%d:. Failed to determine remote address.",
(void *)socket,
socket->io_handle.data.fd)
}
new_sock->options.domain = AWS_SOCKET_IPV4;
} else if (in_addr.ss_family == AF_INET6) {
/* this came from the kernel, a.) it won't fail. b.) even if it does
* its not fatal. come back and add logging later. */
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&in_addr;
port = ntohs(s->sin6_port);
if (!inet_ntop(
AF_INET6,
&s->sin6_addr,
new_sock->remote_endpoint.address,
sizeof(new_sock->remote_endpoint.address))) {
AWS_LOGF_WARN(
AWS_LS_IO_SOCKET,
"id=%p fd=%d:. Failed to determine remote address.",
(void *)socket,
socket->io_handle.data.fd)
}
new_sock->options.domain = AWS_SOCKET_IPV6;
} else if (in_addr.ss_family == AF_UNIX) {
new_sock->remote_endpoint = socket->local_endpoint;
new_sock->options.domain = AWS_SOCKET_LOCAL;
}
new_sock->remote_endpoint.port = port;
AWS_LOGF_INFO(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: connected to %s:%d, incoming fd %d",
(void *)socket,
socket->io_handle.data.fd,
new_sock->remote_endpoint.address,
new_sock->remote_endpoint.port,
in_fd);
int flags = fcntl(in_fd, F_GETFL, 0);
flags |= O_NONBLOCK | O_CLOEXEC;
fcntl(in_fd, F_SETFL, flags);
bool close_occurred = false;
socket_impl->close_happened = &close_occurred;
socket->accept_result_fn(socket, AWS_ERROR_SUCCESS, new_sock, socket->connect_accept_user_data);
if (close_occurred) {
return;
}
socket_impl->close_happened = NULL;
}
}
AWS_LOGF_TRACE(
AWS_LS_IO_SOCKET,
"id=%p fd=%d: finished processing incoming connections, "
"waiting on event-loop notification",
(void *)socket,
socket->io_handle.data.fd);
}