1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

updated more node code

git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@28 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
Steffen Vogel 2014-06-05 09:34:56 +00:00
parent 8b1ba90c31
commit f1119f5633
3 changed files with 141 additions and 85 deletions

View file

@ -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_ */

View file

@ -15,111 +15,86 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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;
}

View file

@ -7,7 +7,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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;
}