Session layer improvements
[vpp.git] / src / vnet / tcp / tcp.c
index c3df5bc..245a35a 100644 (file)
@@ -34,14 +34,19 @@ tcp_connection_bind (u32 session_index, ip46_address_t * ip,
   listener->c_lcl_port = clib_host_to_net_u16 (port_host_byte_order);
 
   if (is_ip4)
-    listener->c_lcl_ip4.as_u32 = ip->ip4.as_u32;
+    {
+      listener->c_lcl_ip4.as_u32 = ip->ip4.as_u32;
+      listener->c_is_ip4 = 1;
+      listener->c_proto = SESSION_TYPE_IP4_TCP;
+    }
   else
-    clib_memcpy (&listener->c_lcl_ip6, &ip->ip6, sizeof (ip6_address_t));
+    {
+      clib_memcpy (&listener->c_lcl_ip6, &ip->ip6, sizeof (ip6_address_t));
+      listener->c_proto = SESSION_TYPE_IP6_TCP;
+    }
 
   listener->c_s_index = session_index;
-  listener->c_proto = SESSION_TYPE_IP4_TCP;
   listener->state = TCP_STATE_LISTEN;
-  listener->c_is_ip4 = 1;
 
   tcp_connection_timers_init (listener);
 
@@ -62,7 +67,6 @@ tcp_session_bind_ip6 (u32 session_index, ip46_address_t * ip,
                      u16 port_host_byte_order)
 {
   return tcp_connection_bind (session_index, ip, port_host_byte_order, 0);
-
 }
 
 static void
@@ -397,6 +401,7 @@ tcp_connection_open (ip46_address_t * rmt_addr, u16 rmt_port, u8 is_ip4)
   tc->c_lcl_port = clib_host_to_net_u16 (lcl_port);
   tc->c_c_index = tc - tm->half_open_connections;
   tc->c_is_ip4 = is_ip4;
+  tc->c_proto = is_ip4 ? SESSION_TYPE_IP4_TCP : SESSION_TYPE_IP6_TCP;
 
   /* The other connection vars will be initialized after SYN ACK */
   tcp_connection_timers_init (tc);
@@ -442,7 +447,7 @@ format_tcp_state (u8 * s, va_list * args)
   if (*state < TCP_N_STATES)
     s = format (s, "%s", tcp_fsm_states[*state]);
   else
-    s = format (s, "UNKNOWN");
+    s = format (s, "UNKNOWN (%d (0x%x))", *state, *state);
 
   return s;
 }
@@ -482,7 +487,8 @@ u8 *
 format_tcp_connection (u8 * s, va_list * args)
 {
   tcp_connection_t *tc = va_arg (*args, tcp_connection_t *);
-
+  if (!tc)
+    return s;
   if (tc->c_is_ip4)
     {
       s = format (s, "[#%d][%s] %U:%d->%U:%d", tc->c_thread_index, "T",
@@ -518,7 +524,10 @@ format_tcp_session (u8 * s, va_list * args)
   tcp_connection_t *tc;
 
   tc = tcp_connection_get (tci, thread_index);
-  return format (s, "%U", format_tcp_connection, tc);
+  if (tc)
+    return format (s, "%U", format_tcp_connection, tc);
+  else
+    return format (s, "empty");
 }
 
 u8 *
@@ -578,7 +587,9 @@ tcp_session_send_space (transport_connection_t * trans_conn)
       /* If we can't write at least a segment, don't try at all */
       if (snd_space < tc->snd_mss)
        return 0;
-      return snd_space;
+
+      /* round down to mss multiple */
+      return snd_space - (snd_space % tc->snd_mss);
     }
 
   /* If in fast recovery, send 1 SMSS if wnd allows */
@@ -644,10 +655,10 @@ const static transport_proto_vft_t tcp6_proto = {
 void
 tcp_timer_keep_handler (u32 conn_index)
 {
-  u32 cpu_index = os_get_cpu_number ();
+  u32 thread_index = vlib_get_thread_index ();
   tcp_connection_t *tc;
 
-  tc = tcp_connection_get (conn_index, cpu_index);
+  tc = tcp_connection_get (conn_index, thread_index);
   tc->timers[TCP_TIMER_KEEP] = TCP_TIMER_HANDLE_INVALID;
 
   tcp_connection_close (tc);
@@ -673,10 +684,10 @@ tcp_timer_establish_handler (u32 conn_index)
 void
 tcp_timer_waitclose_handler (u32 conn_index)
 {
-  u32 cpu_index = os_get_cpu_number ();
+  u32 thread_index = vlib_get_thread_index ();
   tcp_connection_t *tc;
 
-  tc = tcp_connection_get (conn_index, cpu_index);
+  tc = tcp_connection_get (conn_index, thread_index);
   tc->timers[TCP_TIMER_WAITCLOSE] = TCP_TIMER_HANDLE_INVALID;
 
   /* Session didn't come back with a close(). Send FIN either way
@@ -706,7 +717,7 @@ static timer_expiration_handler *timer_expiration_handlers[TCP_N_TIMERS] =
 {
     tcp_timer_retransmit_handler,
     tcp_timer_delack_handler,
-    0,
+    tcp_timer_persist_handler,
     tcp_timer_keep_handler,
     tcp_timer_waitclose_handler,
     tcp_timer_retransmit_syn_handler,
@@ -737,12 +748,14 @@ void
 tcp_initialize_timer_wheels (tcp_main_t * tm)
 {
   tw_timer_wheel_16t_2w_512sl_t *tw;
-  vec_foreach (tw, tm->timer_wheels)
-  {
+  /* *INDENT-OFF* */
+  foreach_vlib_main (({
+    tw = &tm->timer_wheels[ii];
     tw_timer_wheel_init_16t_2w_512sl (tw, tcp_expired_timers_dispatch,
                                      100e-3 /* timer period 100ms */ , ~0);
-    tw->last_run_time = vlib_time_now (tm->vlib_main);
-  }
+    tw->last_run_time = vlib_time_now (this_vlib_main);
+  }));
+  /* *INDENT-ON* */
 }
 
 clib_error_t *