mirror of
https://github.com/hmaxnl/netex.git
synced 2025-01-18 07:24:21 +01:00
Implemented hostname resolving, added IPv6
This commit is contained in:
parent
07cde8f676
commit
6b5dfdc8d4
|
@ -8,9 +8,25 @@
|
|||
#define WARN(msg, args...) fprintf(stdout, "[Warning]: " msg "\n", ##args)
|
||||
#define ERROR(msg, args...) fprintf(stderr, "[ERROR]: " msg "\n", ##args)
|
||||
|
||||
typedef enum socket_ipv
|
||||
{
|
||||
IPv4,
|
||||
IPv6,
|
||||
Double
|
||||
} SOCKET_IPV_TYPE;
|
||||
|
||||
typedef struct host_info
|
||||
{
|
||||
char* ip;
|
||||
struct sockaddr* address;
|
||||
size_t addrlen;
|
||||
SOCKET_IPV_TYPE ipv_type;
|
||||
} HOST_INFO;
|
||||
|
||||
|
||||
void netex_init(void);
|
||||
void netex_shutdown(void);
|
||||
// Creates a socket and bind to that socket on the given port and hostname. If done with the socket close it with 'close()'
|
||||
int setup_socket(int port, const char* hostname);
|
||||
int setup_socket(int port, const char* hostname, SOCKET_IPV_TYPE ipv_type);
|
||||
HOST_INFO* resolve_host(const char* hostname, int port, SOCKET_IPV_TYPE ipv_type);
|
||||
|
||||
#endif //NETEX_H
|
152
src/net/netex.c
152
src/net/netex.c
|
@ -5,7 +5,6 @@
|
|||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "netex.h"
|
||||
#include "config.h"
|
||||
|
@ -21,6 +20,7 @@ void netex_init(void)
|
|||
SSL_library_init();
|
||||
OpenSSL_add_all_algorithms();
|
||||
}
|
||||
|
||||
void netex_shutdown(void)
|
||||
{
|
||||
// OpenSSL
|
||||
|
@ -28,24 +28,146 @@ void netex_shutdown(void)
|
|||
EVP_cleanup();
|
||||
}
|
||||
|
||||
int setup_socket(const int port, const char* hostname)
|
||||
int setup_socket(const int port, const char* hostname, const SOCKET_IPV_TYPE ipv_type)
|
||||
{
|
||||
struct sockaddr_in sockaddr_in;
|
||||
const int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock_fd < 0)
|
||||
HOST_INFO* resolved_host = resolve_host(hostname, port, ipv_type);
|
||||
if (resolved_host == NULL)
|
||||
return -1;
|
||||
int socket_fd;
|
||||
switch (resolved_host->ipv_type)
|
||||
{
|
||||
ERROR("Failed to created socket");
|
||||
default:
|
||||
case IPv4:
|
||||
PRINT_LINE("Creating IPv4 socket...");
|
||||
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (socket_fd < 0)
|
||||
{
|
||||
ERROR("Failed to created socket (IPv4)");
|
||||
free(resolved_host);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case Double:
|
||||
case IPv6:
|
||||
PRINT_LINE("Creating IPv6 socket...");
|
||||
socket_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
if (socket_fd < 0)
|
||||
{
|
||||
ERROR("Failed to create socket (IPv6)");
|
||||
free(resolved_host);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (socket_fd == 0)
|
||||
{
|
||||
WARN("Failed to set socket!");
|
||||
free(resolved_host);
|
||||
return -1;
|
||||
}
|
||||
sockaddr_in.sin_family = AF_INET;
|
||||
sockaddr_in.sin_port = htons(port);
|
||||
sockaddr_in.sin_addr.s_addr = inet_addr(hostname);
|
||||
const int bind_result = bind(sock_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in));
|
||||
const int bind_result = bind(socket_fd, resolved_host->address, resolved_host->addrlen);
|
||||
if (bind_result != 0)
|
||||
{
|
||||
ERROR("Could not bind!");
|
||||
close(sock_fd);
|
||||
return -1;
|
||||
const int bind_error = errno;
|
||||
ERROR("Could not bind! Error: %i", bind_error);
|
||||
close(socket_fd);
|
||||
}
|
||||
return sock_fd;
|
||||
}
|
||||
free(resolved_host);
|
||||
return socket_fd;
|
||||
}
|
||||
|
||||
HOST_INFO* resolve_host(const char* hostname, const int port, const SOCKET_IPV_TYPE ipv_type)
|
||||
{
|
||||
struct addrinfo *resolved, *next, hints;
|
||||
|
||||
const char* p_port = NULL;
|
||||
char port_str[PORT_NUM_LENGHT];
|
||||
if (port != 0)
|
||||
{
|
||||
const int print_result = snprintf(port_str, PORT_NUM_LENGHT, "%d", port);
|
||||
if (print_result < 0)
|
||||
{
|
||||
ERROR("Failed to convert port to string!");
|
||||
return NULL;
|
||||
}
|
||||
p_port = (char*)&port_str;
|
||||
}
|
||||
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_protocol = 0;
|
||||
hints.ai_canonname = NULL;
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
switch (ipv_type)
|
||||
{
|
||||
default:
|
||||
case IPv4:
|
||||
hints.ai_family = AF_INET;
|
||||
break;
|
||||
case IPv6:
|
||||
hints.ai_family = AF_INET6;
|
||||
break;
|
||||
case Double:
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
break;
|
||||
}
|
||||
if (getaddrinfo(hostname, p_port, &hints, &resolved) != 0)
|
||||
{
|
||||
ERROR("Failed to get addres info for hostname '%s'", hostname);
|
||||
return NULL;
|
||||
}
|
||||
for (next = resolved; next != NULL; next = next->ai_next)
|
||||
{
|
||||
const int sock_fd = socket(next->ai_family, next->ai_socktype, next->ai_protocol);
|
||||
if (sock_fd == -1)
|
||||
continue;
|
||||
if (bind(sock_fd, next->ai_addr, next->ai_addrlen) == 0)
|
||||
break; // Succesfull bind
|
||||
if (connect(sock_fd, next->ai_addr, next->ai_addrlen) == 0)
|
||||
break;
|
||||
close(sock_fd);
|
||||
}
|
||||
if (next == NULL)
|
||||
{
|
||||
freeaddrinfo(resolved);
|
||||
return NULL;
|
||||
}
|
||||
HOST_INFO* host_info = malloc(sizeof(HOST_INFO));
|
||||
if (host_info == NULL)
|
||||
{
|
||||
const int malloc_error = errno;
|
||||
ERROR("Failed to allocate object, error: %i", malloc_error);
|
||||
return NULL;
|
||||
}
|
||||
switch (next->ai_family)
|
||||
{
|
||||
case AF_INET:
|
||||
host_info->ipv_type = IPv4;
|
||||
break;
|
||||
case AF_INET6:
|
||||
host_info->ipv_type = IPv6;
|
||||
break;
|
||||
default:
|
||||
ERROR("Invalid net family encounterd!");
|
||||
free(host_info);
|
||||
freeaddrinfo(resolved);
|
||||
return NULL;
|
||||
}
|
||||
char host[NI_MAXHOST];
|
||||
getnameinfo(next->ai_addr, next->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
|
||||
host_info->ip = strdup(host);
|
||||
host_info->addrlen = next->ai_addrlen;
|
||||
host_info->address = malloc(next->ai_addrlen);
|
||||
if (host_info->address != NULL)
|
||||
{
|
||||
if (memcpy(host_info->address, next->ai_addr, next->ai_addrlen) == NULL)
|
||||
{
|
||||
WARN("Failed to copy addrinfo over!");
|
||||
}
|
||||
}
|
||||
freeaddrinfo(resolved);
|
||||
return host_info;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ int main(int argc, char *argv[])
|
|||
const int init_result = initialize_server(argc, argv);
|
||||
if (init_result)
|
||||
{
|
||||
WARN("Failed to initialize server, error: %i. Exiting...", init_result);
|
||||
WARN("Failed to initialize server. Exiting...");
|
||||
return init_result;
|
||||
}
|
||||
return server_execute();
|
||||
|
|
|
@ -32,7 +32,8 @@ int initialize_server(int argc, char* argv[])
|
|||
WARN("Fallback to default config!");
|
||||
srv_configuration = config_create();
|
||||
config_set_int(srv_configuration, "Connection.Port", 6920);
|
||||
config_set_string(srv_configuration, "Connection.Host", "localhost");
|
||||
config_set_string(srv_configuration, "Connection.BindIP", "0.0.0.0");
|
||||
config_set_string(srv_configuration, "Connection.IPv", "Double");
|
||||
config_set_string(srv_configuration, "Connection.Crypto.CertPath", "cert.pem");
|
||||
if (config_save_to_path(srv_configuration, CONFIG_PATH) != 0)
|
||||
{
|
||||
|
@ -43,9 +44,18 @@ int initialize_server(int argc, char* argv[])
|
|||
|
||||
// Socket
|
||||
const int64_t portnum = config_get_int(srv_configuration, "Connection.Port");
|
||||
char* hostname = config_get_string(srv_configuration, "Connection.Host");
|
||||
server_sockfd = setup_socket(portnum, hostname);
|
||||
char* hostname = config_get_string(srv_configuration, "Connection.BindIP");
|
||||
char* ipv = config_get_string(srv_configuration, "Connection.IPv");
|
||||
SOCKET_IPV_TYPE ipv_t = IPv4;
|
||||
if (strcmp(ipv, "Double") == 0)
|
||||
ipv_t = Double;
|
||||
else if (strcmp(ipv, "4") == 0)
|
||||
ipv_t = IPv4;
|
||||
else if (strcmp(ipv, "6") == 0)
|
||||
ipv_t = IPv6;
|
||||
server_sockfd = setup_socket(portnum, hostname, ipv_t);
|
||||
free(hostname);
|
||||
free(ipv);
|
||||
if (server_sockfd <= 0)
|
||||
{
|
||||
WARN("Could not create server sockedfd!");
|
||||
|
@ -56,7 +66,7 @@ int initialize_server(int argc, char* argv[])
|
|||
|
||||
int server_execute(void)
|
||||
{
|
||||
const int thread_create_result = pthread_create(&listen_thread, NULL, server_listen, NULL);
|
||||
const int thread_create_result = pthread_create(&listen_thread, NULL, (void*)server_listen, NULL);
|
||||
if (thread_create_result != 0)
|
||||
{
|
||||
ERROR("Failed to create main listening thread, pthread error: %i", thread_create_result);
|
||||
|
@ -99,5 +109,5 @@ void server_listen()
|
|||
close(accepted_fd);
|
||||
//TODO: Send client to thread that will handle further connection things.
|
||||
}
|
||||
pthread_exit((void*)some_return_code);
|
||||
pthread_exit(&some_return_code);
|
||||
}
|
Loading…
Reference in New Issue
Block a user