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