Reorganization of interfaces.

This commit is contained in:
Nicolás A. Ortega 2017-07-31 14:19:15 -05:00
parent d0a673d767
commit 7222ad3e2a
No known key found for this signature in database
GPG Key ID: 3D786FB3123FF1DD
11 changed files with 249 additions and 55 deletions

View File

@ -15,7 +15,7 @@
# License along with this program. If not, see # License along with this program. If not, see
# <http://www.gnu.org/licenses/>. # <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 3.1)
project(NeoComm) project(NeoComm)
set(TARGET_NAME "neocomm") set(TARGET_NAME "neocomm")
@ -31,14 +31,18 @@ message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")
option(BUILD_SHARED_LIBS option(BUILD_SHARED_LIBS
"Whether to build a shared object instead of a static." OFF) "Whether to build a shared object instead of a static." OFF)
find_package(Threads REQUIRED)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
include_directories( include_directories(
"include/") "include/")
set(SRCS set(SRCS
src/connection.c src/connectivity.c
src/error.c src/error.c
src/neocomm.c src/neocomm.c)
src/nodes.c)
set(CMAKE_C_FLAGS "-std=c99 -Wall -Wextra -Werror -Wfatal-errors -Wmissing-declarations -pedantic-errors") set(CMAKE_C_FLAGS "-std=c99 -Wall -Wextra -Werror -Wfatal-errors -Wmissing-declarations -pedantic-errors")
set(CMAKE_C_FLAGS_DEBUG "-g -O0") set(CMAKE_C_FLAGS_DEBUG "-g -O0")
@ -53,4 +57,11 @@ else()
add_definitions("-DDEBUG") add_definitions("-DDEBUG")
endif() endif()
add_library(${TARGET_NAME} ${SRCS}) if(BUILD_SHARED_LIBS)
add_library(${TARGET_NAME} SHARED ${SRCS})
else()
add_library(${TARGET_NAME} STATIC ${SRCS})
endif()
target_link_libraries(${TARGET_NAME}
Threads::Threads)

View File

@ -30,7 +30,6 @@ What follows is a list roadmap of features and the (approximate) versions in whi
- [ ] Message encryption - [ ] Message encryption
- [ ] Private messages - [ ] Private messages
- v1.0: - v1.0:
- [ ] Special snowflake (Winblows) socket support
- [ ] SOCKS4a/SOCKS5 proxy support - [ ] SOCKS4a/SOCKS5 proxy support
- [ ] HTTP proxy support - [ ] HTTP proxy support
- v2.0: - v2.0:
@ -49,7 +48,7 @@ _There are currently no clients available._
Compiling Compiling
--------- ---------
To build this project you will need a C99 compatible compiler ([GCC](https://gcc.gnu.org/) is recommended) and the [CMake build system](https://cmake.org/). To build run the following commands from the root directory of the project. To build this project you will need a C99 compatible compiler ([GCC](https://gcc.gnu.org/) is recommended), a POSIX threads compatible system, and the [CMake build system](https://cmake.org/). To build run the following commands from the root directory of the project.
``` ```
$ cd build/ $ cd build/
$ cmake .. $ cmake ..

View File

@ -0,0 +1,120 @@
/*
* Copyright (C) 2017 Ortega Froysa, Nicolás <deathsbreed@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <deathsbreed@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
#pragma once
/**
* @file connectivity.h
* @brief Interfaces relating to node connections.
*/
/**
* @brief Simple address structure providing IP/DNS and port information.
*/
struct NeoComm_address {
const char *address; ///< IP/DNS string.
unsigned short port; ///< Port of address.
};
/**
* @brief Structure used for NeoComm nodes.
*/
struct NeoComm_node {
/// The address of the node.
struct NeoComm_address address;
/// Whether or not it is a directory node/server.
int directory;
/// Number of connections a directory has.
unsigned int connections;
/// Maximum number of connections the directory can have.
unsigned int max_connections;
};
/**
* @brief Initialize the directory aspect of the node.
*
* @param max_num_nodes Maximum number of nodes in the directory.
* @param portnum Public facing port which other nodes can connect to.
*
* @return If the operation failed then a 0 will be returned and the error can
* be read from the NeoComm_get_last_error function, else 1 is returned.
*/
int NeoComm_init_directory(const unsigned int max_num_nodes,
const unsigned short portnum);
/**
* @brief Disconnect from all nodes and free memory.
*/
void NeoComm_shutdown_directory();
/**
* @brief Resize the directory.
* @note This function only increments the size, it currently does not have
* the ability to decrease size.
*
* @param new_max_num_nodes The new maximum number of nodes in the directory.
*
* @return If the operation failed then a 0 will be returned and the error can
* be read from the NeoComm_get_last_error function, else 1 is returned.
*/
int NeoComm_resize_directory(const unsigned int new_max_num_nodes);
/**
* @brief Get the current maximum number of nodes for the directory.
*
* @return The current maximum number of nodes for the directory.
*/
unsigned int NeoComm_get_directory_size();
/**
* @brief Get the current number of nodes registered in the directory.
*
* @return The current number of nodes in the directory.
*/
unsigned int NeoComm_get_num_nodes();
/**
* @brief Add and connect to a new node to the directory.
*
* @param addr The address of the new node to connect to.
*
* @return If the operation failed then a 0 will be returned and the error can
* be read from the NeoComm_get_last_error function, else 1 is returned.
*/
int NeoComm_add_node(const struct NeoComm_address addr);
/**
* @brief Disconnect and remove a node from the directory.
*
* @param addr The address of the node to remove.
*
* @return If the operation failed then a 0 will be returned and the error can
* be read from the NeoComm_get_last_error function, else 1 is returned.
*/
int NeoComm_remove_node(const struct NeoComm_address addr);
/**
* @brief Retrieve information on a specific node.
*
* @param addr The address of the node to retrieve.
*
* @return A NeoComm_node structure of the node.
*/
struct NeoComm_node NeoComm_get_node(const struct NeoComm_address addr);

View File

@ -19,9 +19,8 @@
#pragma once #pragma once
#include "neocomm/connection.h"
#include "neocomm/error.h" #include "neocomm/error.h"
#include "neocomm/nodes.h" #include "neocomm/connectivity.h"
/** /**
* @file neocomm.h * @file neocomm.h

View File

@ -17,19 +17,49 @@
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
*/ */
#include "neocomm/connection.h" #include "neocomm/connectivity.h"
#include "iconnectivity.h"
#include "internal_error.h" #include "ierror.h"
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h>
#include <strings.h> #include <strings.h>
#include <stdio.h> #include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
/*
* This is an internal OS specific structure for nodes.
*/
struct NeoComm_directory_node {
int in_use;
struct sockaddr_in addr;
int sockfd;
pthread_t thread;
int open_directory;
unsigned int connections;
unsigned int max_connections;
};
static struct NeoComm_directory_node *node_list;
static unsigned int max_nodes;
static unsigned int num_nodes;
static int run;
static int sockfd;
static pthread_t accept_thread;
/*
* This is a protected bind function that is not accessible as a public
* interface.
*/
int NeoComm_bind(const unsigned short port) { int NeoComm_bind(const unsigned short port) {
int sockfd;//, newsockfd;
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); sockfd = socket(AF_INET, SOCK_STREAM, 0);
@ -100,3 +130,71 @@ int NeoComm_bind(const unsigned short port) {
return 1; return 1;
} }
void *NeoComm_connect_manager() {
while(run)
{
int cli_sockfd;
struct sockaddr_in cli_addr;
socklen_t size_cli_addr = sizeof(cli_addr);
cli_sockfd = accept(sockfd, (struct sockaddr*) &cli_addr,
&size_cli_addr);
if(cli_sockfd < 0)
{
NeoComm_error("Error on accept");
continue;
}
// TODO: Add the new connection and have it listen on a new thread.
}
pthread_exit(NULL);
}
int NeoComm_init_directory(const unsigned int max_num_nodes,
const unsigned short portnum) {
if(max_num_nodes == 0)
{
NeoComm_error("Insufficient number of nodes");
return 0;
}
if(!NeoComm_bind(portnum))
return 0;
node_list = calloc(max_num_nodes, sizeof(struct NeoComm_directory_node));
if(!node_list)
{
NeoComm_error("Failed to allocate memory to directory node list");
return 0;
}
max_nodes = max_num_nodes;
num_nodes = 0;
for(unsigned int i = 0; i < max_nodes; ++i)
node_list[i].in_use = 0;
run = 1;
int err = pthread_create(&accept_thread, NULL,
NeoComm_connect_manager, NULL);
if(err != 0)
{
NeoComm_error("Insufficient resources to create thread");
return 0;
}
return 1;
}
void NeoComm_shutdown_directory() {
run = 0;
void *res;
for(unsigned int i = 0; i < num_nodes; ++i)
{
// in case the threads are still running, we wait
pthread_join(node_list[i].thread, &res);
close(node_list[i].sockfd);
}
pthread_join(accept_thread, &res);
close(sockfd);
pthread_exit(NULL);
}

View File

@ -18,7 +18,7 @@
*/ */
#include "neocomm/error.h" #include "neocomm/error.h"
#include "internal_error.h" #include "ierror.h"
#include <assert.h> #include <assert.h>

View File

@ -1,29 +0,0 @@
/*
* Copyright (C) 2017 Ortega Froysa, Nicolás <deathsbreed@themusicinnoise.net>
* Author: Ortega Froysa, Nicolás <deathsbreed@themusicinnoise.net>
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "neocomm/nodes.h"
// List of nodes
extern struct NeoComm_node *node_list;
// Maximum number of nodes
extern unsigned int node_max;
// Number of nodes in the list
extern unsigned int node_count;

View File

@ -19,6 +19,6 @@
#pragma once #pragma once
int NeoComm_bind(const unsigned short port); int NeoComm_bind(unsigned short portnum);
void NeoComm_close_connections(); void *NeoComm_connect_manager();

View File

@ -18,13 +18,3 @@
*/ */
#include "neocomm/neocomm.h" #include "neocomm/neocomm.h"
int NeoComm_init(unsigned int max_nodes) {
if(!NeoComm_init_nodes(max_nodes))
return 0;
return 1;
}
void NeoComm_shutdown() {
NeoComm_shutdown_nodes();
}

View File

@ -19,13 +19,19 @@
#include "neocomm/nodes.h" #include "neocomm/nodes.h"
#include "globals.h"
#include "internal_error.h" #include "internal_error.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
// List of nodes
static struct NeoComm_node *node_list;
// Maximum number of nodes
static unsigned int node_max;
// Number of nodes in the list
static unsigned int node_count;
int NeoComm_init_nodes(unsigned int max_nodes) { int NeoComm_init_nodes(unsigned int max_nodes) {
if(max_nodes == 0) if(max_nodes == 0)
{ {