From 7834e92b218da69cd934679dec9c2d714d89d15e Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Mon, 13 Jun 2016 13:48:17 +0200 Subject: lib, irmd, tools, ipcpd: updates to dev API. The registration function has been moved to the irm tool, applications now need to be registered by an administrator. Currently only supports one instance per registered name, and an AP can be registered under only one name. The irmd can now start a registered server application on demand. For the full functionality of the tool, execute "irm register". AP name removed from flow allocation. Flow allocation does not send the source ap name as it is quite useless. The accept() call now only returns the AE name. --- include/ouroboros/dev.h | 6 +- include/ouroboros/ipcp.h | 2 - include/ouroboros/irm.h | 18 ++- include/ouroboros/utils.h | 3 + src/ipcpd/ipcp-ops.h | 1 - src/ipcpd/ipcp.c | 1 - src/ipcpd/local/main.c | 6 +- src/ipcpd/shim-udp/main.c | 12 +- src/ipcpd/shim-udp/shim_udp_messages.proto | 1 - src/irmd/main.c | 251 ++++++++++++++++------------- src/lib/dev.c | 123 +------------- src/lib/ipcp.c | 8 +- src/lib/irm.c | 72 ++++++--- src/lib/irmd_messages.proto | 39 ++--- src/lib/utils.c | 18 +++ src/tools/cbr/cbr.c | 42 +++-- src/tools/cbr/cbr_client.c | 16 +- src/tools/cbr/cbr_server.c | 30 +--- src/tools/echo/echo.c | 19 ++- src/tools/echo/echo_client.c | 11 +- src/tools/echo/echo_server.c | 32 +--- src/tools/irm/CMakeLists.txt | 4 +- src/tools/irm/irm.c | 5 +- src/tools/irm/irm_ops.h | 4 +- src/tools/irm/irm_register.c | 123 ++++++++++++++ src/tools/irm/irm_register_ipcp.c | 79 --------- src/tools/irm/irm_unregister.c | 116 +++++++++++++ src/tools/irm/irm_unregister_ipcp.c | 80 --------- 28 files changed, 550 insertions(+), 572 deletions(-) create mode 100644 src/tools/irm/irm_register.c delete mode 100644 src/tools/irm/irm_register_ipcp.c create mode 100644 src/tools/irm/irm_unregister.c delete mode 100644 src/tools/irm/irm_unregister_ipcp.c diff --git a/include/ouroboros/dev.h b/include/ouroboros/dev.h index 506fa789..1f664d35 100644 --- a/include/ouroboros/dev.h +++ b/include/ouroboros/dev.h @@ -36,12 +36,8 @@ int ap_init(char * ap_name); void ap_fini(void); -/* Returns file descriptor */ -int ap_reg(char ** difs, size_t difs_size); -int ap_unreg(char ** difs, size_t difs_size); - /* Returns file descriptor (> 0) and client name(s) */ -int flow_accept(int fd, char ** ap_name, char ** ae_name); +int flow_accept(char ** ae_name); int flow_alloc_resp(int fd, int result); /* Returns file descriptor */ diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index 08bee33e..89b9fa92 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -63,7 +63,6 @@ int ipcp_flow_alloc(pid_t pid, int port_id, pid_t n_pid, char * dst_name, - char * src_ap_name, char * src_ae_name, enum qos_cube qos); int ipcp_flow_alloc_resp(pid_t pid, @@ -76,7 +75,6 @@ int ipcp_flow_alloc_resp(pid_t pid, /* Returns the port_id */ int ipcp_flow_req_arr(pid_t pid, char * dst_name, - char * src_ap_name, char * src_ae_name); int ipcp_flow_alloc_reply(pid_t pid, int port_id, diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index 37524098..9d547643 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -39,10 +39,16 @@ int irm_enroll_ipcp(instance_name_t * api, int irm_bootstrap_ipcp(instance_name_t * api, struct dif_config * conf); -int irm_reg_ipcp(instance_name_t * api, - char ** difs, - size_t difs_size); -int irm_unreg_ipcp(const instance_name_t * api, - char ** difs, - size_t difs_size); +int irm_reg(char * name, + instance_name_t * api, + int argc, + char ** argv, + bool autoexec, + char ** difs, + size_t difs_size); +int irm_unreg(char * name, + const instance_name_t * api, + char ** difs, + size_t difs_size, + bool hard); #endif /* OUROBOROS_IRM_H */ diff --git a/include/ouroboros/utils.h b/include/ouroboros/utils.h index a1d2ac96..17bd41ee 100644 --- a/include/ouroboros/utils.h +++ b/include/ouroboros/utils.h @@ -31,3 +31,6 @@ int n_digits(unsigned i); /* Returns a copy of the source string */ char * strdup(const char * src); + +/* gets the application name */ +char * path_strip(char * src); diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/ipcp-ops.h index 72c57595..ffbc9cd7 100644 --- a/src/ipcpd/ipcp-ops.h +++ b/src/ipcpd/ipcp-ops.h @@ -41,7 +41,6 @@ struct ipcp_ops { int (* ipcp_flow_alloc)(pid_t n_pid, int port_id, char * dst_ap_name, - char * src_ap_name, char * src_ae_name, enum qos_cube qos); int (* ipcp_flow_alloc_resp)(pid_t n_pid, diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index e0dd1b60..09dfa449 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -206,7 +206,6 @@ void * ipcp_main_loop(void * o) _ipcp->ops->ipcp_flow_alloc(msg->pid, msg->port_id, msg->dst_name, - msg->src_ap_name, msg->src_ae_name, msg->qos_cube); break; diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index 4a0ad683..cb20a336 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -341,7 +341,6 @@ static int ipcp_local_name_unreg(char * name) static int ipcp_local_flow_alloc(pid_t n_pid, int port_id, char * dst_name, - char * src_ap_name, char * src_ae_name, enum qos_cube qos) { @@ -350,9 +349,9 @@ static int ipcp_local_flow_alloc(pid_t n_pid, struct shm_ap_rbuff * rb; - LOG_INFO("Allocating flow from %s to %s.", src_ap_name, dst_name); + LOG_INFO("Allocating flow to %s.", dst_name); - if (dst_name == NULL || src_ap_name == NULL || src_ae_name == NULL) + if (dst_name == NULL || src_ae_name == NULL) return -1; /* This ipcpd has all QoS */ @@ -387,7 +386,6 @@ static int ipcp_local_flow_alloc(pid_t n_pid, /* reply to IRM */ port_id = ipcp_flow_req_arr(getpid(), dst_name, - src_ap_name, src_ae_name); if (port_id < 0) { diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 48fa141e..99fb134d 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -384,7 +384,6 @@ static int send_shim_udp_msg(shim_udp_msg_t * msg, static int ipcp_udp_port_alloc(uint32_t dst_ip_addr, uint32_t src_udp_port, char * dst_name, - char * src_ap_name, char * src_ae_name) { shim_udp_msg_t msg = SHIM_UDP_MSG__INIT; @@ -392,7 +391,6 @@ static int ipcp_udp_port_alloc(uint32_t dst_ip_addr, msg.code = SHIM_UDP_MSG_CODE__FLOW_REQ; msg.src_udp_port = src_udp_port; msg.dst_name = dst_name; - msg.src_ap_name = src_ap_name; msg.src_ae_name = src_ae_name; return send_shim_udp_msg(&msg, dst_ip_addr); @@ -428,7 +426,6 @@ static int ipcp_udp_port_dealloc(uint32_t dst_ip_addr, static int ipcp_udp_port_req(struct sockaddr_in * c_saddr, char * dst_name, - char * src_ap_name, char * src_ae_name) { int fd; @@ -486,7 +483,6 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr, /* reply to IRM */ port_id = ipcp_flow_req_arr(getpid(), dst_name, - src_ap_name, src_ae_name); if (port_id < 0) { @@ -682,7 +678,6 @@ static void * ipcp_udp_listener() c_saddr.sin_port = msg->src_udp_port; ipcp_udp_port_req(&c_saddr, msg->dst_name, - msg->src_ap_name, msg->src_ae_name); break; case SHIM_UDP_MSG_CODE__FLOW_REPLY: @@ -1214,7 +1209,6 @@ static int ipcp_udp_name_unreg(char * name) static int ipcp_udp_flow_alloc(pid_t n_pid, int port_id, char * dst_name, - char * src_ap_name, char * src_ae_name, enum qos_cube qos) { @@ -1229,12 +1223,11 @@ static int ipcp_udp_flow_alloc(pid_t n_pid, #endif struct shm_ap_rbuff * rb; - LOG_INFO("Allocating flow from %s to %s.", src_ap_name, dst_name); + LOG_INFO("Allocating flow to %s.", dst_name); - if (dst_name == NULL || src_ap_name == NULL || src_ae_name == NULL) + if (dst_name == NULL || src_ae_name == NULL) return -1; if (strlen(dst_name) > 255 - || strlen(src_ap_name) > 255 || strlen(src_ae_name) > 255) { LOG_ERR("Name too long for this shim."); return -1; @@ -1332,7 +1325,6 @@ static int ipcp_udp_flow_alloc(pid_t n_pid, if (ipcp_udp_port_alloc(ip_addr, f_saddr.sin_port, dst_name, - src_ap_name, src_ae_name) < 0) { LOG_DBGF("Port alloc returned -1."); rw_lock_rdlock(&_ipcp->state_lock); diff --git a/src/ipcpd/shim-udp/shim_udp_messages.proto b/src/ipcpd/shim-udp/shim_udp_messages.proto index a15fc18c..e6bac908 100644 --- a/src/ipcpd/shim-udp/shim_udp_messages.proto +++ b/src/ipcpd/shim-udp/shim_udp_messages.proto @@ -7,7 +7,6 @@ enum shim_udp_msg_code { message shim_udp_msg { required shim_udp_msg_code code = 1; optional string dst_name = 2; - optional string src_ap_name = 3; optional string src_ae_name = 4; required sint32 src_udp_port = 5; optional sint32 dst_udp_port = 6; diff --git a/src/irmd/main.c b/src/irmd/main.c index 03f9a3c2..ea52d67f 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -72,9 +72,10 @@ struct reg_name_entry { /* FIXME: make a list resolve to AP-I instead */ instance_name_t * api; + char ** argv; + bool autoexec; bool accept; - char * req_ap_name; char * req_ae_name; int response; int flow_arrived; @@ -264,8 +265,9 @@ static struct reg_name_entry * reg_name_entry_create() e->name = NULL; e->api = NULL; + e->argv = NULL; + e->autoexec = false; e->accept = false; - e->req_ap_name = NULL; e->req_ae_name = NULL; e->flow_arrived = -1; @@ -286,13 +288,17 @@ static struct reg_name_entry * reg_name_entry_create() static struct reg_name_entry * reg_name_entry_init(struct reg_name_entry * e, char * name, - instance_name_t * api) + instance_name_t * api, + char ** argv, + bool ae) { if (e == NULL || name == NULL || api == NULL) return NULL; - e->name = name; - e->api = api; + e->name = name; + e->api = api; + e->argv = argv; + e->autoexec = ae; return e; } @@ -335,6 +341,21 @@ static struct reg_name_entry * get_reg_name_entry_by_name(char * name) return NULL; } +static struct reg_name_entry * get_reg_name_entry_by_ap_name(char * ap_name) +{ + struct list_head * pos = NULL; + + list_for_each(pos, &instance->reg_names) { + struct reg_name_entry * e = + list_entry(pos, struct reg_name_entry, next); + + if (strcmp(ap_name, e->api->name) == 0) + return e; + } + + return NULL; +} + static struct reg_name_entry * get_reg_name_entry_by_id(pid_t pid) { struct list_head * pos = NULL; @@ -351,7 +372,10 @@ static struct reg_name_entry * get_reg_name_entry_by_id(pid_t pid) } /* FIXME: add only name when we have NSM solved */ -static int reg_name_entry_add_name_instance(char * name, instance_name_t * api) +static int reg_name_entry_add_name_instance(char * name, + instance_name_t * api, + char ** argv, + bool autoexec) { struct reg_name_entry * e = get_reg_name_entry_by_name(name); if (e == NULL) { @@ -359,7 +383,8 @@ static int reg_name_entry_add_name_instance(char * name, instance_name_t * api) if (e == NULL) return -1; - if (reg_name_entry_init(e, name, api) == NULL) { + if (reg_name_entry_init(e, name, api, argv, autoexec) + == NULL) { reg_name_entry_destroy(e); return -1; } @@ -595,46 +620,12 @@ static int enroll_ipcp(instance_name_t * api, return 0; } -static int reg_ipcp(instance_name_t * api, - char ** difs, - size_t difs_size) -{ - rw_lock_rdlock(&instance->state_lock); - rw_lock_wrlock(&instance->reg_lock); - - if (ipcp_reg(api->id, difs, difs_size)) { - rw_lock_unlock(&instance->reg_lock); - rw_lock_unlock(&instance->state_lock); - LOG_ERR("Could not register IPCP to N-1 DIF(s)."); - return -1; - } - - rw_lock_unlock(&instance->reg_lock); - rw_lock_unlock(&instance->state_lock); - - return 0; -} - -static int unreg_ipcp(instance_name_t * api, - char ** difs, - size_t difs_size) -{ - rw_lock_rdlock(&instance->state_lock); - rw_lock_wrlock(&instance->reg_lock); - if (ipcp_unreg(api->id, difs, difs_size)) { - rw_lock_unlock(&instance->reg_lock); - rw_lock_unlock(&instance->state_lock); - LOG_ERR("Could not unregister IPCP from N-1 DIF(s)."); - return -1; - } - rw_lock_unlock(&instance->reg_lock); - rw_lock_unlock(&instance->state_lock); - - return 0; -} - -static int ap_reg(char * ap_name, +static int ap_reg(char * name, + char * ap_name, pid_t ap_id, + int argc, + char ** argv, + bool autoexec, char ** difs, size_t len) { @@ -644,6 +635,7 @@ static int ap_reg(char * ap_name, struct reg_name_entry * rne = NULL; instance_name_t * api = NULL; + char ** argv_dup = NULL; rw_lock_rdlock(&instance->state_lock); rw_lock_wrlock(&instance->reg_lock); @@ -661,16 +653,15 @@ static int ap_reg(char * ap_name, return -1; } - if (instance_name_init_from(api, ap_name, ap_id) == NULL) { + if (instance_name_init_from(api, path_strip(ap_name), ap_id) == NULL) { rw_lock_unlock(&instance->reg_lock); rw_lock_unlock(&instance->state_lock); instance_name_destroy(api); return -1; } - /* check if this ap_name is already registered */ - - rne = get_reg_name_entry_by_name(ap_name); + /* check if this name is already registered */ + rne = get_reg_name_entry_by_name(name); if (rne != NULL) { rw_lock_unlock(&instance->reg_lock); rw_lock_unlock(&instance->state_lock); @@ -678,11 +669,6 @@ static int ap_reg(char * ap_name, return -1; /* can only register one instance for now */ } - /* - * for now, the whatevercast name is the same as the ap_name and - * contains a single instance only - */ - list_for_each(pos, &instance->ipcps) { struct ipcp_entry * e = list_entry(pos, struct ipcp_entry, next); @@ -692,26 +678,42 @@ static int ap_reg(char * ap_name, for (i = 0; i < len; ++i) { if (wildcard_match(difs[i], e->dif_name) == 0) { - if (ipcp_name_reg(e->api->id, ap_name)) { + if (ipcp_name_reg(e->api->id, name)) { LOG_ERR("Could not register " - "%s in DIF %s.", - api->name, e->dif_name); + "%s in DIF %s as %s.", + api->name, e->dif_name, name); } else { + LOG_INFO("Registered %s as %s in %s", + api->name, name, e->dif_name); ++ret; } } } } - if (ret == 0) { rw_lock_unlock(&instance->reg_lock); rw_lock_unlock(&instance->state_lock); instance_name_destroy(api); return -1; } + + /* we need to duplicate argv */ + if (argc != 0) { + argv_dup = malloc ((argc + 2) * sizeof(*argv_dup)); + argv_dup[0] = strdup(api->name); + for (i = 1; i <= argc; ++i) + argv_dup[i] = strdup(argv[i - 1]); + argv_dup[argc + 1] = NULL; + } + + /* for now, we register single instances */ - ret = reg_name_entry_add_name_instance(strdup(ap_name), - api); + if ((ret = reg_name_entry_add_name_instance(strdup(name), + api, + argv_dup, + autoexec)) + < 0) + LOG_DBGF("Failed to add application %s.", api->name); rw_lock_unlock(&instance->reg_lock); rw_lock_unlock(&instance->state_lock); @@ -719,38 +721,28 @@ static int ap_reg(char * ap_name, return ret; } -static int ap_unreg(char * ap_name, +static int ap_unreg(char * name, + char * ap_name, pid_t ap_id, char ** difs, - size_t len) + size_t len, + bool hard) { int i; int ret = 0; struct reg_name_entry * rne = NULL; struct list_head * pos = NULL; + if (name == NULL || len == 0 || difs == NULL || difs[0] == NULL) + return -1; + rw_lock_rdlock(&instance->state_lock); rw_lock_wrlock(&instance->reg_lock); - /* check if ap_name is registered */ - rne = get_reg_name_entry_by_id(ap_id); - if (rne == NULL) { - rw_lock_unlock(&instance->reg_lock); - rw_lock_unlock(&instance->state_lock); - return 0; /* no such id */ - } - - if (strcmp(ap_name, rne->api->name)) { - rw_lock_unlock(&instance->reg_lock); - rw_lock_unlock(&instance->state_lock); - return 0; - } - - if (instance->ipcps.next == NULL) { - rw_lock_unlock(&instance->reg_lock); - rw_lock_unlock(&instance->state_lock); - LOG_ERR("No IPCPs in this system."); - return 0; + if (!hard && strcmp(difs[0], "*") != 0) { + LOG_INFO("Unregistration not complete yet."); + LOG_MISSING; + return -1; } list_for_each(pos, &instance->ipcps) { @@ -762,7 +754,8 @@ static int ap_unreg(char * ap_name, for (i = 0; i < len; ++i) { if (wildcard_match(difs[i], e->dif_name) == 0) { - if (ipcp_name_unreg(e->api->id, rne->name)) { + if (ipcp_name_unreg(e->api->id, + rne->name)) { LOG_ERR("Could not unregister " "%s in DIF %s.", rne->name, e->dif_name); @@ -772,7 +765,6 @@ static int ap_unreg(char * ap_name, } } - /* FIXME: check if name is not registered in any DIF before removing */ reg_name_entry_del_name(rne->name); rw_lock_unlock(&instance->reg_lock); @@ -782,8 +774,8 @@ static int ap_unreg(char * ap_name, } static struct port_map_entry * flow_accept(pid_t pid, - char ** ap_name, - char ** ae_name) + char * srv_ap_name, + char ** dst_ae_name) { struct port_map_entry * pme; struct reg_name_entry * rne = NULL; @@ -791,11 +783,21 @@ static struct port_map_entry * flow_accept(pid_t pid, rw_lock_rdlock(&instance->state_lock); rw_lock_rdlock(&instance->reg_lock); - rne = get_reg_name_entry_by_id(pid); + rne = get_reg_name_entry_by_ap_name(srv_ap_name); if (rne == NULL) { rw_lock_unlock(&instance->reg_lock); rw_lock_unlock(&instance->state_lock); - LOG_DBGF("Unregistered AP calling accept()."); + LOG_DBGF("AP %s is unknown.", srv_ap_name); + return NULL; + } + + if (rne->api->id == 0) { + rne->api->id = pid; + } else if (rne->api->id != pid) { + rw_lock_unlock(&instance->reg_lock); + rw_lock_unlock(&instance->state_lock); + LOG_DBGF("Can only register one instance."); + LOG_MISSING; return NULL; } @@ -843,9 +845,8 @@ static struct port_map_entry * flow_accept(pid_t pid, return NULL; } - *ap_name = rne->req_ap_name; - if (ae_name != NULL) - *ae_name = rne->req_ae_name; + if (dst_ae_name != NULL) + *dst_ae_name = rne->req_ae_name; rw_lock_unlock(&instance->flows_lock); rw_lock_unlock(&instance->state_lock); @@ -919,7 +920,6 @@ static int flow_alloc_resp(pid_t n_pid, static struct port_map_entry * flow_alloc(pid_t pid, char * dst_name, - char * src_ap_name, char * src_ae_name, struct qos_spec * qos) { @@ -967,7 +967,6 @@ static struct port_map_entry * flow_alloc(pid_t pid, pme->port_id, pme->n_pid, dst_name, - src_ap_name, src_ae_name, QOS_CUBE_BE) < 0) { rw_lock_rdlock(&instance->state_lock); @@ -1085,9 +1084,30 @@ static int flow_dealloc(int port_id) return ret; } +static int auto_execute(char * ap, char ** argv) +{ + pid_t pid; + LOG_INFO("Executing %s.", ap); + pid = fork(); + if (pid == -1) { + LOG_ERR("Failed to fork"); + return pid; + } + + if (pid != 0) { + return pid; + } + + execv(ap, argv); + + LOG_DBG("Failed to execute."); + + exit(EXIT_FAILURE); + return 0; +} + static struct port_map_entry * flow_req_arr(pid_t pid, char * dst_name, - char * ap_name, char * ae_name) { struct reg_name_entry * rne; @@ -1125,13 +1145,20 @@ static struct port_map_entry * flow_req_arr(pid_t pid, pthread_mutex_lock(&rne->acc_lock); - rne->req_ap_name = ap_name; rne->req_ae_name = ae_name; if (rne->accept == false) { - pthread_mutex_unlock(&rne->acc_lock); - LOG_WARN("This AP is not accepting flow allocations."); - return NULL; + if (rne->autoexec) { + pme->n_pid = auto_execute(rne->api->name, rne->argv); + while (rne->accept == false) + sched_yield(); + } + else { + pthread_mutex_unlock(&rne->acc_lock); + LOG_WARN("%s is not accepting flow allocations.", + rne->name); + return NULL; + } } rne->flow_arrived = 0; @@ -1345,35 +1372,29 @@ void * mainloop() ret_msg.result = enroll_ipcp(&api, msg->dif_name[0]); break; - case IRM_MSG_CODE__IRM_REG_IPCP: - ret_msg.has_result = true; - ret_msg.result = reg_ipcp(&api, - msg->dif_name, - msg->n_dif_name); - break; - case IRM_MSG_CODE__IRM_UNREG_IPCP: - ret_msg.has_result = true; - ret_msg.result = unreg_ipcp(&api, - msg->dif_name, - msg->n_dif_name); - break; case IRM_MSG_CODE__IRM_AP_REG: ret_msg.has_result = true; - ret_msg.result = ap_reg(msg->ap_name, + ret_msg.result = ap_reg(msg->dst_name, + msg->ap_name, msg->pid, + msg->n_args, + msg->args, + msg->autoexec, msg->dif_name, msg->n_dif_name); break; case IRM_MSG_CODE__IRM_AP_UNREG: ret_msg.has_result = true; - ret_msg.result = ap_unreg(msg->ap_name, + ret_msg.result = ap_unreg(msg->dst_name, + msg->ap_name, msg->pid, msg->dif_name, - msg->n_dif_name); + msg->n_dif_name, + msg->hard); break; case IRM_MSG_CODE__IRM_FLOW_ACCEPT: e = flow_accept(msg->pid, - &ret_msg.ap_name, + msg->ap_name, &ret_msg.ae_name); if (e == NULL) @@ -1393,7 +1414,6 @@ void * mainloop() case IRM_MSG_CODE__IRM_FLOW_ALLOC: e = flow_alloc(msg->pid, msg->dst_name, - msg->ap_name, msg->ae_name, NULL); if (e == NULL) @@ -1415,7 +1435,6 @@ void * mainloop() case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR: e = flow_req_arr(msg->pid, msg->dst_name, - msg->ap_name, msg->ae_name); if (e == NULL) break; diff --git a/src/lib/dev.c b/src/lib/dev.c index ae6d0f6c..ab4365b8 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -58,6 +58,9 @@ struct ap_data { int ap_init(char * ap_name) { int i = 0; + + ap_name = path_strip(ap_name); + _ap_instance = malloc(sizeof(struct ap_data)); if (_ap_instance == NULL) { return -1; @@ -154,109 +157,7 @@ static int port_id_to_fd(int port_id) } #endif -int ap_reg(char ** difs, - size_t len) -{ - irm_msg_t msg = IRM_MSG__INIT; - irm_msg_t * recv_msg = NULL; - int fd = -1; - - if (difs == NULL || - len == 0 || - difs[0] == NULL) { - return -EINVAL; - } - - rw_lock_rdlock(&_ap_instance->data_lock); - - if (_ap_instance == NULL) { - rw_lock_unlock(&_ap_instance->data_lock); - return -1; /* -ENOTINIT */ - } - - msg.code = IRM_MSG_CODE__IRM_AP_REG; - msg.has_pid = true; - msg.dif_name = difs; - msg.n_dif_name = len; - - msg.pid = _ap_instance->api->id; - msg.ap_name = _ap_instance->api->name; - - recv_msg = send_recv_irm_msg(&msg); - if (recv_msg == NULL) { - rw_lock_unlock(&_ap_instance->data_lock); - return -1; - } - - if (!recv_msg->has_result) { - rw_lock_unlock(&_ap_instance->data_lock); - irm_msg__free_unpacked(recv_msg, NULL); - return -1; - } - - if (recv_msg->result < 0) - fd = -1; - - irm_msg__free_unpacked(recv_msg, NULL); - - rw_lock_wrlock(&_ap_instance->flows_lock); - - fd = bmp_allocate(_ap_instance->fds); - _ap_instance->flows[fd].port_id = -1; - - rw_lock_unlock(&_ap_instance->flows_lock); - rw_lock_unlock(&_ap_instance->data_lock); - - return fd; -} - -int ap_unreg(char ** difs, - size_t len) -{ - irm_msg_t msg = IRM_MSG__INIT; - irm_msg_t * recv_msg = NULL; - int ret = -1; - - if (difs == NULL || - len == 0 || - difs[0] == NULL) { - return -EINVAL; - } - - msg.code = IRM_MSG_CODE__IRM_AP_UNREG; - msg.has_pid = true; - msg.dif_name = difs; - msg.n_dif_name = len; - - rw_lock_rdlock(&_ap_instance->data_lock); - - msg.pid = _ap_instance->api->id; - msg.ap_name = _ap_instance->api->name; - - recv_msg = send_recv_irm_msg(&msg); - if (recv_msg == NULL) { - rw_lock_unlock(&_ap_instance->data_lock); - return -1; - } - - if (!recv_msg->has_result) { - rw_lock_unlock(&_ap_instance->data_lock); - irm_msg__free_unpacked(recv_msg, NULL); - return -1; - } - - ret = recv_msg->result; - - rw_lock_unlock(&_ap_instance->data_lock); - - irm_msg__free_unpacked(recv_msg, NULL); - - return ret; -} - -int flow_accept(int fd, - char ** ap_name, - char ** ae_name) +int flow_accept(char ** ae_name) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; @@ -267,6 +168,7 @@ int flow_accept(int fd, rw_lock_rdlock(&_ap_instance->data_lock); + msg.ap_name = _ap_instance->api->name; msg.pid = _ap_instance->api->id; rw_lock_unlock(&_ap_instance->data_lock); @@ -301,23 +203,9 @@ int flow_accept(int fd, return -1; } - if (ap_name != NULL) { - *ap_name = strdup(recv_msg->ap_name); - if (*ap_name == NULL) { - shm_ap_rbuff_close(_ap_instance->flows[cfd].rb); - bmp_release(_ap_instance->fds, cfd); - rw_lock_unlock(&_ap_instance->flows_lock); - rw_lock_unlock(&_ap_instance->data_lock); - irm_msg__free_unpacked(recv_msg, NULL); - return -1; - } - } - if (ae_name != NULL) { *ae_name = strdup(recv_msg->ae_name); if (*ae_name == NULL) { - if (*ap_name != NULL) - free(*ap_name); shm_ap_rbuff_close(_ap_instance->flows[cfd].rb); bmp_release(_ap_instance->fds, cfd); rw_lock_unlock(&_ap_instance->flows_lock); @@ -406,7 +294,6 @@ int flow_alloc(char * dst_name, rw_lock_rdlock(&_ap_instance->data_lock); msg.pid = _ap_instance->api->id; - msg.ap_name = _ap_instance->api->name; rw_lock_unlock(&_ap_instance->data_lock); diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c index ec681f9e..16fb67af 100644 --- a/src/lib/ipcp.c +++ b/src/lib/ipcp.c @@ -365,7 +365,6 @@ int ipcp_flow_alloc(pid_t pid, int port_id, pid_t n_pid, char * dst_name, - char * src_ap_name, char * src_ae_name, enum qos_cube qos) { @@ -373,7 +372,7 @@ int ipcp_flow_alloc(pid_t pid, ipcp_msg_t * recv_msg = NULL; int ret = -1; - if (dst_name == NULL || src_ap_name == NULL || src_ae_name == NULL) + if (dst_name == NULL || src_ae_name == NULL) return -EINVAL; msg.code = IPCP_MSG_CODE__IPCP_FLOW_ALLOC; @@ -381,7 +380,6 @@ int ipcp_flow_alloc(pid_t pid, msg.port_id = port_id; msg.has_pid = true; msg.pid = n_pid; - msg.src_ap_name = src_ap_name; msg.src_ae_name = src_ae_name; msg.dst_name = dst_name; msg.has_qos_cube = true; @@ -436,21 +434,19 @@ int ipcp_flow_alloc_resp(pid_t pid, int ipcp_flow_req_arr(pid_t pid, char * dst_name, - char * src_ap_name, char * src_ae_name) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; int port_id = -1; - if (src_ap_name == NULL || src_ae_name == NULL) + if (dst_name == NULL || src_ae_name == NULL) return -EINVAL; msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; msg.has_pid = true; msg.pid = pid; msg.dst_name = dst_name; - msg.ap_name = src_ap_name; msg.ae_name = src_ae_name; recv_msg = send_recv_irm_msg(&msg); diff --git a/src/lib/irm.c b/src/lib/irm.c index cff5a76a..7c87f034 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -199,27 +199,39 @@ int irm_enroll_ipcp(instance_name_t * api, return ret; } -int irm_reg_ipcp(instance_name_t * api, - char ** difs, - size_t difs_size) +int irm_reg(char * name, + instance_name_t * api, + int argc, + char ** argv, + bool autoexec, + char ** difs, + size_t difs_len) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; int ret = -1; - if (api->name == NULL || - difs == NULL || - difs_size == 0 || - difs[0] == NULL) { + if (name == NULL || api->name == NULL) return -EINVAL; - } - msg.code = IRM_MSG_CODE__IRM_REG_IPCP; + msg.code = IRM_MSG_CODE__IRM_AP_REG; + msg.dst_name = name; msg.ap_name = api->name; - msg.has_api_id = true; - msg.api_id = api->id; - msg.dif_name = difs; - msg.n_dif_name = difs_size; + if (difs != NULL) { + msg.dif_name = difs; + msg.n_dif_name = difs_len; + } + + if (argv != NULL) { + msg.n_args = argc; + msg.args = argv; + } else { + msg.has_api_id = true; + msg.api_id = api->id; + } + + msg.has_autoexec = true; + msg.autoexec = autoexec; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -236,28 +248,36 @@ int irm_reg_ipcp(instance_name_t * api, return ret; } -int irm_unreg_ipcp(const instance_name_t * api, - char ** difs, - size_t difs_size) +int irm_unreg(char * name, + const instance_name_t * api, + char ** difs, + size_t difs_len, + bool hard) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; int ret = -1; - if (api == NULL || - api->name == NULL || - difs == NULL || - difs_size == 0 || - difs[0] == NULL) { + if (name == NULL && api == NULL) + return -EINVAL; + + if (difs == NULL || + difs_len == 0 || + difs[0] == NULL) return -EINVAL; + + msg.code = IRM_MSG_CODE__IRM_AP_UNREG; + if (api != NULL) { + msg.ap_name = api->name; + msg.has_api_id = true; + msg.api_id = api->id; } - msg.code = IRM_MSG_CODE__IRM_UNREG_IPCP; - msg.ap_name = api->name; - msg.has_api_id = true; - msg.api_id = api->id; msg.dif_name = difs; - msg.n_dif_name = difs_size; + msg.n_dif_name = difs_len; + if (name != NULL) + msg.dst_name = name; + msg.hard = hard; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto index 27194ccb..34366975 100644 --- a/src/lib/irmd_messages.proto +++ b/src/lib/irmd_messages.proto @@ -27,19 +27,17 @@ enum irm_msg_code { IRM_DESTROY_IPCP = 2; IRM_BOOTSTRAP_IPCP = 3; IRM_ENROLL_IPCP = 4; - IRM_REG_IPCP = 5; - IRM_UNREG_IPCP = 6; - IRM_AP_REG = 7; - IRM_AP_UNREG = 8; - IRM_FLOW_ACCEPT = 9; - IRM_FLOW_ALLOC_RESP = 10; - IRM_FLOW_ALLOC = 11; - IRM_FLOW_ALLOC_RES = 12; - IRM_FLOW_DEALLOC = 13; - IPCP_FLOW_REQ_ARR = 14; - IPCP_FLOW_ALLOC_REPLY = 15; - IPCP_FLOW_DEALLOC = 16; - IRM_REPLY = 17; + IRM_AP_REG = 5; + IRM_AP_UNREG = 6; + IRM_FLOW_ACCEPT = 7; + IRM_FLOW_ALLOC_RESP = 8; + IRM_FLOW_ALLOC = 9; + IRM_FLOW_ALLOC_RES = 10; + IRM_FLOW_DEALLOC = 11; + IPCP_FLOW_REQ_ARR = 12; + IPCP_FLOW_ALLOC_REPLY = 13; + IPCP_FLOW_DEALLOC = 14; + IRM_REPLY = 15; }; message irm_msg { @@ -49,10 +47,13 @@ message irm_msg { optional uint32 api_id = 3; optional uint32 ipcp_type = 5; repeated string dif_name = 6; - optional sint32 response = 7; - optional string dst_name = 8; - optional sint32 port_id = 9; - optional int32 pid = 10; - optional dif_config_msg conf = 11; - optional sint32 result = 12; + repeated string args = 7; + optional sint32 response = 8; + optional string dst_name = 9; + optional sint32 port_id = 10; + optional int32 pid = 11; + optional dif_config_msg conf = 12; + optional bool autoexec = 13; + optional bool hard = 14; + optional sint32 result = 15; }; diff --git a/src/lib/utils.c b/src/lib/utils.c index 5744fb7c..49065138 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -53,3 +53,21 @@ char * strdup(const char * src) return dst; } + +char * path_strip(char * src) +{ + char * dst = NULL; + + if (src == NULL) + return NULL; + + dst = src + strlen(src); + + while (dst > src && *dst != '/') + --dst; + + if (*dst == '/') + ++dst; + + return dst; +} diff --git a/src/tools/cbr/cbr.c b/src/tools/cbr/cbr.c index e36b1856..750b5a15 100644 --- a/src/tools/cbr/cbr.c +++ b/src/tools/cbr/cbr.c @@ -30,9 +30,6 @@ #include #include -#define SERVER_AP_NAME "cbr-server" -#define CLIENT_AP_NAME "cbr-client" - #define BUF_SIZE 1500 #include "cbr_client.c" @@ -49,6 +46,7 @@ static void usage(void) printf("Usage: cbr [OPTION]...\n" "Sends SDU's from client to server at a constant bit rate.\n\n" " -l, --listen Run in server mode\n" + " -n, --server_apn Specify the name of the server.\n" "\n" "Server options:\n" " -i, --interval Server report interval (s)\n" @@ -66,14 +64,20 @@ static void usage(void) int main(int argc, char ** argv) { - int duration = 60; /* One minute test */ - int size = 1000; /* 1000 byte SDU's */ - long rate = 1000000; /* 1 Mb/s */ - bool flood = false; - bool sleep = false; - char * rem; + int duration = 60; /* One minute test */ + int size = 1000; /* 1000 byte SDU's */ + long rate = 1000000; /* 1 Mb/s */ + bool flood = false; + bool sleep = false; + int ret = 0; + char * rem = NULL; + char * s_apn = NULL; bool server = false; + + /* FIXME: should be argv[0] */ + ap_init(argv[0]); + server_settings.interval = 1; /* One second reporting interval */ server_settings.timeout = 1; @@ -88,6 +92,10 @@ int main(int argc, char ** argv) strcmp(*argv, "--timeout") == 0) { server_settings.timeout = strtol(*(++argv), &rem, 10); --argc; + } else if (strcmp(*argv, "-n") == 0 || + strcmp(*argv, "--server_apn") == 0) { + s_apn = *(++argv); + --argc; } else if (strcmp(*argv, "-d") == 0 || strcmp(*argv, "--duration") == 0) { duration = strtol(*(++argv), &rem, 10); @@ -123,8 +131,20 @@ int main(int argc, char ** argv) } if (server) { - return server_main(); + ret = server_main(); + + } else { + + if (s_apn == NULL) { + printf("No server specified.\n"); + usage(); + return 0; + } + + ret = client_main(s_apn, duration, size, rate, flood, sleep); } - return client_main(duration, size, rate, flood, sleep); + ap_fini(); + + return ret; } diff --git a/src/tools/cbr/cbr_client.c b/src/tools/cbr/cbr_client.c index b0c04f39..1cc325b8 100644 --- a/src/tools/cbr/cbr_client.c +++ b/src/tools/cbr/cbr_client.c @@ -35,7 +35,12 @@ static void busy_wait_until(const struct timespec * deadline) clock_gettime(CLOCK_REALTIME, &now); } -int client_main(int duration, int size, long rate, bool flood, bool sleep) +int client_main(char * server, + int duration, + int size, + long rate, + bool flood, + bool sleep) { int fd = 0; int result = 0; @@ -49,15 +54,10 @@ int client_main(int duration, int size, long rate, bool flood, bool sleep) struct timespec intv = {(gap / BILLION), gap % BILLION}; int ms; - if (ap_init(CLIENT_AP_NAME)) { - printf("Failed to init AP.\n"); - return -1; - } - printf("Client started, duration %d, rate %lu b/s, size %d B.\n", duration, rate, size); - fd = flow_alloc(SERVER_AP_NAME, NULL, NULL); + fd = flow_alloc(server, NULL, NULL); if (fd < 0) { printf("Failed to allocate flow.\n"); ap_fini(); @@ -122,7 +122,5 @@ int client_main(int duration, int size, long rate, bool flood, bool sleep) flow_dealloc(fd); - ap_fini(); - return 0; } diff --git a/src/tools/cbr/cbr_server.c b/src/tools/cbr/cbr_server.c index eef1acc9..3a1d8d5c 100644 --- a/src/tools/cbr/cbr_server.c +++ b/src/tools/cbr/cbr_server.c @@ -30,7 +30,6 @@ #include #include -#define DIF_NAME "*" #define THREADS_SIZE 10 pthread_t listen_thread; @@ -43,19 +42,12 @@ pthread_cond_t fds_signal; void shutdown_server(int signo, siginfo_t * info, void * c) { - char * dif = DIF_NAME; int i; switch(signo) { case SIGINT: case SIGTERM: case SIGHUP: - if (ap_unreg(&dif, 1)) { - printf("Failed to unregister application.\n"); - ap_fini(); - exit(EXIT_FAILURE); - } - pthread_cancel(listen_thread); for (i = 0; i < THREADS_SIZE; i++) { @@ -157,36 +149,20 @@ void * worker(void * o) void * listener(void * o) { - char * dif = DIF_NAME; - int server_fd; - char * client_name = NULL; int client_fd = 0; int response = 0; - if (ap_init(SERVER_AP_NAME)) { - printf("Failed to init AP.\n"); - exit(EXIT_FAILURE); - } - - server_fd = ap_reg(&dif, 1); - if (server_fd < 0) { - printf("Failed to register application.\n"); - ap_fini(); - exit(EXIT_FAILURE); - } - printf("Server started, interval is %ld s, timeout is %ld s.\n", server_settings.interval, server_settings.timeout); while (true) { - client_fd = flow_accept(server_fd, - &client_name, NULL); + client_fd = flow_accept(NULL); if (client_fd < 0) { printf("Failed to accept flow.\n"); break; } - printf("New flow from %s.\n", client_name); + printf("New flow.\n"); pthread_mutex_lock(&fds_lock); @@ -259,7 +235,5 @@ int server_main() pthread_join(threads[i], NULL); } - ap_fini(); - return 0; } diff --git a/src/tools/echo/echo.c b/src/tools/echo/echo.c index 849c0ca8..4484dc71 100644 --- a/src/tools/echo/echo.c +++ b/src/tools/echo/echo.c @@ -23,7 +23,6 @@ #include #include -#define SERVER_AP_NAME "echo-server" #define BUF_SIZE 256 #include "echo_client.c" @@ -37,14 +36,22 @@ static void usage() " --help Display this help text and exit\n"); } -int main(int argc, char ** argv) { +int main(int argc, char ** argv) +{ + int ret = -1; + if (ap_init(argv[0])) { + printf("Failed to init AP.\n"); + return -1; + } argc--; argv++; while (argc > 0) { if (strcmp(*argv, "-l") == 0 || strcmp(*argv, "--listen") == 0) { - return server_main(); + ret = server_main(); + ap_fini(); + return ret; } else { usage(); return 0; @@ -53,5 +60,9 @@ int main(int argc, char ** argv) { argv++; } - return client_main(); + ret = client_main(); + + ap_fini(); + + return ret; } diff --git a/src/tools/echo/echo_client.c b/src/tools/echo/echo_client.c index 5c613817..499e36ee 100644 --- a/src/tools/echo/echo_client.c +++ b/src/tools/echo/echo_client.c @@ -20,8 +20,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define CLIENT_AP_NAME "echo-client" - #include #include @@ -33,12 +31,7 @@ int client_main() char * message = "Client says hi!"; ssize_t count = 0; - if (ap_init(CLIENT_AP_NAME)) { - printf("Failed to init AP.\n"); - return -1; - } - - fd = flow_alloc(SERVER_AP_NAME, NULL, NULL); + fd = flow_alloc("echo", NULL, NULL); if (fd < 0) { printf("Failed to allocate flow.\n"); ap_fini(); @@ -72,7 +65,5 @@ int client_main() flow_dealloc(fd); - ap_fini(); - return 0; } diff --git a/src/tools/echo/echo_server.c b/src/tools/echo/echo_server.c index b72da319..c5e9f807 100644 --- a/src/tools/echo/echo_server.c +++ b/src/tools/echo/echo_server.c @@ -27,28 +27,15 @@ #include -#define DIF_NAME "*" - void shutdown_server(int signo) { - char * dif = DIF_NAME; - - if (ap_unreg(&dif, 1)) { - printf("Failed to unregister application.\n"); - ap_fini(); - exit(EXIT_FAILURE); - } - ap_fini(); exit(EXIT_SUCCESS); } int server_main() { - int server_fd = 0; int client_fd = 0; - char * dif = DIF_NAME; - char * client_name = NULL; char buf[BUF_SIZE]; ssize_t count = 0; @@ -60,27 +47,14 @@ int server_main() return -1; } - if (ap_init(SERVER_AP_NAME)) { - printf("Failed to init AP.\n"); - return -1; - } - - server_fd = ap_reg(&dif, 1); - if (server_fd < 0) { - printf("Failed to register application.\n"); - ap_fini(); - return -1; - } - while (true) { - client_fd = flow_accept(server_fd, - &client_name, NULL); + client_fd = flow_accept(NULL); if (client_fd < 0) { printf("Failed to accept flow.\n"); break; } - printf("New flow from %s.\n", client_name); + printf("New flow.\n"); if (flow_alloc_resp(client_fd, 0)) { printf("Failed to give an allocate response.\n"); @@ -106,7 +80,5 @@ int server_main() flow_dealloc(client_fd); } - ap_fini(); - return 0; } diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt index f356d068..eb385908 100644 --- a/src/tools/irm/CMakeLists.txt +++ b/src/tools/irm/CMakeLists.txt @@ -11,8 +11,8 @@ set(SOURCE_FILES irm_destroy_ipcp.c irm_bootstrap_ipcp.c irm_enroll_ipcp.c - irm_register_ipcp.c - irm_unregister_ipcp.c + irm_register.c + irm_unregister.c irm_utils.c ) diff --git a/src/tools/irm/irm.c b/src/tools/irm/irm.c index d05e083e..a1dc5ade 100644 --- a/src/tools/irm/irm.c +++ b/src/tools/irm/irm.c @@ -34,6 +34,7 @@ static void usage() printf("Usage: irm [OPERATION]\n\n" "where OPERATION = {create_ipcp destroy_ipcp \n" " bootstrap_ipcp enroll_ipcp\n" + " register unregister\n" " register_ipcp unregister_ipcp\n"); } @@ -51,8 +52,8 @@ static const struct cmd { { "destroy_ipcp", do_destroy_ipcp }, { "bootstrap_ipcp", do_bootstrap_ipcp }, { "enroll_ipcp", do_enroll_ipcp }, - { "register_ipcp", do_register_ipcp }, - { "unregister_ipcp", do_unregister_ipcp }, + { "register", do_register }, + { "unregister", do_unregister }, { "help", do_help }, { 0 } }; diff --git a/src/tools/irm/irm_ops.h b/src/tools/irm/irm_ops.h index ff63b6bf..ea51cbeb 100644 --- a/src/tools/irm/irm_ops.h +++ b/src/tools/irm/irm_ops.h @@ -24,5 +24,5 @@ int do_create_ipcp(int argc, char ** argv); int do_destroy_ipcp(int argc, char ** argv); int do_bootstrap_ipcp(int argc, char ** argv); int do_enroll_ipcp(int argc, char ** argv); -int do_register_ipcp(int argc, char ** argv); -int do_unregister_ipcp(int argc, char ** argv); +int do_register(int argc, char ** argv); +int do_unregister(int argc, char ** argv); diff --git a/src/tools/irm/irm_register.c b/src/tools/irm/irm_register.c new file mode 100644 index 00000000..67c81025 --- /dev/null +++ b/src/tools/irm/irm_register.c @@ -0,0 +1,123 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Register AP's in DIFs + * + * Dimitri Staessens + * Sander Vrijders + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "irm_ops.h" +#include "irm_utils.h" + +#define MAX_DIFS 128 + +static void usage() +{ + printf("Usage: irm register\n" + " n \n" + " apn \n" + " [api ]\n" + " [auto] (instantiate apn if not running)\n" + " [dif ]\n" + " [... (maximum %d difs)]\n" + " [-- ]\n" + , MAX_DIFS); +} + + +int do_register(int argc, char ** argv) +{ + char * name = NULL; + char ** args = NULL; + char * difs[MAX_DIFS]; + size_t difs_len = 0; + bool api_opt = false; + bool args_opt = false; + bool autoexec = false; + int i = argc; + + instance_name_t api = {NULL, 0}; + + while (i > 0) { + if (matches(*argv, "name") == 0) { + name = *(argv + 1); + } else if (matches(*argv, "apn") == 0) { + api.name = *(argv + 1); + } else if (matches(*argv, "api") == 0) { + api.id = atoi(*(argv + 1)); + api_opt = true; + } else if (strcmp(*argv, "auto") == 0) { + autoexec = true; + ++i; + --argv; + } else if (strcmp(*argv, "--") == 0) { + ++argv; + --i; + args_opt = true; + break; + } else if (matches(*argv, "dif") == 0) { + difs[difs_len++] = *(argv + 1); + if (difs_len > MAX_DIFS) { + printf("Too many difs specified\n"); + return -1; + } + } else { + printf("\"%s\" is unknown, try \"irm " + "register\".\n", *argv); + return -1; + } + + i -= 2; + argv += 2; + } + + if (name == NULL || api.name == NULL) { + usage(); + return -1; + } + + if (api_opt && kill(api.id, 0) < 0) { + printf("No application running with that pid."); + return -1; + } + + if (api_opt && autoexec) { + printf("Instance is given, auto disabled.\n"); + autoexec = false; + } + + args = argv; + + if (args_opt && api_opt) { + printf("Instance is given, args ignored.\n"); + args = NULL; + i = 0; + } + + return irm_reg(name, &api, i, args, autoexec, difs, difs_len); +} diff --git a/src/tools/irm/irm_register_ipcp.c b/src/tools/irm/irm_register_ipcp.c deleted file mode 100644 index f0c1ccff..00000000 --- a/src/tools/irm/irm_register_ipcp.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Register IPC Processes in an N-1 DIF - * - * Sander Vrijders - * - * 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 -#include -#include -#include -#include -#include - -#include "irm_ops.h" -#include "irm_utils.h" - -#define MAX_DIFS 128 - -static void usage() -{ - printf("Usage: irm register_ipcp\n" - " ap \n" - " [api ]\n" - " dif \n" - " [dif ]\n" - " [... (maximum %d difs)]\n", MAX_DIFS); -} - - -int do_register_ipcp(int argc, char ** argv) -{ - char * difs[MAX_DIFS]; - size_t difs_size = 0; - instance_name_t api = {NULL, 0}; - - while (argc > 0) { - if (matches(*argv, "ap") == 0) { - api.name = *(argv + 1); - } else if (matches(*argv, "api") == 0) { - api.id = atoi(*(argv + 1)); - } else if (matches(*argv, "dif") == 0) { - difs[difs_size++] = *(argv + 1); - if (difs_size > MAX_DIFS) { - printf("Too many difs specified\n"); - return -1; - } - } else { - printf("\"%s\" is unknown, try \"irm " - "register_ipcp\".\n", *argv); - return -1; - } - - argc -= 2; - argv += 2; - } - - if (difs_size == 0 || api.name == NULL) { - usage(); - return -1; - } - - return irm_reg_ipcp(&api, difs, difs_size); -} diff --git a/src/tools/irm/irm_unregister.c b/src/tools/irm/irm_unregister.c new file mode 100644 index 00000000..d778e285 --- /dev/null +++ b/src/tools/irm/irm_unregister.c @@ -0,0 +1,116 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Unregister IPC Processes in an N-1 DIF + * + * Dimitri Staessens + * Sander Vrijders + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "irm_ops.h" +#include "irm_utils.h" + +#define MAX_DIFS 128 + +static void usage() +{ + printf("Usage: irm unregister\n" + " [name ]\n" + " [apn ]\n" + " [api ]\n" + " dif \n" + " [dif ]\n" + " [... (maximum %d difs)]\n" + " [hard] (unregisters everything using that name)\n" + , MAX_DIFS); +} + +int do_unregister(int argc, char ** argv) +{ + instance_name_t api = {NULL, 0}; + char * difs[MAX_DIFS]; + size_t difs_len = 0; + char * name = NULL; + bool hard_opt = false; + bool ap_id = false; + instance_name_t * ptr_api = NULL; + + while (argc > 0) { + if (matches(*argv, "name") == 0) { + name = *(argv + 1); + } else if (matches(*argv, "ap") == 0) { + api.name = *(argv + 1); + ptr_api = &api; + } else if (matches(*argv, "api") == 0) { + api.id = atoi(*(argv + 1)); + ap_id = true; + } else if (strcmp(*argv, "hard") == 0) { + hard_opt = true; + /* this has no value */ + ++argc; + --argv; + } else if (matches(*argv, "dif") == 0) { + difs[difs_len++] = *(argv + 1); + if (difs_len > MAX_DIFS) { + printf("Too many difs specified\n"); + return -1; + } + } else { + printf("\"%s\" is unknown, try \"irm " + "unregister\".\n", *argv); + return -1; + } + + argc -= 2; + argv += 2; + } + + if (difs_len == 0) { + usage(); + return -1; + } + + if (name == NULL && api.name == NULL) { + printf("apn or name must be set.\n"); + usage(); + return -1; + } + + if (ap_id && api.name == NULL) { + printf("api requires apn.\n"); + usage(); + return -1; + } + + if (hard_opt && api.name != NULL) { + printf("apn and/or api must not be set when using hard.\n"); + usage(); + return -1; + } + + return irm_unreg(name, ptr_api, difs, difs_len, hard_opt); +} diff --git a/src/tools/irm/irm_unregister_ipcp.c b/src/tools/irm/irm_unregister_ipcp.c deleted file mode 100644 index 3fd6f148..00000000 --- a/src/tools/irm/irm_unregister_ipcp.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - * - * Unregister IPC Processes in an N-1 DIF - * - * Sander Vrijders - * - * 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 -#include -#include -#include -#include -#include - -#include "irm_ops.h" -#include "irm_utils.h" - -#define MAX_DIFS 128 - -static void usage() -{ - printf("Usage: irm unregister_ipcp\n" - " ap \n" - " [api ]\n" - " dif \n" - " [dif ]\n" - " [... (maximum %d difs)]\n", MAX_DIFS); -} - - -int do_unregister_ipcp(int argc, char ** argv) -{ - instance_name_t api = {NULL, 0}; - char * difs[MAX_DIFS]; - size_t difs_size = 0; - - - while (argc > 0) { - if (matches(*argv, "ap") == 0) { - api.name = *(argv + 1); - } else if (matches(*argv, "api") == 0) { - api.id = atoi(*(argv + 1)); - } else if (matches(*argv, "dif") == 0) { - difs[difs_size++] = *(argv + 1); - if (difs_size > MAX_DIFS) { - printf("Too many difs specified\n"); - return -1; - } - } else { - printf("\"%s\" is unknown, try \"irm " - "unregister_ipcp\".\n", *argv); - return -1; - } - - argc -= 2; - argv += 2; - } - - if (difs_size == 0 || api.name == NULL) { - usage(); - return -1; - } - - return irm_unreg_ipcp(&api, difs, difs_size); -} -- cgit v1.2.3 From f8afe1b570c4829bdc47e5963c93609e7196f414 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 14 Jun 2016 09:26:07 +0200 Subject: irmd: cond_var to wait for ap to accept A condition variable is now used to wait for an auto-executed AP to accept the requested flow. --- src/irmd/main.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/irmd/main.c b/src/irmd/main.c index ea52d67f..fc856687 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -81,6 +81,7 @@ struct reg_name_entry { int flow_arrived; pthread_cond_t acc_signal; + pthread_cond_t acc_arr_signal; pthread_mutex_t acc_lock; }; @@ -271,6 +272,11 @@ static struct reg_name_entry * reg_name_entry_create() e->req_ae_name = NULL; e->flow_arrived = -1; + if (pthread_cond_init(&e->acc_arr_signal, NULL)) { + free(e); + return NULL; + } + if (pthread_cond_init(&e->acc_signal, NULL)) { free(e); return NULL; @@ -312,7 +318,7 @@ static int reg_name_entry_destroy(struct reg_name_entry * e) pthread_mutex_lock(&e->acc_lock); e->flow_arrived = -2; pthread_mutex_unlock(&e->acc_lock); - pthread_cond_broadcast(&e->acc_signal); + pthread_cond_broadcast(&e->acc_arr_signal); sched_yield(); } @@ -811,6 +817,8 @@ static struct port_map_entry * flow_accept(pid_t pid, rne->accept = true; rne->flow_arrived = -1; + pthread_cond_broadcast(&rne->acc_signal); + rw_lock_unlock(&instance->reg_lock); rw_lock_unlock(&instance->state_lock); @@ -819,7 +827,7 @@ static struct port_map_entry * flow_accept(pid_t pid, (void*) &rne->acc_lock); while (rne->flow_arrived == -1) - pthread_cond_wait(&rne->acc_signal, &rne->acc_lock); + pthread_cond_wait(&rne->acc_arr_signal, &rne->acc_lock); pthread_mutex_unlock(&rne->acc_lock); pthread_cleanup_pop(0); @@ -1151,7 +1159,8 @@ static struct port_map_entry * flow_req_arr(pid_t pid, if (rne->autoexec) { pme->n_pid = auto_execute(rne->api->name, rne->argv); while (rne->accept == false) - sched_yield(); + pthread_cond_wait(&rne->acc_signal, + &rne->acc_lock); } else { pthread_mutex_unlock(&rne->acc_lock); @@ -1165,7 +1174,7 @@ static struct port_map_entry * flow_req_arr(pid_t pid, pthread_mutex_unlock(&rne->acc_lock); - if (pthread_cond_signal(&rne->acc_signal)) + if (pthread_cond_signal(&rne->acc_arr_signal)) LOG_ERR("Failed to send signal."); while (acc_wait) { -- cgit v1.2.3 From 10c5059713863321033f58cbc35cc6ac41cd3e30 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 14 Jun 2016 09:29:01 +0200 Subject: lib, dev: fixed comment Comment updated to reflect removal of the AP name from flow allocation. --- include/ouroboros/dev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ouroboros/dev.h b/include/ouroboros/dev.h index 1f664d35..ee253ff8 100644 --- a/include/ouroboros/dev.h +++ b/include/ouroboros/dev.h @@ -36,7 +36,7 @@ int ap_init(char * ap_name); void ap_fini(void); -/* Returns file descriptor (> 0) and client name(s) */ +/* Returns file descriptor (> 0) and client AE name */ int flow_accept(char ** ae_name); int flow_alloc_resp(int fd, int result); -- cgit v1.2.3 From be68864173cf12d9998e4dbe73d876d8974a2ec1 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 14 Jun 2016 11:39:37 +0200 Subject: ipdpd: fixed flow deallocation in local ipcpd Now correctly deallocates the local fd if the remote already deallocated the flow. --- src/ipcpd/local/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index cb20a336..e7db58b6 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -519,7 +519,9 @@ static int ipcp_local_flow_dealloc(int port_id) bmp_release(_ap_instance->fds, fd); - _ap_instance->in_out[_ap_instance->in_out[fd]] = -1; + if (_ap_instance->in_out[fd] != -1) + _ap_instance->in_out[_ap_instance->in_out[fd]] =-1; + _ap_instance->in_out[fd] = -1; _ap_instance->flows[fd].state = FLOW_NULL; -- cgit v1.2.3 From 95124310f647913a678060fc10155a0ad9311dba Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 14 Jun 2016 14:52:26 +0200 Subject: Fixed comments on #122 --- src/ipcpd/local/main.c | 2 +- src/irmd/main.c | 7 +++---- src/tools/cbr/cbr.c | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index e7db58b6..6357487f 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -520,7 +520,7 @@ static int ipcp_local_flow_dealloc(int port_id) bmp_release(_ap_instance->fds, fd); if (_ap_instance->in_out[fd] != -1) - _ap_instance->in_out[_ap_instance->in_out[fd]] =-1; + _ap_instance->in_out[_ap_instance->in_out[fd]] = -1; _ap_instance->in_out[fd] = -1; diff --git a/src/irmd/main.c b/src/irmd/main.c index fc856687..db96b6ed 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -705,7 +705,7 @@ static int ap_reg(char * name, /* we need to duplicate argv */ if (argc != 0) { - argv_dup = malloc ((argc + 2) * sizeof(*argv_dup)); + argv_dup = malloc((argc + 2) * sizeof(*argv_dup)); argv_dup[0] = strdup(api->name); for (i = 1; i <= argc; ++i) argv_dup[i] = strdup(argv[i - 1]); @@ -1108,7 +1108,7 @@ static int auto_execute(char * ap, char ** argv) execv(ap, argv); - LOG_DBG("Failed to execute."); + LOG_ERR("Failed to execute."); exit(EXIT_FAILURE); return 0; @@ -1161,8 +1161,7 @@ static struct port_map_entry * flow_req_arr(pid_t pid, while (rne->accept == false) pthread_cond_wait(&rne->acc_signal, &rne->acc_lock); - } - else { + } else { pthread_mutex_unlock(&rne->acc_lock); LOG_WARN("%s is not accepting flow allocations.", rne->name); diff --git a/src/tools/cbr/cbr.c b/src/tools/cbr/cbr.c index 750b5a15..ab178ca3 100644 --- a/src/tools/cbr/cbr.c +++ b/src/tools/cbr/cbr.c @@ -132,9 +132,7 @@ int main(int argc, char ** argv) if (server) { ret = server_main(); - } else { - if (s_apn == NULL) { printf("No server specified.\n"); usage(); -- cgit v1.2.3