Пример #1
0
void
print_node_list(struct dr_node *first_node)
{
	struct dr_node *parent;
	struct dr_node *child;

	parent = first_node;
	say(DEBUG, "\nDR nodes list\n==============\n");
	while (parent) {
		say(DEBUG, "%s: %s\n"
		    "\tdrc index: 0x%x        description: %s\n"
		    "\tdrc name: %s\n\tloc code: %s\n", 
		    parent->ofdt_path, (parent->skip ? "(SKIP)" : ""),
		    parent->drc_index, node_type(parent),
		    parent->drc_name, parent->loc_code);

		child = parent->children;
		while (child) {
			say(DEBUG, "%s: %s\n"
			    "\tdrc index: 0x%x        description: %s\n"
			    "\tdrc name: %s\n\tloc code: %s\n",
			    child->ofdt_path, (child->skip ? "(SKIP)" : ""),
			    child->drc_index, node_type(child),
			    child->drc_name, child->loc_code);

			child = child->next;
		}

		parent = parent->next;
	}
	say(DEBUG, "\n");
}
Пример #2
0
/* daemon-specific node manipulation */
static void post_process_nodes(void)
{
	uint i, x;

	ldebug("post processing %d masters, %d pollers, %d peers",
	       num_masters, num_pollers, num_peers);

	for (i = 0; i < num_nodes; i++) {
		merlin_node *node = node_table[i];

		if (!node) {
			lerr("node is null. i is %d. num_nodes is %d. wtf?", i, num_nodes);
			continue;
		}

		if (!node->sain.sin_port)
			node->sain.sin_port = htons(default_port);

		node->action = node_action_handler;

		node->ioc = iocache_create(MERLIN_IOC_BUFSIZE);
		if (node->ioc == NULL) {
			lerr("Failed to malloc(%i) for io cache for node %s. Aborting",
				 MERLIN_IOC_BUFSIZE, node->name);
		}

		/*
		 * this lets us support multiple merlin instances on
		 * a single system, but all instances on the same
		 * system will be marked at the same time, so we skip
		 * them on the second pass here.
		 */
		if (node->flags & MERLIN_NODE_FIXED_SRCPORT) {
			continue;
		}

		if (node->sain.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
			node->flags |= MERLIN_NODE_FIXED_SRCPORT;
			ldebug("Using fixed source-port for local %s node %s",
				   node_type(node), node->name);
			continue;
		}
		for (x = i + 1; x < num_nodes; x++) {
			merlin_node *nx = node_table[x];
			if (node->sain.sin_addr.s_addr == nx->sain.sin_addr.s_addr) {
				ldebug("Using fixed source-port for %s node %s",
				       node_type(node), node->name);
				ldebug("Using fixed source-port for %s node %s",
				       node_type(nx), nx->name);
				node->flags |= MERLIN_NODE_FIXED_SRCPORT;
				nx->flags |= MERLIN_NODE_FIXED_SRCPORT;

				if (node->sain.sin_port == nx->sain.sin_port) {
					lwarn("Nodes %s and %s have same ip *and* same port. Voodoo?",
					      node->name, nx->name);
				}
			}
		}
	}
}
Пример #3
0
Файл: net.c Проект: op5/merlin
/*
 * Accept an inbound connection from a remote host
 * Returns 0 on success and -1 on errors
 */
static int net_accept_one(int sd, int events, void *discard)
{
	int sock, result;
	merlin_node *node;
	struct sockaddr_in sain;
	socklen_t slen = sizeof(struct sockaddr_in);

	sock = accept(sd, (struct sockaddr *)&sain, &slen);
	if (sock < 0) {
		lerr("accept() failed: %s", strerror(errno));
		return -1;
	}

	node = find_node(&sain);
	linfo("NODESTATE: %s connected from %s:%d. Current state is %s",
		  node ? node->name : "An unregistered node",
		  inet_ntoa(sain.sin_addr), ntohs(sain.sin_port),
		  node ? node_state_name(node->state) : "unknown");
	if (!node) {
		close(sock);
		return 0;
	}

	switch (node->state) {
	case STATE_NEGOTIATING:
	case STATE_CONNECTED: case STATE_PENDING:
		/* if node->sock >= 0, we must negotiate which one to use */
		if (node->sock >= 0) {
			int sel_sd = net_negotiate_socket(node, node->sock, sock);
			if (sel_sd != sock) {
				close(sock);
			}
		}
		break;

	case STATE_NONE:
		/*
		 * we must close it unconditionally or we'll leak fd's
		 * for reconnecting nodes that were previously connected
		 */
		node_disconnect(node, "fd leak prevention for connecting nodes");
		node->sock = sock;
		break;

	default:
		lerr("%s %s has an unknown status", node_type(node), node->name);
		break;
	}

	node_set_state(node, STATE_NEGOTIATING, "Inbound connection accepted. Negotiating protocol version");
	result = iobroker_register(nagios_iobs, node->sock, node, net_input);
	if (result < 0) {
		lerr("IOB: Failed to register %d for %s node %s for input events: %s",
		     node->sock, node_type(node), node->name, iobroker_strerror(result));
	}

	return sock;
}
Пример #4
0
static
eval_err_t do_splitsym(memory_state_t *ms, node_t **args, node_t **out, void *p)
{
	char *start, *end;
	node_t *sym;

	(void) p;
	sym = args[0];
	if(node_type(sym) != NODE_SYMBOL) {
		*out = sym;
		return eval_err(EVAL_ERR_EXPECTED_SYMBOL);
	}

	start = node_symbol_name(sym);
	end = start + strlen(start) - 1; // end points to last nonzero char

	/* construct value list backwards */
	for(*out = NULL; end >= start; end--) {
		*out = node_cons_new(ms,
		                     node_value_new(ms, *end),
		                     *out);
	}

	return EVAL_OK;
}
Пример #5
0
Файл: net.c Проект: op5/merlin
/*
 * Reads input from a particular node and ships it off to
 * the "handle_event()"
 */
int net_input(int sd, int io_evt, void *node_)
{
	merlin_event *pkt;
	merlin_node *node = (merlin_node *)node_;
	int len, events = 0;

	errno = 0;
	ldebug("NETINPUT from %p (%s)", node, node ? node->name : "oops");
	len = node_recv(node);
	if (len < 0) {
		return 0;
	}
	node->stats.bytes.read += len;
	node->last_recv = time(NULL);

	while ((pkt = node_get_event(node))) {
		events++;
		handle_event(node, pkt);
		free(pkt);
	}
	ldebug("Read %d events in %s from %s node %s",
		   events, human_bytes(len), node_type(node), node->name);

	return events;
}
Пример #6
0
static
eval_err_t do_mathop(memory_state_t *ms, node_t **args, node_t **out, void *p)
{
	mathop_t fn = (mathop_t) p;

	if(node_type(args[0]) != NODE_VALUE) {
		*out = args[0];
		return eval_err(EVAL_ERR_EXPECTED_VALUE);
	}
	if(node_type(args[1]) != NODE_VALUE) {
		*out = args[1];
		return eval_err(EVAL_ERR_EXPECTED_VALUE);
	}
	fn(ms, node_value(args[0]), node_value(args[1]), out);
	return EVAL_OK;

}
Пример #7
0
/*
 * Accept an inbound connection from a remote host
 * Returns 0 on success and -1 on errors
 */
int net_accept_one(void)
{
	int sock;
	merlin_node *node;
	struct sockaddr_in sain;
	socklen_t slen = sizeof(struct sockaddr_in);

	/*
	 * we get called from polling_loop(). If so, check for readability
	 * to see if anyone has connected and, if not, return early
	 */
	if (!io_read_ok(net_sock, 0))
		return -1;

	sock = accept(net_sock, (struct sockaddr *)&sain, &slen);
	if (sock < 0) {
		lerr("accept() failed: %s", strerror(errno));
		return -1;
	}

	node = find_node(&sain, NULL);
	linfo("%s connected from %s:%d. Current state is %s",
		  node ? node->name : "An unregistered node",
		  inet_ntoa(sain.sin_addr), ntohs(sain.sin_port),
		  node ? node_state_name(node->state) : "unknown");
	if (!node) {
		close(sock);
		return 0;
	}

	switch (node->state) {
	case STATE_NEGOTIATING: /* this should *NEVER EVER* happen */
		lerr("Aieee! Negotiating connection with one attempting inbound. Bad Thing(tm)");

		/* fallthrough */
	case STATE_CONNECTED: case STATE_PENDING:
		/* if node->sock >= 0, we must negotiate which one to use */
		node->sock = net_negotiate_socket(node, sock);
		break;

	case STATE_NONE:
		/*
		 * we must close it unconditionally or we'll leak fd's
		 * for reconnecting nodes that were previously connected
		 */
		node_disconnect(node, "fd leak prevention for connecting nodes");
		node->sock = sock;
		break;

	default:
		lerr("%s %s has an unknown status", node_type(node), node->name);
		break;
	}

	node_set_state(node, STATE_CONNECTED, "Inbound connection accepted or negotiated");

	return sock;
}
Пример #8
0
//
// print() functions
//
void Formula::print(FILE *output_file)
    {
    if(myChildren.empty())
	{
	if(node_type()==Op_Relation || node_type()==Op_Or)
	    fprintf(output_file, "FALSE");
	else if(node_type()==Op_And)
	    fprintf(output_file, "TRUE");
	else
	    {
	    assert(0);
	    }
	}
    
    for(List_Iterator<Formula*> c(myChildren); c;)
	{
	if (node_type() == Op_Exists || node_type() == Op_Forall 
	    || (*c)->priority() < priority()) 
	    fprintf(output_file, "( ");
	(*c)->print(output_file);
	if (node_type() == Op_Exists || node_type() == Op_Forall 
	    || (*c)->priority() < priority()) 
	    fprintf(output_file, " )");
	c++;
	if(c.live())
	    print_separator(output_file);
	}
    }
Пример #9
0
/**
 * insert_print_node
 *
 * Insert the node into the list of nodes. The list is
 * sorted by location codes.
 *
 * @param node dlpar node to add
 */
void
insert_print_node(struct dr_node *node)
{
	struct print_node *pnode;

	pnode = zalloc(sizeof(*pnode));
	if (pnode == NULL) {
		fprintf(stderr, "Could not allocate print node for drc %x\n",
			node->drc_index);
		return;
	}

	pnode->node = node;
	pnode->desc = node_type(node);
	pnode->next = NULL;

	max_sname = MAX(max_sname, strlen(node->drc_name));
	max_desc = MAX(max_desc, strlen(pnode->desc));

	/* Insert the new print_node into the sorted list of print nodes */
	if (print_list == NULL) {
		print_list = pnode;
		return;
	}
	
	if (loc_code_cmp(print_list->node->drc_name,
			 pnode->node->drc_name) > 0) {
		/* The location code for the new node is less than that
		 * of the first node so insert the new node at the front.
		 */
		pnode->next = print_list;
		print_list = pnode;
	} else {
		/* Find the first node in the list where the new node's
		 * location code is less than the existing node's location
		 * code and insert the new node before that node.
		 */
		struct print_node *last;
		last = print_list;
		while (last->next != NULL) {
			if (loc_code_cmp(last->next->node->drc_name,
					 pnode->node->drc_name) > 0)
			{
				pnode->next = last->next;
				last->next = pnode;
				break;
			}
			last = last->next;
		}

		/* Put the new node at the end of the list if itslocation
		 * code is not less than any other node's location code.
		 */
		if (last->next == NULL)
			last->next = pnode;
	}
}
Пример #10
0
constant_type_t local_type(node_t*node, int num, model_t*m)
{
    node_t*setlocal = node_find_setlocal(node, num);
    if(!setlocal) {
        fprintf(stderr, "Couldn't find assignment of variable %d\n", num);
        return CONSTANT_MISSING;
    }
    return node_type(setlocal, m);
}
Пример #11
0
/*
 * Read as much data as we possibly can from the node so
 * that whatever parsing code there is can handle it later.
 * All information the caller needs will reside in the
 * nodes own merlin_iocache function, and we return the
 * number of bytes read, or -1 on errors.
 * The io-cache buffer must be allocated before we get
 * to this point, and if the caller wants to poll the
 * socket for input, it'll have to do so itself.
 */
int node_recv(merlin_node *node)
{
	int bytes_read;
	iocache *ioc = node->ioc;

	if (!node || node->sock < 0) {
		return -1;
	}

	bytes_read = iocache_read(ioc, node->sock);

	/*
	 * If we read something, update the stat counter
	 * and return. The caller will have to handle the
	 * input as it sees fit
	 */
	if (bytes_read > 0) {
		node->last_action = node->last_recv = time(NULL);
		node->stats.bytes.read += bytes_read;
		return bytes_read;
	}

	/* no real error, but no new data, so return 0 */
	if (errno == EAGAIN || errno == EWOULDBLOCK) {
		ldebug("No input available from %s node %s.", node_type(node), node->name);
		return 0;
	}

	/*
	 * Remote endpoint shut down, or we ran into some random error
	 * we can't handle any other way than disconnecting the node and
	 * letting the write machinery attempt to reconnect later
	 */
	if (bytes_read < 0) {
		lerr("Failed to read from socket %d into %p for %s node %s: %s",
		     node->sock, ioc, node_type(node), node->name, strerror(errno));
	}

	/* zero-read. We've been disconnected for some reason */
	ldebug("bytes_read: %d; errno: %d; strerror(%d): %s",
		   bytes_read, errno, errno, strerror(errno));
	node_disconnect(node, "recv() failed");
	return -1;
}
Пример #12
0
static
eval_err_t do_symeq_p(memory_state_t *ms, node_t **args, node_t **out, void *p)
{
	(void) p;
	if(node_type(args[0]) != NODE_SYMBOL) {
		*out = args[0];
		return eval_err(EVAL_ERR_EXPECTED_SYMBOL);
	}
	if(node_type(args[1]) != NODE_SYMBOL) {
		*out = args[1];
		return eval_err(EVAL_ERR_EXPECTED_SYMBOL);
	}
	
	*out = NULL;
	if(strcmp(node_symbol_name(args[0]), node_symbol_name(args[1]))) {
		*out = node_value_new(ms, 1);
	}
	return EVAL_OK;
}
Пример #13
0
static void fill_locals(node_t*node, model_t*m, constant_type_t*types)
{
    if(node->type == &node_setlocal) {
        types[node->value.i] = node_type(node->child[0], m);
    }
    int t;
    for(t=0;t<node->num_children;t++) {
        fill_locals(node->child[t], m, types);
    }
}
Пример #14
0
static
eval_err_t do_car(memory_state_t *ms, node_t **in, node_t **out, void *p)
{
	(void) p;
	if(node_type(in[0]) != NODE_CONS) {
		*out = in[0];
		return eval_err(EVAL_ERR_EXPECTED_CONS);
	}
	*out = node_cons_car(in[0]);
	return EVAL_OK;
}
Пример #15
0
static
eval_err_t cons_matchfn(memory_state_t *ms, node_t **in, node_t **out, void *p)
{
	(void) p;
	if(node_type(in[0]) == NODE_SYMBOL) {
		*out = node_value_new(ms, 1);
	} else {
		*out = NULL;
	}
	return EVAL_OK;
}
Пример #16
0
/*
 * creates the node-table, with fanout indices at the various
 * different types of nodes. This allows us to iterate over
 * all the nodes or a particular subset of them using the same
 * table, which is quite handy.
 */
static void create_node_tree(merlin_node *table, unsigned n)
{
	uint i, xnoc, xpeer, xpoll;

	for (i = 0; i < n; i++) {
		merlin_node *node = &table[i];
		switch (node->type) {
		case MODE_NOC:
			num_masters++;
			break;
		case MODE_POLLER:
			num_pollers++;
			break;
		case MODE_PEER:
			num_peers++;
			break;
		}
	}

	/*
	 * Sort nodes by type. This way, we can keep them all linear
	 * while each has its own table base pointer and still not waste
	 * much memory. Pretty nifty, really.
	 */
	node_table = calloc(num_nodes, sizeof(merlin_node *));
	noc_table = node_table;
	peer_table = &node_table[num_masters];
	poller_table = &node_table[num_masters + num_peers];

	xnoc = xpeer = xpoll = 0;
	for (i = 0; i < n; i++) {
		merlin_node *node = &table[i];

		switch (node->type) {
		case MODE_NOC:
			node->id = xnoc;
			noc_table[xnoc++] = node;
			break;
		case MODE_PEER:
			node->id = num_masters + xpeer;
			peer_table[xpeer++] = node;
			break;
		case MODE_POLLER:
			node->id = num_masters + num_peers + xpoll;
			poller_table[xpoll++] = node;
			break;
		}
		if(is_module)
			asprintf(&node->source_name, "Merlin %s %s", node_type(node), node->name);
	}
}
Пример #17
0
void c_write_header(model_t*model, state_t*s)
{
    node_t*root = (node_t*)model->code;

    if(node_has_child(root, &node_arg_max)) {
        c_write_function_arg_min_or_max(s, "max", "", "double", ">");
    }
    if(node_has_child(root, &node_arg_max_i)) {
        c_write_function_arg_min_or_max(s, "max", "_i", "int", ">");
    }
    if(node_has_child(root, &node_arg_min)) {
        c_write_function_arg_min_or_max(s, "min", "", "double", "<");
    }
    if(node_has_child(root, &node_arg_min_i)) {
        c_write_function_arg_min_or_max(s, "min", "_i", "int", "<");
    }
    if(node_has_child(root, &node_array_arg_max_i)) {
        c_write_function_array_arg_max_i(s);
    }
    if(node_has_child(root, &node_sqr)) {
        c_write_function_sqr(s);
    }
    if(node_has_child(root, &node_sort_float_array_asc)) {
        c_write_function_compare_float_ptr(s);
    }

    constant_type_t type = node_type(root, model);
    strf(s, "%s predict(", c_type_name(type));
    int t;
    for(t=0;t<model->sig->num_inputs;t++) {
        if(t) strf(s, ", ");
        if(s->model->sig->has_column_names) {
            strf(s, "%s %s", c_type_name(model_param_type(s->model,t)), s->model->sig->column_names[t]);
        } else {
            strf(s, "%s p%d", c_type_name(model_param_type(s->model,t)), t);
        }
    }
    strf(s, ")\n");
    strf(s, "{\n");
    indent(s);
    int num_locals = 0;
    constant_type_t*types = node_local_types(root, s->model, &num_locals);
    for(t=0;t<num_locals;t++) {
        if(types[t] != CONSTANT_MISSING) {
            strf(s, "%s v%d;\n", c_type_name(types[t]), t);
        }
    }
    c_enumerate_arrays(root, s);

}
Пример #18
0
void c_write_node_equals(node_t*n, state_t*s)
{
    constant_type_t type = node_type(n->child[0], s->model);
    if(type==CONSTANT_STRING) {
        strf(s, "!strcmp(");
        write_node(s, n->child[0]);
        strf(s, ",");
        write_node(s, n->child[1]);
        strf(s, ")");
    } else {
        write_node(s, n->child[0]);
        strf(s, " == ");
        write_node(s, n->child[1]);
    }
}
Пример #19
0
void
print_node_list(struct dr_node *first_node)
{
	struct dr_node *parent;
	struct dr_node *child;

	/* Short-circuit printing nodes if not requested. */
	if (output_level < EXTRA_DEBUG)
		return;

	parent = first_node;
	say(EXTRA_DEBUG, "\nDR nodes list\n==============\n");
	while (parent) {
		say(EXTRA_DEBUG, "%s: %s\n"
		    "\tdrc index: 0x%x        description: %s\n"
		    "\tdrc name: %s\n\tloc code: %s\n", 
		    parent->ofdt_path, (parent->skip ? "(SKIP)" : ""),
		    parent->drc_index, node_type(parent),
		    parent->drc_name, parent->loc_code);

		child = parent->children;
		while (child) {
			say(EXTRA_DEBUG, "%s: %s\n"
			    "\tdrc index: 0x%x        description: %s\n"
			    "\tdrc name: %s\n\tloc code: %s\n",
			    child->ofdt_path, (child->skip ? "(SKIP)" : ""),
			    child->drc_index, node_type(child),
			    child->drc_name, child->loc_code);

			child = child->next;
		}

		parent = parent->next;
	}
	say(EXTRA_DEBUG, "\n");
}
Пример #20
0
static
eval_err_t do_makesym(memory_state_t *ms, node_t **args, node_t **out, void *p)
{
	char name[MAX_SYM_LEN], *cursor;;
	node_t *val, *val_iter;

	(void) p;
	val = args[0];
	if(node_type(val) != NODE_CONS) {
		*out = val;
		return eval_err(EVAL_ERR_EXPECTED_CONS);
	}
	
	val_iter = val;
	cursor = name;
	for(val_iter = val; val_iter; val_iter = node_cons_cdr(val_iter)) {
		val = node_cons_car(val_iter);
		if(node_type(val) != NODE_VALUE) {
			*out = val;
			return eval_err(EVAL_ERR_EXPECTED_VALUE);
		}
		if(node_value(val) > 255 ) {
			*out = val;
			return eval_err(EVAL_ERR_VALUE_BOUNDS);
		}
		*cursor++ = node_value(val);
		if(cursor - &(name[0]) >= (ssize_t) sizeof(name)) {
			break;
		}
		val_iter = node_cons_cdr(val_iter);
	}
	*cursor = 0;
	*out = node_symbol_new(ms, name);

	return EVAL_OK;
}
Пример #21
0
static
eval_err_t func_matchfn(memory_state_t *ms, node_t **in, node_t **out, void *p)
{
	nodetype_t type = node_type(in[0]);
	(void) p;
	if(type == NODE_LAMBDA
	   || type == NODE_FOREIGN
	   || type == NODE_CONTINUATION
	   || type == NODE_SPECIAL_FUNC) {
		*out = node_value_new(ms, 1);
	} else {
		*out = NULL;
	}
	return EVAL_OK;
}
Пример #22
0
EXPORT	int reg_to_mach_diff_reconfigure(
	O_CURVE		**newc,
	O_CURVE		**oldc,
	NODE		*oldn)
{
	int		i;

	debug_print("mach_diff","Entering reg_to_mach_diff_reconfigure()\n");
	if (debugging("mach_diff"))
	{
	    (void) printf("WARNING in diffraction_node_propagate(), "
	                  "bifurcation from regular diffraction "
	                  "to mach difraction.\n");
	}

	if (newc[5]->orient == POSITIVE_ORIENTATION)
	{
	    start_status(oldc[5]->curve) = INCIDENT;
	    start_status(newc[5]->curve) = INCIDENT;
	}
	else
	{
	    end_status(oldc[5]->curve) = INCIDENT;
	    end_status(newc[5]->curve) = INCIDENT;
	}
	if (newc[0]->orient == POSITIVE_ORIENTATION)
	{
	    start_status(oldc[0]->curve) = TRANSMITTED;
	    start_status(newc[0]->curve) = TRANSMITTED;
	}
	else
	{
	    end_status(oldc[0]->curve) = TRANSMITTED;
	    end_status(newc[0]->curve) = TRANSMITTED;
	}

		/* untrack any reflected waves */

	for (i = 1; i < 4; i++)
	    if (newc[i]->curve != NULL)
	    	untracked_hyper_surf(newc[i]->curve) = YES;

	node_type(oldn) = TRANSMISSION_NODE;

	debug_print("mach_diff","Leaving reg_to_mach_diff_reconfigure()\n");
	return REPEAT_TIME_STEP_NODE;
}		/*end reg_to_mach_diff_reconfigure*/
Пример #23
0
/*
 * Reads input from a particular node and ships it off to
 * the "handle_network_event()" routine up above
 */
static int net_input(merlin_node *node)
{
	merlin_event *pkt;
	int len, events = 0;

	errno = 0;
	len = node_recv(node);
	if (len < 0) {
		return 0;
	}
	node->stats.bytes.read += len;
	node->last_recv = time(NULL);

	while ((pkt = node_get_event(node))) {
		events++;
		handle_network_event(node, pkt);
	}
	ldebug("Read %d events in %s from %s node %s",
		   events, human_bytes(len), node_type(node), node->name);

	return events;
}
Пример #24
0
/*
 * Initiate a connection attempt to a node and mark it as PENDING.
 * Note that since we're using sockets in non-blocking mode (in order
 * to be able to effectively multiplex), the connection attempt will
 * never be completed in this function
 */
int net_try_connect(merlin_node *node)
{
	int sockopt = 1;
	struct sockaddr *sa = (struct sockaddr *)&node->sain;
	int connected = 0, should_log = 0;
	struct timeval connect_timeout = { MERLIN_CONNECT_TIMEOUT, 0 };
	struct sockaddr_in sain;
	time_t interval = MERLIN_CONNECT_INTERVAL;

	/* don't log obsessively */
	if (node->last_conn_attempt_logged + 30 <= time(NULL)) {
		should_log = 1;
		node->last_conn_attempt_logged = time(NULL);
	}

	if (!(node->flags & MERLIN_NODE_CONNECT)) {
		if (should_log) {
			linfo("Connect attempt blocked by config to %s node %s",
				  node_type(node), node->name);
		}
		return 0;
	}

	/* if it's not yet time to connect, don't even try it */
	if (node->last_conn_attempt + interval > time(NULL)) {
		ldebug("connect to %s blocked for %lu more seconds", node->name,
			   node->last_conn_attempt + interval - time(NULL));
		return 0;
	}

	/* mark the time so we can time it out ourselves if need be */
	node->last_conn_attempt = time(NULL);

	/* create the socket if necessary */
	if (node->sock < 0) {
		node_disconnect(node, "struct reset (no real disconnect)");
		node->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (node->sock < 0) {
			lerr("Failed to obtain socket for node %s: %s", node->name, strerror(errno));
			lerr("Aborting connection attempt to %s", node->name);
			return -1;
		}
	}

	/*
	 * don't try to connect to a node if an attempt is already pending,
	 * but do check if the connection has completed successfully
	 */
	if (node->state == STATE_PENDING || node->state == STATE_CONNECTED) {
		if (net_is_connected(node))
			node_set_state(node, STATE_CONNECTED, "Attempted connect completed");
		return 0;
	}

	sa->sa_family = AF_INET;
	if (should_log) {
		linfo("Connecting to %s %s@%s:%d", node_type(node), node->name,
		      inet_ntoa(node->sain.sin_addr),
		      ntohs(node->sain.sin_port));
	}

	(void)setsockopt(node->sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int));
	if (node->flags & MERLIN_NODE_FIXED_SRCPORT) {
		ldebug("Using fixed source port for %s node %s",
			   node_type(node), node->name);
		/*
		 * first we bind() to a local port calculated by our own
		 * listening port + the target port.
		 */
		sain.sin_family = AF_INET;
		sain.sin_port = htons(net_source_port(node));
		sain.sin_addr.s_addr = 0;
		if (bind(node->sock, (struct sockaddr *)&sain, sizeof(sain))) {
			lerr("Failed to bind() outgoing socket for node %s to port %d: %s",
				 node->name, ntohs(sain.sin_port), strerror(errno));
		}
	}

	if (fcntl(node->sock, F_SETFL, O_NONBLOCK) < 0) {
		lwarn("Failed to set socket for %s non-blocking: %s", node->name, strerror(errno));
	}
	if (setsockopt(node->sock, SOL_SOCKET, SO_RCVTIMEO,
	               &connect_timeout, sizeof(connect_timeout)) < 0)
	{
		ldebug("Failed to set receive timeout for node %s: %s",
		       node->name, strerror(errno));
	}
	if (setsockopt(node->sock, SOL_SOCKET, SO_SNDTIMEO,
	               &connect_timeout, sizeof(connect_timeout)) < 0)
	{
		ldebug("Failed to set send timeout for node %s: %s",
		       node->name, strerror(errno));
	}

	if (connect(node->sock, sa, sizeof(struct sockaddr_in)) < 0) {
		if (errno == EINPROGRESS || errno == EALREADY) {
			node_set_state(node, STATE_PENDING, "connect() already in progress");
		} else if (errno == EISCONN) {
			connected = 1;
		} else {
			if (should_log) {
				node_disconnect(node, "connect() failed to %s node '%s' (%s:%d): %s",
								node_type(node), node->name,
								inet_ntoa(node->sain.sin_addr),
								ntohs(node->sain.sin_port),
								strerror(errno));
			} else {
				node_disconnect(node, NULL);
			}
			return -1;
		}
	}

	if (connected || net_is_connected(node)) {
		linfo("Successfully connected to %s %s@%s:%d",
			  node_type(node), node->name, inet_ntoa(node->sain.sin_addr),
			  ntohs(node->sain.sin_port));
		node_set_state(node, STATE_CONNECTED, "connect() successful");
	} else {
		if (should_log) {
			linfo("Connection pending to %s %s@%s:%d",
			      node_type(node), node->name,
			      inet_ntoa(node->sain.sin_addr),
			      ntohs(node->sain.sin_port));
		}
		node_set_state(node, STATE_PENDING, "connect() in progress");
	}

	return 0;
}
Пример #25
0
constant_type_t node_type(node_t*n, model_t*m)
{
    switch(node_get_opcode(n)) {
        case opcode_node_arg_max:
        case opcode_node_arg_max_i:
        case opcode_node_array_arg_max_i:
        case opcode_node_inc_array_at_pos:
        case opcode_node_int:
        case opcode_node_inclocal:
            return CONSTANT_INT;
        case opcode_node_nop:
        case opcode_node_debug_print:
        case opcode_node_missing:
        case opcode_node_for_local_from_n_to_m:
        case opcode_node_sort_float_array_asc:
            return CONSTANT_MISSING;
        case opcode_node_in:
        case opcode_node_not:
        case opcode_node_lt:
        case opcode_node_lte:
        case opcode_node_gt:
        case opcode_node_gte:
        case opcode_node_bool:
        case opcode_node_equals:
            return CONSTANT_BOOL;
        case opcode_node_bool_to_float:
        case opcode_node_float:
        case opcode_node_term_frequency:
            return CONSTANT_FLOAT;
        case opcode_node_category:
            return CONSTANT_CATEGORY;
        case opcode_node_int_array:
            return CONSTANT_INT_ARRAY;
        case opcode_node_category_array:
            return CONSTANT_CATEGORY_ARRAY;
        case opcode_node_float_array:
            return CONSTANT_FLOAT_ARRAY;
        case opcode_node_string_array:
            return CONSTANT_STRING_ARRAY;
        case opcode_node_mixed_array:
            return CONSTANT_MIXED_ARRAY;
        case opcode_node_zero_int_array:
            return CONSTANT_INT_ARRAY;
        case opcode_node_zero_float_array:
            return CONSTANT_FLOAT_ARRAY;
        case opcode_node_string:
            return CONSTANT_STRING;
        case opcode_node_constant:
            return n->value.type;
        case opcode_node_return:
            /* strictly speaking, this node doesn't have a "type" at all
               (since it causes evaluation to terminate), but in order to
               make node_type(root) do the right thing, we treat it as if
               it would cascade its value up the tree */
            return node_type(n->child[0],m);
        case opcode_node_brackets:
        case opcode_node_sqr:
        case opcode_node_abs:
        case opcode_node_neg:
        case opcode_node_exp:
        case opcode_node_add:
        case opcode_node_sub:
        case opcode_node_mul:
        case opcode_node_div:
        case opcode_node_setlocal:
            return node_type(n->child[0],m);
        case opcode_node_block:
            return node_type(n->child[n->num_children-1],m);
        case opcode_node_if:
            return node_type(n->child[1],m);
        case opcode_node_set_array_at_pos:
            return node_type(n->child[2],m);
        case opcode_node_array_at_pos:
            return node_array_element_type(n->child[0]);
        case opcode_node_param:
            return model_param_type(m, n->value.i);
        case opcode_node_getlocal:
            return local_type(node_find_root(n), n->value.i, m);
        default:
            fprintf(stderr, "Couldn't do type deduction for ast node %s\n", n->type->name);
            return CONSTANT_MISSING;
    }
}
Пример #26
0
Файл: net.c Проект: op5/merlin
/*
 * Negotiate which socket to use for communication when the remote
 * host has accepted a connection attempt from us while we have
 * accepted one from the remote host. We must make sure both ends
 * agree on one socket to use.
 */
static int net_negotiate_socket(merlin_node *node, int con, int lis)
{
	struct sockaddr_in lissain, consain;
	socklen_t slen = sizeof(struct sockaddr_in);

	linfo("negotiate: Choosing socket for %s %s (%d or %d)", node_type(node), node->name, con, lis);

	if (con < 0)
		return lis;
	if (lis < 0)
		return con;

	/* we prefer the socket with the lowest ip-address */
	if (getsockname(lis, (struct sockaddr *)&lissain, &slen) < 0) {
		lerr("negotiate: getsockname(%d, ...) failed: %s",
			 lis, strerror(errno));
		return con;
	}

	if (getpeername(con, (struct sockaddr *)&consain, &slen) < 0) {
		lerr("negotiate: getpeername(%d, ...) failed: %s",
			 con, strerror(errno));
		return lis;
	}

	ldebug("negotiate: lis(%d): %s:%d", lis,
		   inet_ntoa(lissain.sin_addr), ntohs(lissain.sin_port));
	ldebug("negotiate: con(%d): %s:%d", con,
		   inet_ntoa(consain.sin_addr), ntohs(consain.sin_port));

	if (lissain.sin_addr.s_addr > consain.sin_addr.s_addr) {
		ldebug("negotiate: con has lowest ip. using that");
		return con;
	}
	if (consain.sin_addr.s_addr > lissain.sin_addr.s_addr) {
		ldebug("negotiate: lis has lowest ip. using that");
		return lis;
	}

	/*
	 * this will happen if multiple merlin instances run
	 * on the same server, such as when we're testing
	 * things. In that case, let the portnumber decide
	 * the tiebreak
	 */
	if (lissain.sin_port > consain.sin_port) {
		ldebug("negotiate: con has lowest port. using that");
		return con;
	}
	if (consain.sin_port > lissain.sin_port) {
		ldebug("negotiate: lis has lowest port. using that");
		return lis;
	}

	ldebug("negotiate: con and lis are equal. killing both");
	node->last_conn_attempt_logged = 0;
	node_disconnect(node, "socket negotiation failed");
	iobroker_close(nagios_iobs, lis);
	node->sock = -1;

	return -1;
}
Пример #27
0
Файл: net.c Проект: op5/merlin
/*
 * Initiate a connection attempt to a node and mark it as PENDING.
 * Note that since we're using sockets in non-blocking mode (in order
 * to be able to effectively multiplex), the connection attempt will
 * never be completed in this function
 */
int net_try_connect(merlin_node *node)
{
	int sockopt = 1;
	struct sockaddr *sa = (struct sockaddr *)&node->sain;
	int should_log = 0;
	struct timeval connect_timeout = { MERLIN_CONNECT_TIMEOUT, 0 };
	struct sockaddr_in sain;
	time_t interval = MERLIN_CONNECT_INTERVAL;
	int result;

	/* don't log obsessively */
	if (node->last_conn_attempt_logged + 30 <= time(NULL)) {
		should_log = 1;
		node->last_conn_attempt_logged = time(NULL);
	}

	if (!(node->flags & MERLIN_NODE_CONNECT)) {
		if (should_log) {
			linfo("CONN: Connect attempt blocked by config to %s node %s",
				  node_type(node), node->name);
		}
		return 0;
	}

	/* don't bother trying to connect if it's pending or done */
	switch (node->state) {
	case STATE_NEGOTIATING:
		if (node->conn_sock < 0)
			break;
	case STATE_CONNECTED:
	case STATE_PENDING:
		ldebug("CONN: node %s state is %s, so bailing",
		       node->name, node_state_name(node->state));
		return 0;
	}

	/* if it's not yet time to connect, don't even try it */
	if (node->last_conn_attempt + interval > time(NULL)) {
		return 0;
	}

	/* mark the time so we can time it out ourselves if need be */
	node->last_conn_attempt = time(NULL);

	/* create the socket if necessary */
	if (node->conn_sock < 0) {
		node_disconnect(node, "struct reset (no real disconnect)");
		node->conn_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (node->conn_sock < 0) {
			lerr("CONN: Failed to obtain connection socket for node %s: %s", node->name, strerror(errno));
			lerr("CONN: Aborting connection attempt to %s", node->name);
			return -1;
		}
	}

	sa->sa_family = AF_INET;
	if (should_log) {
		linfo("CONN: Connecting to %s %s@%s:%d", node_type(node), node->name,
		      inet_ntoa(node->sain.sin_addr),
		      ntohs(node->sain.sin_port));
	}

	if (setsockopt(node->conn_sock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int))) {
		ldebug("CONN: Failed to set sockopt SO_REUSEADDR for node %s connect socket %d: %s",
		       node->name, node->conn_sock, strerror(errno));
	}
	if (node->flags & MERLIN_NODE_FIXED_SRCPORT) {
		ldebug("CONN: Using fixed source port %d for %s node %s",
			   net_source_port(node), node_type(node), node->name);
		/*
		 * first we bind() to a local port calculated by our own
		 * listening port + the target port.
		 */
		sain.sin_family = AF_INET;
		sain.sin_port = htons(net_source_port(node));
		sain.sin_addr.s_addr = 0;
		if (bind(node->conn_sock, (struct sockaddr *)&sain, sizeof(sain))) {
			lerr("CONN: Failed to bind() outgoing socket %d for node %s to port %d: %s",
				 node->conn_sock, node->name, ntohs(sain.sin_port), strerror(errno));
			if (errno == EBADF || errno == EADDRINUSE) {
				close(node->conn_sock);
				node->conn_sock = -1;
				return -1;
			}
		}
	}

	if (fcntl(node->conn_sock, F_SETFL, O_NONBLOCK) < 0) {
		lwarn("CONN: Failed to set socket %d for %s non-blocking: %s", node->conn_sock, node->name, strerror(errno));
	}
	if (setsockopt(node->conn_sock, SOL_SOCKET, SO_RCVTIMEO,
	               &connect_timeout, sizeof(connect_timeout)) < 0)
	{
		ldebug("CONN: Failed to set receive timeout for %d, node %s: %s",
		       node->conn_sock, node->name, strerror(errno));
	}
	if (setsockopt(node->conn_sock, SOL_SOCKET, SO_SNDTIMEO,
	               &connect_timeout, sizeof(connect_timeout)) < 0)
	{
		ldebug("CONN: Failed to set send timeout for %d, node %s: %s",
		       node->conn_sock, node->name, strerror(errno));
	}

	if (connect(node->conn_sock, sa, sizeof(struct sockaddr_in)) < 0) {
		if (errno == EINPROGRESS) {
			/*
			 * non-blocking socket and connect() can't be completed
			 * immediately (ie, the normal case)
			 */
			node_set_state(node, STATE_PENDING, "Connecting");
		}
		else if (errno == EALREADY) {
			ldebug("CONN: Connect already in progress for socket %d to %s. This should never happen", node->conn_sock, node->name);
			node_set_state(node, STATE_PENDING, "connect() already in progress");
		} else {
			/* a real connection error */
			ldebug("CONN: connect() via %d to %s failed: %s",
			       node->conn_sock, node->name, strerror(errno));
			close(node->conn_sock);
			node->conn_sock = -1;
			if (should_log) {
				node_disconnect(node, "CONN: connect() failed to %s node '%s' (%s:%d): %s",
								node_type(node), node->name,
								inet_ntoa(node->sain.sin_addr),
								ntohs(node->sain.sin_port),
								strerror(errno));
			} else {
				node_disconnect(node, NULL);
			}
			return -1;
		}
	}

	result = iobroker_register_out(nagios_iobs, node->conn_sock, node, conn_writable);
	if (result < 0) {
		node_disconnect(node, "IOB: Failed to register %s connect socket %d with iobroker: %s",
		                node->name, node->conn_sock, iobroker_strerror(result));
		close(node->conn_sock);
		node->conn_sock = -1;
		return -1;
	}

	return 0;
}
Пример #28
0
Файл: net.c Проект: op5/merlin
/*
 * Check if a socket is connected by looking up
 * ip and port of the remote host.
 * Returns 0 if not, and 1 if it is.
 */
int net_is_connected(merlin_node *node)
{
	struct sockaddr_in sain;
	socklen_t slen;
	int optval = 0, gsoerr = 0, gsores = 0, gpnres = 0, gpnerr = 0;

	if (!node || node->sock < 0)
		return 0;

	if (node->state == STATE_CONNECTED)
		return 1;
	if (node->state == STATE_NONE)
		return 0;

	/*
	 * yes, getpeername() actually has to be here, or getsockopt()
	 * won't return errors when we're not yet connected. It's
	 * important that we read the socket error state though, or
	 * some older kernels will maintain the link in SYN_SENT state
	 * more or less indefinitely, so get all the syscalls taken
	 * care of no matter if they actually work or not.
	 */
	errno = 0;
	slen = sizeof(struct sockaddr_in);
	gpnres = getpeername(node->sock, (struct sockaddr *)&sain, &slen);
	gpnerr = errno;
	slen = sizeof(optval);
	gsores = getsockopt(node->sock, SOL_SOCKET, SO_ERROR, &optval, &slen);
	gsoerr = errno;
	if (!gpnres && !gsores && !optval && !gpnerr && !gsoerr) {
		return 1;
	}

	if (optval) {
		node_disconnect(node, "connect() to %s node %s (%s:%d) failed: %s",
		                node_type(node), node->name,
		                inet_ntoa(node->sain.sin_addr),
		                ntohs(node->sain.sin_port),
		                strerror(optval));
		return 0;
	}

	if (gsores < 0 && gsoerr != ENOTCONN) {
		node_disconnect(node, "getsockopt(%d) failed for %s node %s: %s",
						node->sock, node_type(node), node->name, strerror(gsoerr));
	}

	if (gpnres < 0 && gpnerr != ENOTCONN) {
		lerr("getpeername(%d) failed for %s: %s",
			 node->sock, node->name, strerror(gpnerr));
		return 0;
	}

	/*
	 * if a connection is in progress, we should be getting
	 * ENOTCONN, but we need to give it time to complete
	 * first. 30 seconds should be enough.
	 */
	if (node->last_conn_attempt + MERLIN_CONNECT_TIMEOUT < time(NULL)) {
		node_disconnect(node, "connect() timed out after %d seconds",
						MERLIN_CONNECT_TIMEOUT);
	}

	return 0;
}
Пример #29
0
EXPORT	NODE *adv_node_loop_after_good_prop(
	NODE		*oldn,
	NODE		*newn,
	RPROBLEM	**rp)
{
	NODE		*n;
	NODE		*next_oldn;
	RPROBLEM	*rp1;
	RP_NODE		*rpn;

	if ((rp != NULL) && (*rp != NULL) && 
	    (newn != NULL) && (node_type(newn) != SUBDOMAIN_NODE) &&
	    (!is_virtual_fixed_node(newn)))
	{
	    for (rp1 = *rp; rp1; rp1 = rp1->prev) 
	    {
	    	for (rpn = rp1->first_rp_node; rpn; rpn = rpn->next)
	    	{
	    	    if ((rpn->node == newn)) 
	    	    	break;
	    	}
	    	if (rpn == NULL)
		    continue;

	    		/* Delete rp1 from rp list */

	    	if (rp1->prev)
		    rp1->prev->next = rp1->next;
	    	if (rp1->next)
		    rp1->next->prev = rp1->prev;
	    	else
		    *rp = rp1->prev;
				
	    	    /* Push other nodes in rp1 to end of node list */

	    	for (rpn = rp1->first_rp_node; rpn; rpn = rpn->next)
	    	{
	    	    if ((rpn->node == newn)) 
	    	    	continue;

	    	    if (propagation_status(rpn->node) == PROPAGATED_NODE)
	    		continue;

	    	    /* Check if node already follows newn */

	       	    for (n = next_node(newn); n != NULL; n = next_node(n))
	    	    {
	    	    	if (n == rpn->node)
			    break;
	    	    }
	    	    if (n != NULL)
			continue;

	    	    n = rpn->node;
	    	    (void) reorder_node_loop(rpn->old_node,rpn->node);
	    	}
	    	free_rp(rp1);
	    }
	}

	/*
	*  Reset propagation status to UNPROPAGATED_NODE
	*  after successful node propagation.
	*/
	next_oldn = next_node(oldn);
	for (oldn = next_oldn; oldn != NULL; oldn = next_node(oldn))
	{
	    if ((newn = correspond_node(oldn)) == NULL)
		continue;
	    if (propagation_status(newn) != PROPAGATED_NODE)
	    	propagation_status(newn) = UNPROPAGATED_NODE;
	}
	return next_oldn;
}		/*end adv_node_loop_after_good_prop*/
Пример #30
0
void c_write_node_debug_print(node_t*n, state_t*s)
{
    strf(s, "printf(\"%s\n\", ", c_printf_type(node_type(n, s->model)));
    write_node(s, n->child[0]);
    strf(s, ");");
}