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 55 CONN_OBJ_TYPE GetConnType() { 56 return _type; 57 }; 58 59 void SetIMtActon(IMtAction* action ) { 60 _action = action; 61 }; 62 63 IMtAction* GetIMtActon() { 64 return _action; 65 }; 66 67 void SetNtfyObj(KqueuerObj* obj ) { 68 _ntfy_obj = obj; 69 }; 70 71 KqueuerObj* GetNtfyObj() { 72 return _ntfy_obj; 73 }; 74 75 void SetMtMsgBuff(MtMsgBuf* msg_buf) { 76 _msg_buff = msg_buf; 77 }; 78 79 MtMsgBuf* GetMtMsgBuff() { 80 return _msg_buff; 81 }; 82 83 public: 84 85 virtual int CreateSocket() {return 0;}; 86 87 virtual int OpenCnnect() {return 0;}; 88 89 virtual int SendData() {return 0;}; 90 91 virtual int RecvData() {return 0;}; 92 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 107 UdpShortConn() { 108 _osfd = -1; 109 _type = OBJ_SHORT_CONN; 110 }; 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 140 UdpSessionConn() { 141 _type = OBJ_UDP_SESSION; 142 }; 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 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 }; 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 192 void SetDestAddr(struct sockaddr_in* dst) { 193 memcpy(&_dst_addr, dst, sizeof(_dst_addr)); 194 } 195 196 struct sockaddr_in* GetDestAddr() { 197 return &_dst_addr; 198 } 199 200 201 virtual void timer_notify(); 202 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 219 TcpKeepKey() { 220 _addr_ipv4 = 0; 221 _net_port = 0; 222 TAILQ_INIT(&_keep_list); 223 this->SetDataPtr(this); 224 }; 225 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 233 ~TcpKeepKey() { 234 TAILQ_INIT(&_keep_list); 235 }; 236 237 virtual uint32_t HashValue(){ 238 return _addr_ipv4 ^ ((_net_port << 16) | _net_port); 239 }; 240 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 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 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 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