summaryrefslogtreecommitdiff
path: root/src/irmd/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/irmd/main.c')
-rw-r--r--src/irmd/main.c284
1 files changed, 254 insertions, 30 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 374bfb6c..fcd93bd5 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -41,6 +41,10 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <limits.h>
+
+/* FIXME: this smells like part of namespace management */
+#define ALL_DIFS "*"
struct ipcp_entry {
struct list_head next;
@@ -49,12 +53,27 @@ struct ipcp_entry {
char * dif_name;
};
+/* currently supports only registering whatevercast groups of a single AP */
+struct reg_name_entry {
+ struct list_head next;
+
+ /* generic whatevercast name */
+ char * name;
+
+ /* FIXME: resolve name instead */
+ instance_name_t * api;
+ uint32_t reg_ap_id;
+};
+
struct irm {
+ /* FIXME: list of ipcps can be merged with registered names */
struct list_head ipcps;
+ struct list_head reg_names;
+
+ struct shm_du_map * dum;
};
struct irm * instance = NULL;
-struct shm_du_map * dum;
static pid_t find_pid_by_ipcp_name(instance_name_t * api)
{
@@ -105,6 +124,101 @@ static pid_t find_pid_by_dif_name(char * dif_name)
return 0;
}
+static struct reg_name_entry * reg_name_entry_create()
+{
+ struct reg_name_entry * e = malloc(sizeof(*e));
+ if (e == NULL)
+ return NULL;
+
+ e->reg_ap_id = rand() % INT_MAX;
+ e->name = NULL;
+
+ INIT_LIST_HEAD(&e->next);
+
+ return e;
+}
+
+static struct reg_name_entry * reg_name_entry_init(struct reg_name_entry * e,
+ char * name,
+ instance_name_t * api)
+{
+ if (e == NULL || name == NULL || api == NULL)
+ return NULL;
+
+ e->name = name;
+ e->api = api;
+
+ return e;
+}
+
+static int reg_name_entry_destroy(struct reg_name_entry * e)
+{
+ if (e == NULL)
+ return 0;
+
+ free(e->name);
+ instance_name_destroy(e->api);
+ return 0;
+}
+
+static struct reg_name_entry * find_reg_name_entry_by_name(char * 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(name, e->name) == 0)
+ return e;
+ }
+
+ return NULL;
+}
+
+static struct reg_name_entry * find_reg_name_entry_by_id(uint32_t reg_ap_id)
+{
+ 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 (reg_ap_id == e->reg_ap_id)
+ return e;
+ }
+
+ return NULL;
+}
+
+/* FIXME: add only name when we have NSM solved */
+static int reg_name_entry_add_name_instance(char * name, instance_name_t * api)
+{
+ struct reg_name_entry * e = find_reg_name_entry_by_name(name);
+ if (e == NULL) {
+ e = reg_name_entry_create();
+ e = reg_name_entry_init(e, name, api);
+ list_add(&e->next, &instance->reg_names);
+ return 0;
+ }
+
+ /* already exists, we don't have NSM yet */
+ return -1;
+}
+
+static int reg_name_entry_del_name(char * name)
+{
+ struct reg_name_entry * e = find_reg_name_entry_by_name(name);
+ if (e == NULL)
+ return 0;
+
+ list_del(&e->next);
+
+ reg_name_entry_destroy(e);
+
+ return 0;
+}
+
static int create_ipcp(instance_name_t * api,
enum ipcp_type ipcp_type)
{
@@ -280,54 +394,161 @@ static int unreg_ipcp(instance_name_t * api,
return 0;
}
-static int ap_reg(char * ap_name,
+static int ap_unreg_id(uint32_t reg_ap_id,
+ pid_t pid,
+ char ** difs,
+ size_t len)
+{
+ int i;
+ int ret = 0;
+ struct reg_name_entry * rne = NULL;
+ struct list_head * pos = NULL;
+
+ rne = find_reg_name_entry_by_id (reg_ap_id);
+ if (rne == NULL)
+ return 0; /* no such id */
+
+ if (instance->ipcps.next == NULL) {
+ LOG_ERR("No IPCPs in this system.");
+ return 0;
+ }
+
+ if (strcmp(difs[0], ALL_DIFS) == 0) {
+ list_for_each(pos, &instance->ipcps) {
+ struct ipcp_entry * e =
+ list_entry(pos, struct ipcp_entry, next);
+
+ if (ipcp_name_unreg(e->pid, rne->name)) {
+ LOG_ERR("Could not unregister %s in DIF %s.",
+ rne->name, e->dif_name);
+ --ret;
+ }
+ }
+ } else {
+ for (i = 0; i < len; ++i) {
+ pid = find_pid_by_dif_name(difs[i]);
+ if (pid == 0) {
+ LOG_ERR("%s: No such DIF.", difs[i]);
+ continue;
+ }
+
+ if (ipcp_name_unreg(pid, rne->name)) {
+ LOG_ERR("Could not unregister %s in DIF %s.",
+ rne->name, difs[i]);
+ --ret;
+ }
+ }
+ }
+
+ reg_name_entry_del_name(rne->name);
+
+ return ret;
+}
+
+static int ap_reg(char * ap_name,
+ pid_t ap_id,
char ** difs,
- size_t difs_size)
+ size_t len)
{
pid_t pid = 0;
int i;
int ret = 0;
+ int reg_ap_id = 0;
+ struct list_head * pos = NULL;
+ struct reg_name_entry * rne = NULL;
+ instance_name_t * api = NULL;
+
if (instance->ipcps.next == NULL)
LOG_ERR("No IPCPs in this system.");
+ /* check if this ap_name is already registered */
+ rne = find_reg_name_entry_by_name(ap_name);
+ if (rne != NULL)
+ return -1; /* can only register one instance for now */
+
+ rne = reg_name_entry_create();
+ if (rne == NULL)
+ return -1;
+
+ api = instance_name_create();
+ if (instance_name_init_from(api, ap_name, ap_id) == NULL) {
+ instance_name_destroy(api);
+ return -1;
+ }
+
/*
- * FIXME: this should be resolved by NSM
- * Now it just takes the first DIF
+ * for now, the whatevercast name is the same as the ap_name and
+ * contains a single instance only
*/
- if (strcmp(difs[0], "*") == 0) {
- difs[0] = list_entry(instance->ipcps.next,
- struct ipcp_entry,
- next)->dif_name;
- difs_size = 1;
+ if (reg_name_entry_init(rne, strdup(ap_name), api) == NULL) {
+ reg_name_entry_destroy(rne);
+ instance_name_destroy(api);
+ return -1;
}
- for (i = 0; i < difs_size; ++i) {
- pid = find_pid_by_dif_name(difs[i]);
- if (pid == 0) {
- LOG_ERR("%s: No such DIF.", difs[i]);
- continue;
+ if (strcmp(difs[0], ALL_DIFS) == 0) {
+ list_for_each(pos, &instance->ipcps) {
+ struct ipcp_entry * e =
+ list_entry(pos, struct ipcp_entry, next);
+
+ if (ipcp_name_reg(e->pid, api->name)) {
+ LOG_ERR("Could not register %s in DIF %s.",
+ api->name, e->dif_name);
+ } else {
+ ++ret;
+ }
}
-
- /* FIXME: get proper reg_ap_id */
- if (ipcp_ap_reg(pid, rand(),ap_name)) {
- LOG_ERR("Could not register %s in DIF %s.",
- ap_name, difs[i]);
- ret = -1;
+ } else {
+ for (i = 0; i < len; ++i) {
+ pid = find_pid_by_dif_name(difs[i]);
+ if (pid == 0) {
+ LOG_ERR("%s: No such DIF.", difs[i]);
+ continue;
+ }
+
+ if (ipcp_name_reg(pid, api->name)) {
+ LOG_ERR("Could not register %s in DIF %s.",
+ api->name, difs[i]);
+ } else {
+ ++ret;
+ }
}
}
- return ret;
+ if (ret == 0) {
+ instance_name_destroy(api);
+ return -1;
+ }
+ /* for now, we register single instances */
+ reg_name_entry_add_name_instance(strdup(ap_name), instance_name_dup(api));
+
+ return reg_ap_id;
}
-static int ap_unreg(char * ap_name,
+static int ap_unreg(char * ap_name,
+ pid_t ap_id,
char ** difs,
- size_t difs_size)
+ size_t len)
{
- return -1;
+ struct reg_name_entry * tmp = NULL;
+
+ instance_name_t * api = instance_name_create();
+ if (instance_name_init_from(api, ap_name, ap_id) == NULL) {
+ instance_name_destroy(api);
+ return -1;
+ }
+
+ /* check if ap_name is registered */
+ tmp = find_reg_name_entry_by_name(api->name);
+ if (tmp == NULL)
+ return 0;
+ else
+ return ap_unreg_id(tmp->reg_ap_id, api->id, difs, len);
}
+
static int flow_accept(int fd,
char * ap_name,
char * ae_name)
@@ -392,7 +613,7 @@ void irmd_sig_handler(int sig, siginfo_t * info, void * c)
case SIGINT:
case SIGTERM:
case SIGHUP:
- shm_du_map_close(dum);
+ shm_du_map_close(instance->dum);
free(instance);
exit(0);
default:
@@ -421,14 +642,15 @@ int main()
if (access("/dev/shm/" SHM_DU_MAP_FILENAME, F_OK) != -1)
unlink("/dev/shm/" SHM_DU_MAP_FILENAME);
- if ((dum = shm_du_map_create()) == NULL)
- return -1;
-
instance = malloc(sizeof(*instance));
if (instance == NULL)
return -1;
+ if ((instance->dum = shm_du_map_create()) == NULL)
+ return -1;
+
INIT_LIST_HEAD(&instance->ipcps);
+ INIT_LIST_HEAD(&instance->reg_names);
sockfd = server_socket_open(IRM_SOCK_PATH);
if (sockfd < 0) {
@@ -502,12 +724,14 @@ int main()
case IRM_MSG_CODE__IRM_AP_REG:
ret_msg.has_fd = true;
ret_msg.fd = ap_reg(msg->ap_name,
+ msg->pid,
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,
+ msg->pid,
msg->dif_name,
msg->n_dif_name);
break;
@@ -524,7 +748,7 @@ int main()
break;
case IRM_MSG_CODE__IRM_FLOW_ALLOC:
ret_msg.has_fd = true;
- ret_msg.fd = flow_alloc(msg->dst_ap_name,
+ ret_msg.fd = flow_alloc(msg->dst_name,
msg->ap_name,
msg->ae_name,
NULL,