xref: /f-stack/app/micro_thread/mt_connection.h (revision a9643ea8)
1 
2 /**
3  * Tencent is pleased to support the open source community by making MSEC available.
4  *
5  * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
6  *
7  * Licensed under the GNU General Public License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License. You may
9  * obtain a copy of the License at
10  *
11  *     https://opensource.org/licenses/GPL-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software distributed under the
14  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15  * either express or implied. See the License for the specific language governing permissions
16  * and limitations under the License.
17  */
18 
19 
20 /**
21  *  @file mt_connection.h
22  *  @info ΢�߳����ӹ����岿��
23  *  @time 20130924
24  **/
25 
26 #ifndef __MT_CONNECTION_H__
27 #define __MT_CONNECTION_H__
28 
29 #include <netinet/in.h>
30 #include <queue>
31 #include "mt_mbuf_pool.h"
32 #include "hash_list.h"
33 #include "mt_action.h"
34 
35 namespace NS_MICRO_THREAD {
36 
37 using std::queue;
38 
39 /**
40  * @brief ���Ӷ�������
41  */
42 enum CONN_OBJ_TYPE
43 {
44     OBJ_CONN_UNDEF     = 0,     ///< δ��������Ӷ���
45     OBJ_SHORT_CONN     = 1,     ///< �����Ӷ���, fd�����Ự, ÿ������CLOSE
46     OBJ_TCP_KEEP       = 2,     ///< TCP�ĸ���ģ��, ÿ��ÿ����ʹ�ø�fd, ����ɸ���
47     OBJ_UDP_SESSION    = 3,     ///< UDP��sessionģ��, ÿ���ӿɹ������߳�ʹ��
48 };
49 
50 /**
51  * @brief ΢�߳�һ���������, ӳ��һ�����Ӷ���
52  */
53 class IMtConnection
54 {
55 public:
56 
57     /**
58      * @brief  ΢�߳����ӻ��๹��������
59      */
60     IMtConnection();
61     virtual ~IMtConnection();
62 
63     /**
64      * @brief ���ӻ��ո����������
65      */
66     virtual void Reset();
67 
68     /**
69      * @brief ��ȡ���Ӷ����������Ϣ
70      */
71     CONN_OBJ_TYPE GetConnType() {
72         return _type;
73     };
74 
75     /**
76      * @brief �����ڲ�ACTIONָ��
77      * @return IMtConnָ��
78      */
79     void SetIMtActon(IMtAction* action  ) {
80         _action = action;
81     };
82 
83     /**
84      * @brief ��ȡ�ڲ�ACTIONָ��
85      * @return IMtConnָ��
86      */
87     IMtAction* GetIMtActon() {
88         return _action;
89     };
90 
91     /**
92      * @brief �����ڲ�ACTIONָ��
93      * @return IMtConnָ��
94      */
95     void SetNtfyObj(KqueuerObj* obj  ) {
96         _ntfy_obj = obj;
97     };
98 
99     /**
100      * @brief ��ȡ�ڲ�ACTIONָ��
101      * @return IMtConnָ��
102      */
103     KqueuerObj* GetNtfyObj() {
104         return _ntfy_obj;
105     };
106 
107     /**
108      * @brief �����ڲ�msgbuffָ��
109      * @return IMtConnָ��
110      */
111     void SetMtMsgBuff(MtMsgBuf* msg_buf) {
112         _msg_buff = msg_buf;
113     };
114 
115     /**
116      * @brief ��ȡ�ڲ�msgbuffָ��
117      * @return IMtConnָ��
118      */
119     MtMsgBuf* GetMtMsgBuff() {
120         return _msg_buff;
121     };
122 
123 public:
124 
125     /**
126      * @brief  ���ӵ�socket����, �������ӵ�Э�����͵�
127      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
128      */
129     virtual int CreateSocket() {return 0;};
130 
131     /**
132      * @brief  ���Ӵ���Զ�˻Ựͨ��, ��TCP��connect��
133      * @return 0 -�ɹ�, < 0 ʧ��
134      */
135     virtual int OpenCnnect() {return 0;};
136 
137     /**
138      * @brief  ���ӷ�������
139      * @return >0 -�ɹ�, ����ʵ�ʷ��ͳ���, < 0 ʧ��
140      */
141     virtual int SendData() {return 0;};
142 
143     /**
144      * @brief  ���ӽ�������
145      * @return >0 -�ɹ�, ���ر��ν��ճ���, < 0 ʧ��(-1 �Զ˹ر�; -2 ���մ���)
146      */
147     virtual int RecvData() {return 0;};
148 
149     /**
150      * @brief  �ر�socket�˿�
151      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
152      */
153     virtual int CloseSocket() {return 0;};
154 
155 protected:
156 
157     CONN_OBJ_TYPE       _type;      // Ԥ�õ�type, �ɰ�type����������
158     IMtAction*          _action;    // ������actionָ��, �ϼ�ָ��, ��������Դ������
159     KqueuerObj*         _ntfy_obj;  // EPOLL֪ͨ����, �¼�ָ��, ����������
160     MtMsgBuf*           _msg_buff;  // ��̬�����buff�ֶ�, �¼�ָ��, ����������
161 };
162 
163 /**
164  * @brief ����sock�Ķ���������
165  */
166 class UdpShortConn : public IMtConnection
167 {
168 public:
169 
170     /**
171      * @brief ����socket�Ķ����ӵĹ���������
172      */
173     UdpShortConn() {
174         _osfd = -1;
175         _type = OBJ_SHORT_CONN;
176     };
177     virtual ~UdpShortConn() {
178         CloseSocket();
179     };
180 
181     /**
182      * @brief ���ӻ��ո����������
183      */
184     virtual void Reset();
185 
186     /**
187      * @brief  ���ӵ�socket����, �������ӵ�Э�����͵�
188      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
189      */
190     virtual int CreateSocket();
191 
192     /**
193      * @brief  ���ӷ�������
194      * @return >0 -�ɹ�, ����ʵ�ʷ��ͳ���, < 0 ʧ��
195      */
196     virtual int SendData();
197 
198     /**
199      * @brief  ���ӽ�������
200      * @return >0 -�ɹ�, ���ر��ν��ճ���, < 0 ʧ��(-1 �Զ˹ر�; -2 ���մ���)
201      */
202     virtual int RecvData();
203 
204     /**
205      * @brief  �ر�socket�˿�
206      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
207      */
208     virtual int CloseSocket();
209 
210 protected:
211     int                 _osfd;      // ÿ�����ӵ�������socket
212 };
213 
214 
215 enum TcpKeepFlag
216 {
217     TCP_KEEP_IN_LIST   = 0x1,
218     TCP_KEEP_IN_KQUEUE = 0x2,
219 };
220 
221 /**
222  * @brief ����session��UDP��������
223  */
224 class UdpSessionConn : public IMtConnection
225 {
226 public:
227 
228     /**
229      * @brief ����socket�Ķ����ӵĹ���������
230      */
231     UdpSessionConn() {
232         _type = OBJ_UDP_SESSION;
233     };
234     virtual ~UdpSessionConn() {    };
235 
236     /**
237      * @brief  ���ӵ�socket����, �������ӵ�Э�����͵�
238      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
239      */
240     virtual int CreateSocket();
241 
242     /**
243      * @brief  ���ӷ�������
244      * @return >0 -�ɹ�, ����ʵ�ʷ��ͳ���, < 0 ʧ��
245      */
246     virtual int SendData();
247 
248     /**
249      * @brief  ���ӽ�������
250      * @return >0 -�ɹ�, ���ر��ν��ճ���, < 0 ʧ��(-1 �Զ˹ر�; -2 ���մ���)
251      */
252     virtual int RecvData();
253 
254     /**
255      * @brief  �ر�socket�˿�
256      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
257      */
258     virtual int CloseSocket();
259 };
260 
261 /**
262  * @brief ����sock��TCP��������
263  */
264 typedef TAILQ_ENTRY(TcpKeepConn) KeepConnLink;
265 typedef TAILQ_HEAD(__KeepConnTailq, TcpKeepConn) KeepConnList;
266 class TcpKeepConn : public IMtConnection, public CTimerNotify
267 {
268 public:
269 
270     int           _keep_flag;  // ����״̬���
271     KeepConnLink  _keep_entry; // ���й������
272 
273     /**
274      * @brief ����socket�Ķ����ӵĹ���������
275      */
276     TcpKeepConn() {
277         _osfd = -1;
278         _keep_time = 10*60*1000; // Ĭ��10����, ���԰������
279         _keep_flag = 0;
280         _type = OBJ_TCP_KEEP;
281         _keep_ntfy.SetKeepNtfyObj(this);
282     };
283     virtual ~TcpKeepConn() {
284         CloseSocket();
285     };
286 
287     /**
288      * @brief ���ӻ��ո����������
289      */
290     virtual void Reset();
291 
292     /**
293      * @brief  ���Ӵ���Զ�˻Ựͨ��, ��TCP��connect��
294      * @return 0 -�ɹ�, < 0 ʧ��
295      */
296     virtual int OpenCnnect();
297 
298     /**
299      * @brief  ���ӵ�socket����, �������ӵ�Э�����͵�
300      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
301      */
302     virtual int CreateSocket();
303 
304     /**
305      * @brief  ���ӷ�������
306      * @return >0 -�ɹ�, ����ʵ�ʷ��ͳ���, < 0 ʧ��
307      */
308     virtual int SendData();
309 
310     /**
311      * @brief  ���ӽ�������
312      * @return >0 -�ɹ�, ���ر��ν��ճ���, < 0 ʧ��(-1 �Զ˹ر�; -2 ���մ���)
313      */
314     virtual int RecvData();
315 
316     /**
317      * @brief  �ر�socket�˿�
318      * @return >0 -�ɹ�, ����ϵͳfd, < 0 ʧ��
319      */
320     virtual int CloseSocket();
321 
322     /**
323      * @brief ���ӱ��ָ���
324      */
325     void ConnReuseClean();
326 
327     /**
328      * @brief Idle���洦��, epoll ����Զ�˹رյ�
329      */
330     bool IdleAttach();
331 
332     /**
333      * @brief Idleȡ�����洦��, �����ɿ����߳�����Զ�˹ر�
334      */
335     bool IdleDetach();
336 
337     /**
338      * @brief �洢Ŀ�ĵ�ַ��Ϣ, ���ڸ���
339      */
340     void SetDestAddr(struct sockaddr_in* dst) {
341         memcpy(&_dst_addr, dst, sizeof(_dst_addr));
342     }
343 
344     /**
345      * @brief ��ȡĿ�ĵ�ַ��Ϣ
346      */
347     struct sockaddr_in* GetDestAddr() {
348         return &_dst_addr;
349     }
350 
351     /**
352      * @brief ��ʱ֪ͨ����, ����ʵ���߼�
353      */
354     virtual void timer_notify();
355 
356     /**
357      * @brief ���ó�ʱʱ��, ���뵥λ
358      */
359     void SetKeepTime(unsigned int time) {
360         _keep_time = time;
361     };
362 
363 protected:
364     int                 _osfd;      // ÿ�����ӵ�������socket
365     unsigned int        _keep_time; // ���ñ����ʱ��
366     TcpKeepNtfy         _keep_ntfy; // ����һ���������Ӷ���
367     struct sockaddr_in  _dst_addr;  // Զ�˵�ַ��Ϣ
368 
369 };
370 
371 
372 
373 /**
374  * @brief ����ַhash���泤����
375  */
376 class TcpKeepKey : public HashKey
377 {
378 public:
379 
380     /**
381      * @brief ��������������
382      */
383     TcpKeepKey() {
384         _addr_ipv4  = 0;
385         _net_port   = 0;
386         TAILQ_INIT(&_keep_list);
387         this->SetDataPtr(this);
388     };
389 
390     TcpKeepKey(struct sockaddr_in * dst) {
391         _addr_ipv4  = dst->sin_addr.s_addr;
392         _net_port   = dst->sin_port;
393         TAILQ_INIT(&_keep_list);
394         this->SetDataPtr(this);
395     };
396 
397     /**
398      * @brief �����ݲ�����conn
399      */
400     ~TcpKeepKey() {
401         TAILQ_INIT(&_keep_list);
402     };
403 
404     /**
405      *  @brief �ڵ�Ԫ�ص�hash�㷨, ��ȡkey��hashֵ
406      *  @return �ڵ�Ԫ�ص�hashֵ
407      */
408     virtual uint32_t HashValue(){
409         return _addr_ipv4 ^ ((_net_port << 16) | _net_port);
410     };
411 
412     /**
413      *  @brief �ڵ�Ԫ�ص�cmp����, ͬһͰID��, ��key�Ƚ�
414      *  @return �ڵ�Ԫ�ص�hashֵ
415      */
416     virtual int HashCmp(HashKey* rhs){
417         TcpKeepKey* data = dynamic_cast<TcpKeepKey*>(rhs);
418         if (!data) {
419             return -1;
420         }
421         if (this->_addr_ipv4 != data->_addr_ipv4) {
422             return this->_addr_ipv4 - data->_addr_ipv4;
423         }
424         if (this->_net_port != data->_net_port) {
425             return this->_net_port - data->_net_port;
426         }
427         return 0;
428     };
429 
430 
431     /**
432      * @brief ���Ӷ������
433      */
434     void InsertConn(TcpKeepConn* conn) {
435         if (conn->_keep_flag & TCP_KEEP_IN_LIST) {
436             return;
437         }
438         TAILQ_INSERT_TAIL(&_keep_list, conn, _keep_entry);
439         conn->_keep_flag |= TCP_KEEP_IN_LIST;
440     };
441 
442     void RemoveConn(TcpKeepConn* conn) {
443         if (!(conn->_keep_flag & TCP_KEEP_IN_LIST)) {
444             return;
445         }
446         TAILQ_REMOVE(&_keep_list, conn, _keep_entry);
447         conn->_keep_flag &= ~TCP_KEEP_IN_LIST;
448     };
449 
450     TcpKeepConn* GetFirstConn() {
451         return TAILQ_FIRST(&_keep_list);
452     };
453 
454 private:
455     uint32_t            _addr_ipv4;     ///< ip��ַ
456     uint16_t            _net_port;      ///< port ��������
457     KeepConnList        _keep_list;     ///< ʵ�ʵĿ��ж���
458 
459 };
460 
461 
462 /**
463  * @brief TCP�����ӵ����Ӷ���������ڴ�cache
464  */
465 class TcpKeepMgr
466 {
467 public:
468 
469     typedef CPtrPool<TcpKeepConn>   TcpKeepQueue;   ///< �ڴ滺���
470 
471     /**
472      * @brief ��������������
473      */
474     TcpKeepMgr();
475 
476     ~TcpKeepMgr();
477 
478 
479     /**
480      * @brief ��IP��ַ��ȡTCP�ı�������
481      */
482     TcpKeepConn* GetTcpKeepConn(struct sockaddr_in*       dst);
483 
484     /**
485      * @brief ��IP��ַ����TCP�ı�������
486      */
487     bool CacheTcpKeepConn(TcpKeepConn* conn);
488 
489     /**
490      * @brief ��IP��ַ����TCP�ı�������, ȥ��CACHE
491      */
492     bool RemoveTcpKeepConn(TcpKeepConn* conn);
493 
494     /**
495      * @brief �رջ���tcp������
496      */
497     void FreeTcpKeepConn(TcpKeepConn* conn, bool force_free);
498 
499 private:
500 
501     HashList*       _keep_hash;            ///< hash��, �洢��IP���������Ӷ���
502     TcpKeepQueue    _mem_queue;            ///< mem����, ����conn�ڴ��
503 };
504 
505 
506 /**
507  * @brief ���ӹ�����ģ��
508  */
509 class ConnectionMgr
510 {
511 public:
512 
513     typedef CPtrPool<UdpShortConn>      UdpShortQueue;
514     typedef CPtrPool<UdpSessionConn>    UdpSessionQueue;
515 
516     /**
517      * @brief ��Ϣbuff��ȫ�ֹ������ӿ�
518      * @return ȫ�־��ָ��
519      */
520     static ConnectionMgr* Instance (void);
521 
522     /**
523      * @brief ��Ϣ����ӿ�
524      */
525     static void Destroy(void);
526 
527     /**
528      * @brief ��ȡ�ӿ�
529      */
530     IMtConnection* GetConnection(CONN_OBJ_TYPE type, struct sockaddr_in*     dst);
531 
532     /**
533      * @brief ���սӿ�
534      */
535     void FreeConnection(IMtConnection* conn, bool force_free);
536 
537     /**
538      * @brief �ر�idle��tcp������
539      */
540     void CloseIdleTcpKeep(TcpKeepConn* conn);
541 
542     /**
543      * @brief ��Ϣbuff����������
544      */
545     ~ConnectionMgr();
546 
547 private:
548     /**
549      * @brief ��Ϣbuff�Ĺ��캯��
550      */
551     ConnectionMgr();
552 
553     static ConnectionMgr * _instance;         ///< ��������
554 
555     UdpShortQueue  _udp_short_queue;          ///< �����ӵĶ��г�
556     UdpSessionQueue  _udp_session_queue;      ///< udp session ���ӳ�
557     TcpKeepMgr      _tcp_keep_mgr;            ///< tcp keep ������
558 };
559 
560 }
561 #endif
562 
563 
564