mirror of
https://github.com/hmaxnl/netex.git
synced 2025-01-18 07:24:21 +01:00
Implementing socket creation
This commit is contained in:
parent
71326e34b2
commit
42bfd9dc14
|
@ -2,8 +2,7 @@
|
|||
|
||||
add_library(netex SHARED
|
||||
"configuration.c"
|
||||
"netex.c"
|
||||
"storage.c")
|
||||
"netex.c")
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
target_link_libraries(netex OpenSSL::SSL)
|
||||
|
|
|
@ -5,5 +5,4 @@ target_sources(netex PUBLIC
|
|||
"net.h"
|
||||
"netex.h"
|
||||
"sockets.h"
|
||||
"storage.h"
|
||||
"strutil.h")
|
|
@ -10,5 +10,6 @@
|
|||
|
||||
void netex_init(void);
|
||||
void netex_shutdown(void);
|
||||
int setup_socket(int port, const char* hostname);
|
||||
|
||||
#endif //NETEX_H
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// Created by max on 25-12-23.
|
||||
//
|
||||
|
||||
#ifndef STORAGE_H
|
||||
#define STORAGE_H
|
||||
#include "netex.h"
|
||||
|
||||
struct netex_configuration
|
||||
{
|
||||
char* server_name;
|
||||
size_t port;
|
||||
char* certificate_path;
|
||||
};
|
||||
|
||||
int save_config(void);
|
||||
int load_config_storage(void);
|
||||
|
||||
#endif //STORAGE_H
|
|
@ -1,20 +1,17 @@
|
|||
#include <openssl/bio.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "netex.h"
|
||||
#include "storage.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
void netex_init(void)
|
||||
{
|
||||
// Config
|
||||
const int config_loaded = load_config_storage();
|
||||
if (config_loaded != 0)
|
||||
{
|
||||
ERROR("Failed to load config! Shutting down...");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// OpenSSL
|
||||
PRINT_LINE("Initializing OpenSSL...");
|
||||
SSL_load_error_strings();
|
||||
|
@ -23,10 +20,54 @@ void netex_init(void)
|
|||
}
|
||||
void netex_shutdown(void)
|
||||
{
|
||||
// Config
|
||||
save_config();
|
||||
|
||||
// OpenSSL
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
}
|
||||
|
||||
int setup_socket(const int port, const char* hostname)
|
||||
{
|
||||
struct addrinfo *cur_addrdinfo;
|
||||
struct addrinfo hints_addrinfo = {0};
|
||||
int sock_fd = 0;
|
||||
hints_addrinfo.ai_family = AF_UNSPEC;
|
||||
hints_addrinfo.ai_socktype = SOCK_DGRAM;
|
||||
hints_addrinfo.ai_flags = AI_PASSIVE;
|
||||
hints_addrinfo.ai_protocol = 0;
|
||||
hints_addrinfo.ai_canonname = NULL;
|
||||
hints_addrinfo.ai_addr = NULL;
|
||||
hints_addrinfo.ai_next = NULL;
|
||||
if (getaddrinfo(NULL, hostname, &hints_addrinfo, &cur_addrdinfo) != 0)
|
||||
{
|
||||
ERROR("Could not get the address info of hostname: '%s'", hostname);
|
||||
return 1;
|
||||
}
|
||||
for (const struct addrinfo* tmp_addrinfo = cur_addrdinfo; tmp_addrinfo != NULL; tmp_addrinfo = tmp_addrinfo->ai_next)
|
||||
{
|
||||
sock_fd = socket(tmp_addrinfo->ai_family, tmp_addrinfo->ai_socktype, tmp_addrinfo->ai_protocol);
|
||||
if (sock_fd == -1)
|
||||
continue;
|
||||
|
||||
if (bind(sock_fd, tmp_addrinfo->ai_addr, tmp_addrinfo->ai_addrlen) == 0)
|
||||
break; // Succesfull bind to the hostname
|
||||
close(sock_fd);
|
||||
}
|
||||
/*struct sockaddr_in sockaddr;
|
||||
const int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0)
|
||||
{
|
||||
WARN("Failed to create socket!");
|
||||
return 1;
|
||||
}
|
||||
sockaddr.sin_family = AF_INET;
|
||||
sockaddr.sin_port = htons(port);
|
||||
sockaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
const int bind_result = bind(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
|
||||
if (bind_result != 0)
|
||||
{
|
||||
const int bind_error = errno;
|
||||
ERROR("Failed to bind to socket! Error: %i", bind_error);
|
||||
return 1;
|
||||
}*/
|
||||
return sock_fd;
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <json-c/json.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include "storage.h"
|
||||
|
||||
#define CONFIG_FILE_NAME "config.json"
|
||||
#define PROP_SRV_NAME "server_name"
|
||||
#define PROP_PORT "port"
|
||||
#define PROP_CERT "certificate_path"
|
||||
|
||||
const char* config_to_json(const struct netex_configuration* net_config);
|
||||
struct netex_configuration* create_config(const char* server_name, const size_t port);
|
||||
void set_config(struct netex_configuration* config);
|
||||
struct netex_configuration* json_to_config(const char* json);
|
||||
|
||||
struct netex_configuration* loaded_configuration;
|
||||
|
||||
int save_config(void)
|
||||
{
|
||||
if (loaded_configuration == NULL)
|
||||
return 0; // Nothing to save
|
||||
FILE* config_file = fopen(CONFIG_FILE_NAME, "w");
|
||||
if (config_file == NULL)
|
||||
{
|
||||
const int error = errno;
|
||||
ERROR("Failed to open file '%s', code %i", CONFIG_FILE_NAME, error);
|
||||
return -1;
|
||||
}
|
||||
const char* json = config_to_json(loaded_configuration);
|
||||
const size_t json_len = strlen(json);
|
||||
const int write_result = fwrite(json, 1, json_len, config_file);
|
||||
fclose(config_file);
|
||||
if (write_result <= 0)
|
||||
{
|
||||
const int write_error = errno;
|
||||
ERROR("Failed to write config file to disk! Error: %i", write_error);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int load_config_storage(void)
|
||||
{
|
||||
struct stat config_stat;
|
||||
if (lstat(CONFIG_FILE_NAME, &config_stat) == -1)
|
||||
{
|
||||
const int error = errno;
|
||||
if (error == ENOENT)// No config file found -> create new config with defaults & save to disk.
|
||||
{
|
||||
set_config(NULL);
|
||||
return save_config();
|
||||
}
|
||||
WARN("Failed to get stat on file '%s', error: %i ", CONFIG_FILE_NAME, error);
|
||||
return error;
|
||||
}
|
||||
const long int file_size = config_stat.st_size;
|
||||
if (file_size <= 0)
|
||||
{
|
||||
WARN("Config file exists but is empty, fallback to default config...");
|
||||
set_config(NULL);
|
||||
return save_config();
|
||||
}
|
||||
FILE *config_fd = fopen(CONFIG_FILE_NAME, "r");
|
||||
if (config_fd == NULL)
|
||||
{
|
||||
const int error = errno;
|
||||
WARN("Failed to open file: '%s' with error code: %i", CONFIG_FILE_NAME, error);
|
||||
return error;
|
||||
}
|
||||
void* file_mem = malloc(file_size);
|
||||
if (file_mem == NULL)
|
||||
{
|
||||
const int error = errno;
|
||||
WARN("Failed to allocate memory!");
|
||||
return error;
|
||||
}
|
||||
const size_t total_read = fread(file_mem, file_size, file_size, config_fd);
|
||||
fclose(config_fd);
|
||||
if (total_read != 1)
|
||||
{
|
||||
free(file_mem);
|
||||
return -1;
|
||||
}
|
||||
loaded_configuration = json_to_config(file_mem);
|
||||
free(file_mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct netex_configuration* get_configuration()
|
||||
{
|
||||
if (loaded_configuration == NULL)
|
||||
{
|
||||
const int load_result = load_config_storage();
|
||||
if (load_result != 0)
|
||||
WARN("Failed to get configuration!");
|
||||
}
|
||||
return loaded_configuration;
|
||||
}
|
||||
|
||||
struct netex_configuration* create_config(const char* server_name, const size_t port)
|
||||
{
|
||||
struct netex_configuration* nx_config = malloc(sizeof(struct netex_configuration));
|
||||
if (nx_config == NULL)
|
||||
{
|
||||
WARN("Failed to allocate memory for configuration object!");
|
||||
return nx_config;
|
||||
}
|
||||
nx_config->server_name = strdup(server_name);
|
||||
nx_config->port = port;
|
||||
return nx_config;
|
||||
}
|
||||
|
||||
void set_config(struct netex_configuration* config)
|
||||
{
|
||||
if (loaded_configuration != NULL)
|
||||
{
|
||||
if (loaded_configuration->server_name != NULL)
|
||||
free(loaded_configuration->server_name);
|
||||
free(loaded_configuration);
|
||||
}
|
||||
if (config == NULL) // Fallback to default values
|
||||
config = create_config("Linux netex server", 6920);
|
||||
loaded_configuration = config;
|
||||
}
|
||||
|
||||
struct netex_configuration* json_to_config(const char* json)
|
||||
{
|
||||
const json_object* json_obj = json_tokener_parse(json);
|
||||
json_object* json_prop_srv_name;
|
||||
const char* srv_name = "";
|
||||
if (json_object_object_get_ex(json_obj, PROP_SRV_NAME, &json_prop_srv_name))
|
||||
srv_name = json_object_get_string(json_prop_srv_name);
|
||||
json_object* json_prop_port;
|
||||
size_t srv_port = 0;
|
||||
if (json_object_object_get_ex(json_obj, PROP_PORT, &json_prop_port))
|
||||
srv_port = json_object_get_int64(json_prop_port);
|
||||
struct netex_configuration* config = create_config(srv_name, srv_port);
|
||||
return config;
|
||||
}
|
||||
|
||||
const char* config_to_json(const struct netex_configuration* net_config)
|
||||
{
|
||||
json_object* jobj = json_object_new_object();
|
||||
json_object* srv_name_obj = json_object_new_string(net_config->server_name);
|
||||
if (json_object_object_add(jobj, PROP_SRV_NAME, srv_name_obj) != 0)
|
||||
WARN("Failed to add property: '%s' to JSON!", PROP_SRV_NAME);
|
||||
json_object* srv_port_obj = json_object_new_int64(net_config->port);
|
||||
if (json_object_object_add(jobj, PROP_PORT, srv_port_obj) != 0)
|
||||
WARN("Failed to add property: '%s' to JSON!", PROP_PORT);
|
||||
return json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
add_executable(netex_svr
|
||||
"server.c")
|
||||
"main.c"
|
||||
"server.c"
|
||||
server.h)
|
||||
|
||||
target_include_directories(netex_svr PRIVATE ${CMAKE_SOURCE_DIR}/src/net/include)
|
||||
target_link_libraries(netex_svr netex)
|
21
src/server/main.c
Normal file
21
src/server/main.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "netex.h"
|
||||
#include "server.h"
|
||||
|
||||
// Sources:
|
||||
// http://simplestcodings.blogspot.com/2010/08/secure-server-client-using-openssl-in-c.html
|
||||
// https://stackoverflow.com/questions/40812836/how-to-create-chat-server-using-openssl-in-c
|
||||
// https://www.cs.cmu.edu/~srini/15-441/F02/Projects/lab01/reference/part1.pdf
|
||||
|
||||
|
||||
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);
|
||||
return init_result;
|
||||
}
|
||||
return server_execute();
|
||||
}
|
|
@ -1,50 +1,45 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "netex.h"
|
||||
#include "config.h"
|
||||
|
||||
#define CONFIG_PATH "srv_config.json"
|
||||
CONFIGURATION* srv_configuration;
|
||||
int server_sockfd;
|
||||
struct sockaddr_in server_sockaddr;
|
||||
|
||||
int srv_setup(void);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int initialize_server(int argc, char* argv[])
|
||||
{
|
||||
const CONFIGURATION* srv_config = config_load_from_path(CONFIG_PATH);
|
||||
int remove_result = config_remove(srv_config, "Connection.CertPath");
|
||||
config_set_string(srv_config, "Connection.CertPath", "cert.pem");
|
||||
config_save_to_path(srv_config, CONFIG_PATH);
|
||||
config_clear(srv_config);
|
||||
|
||||
// Config
|
||||
srv_configuration = config_load_from_path(CONFIG_PATH);
|
||||
if (srv_configuration == NULL)
|
||||
{
|
||||
WARN("Fallback to default config!");
|
||||
srv_configuration = config_create();
|
||||
config_set_int(srv_configuration, "Connection.Port", 6920);
|
||||
config_set_string(srv_configuration, "Connection.Crypto.CertPath", "cert.pem");
|
||||
if (config_save_to_path(srv_configuration, CONFIG_PATH) != 0)
|
||||
{
|
||||
WARN("Failed to save configuration to disk, default config is only available in memory!");
|
||||
}
|
||||
}
|
||||
netex_init();
|
||||
PRINT_LINE("Hello, server!");
|
||||
if (argc > 1)
|
||||
|
||||
// Socket
|
||||
const int64_t portnum = config_get_int(srv_configuration, "Connection.Port");
|
||||
server_sockfd = setup_socket(portnum, "localhost");
|
||||
if (server_sockfd < 0)
|
||||
{
|
||||
//TODO: Handle args
|
||||
WARN("Failed to create socket!");
|
||||
return 1;
|
||||
}
|
||||
if (srv_setup() != 0)
|
||||
{
|
||||
ERROR("Failed to initialize server!");
|
||||
return 0;
|
||||
}
|
||||
netex_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* th_srv_listen(void)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
//TODO: Listen to connections & give a thread to handle communication
|
||||
}
|
||||
}
|
||||
|
||||
int svr_command(void)
|
||||
int server_execute(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int srv_setup(void)
|
||||
{
|
||||
|
||||
return -1;
|
||||
}
|
7
src/server/server.h
Normal file
7
src/server/server.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
int initialize_server(int argc, char* argv[]);
|
||||
int server_execute(void);
|
||||
|
||||
#endif //SERVER_H
|
Loading…
Reference in New Issue
Block a user