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