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"); }
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"); }
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()"); }
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()"); }
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); } }
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; }