u32
tcp_initial_window_to_advertise (tcp_connection_t * tc)
{
+ tcp_main_t *tm = &tcp_main;
u32 max_fifo;
/* Initial wnd for SYN. Fifos are not allocated yet.
* Use some predefined value. For SYN-ACK we still want the
* scale to be computed in the same way */
- max_fifo = TCP_MAX_RX_FIFO_SIZE;
+ max_fifo = tm->max_rx_fifo ? tm->max_rx_fifo : TCP_MAX_RX_FIFO_SIZE;
tc->rcv_wscale = tcp_window_compute_scale (max_fifo);
tc->rcv_wnd = tcp_initial_wnd_unscaled (tc);
initial_wnd = tcp_initial_window_to_advertise (tc);
/* Make and write options */
- memset (&snd_opts, 0, sizeof (snd_opts));
+ clib_memset (&snd_opts, 0, sizeof (snd_opts));
tcp_opts_len = tcp_make_syn_options (&snd_opts, tc->rcv_wscale);
tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
tcp_header_t *th;
u16 initial_wnd;
- memset (snd_opts, 0, sizeof (*snd_opts));
+ clib_memset (snd_opts, 0, sizeof (*snd_opts));
tcp_reuse_buffer (vm, b);
initial_wnd = tcp_initial_window_to_advertise (tc);
u32 bi;
u8 fin_snt = 0;
- tcp_retransmit_timer_force_update (tc);
- if (PREDICT_FALSE (tcp_get_free_buffer_index (tm, &bi)))
- return;
- b = vlib_get_buffer (vm, bi);
- tcp_init_buffer (vm, b);
fin_snt = tc->flags & TCP_CONN_FINSNT;
if (fin_snt)
tc->snd_nxt = tc->snd_una;
+
+ if (PREDICT_FALSE (tcp_get_free_buffer_index (tm, &bi)))
+ {
+ /* Out of buffers so program fin retransmit ASAP */
+ tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 1);
+ goto post_enqueue;
+ }
+
+ tcp_retransmit_timer_force_update (tc);
+ b = vlib_get_buffer (vm, bi);
+ tcp_init_buffer (vm, b);
tcp_make_fin (tc, b);
tcp_enqueue_to_output_now (vm, b, bi, tc->c_is_ip4);
+ TCP_EVT_DBG (TCP_EVT_FIN_SENT, tc);
+
+post_enqueue:
if (!fin_snt)
{
tc->flags |= TCP_CONN_FINSNT;
{
tc->snd_nxt = tc->snd_una_max;
}
- TCP_EVT_DBG (TCP_EVT_FIN_SENT, tc);
}
always_inline u8