From 38c416988fe7956f377f064e98423d8f0f30eaea Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 19 Apr 2016 19:22:03 +0200 Subject: shim-udp: flow allocation added This implements the API for flow allocation. The shims currently does the following. The shim IPCP binds to an interface (IP address) and listens for flow allocation requests on UDP port 0x0D1F (3359), referenced as the listen port (lp). It will treat any datagram received on lp as a flow allocation request. Upon receiving an allocation request IRM_MSG_CODE__IPCP_FLOW_ALLOC from the IRMd, the shim IPCP will bind a UDP socket to a port (cp) allocated by the host OS. From that port it will send a UDP packet containing the destination ap_name to server_host:lp and wait for a response. Upon reception of a packet on server_host:lp, the shim_IPCP creates a UDP socket for the flow with a port set by the host os (sp), binds to it and echoes the received datagram back from server_host:sp to client_host:cp. It will also notify the IRMd of an incoming flow allocation request IRM_MSG_CODE__IPCP_FLOW_REQ_ARR, with as src_ap_name ("John Day"). It will get the port_id as a return value of that message and create a flow with status FLOW_PENDING with that port_id. If the server responds negatively to the flow allocation request (i.e. the shim IPCP on the server side receives a IRM_MSG_CODE__IPCP_FLOW_ALLOC_RESPONSE with a response != 0, it will delete the pending flow. If response == 0, it will set the status to FLOW_ALLOCATED. On the client machine the IPCP will learn sp upon reception of the echoed datagram. It will then create a flow with the port_id it received with the message from the IRMd and set it to ALLOCATED. Pending implementation: DNS support, this PR only supports local flows on the loopback adapter 127.0.0.1. A thread to listen for the echoed message, to avoid the entire IPCP to block when the echoed message is lost. This PR compiles but is untested pending necessary implementations elsewhere in the stack. --- src/ipcpd/ipcp-data.c | 29 ++++- src/ipcpd/ipcp-data.h | 9 +- src/ipcpd/ipcp.c | 4 +- src/ipcpd/shim-udp/main.c | 294 +++++++++++++++++++++++++++++++++++++++++-- src/irmd/main.c | 15 ++- src/lib/ipcpd_messages.proto | 1 + src/lib/irmd_messages.proto | 3 +- 7 files changed, 329 insertions(+), 26 deletions(-) diff --git a/src/ipcpd/ipcp-data.c b/src/ipcpd/ipcp-data.c index 2ed20943..1828fda9 100644 --- a/src/ipcpd/ipcp-data.c +++ b/src/ipcpd/ipcp-data.c @@ -436,8 +436,8 @@ uint64_t ipcp_data_get_addr(struct ipcp_data * data, return addr; } -static flow_t * find_flow(struct ipcp_data * data, - uint32_t port_id) +flow_t * ipcp_data_find_flow(struct ipcp_data * data, + uint32_t port_id) { struct list_head * h; list_for_each(h, &data->flows) { @@ -452,7 +452,7 @@ static flow_t * find_flow(struct ipcp_data * data, bool ipcp_data_has_flow(struct ipcp_data * data, uint32_t port_id) { - return find_flow(data, port_id) != NULL; + return ipcp_data_find_flow(data, port_id) != NULL; } int ipcp_data_add_flow(struct ipcp_data * data, @@ -474,3 +474,26 @@ int ipcp_data_add_flow(struct ipcp_data * data, return 0; } + +int ipcp_data_del_flow(struct ipcp_data * data, + uint32_t port_id) +{ + flow_t * f; + + if (data == NULL) + return -1; + + pthread_mutex_lock(&data->flow_lock); + + f = ipcp_data_find_flow(data, port_id); + if (f == NULL) + return -1; + + list_del(&f->list); + + free(f); + + pthread_mutex_unlock(&data->flow_lock); + + return 0; +} diff --git a/src/ipcpd/ipcp-data.h b/src/ipcpd/ipcp-data.h index a8db44f7..3f036ef5 100644 --- a/src/ipcpd/ipcp-data.h +++ b/src/ipcpd/ipcp-data.h @@ -80,12 +80,11 @@ uint64_t ipcp_data_get_addr(struct ipcp_data * data, const char * ap_name); bool ipcp_data_has_flow(struct ipcp_data * data, uint32_t port_id); -bool ipcp_data_has_flow_s(struct ipcp_data * data, - uint32_t port_id, - enum flow_state state); +flow_t * ipcp_data_find_flow(struct ipcp_data * data, + uint32_t port_id); int ipcp_data_add_flow(struct ipcp_data * data, flow_t * flow); -int ipcp_data_remove_flow(struct ipcp_data * data, - uint32_t port_id); +int ipcp_data_del_flow(struct ipcp_data * data, + uint32_t port_id); #endif /* IPCPD_IPCP_DATA_H */ diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 0b652ff6..e0dac20b 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -174,8 +174,8 @@ int ipcp_main_loop(struct ipcp * _ipcp) LOG_ERR("Flow_alloc unsupported."); break; } - ret_msg.has_result = true; - ret_msg.result = _ipcp->ops->ipcp_flow_alloc( + ret_msg.has_fd = true; + ret_msg.fd = _ipcp->ops->ipcp_flow_alloc( msg->port_id, msg->dst_ap_name, msg->ap_name, diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index df731490..66513b02 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -43,10 +43,23 @@ #include #include +#include "irmd_messages.pb-c.h" + +typedef IrmMsg irm_msg_t; + +#include "ipcpd_messages.pb-c.h" + +typedef IpcpMsg ipcp_msg_t; + #define THIS_TYPE IPCP_SHIM_UDP +#define LISTEN_PORT htons(0x0D1F) +#define SHIM_UDP_BUF_SIZE 256 #define shim_data(type) ((struct ipcp_udp_data *) type->data) +#define local_ip (((struct ipcp_udp_data *) \ + _ipcp->data)->s_saddr.sin_addr.s_addr) + /* global for trapping signal */ int irmd_pid; @@ -64,16 +77,16 @@ struct ipcp_udp_data { uint32_t ip_addr; uint32_t dns_addr; + /* listen server */ + struct sockaddr_in s_saddr; + int s_fd; + pthread_mutex_t lock; }; struct udp_flow { /* FLOW MUST BE FIRST !!!! */ flow_t flow; - - uint16_t localport; - - struct sockaddr_in * remote; int fd; }; @@ -131,10 +144,117 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, return udp_data; } +void * ipcp_udp_listener() +{ + char buf[SHIM_UDP_BUF_SIZE]; + int n = 0; + + struct sockaddr_in f_saddr; + struct sockaddr_in c_saddr; + struct hostent * hostp; + struct udp_flow * flow; + int sfd = shim_data(_ipcp)->s_fd; + + irm_msg_t msg = IRM_MSG__INIT; + irm_msg_t * ret_msg ; + + while (true) { + flow = malloc(sizeof *flow); + if (flow == NULL) + continue; + n = sizeof c_saddr; + n = recvfrom(sfd, buf, SHIM_UDP_BUF_SIZE, 0, + (struct sockaddr *) &c_saddr, (unsigned *) &n); + if (n < 0) + continue; + + /* flow alloc request from other host */ + hostp = gethostbyaddr((const char *)&c_saddr.sin_addr.s_addr, + sizeof(c_saddr.sin_addr.s_addr), AF_INET); + if (hostp == NULL) + continue; + + /* create a new socket for the server */ + + flow->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (flow->fd == -1) { + free(flow); + continue; + } + + memset((char *)&f_saddr, 0, sizeof f_saddr); + f_saddr.sin_family = AF_INET; + f_saddr.sin_addr.s_addr = local_ip; + + /* + * FIXME: we could have a port dedicated per registered AP + * Not that critical for UDP, but will be for LLC + */ + + f_saddr.sin_port = 0; + + /* at least try to get the packet on the wire */ + while (sendto(flow->fd, buf, n, 0, + (struct sockaddr *) &c_saddr, sizeof c_saddr) < 0) + ; + + /* + * store the remote address in the file descriptor + * this avoids having to store the sockaddr_in in + * the flow structure + */ + + if (connect(flow->fd, + (struct sockaddr *)&c_saddr, sizeof c_saddr) < 0) { + close(flow->fd); + free(flow); + continue; + } + + + /* GERONIMOO */ + + msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; + msg.ap_name = "John Day"; + msg.ae_name = ""; /* no AE */ + msg.has_reg_ap_id = true; + msg.reg_ap_id = ipcp_data_get_reg_ap_id(_ipcp->data, buf); + + ret_msg = send_recv_irm_msg(&msg); + if (ret_msg == NULL) { + LOG_ERR("Could not send message to IRM."); + close(flow->fd); + free(flow); + continue; + } + + if (!ret_msg->has_port_id) { + LOG_ERR("Didn't get port_id."); + free(ret_msg); + close(flow->fd); + free(flow); + continue; + } + + flow->flow.port_id = ret_msg->port_id; + flow->flow.oflags = FLOW_O_DEFAULT; + flow->flow.state = FLOW_PENDING; + + if(ipcp_data_add_flow(_ipcp->data, (flow_t *) flow)) { + LOG_DBGF("Could not add flow."); + free(ret_msg); + close(flow->fd); + free(flow); + continue; + } + } +} + int ipcp_udp_bootstrap(struct dif_config * conf) { char ipstr[INET_ADDRSTRLEN]; char dnsstr[INET_ADDRSTRLEN]; + pthread_t handler; if (conf->type != THIS_TYPE) { LOG_ERR("Config doesn't match IPCP type."); @@ -162,6 +282,27 @@ int ipcp_udp_bootstrap(struct dif_config * conf) shim_data(_ipcp)->ip_addr = conf->ip_addr; shim_data(_ipcp)->dns_addr = conf->dns_addr; + /* UDP listen server */ + + if ((shim_data(_ipcp)->s_fd = + socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { + LOG_DBGF("Can't create socket."); + return -1; + } + + shim_data(_ipcp)->s_saddr.sin_family = AF_INET; + shim_data(_ipcp)->s_saddr.sin_addr.s_addr = conf->ip_addr; + shim_data(_ipcp)->s_saddr.sin_port = LISTEN_PORT; + + if (bind(shim_data(_ipcp)->s_fd, + (struct sockaddr *)&shim_data(_ipcp)->s_saddr, + sizeof shim_data(_ipcp)->s_saddr ) < 0) { + LOG_ERR("Couldn't bind to %s.", ipstr); + return -1; + } + + pthread_create(&handler, NULL, ipcp_udp_listener, NULL); + _ipcp->state = IPCP_ENROLLED; LOG_DBG("Bootstrapped shim IPCP over UDP %s-%d.", @@ -196,7 +337,6 @@ int ipcp_udp_ap_unreg(uint32_t reg_ap_id) { char * name = strdup(ipcp_data_get_reg_ap_name(_ipcp->data, reg_ap_id)); - LOG_DBG("Unregistering %s.", name); ipcp_data_del_reg_entry(_ipcp->data, reg_ap_id); @@ -214,11 +354,151 @@ int ipcp_udp_flow_alloc(uint32_t port_id, char * src_ae_name, struct qos_spec * qos) { - return 0; + char buf[SHIM_UDP_BUF_SIZE]; + struct udp_flow * flow = NULL; + struct sockaddr_in l_saddr; + struct sockaddr_in r_saddr; + int n; + + irm_msg_t msg = IRM_MSG__INIT; + irm_msg_t * ret_msg = NULL; + + if (dst_ap_name == NULL || src_ap_name == NULL || src_ae_name == NULL) + return -1; + + LOG_DBG("Received flow allocation request from %s to %s.", + src_ap_name, dst_ap_name); + + if (strlen(dst_ap_name) > 255 + || strlen(src_ap_name) > 255 + || strlen(src_ae_name) > 255) { + LOG_ERR("Name too long for this shim."); + return -1; + } + + if (qos != NULL) + LOG_DBGF("QoS requested. UDP/IP can't do that."); + + flow = malloc (sizeof *flow); + if (flow == NULL) + return -1; + + flow->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (flow->fd == -1) { + free(flow); + return -1; + } + + /* this socket is for the flow */ + memset((char *)&l_saddr, 0, sizeof l_saddr); + l_saddr.sin_family = AF_INET; + l_saddr.sin_addr.s_addr = local_ip; + l_saddr.sin_port = 0; + + if (bind(flow->fd, (struct sockaddr *) &l_saddr, sizeof l_saddr) < 0) { + char ipstr[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, + &l_saddr.sin_addr.s_addr, + ipstr, + INET_ADDRSTRLEN); + close(flow->fd); + free(flow); + return -1; + } + + /* get the remote IPv4 address using dns */ + /* FIXME: use calls to specify DDNS server */ + +#define IP_ADDR 0x7f000001; /* localhost */ + + LOG_MISSING; + + memset((char *)&r_saddr, 0, sizeof r_saddr); + r_saddr.sin_family = AF_INET; + /* FIXME: pull in correct IP address */ + r_saddr.sin_addr.s_addr = IP_ADDR; /* FIXME */ + r_saddr.sin_port = LISTEN_PORT; + + /* at least try to get the packet on the wire */ + while (sendto(flow->fd, dst_ap_name, n, 0, + (struct sockaddr *) &r_saddr, sizeof r_saddr) < 0) + + /* wait for the echo from the server */ + /* FIXME: do this in a different thread not to block the entire shim */ + n = sizeof r_saddr; + n = recvfrom(flow->fd, buf, SHIM_UDP_BUF_SIZE, 0, + (struct sockaddr *) &r_saddr, (unsigned *) &n); + + flow->flow.port_id = port_id; + flow->flow.oflags = FLOW_O_DEFAULT; + flow->flow.state = FLOW_ALLOCATED; + + /* + * store the remote address in the file descriptor + * this avoids having to store the sockaddr_in in + * the flow structure + */ + + if (connect(flow->fd, + (struct sockaddr *)&r_saddr, sizeof r_saddr) < 0) { + close(flow->fd); + free(flow); + return -1; + } + + /* add flow to the list */ + + pthread_mutex_lock(&_ipcp->data->flow_lock); + + if(ipcp_data_add_flow(_ipcp->data, (flow_t *)flow)) { + LOG_DBGF("Could not add flow."); + pthread_mutex_unlock(&_ipcp->data->flow_lock); + close(flow->fd); + free(flow); + return -1; + } + + pthread_mutex_unlock(&_ipcp->data->flow_lock); + + /* tell IRMd that flow allocation worked */ + /* well,there is no flow allocation */ + + msg.code = IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY; + msg.has_port_id = true; + msg.port_id = flow->flow.port_id; + msg.has_response = true; + msg.response = 0; + + ret_msg = send_recv_irm_msg(&msg); + if (ret_msg == NULL) { + close (flow->fd); + ipcp_data_del_flow(_ipcp->data, flow->flow.port_id); + return -1; + } + + return flow->fd; } int ipcp_udp_flow_alloc_resp(uint32_t port_id, - int result) + int response) { + struct udp_flow * flow = (struct udp_flow *) ipcp_data_find_flow( + _ipcp->data, port_id); + if (flow == NULL) { + return -1; + } + + if (response) { + ipcp_data_del_flow(_ipcp->data, port_id); + return 0; + } + + /* awaken pending flow */ + + if (flow->flow.state != FLOW_PENDING) + return -1; + + flow->flow.state = FLOW_ALLOCATED; + return 0; } diff --git a/src/irmd/main.c b/src/irmd/main.c index 13076cd1..b5a5e145 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -366,7 +366,6 @@ int main() sigaction(SIGTERM, &sig_act, NULL); sigaction(SIGHUP, &sig_act, NULL); - if (access("/dev/shm/" SHM_DU_MAP_FILENAME, F_OK) != -1) unlink("/dev/shm/" SHM_DU_MAP_FILENAME); @@ -480,8 +479,8 @@ int main() msg->oflags); break; case IRM_MSG_CODE__IRM_FLOW_ALLOC_RES: - ret_msg.has_result = true; - ret_msg.result = flow_alloc_res(msg->fd); + ret_msg.has_response = true; + ret_msg.response = flow_alloc_res(msg->fd); break; case IRM_MSG_CODE__IRM_FLOW_DEALLOC: ret_msg.has_result = true; @@ -493,15 +492,15 @@ int main() msg->oflags); break; case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR: - ret_msg.has_fd = true; - ret_msg.fd = flow_req_arr(msg->port_id, - msg->ap_name, - msg->ae_name); + ret_msg.has_port_id = true; + ret_msg.port_id = flow_req_arr(msg->port_id, + msg->ap_name, + msg->ae_name); break; case IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY: ret_msg.has_result = true; ret_msg.result = flow_alloc_reply(msg->port_id, - msg->result); + msg->response); break; case IRM_MSG_CODE__IPCP_FLOW_DEALLOC: ret_msg.has_result = true; diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto index 796638c7..850c64e4 100644 --- a/src/lib/ipcpd_messages.proto +++ b/src/lib/ipcpd_messages.proto @@ -26,4 +26,5 @@ message ipcp_msg { optional string ae_name = 10; optional dif_config_msg conf = 11; optional int32 result = 12; + optional int32 fd = 13; }; diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto index 92ea439e..d484a007 100644 --- a/src/lib/irmd_messages.proto +++ b/src/lib/irmd_messages.proto @@ -31,11 +31,12 @@ message irm_msg { optional uint32 ipcp_type = 5; repeated string dif_name = 6; optional int32 fd = 7; - optional int32 result = 8; + optional int32 response = 8; optional int32 oflags = 9; optional string dst_ap_name = 10; optional uint32 port_id = 11; optional uint32 reg_ap_id = 12; optional int32 pid = 13; optional dif_config_msg conf = 14; + optional int32 result = 15; }; -- cgit v1.2.3 From 423cbd695b0eed9d4ec55abb1f6a0bfa0e4e48a4 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 20 Apr 2016 12:36:53 +0200 Subject: ipdpd: defined ANONYMOUS_AP name fixes comments on 38c4169 (memleaks) --- src/ipcpd/ipcp.h | 3 +++ src/ipcpd/shim-udp/main.c | 31 ++++++++----------------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index 9decac8b..f640d78b 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -26,6 +26,9 @@ #include "ipcp-ops.h" #include "ipcp-data.h" +/* needed to run over shim DIFs */ +#define ANONYMOUS_AP "__ANONYMOUS__" + enum ipcp_state { IPCP_INIT = 0, IPCP_ENROLLING, diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 66513b02..9f33cf80 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -29,6 +29,7 @@ #include #include #include +#include #define OUROBOROS_PREFIX "ipcpd/shim-udp" @@ -43,14 +44,6 @@ #include #include -#include "irmd_messages.pb-c.h" - -typedef IrmMsg irm_msg_t; - -#include "ipcpd_messages.pb-c.h" - -typedef IpcpMsg ipcp_msg_t; - #define THIS_TYPE IPCP_SHIM_UDP #define LISTEN_PORT htons(0x0D1F) #define SHIM_UDP_BUF_SIZE 256 @@ -159,9 +152,6 @@ void * ipcp_udp_listener() irm_msg_t * ret_msg ; while (true) { - flow = malloc(sizeof *flow); - if (flow == NULL) - continue; n = sizeof c_saddr; n = recvfrom(sfd, buf, SHIM_UDP_BUF_SIZE, 0, (struct sockaddr *) &c_saddr, (unsigned *) &n); @@ -175,6 +165,9 @@ void * ipcp_udp_listener() continue; /* create a new socket for the server */ + flow = malloc(sizeof *flow); + if (flow == NULL) + continue; flow->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (flow->fd == -1) { @@ -193,11 +186,6 @@ void * ipcp_udp_listener() f_saddr.sin_port = 0; - /* at least try to get the packet on the wire */ - while (sendto(flow->fd, buf, n, 0, - (struct sockaddr *) &c_saddr, sizeof c_saddr) < 0) - ; - /* * store the remote address in the file descriptor * this avoids having to store the sockaddr_in in @@ -211,11 +199,10 @@ void * ipcp_udp_listener() continue; } - - /* GERONIMOO */ + /* reply to IRM */ msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; - msg.ap_name = "John Day"; + msg.ap_name = ANONYMOUS_AP; msg.ae_name = ""; /* no AE */ msg.has_reg_ap_id = true; msg.reg_ap_id = ipcp_data_get_reg_ap_id(_ipcp->data, buf); @@ -406,7 +393,6 @@ int ipcp_udp_flow_alloc(uint32_t port_id, return -1; } - /* get the remote IPv4 address using dns */ /* FIXME: use calls to specify DDNS server */ #define IP_ADDR 0x7f000001; /* localhost */ @@ -423,8 +409,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, while (sendto(flow->fd, dst_ap_name, n, 0, (struct sockaddr *) &r_saddr, sizeof r_saddr) < 0) - /* wait for the echo from the server */ - /* FIXME: do this in a different thread not to block the entire shim */ + /* FIXME:move the client handling to thread pool */ n = sizeof r_saddr; n = recvfrom(flow->fd, buf, SHIM_UDP_BUF_SIZE, 0, (struct sockaddr *) &r_saddr, (unsigned *) &n); @@ -476,7 +461,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, return -1; } - return flow->fd; + return 0; } int ipcp_udp_flow_alloc_resp(uint32_t port_id, int response) -- cgit v1.2.3 From ad99455aa38171c28705a7e9b002b53168dc8ff0 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 20 Apr 2016 16:13:47 +0200 Subject: ipdpd: shim UDP: listen to incoming SDUs The shim UDP will listen to incoming SDU's for a flow. If the flow is FLOW_PENDING, it will set it to FLOW_ALLOCATED on the reception of the first SDU, and connect() to set the destination server_host:sp. --- src/ipcpd/shim-udp/main.c | 102 +++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 28 deletions(-) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 9f33cf80..c41d35a1 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #define THIS_TYPE IPCP_SHIM_UDP #define LISTEN_PORT htons(0x0D1F) #define SHIM_UDP_BUF_SIZE 256 +#define SHIM_UDP_MAX_SDU_SIZE 9000 #define shim_data(type) ((struct ipcp_udp_data *) type->data) @@ -74,6 +76,9 @@ struct ipcp_udp_data { struct sockaddr_in s_saddr; int s_fd; + fd_set flow_fd_s; + flow_t * fd_to_flow_ptr[FD_SETSIZE]; + pthread_mutex_t lock; }; @@ -106,6 +111,7 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, struct ipcp_data * data; instance_name_t * instance_name; enum ipcp_type ipcp_type; + int n; instance_name = instance_name_create(); if (instance_name == NULL) { @@ -116,12 +122,12 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, instance_name = instance_name_init_with( instance_name, ap_name, (uint16_t)atoi(ap_id)); - if (instance_name == NULL) { + if (instance_name == NULL) { LOG_ERR("Failed to create instance name struct."); return NULL; } - udp_data= malloc (sizeof *udp_data); + udp_data = malloc (sizeof *udp_data); if (udp_data == NULL) { LOG_DBGF("Failed to allocate."); return NULL; @@ -134,6 +140,10 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, return NULL; } + FD_ZERO(&udp_data->flow_fd_s); + for (n = 0; n < FD_SETSIZE; ++n) + udp_data->fd_to_flow_ptr[n] = NULL; + return udp_data; } @@ -234,14 +244,66 @@ void * ipcp_udp_listener() free(flow); continue; } + + FD_SET(flow->fd, &shim_data(_ipcp)->flow_fd_s); + shim_data(_ipcp)->fd_to_flow_ptr[flow->fd] = &flow->flow; + } } +static void * ipcp_udp_sdu_reader (void * o) +{ + int n; + int fd; + char buf[SHIM_UDP_MAX_SDU_SIZE]; + + struct sockaddr_in r_saddr; + + while (true) { + flow_t * flow; + + if (select(FD_SETSIZE, + &shim_data(_ipcp)->flow_fd_s, + NULL, NULL, NULL) + < 0) + continue; + + for (fd = 0; fd < FD_SETSIZE; ++fd) { + if (!FD_ISSET(fd, &shim_data(_ipcp)->flow_fd_s)) + continue; + + n = sizeof r_saddr; + n = recvfrom(fd, + buf, + SHIM_UDP_MAX_SDU_SIZE, + 0, + (struct sockaddr *) &r_saddr, + (unsigned *) &n); + + flow = shim_data(_ipcp)->fd_to_flow_ptr[fd]; + if (flow->state == FLOW_PENDING) { + if (connect(fd, + (struct sockaddr *)&r_saddr, + sizeof r_saddr) + < 0) + continue; + flow->state = FLOW_ALLOCATED; + } + + /* send the sdu to the correct port_id */ + LOG_MISSING; + } + } + + return (void *) 0; +} + int ipcp_udp_bootstrap(struct dif_config * conf) { char ipstr[INET_ADDRSTRLEN]; char dnsstr[INET_ADDRSTRLEN]; pthread_t handler; + pthread_t sdu_reader; if (conf->type != THIS_TYPE) { LOG_ERR("Config doesn't match IPCP type."); @@ -289,6 +351,7 @@ int ipcp_udp_bootstrap(struct dif_config * conf) } pthread_create(&handler, NULL, ipcp_udp_listener, NULL); + pthread_create(&sdu_reader, NULL, ipcp_udp_sdu_reader, NULL); _ipcp->state = IPCP_ENROLLED; @@ -341,11 +404,9 @@ int ipcp_udp_flow_alloc(uint32_t port_id, char * src_ae_name, struct qos_spec * qos) { - char buf[SHIM_UDP_BUF_SIZE]; struct udp_flow * flow = NULL; struct sockaddr_in l_saddr; struct sockaddr_in r_saddr; - int n; irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * ret_msg = NULL; @@ -406,30 +467,12 @@ int ipcp_udp_flow_alloc(uint32_t port_id, r_saddr.sin_port = LISTEN_PORT; /* at least try to get the packet on the wire */ - while (sendto(flow->fd, dst_ap_name, n, 0, + while (sendto(flow->fd, dst_ap_name, strlen(dst_ap_name), 0, (struct sockaddr *) &r_saddr, sizeof r_saddr) < 0) - /* FIXME:move the client handling to thread pool */ - n = sizeof r_saddr; - n = recvfrom(flow->fd, buf, SHIM_UDP_BUF_SIZE, 0, - (struct sockaddr *) &r_saddr, (unsigned *) &n); - flow->flow.port_id = port_id; flow->flow.oflags = FLOW_O_DEFAULT; - flow->flow.state = FLOW_ALLOCATED; - - /* - * store the remote address in the file descriptor - * this avoids having to store the sockaddr_in in - * the flow structure - */ - - if (connect(flow->fd, - (struct sockaddr *)&r_saddr, sizeof r_saddr) < 0) { - close(flow->fd); - free(flow); - return -1; - } + flow->flow.state = FLOW_PENDING; /* add flow to the list */ @@ -445,8 +488,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, pthread_mutex_unlock(&_ipcp->data->flow_lock); - /* tell IRMd that flow allocation worked */ - /* well,there is no flow allocation */ + /* tell IRMd that flow allocation "worked" */ msg.code = IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY; msg.has_port_id = true; @@ -461,13 +503,17 @@ int ipcp_udp_flow_alloc(uint32_t port_id, return -1; } + FD_SET(flow->fd, &shim_data(_ipcp)->flow_fd_s); + shim_data(_ipcp)->fd_to_flow_ptr[flow->fd] = &flow->flow; + return 0; } + int ipcp_udp_flow_alloc_resp(uint32_t port_id, int response) { - struct udp_flow * flow = (struct udp_flow *) ipcp_data_find_flow( - _ipcp->data, port_id); + struct udp_flow * flow = + (struct udp_flow *) ipcp_data_find_flow(_ipcp->data, port_id); if (flow == NULL) { return -1; } -- cgit v1.2.3 From 18c5da3a77fd736c45730d562e35c4957269ebe3 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Thu, 21 Apr 2016 08:03:21 +0200 Subject: irmd: application registration Initial code for application registration. Specifying "*" will (for now) register with the first IPCP available in the system. Modified the echo server not to barf messages on failed accept() --- src/ipcpd/shim-udp/main.c | 12 ++++------ src/irmd/main.c | 54 +++++++++++++++++++++++++++++++++++++++++++- src/tools/echo/echo_server.c | 3 ++- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index c41d35a1..130ac17e 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -366,8 +366,6 @@ int ipcp_udp_bootstrap(struct dif_config * conf) int ipcp_udp_ap_reg(char * ap_name, uint32_t reg_ap_id) { - LOG_DBG("Registering local ap %s, %u.", ap_name, reg_ap_id); - if (_ipcp->state != IPCP_ENROLLED) { LOG_DBGF("Won't register with non-enrolled IPCP."); return -1; @@ -378,6 +376,9 @@ int ipcp_udp_ap_reg(char * ap_name, uint32_t reg_ap_id) return -1; } + LOG_DBG("Registered local ap %s, %u.", ap_name, reg_ap_id); + + /* FIXME: register application with DNS server */ LOG_MISSING; return 0; @@ -385,16 +386,11 @@ int ipcp_udp_ap_reg(char * ap_name, uint32_t reg_ap_id) int ipcp_udp_ap_unreg(uint32_t reg_ap_id) { - char * name = strdup(ipcp_data_get_reg_ap_name(_ipcp->data, - reg_ap_id)); - ipcp_data_del_reg_entry(_ipcp->data, reg_ap_id); - /* we are using dns */ + /* FIXME: unregister application from DNS server */ LOG_MISSING; - free (name); - return 0; } diff --git a/src/irmd/main.c b/src/irmd/main.c index b5a5e145..9a65cd4a 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -87,6 +87,24 @@ static struct ipcp_entry * find_ipcp_by_name(instance_name_t * api) return tmp; } +static pid_t find_pid_by_dif_name(char * dif_name) +{ + struct list_head * pos = NULL; + + list_for_each(pos, &instance->ipcps) { + struct ipcp_entry * tmp = + list_entry(pos, struct ipcp_entry, next); + + if (tmp->dif_name == NULL) + return tmp->pid; + + if (strcmp(dif_name, tmp->dif_name) == 0) + return tmp->pid; + } + + return 0; +} + static int create_ipcp(instance_name_t * api, enum ipcp_type ipcp_type) { @@ -266,7 +284,41 @@ static int ap_reg(char * ap_name, char ** difs, size_t difs_size) { - return -1; + pid_t pid = 0; + int i; + int ret = 0; + + if (instance->ipcps.next == NULL) + LOG_ERR("No IPCPs in this system."); + + /* + * FIXME: this should be resolved by NSM + * Now it just takes the first DIF + */ + + if (strcmp(difs[0], "*") == 0) { + difs[0] = list_entry(instance->ipcps.next, + struct ipcp_entry, + next)->dif_name; + difs_size = 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; + } + + /* 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; + } + } + + return ret; } static int ap_unreg(char * ap_name, diff --git a/src/tools/echo/echo_server.c b/src/tools/echo/echo_server.c index b1547d8c..d7099a2d 100644 --- a/src/tools/echo/echo_server.c +++ b/src/tools/echo/echo_server.c @@ -64,11 +64,12 @@ int server_main() return -1; } + printf("Echo server started..."); + while (true) { client_fd = flow_accept(server_fd, client_name, NULL); if (client_fd < 0) { - printf("Failed to accept flow\n"); continue; } -- cgit v1.2.3 From e57fb225562afeec7e151c64f8f4e6312b447c7c Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Thu, 21 Apr 2016 15:04:10 +0200 Subject: ipcpd: fixes comments on 18c5da3 --- src/ipcpd/shim-udp/main.c | 14 +++++++------- src/irmd/main.c | 2 +- src/tools/echo/echo_server.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 130ac17e..14b08ba8 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -48,7 +48,7 @@ #define THIS_TYPE IPCP_SHIM_UDP #define LISTEN_PORT htons(0x0D1F) #define SHIM_UDP_BUF_SIZE 256 -#define SHIM_UDP_MAX_SDU_SIZE 9000 +#define SHIM_UDP_MAX_SDU_SIZE 8980 #define shim_data(type) ((struct ipcp_udp_data *) type->data) @@ -127,7 +127,7 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, return NULL; } - udp_data = malloc (sizeof *udp_data); + udp_data = malloc(sizeof *udp_data); if (udp_data == NULL) { LOG_DBGF("Failed to allocate."); return NULL; @@ -147,7 +147,7 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, return udp_data; } -void * ipcp_udp_listener() +static void * ipcp_udp_listener() { char buf[SHIM_UDP_BUF_SIZE]; int n = 0; @@ -251,7 +251,7 @@ void * ipcp_udp_listener() } } -static void * ipcp_udp_sdu_reader (void * o) +static void * ipcp_udp_sdu_reader() { int n; int fd; @@ -423,7 +423,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, if (qos != NULL) LOG_DBGF("QoS requested. UDP/IP can't do that."); - flow = malloc (sizeof *flow); + flow = malloc(sizeof *flow); if (flow == NULL) return -1; @@ -494,7 +494,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, ret_msg = send_recv_irm_msg(&msg); if (ret_msg == NULL) { - close (flow->fd); + close(flow->fd); ipcp_data_del_flow(_ipcp->data, flow->flow.port_id); return -1; } @@ -562,7 +562,7 @@ struct ipcp * ipcp_udp_create(char * ap_name, char * i_id) return NULL; } - ops = malloc (sizeof *ops); + ops = malloc(sizeof *ops); if (ops == NULL) { free(data); free(i); diff --git a/src/irmd/main.c b/src/irmd/main.c index 9a65cd4a..374bfb6c 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -89,7 +89,7 @@ static struct ipcp_entry * find_ipcp_by_name(instance_name_t * api) static pid_t find_pid_by_dif_name(char * dif_name) { - struct list_head * pos = NULL; + struct list_head * pos = NULL; list_for_each(pos, &instance->ipcps) { struct ipcp_entry * tmp = diff --git a/src/tools/echo/echo_server.c b/src/tools/echo/echo_server.c index d7099a2d..e457e22b 100644 --- a/src/tools/echo/echo_server.c +++ b/src/tools/echo/echo_server.c @@ -64,7 +64,7 @@ int server_main() return -1; } - printf("Echo server started..."); + printf("Echo server started...\n"); while (true) { client_fd = flow_accept(server_fd, @@ -73,7 +73,7 @@ int server_main() continue; } - printf("New flow from %s", client_name); + printf("New flow from %s\n", client_name); if (flow_alloc_resp(client_fd, 0)) { printf("Failed to give an allocate response\n"); -- cgit v1.2.3 From f4f67651db3891652f4dd08dec990aa0560bb35c Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Fri, 22 Apr 2016 17:39:30 +0200 Subject: irmd: reg/unreg whatevercast names Unregistering ap's now works. An AP now registers/unregisters its AP-I by sending its AP name and its pid to the IRMd. The IPCPs register whatevercast names. An AP name is currently mapped on a whatevercast name represented by the same string literal. The IRMd allows registration of only one AP-I per AP. A Name Space Management system is needed in the processing system so we can resolve this completely. Changing the stack to register whatevercast names required some changes all over the ipcpd implemented and in the library. --- include/ouroboros/ipcp.h | 21 ++- src/ipcpd/ipcp-data.c | 94 ++-------- src/ipcpd/ipcp-data.h | 13 +- src/ipcpd/ipcp-ops.h | 5 +- src/ipcpd/ipcp.c | 22 +-- src/ipcpd/shim-udp/main.c | 24 +-- src/ipcpd/shim-udp/tests/shim_udp_test.c | 13 +- src/irmd/main.c | 284 +++++++++++++++++++++++++++---- src/lib/dev.c | 78 +++++---- src/lib/ipcp.c | 67 ++++---- src/lib/ipcpd_messages.proto | 30 ++-- src/lib/irmd_messages.proto | 71 +++++--- 12 files changed, 453 insertions(+), 269 deletions(-) diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index 3198a882..1c8d3f86 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -54,15 +54,14 @@ int ipcp_bootstrap(pid_t pid, /* Flow related ops, these go from IRMd to IPCP */ -int ipcp_ap_reg(pid_t pid, - uint32_t reg_api_id, - char * ap_name); -int ipcp_ap_unreg(pid_t pid, - uint32_t reg_api_id); +int ipcp_name_reg(pid_t pid, + char * name); +int ipcp_name_unreg(pid_t pid, + char * name); int ipcp_flow_alloc(pid_t pid, uint32_t port_id, - char * dst_ap_name, + char * dst_name, char * src_ap_name, char * src_ae_name, struct qos_spec * qos); @@ -73,13 +72,13 @@ int ipcp_flow_alloc_resp(pid_t pid, /* These operations go from the IPCP to the IRMd */ /* Returns the port_id */ -int ipcp_flow_req_arr(pid_t pid, - uint32_t reg_api_id, - char * ap_name, - char * ae_name); +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, uint32_t port_id, - int result); + int response); /* * This operation can go both ways diff --git a/src/ipcpd/ipcp-data.c b/src/ipcpd/ipcp-data.c index 1828fda9..e6997e3e 100644 --- a/src/ipcpd/ipcp-data.c +++ b/src/ipcpd/ipcp-data.c @@ -35,8 +35,7 @@ struct reg_entry { struct list_head list; - char * ap_name; - uint32_t reg_ap_id; + char * name; }; struct dir_entry { @@ -45,16 +44,14 @@ struct dir_entry { uint64_t addr; }; -static struct reg_entry * reg_entry_create(const char * ap_name, - uint32_t reg_ap_id) +static struct reg_entry * reg_entry_create(const char * name) { struct reg_entry * entry = malloc(sizeof *entry); if (entry == NULL) return NULL; - entry->reg_ap_id = reg_ap_id; - entry->ap_name = strdup(ap_name); - if (entry->ap_name == NULL) + entry->name = strdup(name); + if (entry->name == NULL) return NULL; return entry; @@ -65,7 +62,7 @@ static void reg_entry_destroy(struct reg_entry * entry) if (entry == NULL) return; - free(entry->ap_name); + free(entry->name); free(entry); } @@ -194,25 +191,12 @@ void ipcp_data_destroy(struct ipcp_data * data) static struct reg_entry * find_reg_entry_by_name(struct ipcp_data * data, - const char * ap_name) + const char * name) { struct list_head * h; list_for_each(h, &data->registry) { struct reg_entry * e = list_entry(h, struct reg_entry, list); - if (!strcmp(e->ap_name, ap_name)) - return e; - } - - return NULL; -} - -static struct reg_entry * find_reg_entry_by_id(struct ipcp_data * data, - uint32_t reg_ap_id) -{ - struct list_head * h; - list_for_each(h, &data->registry) { - struct reg_entry * e = list_entry(h, struct reg_entry, list); - if (e->reg_ap_id == reg_ap_id) + if (!strcmp(e->name, name)) return e; } @@ -253,7 +237,7 @@ bool ipcp_data_is_in_directory(struct ipcp_data * data, } int ipcp_data_del_reg_entry(struct ipcp_data * data, - uint32_t reg_ap_id) + const char * name) { struct reg_entry * e; if (data == NULL) @@ -261,7 +245,7 @@ int ipcp_data_del_reg_entry(struct ipcp_data * data, pthread_mutex_lock(&data->reg_lock); - e = find_reg_entry_by_id(data, reg_ap_id); + e = find_reg_entry_by_name(data, name); if (e == NULL) { pthread_mutex_unlock(&data->reg_lock); return 0; /* nothing to do */ @@ -302,23 +286,21 @@ int ipcp_data_del_dir_entry(struct ipcp_data * data, } int ipcp_data_add_reg_entry(struct ipcp_data * data, - char * ap_name, - uint32_t reg_ap_id) + const char * name) { struct reg_entry * entry; - if (data == NULL || ap_name == NULL) + if (data == NULL || name == NULL) return -1; pthread_mutex_lock(&data->reg_lock); - if (find_reg_entry_by_name(data, ap_name) || - find_reg_entry_by_id(data, reg_ap_id)) { + if (find_reg_entry_by_name(data, name)) { pthread_mutex_unlock(&data->reg_lock); return -2; } - entry = reg_entry_create(ap_name, reg_ap_id); + entry = reg_entry_create(name); if (entry == NULL) { pthread_mutex_unlock(&data->reg_lock); return -1; @@ -332,7 +314,7 @@ int ipcp_data_add_reg_entry(struct ipcp_data * data, } int ipcp_data_add_dir_entry(struct ipcp_data * data, - char * ap_name, + const char * ap_name, uint64_t addr) { struct dir_entry * entry; @@ -366,54 +348,6 @@ bool ipcp_data_is_in_registry(struct ipcp_data * data, return find_reg_entry_by_name(data, ap_name) != NULL; } -uint32_t ipcp_data_get_reg_ap_id(struct ipcp_data * data, - const char * ap_name) -{ - struct reg_entry * entry; - uint32_t id; - - pthread_mutex_lock(&data->reg_lock); - - entry = find_reg_entry_by_name(data, ap_name); - - if (entry == NULL) { - pthread_mutex_unlock(&data->reg_lock); - return 0; /* undefined behaviour */ - } - - id = entry->reg_ap_id; - - pthread_mutex_unlock(&data->reg_lock); - - return id; -} - -const char * ipcp_data_get_reg_ap_name(struct ipcp_data * data, - uint32_t reg_ap_id) -{ - struct reg_entry * entry; - char * name; - - pthread_mutex_lock(&data->reg_lock); - - entry = find_reg_entry_by_id(data, reg_ap_id); - - if (entry == NULL) { - pthread_mutex_unlock(&data->reg_lock); - return NULL; - } - - name = strdup(entry->ap_name); - if (name == NULL) { - pthread_mutex_unlock(&data->reg_lock); - return NULL; - } - - pthread_mutex_unlock(&data->reg_lock); - - return name; -} - uint64_t ipcp_data_get_addr(struct ipcp_data * data, const char * ap_name) { diff --git a/src/ipcpd/ipcp-data.h b/src/ipcpd/ipcp-data.h index 3f036ef5..7e48df24 100644 --- a/src/ipcpd/ipcp-data.h +++ b/src/ipcpd/ipcp-data.h @@ -58,22 +58,17 @@ struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, void ipcp_data_destroy(struct ipcp_data * data); int ipcp_data_add_reg_entry(struct ipcp_data * data, - char * ap_name, - uint32_t reg_ap_id); + const char * name); int ipcp_data_del_reg_entry(struct ipcp_data * data, - uint32_t reg_ap_id); + const char * name); int ipcp_data_add_dir_entry(struct ipcp_data * data, - char * ap_name, + const char * ap_name, uint64_t addr); int ipcp_data_del_dir_entry(struct ipcp_data * data, const char * ap_name, uint64_t addr); bool ipcp_data_is_in_registry(struct ipcp_data * data, - const char * ap_name); -uint32_t ipcp_data_get_reg_ap_id(struct ipcp_data * data, - const char * ap_name); -const char * ipcp_data_get_reg_ap_name(struct ipcp_data * data, - uint32_t reg_ap_id); + const char * name); bool ipcp_data_is_in_directory(struct ipcp_data * data, const char * ap_name); uint64_t ipcp_data_get_addr(struct ipcp_data * data, diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/ipcp-ops.h index 5c917229..2ccb2e59 100644 --- a/src/ipcpd/ipcp-ops.h +++ b/src/ipcpd/ipcp-ops.h @@ -36,9 +36,8 @@ struct ipcp_ops { size_t len); int (* ipcp_unreg)(char ** dif_names, size_t len); - int (* ipcp_ap_reg)(char * ap_name, - uint32_t reg_ap_id); - int (* ipcp_ap_unreg)(uint32_t reg_ap_id); + int (* ipcp_name_reg)(char * name); + int (* ipcp_name_unreg)(char * name); int (* ipcp_flow_alloc)(uint32_t port_id, char * dst_ap_name, char * src_ap_name, diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index e0dac20b..c1071e05 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -151,23 +151,23 @@ int ipcp_main_loop(struct ipcp * _ipcp) ret_msg.result = _ipcp->ops->ipcp_unreg( msg->dif_names, msg->len); break; - case IPCP_MSG_CODE__IPCP_AP_REG: - if (_ipcp->ops->ipcp_ap_reg == NULL) { + case IPCP_MSG_CODE__IPCP_NAME_REG: + if (_ipcp->ops->ipcp_name_reg == NULL) { LOG_ERR("Ap_reg unsupported."); break; } ret_msg.has_result = true; - ret_msg.result = _ipcp->ops->ipcp_ap_reg( - msg->ap_name, msg->reg_ap_id); + ret_msg.result = _ipcp->ops->ipcp_name_reg( + msg->name); break; - case IPCP_MSG_CODE__IPCP_AP_UNREG: - if (_ipcp->ops->ipcp_ap_unreg == NULL) { + case IPCP_MSG_CODE__IPCP_NAME_UNREG: + if (_ipcp->ops->ipcp_name_unreg == NULL) { LOG_ERR("Ap_unreg unsupported."); break; } ret_msg.has_result = true; - ret_msg.result = _ipcp->ops->ipcp_ap_unreg( - msg->reg_ap_id); + ret_msg.result = _ipcp->ops->ipcp_name_unreg( + msg->name); break; case IPCP_MSG_CODE__IPCP_FLOW_ALLOC: if (_ipcp->ops->ipcp_flow_alloc == NULL) { @@ -177,9 +177,9 @@ int ipcp_main_loop(struct ipcp * _ipcp) ret_msg.has_fd = true; ret_msg.fd = _ipcp->ops->ipcp_flow_alloc( msg->port_id, - msg->dst_ap_name, - msg->ap_name, - msg->ae_name, + msg->dst_name, + msg->src_ap_name, + msg->src_ae_name, NULL); break; case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP: diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 14b08ba8..a65aa11d 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -214,8 +214,7 @@ static void * ipcp_udp_listener() msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; msg.ap_name = ANONYMOUS_AP; msg.ae_name = ""; /* no AE */ - msg.has_reg_ap_id = true; - msg.reg_ap_id = ipcp_data_get_reg_ap_id(_ipcp->data, buf); + msg.dst_name = buf; ret_msg = send_recv_irm_msg(&msg); if (ret_msg == NULL) { @@ -247,8 +246,9 @@ static void * ipcp_udp_listener() FD_SET(flow->fd, &shim_data(_ipcp)->flow_fd_s); shim_data(_ipcp)->fd_to_flow_ptr[flow->fd] = &flow->flow; - } + + return 0; } static void * ipcp_udp_sdu_reader() @@ -364,19 +364,19 @@ int ipcp_udp_bootstrap(struct dif_config * conf) return 0; } -int ipcp_udp_ap_reg(char * ap_name, uint32_t reg_ap_id) +int ipcp_udp_name_reg(char * name) { if (_ipcp->state != IPCP_ENROLLED) { LOG_DBGF("Won't register with non-enrolled IPCP."); return -1; } - if (ipcp_data_add_reg_entry(_ipcp->data, ap_name, reg_ap_id)) { - LOG_ERR("Failed to add AP to local registry."); + if (ipcp_data_add_reg_entry(_ipcp->data, name)) { + LOG_ERR("Failed to add %s to local registry.", name); return -1; } - LOG_DBG("Registered local ap %s, %u.", ap_name, reg_ap_id); + LOG_DBG("Registered %s", name); /* FIXME: register application with DNS server */ LOG_MISSING; @@ -384,9 +384,11 @@ int ipcp_udp_ap_reg(char * ap_name, uint32_t reg_ap_id) return 0; } -int ipcp_udp_ap_unreg(uint32_t reg_ap_id) +int ipcp_udp_name_unreg(char * name) { - ipcp_data_del_reg_entry(_ipcp->data, reg_ap_id); + ipcp_data_del_reg_entry(_ipcp->data, name); + + LOG_DBG("Unregistered %s.", name); /* FIXME: unregister application from DNS server */ LOG_MISSING; @@ -573,8 +575,8 @@ struct ipcp * ipcp_udp_create(char * ap_name, char * i_id) ops->ipcp_enroll = NULL; /* shim */ ops->ipcp_reg = NULL; /* shim */ ops->ipcp_unreg = NULL; /* shim */ - ops->ipcp_ap_reg = ipcp_udp_ap_reg; - ops->ipcp_ap_unreg = ipcp_udp_ap_unreg; + ops->ipcp_name_reg = ipcp_udp_name_reg; + ops->ipcp_name_unreg = ipcp_udp_name_unreg; ops->ipcp_flow_alloc = ipcp_udp_flow_alloc; ops->ipcp_flow_alloc_resp = ipcp_udp_flow_alloc_resp; ops->ipcp_flow_dealloc = ipcp_udp_flow_dealloc; diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c index 427d0e1e..0fcf9f4d 100644 --- a/src/ipcpd/shim-udp/tests/shim_udp_test.c +++ b/src/ipcpd/shim-udp/tests/shim_udp_test.c @@ -68,21 +68,21 @@ int shim_udp_test(int argc, char ** argv) LOG_ERR("Could not bootstrap."); } - if(ipcp_udp_ap_reg("bogus ap", 1865)) { + if(ipcp_udp_name_reg("bogus name")) { LOG_ERR("Failed to register application."); shm_du_map_close(dum); exit(1); } - if (ipcp_udp_ap_unreg(1865)) { + if (ipcp_udp_name_unreg("bogus name")) { LOG_ERR("Failed to unregister application."); shm_du_map_close(dum); exit(1); } for (i = 0; i < 1000; ++i) { - sprintf (bogus, "bogus ap %4d", i); - if(ipcp_udp_ap_reg(bogus, i)) { + sprintf (bogus, "bogus name %4d", i); + if(ipcp_udp_name_reg(bogus)) { LOG_ERR("Failed to register application %s.", bogus); shm_du_map_close(dum); exit(1); @@ -90,8 +90,9 @@ int shim_udp_test(int argc, char ** argv) } for (i = 0; i < 1000; ++i) { - if(ipcp_udp_ap_unreg(i)) { - LOG_ERR("Failed to unregister application %d.", i); + sprintf (bogus, "bogus name %4d", i); + if(ipcp_udp_name_unreg(bogus)) { + LOG_ERR("Failed to unregister application %s.", bogus); shm_du_map_close(dum); exit(1); } 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 #include #include +#include + +/* 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, diff --git a/src/lib/dev.c b/src/lib/dev.c index c138b009..60dee701 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -43,9 +43,11 @@ int ap_reg(char * ap_name, return -EINVAL; } - msg.code = IRM_MSG_CODE__IRM_AP_REG; - msg.ap_name = ap_name; - msg.dif_name = difs; + msg.code = IRM_MSG_CODE__IRM_AP_REG; + msg.has_pid = true; + msg.pid = getpid(); + msg.ap_name = ap_name; + msg.dif_name = difs; msg.n_dif_name = difs_size; recv_msg = send_recv_irm_msg(&msg); @@ -78,9 +80,11 @@ int ap_unreg(char * ap_name, return -EINVAL; } - msg.code = IRM_MSG_CODE__IRM_AP_UNREG; - msg.ap_name = ap_name; - msg.dif_name = difs; + msg.code = IRM_MSG_CODE__IRM_AP_UNREG; + msg.has_pid = true; + msg.pid = getpid(); + msg.ap_name = ap_name; + msg.dif_name = difs; msg.n_dif_name = difs_size; recv_msg = send_recv_irm_msg(&msg); @@ -110,9 +114,11 @@ int flow_accept(int fd, return -EINVAL; } - msg.code = IRM_MSG_CODE__IRM_FLOW_ACCEPT; - msg.has_fd = true; - msg.fd = fd; + msg.code = IRM_MSG_CODE__IRM_FLOW_ACCEPT; + msg.has_pid = true; + msg.pid = getpid(); + msg.has_fd = true; + msg.fd = fd; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -122,7 +128,7 @@ int flow_accept(int fd, irm_msg__free_unpacked(recv_msg, NULL); return -1; } - cli_fd = recv_msg->fd; + cli_fd = recv_msg->fd; ap_name = recv_msg->ap_name; ae_name = recv_msg->ae_name; @@ -131,17 +137,19 @@ int flow_accept(int fd, } int flow_alloc_resp(int fd, - int result) + int response) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC_RESP; - msg.has_fd = true; + msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC_RESP; + msg.has_pid = true; + msg.pid = getpid(); + msg.has_fd = true; msg.fd = fd; - msg.has_result = true; - msg.result = result; + msg.has_response = true; + msg.response = response; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -158,7 +166,7 @@ int flow_alloc_resp(int fd, return ret; } -int flow_alloc(char * dst_ap_name, +int flow_alloc(char * dst_name, char * src_ap_name, char * src_ae_name, struct qos_spec * qos, @@ -168,18 +176,18 @@ int flow_alloc(char * dst_ap_name, irm_msg_t * recv_msg = NULL; int fd = 0; - if (dst_ap_name == NULL || + if (dst_name == NULL || src_ap_name == NULL || qos == NULL) { return -EINVAL; } - msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC; - msg.dst_ap_name = dst_ap_name; - msg.ap_name = src_ap_name; - msg.ae_name = src_ae_name; - msg.has_oflags = true; - msg.oflags = oflags; + msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC; + msg.dst_name = dst_name; + msg.ap_name = src_ap_name; + msg.ae_name = src_ae_name; + msg.has_oflags = true; + msg.oflags = oflags; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -201,9 +209,11 @@ int flow_alloc_res(int fd) irm_msg_t * recv_msg = NULL; int result = 0; - msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC_RES; - msg.has_fd = true; - msg.fd = fd; + msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC_RES; + msg.has_pid = true; + msg.pid = getpid(); + msg.has_fd = true; + msg.fd = fd; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -226,9 +236,11 @@ int flow_dealloc(int fd) irm_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IRM_MSG_CODE__IRM_FLOW_DEALLOC; - msg.has_fd = true; - msg.fd = fd; + msg.code = IRM_MSG_CODE__IRM_FLOW_DEALLOC; + msg.has_pid = true; + msg.pid = getpid(); + msg.has_fd = true; + msg.fd = fd; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -251,9 +263,11 @@ int flow_cntl(int fd, int oflags) irm_msg_t * recv_msg = NULL; int ret = -1; - msg.has_fd = true; - msg.fd = fd; - msg.oflags = oflags; + msg.has_pid = true; + msg.pid = getpid(); + msg.has_fd = true; + msg.fd = fd; + msg.oflags = oflags; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c index 338d8683..b93f5488 100644 --- a/src/lib/ipcp.c +++ b/src/lib/ipcp.c @@ -326,21 +326,18 @@ int ipcp_enroll(pid_t pid, return ret; } -int ipcp_ap_reg(pid_t pid, - uint32_t reg_ap_id, - char * ap_name) +int ipcp_name_reg(pid_t pid, + char * name) { ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; int ret = -1; - if (ap_name == NULL) + if (name == NULL) return -1; - msg.code = IPCP_MSG_CODE__IPCP_AP_REG; - msg.ap_name = ap_name; - msg.has_reg_ap_id = true; - msg.reg_ap_id = reg_ap_id; + msg.code = IPCP_MSG_CODE__IPCP_NAME_REG; + msg.name = name; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -357,16 +354,15 @@ int ipcp_ap_reg(pid_t pid, return ret; } -int ipcp_ap_unreg(pid_t pid, - uint32_t reg_ap_id) +int ipcp_name_unreg(pid_t pid, + char * name) { ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IPCP_MSG_CODE__IPCP_AP_UNREG; - msg.has_reg_ap_id = true; - msg.reg_ap_id = reg_ap_id; + msg.code = IPCP_MSG_CODE__IPCP_NAME_UNREG; + msg.name = name; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -385,7 +381,7 @@ int ipcp_ap_unreg(pid_t pid, int ipcp_flow_alloc(pid_t pid, uint32_t port_id, - char * dst_ap_name, + char * dst_name, char * src_ap_name, char * src_ae_name, struct qos_spec * qos) @@ -394,13 +390,13 @@ int ipcp_flow_alloc(pid_t pid, ipcp_msg_t * recv_msg = NULL; int ret = -1; - if (dst_ap_name == NULL || src_ap_name == NULL || src_ae_name == NULL) + if (dst_name == NULL || src_ap_name == NULL || src_ae_name == NULL) return -EINVAL; msg.code = IPCP_MSG_CODE__IPCP_FLOW_ALLOC; - msg.ap_name = src_ap_name; - msg.ae_name = src_ae_name; - msg.dst_ap_name = dst_ap_name; + msg.src_ap_name = src_ap_name; + msg.src_ae_name = src_ae_name; + msg.dst_name = dst_name; msg.port_id = port_id; msg.has_port_id = true; @@ -449,22 +445,21 @@ int ipcp_flow_alloc_resp(pid_t pid, } int ipcp_flow_req_arr(pid_t pid, - uint32_t reg_ap_id, - char * ap_name, - char * ae_name) + 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 fd = -1; - if (ap_name == NULL || ae_name == NULL) + if (src_ap_name == NULL || src_ae_name == NULL) return -EINVAL; msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; - msg.ap_name = ap_name; - msg.ae_name = ae_name; - msg.reg_ap_id = reg_ap_id; - msg.has_reg_ap_id = true; + msg.dst_name = dst_name; + msg.ap_name = src_ap_name; + msg.ae_name = src_ae_name; msg.pid = pid; msg.has_pid = true; @@ -485,17 +480,17 @@ int ipcp_flow_req_arr(pid_t pid, int ipcp_flow_alloc_reply(pid_t pid, uint32_t port_id, - int result) + int response) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY; - msg.port_id = port_id; - msg.has_port_id = true; - msg.result = result; - msg.has_result = true; + msg.code = IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY; + msg.port_id = port_id; + msg.has_port_id = true; + msg.response = response; + msg.has_response = true; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) @@ -521,9 +516,9 @@ int ipcp_flow_dealloc(pid_t pid, ipcp_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IPCP_MSG_CODE__IPCP_FLOW_DEALLOC; + msg.code = IPCP_MSG_CODE__IPCP_FLOW_DEALLOC; msg.has_port_id = true; - msg.port_id = port_id; + msg.port_id = port_id; recv_msg = send_recv_ipcp_msg(pid, &msg); if (recv_msg == NULL) @@ -543,9 +538,9 @@ int ipcp_flow_dealloc(pid_t pid, irm_msg_t * recv_msg = NULL; int ret = -1; - msg.code = IRM_MSG_CODE__IPCP_FLOW_DEALLOC; + msg.code = IRM_MSG_CODE__IPCP_FLOW_DEALLOC; msg.has_port_id = true; - msg.port_id = port_id; + msg.port_id = port_id; recv_msg = send_recv_irm_msg(&msg); if (recv_msg == NULL) diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto index 850c64e4..da4bb469 100644 --- a/src/lib/ipcpd_messages.proto +++ b/src/lib/ipcpd_messages.proto @@ -1,16 +1,16 @@ import "dif_config.proto"; enum ipcp_msg_code { - IPCP_BOOTSTRAP = 1; - IPCP_ENROLL = 2; - IPCP_REG = 3; - IPCP_UNREG = 4; - IPCP_AP_REG = 5; - IPCP_AP_UNREG = 6; - IPCP_FLOW_ALLOC = 7; - IPCP_FLOW_ALLOC_RESP = 8; - IPCP_FLOW_DEALLOC = 9; - IPCP_REPLY = 10; + IPCP_BOOTSTRAP = 1; + IPCP_ENROLL = 2; + IPCP_REG = 3; + IPCP_UNREG = 4; + IPCP_NAME_REG = 5; + IPCP_NAME_UNREG = 6; + IPCP_FLOW_ALLOC = 7; + IPCP_FLOW_ALLOC_RESP = 8; + IPCP_FLOW_DEALLOC = 9; + IPCP_REPLY = 10; }; message ipcp_msg { @@ -19,11 +19,11 @@ message ipcp_msg { optional string n_1_dif = 3; repeated string dif_names = 4; optional int32 len = 5; - optional string ap_name = 6; - optional int32 reg_ap_id = 7; - optional int32 port_id = 8; - optional string dst_ap_name = 9; - optional string ae_name = 10; + optional string name = 6; + optional int32 port_id = 7; + optional string dst_name = 8; + optional string src_ap_name = 9; + optional string src_ae_name = 10; optional dif_config_msg conf = 11; optional int32 result = 12; optional int32 fd = 13; diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto index d484a007..89e2c882 100644 --- a/src/lib/irmd_messages.proto +++ b/src/lib/irmd_messages.proto @@ -1,42 +1,63 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * IRM messages + * + * 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. + */ + import "dif_config.proto"; enum irm_msg_code { - IRM_CREATE_IPCP = 1; - 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; - IRM_FLOW_CONTROL = 14; - IRM_FLOW_WRITE = 15; - IRM_FLOW_READ = 16; - IPCP_FLOW_REQ_ARR = 17; + IRM_CREATE_IPCP = 1; + 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; + IRM_FLOW_CONTROL = 14; + IRM_FLOW_WRITE = 15; + IRM_FLOW_READ = 16; + IPCP_FLOW_REQ_ARR = 17; IPCP_FLOW_ALLOC_REPLY = 18; - IPCP_FLOW_DEALLOC = 19; - IRM_REPLY = 20; + IPCP_FLOW_DEALLOC = 19; + IRM_REPLY = 20; }; message irm_msg { required irm_msg_code code = 1; optional string ap_name = 2; - optional uint32 api_id = 3; optional string ae_name = 4; + optional uint32 api_id = 3; optional uint32 ipcp_type = 5; repeated string dif_name = 6; optional int32 fd = 7; optional int32 response = 8; optional int32 oflags = 9; - optional string dst_ap_name = 10; + optional string dst_name = 10; optional uint32 port_id = 11; - optional uint32 reg_ap_id = 12; - optional int32 pid = 13; - optional dif_config_msg conf = 14; - optional int32 result = 15; + optional int32 pid = 12; + optional dif_config_msg conf = 13; + optional int32 result = 14; }; -- cgit v1.2.3 From a5e2a4cb3ce7bb47ce6b0ad74f11f062bde40e1d Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Mon, 25 Apr 2016 18:32:31 +0200 Subject: irmd/shim-udp: formatting fixes --- src/ipcpd/shim-udp/main.c | 24 ++++++++++++------------ src/irmd/main.c | 16 +++++++++++----- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index a65aa11d..f67c66ca 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -66,7 +66,7 @@ struct ipcp * _ipcp; #endif struct ipcp_udp_data { - /* IPCP_DATA STRUCT MUST BE FIRST!! */ + /* keep ipcp_data first for polymorphism */ struct ipcp_data ipcp_data; uint32_t ip_addr; @@ -83,7 +83,7 @@ struct ipcp_udp_data { }; struct udp_flow { - /* FLOW MUST BE FIRST !!!! */ + /* keep flow first for polymorphism */ flow_t flow; int fd; }; @@ -120,7 +120,7 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, } instance_name = instance_name_init_with( - instance_name, ap_name, (uint16_t)atoi(ap_id)); + instance_name, ap_name, (uint16_t) atoi(ap_id)); if (instance_name == NULL) { LOG_ERR("Failed to create instance name struct."); @@ -169,7 +169,7 @@ static void * ipcp_udp_listener() continue; /* flow alloc request from other host */ - hostp = gethostbyaddr((const char *)&c_saddr.sin_addr.s_addr, + hostp = gethostbyaddr((const char *) &c_saddr.sin_addr.s_addr, sizeof(c_saddr.sin_addr.s_addr), AF_INET); if (hostp == NULL) continue; @@ -185,7 +185,7 @@ static void * ipcp_udp_listener() continue; } - memset((char *)&f_saddr, 0, sizeof f_saddr); + memset((char *) &f_saddr, 0, sizeof f_saddr); f_saddr.sin_family = AF_INET; f_saddr.sin_addr.s_addr = local_ip; @@ -203,7 +203,7 @@ static void * ipcp_udp_listener() */ if (connect(flow->fd, - (struct sockaddr *)&c_saddr, sizeof c_saddr) < 0) { + (struct sockaddr *) &c_saddr, sizeof c_saddr) < 0) { close(flow->fd); free(flow); continue; @@ -283,7 +283,7 @@ static void * ipcp_udp_sdu_reader() flow = shim_data(_ipcp)->fd_to_flow_ptr[fd]; if (flow->state == FLOW_PENDING) { if (connect(fd, - (struct sockaddr *)&r_saddr, + (struct sockaddr *) &r_saddr, sizeof r_saddr) < 0) continue; @@ -344,7 +344,7 @@ int ipcp_udp_bootstrap(struct dif_config * conf) shim_data(_ipcp)->s_saddr.sin_port = LISTEN_PORT; if (bind(shim_data(_ipcp)->s_fd, - (struct sockaddr *)&shim_data(_ipcp)->s_saddr, + (struct sockaddr *) &shim_data(_ipcp)->s_saddr, sizeof shim_data(_ipcp)->s_saddr ) < 0) { LOG_ERR("Couldn't bind to %s.", ipstr); return -1; @@ -436,7 +436,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, } /* this socket is for the flow */ - memset((char *)&l_saddr, 0, sizeof l_saddr); + memset((char *) &l_saddr, 0, sizeof l_saddr); l_saddr.sin_family = AF_INET; l_saddr.sin_addr.s_addr = local_ip; l_saddr.sin_port = 0; @@ -458,7 +458,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, LOG_MISSING; - memset((char *)&r_saddr, 0, sizeof r_saddr); + memset((char *) &r_saddr, 0, sizeof r_saddr); r_saddr.sin_family = AF_INET; /* FIXME: pull in correct IP address */ r_saddr.sin_addr.s_addr = IP_ADDR; /* FIXME */ @@ -476,7 +476,7 @@ int ipcp_udp_flow_alloc(uint32_t port_id, pthread_mutex_lock(&_ipcp->data->flow_lock); - if(ipcp_data_add_flow(_ipcp->data, (flow_t *)flow)) { + if(ipcp_data_add_flow(_ipcp->data, (flow_t *) flow)) { LOG_DBGF("Could not add flow."); pthread_mutex_unlock(&_ipcp->data->flow_lock); close(flow->fd); @@ -609,7 +609,7 @@ int main (int argc, char * argv[]) irmd_pid = atoi(argv[1]); /* init sig_act */ - memset (&sig_act, 0, sizeof sig_act); + memset(&sig_act, 0, sizeof sig_act); /* install signal traps */ sig_act.sa_sigaction = &ipcp_sig_handler; diff --git a/src/irmd/main.c b/src/irmd/main.c index fcd93bd5..df3070f4 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -404,7 +404,7 @@ static int ap_unreg_id(uint32_t reg_ap_id, struct reg_name_entry * rne = NULL; struct list_head * pos = NULL; - rne = find_reg_name_entry_by_id (reg_ap_id); + rne = find_reg_name_entry_by_id(reg_ap_id); if (rne == NULL) return 0; /* no such id */ @@ -522,7 +522,9 @@ static int ap_reg(char * ap_name, return -1; } /* for now, we register single instances */ - reg_name_entry_add_name_instance(strdup(ap_name), instance_name_dup(api)); + reg_name_entry_add_name_instance(strdup(ap_name), + instance_name_dup(api)); + instance_name_destroy(api); return reg_ap_id; } @@ -535,6 +537,8 @@ static int ap_unreg(char * ap_name, struct reg_name_entry * tmp = NULL; instance_name_t * api = instance_name_create(); + if (api == NULL) + return -1; if (instance_name_init_from(api, ap_name, ap_id) == NULL) { instance_name_destroy(api); return -1; @@ -542,10 +546,12 @@ static int ap_unreg(char * ap_name, /* check if ap_name is registered */ tmp = find_reg_name_entry_by_name(api->name); - if (tmp == NULL) + if (tmp == NULL) { + instance_name_destroy(api); return 0; - else + } else { return ap_unreg_id(tmp->reg_ap_id, api->id, difs, len); + } } @@ -629,7 +635,7 @@ int main() struct sigaction sig_act; /* init sig_act */ - memset (&sig_act, 0, sizeof sig_act); + memset(&sig_act, 0, sizeof sig_act); /* install signal traps */ sig_act.sa_sigaction = &irmd_sig_handler; -- cgit v1.2.3 From 6be9ae98877f23b05f69e6006036fec0f6c9d338 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 26 Apr 2016 14:42:05 +0200 Subject: lib: instance ID's are now set to the process PID All instance-id's in ouroboros will be set by the system to the pid of the process associated with this application process instance. This means that the user has no way to choose the instance id's. Function calls that assumed manually defined instance id's have been replaced throughout the system. --- include/ouroboros/ipcp.h | 4 +- include/ouroboros/irm.h | 4 +- src/ipcpd/ipcp-data.c | 18 ++++- src/ipcpd/ipcp-data.h | 2 +- src/ipcpd/ipcp.c | 3 +- src/ipcpd/shim-udp/main.c | 29 ++----- src/ipcpd/shim-udp/tests/shim_udp_test.c | 3 +- src/irmd/main.c | 127 +++++++++++++++---------------- src/lib/ipcp.c | 21 +---- src/lib/irm.c | 10 +-- src/tools/irm/irm_create_ipcp.c | 11 +-- 11 files changed, 101 insertions(+), 131 deletions(-) diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index 1c8d3f86..e3c17bda 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -33,8 +33,8 @@ struct ipcp; /* Returns the process id */ -pid_t ipcp_create(instance_name_t * api, - enum ipcp_type ipcp_type); +pid_t ipcp_create(char * ipcp_name, + enum ipcp_type ipcp_type); int ipcp_destroy(pid_t pid); diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index 24bb2c42..26ff536a 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -26,8 +26,8 @@ #include #include -int irm_create_ipcp(instance_name_t * api, - enum ipcp_type ipcp_type); +int irm_create_ipcp(char * ipcp_name, + enum ipcp_type ipcp_type); int irm_destroy_ipcp(instance_name_t * api); diff --git a/src/ipcpd/ipcp-data.c b/src/ipcpd/ipcp-data.c index e6997e3e..106226de 100644 --- a/src/ipcpd/ipcp-data.c +++ b/src/ipcpd/ipcp-data.c @@ -104,18 +104,28 @@ struct ipcp_data * ipcp_data_create() } struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, - instance_name_t * iname, - enum ipcp_type ipcp_type) + const char * ipcp_name, + enum ipcp_type ipcp_type) { if (dst == NULL) return NULL; - dst->iname = instance_name_dup(iname); + dst->iname = instance_name_create(); + if (dst->iname == NULL) + return NULL; + + if(instance_name_init_from(dst->iname, ipcp_name, getpid()) == NULL) { + instance_name_destroy(dst->iname); + return NULL; + } + dst->type = ipcp_type; dst->dum = shm_du_map_open(); - if (dst->dum == NULL) + if (dst->dum == NULL) { + instance_name_destroy(dst->iname); return NULL; + } /* init the lists */ INIT_LIST_HEAD(&dst->registry); diff --git a/src/ipcpd/ipcp-data.h b/src/ipcpd/ipcp-data.h index 7e48df24..1dea8c3c 100644 --- a/src/ipcpd/ipcp-data.h +++ b/src/ipcpd/ipcp-data.h @@ -53,7 +53,7 @@ struct ipcp_data { struct ipcp_data * ipcp_data_create(); struct ipcp_data * ipcp_data_init(struct ipcp_data * dst, - instance_name_t * iname, + const char * ipcp_name, enum ipcp_type ipcp_type); void ipcp_data_destroy(struct ipcp_data * data); diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index c1071e05..23c432f1 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -31,7 +31,7 @@ int ipcp_arg_check(int argc, char * argv[]) { - if (argc != 4) + if (argc != 3) return -1; /* argument 1: pid of irmd */ @@ -41,7 +41,6 @@ int ipcp_arg_check(int argc, char * argv[]) /* name conformity responsibility of NMS */ /* argument 2: ap name */ - /* argument 3: instance id */ return 0; } diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index f67c66ca..785f2344 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -96,7 +96,7 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c) case SIGHUP: LOG_DBG("Terminating by order of %d. Bye.", info->si_pid); if (info->si_pid == irmd_pid) { - shm_du_map_close(_ipcp->data->dum); + /* shm_du_map_close(_ipcp->data->dum); */ exit(0); } default: @@ -104,29 +104,13 @@ void ipcp_sig_handler(int sig, siginfo_t * info, void * c) } } -struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, - char * ap_id) +struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name) { struct ipcp_udp_data * udp_data; struct ipcp_data * data; - instance_name_t * instance_name; enum ipcp_type ipcp_type; int n; - instance_name = instance_name_create(); - if (instance_name == NULL) { - LOG_ERR("Failed to create instance name struct."); - return NULL; - } - - instance_name = instance_name_init_with( - instance_name, ap_name, (uint16_t) atoi(ap_id)); - - if (instance_name == NULL) { - LOG_ERR("Failed to create instance name struct."); - return NULL; - } - udp_data = malloc(sizeof *udp_data); if (udp_data == NULL) { LOG_DBGF("Failed to allocate."); @@ -135,7 +119,7 @@ struct ipcp_udp_data * ipcp_udp_data_create(char * ap_name, ipcp_type = THIS_TYPE; data = (struct ipcp_data *) udp_data; - if (ipcp_data_init(data, instance_name, ipcp_type) == NULL) { + if (ipcp_data_init(data, ap_name, ipcp_type) == NULL) { free(udp_data); return NULL; } @@ -548,7 +532,7 @@ int ipcp_udp_du_read(uint32_t port_id, return 0; } -struct ipcp * ipcp_udp_create(char * ap_name, char * i_id) +struct ipcp * ipcp_udp_create(char * ap_name) { struct ipcp * i; struct ipcp_udp_data * data; @@ -558,7 +542,7 @@ struct ipcp * ipcp_udp_create(char * ap_name, char * i_id) if (i == NULL) return NULL; - data = ipcp_udp_data_create(ap_name, i_id); + data = ipcp_udp_data_create(ap_name); if (data == NULL) { free(i); return NULL; @@ -597,7 +581,6 @@ int main (int argc, char * argv[]) { /* argument 1: pid of irmd ? */ /* argument 2: ap name */ - /* argument 3: instance id */ struct sigaction sig_act; if (ipcp_arg_check(argc, argv)) { @@ -619,7 +602,7 @@ int main (int argc, char * argv[]) sigaction(SIGTERM, &sig_act, NULL); sigaction(SIGHUP, &sig_act, NULL); - _ipcp = ipcp_udp_create(argv[2], argv[3]); + _ipcp = ipcp_udp_create(argv[2]); if (_ipcp == NULL) { LOG_ERR("Won't."); exit(1); diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c index 0fcf9f4d..4e0c2dd6 100644 --- a/src/ipcpd/shim-udp/tests/shim_udp_test.c +++ b/src/ipcpd/shim-udp/tests/shim_udp_test.c @@ -39,7 +39,6 @@ int shim_udp_test(int argc, char ** argv) /* argument 3: instance id */ struct shm_du_map * dum; char * ipcp_name = "test-shim-ipcp"; - char * i_id = "1"; int i = 0; char bogus[15]; @@ -57,7 +56,7 @@ int shim_udp_test(int argc, char ** argv) exit(1); } - _ipcp = ipcp_udp_create(ipcp_name, i_id); + _ipcp = ipcp_udp_create(ipcp_name); if (_ipcp == NULL) { LOG_ERR("Could not instantiate shim IPCP."); shm_du_map_close(dum); diff --git a/src/irmd/main.c b/src/irmd/main.c index df3070f4..c47bcffc 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -48,7 +48,6 @@ struct ipcp_entry { struct list_head next; - pid_t pid; instance_name_t * api; char * dif_name; }; @@ -75,8 +74,9 @@ struct irm { struct irm * instance = NULL; -static pid_t find_pid_by_ipcp_name(instance_name_t * api) +static struct ipcp_entry * find_ipcp_entry_by_name(instance_name_t * api) { + struct ipcp_entry * tmp = NULL; struct list_head * pos = NULL; list_for_each(pos, &instance->ipcps) { @@ -84,44 +84,43 @@ static pid_t find_pid_by_ipcp_name(instance_name_t * api) list_entry(pos, struct ipcp_entry, next); if (instance_name_cmp(api, tmp->api) == 0) - return tmp->pid; + return tmp; } - return 0; + return tmp; } -static struct ipcp_entry * find_ipcp_by_name(instance_name_t * api) +static instance_name_t * get_ipcp_by_name(char * ap_name) { - struct ipcp_entry * tmp = NULL; struct list_head * pos = NULL; list_for_each(pos, &instance->ipcps) { - struct ipcp_entry * tmp = + struct ipcp_entry * e = list_entry(pos, struct ipcp_entry, next); - if (instance_name_cmp(api, tmp->api) == 0) - return tmp; + if (strcmp(e->api->name, ap_name) == 0) + return e->api; } - return tmp; + return NULL; } -static pid_t find_pid_by_dif_name(char * dif_name) +static instance_name_t * get_ipcp_by_dif_name(char * dif_name) { struct list_head * pos = NULL; list_for_each(pos, &instance->ipcps) { - struct ipcp_entry * tmp = + struct ipcp_entry * e = list_entry(pos, struct ipcp_entry, next); - if (tmp->dif_name == NULL) - return tmp->pid; + if (e->dif_name == NULL) + continue; - if (strcmp(dif_name, tmp->dif_name) == 0) - return tmp->pid; + if (strcmp(dif_name, e->dif_name) == 0) + return e->api; } - return 0; + return NULL; } static struct reg_name_entry * reg_name_entry_create() @@ -219,13 +218,13 @@ static int reg_name_entry_del_name(char * name) return 0; } -static int create_ipcp(instance_name_t * api, - enum ipcp_type ipcp_type) +static int create_ipcp(char * ap_name, + enum ipcp_type ipcp_type) { pid_t pid; struct ipcp_entry * tmp = NULL; - pid = ipcp_create(api, ipcp_type); + pid = ipcp_create(ap_name, ipcp_type); if (pid == -1) { LOG_ERR("Failed to create IPCP"); return -1; @@ -238,13 +237,18 @@ static int create_ipcp(instance_name_t * api, INIT_LIST_HEAD(&tmp->next); - tmp->pid = pid; - tmp->api = instance_name_dup(api); + tmp->api = instance_name_create(); if (tmp->api == NULL) { free(tmp); return -1; } + if(instance_name_init_from(tmp->api, ap_name, pid) == NULL) { + instance_name_destroy(tmp->api); + free(tmp); + return -1; + } + tmp->dif_name = NULL; LOG_DBG("Created IPC process with pid %d", pid); @@ -255,19 +259,20 @@ static int create_ipcp(instance_name_t * api, static int destroy_ipcp(instance_name_t * api) { - pid_t pid = 0; struct list_head * pos = NULL; struct list_head * n = NULL; - pid = find_pid_by_ipcp_name(api); - if (pid == 0) { - LOG_ERR("No such IPCP"); + if (api->id == 0) + api = get_ipcp_by_name(api->name); + + if (api == NULL) { + LOG_ERR("No such IPCP in the system."); return -1; } - LOG_DBG("Destroying ipcp with pid %d", pid); + LOG_DBG("Destroying ipcp %s-%d", api->name, api->id); - if (ipcp_destroy(pid)) + if (ipcp_destroy(api->id)) LOG_ERR("Could not destroy IPCP"); list_for_each_safe(pos, n, &(instance->ipcps)) { @@ -286,7 +291,15 @@ static int bootstrap_ipcp(instance_name_t * api, { struct ipcp_entry * entry = NULL; - entry = find_ipcp_by_name(api); + if (api->id == 0) + api = get_ipcp_by_name(api->name); + + if (api == NULL) { + LOG_ERR("No such IPCP in the system."); + return -1; + } + + entry = find_ipcp_entry_by_name(api); if (entry == NULL) { LOG_ERR("No such IPCP"); return -1; @@ -298,7 +311,7 @@ static int bootstrap_ipcp(instance_name_t * api, return -1; } - if (ipcp_bootstrap(entry->pid, conf)) { + if (ipcp_bootstrap(entry->api->id, conf)) { LOG_ERR("Could not bootstrap IPCP"); free(entry->dif_name); entry->dif_name = NULL; @@ -316,7 +329,7 @@ static int enroll_ipcp(instance_name_t * api, ssize_t n_1_difs_size = 0; struct ipcp_entry * entry = NULL; - entry = find_ipcp_by_name(api); + entry = find_ipcp_entry_by_name(api); if (entry == NULL) { LOG_ERR("No such IPCP"); return -1; @@ -344,7 +357,7 @@ static int enroll_ipcp(instance_name_t * api, return -1; } - if (ipcp_enroll(entry->pid, member, n_1_difs[0])) { + if (ipcp_enroll(entry->api->id, member, n_1_difs[0])) { LOG_ERR("Could not enroll IPCP"); free(entry->dif_name); entry->dif_name = NULL; @@ -358,15 +371,7 @@ static int reg_ipcp(instance_name_t * api, char ** difs, size_t difs_size) { - pid_t pid = 0; - - pid = find_pid_by_ipcp_name(api); - if (pid == 0) { - LOG_ERR("No such IPCP"); - return -1; - } - - if (ipcp_reg(pid, difs, difs_size)) { + if (ipcp_reg(api->id, difs, difs_size)) { LOG_ERR("Could not register IPCP to N-1 DIF(s)"); return -1; } @@ -378,15 +383,8 @@ static int unreg_ipcp(instance_name_t * api, char ** difs, size_t difs_size) { - pid_t pid = 0; - - pid = find_pid_by_ipcp_name(api); - if (pid == 0) { - LOG_ERR("No such IPCP"); - return -1; - } - if (ipcp_unreg(pid, difs, difs_size)) { + if (ipcp_unreg(api->id, difs, difs_size)) { LOG_ERR("Could not unregister IPCP from N-1 DIF(s)"); return -1; } @@ -418,7 +416,7 @@ static int ap_unreg_id(uint32_t reg_ap_id, struct ipcp_entry * e = list_entry(pos, struct ipcp_entry, next); - if (ipcp_name_unreg(e->pid, 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); --ret; @@ -426,12 +424,6 @@ static int ap_unreg_id(uint32_t reg_ap_id, } } 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]); @@ -450,14 +442,14 @@ static int ap_reg(char * ap_name, char ** difs, 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; + instance_name_t * api = NULL; + instance_name_t * ipcpi = NULL; if (instance->ipcps.next == NULL) LOG_ERR("No IPCPs in this system."); @@ -493,7 +485,7 @@ static int ap_reg(char * ap_name, struct ipcp_entry * e = list_entry(pos, struct ipcp_entry, next); - if (ipcp_name_reg(e->pid, api->name)) { + if (ipcp_name_reg(e->api->id, ap_name)) { LOG_ERR("Could not register %s in DIF %s.", api->name, e->dif_name); } else { @@ -502,13 +494,13 @@ static int ap_reg(char * ap_name, } } else { for (i = 0; i < len; ++i) { - pid = find_pid_by_dif_name(difs[i]); - if (pid == 0) { + ipcpi = get_ipcp_by_dif_name(difs[i]); + if (ipcpi == NULL) { LOG_ERR("%s: No such DIF.", difs[i]); continue; } - if (ipcp_name_reg(pid, api->name)) { + if (ipcp_name_reg(ipcpi->id, api->name)) { LOG_ERR("Could not register %s in DIF %s.", api->name, difs[i]); } else { @@ -539,6 +531,7 @@ static int ap_unreg(char * ap_name, instance_name_t * api = instance_name_create(); if (api == NULL) return -1; + if (instance_name_init_from(api, ap_name, ap_id) == NULL) { instance_name_destroy(api); return -1; @@ -652,14 +645,17 @@ int main() if (instance == NULL) return -1; - if ((instance->dum = shm_du_map_create()) == NULL) + if ((instance->dum = shm_du_map_create()) == NULL) { + free(instance); return -1; + } INIT_LIST_HEAD(&instance->ipcps); INIT_LIST_HEAD(&instance->reg_names); sockfd = server_socket_open(IRM_SOCK_PATH); if (sockfd < 0) { + shm_du_map_close(instance->dum); free(instance); return -1; } @@ -694,12 +690,13 @@ int main() } api.name = msg->ap_name; - api.id = msg->api_id; + if (msg->has_api_id == true) + api.id = msg->api_id; switch (msg->code) { case IRM_MSG_CODE__IRM_CREATE_IPCP: ret_msg.has_result = true; - ret_msg.result = create_ipcp(&api, + ret_msg.result = create_ipcp(msg->ap_name, msg->ipcp_type); break; case IRM_MSG_CODE__IRM_DESTROY_IPCP: diff --git a/src/lib/ipcp.c b/src/lib/ipcp.c index b93f5488..387572b3 100644 --- a/src/lib/ipcp.c +++ b/src/lib/ipcp.c @@ -99,12 +99,11 @@ static ipcp_msg_t * send_recv_ipcp_msg(pid_t pid, return recv_msg; } -pid_t ipcp_create(instance_name_t * api, - enum ipcp_type ipcp_type) +pid_t ipcp_create(char * ipcp_name, + enum ipcp_type ipcp_type) { pid_t pid = 0; char irmd_pid[10]; - char * api_id = NULL; size_t len = 0; char * ipcp_dir = "bin"; char * full_name = NULL; @@ -122,21 +121,12 @@ pid_t ipcp_create(instance_name_t * api, return pid; } - api_id = malloc(n_digits(api->id) + 1); - if (!api_id) { - LOG_ERR("Failed to malloc"); - exit(EXIT_FAILURE); - } - sprintf(api_id, "%d", api->id); - if (ipcp_type == IPCP_NORMAL) exec_name = IPCP_NORMAL_EXEC; else if (ipcp_type == IPCP_SHIM_UDP) exec_name = IPCP_SHIM_UDP_EXEC; - else { - free(api_id); + else exit(EXIT_FAILURE); - } len += strlen(INSTALL_DIR); len += strlen(ipcp_dir); @@ -146,7 +136,6 @@ pid_t ipcp_create(instance_name_t * api, full_name = malloc(len + 1); if (full_name == NULL) { LOG_ERR("Failed to malloc"); - free(api_id); exit(EXIT_FAILURE); } @@ -161,8 +150,7 @@ pid_t ipcp_create(instance_name_t * api, char * argv[] = {full_name, irmd_pid, - api->name, - api_id, + ipcp_name, 0}; char * envp[] = {0}; @@ -172,7 +160,6 @@ pid_t ipcp_create(instance_name_t * api, LOG_DBG("%s", strerror(errno)); LOG_ERR("Failed to load IPCP daemon"); LOG_ERR("Make sure to run the installed version"); - free(api_id); free(full_name); exit(EXIT_FAILURE); } diff --git a/src/lib/irm.c b/src/lib/irm.c index b17cb04c..d3c77f2e 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -30,20 +30,18 @@ #include -int irm_create_ipcp(instance_name_t * api, - enum ipcp_type ipcp_type) +int irm_create_ipcp(char * ipcp_name, + enum ipcp_type ipcp_type) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; int ret = -1; - if (api == NULL || api->name == NULL) + if (ipcp_name == NULL) return -EINVAL; msg.code = IRM_MSG_CODE__IRM_CREATE_IPCP; - msg.ap_name = api->name; - msg.has_api_id = true; - msg.api_id = api->id; + msg.ap_name = ipcp_name; msg.has_ipcp_type = true; msg.ipcp_type = ipcp_type; diff --git a/src/tools/irm/irm_create_ipcp.c b/src/tools/irm/irm_create_ipcp.c index 08b55259..3c9b9cb8 100644 --- a/src/tools/irm/irm_create_ipcp.c +++ b/src/tools/irm/irm_create_ipcp.c @@ -39,7 +39,6 @@ static void usage() { printf("Usage: irm create_ipcp\n" " ap \n" - " [api ]\n" " type [TYPE]\n\n" "where TYPE = {" NORMAL " " SHIM_UDP "}\n"); } @@ -47,16 +46,14 @@ static void usage() int do_create_ipcp(int argc, char ** argv) { char * ipcp_type = NULL; - instance_name_t api = {NULL, 0}; + char * ipcp_name = NULL; enum ipcp_type type = 0; while (argc > 0) { if (matches(*argv, "type") == 0) { ipcp_type = *(argv + 1); } else if (matches(*argv, "ap") == 0) { - api.name = *(argv + 1); - } else if (matches(*argv, "api") == 0) { - api.id = atoi(*(argv + 1)); + ipcp_name = *(argv + 1); } else { printf("\"%s\" is unknown, try \"irm " "create_ipcp\".\n", *argv); @@ -67,7 +64,7 @@ int do_create_ipcp(int argc, char ** argv) argv += 2; } - if (ipcp_type == NULL || api.name == NULL) { + if (ipcp_type == NULL || ipcp_name == NULL) { usage(); return -1; } @@ -81,5 +78,5 @@ int do_create_ipcp(int argc, char ** argv) return -1; } - return irm_create_ipcp(&api, type); + return irm_create_ipcp(ipcp_name, type); } -- cgit v1.2.3 From 45b7d79088174303193f8772c9b14fed2011551e Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 26 Apr 2016 15:24:26 +0200 Subject: lib: irm.h create_ipcp now returns pid_t ipcp_create now returns the pid of the created process to allow for more efficient scripting. --- include/ouroboros/irm.h | 6 ++++-- src/irmd/main.c | 6 +++--- src/lib/irm.c | 4 ++-- src/tools/irm/irm_create_ipcp.c | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index 26ff536a..37524098 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -26,8 +26,10 @@ #include #include -int irm_create_ipcp(char * ipcp_name, - enum ipcp_type ipcp_type); +#include + +pid_t irm_create_ipcp(char * ipcp_name, + enum ipcp_type ipcp_type); int irm_destroy_ipcp(instance_name_t * api); diff --git a/src/irmd/main.c b/src/irmd/main.c index c47bcffc..31dabebb 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -218,8 +218,8 @@ static int reg_name_entry_del_name(char * name) return 0; } -static int create_ipcp(char * ap_name, - enum ipcp_type ipcp_type) +static pid_t create_ipcp(char * ap_name, + enum ipcp_type ipcp_type) { pid_t pid; struct ipcp_entry * tmp = NULL; @@ -254,7 +254,7 @@ static int create_ipcp(char * ap_name, LOG_DBG("Created IPC process with pid %d", pid); list_add(&tmp->next, &instance->ipcps); - return 0; + return pid; } static int destroy_ipcp(instance_name_t * api) diff --git a/src/lib/irm.c b/src/lib/irm.c index d3c77f2e..cc1c0d01 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -30,8 +30,8 @@ #include -int irm_create_ipcp(char * ipcp_name, - enum ipcp_type ipcp_type) +pid_t irm_create_ipcp(char * ipcp_name, + enum ipcp_type ipcp_type) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; diff --git a/src/tools/irm/irm_create_ipcp.c b/src/tools/irm/irm_create_ipcp.c index 3c9b9cb8..e82bd980 100644 --- a/src/tools/irm/irm_create_ipcp.c +++ b/src/tools/irm/irm_create_ipcp.c @@ -78,5 +78,5 @@ int do_create_ipcp(int argc, char ** argv) return -1; } - return irm_create_ipcp(ipcp_name, type); + return !irm_create_ipcp(ipcp_name, type); } -- cgit v1.2.3 From a17657c4321dc0770e5431467261eb2bc579f79c Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Tue, 26 Apr 2016 18:16:08 +0200 Subject: shim-udp: resolve dst_name using DNS This commits adds the gethostbyname call to resolve the dst_name for a flow allocation using DNS. The DNS server should be specified using the method mandated by the system (e.g. added to /etc/resolv.conf). --- src/ipcpd/shim-udp/CMakeLists.txt | 15 +++++++++++++++ src/ipcpd/shim-udp/main.c | 28 +++++++++++++++------------- src/ipcpd/shim-udp/tests/shim_udp_test.c | 14 +++++++------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt index 27907880..f730fa3a 100644 --- a/src/ipcpd/shim-udp/CMakeLists.txt +++ b/src/ipcpd/shim-udp/CMakeLists.txt @@ -10,6 +10,21 @@ include_directories(${CURRENT_BINARY_PARENT_DIR}) include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) +# Find library needed for gethostbyname. +include(CheckFunctionExists) +CHECK_FUNCTION_EXISTS("gethostbyname" CMAKE_HAVE_GETHOSTBYNAME) +IF(NOT CMAKE_HAVE_GETHOSTBYNAME) + CHECK_LIBRARY_EXISTS("nsl" "gethostbyname" "" CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) + IF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) + SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lnsl) + ELSE (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) + CHECK_LIBRARY_EXISTS("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) + IF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) + SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lbsd) + ENDIF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME) + ENDIF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME) +ENDIF(NOT CMAKE_HAVE_GETHOSTBYNAME) + SET(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET") set(SHIM_UDP_SOURCES diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 785f2344..029df111 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -21,7 +21,6 @@ */ #include - #include "ipcp.h" #include "flow.h" #include @@ -310,7 +309,7 @@ int ipcp_udp_bootstrap(struct dif_config * conf) dnsstr, INET_ADDRSTRLEN); else - strcpy(dnsstr, "not set"); + strcpy(dnsstr, "not set.\n"); shim_data(_ipcp)->ip_addr = conf->ip_addr; shim_data(_ipcp)->dns_addr = conf->dns_addr; @@ -381,7 +380,7 @@ int ipcp_udp_name_unreg(char * name) } int ipcp_udp_flow_alloc(uint32_t port_id, - char * dst_ap_name, + char * dst_name, char * src_ap_name, char * src_ae_name, struct qos_spec * qos) @@ -390,16 +389,18 @@ int ipcp_udp_flow_alloc(uint32_t port_id, struct sockaddr_in l_saddr; struct sockaddr_in r_saddr; + struct hostent * h; + irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * ret_msg = NULL; - if (dst_ap_name == NULL || src_ap_name == NULL || src_ae_name == NULL) + if (dst_name == NULL || src_ap_name == NULL || src_ae_name == NULL) return -1; LOG_DBG("Received flow allocation request from %s to %s.", - src_ap_name, dst_ap_name); + src_ap_name, dst_name); - if (strlen(dst_ap_name) > 255 + if (strlen(dst_name) > 255 || strlen(src_ap_name) > 255 || strlen(src_ae_name) > 255) { LOG_ERR("Name too long for this shim."); @@ -436,20 +437,21 @@ int ipcp_udp_flow_alloc(uint32_t port_id, return -1; } - /* FIXME: use calls to specify DDNS server */ - -#define IP_ADDR 0x7f000001; /* localhost */ + h = gethostbyname(dst_name); + if (h == NULL) { + close(flow->fd); + free(flow); + return -1; + } - LOG_MISSING; memset((char *) &r_saddr, 0, sizeof r_saddr); r_saddr.sin_family = AF_INET; - /* FIXME: pull in correct IP address */ - r_saddr.sin_addr.s_addr = IP_ADDR; /* FIXME */ + r_saddr.sin_addr.s_addr = (uint32_t) *(h->h_addr_list[0]); r_saddr.sin_port = LISTEN_PORT; /* at least try to get the packet on the wire */ - while (sendto(flow->fd, dst_ap_name, strlen(dst_ap_name), 0, + while (sendto(flow->fd, dst_name, strlen(dst_name), 0, (struct sockaddr *) &r_saddr, sizeof r_saddr) < 0) flow->flow.port_id = port_id; diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c index 4e0c2dd6..d2b9c642 100644 --- a/src/ipcpd/shim-udp/tests/shim_udp_test.c +++ b/src/ipcpd/shim-udp/tests/shim_udp_test.c @@ -42,10 +42,10 @@ int shim_udp_test(int argc, char ** argv) int i = 0; char bogus[15]; - memset (&bogus, 0, 15); + memset(&bogus, 0, 15); struct dif_config conf; - memset (&conf, 0, sizeof conf); + memset(&conf, 0, sizeof conf); conf.dif_name = strdup("test-dif"); conf.type = IPCP_SHIM_UDP; conf.ip_addr = 0; @@ -63,11 +63,11 @@ int shim_udp_test(int argc, char ** argv) exit(1); } - if (ipcp_udp_bootstrap (&conf)) { + if (ipcp_udp_bootstrap(&conf)) { LOG_ERR("Could not bootstrap."); } - if(ipcp_udp_name_reg("bogus name")) { + if (ipcp_udp_name_reg("bogus name")) { LOG_ERR("Failed to register application."); shm_du_map_close(dum); exit(1); @@ -80,8 +80,8 @@ int shim_udp_test(int argc, char ** argv) } for (i = 0; i < 1000; ++i) { - sprintf (bogus, "bogus name %4d", i); - if(ipcp_udp_name_reg(bogus)) { + sprintf(bogus, "bogus name %4d", i); + if (ipcp_udp_name_reg(bogus)) { LOG_ERR("Failed to register application %s.", bogus); shm_du_map_close(dum); exit(1); @@ -89,7 +89,7 @@ int shim_udp_test(int argc, char ** argv) } for (i = 0; i < 1000; ++i) { - sprintf (bogus, "bogus name %4d", i); + sprintf(bogus, "bogus name %4d", i); if(ipcp_udp_name_unreg(bogus)) { LOG_ERR("Failed to unregister application %s.", bogus); shm_du_map_close(dum); -- cgit v1.2.3