From f1119f56330ffffd02ea03fd4185ea492b68c563 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 5 Jun 2014 09:34:56 +0000 Subject: [PATCH] updated more node code git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@28 8ec27952-4edc-4aab-86aa-e87bb2611832 --- include/node.h | 54 ++++++++++++++++++---- src/node.c | 121 ++++++++++++++++++++----------------------------- src/utils.c | 51 +++++++++++++++++++-- 3 files changed, 141 insertions(+), 85 deletions(-) diff --git a/include/node.h b/include/node.h index d3675bfd2..b0c799ec7 100644 --- a/include/node.h +++ b/include/node.h @@ -19,9 +19,12 @@ enum node_type { - SIMULATOR, - SERVER, - WORKSTATION + NODE_INVALID, + NODE_SERVER, + NODE_WORKSTATION, + NODE_SIM_OPAL, + NODE_SIM_RTDS, + NODE_SIM_DSP }; struct node @@ -29,6 +32,9 @@ struct node /// The socket descriptor int sd; + /// Reference counter + int ref_cnt; + // Local address of the socket struct sockaddr_in local; @@ -39,7 +45,7 @@ struct node enum node_type type; /// A short identifier of the node - char *name; + const char *name; }; struct msg; /* forward decl */ @@ -49,29 +55,59 @@ struct msg; /* forward decl */ * * Memory is allocated dynamically and has to be freed by node_destroy() * + * @param n A pointer to the node structure * @param name An acroynm, describing the node - * @param type The type of a node (SERVER, SIMULATOR, WORKSTATION) - * @param local A string specifying the local ip:port - * @param remote A string specifying the remote ip:port + * @param type The type of a node (server, simulator, workstation) * @return * - 0 on success * - otherwise on error occured */ -struct node* node_create(const char *name, enum node_type type, const char *local, const char *remote); +int node_create(struct node *n, const char *name, enum node_type type, + struct sockaddr_in local, struct sockaddr_in remote); /** * @brief Delete a node created by node_create() * * @param p A pointer to the node struct */ -void node_destroy(struct node* n); +void node_destroy(struct node *n); /** + * @brief Connect and bind the UDP socket of this node * + * @param n A pointer to the node structure + * @return + * - 0 on success + * - otherwise on error occured */ +int node_connect(struct node *n); /** + * @brief Disconnect the UDP socket of this node * + * @param n A pointer to the node structure + * @return + * - 0 on success + * - otherwise on error occured */ +int node_disconnect(struct node *n); + +/** + * @brief Lookup node type from string + * + * @param str The string containing the node type + * @return The node type enumeration value + */ +enum node_type node_lookup_type(const char *str); + +/** + * @brief Search list of nodes for a name + * + * @param str The name of the wanted node + * @param nodes A pointer to the first list element + * @param len Length of the node list + * @return A pointer to the node or NULL if not found + */ +struct node* node_lookup_name(const char *str, struct node *nodes, int len); #endif /* _NODE_H_ */ diff --git a/src/node.c b/src/node.c index a8356b9fd..56fe4b690 100644 --- a/src/node.c +++ b/src/node.c @@ -15,111 +15,86 @@ #include #include #include -#include -#include #include +#include "cfg.h" #include "utils.h" #include "msg.h" #include "node.h" -struct node* node_create(const char *name, enum node_type type, const char *local, const char *remote) +extern struct config config; + +int node_create(struct node *n, const char *name, enum node_type type, + struct sockaddr_in local, struct sockaddr_in remote) { int ret; - struct node *n = malloc(sizeof(struct node)); - if (!n) - return NULL; - memset(n, 0, sizeof(struct node)); - - n->name = strdup(name); + n->name = name; n->type = type; + n->local = local; + n->remote = remote; - if (!resolve(local, &n->local)) - error("Failed to resolve local address '%s' of node '%s'", local, name); - if (!resolve(remote, &n->remote)) - error("Failed to resolve remote address '%s' of node '%s'", remote, name); - - /* Create socket */ - n->sd = socket(AF_INET, SOCK_DGRAM, 0); - if (n->sd < 0) { - node_destroy(n); - error("Failed to create socket: %s", strerror(errno)); - return NULL; - } - - /* Bind socket for receiving */ - ret = bind(n->sd, (struct sockaddr *) &n->local, sizeof(struct sockaddr_in)); - if (ret < 0) { - node_destroy(n); - error("Failed to bind socket: %s", strerror(errno)); - return NULL; - } - debug(1, "We listen for node %s at %s:%u", name, inet_ntoa(n->local.sin_addr), ntohs(n->local.sin_port)); - - /* Connect socket for sending */ - ret = connect(n->sd, (struct sockaddr *) &n->remote, sizeof(struct sockaddr_in)); - if (ret < 0) { - node_destroy(n); - error("Failed to connect socket: %s", strerror(errno)); - return NULL; - } - debug(1, "We sent to node %s at %s:%u", name, inet_ntoa(n->remote.sin_addr), ntohs(n->remote.sin_port)); - - return n; + return 0; } -int resolve(const char *addr, struct sockaddr_in *sa) +int node_connect(struct node *n) { - /* split host:port */ - char *host; - char *port; + /* Create socket */ + n->sd = socket(AF_INET, SOCK_DGRAM, 0); + if (n->sd < 0) + error("Failed to create socket: %s", strerror(errno)); - if (sscanf(addr, "%m[^:]:%ms", &host, &port) != 2) { - print(FATAL, "Invalid address format: %s", addr); - } + /* Set socket options */ + int prio = SOCKET_PRIO; + if (setsockopt(n->sd, SOL_SOCKET, SOCKET_PRIO, &prio, sizeof(prio))) + perror("Failed to set socket options"); - /* get ip */ - struct addrinfo *result; - struct addrinfo hint = { - .ai_family = AF_INET, - .ai_socktype = SOCK_DGRAM, - .ai_protocol = 0 - }; + /* Bind socket for receiving */ + if (bind(n->sd, (struct sockaddr *) &n->local, sizeof(struct sockaddr_in))) + error("Failed to bind socket: %s", strerror(errno)); - int ret = getaddrinfo(host, port, &hint, &result); - if (ret) { - print(FATAL, "Failed to get address for node %s: %s", addr, gai_strerror(ret)); - return -EINVAL; - } + debug(1, " We listen for node %s at %s:%u", n->name, inet_ntoa(n->local.sin_addr), ntohs(n->local.sin_port)); - memcpy(sa, result->ai_addr, sizeof(struct sockaddr_in)); - sa->sin_family = AF_INET; - sa->sin_port = htons(atoi(port)); + /* Connect socket for sending */ + /*if (connect(n->sd, (struct sockaddr *) &n->remote, sizeof(struct sockaddr_in))) + error("Failed to connect socket: %s", strerror(errno));*/ - freeaddrinfo(result); - free(host); - free(port); + debug(1, " We sent to node %s at %s:%u", n->name, inet_ntoa(n->remote.sin_addr), ntohs(n->remote.sin_port)); return 0; } void node_destroy(struct node* n) { - if (!n) - return; + assert(n); close(n->sd); - - if (n->name) - free(n->name); - - free(n); } +enum node_type node_lookup_type(const char *str) { + if (!strcmp(str, "workstation")) + return NODE_WORKSTATION; + else if (!strcmp(str, "server")) + return NODE_SERVER; + else if (!strcmp(str, "rtds")) + return NODE_SIM_RTDS; + else if (!strcmp(str, "opal")) + return NODE_SIM_OPAL; + else if (!strcmp(str, "dsp")) + return NODE_SIM_DSP; + else + return NODE_INVALID; } +struct node* node_lookup_name(const char *str, struct node *nodes, int len) { + for (int i = 0; i < len; i++) { + if (!strcmp(str, nodes[i].name)) { + return &nodes[i]; + } + } + return NULL; } + diff --git a/src/utils.c b/src/utils.c index ab0c0ecf5..0f8b86148 100644 --- a/src/utils.c +++ b/src/utils.c @@ -7,7 +7,13 @@ #include #include +#include #include +#include + +#include +#include +#include #include "config.h" #include "utils.h" @@ -33,7 +39,46 @@ void print(enum log_level lvl, const char *fmt, ...) printf("\n"); va_end(ap); - - if (lvl >= FATAL) - exit(EXIT_FAILURE); +} + +int resolve(const char *addr, struct sockaddr_in *sa, int flags) +{ + int ret; + char *node; + char *service; + + /* Split addr into node:service */ + if (sscanf(addr, "%m[^:]:%ms", &node, &service) != 2) + return -EINVAL; + + /* Check for wildcards */ + if (!strcmp(node, "*")) { + free(node); + node = NULL; + } + + if (!strcmp(service, "*")) { + free(service); + service = NULL; + } + + /* Get IP */ + struct addrinfo *result; + struct addrinfo hint = { + .ai_flags = flags, + .ai_family = AF_INET, + .ai_socktype = SOCK_DGRAM, + .ai_protocol = 0 + }; + + if (getaddrinfo(node, service, &hint, &result)) + error("Failed to lookup address: %s", gai_strerror(ret)); + + memcpy(sa, result->ai_addr, result->ai_addrlen); + + free(node); + free(service); + freeaddrinfo(result); + + return 0; }