tcp: timestamp adjustment
[vpp.git] / src / vnet / tcp / tcp.h
index b0c3ecc..a13a30d 100644 (file)
@@ -130,6 +130,7 @@ extern timer_expiration_handler tcp_timer_retransmit_syn_handler;
   _(FINRCVD, "FIN received")                   \
   _(RATE_SAMPLE, "Conn does rate sampling")    \
   _(TRACK_BURST, "Track burst")                        \
+  _(ZERO_RWND_SENT, "Zero RWND sent")          \
 
 typedef enum _tcp_connection_flag_bits
 {
@@ -287,6 +288,11 @@ typedef enum _tcp_cc_ack_t
   TCP_CC_PARTIALACK
 } tcp_cc_ack_t;
 
+typedef enum tcp_cc_event_
+{
+  TCP_CC_EVT_START_TX,
+} tcp_cc_event_t;
+
 typedef struct _tcp_connection
 {
   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
@@ -371,6 +377,7 @@ typedef struct _tcp_connection
 
   u32 last_fib_check;  /**< Last time we checked fib route for peer */
   u16 mss;             /**< Our max seg size that includes options */
+  u32 timestamp_delta;
 } tcp_connection_t;
 
 /* *INDENT-OFF* */
@@ -378,13 +385,16 @@ struct _tcp_cc_algorithm
 {
   const char *name;
   uword (*unformat_cfg) (unformat_input_t * input);
+  void (*init) (tcp_connection_t * tc);
+  void (*cleanup) (tcp_connection_t * tc);
   void (*rcv_ack) (tcp_connection_t * tc, tcp_rate_sample_t *rs);
   void (*rcv_cong_ack) (tcp_connection_t * tc, tcp_cc_ack_t ack,
                        tcp_rate_sample_t *rs);
   void (*congestion) (tcp_connection_t * tc);
+  void (*loss) (tcp_connection_t * tc);
   void (*recovered) (tcp_connection_t * tc);
-  void (*init) (tcp_connection_t * tc);
-  void (*cleanup) (tcp_connection_t * tc);
+  void (*undo_recovery) (tcp_connection_t * tc);
+  void (*event) (tcp_connection_t *tc, tcp_cc_event_t evt);
 };
 /* *INDENT-ON* */
 
@@ -412,6 +422,10 @@ tcp_cong_recovery_off (tcp_connection_t * tc)
   tcp_fastrecovery_first_off (tc);
 }
 
+#define tcp_zero_rwnd_sent(tc) (tc)->flags &= TCP_CONN_ZERO_RWND_SENT
+#define tcp_zero_rwnd_sent_on(tc) (tc)->flags |= TCP_CONN_ZERO_RWND_SENT
+#define tcp_zero_rwnd_sent_off(tc) (tc)->flags &= ~TCP_CONN_ZERO_RWND_SENT
+
 typedef enum _tcp_error
 {
 #define tcp_error(n,s) TCP_ERROR_##n,
@@ -527,6 +541,10 @@ typedef struct _tcp_main
   /** Default MTU to be used when establishing connections */
   u16 default_mtu;
 
+  /** Initial CWND multiplier, which multiplies MSS to determine initial CWND.
+   *  Set 0 to determine the initial CWND by another way */
+  u16 initial_cwnd_multiplier;
+
   /** Number of preallocated connections */
   u32 preallocated_connections;
   u32 preallocated_half_open_connections;
@@ -682,6 +700,7 @@ void tcp_do_fastretransmits (tcp_worker_ctx_t * wrk);
 void tcp_program_ack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc);
 void tcp_program_dupack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc);
 void tcp_send_acks (tcp_worker_ctx_t * wrk);
+void tcp_send_window_update_ack (tcp_connection_t * tc);
 
 /*
  * Rate estimation
@@ -803,6 +822,9 @@ tcp_flight_size (const tcp_connection_t * tc)
 always_inline u32
 tcp_initial_cwnd (const tcp_connection_t * tc)
 {
+  if (tcp_main.initial_cwnd_multiplier > 0)
+    return tcp_main.initial_cwnd_multiplier * tc->snd_mss;
+
   if (tc->snd_mss > 2190)
     return 2 * tc->snd_mss;
   else if (tc->snd_mss > 1095)
@@ -887,7 +909,7 @@ int tcp_fast_retransmit_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
 int tcp_fast_retransmit (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
                         u32 burst_size);
 void tcp_cc_init_congestion (tcp_connection_t * tc);
-void tcp_cc_fastrecovery_exit (tcp_connection_t * tc);
+void tcp_cc_fastrecovery_clear (tcp_connection_t * tc);
 
 fib_node_index_t tcp_lookup_rmt_in_fib (tcp_connection_t * tc);
 
@@ -907,6 +929,16 @@ tcp_time_now_w_thread (u32 thread_index)
   return tcp_main.wrk_ctx[thread_index].time_now;
 }
 
+/**
+ * Generate timestamp for tcp connection
+ */
+always_inline u32
+tcp_tstamp (tcp_connection_t * tc)
+{
+  return (tcp_main.wrk_ctx[tc->c_thread_index].time_now -
+         tc->timestamp_delta);
+}
+
 always_inline f64
 tcp_time_now_us (u32 thread_index)
 {
@@ -945,6 +977,32 @@ tcp_cc_rcv_cong_ack (tcp_connection_t * tc, tcp_cc_ack_t ack_type,
   tc->cc_algo->rcv_cong_ack (tc, ack_type, rs);
 }
 
+static inline void
+tcp_cc_loss (tcp_connection_t * tc)
+{
+  tc->cc_algo->loss (tc);
+}
+
+static inline void
+tcp_cc_recovered (tcp_connection_t * tc)
+{
+  tc->cc_algo->recovered (tc);
+}
+
+static inline void
+tcp_cc_undo_recovery (tcp_connection_t * tc)
+{
+  if (tc->cc_algo->undo_recovery)
+    tc->cc_algo->undo_recovery (tc);
+}
+
+static inline void
+tcp_cc_event (tcp_connection_t * tc, tcp_cc_event_t evt)
+{
+  if (tc->cc_algo->event)
+    tc->cc_algo->event (tc, evt);
+}
+
 always_inline void
 tcp_timer_set (tcp_connection_t * tc, u8 timer_id, u32 interval)
 {