1 #pragma once
2 
3 #include <stdio.h>
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <sys/queue.h>
7 #include <memory_mgt.h>
8 #include "mos_api.h"
9 
10 /* Abstract ring buffer as an infinite but windowed buffer */
11 /* Keep in mind about inc/dec buffer */
12 /* FYI, I hate current tcp ring buffer implementation with memmove() */
13 
14 #define UNITBUFSIZE 1024
15 #if UNITBUFSIZE < 2
16 #error UNITBUFSIZE cannot be smaller than 2
17 #endif
18 
19 #define BUFMGMT_FULL    2
20 #define BUFMGMT_FRAGS   1
21 #define BUFMGMT_OFF     0
22 
23 #define DISABLE_DYN_RESIZE
24 
25 #if 0
26 typedef enum {
27 	MOS_OVERLAP_POLICY_FIRST=0,
28 	MOS_OVERLAP_POLICY_LAST,
29 	MOS_OVERLAP_CNT
30 } MOS_OVERLAP_POLICY;
31 #endif
32 
33 enum tcprb_mode {
34 	__RB_NO_FRAG = 1,
35 	__RB_NO_BUF  = 2,
36 };
37 
38 typedef int      boff_t; /* buffer offset space */
39 typedef int64_t  loff_t; /* logical offset space */
40 
41 typedef struct _tcpbufseg_t {
42 	uint8_t buf[UNITBUFSIZE];
43 
44 	int id;
45 	TAILQ_ENTRY(_tcpbufseg_t) link;
46 } tcpbufseg_t;
47 
48 typedef struct _tcpfrag_t {
49 	bool empty;  /* true if this fragment does not have actual data */
50 
51 	loff_t head; /* head of this fragment */
52 	loff_t tail; /* tail of this fragment */
53 
54 	TAILQ_ENTRY(_tcpfrag_t) link;
55 } tcpfrag_t;
56 
57 typedef struct _tcprb_t {
58 	mem_pool_t mp;
59 
60 	unsigned mode:4,
61 		buf_mgmt:2,
62 		overlap:2;
63 	int corr;
64 
65 	int metalen;
66 
67 	TAILQ_HEAD(blist, _tcpbufseg_t) bufsegs;
68 	int lbufsegs;
69 	int len;
70 
71 	loff_t head; /* head of this window (inf space) */
72 	loff_t pile; /* maximum head. tcprb_ffhead() cannot move hseq further
73 					than cseq. (sequence space) */
74 
75 	TAILQ_HEAD(flist, _tcpfrag_t) frags;
76 
77 	TAILQ_ENTRY(_tcprb_t) link;
78 } tcprb_t;
79 
80 extern inline tcprb_t *
81 tcprb_new(mem_pool_t mp, int len, unsigned buf_mgmt);
82 
83 extern inline int
84 tcprb_del(tcprb_t *rb);
85 
86 extern inline int
87 tcprb_setpile(tcprb_t *rb, loff_t new);
88 
89 extern inline int
90 tcprb_cflen(tcprb_t *rb);
91 
92 extern inline int
93 tcprb_resize_meta(tcprb_t *rb, int len);
94 
95 extern inline int
96 tcprb_resize(tcprb_t *rb, int len);
97 
98 extern inline int
99 tcprb_ffhead(tcprb_t *rb, int len);
100 
101 extern inline int
102 tcprb_ppeek(tcprb_t *rb, uint8_t *buf, int len, loff_t off);
103 
104 extern inline int
105 tcprb_pwrite(tcprb_t *rb, uint8_t *buf, int len, loff_t off);
106 
107 extern inline void
108 tcprb_printfrags(struct _tcprb_t *rb);
109 
110 extern inline void
111 tcprb_printrb(struct _tcprb_t *rb);
112 
113 extern inline loff_t
114 seq2loff(tcprb_t *rb, uint32_t seq, uint32_t isn);
115 
116 extern inline void
117 tcp_rb_overlapchk(mtcp_manager_t mtcp, struct pkt_ctx *pctx,
118 		  struct tcp_stream *recvside_stream);
119 
120 extern inline int
121 tcprb_setpolicy(tcprb_t *rb, uint8_t policy);
122