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* 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 /*----------------------------------------------------------------------------*/ 49 int GetTotSizeRBuffer(ring_buffer* r_buff) 50 { 51 return r_buff->tot_size; 52 } 53 /*----------------------------------------------------------------------------*/ 54 int GetDataSizeRBuffer(ring_buffer* r_buff) 55 { 56 return r_buff->data_size; 57 } 58 /*----------------------------------------------------------------------------*/ 59 int GetCumSizeRBuffer(ring_buffer* r_buff) 60 { 61 return r_buff->cum_size; 62 } 63 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 90 u_char* GetDataPoint(ring_buffer* r_buff) 91 { 92 return r_buff->data; 93 } 94 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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 /*----------------------------------------------------------------------------*/ 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