diff options
-rw-r--r-- | include/ouroboros/sockets.h | 50 | ||||
-rw-r--r-- | src/lib/ipcp.c | 122 | ||||
-rw-r--r-- | src/lib/irm.c | 2 | ||||
-rw-r--r-- | src/lib/sockets.c | 346 |
4 files changed, 435 insertions, 85 deletions
diff --git a/include/ouroboros/sockets.h b/include/ouroboros/sockets.h index 871e3c36..426e1006 100644 --- a/include/ouroboros/sockets.h +++ b/include/ouroboros/sockets.h @@ -23,12 +23,17 @@ #ifndef OUROBOROS_SOCKETS_H #define OUROBOROS_SOCKETS_H -#include "common.h" -#include "rina_name.h" +#include <ouroboros/common.h> +#include <ouroboros/rina_name.h> + +#include <sys/types.h> #define IRM_SOCK_PATH "/tmp/irm_sock" #define IRM_MSG_BUF_SIZE 256 +#define IPCP_SOCK_PATH_PREFIX "/tmp/ipcp_sock" +#define IPCP_MSG_BUFS_SIZE IRM_MSG_BUF_SIZE + enum irm_msg_code { IRM_CREATE_IPCP, IRM_DESTROY_IPCP, @@ -39,21 +44,42 @@ enum irm_msg_code { }; struct irm_msg { - enum irm_msg_code code; - rina_name_t * name; - char * ipcp_type; + enum irm_msg_code code; + rina_name_t * name; + char * ipcp_type; + struct dif_config * conf; + char * dif_name; + char ** difs; + size_t difs_size; +}; + +enum ipcp_msg_code { + IPCP_BOOTSTRAP, + IPCP_ENROLL, + IPCP_REG, + IPCP_UNREG +}; + +struct ipcp_msg { + enum ipcp_msg_code code; struct dif_config * conf; - char * dif_name; - char ** difs; - size_t difs_size; + char * dif_name; + rina_name_t * member; + char ** difs; + size_t difs_size; }; -int client_socket_open(char * file_name); -int server_socket_open(char * file_name); +/* Returns the full socket path of an IPCP */ +char * ipcp_sock_path(pid_t pid); + +int client_socket_open(char * file_name); +int server_socket_open(char * file_name); /* Caller has to free the buffer */ -buffer_t * serialize_irm_msg(struct irm_msg * msg); +buffer_t * serialize_irm_msg(struct irm_msg * msg); +buffer_t * serialize_ipcp_msg(struct ipcp_msg * msg); /* Caller has to free all the allocated fields in the message */ -struct irm_msg * deserialize_irm_msg(buffer_t * data); +struct irm_msg * deserialize_irm_msg(buffer_t * data); +struct ipcp_msg * deserialize_ipcp_msg(buffer_t * data); #endif diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c index 294d518c..6bc3c75f 100644 --- a/src/lib/ipcp.c +++ b/src/lib/ipcp.c @@ -31,6 +31,7 @@ #include <ouroboros/logs.h> #include <ouroboros/config.h> #include <ouroboros/utils.h> +#include <ouroboros/sockets.h> #include <stdlib.h> #include <string.h> @@ -38,6 +39,45 @@ #include <sys/types.h> #include <sys/wait.h> +static int send_ipcp_msg(pid_t pid, + struct ipcp_msg * msg) +{ + int sockfd = 0; + buffer_t * buf = NULL; + char * sock_path; + + sock_path = ipcp_sock_path(pid); + if (sock_path == NULL) + return -1; + + sockfd = client_socket_open(sock_path); + if (sockfd < 0) { + free(sock_path); + return -1; + } + + buf = serialize_ipcp_msg(msg); + if (buf == NULL) { + free(sock_path); + close(sockfd); + return -1; + } + + if (write(sockfd, buf->data, buf->size) == -1) { + free(sock_path); + free(buf->data); + free(buf); + close(sockfd); + return -1; + } + + free(buf->data); + free(buf); + + close(sockfd); + return 0; +} + pid_t ipcp_create(rina_name_t name, char * ipcp_type) { @@ -48,6 +88,9 @@ pid_t ipcp_create(rina_name_t name, char * ipcp_dir = "bin/ipcpd"; char * full_name = NULL; + if (ipcp_type == NULL) + return -1; + pid = fork(); if (pid == -1) { LOG_ERR("Failed to fork"); @@ -61,14 +104,15 @@ pid_t ipcp_create(rina_name_t name, api_id = malloc(n_digits(name.api_id) + 1); if (!api_id) { LOG_ERR("Failed to malloc"); - exit(-1); + exit(EXIT_FAILURE); } sprintf(api_id, "%d", name.api_id); aei_id = malloc(n_digits(name.aei_id) + 1); if (!aei_id) { LOG_ERR("Failed to malloc"); - exit(-1); + free(api_id); + exit(EXIT_FAILURE); } sprintf(aei_id, "%d", name.aei_id); @@ -78,7 +122,9 @@ pid_t ipcp_create(rina_name_t name, full_name = malloc(len); if (!full_name) { LOG_ERR("Failed to malloc"); - exit(-1); + free(api_id); + free(aei_id); + exit(EXIT_FAILURE); } strcpy(full_name, INSTALL_DIR); @@ -97,7 +143,10 @@ pid_t ipcp_create(rina_name_t name, LOG_DBG("%s", strerror(errno)); LOG_ERR("Failed to load IPCP daemon"); LOG_ERR("Make sure to run the installed version"); - exit(-1); + free(api_id); + free(aei_id); + free(full_name); + exit(EXIT_FAILURE); } int ipcp_destroy(pid_t pid) @@ -121,20 +170,58 @@ int ipcp_reg(pid_t pid, char ** difs, size_t difs_size) { - return -1; + struct ipcp_msg msg; + + if (difs == NULL) + return -1; + + msg.code = IPCP_REG; + msg.difs = difs; + msg.difs_size = difs_size; + + if (send_ipcp_msg(pid, &msg)) { + LOG_ERR("Failed to send message to daemon"); + return -1; + } + + return 0; } int ipcp_unreg(pid_t pid, char ** difs, size_t difs_size) { - return -1; + struct ipcp_msg msg; + + if (difs == NULL) + return -1; + + msg.code = IPCP_UNREG; + msg.difs = difs; + msg.difs_size = difs_size; + + if (send_ipcp_msg(pid, &msg)) { + LOG_ERR("Failed to send message to daemon"); + return -1; + } + + return 0; } int ipcp_bootstrap(pid_t pid, struct dif_config conf) { - return -1; + struct ipcp_msg msg; + + msg.code = IPCP_BOOTSTRAP; + msg.conf = &conf; + + if (send_ipcp_msg(pid, &msg)) { + LOG_ERR("Failed to send message to daemon"); + return -1; + } + + return 0; } int ipcp_enroll(pid_t pid, @@ -143,5 +230,24 @@ int ipcp_enroll(pid_t pid, char ** n_1_difs, ssize_t n_1_difs_size) { - return -1; + struct ipcp_msg msg; + + if (n_1_difs == NULL) + return -1; + + if (dif_name == NULL) + return -1; + + msg.code = IPCP_ENROLL; + msg.dif_name = dif_name; + msg.member = &member; + msg.difs = n_1_difs; + msg.difs_size = n_1_difs_size; + + if (send_ipcp_msg(pid, &msg)) { + LOG_ERR("Failed to send message to daemon"); + return -1; + } + + return 0; } diff --git a/src/lib/irm.c b/src/lib/irm.c index a1847eed..e4804074 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -44,6 +44,8 @@ static int send_irm_msg(struct irm_msg * msg) } if (write(sockfd, buf->data, buf->size) == -1) { + free(buf->data); + free(buf); close(sockfd); return -1; } diff --git a/src/lib/sockets.c b/src/lib/sockets.c index 59ac40f9..425d0354 100644 --- a/src/lib/sockets.c +++ b/src/lib/sockets.c @@ -25,6 +25,8 @@ #include <ouroboros/logs.h> #include <ouroboros/common.h> #include <ouroboros/sockets.h> +#include <ouroboros/utils.h> + #include <sys/socket.h> #include <sys/un.h> #include <sys/stat.h> @@ -94,6 +96,37 @@ int server_socket_open(char * file_name) return sockfd; } +char * ipcp_sock_path(pid_t pid) +{ + char * full_name = NULL; + char * pid_string = NULL; + size_t len = 0; + char * delim = "-"; + + len = n_digits(pid); + pid_string = malloc(len + 1); + if (pid_string == NULL) + return NULL; + + sprintf(pid_string, "%d", pid); + + len += strlen(IPCP_SOCK_PATH_PREFIX); + len += strlen(delim); + full_name = malloc(len + 1); + if (full_name == NULL) { + free(pid_string); + return NULL; + } + + strcpy(full_name, IPCP_SOCK_PATH_PREFIX); + strcat(full_name, delim); + strcat(full_name, pid_string); + + free(pid_string); + + return full_name; +} + static int serialized_string_len(uint8_t * data) { uint8_t * seek = data; @@ -113,6 +146,20 @@ static void ser_copy_value(size_t flen, *offset += flen; } +static void ser_copy_name(rina_name_t * name, + uint8_t * data, + int * offset) +{ + ser_copy_value(strlen(name->ap_name) + 1, + data, name->ap_name, offset); + ser_copy_value(sizeof(int), data, + &name->api_id, offset); + ser_copy_value(strlen(name->ae_name) + 1, + data, name->ae_name, offset); + ser_copy_value(sizeof(int), data, + &name->aei_id, offset); +} + static void deser_copy_value(size_t flen, void * dst, void * src, @@ -152,12 +199,60 @@ static void deser_copy_size_t(uint8_t * data, deser_copy_value(sizeof(size_t), dst, data, offset); } -static void deser_copy_enum(uint8_t * data, - enum irm_msg_code * dst, - int * offset) +static rina_name_t * deser_copy_name(uint8_t * data, + int * offset) { - *dst = 0; - deser_copy_value(sizeof(enum irm_msg_code), dst, data, offset); + rina_name_t * name; + + name = name_create(); + if (name == NULL) { + LOG_ERR("Failed to alloc memory"); + return NULL; + } + + if (deser_copy_string(data, &name->ap_name, offset)) { + name_destroy(name); + return NULL; + } + + deser_copy_int(data, &name->api_id, offset); + + if (deser_copy_string(data, &name->ae_name, offset)) { + name_destroy(name); + return NULL; + } + + deser_copy_int(data, &name->aei_id, offset); + + return name; +} + + +/* Move these to a separate file? */ +static buffer_t * buffer_create() +{ + buffer_t * buf; + + buf = malloc(sizeof(*buf)); + if (buf == NULL) + return NULL; + + buf->data = malloc(IRM_MSG_BUF_SIZE); + if (buf->data == NULL) { + free(buf); + return NULL; + } + + return buf; +} + +static void buffer_destroy(buffer_t * buf) +{ + if (buf->data != NULL) + free(buf->data); + + if (buf != NULL) + free(buf); } buffer_t * serialize_irm_msg(struct irm_msg * msg) @@ -171,47 +266,26 @@ buffer_t * serialize_irm_msg(struct irm_msg * msg) if (msg == NULL) return NULL; - buf = malloc(sizeof(*buf)); + buf = buffer_create(); if (buf == NULL) return NULL; - buf->data = malloc(IRM_MSG_BUF_SIZE); - if (buf->data == NULL) { - free(buf); - return NULL; - } - data = buf->data; ser_copy_value(sizeof(enum irm_msg_code), data, &msg->code, &offset); if (!name_is_ok(msg->name)) { LOG_ERR("Null pointer passed"); - free(buf->data); - free(buf); + buffer_destroy(buf); return NULL; } - - /* - * Every IRM message passes the name, may change - * Move to separate function when it does - */ - ser_copy_value(strlen(msg->name->ap_name) + 1, data, - msg->name->ap_name, &offset); - - ser_copy_value(sizeof(int), data, &msg->name->api_id, &offset); - - ser_copy_value(strlen(msg->name->ae_name) + 1, data, - msg->name->ae_name, &offset); - - ser_copy_value(sizeof(int), data, &msg->name->aei_id, &offset); + ser_copy_name(msg->name, data, &offset); switch (msg->code) { case IRM_CREATE_IPCP: if (!msg->ipcp_type) { LOG_ERR("Null pointer passed"); - free(buf->data); - free(buf); + buffer_destroy(buf); return NULL; } @@ -225,8 +299,7 @@ buffer_t * serialize_irm_msg(struct irm_msg * msg) break; case IRM_ENROLL_IPCP: if (msg->dif_name == NULL) { - free(buf->data); - free(buf); + buffer_destroy(buf); return NULL; } @@ -237,8 +310,7 @@ buffer_t * serialize_irm_msg(struct irm_msg * msg) case IRM_REG_IPCP: case IRM_UNREG_IPCP: if (msg->difs == NULL || msg->difs[0] == NULL) { - free(buf->data); - free(buf); + buffer_destroy(buf); return NULL; } @@ -253,8 +325,7 @@ buffer_t * serialize_irm_msg(struct irm_msg * msg) break; default: LOG_ERR("Don't know that code"); - free(buf->data); - free(buf); + buffer_destroy(buf); return NULL; } @@ -281,43 +352,24 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) return NULL; } - deser_copy_enum(data->data, &msg->code, &offset); + deser_copy_value(sizeof(enum irm_msg_code), + &msg->code, data->data, &offset); - msg->name = name_create(); + msg->name = deser_copy_name(data->data, &offset); if (msg->name == NULL) { - LOG_ERR("Failed to alloc memory"); + LOG_ERR("Failed to reconstruct name"); free(msg); return NULL; } - if (deser_copy_string(data->data, - &msg->name->ap_name, - &offset)) { - name_destroy(msg->name); - free(msg); - return NULL; - } - - deser_copy_int(data->data, &msg->name->api_id, &offset); - - if (deser_copy_string(data->data, - &msg->name->ae_name, - &offset)) { - name_destroy(msg->name); - free(msg); - return NULL; - } - - deser_copy_int(data->data, &msg->name->aei_id, &offset); - switch (msg->code) { case IRM_CREATE_IPCP: - if (deser_copy_string(data->data, - &msg->ipcp_type, - &offset)) { - name_destroy(msg->name); - free(msg); - return NULL; + if (deser_copy_string(data->data, + &msg->ipcp_type, + &offset)) { + name_destroy(msg->name); + free(msg); + return NULL; } break; @@ -369,3 +421,167 @@ struct irm_msg * deserialize_irm_msg(buffer_t * data) return msg; } + +buffer_t * serialize_ipcp_msg(struct ipcp_msg * msg) +{ + buffer_t * buf = NULL; + uint8_t * data = NULL; + int offset = 0; + char ** pos = NULL; + int i = 0; + + if (msg == NULL) + return NULL; + + buf = buffer_create(); + if (buf == NULL) + return NULL; + + data = buf->data; + + ser_copy_value(sizeof(enum ipcp_msg_code), + data, &msg->code, &offset); + + switch (msg->code) { + case IPCP_BOOTSTRAP: + break; + case IPCP_ENROLL: + if (msg->dif_name == NULL) { + buffer_destroy(buf); + return NULL; + } + + ser_copy_value(strlen(msg->dif_name) + 1, data, + msg->dif_name, &offset); + + if (!name_is_ok(msg->member)) { + LOG_ERR("Null pointer passed"); + buffer_destroy(buf); + return NULL; + } + ser_copy_name(msg->member, data, &offset); + + /* All these operations end with a list of DIFs */ + case IPCP_REG: + case IPCP_UNREG: + if (msg->difs == NULL || msg->difs[0] == NULL) { + buffer_destroy(buf); + return NULL; + } + + ser_copy_value(sizeof(size_t), data, &msg->difs_size, &offset); + + pos = msg->difs; + for (i = 0; i < msg->difs_size; i++) { + ser_copy_value(strlen(*pos) + 1, data, *pos, &offset); + pos++; + } + break; + default: + LOG_ERR("Don't know that code"); + buffer_destroy(buf); + return NULL; + } + + buf->size = offset; + + return buf; +} + +struct ipcp_msg * deserialize_ipcp_msg(buffer_t * data) +{ + struct ipcp_msg * msg; + int i, j; + int offset = 0; + size_t difs_size; + + if (data == NULL || data->data == NULL) { + LOG_ERR("Got a null pointer"); + return NULL; + } + + msg = malloc(sizeof(*msg)); + if (msg == NULL) { + LOG_ERR("Failed to allocate memory"); + return NULL; + } + + deser_copy_value(sizeof(enum ipcp_msg_code), + &msg->code, data->data, &offset); + + switch (msg->code) { + case IPCP_BOOTSTRAP: + break; + case IPCP_ENROLL: + if (deser_copy_string(data->data, + &msg->dif_name, + &offset)) { + free(msg); + return NULL; + } + + msg->member = deser_copy_name(data->data, &offset); + if (msg->member == NULL) { + LOG_ERR("Failed to reconstruct name"); + free(msg->dif_name); + free(msg); + return NULL; + } + + deser_copy_size_t(data->data, &difs_size, &offset); + msg->difs_size = difs_size; + + msg->difs = malloc(sizeof(*(msg->difs)) * difs_size); + if (msg->difs == NULL) { + free(msg->dif_name); + name_destroy(msg->member); + free(msg); + return NULL; + } + + for (i = 0; i < difs_size; i++) { + if (deser_copy_string(data->data, + &msg->difs[i], + &offset)) { + for (j = 0; j < i; j++) + free(msg->difs[j]); + free(msg->dif_name); + free(msg->difs); + name_destroy(msg->member); + free(msg); + return NULL; + } + } + break; + case IPCP_REG: + case IPCP_UNREG: + deser_copy_size_t(data->data, &difs_size, &offset); + msg->difs_size = difs_size; + + msg->difs = malloc(sizeof(*(msg->difs)) * difs_size); + if (msg->difs == NULL) { + free(msg); + return NULL; + } + + for (i = 0; i < difs_size; i++) { + if (deser_copy_string(data->data, + &msg->difs[i], + &offset)) { + for (j = 0; j < i; j++) + free(msg->difs[j]); + free(msg->difs); + free(msg); + return NULL; + } + } + + break; + default: + LOG_ERR("Don't know that code"); + free(msg); + return NULL; + } + + return msg; +} |