summaryrefslogtreecommitdiff
path: root/src/ipcpd/ipcp.c
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2016-04-17 12:08:49 +0200
committerdimitri staessens <[email protected]>2016-04-18 22:25:34 +0200
commit21b304b46a347772c1338b22fba6a15291bb2945 (patch)
treeeb8d0980ded5216b282a7932ecce38fd09473210 /src/ipcpd/ipcp.c
parentd8e9019fcb56a49c6730bbe7d47e5e1cec682a2d (diff)
downloadouroboros-21b304b46a347772c1338b22fba6a15291bb2945.tar.gz
ouroboros-21b304b46a347772c1338b22fba6a15291bb2945.zip
ipcpd: initial IPC processes
Basic functions for implementation of IPC processes, and implementation of core functions of the shim IPCP over UDP. Updates to the build system to compile these IPC processes, as well as some fixes in the irmd (rudimentary capturing exit signals) and some fixes in the library, mainly relating to the messaging. Basic implementation of creation / bootstrapping / deletion of the shim UDP. Placeholders for other functions.
Diffstat (limited to 'src/ipcpd/ipcp.c')
-rw-r--r--src/ipcpd/ipcp.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
new file mode 100644
index 00000000..a1276769
--- /dev/null
+++ b/src/ipcpd/ipcp.c
@@ -0,0 +1,195 @@
+/*
+ * Ouroboros - Copyright (C) 2016
+ *
+ * IPC process main loop
+ *
+ * Dimitri Staessens <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <ouroboros/config.h>
+#include <ouroboros/ipcp.h>
+#include <sys/socket.h>
+#include <stdlib.h>
+#include "ipcp.h"
+
+#define OUROBOROS_PREFIX "ipcpd/ipcp"
+#include <ouroboros/logs.h>
+
+int ipcp_main_loop(struct ipcp * _ipcp)
+{
+ int lsockfd;
+ int sockfd;
+ uint8_t buf[IPCP_MSG_BUF_SIZE];
+
+ ipcp_msg_t * msg;
+ ssize_t count;
+ buffer_t buffer;
+ ipcp_msg_t ret_msg = IPCP_MSG__INIT;
+
+ dif_config_msg_t * conf_msg;
+ struct dif_config conf;
+
+ if (_ipcp == NULL) {
+ LOG_ERR("Invalid ipcp struct.");
+ return 1;
+ }
+
+ sockfd = server_socket_open(ipcp_sock_path(getpid()));
+ if (sockfd < 0) {
+ LOG_ERR("Could not open server socket.");
+ return 1;
+ }
+
+ while (true) {
+ ret_msg.code = IPCP_MSG_CODE__IPCP_REPLY;
+
+ lsockfd = accept(sockfd, 0, 0);
+ if (lsockfd < 0) {
+ LOG_ERR("Cannot accept new connection");
+ break;
+ }
+
+ count = read(lsockfd, buf, IPCP_MSG_BUF_SIZE);
+ if (count <= 0) {
+ LOG_ERR("Failed to read from socket");
+ close(lsockfd);
+ continue;
+ }
+
+ msg = ipcp_msg__unpack(NULL, count, buf);
+ if (msg == NULL) {
+ close(lsockfd);
+ continue;
+ }
+
+ switch (msg->code) {
+ case IPCP_MSG_CODE__IPCP_BOOTSTRAP:
+ conf_msg = msg->conf;
+ conf.type = conf_msg->ipcp_type;
+ if (conf_msg->ipcp_type == IPCP_NORMAL) {
+ conf.addr_size = conf_msg->addr_size;
+ conf.cep_id_size = conf_msg->cep_id_size;
+ conf.pdu_length_size
+ = conf_msg->pdu_length_size;
+ conf.qos_id_size = conf_msg->qos_id_size;
+ conf.seqno_size = conf_msg->seqno_size;
+ conf.ttl_size = conf_msg->seqno_size;
+ conf.chk_size = conf_msg->chk_size;
+ conf.min_pdu_size = conf_msg->min_pdu_size;
+ conf.max_pdu_size = conf_msg->max_pdu_size;
+ }
+ if (conf_msg->ipcp_type == IPCP_SHIM_UDP) {
+ conf.ip_addr = conf_msg->ip_addr;
+ conf.dns_addr = conf_msg->dns_addr;
+ }
+
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_bootstrap(&conf);
+ break;
+ case IPCP_MSG_CODE__IPCP_ENROLL:
+ if (_ipcp->ops->ipcp_enroll == NULL) {
+ LOG_ERR("ipcp_enroll unsupported.");
+ } else {
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_enroll(
+ msg->member_name, msg->n_1_dif);
+ }
+ break;
+
+ case IPCP_MSG_CODE__IPCP_REG:
+ if (_ipcp->ops->ipcp_reg == NULL) {
+ LOG_ERR("ipcp_reg unsupported.");
+
+ } else {
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_reg(
+ msg->dif_names, msg->len);
+ }
+ break;
+ case IPCP_MSG_CODE__IPCP_UNREG:
+ if (_ipcp->ops->ipcp_unreg == NULL) {
+ LOG_ERR("ipcp_unreg unsupported.");
+
+ } else {
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_unreg(
+ msg->dif_names, msg->len);
+ }
+ break;
+ case IPCP_MSG_CODE__IPCP_AP_REG:
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_ap_reg(
+ msg->ap_name, msg->reg_ap_id);
+ break;
+ case IPCP_MSG_CODE__IPCP_AP_UNREG:
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_ap_unreg(
+ msg->reg_ap_id);
+ break;
+ case IPCP_MSG_CODE__IPCP_FLOW_ALLOC:
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_flow_alloc(
+ msg->port_id,
+ msg->dst_ap_name,
+ msg->ap_name,
+ msg->ae_name,
+ NULL);
+ break;
+ case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP:
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_flow_alloc_resp(
+ msg->port_id, msg->result);
+ break;
+ case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC:
+ ret_msg.has_result = true;
+ ret_msg.result = _ipcp->ops->ipcp_flow_dealloc(
+ msg->port_id);
+ break;
+ default:
+ LOG_ERR("Don't know that message code");
+ break;
+ }
+
+ ipcp_msg__free_unpacked(msg, NULL);
+
+ buffer.size = ipcp_msg__get_packed_size(&ret_msg);
+ if (buffer.size == 0) {
+ LOG_ERR("Failed to send reply message");
+ close(lsockfd);
+ continue;
+ }
+
+ buffer.data = malloc(buffer.size);
+ if (buffer.data == NULL) {
+ close(lsockfd);
+ continue;
+ }
+
+ ipcp_msg__pack(&ret_msg, buffer.data);
+
+ if (write(lsockfd, buffer.data, buffer.size) == -1) {
+ free(buffer.data);
+ close(lsockfd);
+ continue;
+ }
+
+ free(buffer.data);
+ close(lsockfd);
+ }
+
+ return 0;
+}