xref: /f-stack/app/micro_thread/mt_connection.h (revision 35a81399)
1a9643ea8Slogwang 
2a9643ea8Slogwang /**
3a9643ea8Slogwang  * Tencent is pleased to support the open source community by making MSEC available.
4a9643ea8Slogwang  *
5a9643ea8Slogwang  * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
6a9643ea8Slogwang  *
7a9643ea8Slogwang  * Licensed under the GNU General Public License, Version 2.0 (the "License");
8a9643ea8Slogwang  * you may not use this file except in compliance with the License. You may
9a9643ea8Slogwang  * obtain a copy of the License at
10a9643ea8Slogwang  *
11a9643ea8Slogwang  *     https://opensource.org/licenses/GPL-2.0
12a9643ea8Slogwang  *
13a9643ea8Slogwang  * Unless required by applicable law or agreed to in writing, software distributed under the
14a9643ea8Slogwang  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15a9643ea8Slogwang  * either express or implied. See the License for the specific language governing permissions
16a9643ea8Slogwang  * and limitations under the License.
17a9643ea8Slogwang  */
18a9643ea8Slogwang 
19a9643ea8Slogwang 
20a9643ea8Slogwang /**
21a9643ea8Slogwang  *  @file mt_connection.h
22a9643ea8Slogwang  *  @time 20130924
23a9643ea8Slogwang  **/
24a9643ea8Slogwang 
25a9643ea8Slogwang #ifndef __MT_CONNECTION_H__
26a9643ea8Slogwang #define __MT_CONNECTION_H__
27a9643ea8Slogwang 
28a9643ea8Slogwang #include <netinet/in.h>
29a9643ea8Slogwang #include <queue>
30a9643ea8Slogwang #include "mt_mbuf_pool.h"
31a9643ea8Slogwang #include "hash_list.h"
32a9643ea8Slogwang #include "mt_action.h"
33a9643ea8Slogwang 
34a9643ea8Slogwang namespace NS_MICRO_THREAD {
35a9643ea8Slogwang 
36a9643ea8Slogwang using std::queue;
37a9643ea8Slogwang 
38a9643ea8Slogwang enum CONN_OBJ_TYPE
39a9643ea8Slogwang {
40*35a81399Slogwang     OBJ_CONN_UNDEF     = 0,
41*35a81399Slogwang     OBJ_SHORT_CONN     = 1,
42*35a81399Slogwang     OBJ_TCP_KEEP       = 2,
43*35a81399Slogwang     OBJ_UDP_SESSION    = 3,
44a9643ea8Slogwang };
45a9643ea8Slogwang 
46a9643ea8Slogwang class IMtConnection
47a9643ea8Slogwang {
48a9643ea8Slogwang public:
49a9643ea8Slogwang 
50a9643ea8Slogwang     IMtConnection();
51a9643ea8Slogwang     virtual ~IMtConnection();
52a9643ea8Slogwang 
53a9643ea8Slogwang     virtual void Reset();
54a9643ea8Slogwang 
GetConnType()55a9643ea8Slogwang     CONN_OBJ_TYPE GetConnType() {
56a9643ea8Slogwang         return _type;
57a9643ea8Slogwang     };
58a9643ea8Slogwang 
SetIMtActon(IMtAction * action)59a9643ea8Slogwang     void SetIMtActon(IMtAction* action  ) {
60a9643ea8Slogwang         _action = action;
61a9643ea8Slogwang     };
62a9643ea8Slogwang 
GetIMtActon()63a9643ea8Slogwang     IMtAction* GetIMtActon() {
64a9643ea8Slogwang         return _action;
65a9643ea8Slogwang     };
66a9643ea8Slogwang 
SetNtfyObj(KqueuerObj * obj)67a9643ea8Slogwang     void SetNtfyObj(KqueuerObj* obj  ) {
68a9643ea8Slogwang         _ntfy_obj = obj;
69a9643ea8Slogwang     };
70a9643ea8Slogwang 
GetNtfyObj()71a9643ea8Slogwang     KqueuerObj* GetNtfyObj() {
72a9643ea8Slogwang         return _ntfy_obj;
73a9643ea8Slogwang     };
74a9643ea8Slogwang 
SetMtMsgBuff(MtMsgBuf * msg_buf)75a9643ea8Slogwang     void SetMtMsgBuff(MtMsgBuf* msg_buf) {
76a9643ea8Slogwang         _msg_buff = msg_buf;
77a9643ea8Slogwang     };
78a9643ea8Slogwang 
GetMtMsgBuff()79a9643ea8Slogwang     MtMsgBuf* GetMtMsgBuff() {
80a9643ea8Slogwang         return _msg_buff;
81a9643ea8Slogwang     };
82a9643ea8Slogwang 
83a9643ea8Slogwang public:
84a9643ea8Slogwang 
CreateSocket()85a9643ea8Slogwang     virtual int CreateSocket() {return 0;};
86a9643ea8Slogwang 
OpenCnnect()87a9643ea8Slogwang     virtual int OpenCnnect() {return 0;};
88a9643ea8Slogwang 
SendData()89a9643ea8Slogwang     virtual int SendData() {return 0;};
90a9643ea8Slogwang 
RecvData()91a9643ea8Slogwang     virtual int RecvData() {return 0;};
92a9643ea8Slogwang 
CloseSocket()93a9643ea8Slogwang     virtual int CloseSocket() {return 0;};
94a9643ea8Slogwang 
95a9643ea8Slogwang protected:
96a9643ea8Slogwang 
97*35a81399Slogwang     CONN_OBJ_TYPE       _type;
98*35a81399Slogwang     IMtAction*          _action;
99*35a81399Slogwang     KqueuerObj*         _ntfy_obj;
100*35a81399Slogwang     MtMsgBuf*           _msg_buff;
101a9643ea8Slogwang };
102a9643ea8Slogwang 
103a9643ea8Slogwang class UdpShortConn : public IMtConnection
104a9643ea8Slogwang {
105a9643ea8Slogwang public:
106a9643ea8Slogwang 
UdpShortConn()107a9643ea8Slogwang     UdpShortConn() {
108a9643ea8Slogwang         _osfd = -1;
109a9643ea8Slogwang         _type = OBJ_SHORT_CONN;
110a9643ea8Slogwang     };
~UdpShortConn()111a9643ea8Slogwang     virtual ~UdpShortConn() {
112a9643ea8Slogwang         CloseSocket();
113a9643ea8Slogwang     };
114a9643ea8Slogwang 
115a9643ea8Slogwang     virtual void Reset();
116a9643ea8Slogwang 
117a9643ea8Slogwang     virtual int CreateSocket();
118a9643ea8Slogwang 
119a9643ea8Slogwang     virtual int SendData();
120a9643ea8Slogwang 
121a9643ea8Slogwang     virtual int RecvData();
122a9643ea8Slogwang 
123a9643ea8Slogwang     virtual int CloseSocket();
124a9643ea8Slogwang 
125a9643ea8Slogwang protected:
126*35a81399Slogwang     int                 _osfd;
127a9643ea8Slogwang };
128a9643ea8Slogwang 
129a9643ea8Slogwang 
130a9643ea8Slogwang enum TcpKeepFlag
131a9643ea8Slogwang {
132a9643ea8Slogwang     TCP_KEEP_IN_LIST   = 0x1,
133a9643ea8Slogwang     TCP_KEEP_IN_KQUEUE = 0x2,
134a9643ea8Slogwang };
135a9643ea8Slogwang 
136a9643ea8Slogwang class UdpSessionConn : public IMtConnection
137a9643ea8Slogwang {
138a9643ea8Slogwang public:
139a9643ea8Slogwang 
UdpSessionConn()140a9643ea8Slogwang     UdpSessionConn() {
141a9643ea8Slogwang         _type = OBJ_UDP_SESSION;
142a9643ea8Slogwang     };
~UdpSessionConn()143a9643ea8Slogwang     virtual ~UdpSessionConn() {    };
144a9643ea8Slogwang 
145a9643ea8Slogwang     virtual int CreateSocket();
146a9643ea8Slogwang 
147a9643ea8Slogwang     virtual int SendData();
148a9643ea8Slogwang 
149a9643ea8Slogwang     virtual int RecvData();
150a9643ea8Slogwang 
151a9643ea8Slogwang     virtual int CloseSocket();
152a9643ea8Slogwang };
153a9643ea8Slogwang 
154a9643ea8Slogwang typedef TAILQ_ENTRY(TcpKeepConn) KeepConnLink;
155a9643ea8Slogwang typedef TAILQ_HEAD(__KeepConnTailq, TcpKeepConn) KeepConnList;
156a9643ea8Slogwang class TcpKeepConn : public IMtConnection, public CTimerNotify
157a9643ea8Slogwang {
158a9643ea8Slogwang public:
159a9643ea8Slogwang 
160*35a81399Slogwang     int           _keep_flag;
161*35a81399Slogwang     KeepConnLink  _keep_entry;
162a9643ea8Slogwang 
TcpKeepConn()163a9643ea8Slogwang     TcpKeepConn() {
164a9643ea8Slogwang         _osfd = -1;
165*35a81399Slogwang         _keep_time = 10*60*1000;
166a9643ea8Slogwang         _keep_flag = 0;
167a9643ea8Slogwang         _type = OBJ_TCP_KEEP;
168a9643ea8Slogwang         _keep_ntfy.SetKeepNtfyObj(this);
169a9643ea8Slogwang     };
~TcpKeepConn()170a9643ea8Slogwang     virtual ~TcpKeepConn() {
171a9643ea8Slogwang         CloseSocket();
172a9643ea8Slogwang     };
173a9643ea8Slogwang 
174a9643ea8Slogwang     virtual void Reset();
175a9643ea8Slogwang 
176a9643ea8Slogwang     virtual int OpenCnnect();
177a9643ea8Slogwang 
178a9643ea8Slogwang     virtual int CreateSocket();
179a9643ea8Slogwang 
180a9643ea8Slogwang     virtual int SendData();
181a9643ea8Slogwang 
182a9643ea8Slogwang     virtual int RecvData();
183a9643ea8Slogwang 
184a9643ea8Slogwang     virtual int CloseSocket();
185a9643ea8Slogwang 
186a9643ea8Slogwang     void ConnReuseClean();
187a9643ea8Slogwang 
188a9643ea8Slogwang     bool IdleAttach();
189a9643ea8Slogwang 
190a9643ea8Slogwang     bool IdleDetach();
191a9643ea8Slogwang 
SetDestAddr(struct sockaddr_in * dst)192a9643ea8Slogwang     void SetDestAddr(struct sockaddr_in* dst) {
193a9643ea8Slogwang         memcpy(&_dst_addr, dst, sizeof(_dst_addr));
194a9643ea8Slogwang     }
195a9643ea8Slogwang 
GetDestAddr()196a9643ea8Slogwang     struct sockaddr_in* GetDestAddr() {
197a9643ea8Slogwang         return &_dst_addr;
198a9643ea8Slogwang     }
199a9643ea8Slogwang 
200*35a81399Slogwang 
201a9643ea8Slogwang     virtual void timer_notify();
202a9643ea8Slogwang 
SetKeepTime(unsigned int time)203a9643ea8Slogwang     void SetKeepTime(unsigned int time) {
204a9643ea8Slogwang         _keep_time = time;
205a9643ea8Slogwang     };
206a9643ea8Slogwang 
207a9643ea8Slogwang protected:
208*35a81399Slogwang     int                 _osfd;
209*35a81399Slogwang     unsigned int        _keep_time;
210*35a81399Slogwang     TcpKeepNtfy         _keep_ntfy;
211*35a81399Slogwang     struct sockaddr_in  _dst_addr;
212a9643ea8Slogwang 
213a9643ea8Slogwang };
214a9643ea8Slogwang 
215a9643ea8Slogwang class TcpKeepKey : public HashKey
216a9643ea8Slogwang {
217a9643ea8Slogwang public:
218a9643ea8Slogwang 
TcpKeepKey()219a9643ea8Slogwang     TcpKeepKey() {
220a9643ea8Slogwang         _addr_ipv4  = 0;
221a9643ea8Slogwang         _net_port   = 0;
222a9643ea8Slogwang         TAILQ_INIT(&_keep_list);
223a9643ea8Slogwang         this->SetDataPtr(this);
224a9643ea8Slogwang     };
225a9643ea8Slogwang 
TcpKeepKey(struct sockaddr_in * dst)226a9643ea8Slogwang     TcpKeepKey(struct sockaddr_in * dst) {
227a9643ea8Slogwang         _addr_ipv4  = dst->sin_addr.s_addr;
228a9643ea8Slogwang         _net_port   = dst->sin_port;
229a9643ea8Slogwang         TAILQ_INIT(&_keep_list);
230a9643ea8Slogwang         this->SetDataPtr(this);
231a9643ea8Slogwang     };
232a9643ea8Slogwang 
~TcpKeepKey()233a9643ea8Slogwang     ~TcpKeepKey() {
234a9643ea8Slogwang         TAILQ_INIT(&_keep_list);
235a9643ea8Slogwang     };
236a9643ea8Slogwang 
HashValue()237a9643ea8Slogwang     virtual uint32_t HashValue(){
238a9643ea8Slogwang         return _addr_ipv4 ^ ((_net_port << 16) | _net_port);
239a9643ea8Slogwang     };
240a9643ea8Slogwang 
HashCmp(HashKey * rhs)241a9643ea8Slogwang     virtual int HashCmp(HashKey* rhs){
242a9643ea8Slogwang         TcpKeepKey* data = dynamic_cast<TcpKeepKey*>(rhs);
243a9643ea8Slogwang         if (!data) {
244a9643ea8Slogwang             return -1;
245a9643ea8Slogwang         }
246a9643ea8Slogwang         if (this->_addr_ipv4 != data->_addr_ipv4) {
247a9643ea8Slogwang             return this->_addr_ipv4 - data->_addr_ipv4;
248a9643ea8Slogwang         }
249a9643ea8Slogwang         if (this->_net_port != data->_net_port) {
250a9643ea8Slogwang             return this->_net_port - data->_net_port;
251a9643ea8Slogwang         }
252a9643ea8Slogwang         return 0;
253a9643ea8Slogwang     };
254a9643ea8Slogwang 
InsertConn(TcpKeepConn * conn)255a9643ea8Slogwang     void InsertConn(TcpKeepConn* conn) {
256a9643ea8Slogwang         if (conn->_keep_flag & TCP_KEEP_IN_LIST) {
257a9643ea8Slogwang             return;
258a9643ea8Slogwang         }
259a9643ea8Slogwang         TAILQ_INSERT_TAIL(&_keep_list, conn, _keep_entry);
260a9643ea8Slogwang         conn->_keep_flag |= TCP_KEEP_IN_LIST;
261a9643ea8Slogwang     };
262a9643ea8Slogwang 
RemoveConn(TcpKeepConn * conn)263a9643ea8Slogwang     void RemoveConn(TcpKeepConn* conn) {
264a9643ea8Slogwang         if (!(conn->_keep_flag & TCP_KEEP_IN_LIST)) {
265a9643ea8Slogwang             return;
266a9643ea8Slogwang         }
267a9643ea8Slogwang         TAILQ_REMOVE(&_keep_list, conn, _keep_entry);
268a9643ea8Slogwang         conn->_keep_flag &= ~TCP_KEEP_IN_LIST;
269a9643ea8Slogwang     };
270a9643ea8Slogwang 
GetFirstConn()271a9643ea8Slogwang     TcpKeepConn* GetFirstConn() {
272a9643ea8Slogwang         return TAILQ_FIRST(&_keep_list);
273a9643ea8Slogwang     };
274a9643ea8Slogwang 
275a9643ea8Slogwang private:
276*35a81399Slogwang     uint32_t            _addr_ipv4;
277*35a81399Slogwang     uint16_t            _net_port;
278*35a81399Slogwang     KeepConnList        _keep_list;
279a9643ea8Slogwang 
280a9643ea8Slogwang };
281a9643ea8Slogwang 
282a9643ea8Slogwang class TcpKeepMgr
283a9643ea8Slogwang {
284a9643ea8Slogwang public:
285a9643ea8Slogwang 
286*35a81399Slogwang     typedef CPtrPool<TcpKeepConn>   TcpKeepQueue;
287a9643ea8Slogwang 
288a9643ea8Slogwang     TcpKeepMgr();
289a9643ea8Slogwang 
290a9643ea8Slogwang     ~TcpKeepMgr();
291a9643ea8Slogwang 
292a9643ea8Slogwang     TcpKeepConn* GetTcpKeepConn(struct sockaddr_in*       dst);
293a9643ea8Slogwang 
294a9643ea8Slogwang     bool CacheTcpKeepConn(TcpKeepConn* conn);
295a9643ea8Slogwang 
296a9643ea8Slogwang     bool RemoveTcpKeepConn(TcpKeepConn* conn);
297a9643ea8Slogwang 
298a9643ea8Slogwang     void FreeTcpKeepConn(TcpKeepConn* conn, bool force_free);
299a9643ea8Slogwang 
300a9643ea8Slogwang private:
301a9643ea8Slogwang 
302*35a81399Slogwang     HashList*       _keep_hash;
303*35a81399Slogwang     TcpKeepQueue    _mem_queue;
304a9643ea8Slogwang };
305a9643ea8Slogwang 
306a9643ea8Slogwang class ConnectionMgr
307a9643ea8Slogwang {
308a9643ea8Slogwang public:
309a9643ea8Slogwang 
310a9643ea8Slogwang     typedef CPtrPool<UdpShortConn>      UdpShortQueue;
311a9643ea8Slogwang     typedef CPtrPool<UdpSessionConn>    UdpSessionQueue;
312a9643ea8Slogwang 
313a9643ea8Slogwang     static ConnectionMgr* Instance (void);
314a9643ea8Slogwang 
315a9643ea8Slogwang     static void Destroy(void);
316a9643ea8Slogwang 
317a9643ea8Slogwang     IMtConnection* GetConnection(CONN_OBJ_TYPE type, struct sockaddr_in*     dst);
318a9643ea8Slogwang 
319a9643ea8Slogwang     void FreeConnection(IMtConnection* conn, bool force_free);
320a9643ea8Slogwang 
321a9643ea8Slogwang     void CloseIdleTcpKeep(TcpKeepConn* conn);
322a9643ea8Slogwang 
323a9643ea8Slogwang     ~ConnectionMgr();
324a9643ea8Slogwang 
325a9643ea8Slogwang private:
326a9643ea8Slogwang     ConnectionMgr();
327a9643ea8Slogwang 
328*35a81399Slogwang     static ConnectionMgr * _instance;
329a9643ea8Slogwang 
330*35a81399Slogwang     UdpShortQueue  _udp_short_queue;
331*35a81399Slogwang     UdpSessionQueue  _udp_session_queue;
332*35a81399Slogwang     TcpKeepMgr      _tcp_keep_mgr;
333a9643ea8Slogwang };
334a9643ea8Slogwang 
335a9643ea8Slogwang }
336a9643ea8Slogwang #endif
337a9643ea8Slogwang 
338a9643ea8Slogwang 
339