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 * @file mt_connection.cpp 22*a9643ea8Slogwang * @info �߳���Ϣ�������ӹ���ʵ�� 23*a9643ea8Slogwang * @time 20130924 24*a9643ea8Slogwang **/ 25*a9643ea8Slogwang #include <fcntl.h> 26*a9643ea8Slogwang #include <sys/types.h> 27*a9643ea8Slogwang #include <sys/socket.h> 28*a9643ea8Slogwang #include <netinet/in.h> 29*a9643ea8Slogwang #include <arpa/inet.h> 30*a9643ea8Slogwang 31*a9643ea8Slogwang #include "micro_thread.h" 32*a9643ea8Slogwang #include "mt_msg.h" 33*a9643ea8Slogwang #include "mt_notify.h" 34*a9643ea8Slogwang #include "mt_connection.h" 35*a9643ea8Slogwang #include "mt_sys_hook.h" 36*a9643ea8Slogwang #include "ff_hook.h" 37*a9643ea8Slogwang 38*a9643ea8Slogwang using namespace std; 39*a9643ea8Slogwang using namespace NS_MICRO_THREAD; 40*a9643ea8Slogwang 41*a9643ea8Slogwang 42*a9643ea8Slogwang /** 43*a9643ea8Slogwang * @brief �߳����ӻ���������� 44*a9643ea8Slogwang */ 45*a9643ea8Slogwang IMtConnection::IMtConnection() 46*a9643ea8Slogwang { 47*a9643ea8Slogwang _type = OBJ_CONN_UNDEF; 48*a9643ea8Slogwang _action = NULL; 49*a9643ea8Slogwang _ntfy_obj = NULL; 50*a9643ea8Slogwang _msg_buff = NULL; 51*a9643ea8Slogwang } 52*a9643ea8Slogwang IMtConnection::~IMtConnection() 53*a9643ea8Slogwang { 54*a9643ea8Slogwang if (_ntfy_obj) { 55*a9643ea8Slogwang NtfyObjMgr::Instance()->FreeNtfyObj(_ntfy_obj); 56*a9643ea8Slogwang _ntfy_obj = NULL; 57*a9643ea8Slogwang } 58*a9643ea8Slogwang 59*a9643ea8Slogwang if (_msg_buff) { 60*a9643ea8Slogwang MsgBuffPool::Instance()->FreeMsgBuf(_msg_buff); 61*a9643ea8Slogwang _msg_buff = NULL; 62*a9643ea8Slogwang } 63*a9643ea8Slogwang } 64*a9643ea8Slogwang 65*a9643ea8Slogwang 66*a9643ea8Slogwang /** 67*a9643ea8Slogwang * @brief ���ӻ��ո���������� 68*a9643ea8Slogwang */ 69*a9643ea8Slogwang void IMtConnection::Reset() 70*a9643ea8Slogwang { 71*a9643ea8Slogwang if (_ntfy_obj) { 72*a9643ea8Slogwang NtfyObjMgr::Instance()->FreeNtfyObj(_ntfy_obj); 73*a9643ea8Slogwang _ntfy_obj = NULL; 74*a9643ea8Slogwang } 75*a9643ea8Slogwang 76*a9643ea8Slogwang if (_msg_buff) { 77*a9643ea8Slogwang MsgBuffPool::Instance()->FreeMsgBuf(_msg_buff); 78*a9643ea8Slogwang _msg_buff = NULL; 79*a9643ea8Slogwang } 80*a9643ea8Slogwang 81*a9643ea8Slogwang _action = NULL; 82*a9643ea8Slogwang _ntfy_obj = NULL; 83*a9643ea8Slogwang _msg_buff = NULL; 84*a9643ea8Slogwang } 85*a9643ea8Slogwang 86*a9643ea8Slogwang 87*a9643ea8Slogwang /** 88*a9643ea8Slogwang * @brief ���ӵ�socket����, �������ӵ�Э�����͵� 89*a9643ea8Slogwang * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ�� 90*a9643ea8Slogwang */ 91*a9643ea8Slogwang int UdpShortConn::CreateSocket() 92*a9643ea8Slogwang { 93*a9643ea8Slogwang // 1. UDP������, ÿ���´�SOCKET 94*a9643ea8Slogwang _osfd = socket(AF_INET, SOCK_DGRAM, 0); 95*a9643ea8Slogwang if (_osfd < 0) 96*a9643ea8Slogwang { 97*a9643ea8Slogwang MTLOG_ERROR("socket create failed, errno %d(%s)", errno, strerror(errno)); 98*a9643ea8Slogwang return -1; 99*a9643ea8Slogwang } 100*a9643ea8Slogwang 101*a9643ea8Slogwang // 2. ���������� 102*a9643ea8Slogwang int flags = 1; 103*a9643ea8Slogwang if (ioctl(_osfd, FIONBIO, &flags) < 0) 104*a9643ea8Slogwang { 105*a9643ea8Slogwang MTLOG_ERROR("socket unblock failed, errno %d(%s)", errno, strerror(errno)); 106*a9643ea8Slogwang close(_osfd); 107*a9643ea8Slogwang _osfd = -1; 108*a9643ea8Slogwang return -2; 109*a9643ea8Slogwang } 110*a9643ea8Slogwang 111*a9643ea8Slogwang // 3. ���¹�����Ϣ 112*a9643ea8Slogwang if (_ntfy_obj) { 113*a9643ea8Slogwang _ntfy_obj->SetOsfd(_osfd); 114*a9643ea8Slogwang } 115*a9643ea8Slogwang 116*a9643ea8Slogwang return _osfd; 117*a9643ea8Slogwang } 118*a9643ea8Slogwang 119*a9643ea8Slogwang /** 120*a9643ea8Slogwang * @brief �ر�ϵͳsocket, ����һЩ״̬ 121*a9643ea8Slogwang */ 122*a9643ea8Slogwang int UdpShortConn::CloseSocket() 123*a9643ea8Slogwang { 124*a9643ea8Slogwang if (_osfd < 0) 125*a9643ea8Slogwang { 126*a9643ea8Slogwang return 0; 127*a9643ea8Slogwang } 128*a9643ea8Slogwang 129*a9643ea8Slogwang close(_osfd); 130*a9643ea8Slogwang _osfd = -1; 131*a9643ea8Slogwang 132*a9643ea8Slogwang return 0; 133*a9643ea8Slogwang } 134*a9643ea8Slogwang 135*a9643ea8Slogwang 136*a9643ea8Slogwang /** 137*a9643ea8Slogwang * @brief ���Է�������, ������һ�� 138*a9643ea8Slogwang * @return 0 ���ͱ��ж�, ������. <0 ϵͳʧ��. >0 ���η��ͳɹ� 139*a9643ea8Slogwang */ 140*a9643ea8Slogwang int UdpShortConn::SendData() 141*a9643ea8Slogwang { 142*a9643ea8Slogwang if (!_action || !_msg_buff) { 143*a9643ea8Slogwang MTLOG_ERROR("conn not set action %p, or msg %p, error", _action, _msg_buff); 144*a9643ea8Slogwang return -100; 145*a9643ea8Slogwang } 146*a9643ea8Slogwang 147*a9643ea8Slogwang mt_hook_syscall(sendto); 148*a9643ea8Slogwang int ret = ff_hook_sendto(_osfd, _msg_buff->GetMsgBuff(), _msg_buff->GetMsgLen(), 0, 149*a9643ea8Slogwang (struct sockaddr*)_action->GetMsgDstAddr(), sizeof(struct sockaddr_in)); 150*a9643ea8Slogwang if (ret == -1) 151*a9643ea8Slogwang { 152*a9643ea8Slogwang if ((errno == EINTR) || (errno == EAGAIN) || (errno == EINPROGRESS)) 153*a9643ea8Slogwang { 154*a9643ea8Slogwang return 0; 155*a9643ea8Slogwang } 156*a9643ea8Slogwang else 157*a9643ea8Slogwang { 158*a9643ea8Slogwang MTLOG_ERROR("socket send failed, fd %d, errno %d(%s)", _osfd, 159*a9643ea8Slogwang errno, strerror(errno)); 160*a9643ea8Slogwang return -2; 161*a9643ea8Slogwang } 162*a9643ea8Slogwang } 163*a9643ea8Slogwang else 164*a9643ea8Slogwang { 165*a9643ea8Slogwang _msg_buff->SetHaveSndLen(ret); 166*a9643ea8Slogwang return ret; 167*a9643ea8Slogwang } 168*a9643ea8Slogwang } 169*a9643ea8Slogwang 170*a9643ea8Slogwang /** 171*a9643ea8Slogwang * @brief ���Խ�������, ������һ�� 172*a9643ea8Slogwang * @param buff ���ջ�����ָ�� 173*a9643ea8Slogwang * @return -1 �Զ˹ر�. -2 ϵͳʧ��. >0 ���ν��ճɹ� 174*a9643ea8Slogwang */ 175*a9643ea8Slogwang int UdpShortConn::RecvData() 176*a9643ea8Slogwang { 177*a9643ea8Slogwang if (!_action || !_msg_buff) { 178*a9643ea8Slogwang MTLOG_ERROR("conn not set action %p, or msg %p, error", _action, _msg_buff); 179*a9643ea8Slogwang return -100; 180*a9643ea8Slogwang } 181*a9643ea8Slogwang 182*a9643ea8Slogwang struct sockaddr_in from; 183*a9643ea8Slogwang socklen_t fromlen = sizeof(from); 184*a9643ea8Slogwang mt_hook_syscall(recvfrom); 185*a9643ea8Slogwang int ret = ff_hook_recvfrom(_osfd, _msg_buff->GetMsgBuff(), _msg_buff->GetMaxLen(), 186*a9643ea8Slogwang 0, (struct sockaddr*)&from, &fromlen); 187*a9643ea8Slogwang if (ret < 0) 188*a9643ea8Slogwang { 189*a9643ea8Slogwang if ((errno == EINTR) || (errno == EAGAIN) || (errno == EINPROGRESS)) 190*a9643ea8Slogwang { 191*a9643ea8Slogwang return 0; 192*a9643ea8Slogwang } 193*a9643ea8Slogwang else 194*a9643ea8Slogwang { 195*a9643ea8Slogwang MTLOG_ERROR("socket recv failed, fd %d, errno %d(%s)", _osfd, 196*a9643ea8Slogwang errno, strerror(errno)); 197*a9643ea8Slogwang return -2; // ϵͳ���� 198*a9643ea8Slogwang } 199*a9643ea8Slogwang } 200*a9643ea8Slogwang else if (ret == 0) 201*a9643ea8Slogwang { 202*a9643ea8Slogwang return -1; // �Զ˹ر� 203*a9643ea8Slogwang } 204*a9643ea8Slogwang else 205*a9643ea8Slogwang { 206*a9643ea8Slogwang _msg_buff->SetHaveRcvLen(ret); 207*a9643ea8Slogwang } 208*a9643ea8Slogwang 209*a9643ea8Slogwang // �����ļ��, >0 �հ�����; =0 �����ȴ�; <0(-65535����)�����쳣 210*a9643ea8Slogwang ret = _action->DoInput(); 211*a9643ea8Slogwang if (ret > 0) 212*a9643ea8Slogwang { 213*a9643ea8Slogwang _msg_buff->SetMsgLen(ret); 214*a9643ea8Slogwang return ret; 215*a9643ea8Slogwang } 216*a9643ea8Slogwang else if (ret == 0) 217*a9643ea8Slogwang { 218*a9643ea8Slogwang return 0; 219*a9643ea8Slogwang } 220*a9643ea8Slogwang else if (ret == -65535) 221*a9643ea8Slogwang { 222*a9643ea8Slogwang _msg_buff->SetHaveRcvLen(0); 223*a9643ea8Slogwang return 0; 224*a9643ea8Slogwang } 225*a9643ea8Slogwang else 226*a9643ea8Slogwang { 227*a9643ea8Slogwang return -1; 228*a9643ea8Slogwang } 229*a9643ea8Slogwang } 230*a9643ea8Slogwang 231*a9643ea8Slogwang /** 232*a9643ea8Slogwang * @brief ���ӻ��ո���������� 233*a9643ea8Slogwang */ 234*a9643ea8Slogwang void UdpShortConn::Reset() 235*a9643ea8Slogwang { 236*a9643ea8Slogwang CloseSocket(); 237*a9643ea8Slogwang this->IMtConnection::Reset(); 238*a9643ea8Slogwang } 239*a9643ea8Slogwang 240*a9643ea8Slogwang 241*a9643ea8Slogwang /** 242*a9643ea8Slogwang * @brief ���Ӵ���Զ�˻Ựͨ��, ��TCP��connect�� 243*a9643ea8Slogwang * @return 0 -�ɹ�, < 0 ʧ�� 244*a9643ea8Slogwang */ 245*a9643ea8Slogwang int TcpKeepConn::OpenCnnect() 246*a9643ea8Slogwang { 247*a9643ea8Slogwang if (!_action || !_msg_buff) { 248*a9643ea8Slogwang MTLOG_ERROR("conn not set action %p, or msg %p, error", _action, _msg_buff); 249*a9643ea8Slogwang return -100; 250*a9643ea8Slogwang } 251*a9643ea8Slogwang 252*a9643ea8Slogwang int err = 0; 253*a9643ea8Slogwang mt_hook_syscall(connect); 254*a9643ea8Slogwang int ret = ff_hook_connect(_osfd, (struct sockaddr*)_action->GetMsgDstAddr(), sizeof(struct sockaddr_in)); 255*a9643ea8Slogwang if (ret < 0) 256*a9643ea8Slogwang { 257*a9643ea8Slogwang err = errno; 258*a9643ea8Slogwang if (err == EISCONN) 259*a9643ea8Slogwang { 260*a9643ea8Slogwang return 0; 261*a9643ea8Slogwang } 262*a9643ea8Slogwang else 263*a9643ea8Slogwang { 264*a9643ea8Slogwang if ((err == EINPROGRESS) || (err == EALREADY) || (err == EINTR)) 265*a9643ea8Slogwang { 266*a9643ea8Slogwang MTLOG_DEBUG("Open connect not ok, maybe first try, sock %d, errno %d", _osfd, err); 267*a9643ea8Slogwang return -1; 268*a9643ea8Slogwang } 269*a9643ea8Slogwang else 270*a9643ea8Slogwang { 271*a9643ea8Slogwang MTLOG_ERROR("Open connect not ok, sock %d, errno %d", _osfd, err); 272*a9643ea8Slogwang return -2; 273*a9643ea8Slogwang } 274*a9643ea8Slogwang } 275*a9643ea8Slogwang } 276*a9643ea8Slogwang else 277*a9643ea8Slogwang { 278*a9643ea8Slogwang return 0; 279*a9643ea8Slogwang } 280*a9643ea8Slogwang } 281*a9643ea8Slogwang 282*a9643ea8Slogwang /** 283*a9643ea8Slogwang * @brief ����sock��TCP�������� 284*a9643ea8Slogwang */ 285*a9643ea8Slogwang int TcpKeepConn::CreateSocket() 286*a9643ea8Slogwang { 287*a9643ea8Slogwang if (_osfd > 0) // ��������ʱ, ��������������; ������������ntfyfd 288*a9643ea8Slogwang { 289*a9643ea8Slogwang if (_ntfy_obj) { 290*a9643ea8Slogwang _ntfy_obj->SetOsfd(_osfd); 291*a9643ea8Slogwang } 292*a9643ea8Slogwang 293*a9643ea8Slogwang return _osfd; 294*a9643ea8Slogwang } 295*a9643ea8Slogwang 296*a9643ea8Slogwang // ��һ�ν���ʱ, ����socket 297*a9643ea8Slogwang _osfd = socket(AF_INET, SOCK_STREAM, 0); 298*a9643ea8Slogwang if (_osfd < 0) 299*a9643ea8Slogwang { 300*a9643ea8Slogwang MTLOG_ERROR("create tcp socket failed, error: %d", errno); 301*a9643ea8Slogwang return -1; 302*a9643ea8Slogwang } 303*a9643ea8Slogwang 304*a9643ea8Slogwang // ���������� 305*a9643ea8Slogwang int flags = 1; 306*a9643ea8Slogwang if (ioctl(_osfd, FIONBIO, &flags) < 0) 307*a9643ea8Slogwang { 308*a9643ea8Slogwang MTLOG_ERROR("set tcp socket unblock failed, error: %d", errno); 309*a9643ea8Slogwang close(_osfd); 310*a9643ea8Slogwang _osfd = -1; 311*a9643ea8Slogwang return -2; 312*a9643ea8Slogwang } 313*a9643ea8Slogwang 314*a9643ea8Slogwang // ���¹�����Ϣ 315*a9643ea8Slogwang _keep_ntfy.SetOsfd(_osfd); 316*a9643ea8Slogwang _keep_ntfy.DisableOutput(); 317*a9643ea8Slogwang _keep_ntfy.EnableInput(); 318*a9643ea8Slogwang 319*a9643ea8Slogwang if (_ntfy_obj) { 320*a9643ea8Slogwang _ntfy_obj->SetOsfd(_osfd); 321*a9643ea8Slogwang } 322*a9643ea8Slogwang 323*a9643ea8Slogwang return _osfd; 324*a9643ea8Slogwang } 325*a9643ea8Slogwang 326*a9643ea8Slogwang /** 327*a9643ea8Slogwang * @brief ���Է�������, ������һ�� 328*a9643ea8Slogwang * @param dst ����Ŀ�ĵ�ַ 329*a9643ea8Slogwang * @param buff ���ͻ�����ָ�� 330*a9643ea8Slogwang * @param size �����͵���� 331*a9643ea8Slogwang * @return 0 ���ͱ��ж�, ������. <0 ϵͳʧ��. >0 ���η��ͳɹ� 332*a9643ea8Slogwang */ 333*a9643ea8Slogwang int TcpKeepConn::SendData() 334*a9643ea8Slogwang { 335*a9643ea8Slogwang if (!_action || !_msg_buff) { 336*a9643ea8Slogwang MTLOG_ERROR("conn not set action %p, or msg %p, error", _action, _msg_buff); 337*a9643ea8Slogwang return -100; 338*a9643ea8Slogwang } 339*a9643ea8Slogwang 340*a9643ea8Slogwang char* msg_ptr = (char*)_msg_buff->GetMsgBuff(); 341*a9643ea8Slogwang int msg_len = _msg_buff->GetMsgLen(); 342*a9643ea8Slogwang int have_send_len = _msg_buff->GetHaveSndLen(); 343*a9643ea8Slogwang mt_hook_syscall(send); 344*a9643ea8Slogwang int ret = ff_hook_send(_osfd, msg_ptr + have_send_len, msg_len - have_send_len, 0); 345*a9643ea8Slogwang if (ret == -1) 346*a9643ea8Slogwang { 347*a9643ea8Slogwang if ((errno == EINTR) || (errno == EAGAIN) || (errno == EINPROGRESS)) 348*a9643ea8Slogwang { 349*a9643ea8Slogwang return 0; 350*a9643ea8Slogwang } 351*a9643ea8Slogwang else 352*a9643ea8Slogwang { 353*a9643ea8Slogwang MTLOG_ERROR("send tcp socket failed, error: %d", errno); 354*a9643ea8Slogwang return -1; 355*a9643ea8Slogwang } 356*a9643ea8Slogwang } 357*a9643ea8Slogwang else 358*a9643ea8Slogwang { 359*a9643ea8Slogwang have_send_len += ret; 360*a9643ea8Slogwang _msg_buff->SetHaveSndLen(have_send_len); 361*a9643ea8Slogwang } 362*a9643ea8Slogwang 363*a9643ea8Slogwang // ȫ���������, ���سɹ�, ��������ȴ� 364*a9643ea8Slogwang if (have_send_len >= msg_len) 365*a9643ea8Slogwang { 366*a9643ea8Slogwang return msg_len; 367*a9643ea8Slogwang } 368*a9643ea8Slogwang else 369*a9643ea8Slogwang { 370*a9643ea8Slogwang return 0; 371*a9643ea8Slogwang } 372*a9643ea8Slogwang } 373*a9643ea8Slogwang 374*a9643ea8Slogwang /** 375*a9643ea8Slogwang * @brief ���Խ�������, ������һ�� 376*a9643ea8Slogwang * @param buff ���ջ�����ָ�� 377*a9643ea8Slogwang * @return -1 �Զ˹ر�. -2 ϵͳʧ��. >0 ���ν��ճɹ� 378*a9643ea8Slogwang */ 379*a9643ea8Slogwang int TcpKeepConn::RecvData() 380*a9643ea8Slogwang { 381*a9643ea8Slogwang if (!_action || !_msg_buff) { 382*a9643ea8Slogwang MTLOG_ERROR("conn not set action %p, or msg %p, error", _action, _msg_buff); 383*a9643ea8Slogwang return -100; 384*a9643ea8Slogwang } 385*a9643ea8Slogwang 386*a9643ea8Slogwang char* msg_ptr = (char*)_msg_buff->GetMsgBuff(); 387*a9643ea8Slogwang int max_len = _msg_buff->GetMaxLen(); 388*a9643ea8Slogwang int have_rcv_len = _msg_buff->GetHaveRcvLen(); 389*a9643ea8Slogwang mt_hook_syscall(recv); 390*a9643ea8Slogwang int ret = ff_hook_recv(_osfd, (char*)msg_ptr + have_rcv_len, max_len - have_rcv_len, 0); 391*a9643ea8Slogwang if (ret < 0) 392*a9643ea8Slogwang { 393*a9643ea8Slogwang if ((errno == EINTR) || (errno == EAGAIN) || (errno == EINPROGRESS)) 394*a9643ea8Slogwang { 395*a9643ea8Slogwang return 0; 396*a9643ea8Slogwang } 397*a9643ea8Slogwang else 398*a9643ea8Slogwang { 399*a9643ea8Slogwang MTLOG_ERROR("recv tcp socket failed, error: %d", errno); 400*a9643ea8Slogwang return -2; // ϵͳ���� 401*a9643ea8Slogwang } 402*a9643ea8Slogwang } 403*a9643ea8Slogwang else if (ret == 0) 404*a9643ea8Slogwang { 405*a9643ea8Slogwang MTLOG_ERROR("tcp remote close, address: %s[%d]", 406*a9643ea8Slogwang inet_ntoa(_dst_addr.sin_addr), ntohs(_dst_addr.sin_port)); 407*a9643ea8Slogwang return -1; // �Զ˹ر� 408*a9643ea8Slogwang } 409*a9643ea8Slogwang else 410*a9643ea8Slogwang { 411*a9643ea8Slogwang have_rcv_len += ret; 412*a9643ea8Slogwang _msg_buff->SetHaveRcvLen(have_rcv_len); 413*a9643ea8Slogwang } 414*a9643ea8Slogwang 415*a9643ea8Slogwang // �����ļ��, >0 �հ�����; =0 �����ȴ�; <0(-65535����)�����쳣 416*a9643ea8Slogwang ret = _action->DoInput(); 417*a9643ea8Slogwang if (ret > 0) 418*a9643ea8Slogwang { 419*a9643ea8Slogwang _msg_buff->SetMsgLen(have_rcv_len); 420*a9643ea8Slogwang return ret; 421*a9643ea8Slogwang } 422*a9643ea8Slogwang else if (ret == 0) 423*a9643ea8Slogwang { 424*a9643ea8Slogwang return 0; 425*a9643ea8Slogwang } 426*a9643ea8Slogwang else 427*a9643ea8Slogwang { 428*a9643ea8Slogwang return -1; 429*a9643ea8Slogwang } 430*a9643ea8Slogwang } 431*a9643ea8Slogwang 432*a9643ea8Slogwang /** 433*a9643ea8Slogwang * @brief �ر�ϵͳsocket, ����һЩ״̬ 434*a9643ea8Slogwang */ 435*a9643ea8Slogwang int TcpKeepConn::CloseSocket() 436*a9643ea8Slogwang { 437*a9643ea8Slogwang if (_osfd < 0) 438*a9643ea8Slogwang { 439*a9643ea8Slogwang return 0; 440*a9643ea8Slogwang } 441*a9643ea8Slogwang _keep_ntfy.SetOsfd(-1); 442*a9643ea8Slogwang 443*a9643ea8Slogwang close(_osfd); 444*a9643ea8Slogwang _osfd = -1; 445*a9643ea8Slogwang 446*a9643ea8Slogwang return 0; 447*a9643ea8Slogwang } 448*a9643ea8Slogwang 449*a9643ea8Slogwang /** 450*a9643ea8Slogwang * @brief ���ӻ��ո���������� 451*a9643ea8Slogwang */ 452*a9643ea8Slogwang void TcpKeepConn::Reset() 453*a9643ea8Slogwang { 454*a9643ea8Slogwang memset(&_dst_addr, 0 ,sizeof(_dst_addr)); 455*a9643ea8Slogwang CloseSocket(); 456*a9643ea8Slogwang this->IMtConnection::Reset(); 457*a9643ea8Slogwang } 458*a9643ea8Slogwang 459*a9643ea8Slogwang /** 460*a9643ea8Slogwang * @brief ���ӻ��ո���������� 461*a9643ea8Slogwang */ 462*a9643ea8Slogwang void TcpKeepConn::ConnReuseClean() 463*a9643ea8Slogwang { 464*a9643ea8Slogwang this->IMtConnection::Reset(); 465*a9643ea8Slogwang } 466*a9643ea8Slogwang 467*a9643ea8Slogwang /** 468*a9643ea8Slogwang * @brief Idle���洦��, epoll ����Զ�˹رյ� 469*a9643ea8Slogwang */ 470*a9643ea8Slogwang bool TcpKeepConn::IdleAttach() 471*a9643ea8Slogwang { 472*a9643ea8Slogwang if (_osfd < 0) { 473*a9643ea8Slogwang MTLOG_ERROR("obj %p attach failed, fd %d error", this, _osfd); 474*a9643ea8Slogwang return false; 475*a9643ea8Slogwang } 476*a9643ea8Slogwang 477*a9643ea8Slogwang if (_keep_flag & TCP_KEEP_IN_KQUEUE) { 478*a9643ea8Slogwang MTLOG_ERROR("obj %p repeat attach, error", this); 479*a9643ea8Slogwang return true; 480*a9643ea8Slogwang } 481*a9643ea8Slogwang 482*a9643ea8Slogwang _keep_ntfy.DisableOutput(); 483*a9643ea8Slogwang _keep_ntfy.EnableInput(); 484*a9643ea8Slogwang 485*a9643ea8Slogwang // ���ʱ����� 486*a9643ea8Slogwang CTimerMng* timer = MtFrame::Instance()->GetTimerMng(); 487*a9643ea8Slogwang if ((NULL == timer) || !timer->start_timer(this, _keep_time)) 488*a9643ea8Slogwang { 489*a9643ea8Slogwang MTLOG_ERROR("obj %p attach timer failed, error", this); 490*a9643ea8Slogwang return false; 491*a9643ea8Slogwang } 492*a9643ea8Slogwang 493*a9643ea8Slogwang if (MtFrame::Instance()->KqueueAddObj(&_keep_ntfy)) 494*a9643ea8Slogwang { 495*a9643ea8Slogwang _keep_flag |= TCP_KEEP_IN_KQUEUE; 496*a9643ea8Slogwang return true; 497*a9643ea8Slogwang } 498*a9643ea8Slogwang else 499*a9643ea8Slogwang { 500*a9643ea8Slogwang MTLOG_ERROR("obj %p attach failed, error", this); 501*a9643ea8Slogwang return false; 502*a9643ea8Slogwang } 503*a9643ea8Slogwang } 504*a9643ea8Slogwang 505*a9643ea8Slogwang /** 506*a9643ea8Slogwang * @brief Idleȡ�����洦��, �����ɿ����߳�����Զ�˹ر� 507*a9643ea8Slogwang */ 508*a9643ea8Slogwang bool TcpKeepConn::IdleDetach() 509*a9643ea8Slogwang { 510*a9643ea8Slogwang if (_osfd < 0) { 511*a9643ea8Slogwang MTLOG_ERROR("obj %p detach failed, fd %d error", this, _osfd); 512*a9643ea8Slogwang return false; 513*a9643ea8Slogwang } 514*a9643ea8Slogwang 515*a9643ea8Slogwang if (!(_keep_flag & TCP_KEEP_IN_KQUEUE)) { 516*a9643ea8Slogwang MTLOG_DEBUG("obj %p repeat detach, error", this); 517*a9643ea8Slogwang return true; 518*a9643ea8Slogwang } 519*a9643ea8Slogwang 520*a9643ea8Slogwang _keep_ntfy.DisableOutput(); 521*a9643ea8Slogwang _keep_ntfy.EnableInput(); 522*a9643ea8Slogwang 523*a9643ea8Slogwang // ���ʱ��ɾ�� 524*a9643ea8Slogwang CTimerMng* timer = MtFrame::Instance()->GetTimerMng(); 525*a9643ea8Slogwang if (NULL != timer) 526*a9643ea8Slogwang { 527*a9643ea8Slogwang timer->stop_timer(this); 528*a9643ea8Slogwang } 529*a9643ea8Slogwang 530*a9643ea8Slogwang if (MtFrame::Instance()->KqueueDelObj(&_keep_ntfy)) 531*a9643ea8Slogwang { 532*a9643ea8Slogwang _keep_flag &= ~TCP_KEEP_IN_KQUEUE; 533*a9643ea8Slogwang return true; 534*a9643ea8Slogwang } 535*a9643ea8Slogwang else 536*a9643ea8Slogwang { 537*a9643ea8Slogwang MTLOG_ERROR("obj %p detach failed, error", this); 538*a9643ea8Slogwang return false; 539*a9643ea8Slogwang } 540*a9643ea8Slogwang } 541*a9643ea8Slogwang 542*a9643ea8Slogwang 543*a9643ea8Slogwang /** 544*a9643ea8Slogwang * @brief ��ʱ֪ͨ����, ����ʵ���� 545*a9643ea8Slogwang */ 546*a9643ea8Slogwang void TcpKeepConn::timer_notify() 547*a9643ea8Slogwang { 548*a9643ea8Slogwang MTLOG_DEBUG("keep timeout[%u], fd %d, close connection", _keep_time, _osfd); 549*a9643ea8Slogwang ConnectionMgr::Instance()->CloseIdleTcpKeep(this); 550*a9643ea8Slogwang } 551*a9643ea8Slogwang 552*a9643ea8Slogwang /** 553*a9643ea8Slogwang * @brief �������������� 554*a9643ea8Slogwang */ 555*a9643ea8Slogwang TcpKeepMgr::TcpKeepMgr() 556*a9643ea8Slogwang { 557*a9643ea8Slogwang _keep_hash = new HashList(10000); 558*a9643ea8Slogwang } 559*a9643ea8Slogwang 560*a9643ea8Slogwang TcpKeepMgr::~TcpKeepMgr() 561*a9643ea8Slogwang { 562*a9643ea8Slogwang if (!_keep_hash) { 563*a9643ea8Slogwang return; 564*a9643ea8Slogwang } 565*a9643ea8Slogwang 566*a9643ea8Slogwang HashKey* hash_item = _keep_hash->HashGetFirst(); 567*a9643ea8Slogwang while (hash_item) 568*a9643ea8Slogwang { 569*a9643ea8Slogwang delete hash_item; 570*a9643ea8Slogwang hash_item = _keep_hash->HashGetFirst(); 571*a9643ea8Slogwang } 572*a9643ea8Slogwang 573*a9643ea8Slogwang delete _keep_hash; 574*a9643ea8Slogwang _keep_hash = NULL; 575*a9643ea8Slogwang } 576*a9643ea8Slogwang 577*a9643ea8Slogwang 578*a9643ea8Slogwang /** 579*a9643ea8Slogwang * @brief ��IP��ַ��ȡTCP�ı������� 580*a9643ea8Slogwang */ 581*a9643ea8Slogwang TcpKeepConn* TcpKeepMgr::GetTcpKeepConn(struct sockaddr_in* dst) 582*a9643ea8Slogwang { 583*a9643ea8Slogwang TcpKeepConn* conn = NULL; 584*a9643ea8Slogwang if (NULL == dst) 585*a9643ea8Slogwang { 586*a9643ea8Slogwang MTLOG_ERROR("input param dst null, error"); 587*a9643ea8Slogwang return NULL; 588*a9643ea8Slogwang } 589*a9643ea8Slogwang 590*a9643ea8Slogwang TcpKeepKey key(dst); 591*a9643ea8Slogwang TcpKeepKey* conn_list = (TcpKeepKey*)_keep_hash->HashFindData(&key); 592*a9643ea8Slogwang if ((NULL == conn_list) || (NULL == conn_list->GetFirstConn())) 593*a9643ea8Slogwang { 594*a9643ea8Slogwang conn = _mem_queue.AllocPtr(); 595*a9643ea8Slogwang if (conn) { 596*a9643ea8Slogwang conn->SetDestAddr(dst); 597*a9643ea8Slogwang } 598*a9643ea8Slogwang } 599*a9643ea8Slogwang else 600*a9643ea8Slogwang { 601*a9643ea8Slogwang conn = conn_list->GetFirstConn(); 602*a9643ea8Slogwang conn_list->RemoveConn(conn); 603*a9643ea8Slogwang conn->IdleDetach(); 604*a9643ea8Slogwang } 605*a9643ea8Slogwang 606*a9643ea8Slogwang return conn; 607*a9643ea8Slogwang } 608*a9643ea8Slogwang 609*a9643ea8Slogwang /** 610*a9643ea8Slogwang * @brief ��IP��ַ����TCP�ı������� 611*a9643ea8Slogwang */ 612*a9643ea8Slogwang bool TcpKeepMgr::RemoveTcpKeepConn(TcpKeepConn* conn) 613*a9643ea8Slogwang { 614*a9643ea8Slogwang struct sockaddr_in* dst = conn->GetDestAddr(); 615*a9643ea8Slogwang if ((dst->sin_addr.s_addr == 0) || (dst->sin_port == 0)) 616*a9643ea8Slogwang { 617*a9643ea8Slogwang MTLOG_ERROR("sock addr, invalid, %x:%d", dst->sin_addr.s_addr, dst->sin_port); 618*a9643ea8Slogwang return false; 619*a9643ea8Slogwang } 620*a9643ea8Slogwang 621*a9643ea8Slogwang TcpKeepKey key(dst); 622*a9643ea8Slogwang TcpKeepKey* conn_list = (TcpKeepKey*)_keep_hash->HashFindData(&key); 623*a9643ea8Slogwang if (!conn_list) 624*a9643ea8Slogwang { 625*a9643ea8Slogwang MTLOG_ERROR("no conn cache list, invalid, %x:%d", dst->sin_addr.s_addr, dst->sin_port); 626*a9643ea8Slogwang return false; 627*a9643ea8Slogwang } 628*a9643ea8Slogwang 629*a9643ea8Slogwang conn->IdleDetach(); 630*a9643ea8Slogwang conn_list->RemoveConn(conn); 631*a9643ea8Slogwang 632*a9643ea8Slogwang return true; 633*a9643ea8Slogwang 634*a9643ea8Slogwang } 635*a9643ea8Slogwang 636*a9643ea8Slogwang 637*a9643ea8Slogwang /** 638*a9643ea8Slogwang * @brief ��IP��ַ����TCP�ı������� 639*a9643ea8Slogwang */ 640*a9643ea8Slogwang bool TcpKeepMgr::CacheTcpKeepConn(TcpKeepConn* conn) 641*a9643ea8Slogwang { 642*a9643ea8Slogwang struct sockaddr_in* dst = conn->GetDestAddr(); 643*a9643ea8Slogwang if ((dst->sin_addr.s_addr == 0) || (dst->sin_port == 0)) 644*a9643ea8Slogwang { 645*a9643ea8Slogwang MTLOG_ERROR("sock addr, invalid, %x:%d", dst->sin_addr.s_addr, dst->sin_port); 646*a9643ea8Slogwang return false; 647*a9643ea8Slogwang } 648*a9643ea8Slogwang 649*a9643ea8Slogwang TcpKeepKey key(dst); 650*a9643ea8Slogwang TcpKeepKey* conn_list = (TcpKeepKey*)_keep_hash->HashFindData(&key); 651*a9643ea8Slogwang if (!conn_list) 652*a9643ea8Slogwang { 653*a9643ea8Slogwang conn_list = new TcpKeepKey(conn->GetDestAddr()); 654*a9643ea8Slogwang if (!conn_list) { 655*a9643ea8Slogwang MTLOG_ERROR("new conn list failed, error"); 656*a9643ea8Slogwang return false; 657*a9643ea8Slogwang } 658*a9643ea8Slogwang _keep_hash->HashInsert(conn_list); 659*a9643ea8Slogwang } 660*a9643ea8Slogwang 661*a9643ea8Slogwang if (!conn->IdleAttach()) 662*a9643ea8Slogwang { 663*a9643ea8Slogwang MTLOG_ERROR("conn IdleAttach failed, error"); 664*a9643ea8Slogwang return false; 665*a9643ea8Slogwang } 666*a9643ea8Slogwang 667*a9643ea8Slogwang conn->ConnReuseClean(); 668*a9643ea8Slogwang conn_list->InsertConn(conn); 669*a9643ea8Slogwang 670*a9643ea8Slogwang 671*a9643ea8Slogwang return true; 672*a9643ea8Slogwang 673*a9643ea8Slogwang } 674*a9643ea8Slogwang 675*a9643ea8Slogwang /** 676*a9643ea8Slogwang * @brief �رջ�tcp������ 677*a9643ea8Slogwang */ 678*a9643ea8Slogwang void TcpKeepMgr::FreeTcpKeepConn(TcpKeepConn* conn, bool force_free) 679*a9643ea8Slogwang { 680*a9643ea8Slogwang if (force_free) 681*a9643ea8Slogwang { 682*a9643ea8Slogwang conn->Reset(); 683*a9643ea8Slogwang _mem_queue.FreePtr(conn); 684*a9643ea8Slogwang return; 685*a9643ea8Slogwang } 686*a9643ea8Slogwang else 687*a9643ea8Slogwang { 688*a9643ea8Slogwang if (!CacheTcpKeepConn(conn)) 689*a9643ea8Slogwang { 690*a9643ea8Slogwang conn->Reset(); 691*a9643ea8Slogwang _mem_queue.FreePtr(conn); 692*a9643ea8Slogwang return; 693*a9643ea8Slogwang } 694*a9643ea8Slogwang } 695*a9643ea8Slogwang } 696*a9643ea8Slogwang 697*a9643ea8Slogwang 698*a9643ea8Slogwang 699*a9643ea8Slogwang /** 700*a9643ea8Slogwang * @brief ���ӵ�socket����, �������ӵ�Э�����͵� 701*a9643ea8Slogwang * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ�� 702*a9643ea8Slogwang */ 703*a9643ea8Slogwang int UdpSessionConn::CreateSocket() 704*a9643ea8Slogwang { 705*a9643ea8Slogwang // 1. session������, ��֪ͨ��������fd 706*a9643ea8Slogwang if (!_action || !_ntfy_obj) { 707*a9643ea8Slogwang MTLOG_ERROR("conn not set action %p, or _ntfy_obj %p, error", _action, _ntfy_obj); 708*a9643ea8Slogwang return -100; 709*a9643ea8Slogwang } 710*a9643ea8Slogwang SessionProxy* proxy = dynamic_cast<SessionProxy*>(_ntfy_obj); 711*a9643ea8Slogwang if (!proxy) { 712*a9643ea8Slogwang MTLOG_ERROR("ntfy obj not match, _ntfy_obj %p, error", _ntfy_obj); 713*a9643ea8Slogwang return -200; 714*a9643ea8Slogwang } 715*a9643ea8Slogwang ISessionNtfy* real_ntfy = proxy->GetRealNtfyObj(); 716*a9643ea8Slogwang if (!real_ntfy) { 717*a9643ea8Slogwang MTLOG_ERROR("real ntfy obj not match, _ntfy_obj %p, error", _ntfy_obj); 718*a9643ea8Slogwang return -300; 719*a9643ea8Slogwang } 720*a9643ea8Slogwang 721*a9643ea8Slogwang // 2. ί�ɴ���, ���¾����Ϣ 722*a9643ea8Slogwang int osfd = real_ntfy->GetOsfd(); 723*a9643ea8Slogwang if (osfd <= 0) 724*a9643ea8Slogwang { 725*a9643ea8Slogwang osfd = real_ntfy->CreateSocket(); 726*a9643ea8Slogwang if (osfd <= 0) { 727*a9643ea8Slogwang MTLOG_ERROR("real ntfy obj create fd failed, _ntfy_obj %p, error", real_ntfy); 728*a9643ea8Slogwang return -400; 729*a9643ea8Slogwang } 730*a9643ea8Slogwang } 731*a9643ea8Slogwang _ntfy_obj->SetOsfd(osfd); 732*a9643ea8Slogwang 733*a9643ea8Slogwang return osfd; 734*a9643ea8Slogwang } 735*a9643ea8Slogwang 736*a9643ea8Slogwang /** 737*a9643ea8Slogwang * @brief �ر�ϵͳsocket, ����һЩ״̬ 738*a9643ea8Slogwang */ 739*a9643ea8Slogwang int UdpSessionConn::CloseSocket() 740*a9643ea8Slogwang { 741*a9643ea8Slogwang return 0; 742*a9643ea8Slogwang } 743*a9643ea8Slogwang 744*a9643ea8Slogwang 745*a9643ea8Slogwang /** 746*a9643ea8Slogwang * @brief ���Է�������, ������һ�� 747*a9643ea8Slogwang * @return 0 ���ͱ��ж�, ������. <0 ϵͳʧ��. >0 ���η��ͳɹ� 748*a9643ea8Slogwang */ 749*a9643ea8Slogwang int UdpSessionConn::SendData() 750*a9643ea8Slogwang { 751*a9643ea8Slogwang if (!_action || !_msg_buff || !_ntfy_obj) { 752*a9643ea8Slogwang MTLOG_ERROR("conn not set action %p, or msg %p, ntfy %p error", _action, _msg_buff, _ntfy_obj); 753*a9643ea8Slogwang return -100; 754*a9643ea8Slogwang } 755*a9643ea8Slogwang 756*a9643ea8Slogwang mt_hook_syscall(sendto); 757*a9643ea8Slogwang int ret = ff_hook_sendto(_ntfy_obj->GetOsfd(), _msg_buff->GetMsgBuff(), _msg_buff->GetMsgLen(), 0, 758*a9643ea8Slogwang (struct sockaddr*)_action->GetMsgDstAddr(), sizeof(struct sockaddr_in)); 759*a9643ea8Slogwang if (ret == -1) 760*a9643ea8Slogwang { 761*a9643ea8Slogwang if ((errno == EINTR) || (errno == EAGAIN) || (errno == EINPROGRESS)) 762*a9643ea8Slogwang { 763*a9643ea8Slogwang return 0; 764*a9643ea8Slogwang } 765*a9643ea8Slogwang else 766*a9643ea8Slogwang { 767*a9643ea8Slogwang MTLOG_ERROR("socket send failed, fd %d, errno %d(%s)", _ntfy_obj->GetOsfd(), 768*a9643ea8Slogwang errno, strerror(errno)); 769*a9643ea8Slogwang return -2; 770*a9643ea8Slogwang } 771*a9643ea8Slogwang } 772*a9643ea8Slogwang else 773*a9643ea8Slogwang { 774*a9643ea8Slogwang _msg_buff->SetHaveSndLen(ret); 775*a9643ea8Slogwang return ret; 776*a9643ea8Slogwang } 777*a9643ea8Slogwang } 778*a9643ea8Slogwang 779*a9643ea8Slogwang /** 780*a9643ea8Slogwang * @brief ���Խ�������, ������һ�� 781*a9643ea8Slogwang * @param buff ���ջ�����ָ�� 782*a9643ea8Slogwang * @return 0 -�����ȴ�����; >0 ���ճɹ�; < 0 ʧ�� 783*a9643ea8Slogwang */ 784*a9643ea8Slogwang int UdpSessionConn::RecvData() 785*a9643ea8Slogwang { 786*a9643ea8Slogwang if (!_ntfy_obj || !_msg_buff) { 787*a9643ea8Slogwang MTLOG_ERROR("conn not set _ntfy_obj %p, or msg %p, error", _ntfy_obj, _msg_buff); 788*a9643ea8Slogwang return -100; 789*a9643ea8Slogwang } 790*a9643ea8Slogwang 791*a9643ea8Slogwang if (_ntfy_obj->GetRcvEvents() <= 0) { 792*a9643ea8Slogwang MTLOG_DEBUG("conn _ntfy_obj %p, no recv event, retry it", _ntfy_obj); 793*a9643ea8Slogwang return 0; 794*a9643ea8Slogwang } 795*a9643ea8Slogwang 796*a9643ea8Slogwang // UDP Session ֪ͨ���滻msg buff, ͨ��type�ж� 797*a9643ea8Slogwang int msg_len = _msg_buff->GetMsgLen(); 798*a9643ea8Slogwang if (BUFF_RECV == _msg_buff->GetBuffType()) 799*a9643ea8Slogwang { 800*a9643ea8Slogwang return msg_len; 801*a9643ea8Slogwang } 802*a9643ea8Slogwang else 803*a9643ea8Slogwang { 804*a9643ea8Slogwang MTLOG_DEBUG("conn msg buff %p, no recv comm", _msg_buff); 805*a9643ea8Slogwang return 0; 806*a9643ea8Slogwang } 807*a9643ea8Slogwang } 808*a9643ea8Slogwang 809*a9643ea8Slogwang 810*a9643ea8Slogwang /** 811*a9643ea8Slogwang * @brief sessionȫ�ֹ����� 812*a9643ea8Slogwang * @return ȫ�־��ָ�� 813*a9643ea8Slogwang */ 814*a9643ea8Slogwang ConnectionMgr* ConnectionMgr::_instance = NULL; 815*a9643ea8Slogwang ConnectionMgr* ConnectionMgr::Instance (void) 816*a9643ea8Slogwang { 817*a9643ea8Slogwang if (NULL == _instance) 818*a9643ea8Slogwang { 819*a9643ea8Slogwang _instance = new ConnectionMgr(); 820*a9643ea8Slogwang } 821*a9643ea8Slogwang 822*a9643ea8Slogwang return _instance; 823*a9643ea8Slogwang } 824*a9643ea8Slogwang 825*a9643ea8Slogwang /** 826*a9643ea8Slogwang * @brief session����ȫ�ֵ����ٽӿ� 827*a9643ea8Slogwang */ 828*a9643ea8Slogwang void ConnectionMgr::Destroy() 829*a9643ea8Slogwang { 830*a9643ea8Slogwang if( _instance != NULL ) 831*a9643ea8Slogwang { 832*a9643ea8Slogwang delete _instance; 833*a9643ea8Slogwang _instance = NULL; 834*a9643ea8Slogwang } 835*a9643ea8Slogwang } 836*a9643ea8Slogwang 837*a9643ea8Slogwang /** 838*a9643ea8Slogwang * @brief ��Ϣbuff�Ĺ��캯�� 839*a9643ea8Slogwang */ 840*a9643ea8Slogwang ConnectionMgr::ConnectionMgr() 841*a9643ea8Slogwang { 842*a9643ea8Slogwang } 843*a9643ea8Slogwang 844*a9643ea8Slogwang /** 845*a9643ea8Slogwang * @brief ��������, ��������Դ, ������������ 846*a9643ea8Slogwang */ 847*a9643ea8Slogwang ConnectionMgr::~ConnectionMgr() 848*a9643ea8Slogwang { 849*a9643ea8Slogwang } 850*a9643ea8Slogwang 851*a9643ea8Slogwang /** 852*a9643ea8Slogwang * @brief ��ȡ�ӿ� 853*a9643ea8Slogwang */ 854*a9643ea8Slogwang IMtConnection* ConnectionMgr::GetConnection(CONN_OBJ_TYPE type, struct sockaddr_in* dst) 855*a9643ea8Slogwang { 856*a9643ea8Slogwang switch (type) 857*a9643ea8Slogwang { 858*a9643ea8Slogwang case OBJ_SHORT_CONN: 859*a9643ea8Slogwang return _udp_short_queue.AllocPtr(); 860*a9643ea8Slogwang break; 861*a9643ea8Slogwang 862*a9643ea8Slogwang case OBJ_TCP_KEEP: 863*a9643ea8Slogwang return _tcp_keep_mgr.GetTcpKeepConn(dst); 864*a9643ea8Slogwang break; 865*a9643ea8Slogwang 866*a9643ea8Slogwang case OBJ_UDP_SESSION: 867*a9643ea8Slogwang return _udp_session_queue.AllocPtr(); 868*a9643ea8Slogwang break; 869*a9643ea8Slogwang 870*a9643ea8Slogwang default: 871*a9643ea8Slogwang return NULL; 872*a9643ea8Slogwang break; 873*a9643ea8Slogwang } 874*a9643ea8Slogwang 875*a9643ea8Slogwang } 876*a9643ea8Slogwang 877*a9643ea8Slogwang /** 878*a9643ea8Slogwang * @brief ���սӿ� 879*a9643ea8Slogwang */ 880*a9643ea8Slogwang void ConnectionMgr::FreeConnection(IMtConnection* conn, bool force_free) 881*a9643ea8Slogwang { 882*a9643ea8Slogwang if (!conn) { 883*a9643ea8Slogwang return; 884*a9643ea8Slogwang } 885*a9643ea8Slogwang CONN_OBJ_TYPE type = conn->GetConnType(); 886*a9643ea8Slogwang 887*a9643ea8Slogwang switch (type) 888*a9643ea8Slogwang { 889*a9643ea8Slogwang case OBJ_SHORT_CONN: 890*a9643ea8Slogwang conn->Reset(); 891*a9643ea8Slogwang return _udp_short_queue.FreePtr(dynamic_cast<UdpShortConn*>(conn)); 892*a9643ea8Slogwang break; 893*a9643ea8Slogwang 894*a9643ea8Slogwang case OBJ_TCP_KEEP: 895*a9643ea8Slogwang return _tcp_keep_mgr.FreeTcpKeepConn(dynamic_cast<TcpKeepConn*>(conn), force_free); 896*a9643ea8Slogwang break; 897*a9643ea8Slogwang 898*a9643ea8Slogwang case OBJ_UDP_SESSION: 899*a9643ea8Slogwang conn->Reset(); 900*a9643ea8Slogwang return _udp_session_queue.FreePtr(dynamic_cast<UdpSessionConn*>(conn)); 901*a9643ea8Slogwang break; 902*a9643ea8Slogwang 903*a9643ea8Slogwang default: 904*a9643ea8Slogwang break; 905*a9643ea8Slogwang } 906*a9643ea8Slogwang 907*a9643ea8Slogwang delete conn; 908*a9643ea8Slogwang return; 909*a9643ea8Slogwang } 910*a9643ea8Slogwang 911*a9643ea8Slogwang 912*a9643ea8Slogwang /** 913*a9643ea8Slogwang * @brief �ر�idle��tcp������ 914*a9643ea8Slogwang */ 915*a9643ea8Slogwang void ConnectionMgr::CloseIdleTcpKeep(TcpKeepConn* conn) 916*a9643ea8Slogwang { 917*a9643ea8Slogwang _tcp_keep_mgr.RemoveTcpKeepConn(conn); 918*a9643ea8Slogwang _tcp_keep_mgr.FreeTcpKeepConn(conn, true); 919*a9643ea8Slogwang } 920*a9643ea8Slogwang 921*a9643ea8Slogwang 922