2014-06-05 09:34:29 +00:00
|
|
|
/**
|
|
|
|
* Nodes
|
|
|
|
*
|
|
|
|
* The S2SS server connects multiple nodes.
|
|
|
|
* There are multiple types of nodes:
|
|
|
|
* - simulators
|
|
|
|
* - servers
|
|
|
|
* - workstations
|
|
|
|
*
|
|
|
|
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
|
|
|
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
#include "cfg.h"
|
2014-06-05 09:34:29 +00:00
|
|
|
#include "utils.h"
|
|
|
|
#include "msg.h"
|
|
|
|
#include "node.h"
|
2014-06-05 09:35:39 +00:00
|
|
|
#include "if.h"
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
int node_create(struct node *n, const char *name, enum node_type type,
|
|
|
|
struct sockaddr_in local, struct sockaddr_in remote)
|
2014-06-05 09:34:29 +00:00
|
|
|
{
|
2014-06-05 09:34:56 +00:00
|
|
|
n->name = name;
|
2014-06-05 09:34:29 +00:00
|
|
|
n->type = type;
|
2014-06-05 09:35:09 +00:00
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
n->local = local;
|
|
|
|
n->remote = remote;
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:35:39 +00:00
|
|
|
/* We use to local address to determine the outgoing interface */
|
|
|
|
//n->ifname = if_addrtoname((struct sockaddr*) &local);
|
|
|
|
//n->ifindex = if_nametoindex(n->ifname);
|
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
int node_connect(struct node *n)
|
|
|
|
{
|
2014-06-05 09:34:46 +00:00
|
|
|
/* Create socket */
|
2014-06-05 09:34:29 +00:00
|
|
|
n->sd = socket(AF_INET, SOCK_DGRAM, 0);
|
2014-06-05 09:34:56 +00:00
|
|
|
if (n->sd < 0)
|
2014-06-05 09:35:16 +00:00
|
|
|
perror("Failed to create socket");
|
2014-06-05 09:34:56 +00:00
|
|
|
|
|
|
|
/* Set socket options */
|
|
|
|
int prio = SOCKET_PRIO;
|
2014-06-05 09:35:39 +00:00
|
|
|
if (setsockopt(n->sd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)))
|
|
|
|
perror("Failed to set socket priority");
|
|
|
|
else
|
|
|
|
debug(4, "Set socket priority of node '%s' to %u", n->name, prio);
|
|
|
|
|
|
|
|
/* Set mark for outgoing packets */
|
|
|
|
if (setsockopt(n->sd, SOL_SOCKET, SO_MARK, &n->mark, sizeof(n->mark)))
|
|
|
|
perror("Failed to set mark for outgoing packets");
|
|
|
|
else
|
|
|
|
debug(4, "Set mark of outgoing packets of node '%s' to %u", n->name, n->mark);
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:46 +00:00
|
|
|
/* Bind socket for receiving */
|
2014-06-05 09:34:56 +00:00
|
|
|
if (bind(n->sd, (struct sockaddr *) &n->local, sizeof(struct sockaddr_in)))
|
2014-06-05 09:35:16 +00:00
|
|
|
perror("Failed to bind to socket");
|
2014-06-05 09:34:35 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-06-05 09:35:09 +00:00
|
|
|
int node_disconnect(struct node *n)
|
2014-06-05 09:34:29 +00:00
|
|
|
{
|
|
|
|
close(n->sd);
|
|
|
|
}
|
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
enum node_type node_lookup_type(const char *str)
|
2014-06-05 09:34:29 +00:00
|
|
|
{
|
2014-06-05 09:34:56 +00:00
|
|
|
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;
|
2014-06-05 09:34:29 +00:00
|
|
|
}
|
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
struct node* node_lookup_name(const char *str, struct node *nodes, int len)
|
2014-06-05 09:34:29 +00:00
|
|
|
{
|
2014-06-05 09:34:56 +00:00
|
|
|
for (int i = 0; i < len; i++) {
|
|
|
|
if (!strcmp(str, nodes[i].name)) {
|
|
|
|
return &nodes[i];
|
|
|
|
}
|
|
|
|
}
|
2014-06-05 09:34:29 +00:00
|
|
|
|
2014-06-05 09:34:56 +00:00
|
|
|
return NULL;
|
2014-06-05 09:34:29 +00:00
|
|
|
}
|