mirror of https://github.com/F-Stack/f-stack.git
339 lines
6.7 KiB
C++
339 lines
6.7 KiB
C++
|
|
/**
|
|
* Tencent is pleased to support the open source community by making MSEC available.
|
|
*
|
|
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
|
*
|
|
* Licensed under the GNU General Public License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License. You may
|
|
* obtain a copy of the License at
|
|
*
|
|
* https://opensource.org/licenses/GPL-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the
|
|
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
* either express or implied. See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*/
|
|
|
|
|
|
/**
|
|
* @file mt_connection.h
|
|
* @time 20130924
|
|
**/
|
|
|
|
#ifndef __MT_CONNECTION_H__
|
|
#define __MT_CONNECTION_H__
|
|
|
|
#include <netinet/in.h>
|
|
#include <queue>
|
|
#include "mt_mbuf_pool.h"
|
|
#include "hash_list.h"
|
|
#include "mt_action.h"
|
|
|
|
namespace NS_MICRO_THREAD {
|
|
|
|
using std::queue;
|
|
|
|
enum CONN_OBJ_TYPE
|
|
{
|
|
OBJ_CONN_UNDEF = 0,
|
|
OBJ_SHORT_CONN = 1,
|
|
OBJ_TCP_KEEP = 2,
|
|
OBJ_UDP_SESSION = 3,
|
|
};
|
|
|
|
class IMtConnection
|
|
{
|
|
public:
|
|
|
|
IMtConnection();
|
|
virtual ~IMtConnection();
|
|
|
|
virtual void Reset();
|
|
|
|
CONN_OBJ_TYPE GetConnType() {
|
|
return _type;
|
|
};
|
|
|
|
void SetIMtActon(IMtAction* action ) {
|
|
_action = action;
|
|
};
|
|
|
|
IMtAction* GetIMtActon() {
|
|
return _action;
|
|
};
|
|
|
|
void SetNtfyObj(KqueuerObj* obj ) {
|
|
_ntfy_obj = obj;
|
|
};
|
|
|
|
KqueuerObj* GetNtfyObj() {
|
|
return _ntfy_obj;
|
|
};
|
|
|
|
void SetMtMsgBuff(MtMsgBuf* msg_buf) {
|
|
_msg_buff = msg_buf;
|
|
};
|
|
|
|
MtMsgBuf* GetMtMsgBuff() {
|
|
return _msg_buff;
|
|
};
|
|
|
|
public:
|
|
|
|
virtual int CreateSocket() {return 0;};
|
|
|
|
virtual int OpenCnnect() {return 0;};
|
|
|
|
virtual int SendData() {return 0;};
|
|
|
|
virtual int RecvData() {return 0;};
|
|
|
|
virtual int CloseSocket() {return 0;};
|
|
|
|
protected:
|
|
|
|
CONN_OBJ_TYPE _type;
|
|
IMtAction* _action;
|
|
KqueuerObj* _ntfy_obj;
|
|
MtMsgBuf* _msg_buff;
|
|
};
|
|
|
|
class UdpShortConn : public IMtConnection
|
|
{
|
|
public:
|
|
|
|
UdpShortConn() {
|
|
_osfd = -1;
|
|
_type = OBJ_SHORT_CONN;
|
|
};
|
|
virtual ~UdpShortConn() {
|
|
CloseSocket();
|
|
};
|
|
|
|
virtual void Reset();
|
|
|
|
virtual int CreateSocket();
|
|
|
|
virtual int SendData();
|
|
|
|
virtual int RecvData();
|
|
|
|
virtual int CloseSocket();
|
|
|
|
protected:
|
|
int _osfd;
|
|
};
|
|
|
|
|
|
enum TcpKeepFlag
|
|
{
|
|
TCP_KEEP_IN_LIST = 0x1,
|
|
TCP_KEEP_IN_KQUEUE = 0x2,
|
|
};
|
|
|
|
class UdpSessionConn : public IMtConnection
|
|
{
|
|
public:
|
|
|
|
UdpSessionConn() {
|
|
_type = OBJ_UDP_SESSION;
|
|
};
|
|
virtual ~UdpSessionConn() { };
|
|
|
|
virtual int CreateSocket();
|
|
|
|
virtual int SendData();
|
|
|
|
virtual int RecvData();
|
|
|
|
virtual int CloseSocket();
|
|
};
|
|
|
|
typedef TAILQ_ENTRY(TcpKeepConn) KeepConnLink;
|
|
typedef TAILQ_HEAD(__KeepConnTailq, TcpKeepConn) KeepConnList;
|
|
class TcpKeepConn : public IMtConnection, public CTimerNotify
|
|
{
|
|
public:
|
|
|
|
int _keep_flag;
|
|
KeepConnLink _keep_entry;
|
|
|
|
TcpKeepConn() {
|
|
_osfd = -1;
|
|
_keep_time = 10*60*1000;
|
|
_keep_flag = 0;
|
|
_type = OBJ_TCP_KEEP;
|
|
_keep_ntfy.SetKeepNtfyObj(this);
|
|
};
|
|
virtual ~TcpKeepConn() {
|
|
CloseSocket();
|
|
};
|
|
|
|
virtual void Reset();
|
|
|
|
virtual int OpenCnnect();
|
|
|
|
virtual int CreateSocket();
|
|
|
|
virtual int SendData();
|
|
|
|
virtual int RecvData();
|
|
|
|
virtual int CloseSocket();
|
|
|
|
void ConnReuseClean();
|
|
|
|
bool IdleAttach();
|
|
|
|
bool IdleDetach();
|
|
|
|
void SetDestAddr(struct sockaddr_in* dst) {
|
|
memcpy(&_dst_addr, dst, sizeof(_dst_addr));
|
|
}
|
|
|
|
struct sockaddr_in* GetDestAddr() {
|
|
return &_dst_addr;
|
|
}
|
|
|
|
|
|
virtual void timer_notify();
|
|
|
|
void SetKeepTime(unsigned int time) {
|
|
_keep_time = time;
|
|
};
|
|
|
|
protected:
|
|
int _osfd;
|
|
unsigned int _keep_time;
|
|
TcpKeepNtfy _keep_ntfy;
|
|
struct sockaddr_in _dst_addr;
|
|
|
|
};
|
|
|
|
class TcpKeepKey : public HashKey
|
|
{
|
|
public:
|
|
|
|
TcpKeepKey() {
|
|
_addr_ipv4 = 0;
|
|
_net_port = 0;
|
|
TAILQ_INIT(&_keep_list);
|
|
this->SetDataPtr(this);
|
|
};
|
|
|
|
TcpKeepKey(struct sockaddr_in * dst) {
|
|
_addr_ipv4 = dst->sin_addr.s_addr;
|
|
_net_port = dst->sin_port;
|
|
TAILQ_INIT(&_keep_list);
|
|
this->SetDataPtr(this);
|
|
};
|
|
|
|
~TcpKeepKey() {
|
|
TAILQ_INIT(&_keep_list);
|
|
};
|
|
|
|
virtual uint32_t HashValue(){
|
|
return _addr_ipv4 ^ ((_net_port << 16) | _net_port);
|
|
};
|
|
|
|
virtual int HashCmp(HashKey* rhs){
|
|
TcpKeepKey* data = dynamic_cast<TcpKeepKey*>(rhs);
|
|
if (!data) {
|
|
return -1;
|
|
}
|
|
if (this->_addr_ipv4 != data->_addr_ipv4) {
|
|
return this->_addr_ipv4 - data->_addr_ipv4;
|
|
}
|
|
if (this->_net_port != data->_net_port) {
|
|
return this->_net_port - data->_net_port;
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
void InsertConn(TcpKeepConn* conn) {
|
|
if (conn->_keep_flag & TCP_KEEP_IN_LIST) {
|
|
return;
|
|
}
|
|
TAILQ_INSERT_TAIL(&_keep_list, conn, _keep_entry);
|
|
conn->_keep_flag |= TCP_KEEP_IN_LIST;
|
|
};
|
|
|
|
void RemoveConn(TcpKeepConn* conn) {
|
|
if (!(conn->_keep_flag & TCP_KEEP_IN_LIST)) {
|
|
return;
|
|
}
|
|
TAILQ_REMOVE(&_keep_list, conn, _keep_entry);
|
|
conn->_keep_flag &= ~TCP_KEEP_IN_LIST;
|
|
};
|
|
|
|
TcpKeepConn* GetFirstConn() {
|
|
return TAILQ_FIRST(&_keep_list);
|
|
};
|
|
|
|
private:
|
|
uint32_t _addr_ipv4;
|
|
uint16_t _net_port;
|
|
KeepConnList _keep_list;
|
|
|
|
};
|
|
|
|
class TcpKeepMgr
|
|
{
|
|
public:
|
|
|
|
typedef CPtrPool<TcpKeepConn> TcpKeepQueue;
|
|
|
|
TcpKeepMgr();
|
|
|
|
~TcpKeepMgr();
|
|
|
|
TcpKeepConn* GetTcpKeepConn(struct sockaddr_in* dst);
|
|
|
|
bool CacheTcpKeepConn(TcpKeepConn* conn);
|
|
|
|
bool RemoveTcpKeepConn(TcpKeepConn* conn);
|
|
|
|
void FreeTcpKeepConn(TcpKeepConn* conn, bool force_free);
|
|
|
|
private:
|
|
|
|
HashList* _keep_hash;
|
|
TcpKeepQueue _mem_queue;
|
|
};
|
|
|
|
class ConnectionMgr
|
|
{
|
|
public:
|
|
|
|
typedef CPtrPool<UdpShortConn> UdpShortQueue;
|
|
typedef CPtrPool<UdpSessionConn> UdpSessionQueue;
|
|
|
|
static ConnectionMgr* Instance (void);
|
|
|
|
static void Destroy(void);
|
|
|
|
IMtConnection* GetConnection(CONN_OBJ_TYPE type, struct sockaddr_in* dst);
|
|
|
|
void FreeConnection(IMtConnection* conn, bool force_free);
|
|
|
|
void CloseIdleTcpKeep(TcpKeepConn* conn);
|
|
|
|
~ConnectionMgr();
|
|
|
|
private:
|
|
ConnectionMgr();
|
|
|
|
static ConnectionMgr * _instance;
|
|
|
|
UdpShortQueue _udp_short_queue;
|
|
UdpSessionQueue _udp_session_queue;
|
|
TcpKeepMgr _tcp_keep_mgr;
|
|
};
|
|
|
|
}
|
|
#endif
|
|
|
|
|