1 
2 /*
3  * 2010.12.10 Shinae Woo
4  * Ring buffer structure for managing dynamically allocating ring buffer
5  *
6  * put data to the tail
7  * get/pop/remove data from the head
8  *
9  * always garantee physically continuous ready in-memory data from data_offset to the data_offset+len
10  * automatically increase total buffer size when buffer is full
11  * for efficiently managing packet payload and chunking
12  *
13  */
14 
15 #ifndef __MOS_RING_BUFFER_
16 #define __MOS_RING_BUFFER_
17 
18 #include <stdint.h>
19 #include <sys/types.h>
20 
21 /*----------------------------------------------------------------------------*/
22 enum rb_caller
23 {
24 	AT_APP,
25 	AT_MTCP
26 };
27 /*----------------------------------------------------------------------------*/
28 struct tcp_stream;
29 typedef struct rb_manager* rb_manager_t;
30 /*----------------------------------------------------------------------------*/
31 struct fragment_ctx
32 {
33 	uint32_t seq;
34 	uint32_t len : 31,
35 		is_calloc : 1;
36 	struct fragment_ctx *next;
37 };
38 /*----------------------------------------------------------------------------*/
39 struct tcp_ring_buffer
40 {
41 	u_char* data;			/* buffered data */
42 	u_char* head;			/* pointer to the head */
43 
44 	uint32_t head_offset;	/* offset for the head (head - data) */
45 	uint32_t tail_offset;	/* offset fot the last byte (null byte) */
46 	/*
47 	 * offset that points to the tail-end of the monitoring stream offset.
48 	 */
49 	uint32_t monitor_read_tail_offset;
50 
51 	int merged_len;			/* contiguously merged length */
52 	uint64_t cum_len;		/* cummulatively merged length */
53 	int last_len;			/* currently saved data length */
54 	int size;			/* total ring buffer size */
55 
56 	/* TCP payload features */
57 	uint32_t head_seq;
58 	uint32_t init_seq;
59 
60 	struct fragment_ctx* fctx;
61 };
62 /*----------------------------------------------------------------------------*/
63 uint32_t RBGetCurnum(rb_manager_t rbm);
64 void RBPrintInfo(struct tcp_ring_buffer* buff);
65 void RBPrintStr(struct tcp_ring_buffer* buff);
66 void RBPrintHex(struct tcp_ring_buffer* buff);
67 /*----------------------------------------------------------------------------*/
68 rb_manager_t RBManagerCreate(size_t chunk_size, uint8_t disable_rings, uint32_t concurrency);
69 /*----------------------------------------------------------------------------*/
70 struct tcp_ring_buffer* RBInit(rb_manager_t rbm,  uint32_t init_seq, uint8_t buffer_mgmt);
71 void RBFree(rb_manager_t rbm, struct tcp_ring_buffer* buff, uint8_t buffer_mgmt);
72 uint32_t RBIsDanger(rb_manager_t rbm);
73 /*----------------------------------------------------------------------------*/
74 /* data manupulation functions */
75 int RBPut(rb_manager_t rbm, struct tcp_stream *cur_stream, void *data,
76 	  uint32_t len, uint32_t seq);
77 size_t RBGet(rb_manager_t rbm, struct tcp_ring_buffer* buff, size_t len);
78 size_t RBRemove(rb_manager_t rbm, struct tcp_ring_buffer* buff,
79 		size_t len, int option, uint8_t buffer_mgmt);
80 /*----------------------------------------------------------------------------*/
81 extern inline int
82 RBDoesOverlap(rb_manager_t rbm, struct tcp_ring_buffer *rcvbuf,
83 			  uint32_t cur_seq, uint32_t len);
84 /*----------------------------------------------------------------------------*/
85 
86 #endif /* !MOS_RING_BUFFER */
87