return pool_elt_at_index (wrk->conn_pool, hc_index);
}
+static inline http_conn_t *
+http_conn_get_w_thread_if_valid (u32 hc_index, u32 thread_index)
+{
+ http_worker_t *wrk = http_worker_get (thread_index);
+ if (pool_is_free_index (wrk->conn_pool, hc_index))
+ return 0;
+ return pool_elt_at_index (wrk->conn_pool, hc_index);
+}
+
void
http_conn_free (http_conn_t *hc)
{
clib_warning ("disconnect returned");
}
+static void
+http_conn_invalidate_timer_cb (u32 hs_handle)
+{
+ http_conn_t *hc;
+
+ hc =
+ http_conn_get_w_thread_if_valid (hs_handle & 0x00FFFFFF, hs_handle >> 24);
+
+ HTTP_DBG (1, "hc [%u]%x", hs_handle >> 24, hs_handle & 0x00FFFFFF);
+ if (!hc)
+ {
+ HTTP_DBG (1, "already deleted");
+ return;
+ }
+
+ hc->timer_handle = HTTP_TIMER_HANDLE_INVALID;
+ hc->pending_timer = 1;
+}
+
static void
http_conn_timeout_cb (void *hc_handlep)
{
uword hs_handle;
hs_handle = pointer_to_uword (hc_handlep);
- hc = http_conn_get_w_thread (hs_handle & 0x00FFFFFF, hs_handle >> 24);
+ hc =
+ http_conn_get_w_thread_if_valid (hs_handle & 0x00FFFFFF, hs_handle >> 24);
- HTTP_DBG (1, "terminate thread %d index %d hs %llx", hs_handle >> 24,
- hs_handle & 0x00FFFFFF, hc);
+ HTTP_DBG (1, "hc [%u]%x", hs_handle >> 24, hs_handle & 0x00FFFFFF);
if (!hc)
- return;
+ {
+ HTTP_DBG (1, "already deleted");
+ return;
+ }
+
+ if (!hc->pending_timer)
+ {
+ HTTP_DBG (1, "timer not pending");
+ return;
+ }
- hc->timer_handle = ~0;
session_transport_closing_notify (&hc->connection);
http_disconnect_transport (hc);
}
hc_index = http_conn_alloc_w_thread (ts->thread_index);
hc = http_conn_get_w_thread (hc_index, ts->thread_index);
clib_memcpy_fast (hc, lhc, sizeof (*lhc));
+ hc->timer_handle = HTTP_TIMER_HANDLE_INVALID;
hc->c_thread_index = ts->thread_index;
hc->h_hc_index = hc_index;
clib_memcpy_fast (hc, ho_hc, sizeof (*hc));
+ hc->timer_handle = HTTP_TIMER_HANDLE_INVALID;
hc->c_thread_index = ts->thread_index;
hc->h_tc_session_handle = session_handle (ts);
hc->c_c_index = new_hc_index;
as->session_type = session_type_from_proto_and_ip (
TRANSPORT_PROTO_HTTP, session_type_is_ip4 (ts->session_type));
- HTTP_DBG (1, "half-open hc index %d, hc index %d", ho_hc_index,
- new_hc_index);
+ HTTP_DBG (1, "half-open hc index %x, hc [%u]%x", ho_hc_index,
+ ts->thread_index, new_hc_index);
app_wrk = app_worker_get (hc->h_pa_wrk_index);
if (!app_wrk)
now = clib_timebase_now (&hm->timebase);
data = format (0, http_error_template, http_status_code_str[ec],
format_clib_timebase_time, now);
- HTTP_DBG (1, "%v", data);
+ HTTP_DBG (3, "%v", data);
http_send_data (hc, data, vec_len (data));
vec_free (data);
}
*ec = HTTP_STATUS_BAD_REQUEST;
return -1;
}
- HTTP_DBG (0, "request line length: %d", i);
+ HTTP_DBG (2, "request line length: %d", i);
hc->control_data_len = i + 2;
next_line_offset = hc->control_data_len;
}
/* parse request-target */
- HTTP_DBG (0, "http at %d", i);
+ HTTP_DBG (2, "http at %d", i);
target_len = i - hc->target_path_offset;
- HTTP_DBG (0, "target_len %d", target_len);
+ HTTP_DBG (2, "target_len %d", target_len);
if (target_len < 1)
{
clib_warning ("request-target not present");
*ec = HTTP_STATUS_BAD_REQUEST;
return -1;
}
- HTTP_DBG (0, "request-target path length: %u", hc->target_path_len);
- HTTP_DBG (0, "request-target path offset: %u", hc->target_path_offset);
- HTTP_DBG (0, "request-target query length: %u", hc->target_query_len);
- HTTP_DBG (0, "request-target query offset: %u", hc->target_query_offset);
+ HTTP_DBG (2, "request-target path length: %u", hc->target_path_len);
+ HTTP_DBG (2, "request-target path offset: %u", hc->target_path_offset);
+ HTTP_DBG (2, "request-target query length: %u", hc->target_query_len);
+ HTTP_DBG (2, "request-target query offset: %u", hc->target_query_offset);
/* set buffer offset to nex line start */
hc->rx_buf_offset = next_line_offset;
clib_warning ("status line incomplete");
return -1;
}
- HTTP_DBG (0, "status line length: %d", i);
+ HTTP_DBG (2, "status line length: %d", i);
if (i < 12)
{
clib_warning ("status line too short (%d)", i);
(hc->rx_buf[hc->rx_buf_offset + 1] == '\n'))
{
/* just another CRLF -> no headers */
- HTTP_DBG (0, "no headers");
+ HTTP_DBG (2, "no headers");
hc->headers_len = 0;
hc->control_data_len += 2;
return 0;
hc->headers_offset = hc->rx_buf_offset;
hc->headers_len = i - hc->rx_buf_offset + 2;
hc->control_data_len += (hc->headers_len + 2);
- HTTP_DBG (0, "headers length: %u", hc->headers_len);
- HTTP_DBG (0, "headers offset: %u", hc->headers_offset);
+ HTTP_DBG (2, "headers length: %u", hc->headers_len);
+ HTTP_DBG (2, "headers offset: %u", hc->headers_offset);
return 0;
}
if (hc->headers_len == 0)
{
- HTTP_DBG (0, "no header, no message-body");
+ HTTP_DBG (2, "no header, no message-body");
return 0;
}
"Content-Length:");
if (i < 0)
{
- HTTP_DBG (0, "Content-Length header not present, no message-body");
+ HTTP_DBG (2, "Content-Length header not present, no message-body");
return 0;
}
hc->rx_buf_offset = i + 15;
line = vec_new (u8, len);
clib_memcpy (line, hc->rx_buf + hc->rx_buf_offset, len);
- HTTP_DBG (0, "%v", line);
+ HTTP_DBG (3, "%v", line);
unformat_init_vector (&input, line);
if (!unformat (&input, "%llu", &body_len))
hc->body_len = body_len;
hc->body_offset = hc->headers_offset + hc->headers_len + 2;
- HTTP_DBG (0, "body length: %llu", hc->body_len);
- HTTP_DBG (0, "body offset: %u", hc->body_offset);
+ HTTP_DBG (2, "body length: %llu", hc->body_len);
+ HTTP_DBG (2, "body offset: %u", hc->body_offset);
return 0;
}
return HTTP_SM_STOP;
}
- HTTP_DBG (0, "%v", hc->rx_buf);
+ HTTP_DBG (3, "%v", hc->rx_buf);
if (vec_len (hc->rx_buf) < 8)
{
if (rv)
return HTTP_SM_STOP;
- HTTP_DBG (0, "%v", hc->rx_buf);
+ HTTP_DBG (3, "%v", hc->rx_buf);
if (vec_len (hc->rx_buf) < 8)
{
ASSERT (rv == msg.data.headers_len);
}
}
- HTTP_DBG (0, "%v", response);
+ HTTP_DBG (3, "%v", response);
sent = http_send_data (hc, response, vec_len (response));
if (sent != vec_len (response))
ASSERT (rv == msg.data.headers_len);
}
}
- HTTP_DBG (0, "%v", request);
+ HTTP_DBG (3, "%v", request);
sent = http_send_data (hc, request, vec_len (request));
if (sent != vec_len (request))
{
http_conn_t *hc;
+ HTTP_DBG (1, "hc [%u]%x", ts->thread_index, ts->opaque);
+
hc = http_conn_get_w_thread (ts->opaque, ts->thread_index);
- if (!hc)
+
+ if (hc->state == HTTP_CONN_STATE_CLOSED)
{
- clib_warning ("http connection not found (ts %d)", ts->opaque);
- return -1;
+ HTTP_DBG (1, "conn closed");
+ svm_fifo_dequeue_drop_all (ts->tx_fifo);
+ return 0;
}
if (!http_state_is_rx_valid (hc))
return;
hc = http_conn_get_w_thread (ts->opaque, ts->thread_index);
- if (!hc)
- {
- clib_warning ("no http connection for %u", ts->session_index);
- return;
- }
- HTTP_DBG (1, "going to free session %x", ts->opaque);
+
+ HTTP_DBG (1, "going to free hc [%u]%x", ts->thread_index, ts->opaque);
vec_free (hc->rx_buf);
http_buffer_free (&hc->tx_buf);
- http_conn_timer_stop (hc);
+
+ if (hc->pending_timer == 0)
+ http_conn_timer_stop (hc);
session_transport_delete_notify (&hc->connection);
clib_timebase_init (&hm->timebase, 0 /* GMT */, CLIB_TIMEBASE_DAYLIGHT_NONE,
&vm->clib_time /* share the system clock */);
- http_timers_init (vm, http_conn_timeout_cb);
+ http_timers_init (vm, http_conn_timeout_cb, http_conn_invalidate_timer_cb);
hm->is_init = 1;
return 0;
session_t *as;
http_conn_t *hc;
- HTTP_DBG (1, "App disconnecting %x", hc_index);
+ HTTP_DBG (1, "App disconnecting [%u]%x", thread_index, hc_index);
hc = http_conn_get_w_thread (hc_index, thread_index);
if (hc->state == HTTP_CONN_STATE_CONNECTING)
u32 max_burst_sz, sent;
http_conn_t *hc;
- HTTP_DBG (1, "app session conn index %x", as->connection_index);
+ HTTP_DBG (1, "hc [%u]%x", as->thread_index, as->connection_index);
hc = http_conn_get_w_thread (as->connection_index, as->thread_index);
if (!http_state_is_tx_valid (hc))
{
if (hc->state != HTTP_CONN_STATE_CLOSED)
- clib_warning ("app data req state '%U' session state %u",
- format_http_state, hc->http_state, hc->state);
+ {
+ clib_warning ("hc [%u]%x invalid tx state http state "
+ "'%U', session state %u",
+ as->thread_index, as->connection_index,
+ format_http_state, hc->http_state, hc->state);
+ }
svm_fifo_dequeue_drop_all (as->tx_fifo);
return 0;
}