while (to_deq > 0)
{
/* read datagram header */
- http_io_as_read (req, (u8 *) &hdr, sizeof (hdr), 1);
+ http_io_as_peek (req, (u8 *) &hdr, sizeof (hdr), 0);
ASSERT (hdr.data_length <= HTTP_UDP_PAYLOAD_MAX_LEN);
dgram_size = hdr.data_length + SESSION_CONN_HDR_LEN;
ASSERT (to_deq >= dgram_size);
payload = http_encap_udp_payload_datagram (buf, hdr.data_length);
capsule_size = (payload - buf) + hdr.data_length;
/* read payload */
- http_io_as_read (req, payload, hdr.data_length, 1);
+ http_io_as_peek (req, payload, hdr.data_length, sizeof (hdr));
http_io_as_drain (req, dgram_size);
/* send capsule */
http_io_ts_write (hc, buf, capsule_size, sp);
http_io_as_drain (&req->base, n_written);
req->peer_window -= n_written;
h2c->peer_window -= n_written;
+ HTTP_DBG (1, "written %lu", n_written);
if (req->peer_window == 0)
{
return;
}
/* read datagram header */
- http_io_as_read (&req->base, (u8 *) &hdr, sizeof (hdr), 1);
+ http_io_as_peek (&req->base, (u8 *) &hdr, sizeof (hdr), 0);
+ HTTP_DBG (1, "datagram len %lu", hdr.data_length);
ASSERT (hdr.data_length <= HTTP_UDP_PAYLOAD_MAX_LEN);
dgram_size = hdr.data_length + SESSION_CONN_HDR_LEN;
ASSERT (max_read >= dgram_size);
h2c->peer_settings.max_frame_size))
{
/* drop datagram if not fit into frame */
- HTTP_DBG (1, "datagram too large, dropped");
+ HTTP_DBG (1, "datagram larger than maximum frame size, dropped");
http_io_as_drain (&req->base, dgram_size);
return;
}
if (req->peer_window <
(hdr.data_length + HTTP_UDP_PROXY_DATAGRAM_CAPSULE_OVERHEAD))
{
+ HTTP_DBG (1, "not enough space in stream window (%lu) for capsule",
+ req->peer_window);
/* mark that we need window update on stream */
- HTTP_DBG (1, "not enough space in stream window for capsule");
req->flags |= HTTP2_REQ_F_NEED_WINDOW_UPDATE;
+ return;
}
max_write = http_io_ts_max_write (hc, 0);
payload = http_encap_udp_payload_datagram (buf, hdr.data_length);
capsule_size = (payload - buf) + hdr.data_length;
/* read payload */
- http_io_as_read (&req->base, payload, hdr.data_length, 1);
+ http_io_as_peek (&req->base, payload, hdr.data_length, sizeof (hdr));
http_io_as_drain (&req->base, dgram_size);
req->peer_window -= capsule_size;
{ buf, capsule_size } };
n_written = http_io_ts_write_segs (hc, segs, 2, 0);
ASSERT (n_written == (HTTP2_FRAME_HEADER_SIZE + capsule_size));
+ HTTP_DBG (1, "capsule payload len %lu", hdr.data_length);
if (max_read - dgram_size)
{
{
u32 max_enq;
- HTTP_DBG (1, "tunnel received data from client");
+ HTTP_DBG (1, "tunnel received data from peer");
max_enq = http_io_as_max_write (&req->base);
if (max_enq < req->payload_len)
ASSERT (!clib_llist_elt_is_linked (req, sched_list));
- HTTP_DBG (1, "tunnel received data from target");
+ HTTP_DBG (1, "tunnel received data from app");
/* add data back to stream scheduler */
HTTP_DBG (1, "adding to data queue req_index %x",
HTTP_DBG (1, "received app read notification stream id %u", req->stream_id);
/* send stream window update if app read data in rx fifo and we expect more
* data (stream is still open) */
- expected_state = hc->flags & HTTP_CONN_F_IS_SERVER ?
+ expected_state = (hc->flags & HTTP_CONN_F_IS_SERVER || req->base.is_tunnel) ?
HTTP2_STREAM_STATE_OPEN :
HTTP2_STREAM_STATE_HALF_CLOSED;
if (req->stream_state == expected_state)
if (PREDICT_FALSE (to_deq < HTTP2_FRAME_HEADER_SIZE))
{
HTTP_DBG (1, "to_deq %u is less than frame header size", to_deq);
+#if HTTP_DEBUG
+ u8 *tmp = 0;
+ vec_validate (tmp, to_deq - 1);
+ http_io_ts_read (hc, tmp, to_deq, 0);
+ clib_warning ("%U", format_hex_bytes, tmp, to_deq);
+#endif
http2_connection_error (hc, HTTP2_ERROR_PROTOCOL_ERROR, 0);
return;
}
#define hr_hc_index c_http_req_id.hc_index
#define hr_req_handle connection.c_index
- u32 as_fifo_offset; /* for peek */
-
http_req_state_t state; /* state-machine state */
http_buffer_t tx_buf; /* message body from app to be sent */
}
always_inline u32
-http_io_as_read (http_req_t *req, u8 *buf, u32 len, u8 peek)
+http_io_as_peek (http_req_t *req, u8 *buf, u32 len, u32 offset)
{
int n_read;
session_t *as = session_get_from_handle (req->hr_pa_session_handle);
- if (peek)
- {
- n_read = svm_fifo_peek (as->tx_fifo, req->as_fifo_offset, len, buf);
- ASSERT (n_read > 0);
- req->as_fifo_offset += len;
- return (u32) n_read;
- }
-
- n_read = svm_fifo_dequeue (as->tx_fifo, len, buf);
- ASSERT (n_read == len);
+ n_read = svm_fifo_peek (as->tx_fifo, offset, len, buf);
+ ASSERT (n_read > 0);
return (u32) n_read;
}
{
session_t *as = session_get_from_handle (req->hr_pa_session_handle);
svm_fifo_dequeue_drop (as->tx_fifo, len);
- req->as_fifo_offset = 0;
}
always_inline void
{
session_t *as = session_get_from_handle (req->hr_pa_session_handle);
svm_fifo_dequeue_drop_all (as->tx_fifo);
- req->as_fifo_offset = 0;
}
always_inline void