Example #1
0
/*
 * Handle socket events, such as connection failure or success.
 *   - BEV_EVENT_ERROR           - network is unreachable
 *   - BEV_EVENT_ERROR+READING   - connection refused or connection timed out
 *   - BEV_EVENT_TIMEOUT+READING - write timeout, if activated by
 *                                 bufferevent_set_timeouts
 */
static void
session_eventcb(struct bufferevent *bev, short what, void *thunk)
{
	struct session *session = thunk;
	switch (what & ~(BEV_EVENT_READING|BEV_EVENT_WRITING)) {
	case BEV_EVENT_CONNECTED:
		session_send(session);
		return;
	case BEV_EVENT_EOF:
		bufferevent_disable(bev, EV_READ|EV_WRITE);
		if (session->completed)
			target_mark(session->t, session->seq, '.');
		else
			target_mark(session->t, session->seq, '%');
		break;
	case BEV_EVENT_ERROR:
		bufferevent_disable(bev, EV_READ|EV_WRITE);
		target_mark(session->t, session->seq, '#');
		break;
	case BEV_EVENT_TIMEOUT:
		target_mark(session->t, session->seq, '?');
		break;
	}
	session_free(session);
}
Example #2
0
/*
 * Read response status. Attempt to read the status line, but if CRLF
 * can not be found in the first 2048 bytes, consider it an error and
 * disconnect. Once status line is read switch to draining the rest of
 * the data. The server should close the connection due to
 * "Connection: close" header otherwise it will be caught by timeout.
 *
 * Even though status line says 200, the actual success is registered
 * on socket close.
 */
static void
session_readcb_status(struct bufferevent *bev, void *thunk)
{
	struct session *session = thunk;
	struct evbuffer *evbuf = bufferevent_get_input(bev);
	size_t len;
	char *line;
	char *protocol;
	char *number;

	line = evbuffer_readln(evbuf, &len, EVBUFFER_EOL_CRLF);
	if (line == NULL) {
		if (evbuffer_get_length(evbuf) > 2048) {
			session_free(session);
			return;
		} else
			return; /* wait for more data */
	}
	/* Parse response line */
	protocol = strsep(&line, " ");
	if (line == NULL)
		return session_free(session);
	number = strsep(&line, " ");
	if (line == NULL)
		return session_free(session);
	(void)protocol;
	(void)number;
	switch (atoi(number)) {
	case 200:
		session->completed = 1;
		break;
	default:
		target_mark(session->t, session->seq, '%');
		break;
	}
	/* Drain the response on future callbacks */
	bufferevent_setcb(session->bev, session_readcb_drain, NULL,
	    session_eventcb, session);
}
Example #3
0
/*
 * Register status for send and "timed out" requests and send a probe.
 */
static void
target_probe(int fd, short what, void *thunk)
{
	struct target *t = thunk;

	/* Missed request */
	if (t->npkts > 0 && GETRES(t, -1) != '.') {
		if (GETRES(t, -1) == ' ')
			target_mark(t, t->npkts - 1, '?');
		if (A_flag == 1)
			(void)write(STDOUT_FILENO, "\a", 1);
		else if (A_flag >= 2 &&
		    GETRES(t, -4) == '.' &&
		    GETRES(t, -3) == '.' &&
		    GETRES(t, -2) != '.' &&
		    GETRES(t, -1) != '.')
			(void)write(STDOUT_FILENO, "\a", 1);
	}

	/* Check packet count limit */
	if (c_count && t->npkts >= c_count) {
		numcomplete++;
		event_del(t->ev_write);
		if (numcomplete >= numtargets) {
			event_base_loopexit(ev_base, NULL);
		}
		return;
	}

	/* Transmit request */
	t->res[t->npkts % NUM] = ' ';
	probe_send(t->prb, t->npkts);
	t->npkts++;

	ui_update(t);
}