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