1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 
6 #include <mtcp_api.h>
7 
8 #include "debug.h"
9 #include "rep.h"
10 #include "ring_buffer.h"
11 
12 #ifndef TRUE
13 #define TRUE (1)
14 #endif
15 
16 #ifndef FALSE
17 #define FALSE (0)
18 #endif
19 
20 #ifndef ERROR
21 #define ERROR (-1)
22 #endif
23 
24 #define MAX(a, b) ((a)>(b)?(a):(b))
25 #define MIN(a, b) ((a)<(b)?(a):(b))
26 
27 /*----------------------------------------------------------------------------*/
28 struct ring_buffer
29 {
30 	u_char* head; // pointer to the head
31 	u_char* data; // pointer to the buffered data
32 
33 	int tot_size; // size of buffer
34 	int data_size; // length of data
35 	int cum_size; // length of total merged data
36 
37 };
38 /*----------------------------------------------------------------------------*/
39 ring_buffer*
InitBuffer(int size)40 InitBuffer(int size)
41 {
42 	ring_buffer* r_buff = calloc (1, sizeof(ring_buffer));
43 	r_buff->head = malloc(size);
44 	r_buff->data = r_buff->head;
45 	r_buff->tot_size = size;
46 	return r_buff;
47 }
48 /*----------------------------------------------------------------------------*/
GetTotSizeRBuffer(ring_buffer * r_buff)49 int GetTotSizeRBuffer(ring_buffer* r_buff)
50 {
51 	return  r_buff->tot_size;
52 }
53 /*----------------------------------------------------------------------------*/
GetDataSizeRBuffer(ring_buffer * r_buff)54 int GetDataSizeRBuffer(ring_buffer* r_buff)
55 {
56 	return  r_buff->data_size;
57 }
58 /*----------------------------------------------------------------------------*/
GetCumSizeRBuffer(ring_buffer * r_buff)59 int GetCumSizeRBuffer(ring_buffer* r_buff)
60 {
61 	return  r_buff->cum_size;
62 }
63 /*----------------------------------------------------------------------------*/
GetRemainBufferSize(ring_buffer * r_buff)64 int GetRemainBufferSize(ring_buffer *r_buff)
65 {
66 	assert(r_buff->head <= r_buff->data);
67 
68 	int data_offset = r_buff->data - r_buff->head;
69 	assert (data_offset <= r_buff->tot_size - 1);
70 
71 	if (data_offset > r_buff->tot_size / 2) {
72 		memmove(r_buff->head, r_buff->data, r_buff->data_size);
73 		r_buff->data = r_buff->head;
74 		data_offset = 0;
75 		return r_buff->tot_size - r_buff->data_size;
76 	}
77 
78 	return r_buff->tot_size -  r_buff->data_size - data_offset;
79 }
80 /*----------------------------------------------------------------------------*/
CheckAvailableSize(ring_buffer * r_buff,int size)81 int CheckAvailableSize(ring_buffer *r_buff, int size)
82 {
83 	int remain_size = GetRemainBufferSize(r_buff);
84 	if (remain_size < size)
85 		return FALSE;
86 	else
87 		return TRUE;
88 }
89 /*----------------------------------------------------------------------------*/
GetDataPoint(ring_buffer * r_buff)90 u_char* GetDataPoint(ring_buffer* r_buff)
91 {
92 	return r_buff->data;
93 }
94 /*----------------------------------------------------------------------------*/
GetInputPoint(ring_buffer * r_buff)95 u_char* GetInputPoint(ring_buffer *r_buff)
96 {
97 	assert(r_buff->data_size <= r_buff->tot_size);
98 	return r_buff->data + r_buff->data_size;
99 }
100 /*----------------------------------------------------------------------------*/
RemoveDataFromBuffer(ring_buffer * r_buff,int size)101 int RemoveDataFromBuffer(ring_buffer* r_buff, int size)
102 {
103 	if (size < 0)
104 		return -1;
105 
106 	if (size > r_buff->data_size)
107 		return -1;
108 
109 	r_buff->data_size -= size;
110 
111 	if (r_buff->data_size == 0)
112 		r_buff->data = r_buff->head;
113 	else
114 		r_buff->data += size;
115 
116 	return size;
117 }
118 /*----------------------------------------------------------------------------*/
AddDataLen(ring_buffer * r_buff,int size)119 int AddDataLen(ring_buffer *r_buff, int size)
120 {
121 	assert(r_buff->data_size + size <= r_buff->tot_size);
122 	r_buff->data_size += size;
123 	r_buff->cum_size += size;
124 	return r_buff->data_size;
125 }
126 /*----------------------------------------------------------------------------*/
CopyData(ring_buffer * dest_buff,ring_buffer * src_buff,int len)127 int CopyData(ring_buffer *dest_buff, ring_buffer *src_buff, int len)
128 {
129 	int to_cpy;
130 	u_char* ip;
131 
132 	// getting length to copy
133 	to_cpy = GetRemainBufferSize(dest_buff);
134 	if (to_cpy <= 0)
135 		return 0;
136 
137 	if (to_cpy > 0)
138 		to_cpy = MIN(to_cpy, len);
139 	to_cpy = MIN(GetDataSizeRBuffer(src_buff), to_cpy);
140 
141 	// copy from src_buffer to dest_buffer
142 	ip = GetInputPoint(dest_buff);
143 	memcpy(ip, GetDataPoint(src_buff), to_cpy);
144 	AddDataLen(dest_buff, to_cpy);
145 
146 	return to_cpy;
147 }
148 /*----------------------------------------------------------------------------*/
MoveToREPData(ring_buffer * dest_buff,ring_buffer * src_buff,int len)149 int MoveToREPData(ring_buffer *dest_buff, ring_buffer *src_buff, int len)
150 {
151 	int to_move, ret, sum = 0;
152 	u_char* ip;
153 
154 	int data_size = GetDataSizeRBuffer(src_buff);
155 	int remain_size = GetRemainBufferSize(dest_buff);
156 
157 	if (len > 0)
158 		data_size = MIN(data_size, len);
159 
160 	while (data_size > 0 && remain_size > sizeof(rephdr)) {
161 		// getting length to move
162 		to_move = MIN(data_size, remain_size - sizeof(rephdr));
163 		to_move = MIN(to_move, MAX_REP_LEN);
164 		if (to_move <= 0)
165 			return 0;
166 
167 		remain_size -= sizeof(rephdr);
168 		remain_size -= to_move;
169 		data_size -= to_move;
170 
171 		ip = GetInputPoint(dest_buff);
172 
173 		// create rep header
174 		rephdr rep;
175 		rep.msg_type = 0x01;
176 		rep.command = 0x00;
177 		rep.msg_len = to_move;
178 		memcpy(ip, &rep, sizeof(rephdr));
179 		ip += sizeof(rephdr);
180 		AddDataLen(dest_buff, sizeof(rephdr));
181 
182 		// copy from src_buffer to dest_buffer
183 		memcpy(ip, GetDataPoint(src_buff), to_move);
184 		AddDataLen(dest_buff, to_move);
185 		sum += to_move;
186 
187 		// remove from src_buff
188 		ret = RemoveDataFromBuffer(src_buff, to_move);
189 		assert(to_move == ret);
190 	}
191 
192 	return sum;
193 }
194 /*----------------------------------------------------------------------------*/
MoveData(ring_buffer * dest_buff,ring_buffer * src_buff,int len)195 int MoveData(ring_buffer *dest_buff, ring_buffer *src_buff, int len)
196 {
197 	int to_move, ret;
198 	u_char* ip;
199 
200 	// getting length to move
201 	to_move = GetDataSizeRBuffer(src_buff);
202 
203 	if (len > 0)
204 		to_move = MIN(to_move, len);
205 
206 	to_move = MIN(GetDataSizeRBuffer(src_buff), to_move);
207 	if(to_move <= 0)
208 		return 0;
209 
210 	// copy from src_buffer to dest_buffer
211 	ip = GetInputPoint(dest_buff);
212 	memcpy(ip, GetDataPoint(src_buff), to_move);
213 	AddDataLen(dest_buff, to_move);
214 
215 	// remove from src_buff
216 	ret = RemoveDataFromBuffer(src_buff, to_move);
217 	assert(to_move == ret);
218 
219 	return ret;
220 }
221 /*----------------------------------------------------------------------------*/
MtcpWriteFromBuffer(mctx_t mctx,int fid,ring_buffer * r_buff)222 int MtcpWriteFromBuffer(mctx_t mctx, int fid, ring_buffer *r_buff)
223 {
224 	int to_send, wr, ret;
225 	to_send = GetDataSizeRBuffer(r_buff);
226 	if (to_send <= 0)
227 		return 0;
228 
229 	wr = mtcp_write(mctx, fid, GetDataPoint(r_buff), to_send);
230 	if (wr < 0) {
231 		TRACE_APP("RE_MAIN: Write failed. reason: %d\n", wr);
232 		return wr;
233 	}
234 
235 	ret = RemoveDataFromBuffer(r_buff, wr);
236 	assert (wr == ret);
237 
238 	return wr;
239 }
240 /*----------------------------------------------------------------------------*/
MtcpReadFromBuffer(mctx_t mctx,int fid,ring_buffer * r_buff)241 int MtcpReadFromBuffer(mctx_t mctx, int fid, ring_buffer *r_buff)
242 {
243 	int free_len, ret;
244 	u_char* ip;
245 
246 	free_len = GetRemainBufferSize(r_buff);
247 	ip = GetInputPoint(r_buff);
248 
249 	ret = mtcp_read(mctx, fid, ip, free_len);
250 	if (ret < 0) {
251 		TRACE_APP("RE_MAIN: Read failed. reason: %d\n", ret);
252 		return ret;
253 	}
254 	AddDataLen(r_buff, ret);
255 
256 	return ret;
257 }
258 /*----------------------------------------------------------------------------*/
259