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