All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sir_tcp_syncache.h
Go to the documentation of this file.
1 /*
2  * sir_tcp_syncache.h
3  *
4  * Created on: Apr 30, 2014
5  * Author: root
6  */
7  // Needed by doxygen
9 
10 #ifndef SIR_TCP_SYNCACHE_H_
11 #define SIR_TCP_SYNCACHE_H_
12 
13 #include <cvmx.h>
14 #include <cvmx-pow.h>
15 #include <cvmx-spinlock.h>
16 
18 #include "socket/sir_isocket.h"
19 
20 #define CVMX_FPA_SYNCACHE_POOL CVMX_FPA_PACKET_POOL
21 #define SYNCACHE_TIMER_INTERVAL 200 // Execute timer function every 200 ms
22 #define MAXSACKBLKS 4
23 #define PENDINGCONNPERBUCKET 3 // Maximum number of pending connections per bucket of the synchache hash table
24 #ifdef IXIATEST
25 #define MINRTO 2500 // Minimum RTO is 2500 ms during IXIA protocol tests
26 #else
27 #define MINRTO 1000 // Minimum RTO is 1000 ms
28 #endif
29 #define MAXRTO 60000 // Minimum RTO is 60000 ms
30 
31 #define DELAYEDACKTIME 100 // ACK will be delayed 100ms max
32 #define MSLTIMEx2 60000 // Maximum Segment Lifetime x 2
33 #ifdef IXIATEST
34 #define MAXLINGERTIME 300000 // Max time TCB will be valid after socket close
35 #define SYNCACHE_MAX_SETUP_TIME 300000 // Connection should be established in 300 secs
36 #define MSLTIME 25000 // Maximum Segment Lifetime
37 #define DEFAULTRECVTIMEOUT 1000000 // Default receive time out is 1000s when IXIA test running
38 #else
39 #define MAXLINGERTIME 30000 // Max time TCB will be valid after socket close
40 #define SYNCACHE_MAX_SETUP_TIME 30000 // Connection should be established in 30 secs
41 #define MSLTIME 30000 // Maximum Segment Lifetime
42 #define DEFAULTRECVTIMEOUT 100000 // Default receive time out is 100s
43 #endif
44 #define DEFAULTWINDOWSIZE (64*1024)-1 // Default receive window size is 65535
45 #define DEFAULTMSS 536 // Default MSS is 536 bytes (TCP/IP guide by Charles M. Kozierok, 2005, page 778)
46 #define MAXCWNDVALUE 1000000ul // Max value for snd_cwnd
47 
48 // TCP error codes
49 #define SIR_TCP_OK 0
50 #define SIR_TCP_NOHEADERSPACE 1 // No space for TCP header in buffer
51 #define SIR_TCP_NULLPOINTER 2 // No allocated memory
52 #define SIR_TCP_TOOMANYOPTIONS 3 // Generated too many options
53 #define SIR_TCP_NO_RESOURCES 4 // No memory available
54 #define SIR_TCP_EMPTY_RESOURCE 5 // Designated resource is empty
55 #define SIR_TCP_IP_ERROR 6 // Calling an IP function resulted in an error
56 
57 // Control flags in TCP header
58 #define SIR_TCP_FIN 0x01
59 #define SIR_TCP_SYN 0x02
60 #define SIR_TCP_RST 0x04
61 #define SIR_TCP_PSH 0x08
62 #define SIR_TCP_ACK 0x10
63 #define SIR_TCP_URG 0x20
64 #define SIR_TCP_UAC 0x50 // Urgent ACK, used to bypass delayed ACK (0x50 = 0x40 + 0x10)
65 
66 // Defines for KEEPALIVE
67 #define SIR_KEEPALIVE_IDLE 7200 // Default time in seconds before probing
68 #define SIR_KEEPALIVE_INTERV 75 // Default probe interval in seconds
69 #define SIR_KEEPALIVE_INIT 75 // Initial timeout value in seconds
70 #define SIR_KEEPALIVE_CNT 8 // Max probes before drop
71 
72 #define SYNCACHE_POW2 16 // exponent for Syncache Tashtable
73 #define SHADOWCACHE_POW2 12 // exponent for Shadow cache Tashtable
74 
75 // Macro for changing state of TCP session. ptTCB and eSessionState must be available!
76 #define TCP_CHANGE_STATE(new_state) \
77 ({ \
78  ptTCB->ePrevSynCacheState = eSessionState; \
79  ptTCB->eSynCacheState = new_state; \
80  SIR_COMMON_DEBUG_MSG(SIR_INFO_LEVEL_1, "Changing from state %d to state %d on %s:%d\n", (int)eSessionState, (int)(new_state),__FUNCTION__, __LINE__); \
81 })
82 
83 // Different states of TCP sessions
85 {
97 };
98 
100 {
107 };
108 
110 {
113  Read_Notify = 0x2,
114  Timer_Notify = 0x4, // 1000ms timer interval for application use
116  Reset_Rx_Notify = 0x10, // RST received from other side, connection terminated
117  Reset_Tx_Notify = 0x20, // RST sent to other side, connection terminated
118  Conn_Error = 0x40,
121 };
122 
124 {
127 };
128 
129 struct TSackList
130 {
133 };
135 {
138 };
139 
141 {
144 
150 
154  bool bIsIPV6;
157  uint16_t ui16MSS; // Maximum segment size
158  uint16_t ui16Window;
159 
160  // Interface parameters
161  uint16_t ui16VLAN;
162 
163  union
164  {
165  uint8_t ui8ControlBits;
166  struct
167  {
168  uint8_t bCWR:1;
169  uint8_t bECE:1;
170  uint8_t bURG:1;
171  uint8_t bACK:1;
172  uint8_t bPSH:1;
173  uint8_t bRST:1;
174  uint8_t bSYN:1;
175  uint8_t bFIN:1;
176  };
177  };
178  uint8_t ui8DataOffset;
179  uint8_t ui8WSOPT; // Windows scaling option
180 };
181 
183 {
184  uint32_t ui32SessionTag; // Tag under which SYN was received
185  bool bUserEvent; // Indicates that insert was triggered by a user event (eq. so_connect)
186  int fd; // File descriptor
187 };
188 
189 
191 {
192  TIPAddr tDestIP; // Contains previously used destination address
193  TIPAddr tSrcIP; // Contains previously used source address
194  int iPortNr; // Contains previously used port nr
195  int iArpIndex; // Contains index of entry in arp table
196  uint16_t ui16VLAN; // Contains previously used VLAN
197  uint64_t ui64DMAC; // Contains previously used destination MAC address
198  cvmx_rwlock_wp_lock_t tRWLock;
199 
200  void Init(void)
201  {
202  iPortNr = -1;
203  cvmx_rwlock_wp_init(&tRWLock);
204  };
205 
206  // Use a separate assign operator so tRWLock will not be overridden by assigning
208  {
209  tDestIP = tSrc.tDestIP;
210  tSrcIP = tSrc.tSrcIP;
211  iPortNr = tSrc.iPortNr;
212  iArpIndex = tSrc.iArpIndex;
213  ui16VLAN = tSrc.ui16VLAN;
214  ui64DMAC = tSrc.ui64DMAC;
215  return *this;
216  };
217 };
218 
220 {
223 
224  CSiriusMemList tRTXQueue; // Class that controls Retransmit queue
225  CSiriusMemList tTXQueue; // Class that controls Transmit queue
226  CSiriusMemList tRXQueue; // Class that controls Receive queue
227  CSiriusMemList tSocketRecList; // Entry to first packet in received packet list for the socket
228  CSiriusMemList tTxOverflowQueue; // Contains data that could not be transmitted
229 
230  sir_timer_t tMaxTCPLingerTime; // By this time, the state should be ESTABLISHED
231  sir_timer_t tMSL; // Max Segment Lifetime. This is the time the state will go from TIME-WAIT->CLOSED
232  sir_timer_t tStartKeepAliveTime; // Time the connection was initiated
233  sir_timer_t tLastMessageTimeOut; // Last time something was received on this connection
234  sir_timer_t tNextProbeTime; // Time for next keep alive probe
235  sir_timer_t tRcvTimeOut; // Maximum age in seconds of packets in RTX Queue
236 
237  // --- RTO calculations according to RFC2988 ----
238  sir_timer_t tSRTT; // Smoothed RTT
239  sir_timer_t tRTTVAR; // RTT Variance
240  sir_timer_t tRTTMax; // Max RTT during one timer interval
241  sir_timer_t tRTO; // Calculated RTO
242  // --- Zero probe time out
243  sir_timer_t tZeroProbeTime; // Time when a zero probe should be send
244  sir_timer_t tZeroProbeInterval; // Interval time between zero probes
245 
246  T5Tuple tTupleID; // Items for search in syncache table
247 
250 
251  TSendAccelerate tSendAccelerate; // Contains data so sending can be accelerated
252 
253  int listen_fd; // listen fd that generated this session
254  int fd; // file handle of this socket
255  int iPortIncoming; // Port on which incoming data was received
256  int iPortOut; // Port on which data should be send out
257  int iGrouipIncoming; // Group for which this data was intended
258  int iBytesInRTXQueue; // Nr of bytes that are in RTX queue including bytes in flight
259 
260  TIPAddr tSourceAddr; // Source address of this connection
261  TIPAddr tOrgSourceAddr; // Source address before overloaded by So_BindOverload
264  uint32_t ui32NotifyFlags; // Flags for notification from tcp to application
265  uint32_t ui32RetransmitCount; // Counts nr of times a segment has been retransmitted
266  uint32_t ui32PrevRetransmitCount;// Retransmit count the previous round
268 
269  bool bConnectionIsPending; // This connection is pending and is not completely acknowledged
270  bool bAccepted; // Session is accepted by socket
274  bool bNoDelay; // Disable Nagle's algorithm
275  bool bKeepAlive; // Keep alive packets will be send
276  bool bWindowIsZero; // Receive window has become closed
277  bool bNotSentAllData; // Not all data could be sent
278  bool bIsIPV6; // TCB is IPV6 type
279  bool bIsInDualStackMode; // TCB is in dual stack mode (IPV6 mode handling IPV4 traffic)
280  bool bMSSWasModified; // User changed MSS size of this TCB
281 
287  uint32_t snd_cwnd; // Congestion window (See RFC2001)
290  int i32RxBufferShorten; // Removed nr of bytes to make rcv_wnd zero when it drop below treshhold
291  uint32_t ssthresh; // Soft start threshold (see RFC2001)
292  uint32_t ui32NextExpSeq; // Next expected sequence. Needed to determine if new packet is out of order
293 
294  uint32_t TSRecent; // Timestamp to be echoed in TSecr
295  uint32_t TSLastAckSent; // Holds ACK field from last segment sent.
296 
297  uint16_t ui16SourcePort; // Source port of this connection
298  uint16_t ui16DestPort;
299  uint16_t ui16PeerWindowShift; // Scale option, received from peer
301  uint16_t ui16PeerMSS; // MSS value received from peer
302  uint16_t ui16MSS; // MSS to be send to peer
304  uint16_t ui16DuplicateACKCount; // Counts nr duplicate ACK's received
305  uint16_t ui16VLAN; // VLAN of this session
306 };
307 
309 {
310  friend class CSirius;
311 public:
312  void SynCache_Init(int iInstance);
313  sir_tcp_tcb* SynCache_Search(T5Tuple &tTupleID);
314  sir_tcp_tcb* SynCache_Insert(sir_tcp_tcb *pTCB, T5Tuple &tTupleID, sir_tcp_parse* ptTcpParse, bool bUserEvent);
315  bool SynCache_Remove(sir_tcp_tcb *ptTCB);
316  static bool SYNCache_Handle_Unused_Static(cvmx_wqe_t *pWQE, void *pThis);
317  static bool SYNCache_Handle_UnusedRTQ_Static(cvmx_wqe_t *pWQE, void *pThis);
318  int SYNCache_Send_TCP(sir_tcp_tcb *ptTCB, int iFlags, uint32_t ui32SEQ, uint32_t ui32ACK, sir_memlist_seg *ptMember, bool bRetransmit);
321  bool SynCache_SetSendWindow(uint32_t ui32ReceiveWindow);
322  int SynCache_CreateTCPHeader(CSiriusMemList *pMemList, sir_tcp_tcb *ptTCB, int iFlags, uint32_t ui32SEQ, uint32_t ui32ACK, int &iTCPHeaderSize);
323  static int SynCache_TCPOptionsHeaderSize(sir_tcp_tcb *ptTCB);
324 
325  virtual void Notification(sir_tcp_tcb *pTCB) = 0;
326  virtual bool Handle_TCP_Packet(sir_tcp_tcb *pTCB, sir_tcp_parse *tTcpParse, CSiriusMemList *ptMemList) = 0;
327  virtual void Update_Window(sir_tcp_tcb *ptTCB) = 0;
328  virtual bool RemoveSocket(int fd) = 0;
329 
330  static void FreeResourcesTCB(sir_tcp_tcb *ptTCB);
331  int GetAndAddResourcesInUse(int iIncrement);
332  int GetAndAddShadowResourcesInUse(int iIncrement);
333 
334  static int TCPHeaderSize();
335  static uint32_t CalcUsableWindow(sir_tcp_tcb *ptTCB, bool bAccountForRTXQueue = true);
336 
337  // Override of default keep alive parameters
338  CVMX_SHARED static int m_iTcp_KeepAlive_Probes;
339  CVMX_SHARED static int m_iTcp_KeepAlive_Time;
340  CVMX_SHARED static int m_iTcp_KeepAlive_IntVl;
341  CVMX_SHARED static int m_iTcp_KeepAlive_Idle;
342 
343  uint32_t m_ui32AcceptTag; // Tag of core when accept notifiction is called
344 
345 protected:
346  uint32_t GetISN();
347  bool ProcessRTXQueue(sir_tcp_tcb *ptTCB, bool bForceRetransmit);
348  bool UpdateRTTMax(sir_tcp_tcb *ptTCB, uint32_t ui32TimeStampEcho, sir_timer_t tOrgTime);
349  sir_timer_t GetRTO(sir_tcp_tcb *ptTCB); // Get Retransmit Timeout
350  void EnableTimeStamp(bool bTimeStampOn);
351  bool TimeStampEnabled();
352  void EnableSACK(bool bSACKOn);
353  bool SACKEnabled();
354 
356  CTashTable<T5Tuple, sizeof (sir_shadow_cache)> m_cShadowCache; // Hash table for all sockets that are pending
357 
358  uint32_t m_ui32InitialWindowSize; // 32 bits Receive window size
359  uint32_t m_ui32MinimumWindowsSize; // To avoid Silly Window Syndrome
361 
362  uint16_t m_ui16SegWinScale; // 16 bits Receive window scale factor
363 
366 
367 private:
368  // Bookkeeping for timer monitoring the session
369  struct sir_syncache_timer
370  {
371  uint64_t ui64Ticks;
372  T5Tuple tTupleID;
373  uint32_t ui32Interval;
374  };
375 
376  // Bookkeeping for the retransmit queue, stored in WQE
377  struct sir_wqe_rtq
378  {
379  T5Tuple tTupleID;
380  sir_timer_t tRTO; // Time packet was sent. Used for retransmit timeout.
381  bool bWasFastRetransmitted; // Each segment will be fast-retransmitted only once
382  bool bWasRetransmitted;
383  bool bOnlyTCPHeader; // Packet only has TCP header, no IP and ethernet header available
384  int iTCPHeaderSize; // Store TCP header size so we later know how big it was
385  uint8_t ui8ControlFlags; // Store the control flags of this member
386  };
387 
388  uint8_t m_ui8Unused;
389  uint8_t m_ui8Unused_RTQ; // Unused value, used for putting packets in Retransmit Queue
390 
391  bool SYNCache_Handle_Unused(cvmx_wqe_t *pWQE);
392  bool SYNCache_HandleRTQ_Unused(cvmx_wqe_t *pWQE);
393  sir_timer_t CalculateRTO(sir_tcp_tcb *ptTCB);
394  int SYNCache_ProcessTxQueue(sir_tcp_tcb *ptTCB, bool bSendAll);
395  void ProcessDelayedACK(sir_memlist_seg* ptMember);
396  bool ProcessKeepAlive(sir_tcp_tcb *ptTCB);
397  int CalculateMSS(sir_tcp_tcb *ptTCB);
398 };
399 
400 #endif /* SIR_TCP_SYNCACHE_H_ */
sir_timer_t tZeroProbeInterval
virtual void Update_Window(sir_tcp_tcb *ptTCB)=0
uint16_t ui16KeepAliveProbeCount
sir_timer_t tNextProbeTime
static int TCPHeaderSize()
uint32_t ui32TimeStampEchoReply
uint16_t ui16PeerMSS
virtual bool Handle_TCP_Packet(sir_tcp_tcb *pTCB, sir_tcp_parse *tTcpParse, CSiriusMemList *ptMemList)=0
TTimeStampBlock tTimeStamp
uint32_t m_ui32AcceptTag
uint16_t ui16ReceiveWindowShift
sir_timer_t tRcvTimeOut
TSackList tSackList
bool SynCache_Remove(sir_tcp_tcb *ptTCB)
sir_timer_t tRTTVAR
uint32_t ui32GroupIncoming
CSiriusMemList tTxOverflowQueue
sir_tcp_tcb * SynCache_Search_NewConnection(int fd)
uint16_t ui16MSS
void EnableTimeStamp(bool bTimeStampOn)
ETcp_User_Calls
CTashTable< T5Tuple, sizeof(sir_shadow_cache)> m_cShadowCache
static uint32_t CalcUsableWindow(sir_tcp_tcb *ptTCB, bool bAccountForRTXQueue=true)
uint32_t GetISN()
uint32_t ui32TimeStampValue
sir_timer_t tMaxTCPLingerTime
TIPAddr tSourceAddr
uint32_t m_ui32MinimumWindowsSize
bool TimeStampEnabled()
sir_timer_t tRTTMax
static bool SYNCache_Handle_UnusedRTQ_Static(cvmx_wqe_t *pWQE, void *pThis)
uint32_t snd_wnd
virtual bool RemoveSocket(int fd)=0
uint32_t ui32PrevRetransmitCount
cvmx_rwlock_wp_lock_t tRWLock
uint16_t ui16PeerWindowShift
uint16_t ui16DuplicateACKCount
ENotifyType
TIPAddr tOrgSourceAddr
sir_timer_t tZeroProbeTime
#define MAXSACKBLKS
static void FreeResourcesTCB(sir_tcp_tcb *ptTCB)
uint32_t snd_nxt
int GetAndAddResourcesInUse(int iIncrement)
static int SynCache_TCPOptionsHeaderSize(sir_tcp_tcb *ptTCB)
sir_timer_t tLastMessageTimeOut
uint32_t snd_una
uint32_t TSRecent
CSiriusMemList tRXQueue
uint16_t ui16SourcePort
Struct contains an IPV4 or an IPV6 address.
Definition: packet-defines.h:7
uint32_t snd_cwnd
static CVMX_SHARED int m_iTcp_KeepAlive_Probes
uint16_t m_ui16SegWinScale
uint32_t ui32RightEdge
sir_timer_t tRTO
uint32_t ssthresh
TSackBlock tSack_Block[MAXSACKBLKS]
uint32_t SynCache_Handle_ACK_RTQ(sir_tcp_tcb *pTCB, sir_tcp_parse *ptTcpParse)
sir_timer_t GetRTO(sir_tcp_tcb *ptTCB)
void * pMemList
Definition: sir_cmemlist.h:16
bool UpdateRTTMax(sir_tcp_tcb *ptTCB, uint32_t ui32TimeStampEcho, sir_timer_t tOrgTime)
sir_timer_t tSRTT
static CVMX_SHARED int m_iTcp_KeepAlive_Idle
uint16_t ui16VLAN
uint32_t rcv_nxt
virtual void Notification(sir_tcp_tcb *pTCB)=0
CTashTable< T5Tuple, sizeof(sir_tcp_tcb)> m_cSynCacheHash
uint32_t ui32RetransmitCount
uint8_t ui8ControlBits
uint32_t m_ui32InitialWindowSize
CSiriusMemList tRTXQueue
sir_tcp_tcb * SynCache_Insert(sir_tcp_tcb *pTCB, T5Tuple &tTupleID, sir_tcp_parse *ptTcpParse, bool bUserEvent)
bool ProcessRTXQueue(sir_tcp_tcb *ptTCB, bool bForceRetransmit)
CSiriusMemList tTXQueue
sir_timer_t tStartKeepAliveTime
uint64_t sir_timer_t
static CVMX_SHARED int m_iTcp_KeepAlive_IntVl
uint32_t ui32InitRecWindow
void SynCache_Init(int iInstance)
static CVMX_SHARED int m_iTcp_KeepAlive_Time
Sirius main class.
Definition: sir_socket.h:40
CSiriusMemList tSocketRecList
uint32_t ui32NotifyFlags
bool SynCache_SetSendWindow(uint32_t ui32ReceiveWindow)
uint32_t rcv_wnd
sir_timer_t tMSL
sir_tcp_tcb * SynCache_Search(T5Tuple &tTupleID)
uint32_t TSLastAckSent
TSackList tReceiveSackList
ETcp_Session_State eSynCacheState
bool bConnectionIsPending
uint32_t ui32LeftEdge
uint32_t ui32Tag
uint16_t ui16DestPort
Most important class of Sirius. Used to maintain and process all kinds of queues. ...
Definition: sir_memlist.h:51
ETcp_Session_State ePrevSynCacheState
uint32_t ui32HighestSACK
TSendAccelerate tSendAccelerate
TSackList tSendSackList
uint32_t ui32NextExpSeq
void EnableSACK(bool bSACKOn)
static bool SYNCache_Handle_Unused_Static(cvmx_wqe_t *pWQE, void *pThis)
int SynCache_CreateTCPHeader(CSiriusMemList *pMemList, sir_tcp_tcb *ptTCB, int iFlags, uint32_t ui32SEQ, uint32_t ui32ACK, int &iTCPHeaderSize)
uint32_t ui32PortIncoming
TSendAccelerate & operator=(const TSendAccelerate &tSrc)
int GetAndAddShadowResourcesInUse(int iIncrement)
int SYNCache_Send_TCP(sir_tcp_tcb *ptTCB, int iFlags, uint32_t ui32SEQ, uint32_t ui32ACK, sir_memlist_seg *ptMember, bool bRetransmit)
ETcp_Session_State