예제 #1
0
int udpserver_bind(udpserver_t *server, char *address_and_port, char *default_port, int (*cb_recv)(int, void *)) {
	udplistener_t *listener;
	struct addrinfo hints;
	struct addrinfo *addrs, *p;
	int err;

	char *address;
	char *port;
	char *ptr;

	address = address_and_port;
	ptr = strrchr(address_and_port, ':');
	if(ptr == NULL) {
		port = default_port;
	}else{
		ptr[0] = '\0';
		port = ptr + 1;
	}

	if(address[0] == '*') {
		address = NULL;
	}


	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = AI_PASSIVE;

	err = getaddrinfo(address, port, &hints, &addrs);
	if(err != 0) {
		stats_log("udpserver: getaddrinfo error: %s", gai_strerror(err));
		return 1;
	}

	for(p = addrs; p != NULL; p = p->ai_next) {
		if(server->listeners_len >= MAX_UDP_HANDLERS) {
			stats_log("udpserver: Unable to create more than %i UDP listeners", MAX_UDP_HANDLERS);
			freeaddrinfo(addrs);
			return 1;
		}
		if((address == NULL) && (p->ai_family != AF_INET6)) {
			continue;
		}
		listener = udplistener_create(server, p, cb_recv);
		if(listener == NULL) {
			continue;
		}
		server->listeners[server->listeners_len] = listener;
		server->listeners_len++;
		ev_io_start(server->loop, listener->watcher);
	}

	freeaddrinfo(addrs);
	return 0;
}
예제 #2
0
static void tcpclient_set_state(tcpclient_t *client, enum tcpclient_state state) {
	stats_log("tcpclient[%s]: State transition %s -> %s",
			client->name,
			tcpclient_state_name[client->state],
			tcpclient_state_name[state]);
	client->state = state;
}
예제 #3
0
// [[Rcpp::export]]
Rcpp::NumericVector summary_stats_log_c(Rcpp::IntegerMatrix mat,
                                          int dim,
                                          int n_cores){
  Rcpp::NumericVector stats_log(3);
  int edge = 0;
  double star2 = 0;
  double triangle = 0;
  double sum_star = 0;
  double sum_tria = 0;
  int k, l, p;

  // initialize number of different threads
  omp_set_num_threads(n_cores);

  for(k=0; k<dim; k++)
  {
    #pragma omp parallel for reduction(+:star2, sum_star, triangle, sum_tria, edge)
    for(l=0; l<dim; l++)
    {
      if(l > k)
      {
        edge = edge + mat(k,l);

        for(p=0; p<dim; p++)
        {
          if(p!=k & p!=l)
          {
            sum_star = sum_star + mat(k,p) + mat(l,p);
            sum_tria = sum_tria + mat(k,p) * mat(l,p);
          }
        }
        star2 = star2 + mat(k,l)*log(sum_star + 0.1); // log(change + 1)
        sum_star = 0;
        triangle = triangle + mat(k,l)*log(sum_tria + 0.1); // log(change + 1)
        sum_tria = 0;
      }
    }
  }
  star2 = star2/2;
  triangle = triangle/3;
  stats_log(0) = edge;
  stats_log(1) = star2;
  stats_log(2) = triangle;

  return stats_log;
}
void DataFlash_MAVLink::periodic_1Hz(const uint32_t now)
{
    if (_sending_to_client &&
        _last_response_time + 10000 < _last_send_time) {
        // other end appears to have timed out!
        Debug("Client timed out");
        _sending_to_client = false;
        return;
    }
    stats_log();
}
예제 #5
0
static void parse_server_list(const json_t* jshards, list_t ring) {
    if (jshards == NULL) {
	stats_error_log("no servers specified for routing");
	return;
    }

    const json_t* jserver = NULL;
    size_t index;
    json_array_foreach(jshards, index, jserver) {
	statsrelay_list_expand(ring);
	char* serverline = strdup(json_string_value(jserver));
	stats_log("adding server %s", serverline);
	ring->data[ring->size - 1] = serverline;
    }
예제 #6
0
void udplistener_recv_callback(struct ev_loop *loop, struct ev_io *watcher, int revents) {
	udplistener_t *listener;
	listener = (udplistener_t *)watcher->data;

	if(revents & EV_ERROR) {
		stats_log("udplistener: libev server socket error");
		return;
	}

	if(listener->cb_recv(listener->sd, listener->data) != 0) {
		//stats_log("udplistener: recv callback returned non-zero");
		return;
	}
}
예제 #7
0
static void tcpclient_write_event(struct ev_loop *loop, struct ev_io *watcher, int events) {
	tcpclient_t *client = (tcpclient_t *)watcher->data;
	buffer_t *sendq;

	if (!(events & EV_WRITE)) {
		return;
	}

	sendq = &client->send_queue;
	ssize_t buf_len = buffer_datacount(sendq);
	if (buf_len > 0) {
		ssize_t send_len = send(client->sd, sendq->head, buf_len, 0);
		stats_debug_log("tcpclient: sent %zd of %zd bytes to backend client %s via fd %d",
				send_len, buf_len, client->name, client->sd);
		if (send_len < 0) {
			stats_error_log("tcpclient[%s]: Error from send: %s", client->name, strerror(errno));
			ev_io_stop(client->loop, &client->write_watcher.watcher);
			ev_io_stop(client->loop, &client->read_watcher.watcher);
			client->last_error = time(NULL);
			tcpclient_set_state(client, STATE_BACKOFF);
			close(client->sd);
			client->callback_error(client, EVENT_ERROR, client->callback_context, NULL, 0);
			return;
		} else {
			client->callback_sent(client, EVENT_SENT, client->callback_context, sendq->head, (size_t) send_len);
			if (buffer_consume(sendq, send_len) != 0) {
				stats_error_log("tcpclient[%s]: Unable to consume send queue", client->name);
				return;
			}
			size_t qsize = buffer_datacount(&client->send_queue);
			if (client->failing && qsize < client->config->max_send_queue) {
				stats_log("tcpclient[%s]: client recovered from full queue, send queue is now %zd bytes",
					  client->name,
					  qsize);
				client->failing = 0;
			}
			if (qsize == 0) {
				ev_io_stop(client->loop, &client->write_watcher.watcher);
				client->write_watcher.started = false;
			}
		}
	} else {
		// No data left in the client's buffer, stop waiting
		// for write events.
		ev_io_stop(client->loop, &client->write_watcher.watcher);
		client->write_watcher.started = false;
	}
}
예제 #8
0
int validate_carbon(const char *line, size_t len) {
	int spaces_found = 0;
	const char *p = line;
	size_t n = len;
	while (1) {
		const char *s = memchr(p, ' ', n);
		if (s == NULL) {
			break;
		}
		spaces_found++;
		n = len - (s - line) - 1;
		p = s + 1;
		if (spaces_found > 2) {
			break;
		}
	}
	if (spaces_found != 2) {
		stats_log("validate: found %d spaces in invalid carbon line", spaces_found);
		return 1;
	}
	return 0;
}
예제 #9
0
int validate_statsd(const char *line, size_t len) {
	size_t plen;
	char c;
	int i, valid;

	// FIXME: this is dumb, don't do a memory copy
	char *line_copy = strndup(line, len);
	char *start, *end;
	char *err;

	start = line_copy;
	plen = len;
	end = memchr(start, ':', plen);
	if (end == NULL) {
		stats_log("validate: Invalid line \"%.*s\" missing ':'", len, line);
		goto statsd_err;
	}

	if ((end - start) < 1) {
		stats_log("validate: Invalid line \"%.*s\" zero length key", len, line);
		goto statsd_err;
	}

	start = end + 1;
	plen = len - (start - line_copy);

	c = end[0];
	end[0] = '\0';
	if ((strtod(start, &err) == 0.0) && (err == start)) {
		stats_log("validate: Invalid line \"%.*s\" unable to parse value as double", len, line);
		goto statsd_err;
	}
	end[0] = c;

	end = memchr(start, '|', plen);
	if (end == NULL) {
		stats_log("validate: Invalid line \"%.*s\" missing '|'", len, line);
		goto statsd_err;
	}

	start = end + 1;
	plen = len - (start - line_copy);

	end = memchr(start, '|', plen);
	if (end != NULL) {
		c = end[0];
		end[0] = '\0';
		plen = end - start;
	}

	valid = 0;
	for (i = 0; i < valid_stat_types_len; i++) {
		if (strlen(valid_stat_types[i]) != plen) {
			continue;
		}
		if (strncmp(start, valid_stat_types[i], plen) == 0) {
			valid = 1;
			break;
		}
	}

	if (valid == 0) {
		stats_log("validate: Invalid line \"%.*s\" unknown stat type \"%.*s\"", len, line, plen, start);
		goto statsd_err;
	}

	if (end != NULL) {
		end[0] = c;
		// end[0] is currently the second | char
		// test if we have at least 1 char following it (@)
		if ((len - (end - line_copy) > 1) && (end[1] == '@')) {
			start = end + 2;
			plen = len - (start - line_copy);
			if (plen == 0) {
				stats_log("validate: Invalid line \"%.*s\" @ sample with no rate", len, line);
				goto statsd_err;
			}
			if ((strtod(start, &err) == 0.0) && err == start) {
				stats_log("validate: Invalid line \"%.*s\" invalid sample rate", len, line);
				goto statsd_err;
			}
		} else {
			stats_log("validate: Invalid line \"%.*s\" no @ sample rate specifier", len, line);
			goto statsd_err;
		}
	}

	free(line_copy);
	return 0;

statsd_err:
	free(line_copy);
	return 1;
}
예제 #10
0
struct config* parse_config(FILE *input) {
	struct config *config = malloc(sizeof(struct config));
	if (config == NULL) {
		stats_error_log("malloc() error");
		return NULL;
	}

	init_proto_config(&config->carbon_config);
	if (config->carbon_config.ring == NULL) {
		stats_error_log("failed to allocate ring");
		free(config);
		return NULL;
	}
	config->carbon_config.bind = strdup("127.0.0.1:2003");

	init_proto_config(&config->statsd_config);
	config->statsd_config.bind = strdup("127.0.0.1:8125");

	yaml_parser_t parser;
	yaml_event_t event;

	if (!yaml_parser_initialize(&parser)) {
		stats_log("failed to initialize yaml parser");
		goto parse_err;
	}
	yaml_parser_set_input_file(&parser, input);

	struct proto_config *protoc = NULL;
	char *strval;
	long numval;
	int shard_count = -1;
	int map_nesting = 0;
	bool in_document = false;
	bool keep_going = true;
	bool is_key = false;
	bool update_bind = false;
	bool update_send_queue = false;
	bool update_validate = false;
	bool update_tcp_cork = false;
	bool always_resolve_dns = false;
	bool expect_shard_map = false;
	while (keep_going) {
		if (!yaml_parser_parse(&parser, &event)) {
			goto parse_err;
		}

		switch(event.type) {
		case YAML_NO_EVENT:
		case YAML_STREAM_START_EVENT:
			break;  // nothing to do
		case YAML_STREAM_END_EVENT:
			keep_going = false;
			break;
		case YAML_DOCUMENT_START_EVENT:
			if (in_document) {
				stats_error_log("config should not have nested documents");
				goto parse_err;
			}
			in_document = true;
			break;
		case YAML_DOCUMENT_END_EVENT:
			in_document = false;
			break;
		case YAML_SEQUENCE_START_EVENT:
		case YAML_SEQUENCE_END_EVENT:
			stats_error_log("unexpectedly got sequence");
			goto parse_err;
			break;
		case YAML_MAPPING_START_EVENT:
			is_key = true;
			map_nesting++;
			break;
		case YAML_MAPPING_END_EVENT:
			map_nesting--;
			break;
		case YAML_ALIAS_EVENT:
			stats_error_log("don't know how to handle yaml aliases");
			goto parse_err;
			break;
		case YAML_SCALAR_EVENT:
			strval = (char *) event.data.scalar.value;
			switch (map_nesting) {
			case 0:
				stats_error_log("unexpectedly got scalar outside of a map");
				goto parse_err;
				break;
			case 1:
				if (strcmp(strval, "carbon") == 0) {
					protoc = &config->carbon_config;
					config->carbon_config.initialized = true;
				} else if (strcmp(strval, "statsd") == 0) {
					protoc = &config->statsd_config;
					config->statsd_config.initialized = true;
				} else {
					stats_error_log("unexpectedly got map value: \"%s\"", strval);
					goto parse_err;
				}
				break;
			case 2:
				if (is_key) {
					if (strcmp(strval, "bind") == 0) {
						update_bind = true;
					} else if (strcmp(strval, "max_send_queue") == 0) {
						update_send_queue = true;
					} else if (strcmp(strval, "shard_map") == 0) {
						shard_count = -1;
						expect_shard_map = true;
					} else if (strcmp(strval, "validate") == 0) {
						update_validate = true;
					} else if (strcmp(strval, "tcp_cork") == 0) {
						update_tcp_cork = true;
					} else if (strcmp(strval, "always_resolve_dns") == 0) {
						always_resolve_dns = true;
					}
				} else {
					if (update_bind) {
						free(protoc->bind);
						protoc->bind = strdup(strval);
						update_bind = false;
					} else if (update_send_queue) {
						if (!convert_number(strval, &numval)) {
							stats_error_log("max_send_queue was not a number: %s", strval);
						}
						protoc->max_send_queue = numval;
						update_send_queue = false;
					} else if (update_validate) {
						if (!set_boolean(strval, &protoc->enable_validation)) {
							goto parse_err;
						}
						update_validate = false;
					} else if (update_tcp_cork) {
						if (!set_boolean(strval, &protoc->enable_tcp_cork)) {
							goto parse_err;
						}
						update_tcp_cork = false;
					} else if (always_resolve_dns) {
						if (!set_boolean(strval, &protoc->always_resolve_dns)) {
							goto parse_err;
						}
					}
				}
				break;
			case 3:
				if (!expect_shard_map) {
					stats_error_log("was not expecting shard map");
					goto parse_err;
				} else if (is_key) {
					if (!convert_number(strval, &numval)) {
						stats_error_log("shard key was not a number: \"%s\"", strval);
						goto parse_err;

					}
					shard_count++;
					if (numval != shard_count) {
						stats_error_log("expected to see shard key %d, instead saw %d",
							  shard_count, numval);
						goto parse_err;
					}
				} else {
					if (statsrelay_list_expand(protoc->ring) == NULL) {
						stats_error_log("unable to expand list");
						goto parse_err;
					}
					if ((protoc->ring->data[protoc->ring->size - 1]  = strdup(strval)) == NULL) {
						stats_error_log("failed to copy string");
						goto parse_err;
					}
				}
			}
			is_key = !is_key;
			break;
		default:
			stats_error_log("unhandled yaml event");
			goto parse_err;
		}
		yaml_event_delete(&event);
	}

	yaml_parser_delete(&parser);
	return config;

parse_err:
	destroy_config(config);
	yaml_event_delete(&event);
	yaml_parser_delete(&parser);
	return NULL;
}
예제 #11
0
udplistener_t *udplistener_create(udpserver_t *server, struct addrinfo *addr, int (*cb_recv)(int, void *)) {
	udplistener_t *listener;
	char addr_string[INET6_ADDRSTRLEN];
	void *ip;
	int port;
	int yes = 1;
	int err;

	listener = (udplistener_t *)malloc(sizeof(udplistener_t));
	listener->loop = server->loop;
	listener->data = server->data;
	listener->cb_recv = cb_recv;
	listener->sd = socket(
				addr->ai_family,
				addr->ai_socktype,
				addr->ai_protocol);

	memset(addr_string, 0, INET6_ADDRSTRLEN);
	if(addr->ai_family == AF_INET) {
		struct sockaddr_in *ipv4 = (struct sockaddr_in *)addr->ai_addr;
		ip = &(ipv4->sin_addr);
		port = ntohs(ipv4->sin_port);
	}else{
		struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)addr->ai_addr;
		ip = &(ipv6->sin6_addr);
		port = ntohs(ipv6->sin6_port);
	}
	if(inet_ntop(addr->ai_family, ip, addr_string, addr->ai_addrlen) == NULL) {
		stats_log("udplistener: Unable to format network address string");
		free(listener);
		return NULL;
	}

	if(listener->sd < 0) {
		stats_log("udplistener: Error creating socket %s[:%i]: %s", addr_string, port, strerror(errno));
		free(listener);
		return NULL;
	}

	err = setsockopt(listener->sd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
	if(err != 0) {
		stats_log("udplistener: Error setting SO_REUSEADDR on %s[:%i]: %s", addr_string, port, strerror(errno));
		free(listener);
		return NULL;
	}

	err = fcntl(listener->sd, F_SETFL, (fcntl(listener->sd, F_GETFL) | O_NONBLOCK));
	if(err != 0) {
		stats_log("udplistener: Error setting socket to non-blocking for %s[:%i]: %s", addr_string, port, strerror(errno));
		free(listener);
		return NULL;
	}

	err = bind(listener->sd, addr->ai_addr, addr->ai_addrlen);
	if(err != 0) {
		stats_log("udplistener: Error binding socket for %s[:%i]: %s", addr_string, port, strerror(errno));
		free(listener);
		return NULL;
	}

	listener->watcher = (struct ev_io *)malloc(sizeof(struct ev_io));
	listener->watcher->data = (void *)listener;

	ev_io_init(listener->watcher, udplistener_recv_callback, listener->sd, EV_READ);
	stats_log("udpserver: Listening on %s[:%i]", addr_string, port);

	return listener;
}
예제 #12
0
/**
 * Write zone to output adapter.
 *
 */
ods_status
tools_output(zone_type* zone, engine_type* engine)
{
    ods_status status = ODS_STATUS_OK;
    ods_log_assert(engine);
    ods_log_assert(engine->config);
    ods_log_assert(zone);
    ods_log_assert(zone->db);
    ods_log_assert(zone->name);
    ods_log_assert(zone->signconf);
    ods_log_assert(zone->adoutbound);
    /* prepare */
    if (zone->stats) {
        pthread_mutex_lock(&zone->stats->stats_lock);
        if (zone->stats->sort_done == 0 &&
            (zone->stats->sig_count <= zone->stats->sig_soa_count)) {
            ods_log_verbose("[%s] skip write zone %s serial %u (zone not "
                "changed)", tools_str, zone->name?zone->name:"(null)",
                zone->db->intserial);
            stats_clear(zone->stats);
            pthread_mutex_unlock(&zone->stats->stats_lock);
            zone->db->intserial =
                zone->db->outserial;
            return ODS_STATUS_OK;
        }
        pthread_mutex_unlock(&zone->stats->stats_lock);
    }
    /* Output Adapter */
    status = adapter_write((void*)zone);
    if (status != ODS_STATUS_OK) {
        ods_log_error("[%s] unable to write zone %s: adapter failed (%s)",
            tools_str, zone->name, ods_status2str(status));
        return status;
    }
    zone->db->outserial = zone->db->intserial;
    zone->db->is_initialized = 1;
    zone->db->have_serial = 1;
    pthread_mutex_lock(&zone->ixfr->ixfr_lock);
    ixfr_purge(zone->ixfr, zone->name);
    pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
    /* kick the nameserver */
    if (zone->notify_ns) {
	int pid_status;
        pid_t pid, wpid;
        ods_log_verbose("[%s] notify nameserver: %s", tools_str,
            zone->notify_ns);
	/** fork */
        switch ((pid = fork())) {
            case -1: /* error */
                ods_log_error("[%s] notify nameserver failed: unable to fork "
                    "(%s)", tools_str, strerror(errno));
                return ODS_STATUS_FORK_ERR;
            case 0: /* child */
                /** close fds */
		ods_closeall(0);
                /** execv */
                execvp(zone->notify_ns, zone->notify_args);
                /** error */
                ods_log_error("[%s] notify nameserver failed: execv() failed "
                    "(%s)", tools_str, strerror(errno));
                exit(1);
                break;
            default: /* parent */
                ods_log_debug("[%s] notify nameserver process forked",
                    tools_str);
                /** wait for completion  */
                while((wpid = waitpid(pid, &pid_status, 0)) <= 0) {
                    if (errno != EINTR) {
                        break;
                    }
                }
                if (wpid == -1) {
                    ods_log_error("[%s] notify nameserver failed: waitpid() "
                        "failed (%s)", tools_str, strerror(errno));
                } else if (!WIFEXITED(pid_status)) {
                    ods_log_error("[%s] notify nameserver failed: notify "
                        "command did not terminate normally", tools_str);
                } else {
                    ods_log_verbose("[%s] notify nameserver ok", tools_str);
                }
                break;
        }
    }
    /* log stats */
    if (zone->stats) {
        pthread_mutex_lock(&zone->stats->stats_lock);
        zone->stats->end_time = time(NULL);
        ods_log_debug("[%s] log stats for zone %s serial %u", tools_str,
            zone->name?zone->name:"(null)", (unsigned) zone->db->outserial);
        stats_log(zone->stats, zone->name, zone->db->outserial,
            zone->signconf->nsec_type);
        stats_clear(zone->stats);
        pthread_mutex_unlock(&zone->stats->stats_lock);
    }
    if (engine->dnshandler) {
        ods_log_debug("[%s] forward a notify", tools_str);
        dnshandler_fwd_notify(engine->dnshandler, (uint8_t*) ODS_SE_NOTIFY_CMD,
            strlen(ODS_SE_NOTIFY_CMD));
    }
    return status;
}