static void http_poll_cb(struct http_conn *conn, void *arg) { struct http_ctx *ctx = arg; int code = http_conn_response_code(conn); if (code > 0) { c2_transport_reachable(ctx->t); } else { c2_transport_unreachable(ctx->t); } bool got_command = false; if (code == 200) { struct buffer_queue *q = http_conn_response_queue(conn); if (ctx->first_packet) { patch_uri(ctx, q); ctx->first_packet = 0; got_command = true; } else { size_t len; if (buffer_queue_len(q)) { got_command = true; c2_transport_ingress_queue(ctx->t, q); } } } if (got_command) { ctx->poll_timer.repeat = 0.01; } else { if (ctx->poll_timer.repeat < 0.1) { ctx->poll_timer.repeat = 0.1; } else if (ctx->poll_timer.repeat < 5.0) { ctx->poll_timer.repeat += 0.1; } } ctx->in_flight = 0; }
static void http_poll_timer_cb(struct ev_loop *loop, struct ev_timer *w, int revents) { struct http_ctx *ctx = w->data; if (!ctx->in_flight) { ctx->in_flight = 1; if (buffer_queue_len(ctx->egress) > 0) { ctx->data.content_len = buffer_queue_remove_all(ctx->egress, &ctx->data.content); http_request(ctx->uri, http_request_post, http_poll_cb, ctx, &ctx->data, &ctx->opts); ctx->data.content_len = 0; ctx->data.content = NULL; } else { http_request(ctx->uri, http_request_get, http_poll_cb, ctx, &ctx->data, &ctx->opts); } } if (ctx->running) { ev_timer_again(c2_transport_loop(ctx->t), &ctx->poll_timer); } }
size_t bufferev_bytes_available(struct bufferev *be) { return buffer_queue_len(be->rx_queue); }