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