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