#ifdef LIBUS_USE_IO_URING
#include "libusockets.h"
#include "internal/internal.h"
#include "internal.h"
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
void us_listen_socket_close(int ssl, struct us_listen_socket_t *ls) {
}
void us_socket_context_close(int ssl, struct us_socket_context_t *context) {
}
void us_internal_socket_context_unlink_listen_socket(struct us_socket_context_t *context, struct us_listen_socket_t *ls) {
}
void us_internal_socket_context_unlink_socket(struct us_socket_context_t *context, struct us_socket_t *s) {
}
struct us_socket_t *us_socket_context_adopt_socket(int ssl, struct us_socket_context_t *context, struct us_socket_t *s, int ext_size) {
s->context = context;
return s;
}
void us_internal_socket_context_link_listen_socket(struct us_socket_context_t *context, struct us_listen_socket_t *ls) {
}
void us_internal_socket_context_link_socket(struct us_socket_context_t *context, struct us_socket_t *s) {
}
struct us_loop_t *us_socket_context_loop(int ssl, struct us_socket_context_t *context) {
return context->loop;
}
void *us_socket_context_find_server_name_userdata(int ssl, struct us_socket_context_t *context, const char *hostname_pattern) {
return 0;
}
void *us_socket_server_name_userdata(int ssl, struct us_socket_t *s) {
return 0;
}
void us_socket_context_add_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern, struct us_socket_context_options_t options, void *user) {
}
void us_socket_context_remove_server_name(int ssl, struct us_socket_context_t *context, const char *hostname_pattern) {
}
void us_socket_context_on_server_name(int ssl, struct us_socket_context_t *context, void (*cb)(struct us_socket_context_t *, const char *hostname)) {
}
void *us_socket_context_get_native_handle(int ssl, struct us_socket_context_t *context) {
return 0;
}
struct us_socket_context_t *us_create_socket_context(int ssl, struct us_loop_t *loop, int context_ext_size, struct us_socket_context_options_t options) {
struct us_socket_context_t *context = malloc(context_ext_size + sizeof(struct us_socket_context_t));
context->loop = loop;
return context;
}
void us_socket_context_free(int ssl, struct us_socket_context_t *context) {
}
struct us_listen_socket_t *us_socket_context_listen(int ssl, struct us_socket_context_t *context, const char *host, int port, int options, int socket_ext_size) {
struct us_listen_socket_t *listen_s = malloc(sizeof(struct us_listen_socket_t));
listen_s->context = context;
listen_s->socket_ext_size = socket_ext_size;
int portno = port; struct sockaddr_in serv_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
int sock_listen_fd = socket(AF_INET, SOCK_STREAM, 0);
const int val = 1;
setsockopt(sock_listen_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
setsockopt(sock_listen_fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock_listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Error binding socket...\n");
exit(1);
}
if (listen(sock_listen_fd, BACKLOG) < 0) {
perror("Error listening on socket...\n");
exit(1);
}
struct io_uring_sqe *sqe = io_uring_get_sqe(&context->loop->ring);
io_uring_prep_multishot_accept_direct(sqe, sock_listen_fd, NULL, NULL, 0);
io_uring_sqe_set_flags(sqe, 0);
io_uring_sqe_set_data(sqe, (char *)listen_s + LISTEN_SOCKET_ACCEPT);
return listen_s;
}
struct us_listen_socket_t *us_socket_context_listen_unix(int ssl, struct us_socket_context_t *context, const char *path, int options, int socket_ext_size) {
return 0;
}
struct us_socket_t *us_socket_context_connect(int ssl, struct us_socket_context_t *context, const char *host, int port, const char *source_host, int options, int socket_ext_size) {
struct us_socket_t *s = malloc(sizeof(struct us_socket_t) + socket_ext_size);
s->context = context;
struct addrinfo hints, *result;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
char port_string[16];
snprintf(port_string, 16, "%d", port);
if (getaddrinfo(host, port_string, &hints, &result) != 0) {
return NULL;
}
LIBUS_SOCKET_DESCRIPTOR fd = bsd_create_socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (fd == LIBUS_SOCKET_ERROR) {
freeaddrinfo(result);
return NULL;
}
if (source_host) {
struct addrinfo *interface_result;
if (!getaddrinfo(source_host, NULL, NULL, &interface_result)) {
int ret = bind(fd, interface_result->ai_addr, (socklen_t) interface_result->ai_addrlen);
freeaddrinfo(interface_result);
if (ret == LIBUS_SOCKET_ERROR) {
bsd_close_socket(fd);
freeaddrinfo(result);
return NULL;
}
}
}
struct io_uring_sqe *sqe = io_uring_get_sqe(&context->loop->ring);
io_uring_prep_connect(sqe, fd, result->ai_addr, (socklen_t) result->ai_addrlen);
static int num_sockets;
io_uring_register_files_update(&context->loop->ring, num_sockets, &fd, 1);
s->dd = num_sockets++;
io_uring_sqe_set_data(sqe, (char *)s + SOCKET_CONNECT);
freeaddrinfo(result);
return s;
}
struct us_socket_t *us_socket_context_connect_unix(int ssl, struct us_socket_context_t *context, const char *server_path, int options, int socket_ext_size) {
return 0;
}
struct us_socket_context_t *us_create_child_socket_context(int ssl, struct us_socket_context_t *context, int context_ext_size) {
struct us_socket_context_options_t opt = {0};
return us_create_socket_context(ssl, context->loop, context_ext_size, opt);
}
void us_socket_context_on_open(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_open)(struct us_socket_t *s, int is_client, char *ip, int ip_length)) {
context->on_open = on_open;
}
void us_socket_context_on_close(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_close)(struct us_socket_t *s, int code, void *reason)) {
context->on_close = on_close;
}
void us_socket_context_on_data(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_data)(struct us_socket_t *s, char *data, int length)) {
context->on_data = on_data;
}
void us_socket_context_on_writable(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_writable)(struct us_socket_t *s)) {
}
void us_socket_context_on_long_timeout(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_long_timeout)(struct us_socket_t *)) {
}
void us_socket_context_on_timeout(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_timeout)(struct us_socket_t *)) {
}
void us_socket_context_on_end(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_end)(struct us_socket_t *)) {
}
void us_socket_context_on_connect_error(int ssl, struct us_socket_context_t *context, struct us_socket_t *(*on_connect_error)(struct us_socket_t *s, int code)) {
}
void *us_socket_context_ext(int ssl, struct us_socket_context_t *context) {
return context + 1;
}
#endif