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:
parent
8b1ba90c31
commit
f1119f5633
3 changed files with 141 additions and 85 deletions
|
@ -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_ */
|
||||
|
|
121
src/node.c
121
src/node.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
51
src/utils.c
51
src/utils.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue