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