mirror of
https://github.com/hmaxnl/netex.git
synced 2025-01-18 23:44:20 +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 WARN(msg, args...) fprintf(stdout, "[Warning]: " msg "\n", ##args)
|
||||||
#define ERROR(msg, args...) fprintf(stderr, "[ERROR]: " 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_init(void);
|
||||||
void netex_shutdown(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, SOCKET_IPV_TYPE ipv_type);
|
||||||
int setup_socket(int port, const char* hostname);
|
HOST_INFO* resolve_host(const char* hostname, int port, SOCKET_IPV_TYPE ipv_type);
|
||||||
|
|
||||||
#endif //NETEX_H
|
#endif //NETEX_H
|
148
src/net/netex.c
148
src/net/netex.c
|
@ -5,7 +5,6 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#include "netex.h"
|
#include "netex.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -21,6 +20,7 @@ void netex_init(void)
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
}
|
}
|
||||||
|
|
||||||
void netex_shutdown(void)
|
void netex_shutdown(void)
|
||||||
{
|
{
|
||||||
// OpenSSL
|
// OpenSSL
|
||||||
|
@ -28,24 +28,146 @@ void netex_shutdown(void)
|
||||||
EVP_cleanup();
|
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;
|
HOST_INFO* resolved_host = resolve_host(hostname, port, ipv_type);
|
||||||
const int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
if (resolved_host == NULL)
|
||||||
if (sock_fd < 0)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
sockaddr_in.sin_family = AF_INET;
|
break;
|
||||||
sockaddr_in.sin_port = htons(port);
|
case Double:
|
||||||
sockaddr_in.sin_addr.s_addr = inet_addr(hostname);
|
case IPv6:
|
||||||
const int bind_result = bind(sock_fd, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in));
|
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;
|
||||||
|
}
|
||||||
|
const int bind_result = bind(socket_fd, resolved_host->address, resolved_host->addrlen);
|
||||||
if (bind_result != 0)
|
if (bind_result != 0)
|
||||||
{
|
{
|
||||||
ERROR("Could not bind!");
|
const int bind_error = errno;
|
||||||
|
ERROR("Could not bind! Error: %i", bind_error);
|
||||||
|
close(socket_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);
|
close(sock_fd);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return 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);
|
const int init_result = initialize_server(argc, argv);
|
||||||
if (init_result)
|
if (init_result)
|
||||||
{
|
{
|
||||||
WARN("Failed to initialize server, error: %i. Exiting...", init_result);
|
WARN("Failed to initialize server. Exiting...");
|
||||||
return init_result;
|
return init_result;
|
||||||
}
|
}
|
||||||
return server_execute();
|
return server_execute();
|
||||||
|
|
|
@ -32,7 +32,8 @@ int initialize_server(int argc, char* argv[])
|
||||||
WARN("Fallback to default config!");
|
WARN("Fallback to default config!");
|
||||||
srv_configuration = config_create();
|
srv_configuration = config_create();
|
||||||
config_set_int(srv_configuration, "Connection.Port", 6920);
|
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");
|
config_set_string(srv_configuration, "Connection.Crypto.CertPath", "cert.pem");
|
||||||
if (config_save_to_path(srv_configuration, CONFIG_PATH) != 0)
|
if (config_save_to_path(srv_configuration, CONFIG_PATH) != 0)
|
||||||
{
|
{
|
||||||
|
@ -43,9 +44,18 @@ int initialize_server(int argc, char* argv[])
|
||||||
|
|
||||||
// Socket
|
// Socket
|
||||||
const int64_t portnum = config_get_int(srv_configuration, "Connection.Port");
|
const int64_t portnum = config_get_int(srv_configuration, "Connection.Port");
|
||||||
char* hostname = config_get_string(srv_configuration, "Connection.Host");
|
char* hostname = config_get_string(srv_configuration, "Connection.BindIP");
|
||||||
server_sockfd = setup_socket(portnum, hostname);
|
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(hostname);
|
||||||
|
free(ipv);
|
||||||
if (server_sockfd <= 0)
|
if (server_sockfd <= 0)
|
||||||
{
|
{
|
||||||
WARN("Could not create server sockedfd!");
|
WARN("Could not create server sockedfd!");
|
||||||
|
@ -56,7 +66,7 @@ int initialize_server(int argc, char* argv[])
|
||||||
|
|
||||||
int server_execute(void)
|
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)
|
if (thread_create_result != 0)
|
||||||
{
|
{
|
||||||
ERROR("Failed to create main listening thread, pthread error: %i", thread_create_result);
|
ERROR("Failed to create main listening thread, pthread error: %i", thread_create_result);
|
||||||
|
@ -99,5 +109,5 @@ void server_listen()
|
||||||
close(accepted_fd);
|
close(accepted_fd);
|
||||||
//TODO: Send client to thread that will handle further connection things.
|
//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