1*a9643ea8Slogwang 2*a9643ea8Slogwang /** 3*a9643ea8Slogwang * Tencent is pleased to support the open source community by making MSEC available. 4*a9643ea8Slogwang * 5*a9643ea8Slogwang * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. 6*a9643ea8Slogwang * 7*a9643ea8Slogwang * Licensed under the GNU General Public License, Version 2.0 (the "License"); 8*a9643ea8Slogwang * you may not use this file except in compliance with the License. You may 9*a9643ea8Slogwang * obtain a copy of the License at 10*a9643ea8Slogwang * 11*a9643ea8Slogwang * https://opensource.org/licenses/GPL-2.0 12*a9643ea8Slogwang * 13*a9643ea8Slogwang * Unless required by applicable law or agreed to in writing, software distributed under the 14*a9643ea8Slogwang * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15*a9643ea8Slogwang * either express or implied. See the License for the specific language governing permissions 16*a9643ea8Slogwang * and limitations under the License. 17*a9643ea8Slogwang */ 18*a9643ea8Slogwang 19*a9643ea8Slogwang 20*a9643ea8Slogwang /** 21*a9643ea8Slogwang * @filename mt_cache.cpp 22*a9643ea8Slogwang * @info TCP����buffer����ʵ�� 23*a9643ea8Slogwang */ 24*a9643ea8Slogwang 25*a9643ea8Slogwang #include <stdlib.h> 26*a9643ea8Slogwang #include <errno.h> 27*a9643ea8Slogwang #include <sys/types.h> 28*a9643ea8Slogwang #include <sys/socket.h> 29*a9643ea8Slogwang #include <string.h> 30*a9643ea8Slogwang #include "mt_incl.h" 31*a9643ea8Slogwang #include "kqueue_proxy.h" 32*a9643ea8Slogwang #include "micro_thread.h" 33*a9643ea8Slogwang #include "mt_sys_hook.h" 34*a9643ea8Slogwang #include "ff_hook.h" 35*a9643ea8Slogwang 36*a9643ea8Slogwang #include "mt_cache.h" 37*a9643ea8Slogwang 38*a9643ea8Slogwang namespace NS_MICRO_THREAD { 39*a9643ea8Slogwang 40*a9643ea8Slogwang 41*a9643ea8Slogwang /** 42*a9643ea8Slogwang * @brief Buffer�������� 43*a9643ea8Slogwang * @param size ʵ�ʵ�buff��С 44*a9643ea8Slogwang * @return ��NULL block��, ����ʧ�� 45*a9643ea8Slogwang */ 46*a9643ea8Slogwang TSkBuffer* new_sk_buffer(uint32_t size) 47*a9643ea8Slogwang { 48*a9643ea8Slogwang uint32_t total = sizeof(TSkBuffer) + size; 49*a9643ea8Slogwang total = (total + SK_DFLT_ALIGN_SIZE - 1) / SK_DFLT_ALIGN_SIZE * SK_DFLT_ALIGN_SIZE; 50*a9643ea8Slogwang TSkBuffer* block = (TSkBuffer*)malloc(total); 51*a9643ea8Slogwang if (block == NULL) 52*a9643ea8Slogwang { 53*a9643ea8Slogwang MTLOG_ERROR("malloc failed, no more memory[%u]", total); 54*a9643ea8Slogwang return NULL; 55*a9643ea8Slogwang } 56*a9643ea8Slogwang 57*a9643ea8Slogwang block->last_time = 0; 58*a9643ea8Slogwang block->size = size; 59*a9643ea8Slogwang block->head = block->buff; 60*a9643ea8Slogwang block->end = block->buff + size; 61*a9643ea8Slogwang 62*a9643ea8Slogwang block->data = block->head; 63*a9643ea8Slogwang block->data_len = 0; 64*a9643ea8Slogwang 65*a9643ea8Slogwang return block; 66*a9643ea8Slogwang } 67*a9643ea8Slogwang 68*a9643ea8Slogwang 69*a9643ea8Slogwang /** 70*a9643ea8Slogwang * @brief Buffer�ͷŲ��� 71*a9643ea8Slogwang * @param block -buff�� 72*a9643ea8Slogwang */ 73*a9643ea8Slogwang void delete_sk_buffer(TSkBuffer* block) 74*a9643ea8Slogwang { 75*a9643ea8Slogwang if (NULL == block) { 76*a9643ea8Slogwang return; 77*a9643ea8Slogwang } 78*a9643ea8Slogwang 79*a9643ea8Slogwang free(block); 80*a9643ea8Slogwang } 81*a9643ea8Slogwang 82*a9643ea8Slogwang 83*a9643ea8Slogwang /** 84*a9643ea8Slogwang * @brief ����������Ϣ(����Դ�ػ���buff,����չ) 85*a9643ea8Slogwang * @param buff -���е�buffָ�� 86*a9643ea8Slogwang * @param size -��Ҫ��չ�����ճ��ȴ�С 87*a9643ea8Slogwang * @return ʵ�ʵ�buff��Ϣ 88*a9643ea8Slogwang */ 89*a9643ea8Slogwang TSkBuffer* reserve_sk_buffer(TSkBuffer* buff, uint32_t size) 90*a9643ea8Slogwang { 91*a9643ea8Slogwang if (NULL == buff) { 92*a9643ea8Slogwang return new_sk_buffer(size); 93*a9643ea8Slogwang } 94*a9643ea8Slogwang 95*a9643ea8Slogwang if (buff->size >= size) { 96*a9643ea8Slogwang return buff; 97*a9643ea8Slogwang } 98*a9643ea8Slogwang 99*a9643ea8Slogwang TSkBuffer* new_buff = new_sk_buffer(size); 100*a9643ea8Slogwang if (NULL == new_buff) { 101*a9643ea8Slogwang return buff; 102*a9643ea8Slogwang } 103*a9643ea8Slogwang memcpy(new_buff->data, buff->data, buff->data_len); 104*a9643ea8Slogwang new_buff->data_len = buff->data_len; 105*a9643ea8Slogwang delete_sk_buffer(buff); 106*a9643ea8Slogwang 107*a9643ea8Slogwang return new_buff; 108*a9643ea8Slogwang } 109*a9643ea8Slogwang 110*a9643ea8Slogwang 111*a9643ea8Slogwang /** 112*a9643ea8Slogwang * @brief cache �صij�ʼ���ӿ� 113*a9643ea8Slogwang * @param mng -����ص�ָ�� 114*a9643ea8Slogwang * @param expired -�����ʱ��, ��λ�� 115*a9643ea8Slogwang * @param size -�������Ĭ�����ɵĿ��С 116*a9643ea8Slogwang */ 117*a9643ea8Slogwang void sk_buffer_mng_init(TSkBuffMng* mng, uint32_t expired, uint32_t size) 118*a9643ea8Slogwang { 119*a9643ea8Slogwang TAILQ_INIT(&mng->free_list); 120*a9643ea8Slogwang mng->expired = expired; 121*a9643ea8Slogwang mng->count = 0; 122*a9643ea8Slogwang mng->size = size; 123*a9643ea8Slogwang } 124*a9643ea8Slogwang 125*a9643ea8Slogwang /** 126*a9643ea8Slogwang * @brief cache �ص����ٽӿ� 127*a9643ea8Slogwang * @param mng -����ص�ָ�� 128*a9643ea8Slogwang */ 129*a9643ea8Slogwang void sk_buffer_mng_destroy(TSkBuffMng * mng) 130*a9643ea8Slogwang { 131*a9643ea8Slogwang TSkBuffer* item = NULL; 132*a9643ea8Slogwang TSkBuffer* tmp = NULL; 133*a9643ea8Slogwang TAILQ_FOREACH_SAFE(item, &mng->free_list, entry, tmp) 134*a9643ea8Slogwang { 135*a9643ea8Slogwang TAILQ_REMOVE(&mng->free_list, item, entry); 136*a9643ea8Slogwang delete_sk_buffer(item); 137*a9643ea8Slogwang } 138*a9643ea8Slogwang mng->count = 0; 139*a9643ea8Slogwang } 140*a9643ea8Slogwang 141*a9643ea8Slogwang 142*a9643ea8Slogwang /** 143*a9643ea8Slogwang * @brief �������һ��buff 144*a9643ea8Slogwang * @param mng -����ص�ָ�� 145*a9643ea8Slogwang * @return ��NULLΪ�ɹ���ȡ��buff��ָ�� 146*a9643ea8Slogwang */ 147*a9643ea8Slogwang TSkBuffer* alloc_sk_buffer(TSkBuffMng* mng) 148*a9643ea8Slogwang { 149*a9643ea8Slogwang if (NULL == mng) { 150*a9643ea8Slogwang return NULL; 151*a9643ea8Slogwang } 152*a9643ea8Slogwang 153*a9643ea8Slogwang TSkBuffer* item = TAILQ_FIRST(&mng->free_list); 154*a9643ea8Slogwang if (item != NULL) 155*a9643ea8Slogwang { 156*a9643ea8Slogwang TAILQ_REMOVE(&mng->free_list, item, entry); 157*a9643ea8Slogwang mng->count--; 158*a9643ea8Slogwang return item; 159*a9643ea8Slogwang } 160*a9643ea8Slogwang 161*a9643ea8Slogwang item = new_sk_buffer(mng->size); 162*a9643ea8Slogwang if (NULL == item) 163*a9643ea8Slogwang { 164*a9643ea8Slogwang return NULL; 165*a9643ea8Slogwang } 166*a9643ea8Slogwang 167*a9643ea8Slogwang return item; 168*a9643ea8Slogwang } 169*a9643ea8Slogwang 170*a9643ea8Slogwang 171*a9643ea8Slogwang /** 172*a9643ea8Slogwang * @brief �ͷ�ָ����buff�� 173*a9643ea8Slogwang * @param mng -����ص�ָ�� 174*a9643ea8Slogwang * @param buff -���ͷŵ�buffָ�� 175*a9643ea8Slogwang */ 176*a9643ea8Slogwang void free_sk_buffer(TSkBuffMng* mng, TSkBuffer* buff) 177*a9643ea8Slogwang { 178*a9643ea8Slogwang if ((NULL == mng) || (NULL == buff)) { 179*a9643ea8Slogwang return; 180*a9643ea8Slogwang } 181*a9643ea8Slogwang 182*a9643ea8Slogwang TAILQ_INSERT_TAIL(&mng->free_list, buff, entry); 183*a9643ea8Slogwang mng->count++; 184*a9643ea8Slogwang 185*a9643ea8Slogwang buff->last_time = (uint32_t)(mt_time_ms() / 1000); 186*a9643ea8Slogwang buff->data = buff->head; 187*a9643ea8Slogwang buff->data_len = 0; 188*a9643ea8Slogwang } 189*a9643ea8Slogwang 190*a9643ea8Slogwang 191*a9643ea8Slogwang /** 192*a9643ea8Slogwang * @brief ���չ��ڵ�buff�� 193*a9643ea8Slogwang * @param mng -����ص�ָ�� 194*a9643ea8Slogwang * @param now -��ǰ��ʱ��, �뼶�� 195*a9643ea8Slogwang */ 196*a9643ea8Slogwang void recycle_sk_buffer(TSkBuffMng* mng, uint32_t now) 197*a9643ea8Slogwang { 198*a9643ea8Slogwang TSkBuffer* item = NULL; 199*a9643ea8Slogwang TSkBuffer* tmp = NULL; 200*a9643ea8Slogwang TAILQ_FOREACH_SAFE(item, &mng->free_list, entry, tmp) 201*a9643ea8Slogwang { 202*a9643ea8Slogwang if ((now - item->last_time) < mng->expired) 203*a9643ea8Slogwang { 204*a9643ea8Slogwang break; 205*a9643ea8Slogwang } 206*a9643ea8Slogwang 207*a9643ea8Slogwang TAILQ_REMOVE(&mng->free_list, item, entry); 208*a9643ea8Slogwang delete_sk_buffer(item); 209*a9643ea8Slogwang mng->count--; 210*a9643ea8Slogwang } 211*a9643ea8Slogwang } 212*a9643ea8Slogwang 213*a9643ea8Slogwang 214*a9643ea8Slogwang /** 215*a9643ea8Slogwang * @brief Cache��������ʼ�� 216*a9643ea8Slogwang * @param cache -�����ָ�� 217*a9643ea8Slogwang * @param pool -buff��ָ�� 218*a9643ea8Slogwang */ 219*a9643ea8Slogwang void rw_cache_init(TRWCache* cache, TSkBuffMng* pool) 220*a9643ea8Slogwang { 221*a9643ea8Slogwang TAILQ_INIT(&cache->list); 222*a9643ea8Slogwang cache->len = 0; 223*a9643ea8Slogwang cache->count = 0; 224*a9643ea8Slogwang cache->pool = pool; 225*a9643ea8Slogwang } 226*a9643ea8Slogwang 227*a9643ea8Slogwang /** 228*a9643ea8Slogwang * @brief Cache���������� 229*a9643ea8Slogwang * @param cache -�����ָ�� 230*a9643ea8Slogwang */ 231*a9643ea8Slogwang void rw_cache_destroy(TRWCache* cache) 232*a9643ea8Slogwang { 233*a9643ea8Slogwang if ((cache == NULL) || (cache->pool == NULL)) { 234*a9643ea8Slogwang return; 235*a9643ea8Slogwang } 236*a9643ea8Slogwang 237*a9643ea8Slogwang TSkBuffer* item = NULL; 238*a9643ea8Slogwang TSkBuffer* tmp = NULL; 239*a9643ea8Slogwang TAILQ_FOREACH_SAFE(item, &cache->list, entry, tmp) 240*a9643ea8Slogwang { 241*a9643ea8Slogwang TAILQ_REMOVE(&cache->list, item, entry); 242*a9643ea8Slogwang free_sk_buffer(cache->pool, item); 243*a9643ea8Slogwang } 244*a9643ea8Slogwang cache->count = 0; 245*a9643ea8Slogwang cache->len = 0; 246*a9643ea8Slogwang cache->pool = NULL; 247*a9643ea8Slogwang } 248*a9643ea8Slogwang 249*a9643ea8Slogwang 250*a9643ea8Slogwang /** 251*a9643ea8Slogwang * @brief Cacheɾ��������ָ���������� 252*a9643ea8Slogwang * @param cache -�����ָ�� 253*a9643ea8Slogwang * @param buff -���buff��ָ�� 254*a9643ea8Slogwang * @param len -��ɾ���ij��� 255*a9643ea8Slogwang * @return ʵ�ʿ������� 256*a9643ea8Slogwang */ 257*a9643ea8Slogwang uint32_t cache_copy_out(TRWCache* cache, void* buff, uint32_t len) 258*a9643ea8Slogwang { 259*a9643ea8Slogwang if ((cache == NULL) || (cache->pool == NULL)) { 260*a9643ea8Slogwang return 0; 261*a9643ea8Slogwang } 262*a9643ea8Slogwang 263*a9643ea8Slogwang char* out_buff = (char*)buff; 264*a9643ea8Slogwang uint32_t left = len, skip_len = 0; 265*a9643ea8Slogwang TSkBuffer* item = NULL; 266*a9643ea8Slogwang TSkBuffer* tmp = NULL; 267*a9643ea8Slogwang TAILQ_FOREACH_SAFE(item, &cache->list, entry, tmp) 268*a9643ea8Slogwang { 269*a9643ea8Slogwang // 1. ȷ�Ͽ������ݴ�С 270*a9643ea8Slogwang skip_len = (item->data_len > left) ? left : item->data_len; 271*a9643ea8Slogwang if (out_buff != NULL) 272*a9643ea8Slogwang { 273*a9643ea8Slogwang memcpy(out_buff, item->data, skip_len); 274*a9643ea8Slogwang out_buff += skip_len; 275*a9643ea8Slogwang } 276*a9643ea8Slogwang 277*a9643ea8Slogwang left -= skip_len; 278*a9643ea8Slogwang item->data_len -= skip_len; 279*a9643ea8Slogwang item->data += skip_len; 280*a9643ea8Slogwang if (item->data_len > 0) 281*a9643ea8Slogwang { 282*a9643ea8Slogwang break; 283*a9643ea8Slogwang } 284*a9643ea8Slogwang 285*a9643ea8Slogwang // 2. �Ƴ�һ��block 286*a9643ea8Slogwang if (cache->count > 0) { 287*a9643ea8Slogwang cache->count--; 288*a9643ea8Slogwang } 289*a9643ea8Slogwang TAILQ_REMOVE(&cache->list, item, entry); 290*a9643ea8Slogwang free_sk_buffer(cache->pool, item); 291*a9643ea8Slogwang 292*a9643ea8Slogwang // 3. ѭ���������� 293*a9643ea8Slogwang if (left == 0) 294*a9643ea8Slogwang { 295*a9643ea8Slogwang break; 296*a9643ea8Slogwang } 297*a9643ea8Slogwang } 298*a9643ea8Slogwang 299*a9643ea8Slogwang // ���忼�����ݳ�������, �Ƿ����㹻�������Ƴ� 300*a9643ea8Slogwang skip_len = len - left; 301*a9643ea8Slogwang if (cache->len > skip_len) 302*a9643ea8Slogwang { 303*a9643ea8Slogwang cache->len -= skip_len; 304*a9643ea8Slogwang } 305*a9643ea8Slogwang else 306*a9643ea8Slogwang { 307*a9643ea8Slogwang cache->len = 0; 308*a9643ea8Slogwang } 309*a9643ea8Slogwang 310*a9643ea8Slogwang return skip_len; 311*a9643ea8Slogwang } 312*a9643ea8Slogwang 313*a9643ea8Slogwang 314*a9643ea8Slogwang /** 315*a9643ea8Slogwang * @brief Cacheɾ����ָ���������� 316*a9643ea8Slogwang * @param cache -�����ָ�� 317*a9643ea8Slogwang * @param len -��ɾ���ij��� 318*a9643ea8Slogwang */ 319*a9643ea8Slogwang void cache_skip_data(TRWCache* cache, uint32_t len) 320*a9643ea8Slogwang { 321*a9643ea8Slogwang cache_copy_out(cache, NULL, len); 322*a9643ea8Slogwang } 323*a9643ea8Slogwang 324*a9643ea8Slogwang /** 325*a9643ea8Slogwang * @brief Cache��ָ���������� 326*a9643ea8Slogwang * @param cache -�����ָ�� 327*a9643ea8Slogwang * @param buff -���ӵĿ�ָ�� 328*a9643ea8Slogwang */ 329*a9643ea8Slogwang void cache_append_buffer(TRWCache* cache, TSkBuffer* buff) 330*a9643ea8Slogwang { 331*a9643ea8Slogwang if ((NULL == cache) || (NULL == buff)) 332*a9643ea8Slogwang { 333*a9643ea8Slogwang return; 334*a9643ea8Slogwang } 335*a9643ea8Slogwang 336*a9643ea8Slogwang TAILQ_INSERT_TAIL(&cache->list, buff, entry); 337*a9643ea8Slogwang cache->len += buff->data_len; 338*a9643ea8Slogwang cache->count++; 339*a9643ea8Slogwang } 340*a9643ea8Slogwang 341*a9643ea8Slogwang /** 342*a9643ea8Slogwang * @brief Cache�Ƴ���һ���ڴ�, ����free 343*a9643ea8Slogwang * @param cache -�����ָ�� 344*a9643ea8Slogwang */ 345*a9643ea8Slogwang TSkBuffer* cache_skip_first_buffer(TRWCache* cache) 346*a9643ea8Slogwang { 347*a9643ea8Slogwang TSkBuffer* buff = TAILQ_FIRST(&cache->list); 348*a9643ea8Slogwang if ((NULL == cache) || (NULL == buff)) 349*a9643ea8Slogwang { 350*a9643ea8Slogwang return NULL; 351*a9643ea8Slogwang } 352*a9643ea8Slogwang 353*a9643ea8Slogwang TAILQ_REMOVE(&cache->list, buff, entry); 354*a9643ea8Slogwang if (cache->len >= buff->data_len) 355*a9643ea8Slogwang { 356*a9643ea8Slogwang cache->len -= buff->data_len; 357*a9643ea8Slogwang } 358*a9643ea8Slogwang 359*a9643ea8Slogwang if (cache->count > 0) 360*a9643ea8Slogwang { 361*a9643ea8Slogwang cache->count--; 362*a9643ea8Slogwang } 363*a9643ea8Slogwang 364*a9643ea8Slogwang return buff; 365*a9643ea8Slogwang } 366*a9643ea8Slogwang 367*a9643ea8Slogwang 368*a9643ea8Slogwang /** 369*a9643ea8Slogwang * @brief Cache��ָ���������� 370*a9643ea8Slogwang * @param cache -�����ָ�� 371*a9643ea8Slogwang * @param data -���ӵ�ָ�� 372*a9643ea8Slogwang * @param len -���ӵij��� 373*a9643ea8Slogwang */ 374*a9643ea8Slogwang int32_t cache_append_data(TRWCache* cache, const void* data, uint32_t len) 375*a9643ea8Slogwang { 376*a9643ea8Slogwang if ((NULL == data) || (NULL == cache) || (NULL == cache->pool)) 377*a9643ea8Slogwang { 378*a9643ea8Slogwang return -1; 379*a9643ea8Slogwang } 380*a9643ea8Slogwang 381*a9643ea8Slogwang if (len == 0) 382*a9643ea8Slogwang { 383*a9643ea8Slogwang return 0; 384*a9643ea8Slogwang } 385*a9643ea8Slogwang 386*a9643ea8Slogwang uint32_t left = len; 387*a9643ea8Slogwang uint32_t remain = 0; 388*a9643ea8Slogwang 389*a9643ea8Slogwang // 1. β�ռ��Ƚ���append, ��Ϊ��Ҫ�ع�, ǰһ�����Ȳ����� 390*a9643ea8Slogwang TSkBuffer* tail = TAILQ_LAST(&cache->list, __sk_buff_list); 391*a9643ea8Slogwang if (tail != NULL) 392*a9643ea8Slogwang { 393*a9643ea8Slogwang if (tail->end > (tail->data + tail->data_len)) 394*a9643ea8Slogwang { 395*a9643ea8Slogwang remain = tail->end - tail->data - tail->data_len; 396*a9643ea8Slogwang } 397*a9643ea8Slogwang 398*a9643ea8Slogwang if (remain >= len) 399*a9643ea8Slogwang { 400*a9643ea8Slogwang memcpy(tail->data + tail->data_len, data, len); 401*a9643ea8Slogwang tail->data_len += len; 402*a9643ea8Slogwang cache->len += len; 403*a9643ea8Slogwang return (int32_t)len; 404*a9643ea8Slogwang } 405*a9643ea8Slogwang } 406*a9643ea8Slogwang 407*a9643ea8Slogwang // 2. ��ʣ��buff������, ������ʣ���buff, ����β�ڵ� 408*a9643ea8Slogwang TRWCache keep_list; 409*a9643ea8Slogwang rw_cache_init(&keep_list, cache->pool); 410*a9643ea8Slogwang left -= remain; 411*a9643ea8Slogwang while (left > 0) 412*a9643ea8Slogwang { 413*a9643ea8Slogwang TSkBuffer* item = alloc_sk_buffer(cache->pool); 414*a9643ea8Slogwang if (item == NULL) 415*a9643ea8Slogwang { 416*a9643ea8Slogwang rw_cache_destroy(&keep_list); 417*a9643ea8Slogwang return -2; 418*a9643ea8Slogwang } 419*a9643ea8Slogwang cache_append_buffer(&keep_list, item); 420*a9643ea8Slogwang 421*a9643ea8Slogwang if (left <= item->size) 422*a9643ea8Slogwang { 423*a9643ea8Slogwang memcpy(item->head, (char*)data + len - left, left); 424*a9643ea8Slogwang item->data_len = left; 425*a9643ea8Slogwang break; 426*a9643ea8Slogwang } 427*a9643ea8Slogwang 428*a9643ea8Slogwang memcpy(item->head, (char*)data + len - left, item->size); 429*a9643ea8Slogwang item->data_len = item->size; 430*a9643ea8Slogwang left -= item->size; 431*a9643ea8Slogwang } 432*a9643ea8Slogwang 433*a9643ea8Slogwang // 3. ���Կ��������buff, ���ﲻ��ع��� 434*a9643ea8Slogwang if ((tail != NULL) && (remain > 0)) 435*a9643ea8Slogwang { 436*a9643ea8Slogwang memcpy(tail->data + tail->data_len, data, remain); 437*a9643ea8Slogwang tail->data_len += remain; 438*a9643ea8Slogwang } 439*a9643ea8Slogwang 440*a9643ea8Slogwang cache->len += len; 441*a9643ea8Slogwang cache->count += keep_list.count; 442*a9643ea8Slogwang TAILQ_CONCAT(&cache->list, &keep_list.list, entry); 443*a9643ea8Slogwang 444*a9643ea8Slogwang return (int32_t)len; 445*a9643ea8Slogwang } 446*a9643ea8Slogwang 447*a9643ea8Slogwang 448*a9643ea8Slogwang /** 449*a9643ea8Slogwang * @brief Cache���ϵ�UDP�ձ��ӿ�, �����ڴ�Ƚ϶�, ������32λʹ�� 450*a9643ea8Slogwang * @param cache -�����ָ�� 451*a9643ea8Slogwang * @param fd - ���ձ���fd��� 452*a9643ea8Slogwang * @param remote_addr -�Զ�ip��ַ 453*a9643ea8Slogwang * @return ʵ�ʽ��ճ��� 454*a9643ea8Slogwang */ 455*a9643ea8Slogwang int32_t cache_udp_recv(TRWCache* cache, uint32_t fd, struct sockaddr_in* remote_addr) 456*a9643ea8Slogwang { 457*a9643ea8Slogwang if (NULL == cache) 458*a9643ea8Slogwang { 459*a9643ea8Slogwang return -1; 460*a9643ea8Slogwang } 461*a9643ea8Slogwang 462*a9643ea8Slogwang int32_t total = 0; 463*a9643ea8Slogwang for (uint32_t i = 0; i < 100; i++) 464*a9643ea8Slogwang { 465*a9643ea8Slogwang TSkBuffer* item = alloc_sk_buffer(cache->pool); 466*a9643ea8Slogwang if (NULL == item) 467*a9643ea8Slogwang { 468*a9643ea8Slogwang return -2; 469*a9643ea8Slogwang } 470*a9643ea8Slogwang 471*a9643ea8Slogwang socklen_t addr_len = sizeof(*remote_addr); 472*a9643ea8Slogwang mt_hook_syscall(recvfrom); 473*a9643ea8Slogwang int32_t rc = ff_hook_recvfrom(fd, item->data, item->size, 0, (struct sockaddr*)remote_addr, &addr_len); 474*a9643ea8Slogwang if (rc <= 0) 475*a9643ea8Slogwang { 476*a9643ea8Slogwang free_sk_buffer(cache->pool, item); 477*a9643ea8Slogwang 478*a9643ea8Slogwang if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) 479*a9643ea8Slogwang { 480*a9643ea8Slogwang break; 481*a9643ea8Slogwang } 482*a9643ea8Slogwang else 483*a9643ea8Slogwang { 484*a9643ea8Slogwang MTLOG_ERROR("recvfrom failed, fd[%d] ret %d[%m]", fd, rc); 485*a9643ea8Slogwang return -3; 486*a9643ea8Slogwang } 487*a9643ea8Slogwang } 488*a9643ea8Slogwang 489*a9643ea8Slogwang item->data_len += rc; 490*a9643ea8Slogwang cache_append_buffer(cache, item); 491*a9643ea8Slogwang total += rc; 492*a9643ea8Slogwang } 493*a9643ea8Slogwang 494*a9643ea8Slogwang return total; 495*a9643ea8Slogwang } 496*a9643ea8Slogwang 497*a9643ea8Slogwang 498*a9643ea8Slogwang /** 499*a9643ea8Slogwang * @brief Cache���ϵ�TCP�ձ��ӿ� 500*a9643ea8Slogwang * @param cache -�����ָ�� 501*a9643ea8Slogwang * @param fd - ���ձ���fd��� 502*a9643ea8Slogwang * @return ʵ�ʽ��ճ��� 503*a9643ea8Slogwang */ 504*a9643ea8Slogwang int32_t cache_tcp_recv(TRWCache* cache, uint32_t fd) 505*a9643ea8Slogwang { 506*a9643ea8Slogwang if (NULL == cache) 507*a9643ea8Slogwang { 508*a9643ea8Slogwang return -1; 509*a9643ea8Slogwang } 510*a9643ea8Slogwang 511*a9643ea8Slogwang int32_t total = 0; 512*a9643ea8Slogwang for (uint32_t i = 0; i < 100; i++) 513*a9643ea8Slogwang { 514*a9643ea8Slogwang // 1. ÿ�μ��β�ռ�, �ռ������ʼ״̬, �����¿ռ� 515*a9643ea8Slogwang TSkBuffer* item = TAILQ_LAST(&cache->list, __sk_buff_list); 516*a9643ea8Slogwang if ((NULL == item) 517*a9643ea8Slogwang || ((item->data_len + item->data) >= item->end)) 518*a9643ea8Slogwang { 519*a9643ea8Slogwang item = alloc_sk_buffer(cache->pool); 520*a9643ea8Slogwang if (item == NULL) 521*a9643ea8Slogwang { 522*a9643ea8Slogwang return -2; 523*a9643ea8Slogwang } 524*a9643ea8Slogwang cache_append_buffer(cache, item); 525*a9643ea8Slogwang } 526*a9643ea8Slogwang 527*a9643ea8Slogwang // 2. ����������size��С, Ĭ��64K 528*a9643ea8Slogwang uint8_t* buff = item->data + item->data_len; 529*a9643ea8Slogwang uint32_t remain = item->end - item->data - item->data_len; 530*a9643ea8Slogwang mt_hook_syscall(recv); 531*a9643ea8Slogwang int32_t recvd_len = ff_hook_recv(fd, buff, remain, 0); 532*a9643ea8Slogwang if (recvd_len == 0) 533*a9643ea8Slogwang { 534*a9643ea8Slogwang MTLOG_DEBUG("remote close, socket: %d", fd); 535*a9643ea8Slogwang return -SK_ERR_NEED_CLOSE; 536*a9643ea8Slogwang } 537*a9643ea8Slogwang else if (recvd_len < 0) 538*a9643ea8Slogwang { 539*a9643ea8Slogwang if (errno == EAGAIN) 540*a9643ea8Slogwang { 541*a9643ea8Slogwang return total; 542*a9643ea8Slogwang } 543*a9643ea8Slogwang else 544*a9643ea8Slogwang { 545*a9643ea8Slogwang MTLOG_ERROR("recv tcp socket failed, error: %d[%m]", errno); 546*a9643ea8Slogwang return -2; 547*a9643ea8Slogwang } 548*a9643ea8Slogwang } 549*a9643ea8Slogwang else 550*a9643ea8Slogwang { 551*a9643ea8Slogwang item->data_len += recvd_len; 552*a9643ea8Slogwang cache->len += recvd_len; 553*a9643ea8Slogwang total += recvd_len; 554*a9643ea8Slogwang if (recvd_len < (int32_t)remain) // �ղ���, ����Ϊ����OK 555*a9643ea8Slogwang { 556*a9643ea8Slogwang return total; 557*a9643ea8Slogwang } 558*a9643ea8Slogwang } 559*a9643ea8Slogwang } 560*a9643ea8Slogwang 561*a9643ea8Slogwang return total; 562*a9643ea8Slogwang } 563*a9643ea8Slogwang 564*a9643ea8Slogwang /** 565*a9643ea8Slogwang * @brief Cache���ϵ�TCP���ͽӿ� 566*a9643ea8Slogwang * @param cache -�����ָ�� 567*a9643ea8Slogwang * @param fd - ��������fd��� 568*a9643ea8Slogwang * @return ʵ�ʷ��ͳ��� 569*a9643ea8Slogwang */ 570*a9643ea8Slogwang int32_t cache_tcp_send(TRWCache* cache, uint32_t fd) 571*a9643ea8Slogwang { 572*a9643ea8Slogwang if ((NULL == cache) || (NULL == cache->pool)) 573*a9643ea8Slogwang { 574*a9643ea8Slogwang return -1; 575*a9643ea8Slogwang } 576*a9643ea8Slogwang 577*a9643ea8Slogwang if (cache->len == 0) 578*a9643ea8Slogwang { 579*a9643ea8Slogwang return 0; 580*a9643ea8Slogwang } 581*a9643ea8Slogwang 582*a9643ea8Slogwang 583*a9643ea8Slogwang int32_t ret = 0, total = 0; 584*a9643ea8Slogwang TSkBuffer* item = NULL; 585*a9643ea8Slogwang TSkBuffer* tmp = NULL; 586*a9643ea8Slogwang TAILQ_FOREACH_SAFE(item, &cache->list, entry, tmp) 587*a9643ea8Slogwang { 588*a9643ea8Slogwang mt_hook_syscall(send); 589*a9643ea8Slogwang ret = ff_hook_send(fd, item->data, item->data_len, 0); 590*a9643ea8Slogwang if (ret < 0) 591*a9643ea8Slogwang { 592*a9643ea8Slogwang break; 593*a9643ea8Slogwang } 594*a9643ea8Slogwang 595*a9643ea8Slogwang total += ret; 596*a9643ea8Slogwang if (ret < (int32_t)item->data_len) 597*a9643ea8Slogwang { 598*a9643ea8Slogwang break; 599*a9643ea8Slogwang } 600*a9643ea8Slogwang } 601*a9643ea8Slogwang 602*a9643ea8Slogwang cache_skip_data(cache, total); 603*a9643ea8Slogwang if (ret < 0) 604*a9643ea8Slogwang { 605*a9643ea8Slogwang if (errno != EAGAIN) 606*a9643ea8Slogwang { 607*a9643ea8Slogwang MTLOG_ERROR("tcp socket send failed, error: %d[%m]", errno); 608*a9643ea8Slogwang return -2; 609*a9643ea8Slogwang } 610*a9643ea8Slogwang } 611*a9643ea8Slogwang 612*a9643ea8Slogwang return total; 613*a9643ea8Slogwang } 614*a9643ea8Slogwang 615*a9643ea8Slogwang 616*a9643ea8Slogwang /** 617*a9643ea8Slogwang * @brief Cache���ϵ�TCP���ͽӿ�, δʹ��IOVEC 618*a9643ea8Slogwang * @param cache -�����ָ�� 619*a9643ea8Slogwang * @param fd - ��������fd��� 620*a9643ea8Slogwang * @param data -������cache��, �������͵�buff 621*a9643ea8Slogwang * @param len -�������͵�buff���� 622*a9643ea8Slogwang * @return ʵ�ʷ��ͳ��� 623*a9643ea8Slogwang */ 624*a9643ea8Slogwang int32_t cache_tcp_send_buff(TRWCache* cache, uint32_t fd, const void* data, uint32_t len) 625*a9643ea8Slogwang { 626*a9643ea8Slogwang if ((NULL == cache) || (NULL == data)) 627*a9643ea8Slogwang { 628*a9643ea8Slogwang return -1; 629*a9643ea8Slogwang } 630*a9643ea8Slogwang 631*a9643ea8Slogwang // 1. ���ȷ���CACHE���� 632*a9643ea8Slogwang int32_t ret = cache_tcp_send(cache, fd); 633*a9643ea8Slogwang if (ret < 0) 634*a9643ea8Slogwang { 635*a9643ea8Slogwang MTLOG_ERROR("tcp socket[%d] send cache data failed, rc: %d", fd, ret); 636*a9643ea8Slogwang return ret; 637*a9643ea8Slogwang } 638*a9643ea8Slogwang 639*a9643ea8Slogwang // 2. CACHE�Ѿ������� 640*a9643ea8Slogwang int32_t send_len = 0; 641*a9643ea8Slogwang if (cache->len == 0) 642*a9643ea8Slogwang { 643*a9643ea8Slogwang mt_hook_syscall(send); 644*a9643ea8Slogwang ret = ff_hook_send(fd, data, len, 0); 645*a9643ea8Slogwang if (ret >= 0) 646*a9643ea8Slogwang { 647*a9643ea8Slogwang send_len += ret; 648*a9643ea8Slogwang } 649*a9643ea8Slogwang else 650*a9643ea8Slogwang { 651*a9643ea8Slogwang if (errno != EAGAIN) 652*a9643ea8Slogwang { 653*a9643ea8Slogwang MTLOG_ERROR("tcp socket[%d] send failed, error: %d[%m]", fd, errno); 654*a9643ea8Slogwang return -2; 655*a9643ea8Slogwang } 656*a9643ea8Slogwang } 657*a9643ea8Slogwang } 658*a9643ea8Slogwang 659*a9643ea8Slogwang int32_t rc = cache_append_data(cache, (char*)data + send_len, len - send_len); 660*a9643ea8Slogwang if (rc < 0) 661*a9643ea8Slogwang { 662*a9643ea8Slogwang MTLOG_ERROR("tcp socket[%d] apend data failed, rc: %d", fd, rc); 663*a9643ea8Slogwang return -3; 664*a9643ea8Slogwang } 665*a9643ea8Slogwang 666*a9643ea8Slogwang return send_len; 667*a9643ea8Slogwang } 668*a9643ea8Slogwang 669*a9643ea8Slogwang 670*a9643ea8Slogwang /** 671*a9643ea8Slogwang * @brief ��ȡcache��Ч�����ܳ��� 672*a9643ea8Slogwang * @param multi -�����ָ�� 673*a9643ea8Slogwang * @return ʵ����Ч���ݳ��� 674*a9643ea8Slogwang */ 675*a9643ea8Slogwang uint32_t get_data_len(TBuffVecPtr multi) 676*a9643ea8Slogwang { 677*a9643ea8Slogwang TRWCache* cache = (TRWCache*)multi; 678*a9643ea8Slogwang if (NULL == cache) { 679*a9643ea8Slogwang return 0; 680*a9643ea8Slogwang } else { 681*a9643ea8Slogwang return cache->len; 682*a9643ea8Slogwang } 683*a9643ea8Slogwang } 684*a9643ea8Slogwang 685*a9643ea8Slogwang /** 686*a9643ea8Slogwang * @brief ��ȡcache��Ч���ݿ���� 687*a9643ea8Slogwang * @param multi -�����ָ�� 688*a9643ea8Slogwang * @return ʵ����Ч���ݿ���� 689*a9643ea8Slogwang */ 690*a9643ea8Slogwang uint32_t get_block_count(TBuffVecPtr multi) 691*a9643ea8Slogwang { 692*a9643ea8Slogwang TRWCache* cache = (TRWCache*)multi; 693*a9643ea8Slogwang if (NULL == cache) { 694*a9643ea8Slogwang return 0; 695*a9643ea8Slogwang } else { 696*a9643ea8Slogwang return cache->count; 697*a9643ea8Slogwang } 698*a9643ea8Slogwang } 699*a9643ea8Slogwang 700*a9643ea8Slogwang /** 701*a9643ea8Slogwang * @brief ��ȡcache�ĵ�һ������ָ�� 702*a9643ea8Slogwang * @param multi -�����ָ�� 703*a9643ea8Slogwang * @return ��һ������ָ�� 704*a9643ea8Slogwang */ 705*a9643ea8Slogwang TBuffBlockPtr get_first_block(TBuffVecPtr multi) 706*a9643ea8Slogwang { 707*a9643ea8Slogwang TRWCache* cache = (TRWCache*)multi; 708*a9643ea8Slogwang if (NULL == cache) { 709*a9643ea8Slogwang return NULL; 710*a9643ea8Slogwang } else { 711*a9643ea8Slogwang return (TBuffBlockPtr)TAILQ_FIRST(&cache->list); 712*a9643ea8Slogwang } 713*a9643ea8Slogwang } 714*a9643ea8Slogwang 715*a9643ea8Slogwang /** 716*a9643ea8Slogwang * @brief ��ȡcache����һ������ָ�� 717*a9643ea8Slogwang * @param multi -�����ָ�� 718*a9643ea8Slogwang * @param block -��ǰ��ָ�� 719*a9643ea8Slogwang * @return ��һ������ָ�� 720*a9643ea8Slogwang */ 721*a9643ea8Slogwang TBuffBlockPtr get_next_block(TBuffVecPtr multi, TBuffBlockPtr block) 722*a9643ea8Slogwang { 723*a9643ea8Slogwang TRWCache* cache = (TRWCache*)multi; 724*a9643ea8Slogwang TSkBuffer* item = (TSkBuffer*)block; 725*a9643ea8Slogwang if ((NULL == cache) || (NULL == item)) 726*a9643ea8Slogwang { 727*a9643ea8Slogwang return NULL; 728*a9643ea8Slogwang } 729*a9643ea8Slogwang 730*a9643ea8Slogwang return (TBuffBlockPtr)TAILQ_NEXT(item, entry); 731*a9643ea8Slogwang 732*a9643ea8Slogwang } 733*a9643ea8Slogwang 734*a9643ea8Slogwang /** 735*a9643ea8Slogwang * @brief ��ȡ���ݿ��ָ�������ݳ��� 736*a9643ea8Slogwang * @param block -��ǰ��ָ�� 737*a9643ea8Slogwang * @param data -����ָ��-modify���� 738*a9643ea8Slogwang * @param len -����ָ�� modify���� 739*a9643ea8Slogwang */ 740*a9643ea8Slogwang void get_block_data(TBuffBlockPtr block, const void** data, int32_t* len) 741*a9643ea8Slogwang { 742*a9643ea8Slogwang TSkBuffer* item = (TSkBuffer*)block; 743*a9643ea8Slogwang if (NULL == block) 744*a9643ea8Slogwang { 745*a9643ea8Slogwang return; 746*a9643ea8Slogwang } 747*a9643ea8Slogwang 748*a9643ea8Slogwang if (data != NULL) 749*a9643ea8Slogwang { 750*a9643ea8Slogwang *(uint8_t**)data = item->data; 751*a9643ea8Slogwang } 752*a9643ea8Slogwang 753*a9643ea8Slogwang if (len != NULL) 754*a9643ea8Slogwang { 755*a9643ea8Slogwang *len = (int32_t)item->data_len; 756*a9643ea8Slogwang } 757*a9643ea8Slogwang } 758*a9643ea8Slogwang 759*a9643ea8Slogwang 760*a9643ea8Slogwang /** 761*a9643ea8Slogwang * @brief ��ȡ���ݿ��ָ�������ݳ��� 762*a9643ea8Slogwang * @param multi -�����ָ�� 763*a9643ea8Slogwang * @param data -����д������ָ�� 764*a9643ea8Slogwang * @param len -���� 765*a9643ea8Slogwang * @return ���ݶ�ȡ�����ݳ��� 766*a9643ea8Slogwang */ 767*a9643ea8Slogwang uint32_t read_cache_data(TBuffVecPtr multi, void* data, uint32_t len) 768*a9643ea8Slogwang { 769*a9643ea8Slogwang TRWCache* cache = (TRWCache*)multi; 770*a9643ea8Slogwang if (NULL == cache) { 771*a9643ea8Slogwang return 0; 772*a9643ea8Slogwang } 773*a9643ea8Slogwang 774*a9643ea8Slogwang uint32_t left_len = len; 775*a9643ea8Slogwang uint32_t offset = 0; 776*a9643ea8Slogwang TSkBuffer* item = NULL; 777*a9643ea8Slogwang TSkBuffer* tmp = NULL; 778*a9643ea8Slogwang TAILQ_FOREACH_SAFE(item, &cache->list, entry, tmp) 779*a9643ea8Slogwang { 780*a9643ea8Slogwang uint32_t copy_len = 0; 781*a9643ea8Slogwang if (left_len <= item->data_len) 782*a9643ea8Slogwang { 783*a9643ea8Slogwang copy_len = left_len; 784*a9643ea8Slogwang } 785*a9643ea8Slogwang else 786*a9643ea8Slogwang { 787*a9643ea8Slogwang copy_len = item->data_len; 788*a9643ea8Slogwang } 789*a9643ea8Slogwang 790*a9643ea8Slogwang if (data != NULL) 791*a9643ea8Slogwang { 792*a9643ea8Slogwang memcpy((char*)data + offset, item->data, copy_len); 793*a9643ea8Slogwang } 794*a9643ea8Slogwang offset += copy_len; 795*a9643ea8Slogwang left_len -= copy_len; 796*a9643ea8Slogwang 797*a9643ea8Slogwang if (left_len <= 0) 798*a9643ea8Slogwang { 799*a9643ea8Slogwang break; 800*a9643ea8Slogwang } 801*a9643ea8Slogwang } 802*a9643ea8Slogwang 803*a9643ea8Slogwang return offset; 804*a9643ea8Slogwang } 805*a9643ea8Slogwang 806*a9643ea8Slogwang 807*a9643ea8Slogwang 808*a9643ea8Slogwang /** 809*a9643ea8Slogwang * @brief ��ȡ���ݿ��ָ�������ݳ��� 810*a9643ea8Slogwang * @param multi -�����ָ�� 811*a9643ea8Slogwang * @param data -����д������ָ�� 812*a9643ea8Slogwang * @param len -���� 813*a9643ea8Slogwang * @return ���ݶ�ȡ�����ݳ��� 814*a9643ea8Slogwang */ 815*a9643ea8Slogwang uint32_t read_cache_begin(TBuffVecPtr multi, uint32_t begin, void* data, uint32_t len) 816*a9643ea8Slogwang { 817*a9643ea8Slogwang TRWCache* cache = (TRWCache*)multi; 818*a9643ea8Slogwang if (NULL == cache) { 819*a9643ea8Slogwang return 0; 820*a9643ea8Slogwang } 821*a9643ea8Slogwang 822*a9643ea8Slogwang if (begin >= cache->len) { 823*a9643ea8Slogwang return 0; 824*a9643ea8Slogwang } 825*a9643ea8Slogwang 826*a9643ea8Slogwang uint32_t pos_left = begin; 827*a9643ea8Slogwang uint32_t copy_left = len; 828*a9643ea8Slogwang uint32_t offset = 0; 829*a9643ea8Slogwang TSkBuffer* item = NULL; 830*a9643ea8Slogwang TAILQ_FOREACH(item, &cache->list, entry) 831*a9643ea8Slogwang { 832*a9643ea8Slogwang // 1. ��ʼλ����ʣ��, �������ò��� 833*a9643ea8Slogwang uint8_t* start_ptr = item->data; 834*a9643ea8Slogwang uint32_t real_left = item->data_len; 835*a9643ea8Slogwang if (pos_left > 0) 836*a9643ea8Slogwang { 837*a9643ea8Slogwang uint32_t skip_len = pos_left > real_left ? real_left : pos_left; 838*a9643ea8Slogwang pos_left -= skip_len; 839*a9643ea8Slogwang real_left -= skip_len; 840*a9643ea8Slogwang start_ptr += skip_len; 841*a9643ea8Slogwang } 842*a9643ea8Slogwang 843*a9643ea8Slogwang // 2. ����������ʣ��, ��ȴ���һ�� 844*a9643ea8Slogwang if (real_left == 0) 845*a9643ea8Slogwang { 846*a9643ea8Slogwang continue; 847*a9643ea8Slogwang } 848*a9643ea8Slogwang 849*a9643ea8Slogwang // 3. ��ʣ��, ����������� 850*a9643ea8Slogwang uint32_t copy_len = copy_left > real_left ? real_left : copy_left; 851*a9643ea8Slogwang if (data != NULL) 852*a9643ea8Slogwang { 853*a9643ea8Slogwang memcpy((char*)data + offset, start_ptr, copy_len); 854*a9643ea8Slogwang } 855*a9643ea8Slogwang offset += copy_len; 856*a9643ea8Slogwang copy_left -= copy_len; 857*a9643ea8Slogwang if (copy_left == 0) 858*a9643ea8Slogwang { 859*a9643ea8Slogwang break; 860*a9643ea8Slogwang } 861*a9643ea8Slogwang } 862*a9643ea8Slogwang 863*a9643ea8Slogwang return offset; 864*a9643ea8Slogwang } 865*a9643ea8Slogwang 866*a9643ea8Slogwang 867*a9643ea8Slogwang 868*a9643ea8Slogwang }; 869*a9643ea8Slogwang 870