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