return ret;
}
+static void on_session_idle_timeout(uv_timer_t *timer)
+{
+ struct session *s = timer->data;
+ assert(s);
+ uv_timer_stop(timer);
+ if (s->sflags.closing) {
+ return;
+ }
+ /* session was not in use during timer timeout
+ * remove it from connection list and close
+ */
+ assert(session_is_empty(s));
+ session_close(s);
+}
+
+void session_kill_ioreq(struct session *s, struct qr_task *task)
+{
+ assert(s && s->sflags.outgoing && s->handle);
+ if (s->sflags.closing) {
+ return;
+ }
+ if (s->handle->type == UV_UDP) {
+ uv_timer_stop(&s->timeout);
+ session_tasklist_del(s, task);
+ assert(session_tasklist_is_empty(s));
+ session_close(s);
+ return;
+ }
+ /* TCP-specific code now. */
+ if (s->handle->type != UV_TCP) abort();
+ session_waitinglist_del(s, task);
+ session_tasklist_del(s, task);
+
+ int res = 0;
+
+ const struct sockaddr *peer = &s->peer.ip;
+ if (peer->sa_family != AF_UNSPEC && session_is_empty(s) && !s->sflags.closing) {
+ assert(peer->sa_family == AF_INET || peer->sa_family == AF_INET6);
+ res = 1;
+ if (s->sflags.connected) {
+ /* This is outbound TCP connection which can be reused.
+ * Close it after timeout */
+ s->timeout.data = s;
+ uv_timer_stop(&s->timeout);
+ res = uv_timer_start(&s->timeout, on_session_idle_timeout,
+ KR_CONN_RTT_MAX, 0);
+ }
+ }
+
+ if (res != 0) {
+ /* if any errors, close the session immediately */
+ session_close(s);
+ }
+}
+
const struct sockaddr *addr);
static struct session* worker_find_tcp_waiting(struct worker_ctx *worker,
const struct sockaddr *addr);
-static void on_session_idle_timeout(uv_timer_t *timer);
static void on_tcp_connect_timeout(uv_timer_t *timer);
static void on_tcp_watchdog_timeout(uv_timer_t *timer);
return handle;
}
-static void ioreq_kill_udp(uv_handle_t *req, struct qr_task *task)
-{
- assert(req);
- struct session *s = req->data;
- assert(session_is_outgoing(s));
- if (session_is_closing(s)) {
- return;
- }
- uv_timer_t *t = session_get_timer(s);
- uv_timer_stop(t);
- session_tasklist_del(s, task);
- assert(session_tasklist_is_empty(s));
- session_close(s);
-}
-
-static void ioreq_kill_tcp(uv_handle_t *req, struct qr_task *task)
-{
- assert(req);
- struct session *s = req->data;
- assert(session_is_outgoing(s));
- if (session_is_closing(s)) {
- return;
- }
-
- session_waitinglist_del(s, task);
- session_tasklist_del(s, task);
-
- int res = 0;
-
- const struct sockaddr *peer = session_get_peer(s);
- if (peer->sa_family != AF_UNSPEC && session_is_empty(s) && !session_is_closing(s)) {
- assert(peer->sa_family == AF_INET || peer->sa_family == AF_INET6);
- res = 1;
- if (session_is_connected(s)) {
- /* This is outbound TCP connection which can be reused.
- * Close it after timeout */
- uv_timer_t *t = session_get_timer(s);
- t->data = s;
- uv_timer_stop(t);
- res = uv_timer_start(t, on_session_idle_timeout,
- KR_CONN_RTT_MAX, 0);
- }
- }
-
- if (res != 0) {
- /* if any errors, close the session immediately */
- session_close(s);
- }
-}
-
static void ioreq_kill_pending(struct qr_task *task)
{
for (uint16_t i = 0; i < task->pending_count; ++i) {
- if (task->pending[i]->type == UV_UDP) {
- ioreq_kill_udp(task->pending[i], task);
- } else if (task->pending[i]->type == UV_TCP) {
- ioreq_kill_tcp(task->pending[i], task);
- } else {
- assert(false);
- }
+ session_kill_ioreq(task->pending[i]->data, task);
}
task->pending_count = 0;
}
qr_task_step(task, NULL, NULL);
}
-static void on_session_idle_timeout(uv_timer_t *timer)
-{
- struct session *s = timer->data;
- assert(s);
- uv_timer_stop(timer);
- if (session_is_closing(s)) {
- return;
- }
- /* session was not in use during timer timeout
- * remove it from connection list and close
- */
- assert(session_is_empty(s));
- session_close(s);
-}
-
static uv_handle_t *retransmit(struct qr_task *task)
{
uv_handle_t *ret = NULL;