Beispiel #1
0
static void stop_flow(struct request_stop_flow *request)
{
	DEBUG_MSG(LOG_DEBUG, "stop_flow forcefully unlocked mutex");
	pthread_mutex_unlock(&mutex);

	if (request->flow_id == -1) {
		/* Stop all flows */

		const struct list_node *node = fg_list_front(&flows);
		while (node) {
			struct flow *flow = node->data;
			node = node->next;

			flow->statistics[FINAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[FINAL].tcp_info)
					? 0 : 1;
			flow->pmtu = get_pmtu(flow->fd);

			if (flow->settings.reporting_interval)
				report_flow(flow, INTERVAL);
			report_flow(flow, FINAL);

			uninit_flow(flow);
			remove_flow(flow);
		}

		return;
	}

	const struct list_node *node = fg_list_front(&flows);
	while (node) {
		struct flow *flow = node->data;
		node = node->next;

		if (flow->id != request->flow_id)
			continue;

		/* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */
		flow->statistics[FINAL].has_tcp_info =
			get_tcp_info(flow,
				     &flow->statistics[FINAL].tcp_info)
				? 0 : 1;
		flow->pmtu = get_pmtu(flow->fd);

		if (flow->settings.reporting_interval)
			report_flow(flow, INTERVAL);
		report_flow(flow, FINAL);

		uninit_flow(flow);
		remove_flow(flow);
		return;
	}

	request_error(&request->r, "Unknown flow id");
}
Beispiel #2
0
static void stop_flow(struct _request_stop_flow *request)
{
	DEBUG_MSG(LOG_DEBUG, "stop_flow forcefully unlocked mutex");
	pthread_mutex_unlock(&mutex);

	if (request->flow_id == -1) {
		/* Stop all flows */

		for (unsigned int i = 0; i < num_flows; i++) {
			struct _flow *flow = &flows[i];

			flow->statistics[FINAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[FINAL].tcp_info)
					? 0 : 1;
			flow->pmtu = get_pmtu(flow->fd);

			if (flow->settings.reporting_interval)
				report_flow(flow, INTERVAL);
			report_flow(flow, FINAL);

			uninit_flow(flow);
			remove_flow(i);
		}

		return;
	}

	for (unsigned int i = 0; i < num_flows; i++) {
		struct _flow *flow = &flows[i];

		if (flow->id != request->flow_id)
			continue;

		/* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */
		flow->statistics[FINAL].has_tcp_info =
			get_tcp_info(flow,
				     &flow->statistics[FINAL].tcp_info)
				? 0 : 1;
		flow->pmtu = get_pmtu(flow->fd);

		if (flow->settings.reporting_interval)
			report_flow(flow, INTERVAL);
		report_flow(flow, FINAL);

		uninit_flow(flow);
		remove_flow(i);
		return;
	}

	request_error(&request->r, "Unknown flow id");
}
Beispiel #3
0
static void timer_check()
{
	struct timespec now;

	if (!started)
		return;

	gettime(&now);
	for (unsigned int i = 0; i < num_flows; i++) {
		struct _flow *flow = &flows[i];

		DEBUG_MSG(LOG_DEBUG, "processing timer_check() for flow %d",
			  flow->id);

		if (!flow->settings.reporting_interval)
			continue;

		if (!time_is_after(&now, &flow->next_report_time))
			continue;

		/* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */
		if (flow->fd != -1)
			flow->statistics[INTERVAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[INTERVAL].tcp_info)
					? 0 : 1;
		report_flow(flow, INTERVAL);

		do {
			time_add(&flow->next_report_time,
				 flow->settings.reporting_interval);
		} while (time_is_after(&now, &flow->next_report_time));
	}
	DEBUG_MSG(LOG_DEBUG, "finished timer_check()");
}
Beispiel #4
0
static void timer_check()
{
	struct timespec now;

	if (!started)
		return;

	gettime(&now);
	const struct list_node *node = fg_list_front(&flows);
	while (node) {
		struct flow *flow = node->data;
		node = node->next;

		DEBUG_MSG(LOG_DEBUG, "processing timer_check() for flow %d",
			  flow->id);

		if (!flow->settings.reporting_interval)
			continue;

		if (!time_is_after(&now, &flow->next_report_time))
			continue;

		/* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */
		if (flow->fd != -1)
			flow->statistics[INTERVAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[INTERVAL].tcp_info)
					? 0 : 1;
		report_flow(flow, INTERVAL);

		do {
			time_add(&flow->next_report_time,
				 flow->settings.reporting_interval);
		} while (time_is_after(&now, &flow->next_report_time));
	}
	DEBUG_MSG(LOG_DEBUG, "finished timer_check()");
}
Beispiel #5
0
static void process_select(fd_set *rfds, fd_set *wfds, fd_set *efds)
{
	unsigned int i = 0;
	while (i < num_flows) {

		struct _flow *flow = &flows[i];

		DEBUG_MSG(LOG_DEBUG, "processing pselect() for flow %d",
			  flow->id);

		if (flow->listenfd_data != -1 &&
		    FD_ISSET(flow->listenfd_data, rfds)) {
			DEBUG_MSG(LOG_DEBUG, "ready for accept");
			if (flow->state == GRIND_WAIT_ACCEPT) {
				if (accept_data(flow) == -1) {
					DEBUG_MSG(LOG_ERR, "accept_data() "
						  "failed");
					goto remove;
				}
			}
		}

		if (flow->fd != -1) {
			if (FD_ISSET(flow->fd, efds)) {
				int error_number, rc;
				socklen_t error_number_size =
					sizeof(error_number);
				DEBUG_MSG(LOG_DEBUG, "sock of flow %d in efds",
					  flow->id);
				rc = getsockopt(flow->fd, SOL_SOCKET,
						SO_ERROR,
						(void *)&error_number,
						&error_number_size);
				if (rc == -1) {
					warn("failed to get errno for"
					     "non-blocking connect");
					goto remove;
				}
				if (error_number != 0) {
					warnc(error_number, "connect");
					goto remove;
				}
			}
			if (FD_ISSET(flow->fd, wfds))
				if (write_data(flow) == -1) {
					DEBUG_MSG(LOG_ERR, "write_data() failed");
					goto remove;
				}

			if (FD_ISSET(flow->fd, rfds))
				if (read_data(flow) == -1) {
					DEBUG_MSG(LOG_ERR, "read_data() failed");
					goto remove;
				}
		}
		i++;
		continue;
remove:
		if (flow->fd != -1) {
			flow->statistics[FINAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[FINAL].tcp_info)
					? 0 : 1;
		}
		flow->pmtu = get_pmtu(flow->fd);
		report_flow(flow, FINAL);
		uninit_flow(flow);
		remove_flow(i);
		DEBUG_MSG(LOG_ERR, "removed flow %d", flow->id);
	}
}
Beispiel #6
0
static int prepare_fds() {

	DEBUG_MSG(LOG_DEBUG, "prepare_fds() called, num_flows: %d", num_flows);
	unsigned int i = 0;

	FD_ZERO(&rfds);
	FD_ZERO(&wfds);
	FD_ZERO(&efds);

	FD_SET(daemon_pipe[0], &rfds);
	maxfd = daemon_pipe[0];

	struct timespec now;
	gettime(&now);

	while (i < num_flows) {
		struct _flow *flow = &flows[i++];

		if (started &&
		    (flow->finished[READ] ||
		     !flow->settings.duration[READ] ||
		     (!flow_in_delay(&now, flow, READ) &&
		      !flow_sending(&now, flow, READ))) &&
		    (flow->finished[WRITE] ||
		     !flow->settings.duration[WRITE] ||
		     (!flow_in_delay(&now, flow, WRITE) &&
		      !flow_sending(&now, flow, WRITE)))) {

			/* On Other OSes than Linux or FreeBSD, tcp_info will contain all zeroes */
			flow->statistics[FINAL].has_tcp_info =
				get_tcp_info(flow,
					     &flow->statistics[FINAL].tcp_info)
					? 0 : 1;

			flow->pmtu = get_pmtu(flow->fd);

			if (flow->settings.reporting_interval)
				report_flow(flow, INTERVAL);
			report_flow(flow, FINAL);
			uninit_flow(flow);
			remove_flow(--i);
			continue;
		}

		if (flow->state == GRIND_WAIT_ACCEPT &&
		    flow->listenfd_data != -1) {
			FD_SET(flow->listenfd_data, &rfds);
			maxfd = MAX(maxfd, flow->listenfd_data);
		}

		if (!started)
			continue;

		if (flow->fd != -1) {
			FD_SET(flow->fd, &efds);
			maxfd = MAX(maxfd, flow->fd);
			prepare_wfds(&now, flow, &wfds);
			prepare_rfds(&now, flow, &rfds);
		}
	}

	return num_flows;
}