summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/sockets.h50
-rw-r--r--src/lib/ipcp.c122
-rw-r--r--src/lib/irm.c2
-rw-r--r--src/lib/sockets.c346
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;
+}