/****************************************************************
  copyright   : Copyright (C) 2013-2015, chenbichao,
              : All rights reserved.
              : www.pptun.com, www.peergine.com
              : 
  filename    : pgLibTunnel.h
  discription : 
  modify      : create, chenbichao, 2013/12/13
              :
			  : Modify, chenbichao, 2015/03/31
			  : 1.每个API函数名称加上“Tunnel”前缀，区别于其他SDK的API函数名
			  :
			  : Modify, chenbichao, 2015/04/29
			  : 1.pgTunnelSysInfo函数增加lpszCfgFile参数
			  :
			  : Modify, chenbichao, 2016/04/26
			  : 1.增加pgTunnelSetNetCard函数
			  :
			  : Modify, chenbichao, 2016/11/14
			  : 1.增加下列函数：
			  :     pgTunnelVersionGet
			  :     pgTunnelDomainSet
			  :     pgTunnelDomainGet
			  :     pgTunnelCommentSet
			  :     pgTunnelCommentGet
			  :     pgTunnelTunnelSet
			  :     pgTunnelConnectAdd
			  :     pgTunnelConnectDelete
			  :     pgTunnelConnectQuery
			  :     pgTunnelConnectLocalDelete
			  :     pgTunnelConnectLocalQuery
			  :     pgTunnelUserExtend
			  :     pgTunnelPushGet
			  :
			  : Modify, chenbichao, 2017/02/18
			  : 1.增加pgTunnelStatusGet函数
			  : 
			  : Modify, chenbichao, 2017/06/13
			  : 1.增加pgTunnelSetCfgParam函数
			  :
			  : Modify, chenbichao, 2020/04/04
			  : 1.增加pgTunnelControl函数
			  :
			  : Modify, chenbichao, 2020/04/27
			  : 1.增加pgTunnelChannelSet函数
			  :
			  : Modify, chenbichao, 2023/03/22
			  : 1.增加pgTunnelPeerFwdCfg函数
			  :
*****************************************************************/
#ifndef _PG_LIB_TUNNEL_H
#define _PG_LIB_TUNNEL_H


#ifdef __cplusplus
extern "C" {
#endif


/**
 *  错误码定义
 */
typedef enum tagPG_TUNNEL_ERROR_E {
	PG_TUNNEL_ERROR_OK = 0,             // 成功
	PG_TUNNEL_ERROR_SYSTEM = -1,        // 系统错误。
	PG_TUNNEL_ERROR_BADPARAM = -2,      // 传递的参数错误。
	PG_TUNNEL_ERROR_BADCLASS = -3,      // 无效的功能类
	PG_TUNNEL_ERROR_BADMETHOD = -4,     // 无效的方法
	PG_TUNNEL_ERROR_BADOBJECT = -5,     // 无效的对象
	PG_TUNNEL_ERROR_BADSTATUS = -6,     // 状态不正确。
	PG_TUNNEL_ERROR_BADFILE = -7,       // 无效的文件
	PG_TUNNEL_ERROR_BADUSER = -8,       // 用户不存在。
	PG_TUNNEL_ERROR_BADPASS = -9,       // 密码错误
	PG_TUNNEL_ERROR_NOLOGIN = -10,      // 未登录
	PG_TUNNEL_ERROR_NETWORK = -11,      // 网络故障
	PG_TUNNEL_ERROR_TIMEOUT = -12,      // 操作超时
	PG_TUNNEL_ERROR_REJECT = -13,       // 拒绝操作
	PG_TUNNEL_ERROR_BUSY = -14,         // 系统正忙
	PG_TUNNEL_ERROR_OPENED = -15,       // 资源已经打开
	PG_TUNNEL_ERROR_CLOSED = -16,       // 资源已经关闭
	PG_TUNNEL_ERROR_EXIST = -17,        // 资源已经存在
	PG_TUNNEL_ERROR_NOEXIST = -18,      // 资源不存在
	PG_TUNNEL_ERROR_NOSPACE = -19,      // 空间或容量限制
	PG_TUNNEL_ERROR_BADTYPE = -20,      // 无效的类型
	PG_TUNNEL_ERROR_CHECKERR = -21,     // 校验错误
	PG_TUNNEL_ERROR_BADSERVER = -22,    // 无效的服务器
	PG_TUNNEL_ERROR_BADDOMAIN = -23,    // 无效的域
	PG_TUNNEL_ERROR_NODATA = -24,       // 没有数据
	PG_TUNNEL_ERROR_UNKNOWN = -255,     // 未知错误
	PG_TUNNEL_ERROR_NOIMP = -256,       // 该功能没有实现。
} PG_TUNNEL_ERROR_E;


/**
 *  P2P通道的连接类型
 */
typedef enum tagPG_TUNNEL_CNNT_E {
	PG_TUNNEL_CNNT_Unknown = 0,            // 未知，还没有检测到连接类型

	PG_TUNNEL_CNNT_IPV4_Pub = 4,           // 公网IPv4地址
	PG_TUNNEL_CNNT_IPV4_NATConeFull = 5,   // 完全锥形NAT
	PG_TUNNEL_CNNT_IPV4_NATConeHost = 6,   // 主机限制锥形NAT
	PG_TUNNEL_CNNT_IPV4_NATConePort = 7,   // 端口限制锥形NAT
	PG_TUNNEL_CNNT_IPV4_NATSymmet = 8,     // 对称NAT

	PG_TUNNEL_CNNT_IPV4_Private = 12,      // 私网直连
	PG_TUNNEL_CNNT_IPV4_NATLoop = 13,      // 私网NAT环回

	PG_TUNNEL_CNNT_IPV4_TunnelTCP = 16,    // TCPv4转发
	PG_TUNNEL_CNNT_IPV4_TunnelHTTP = 17,   // HTTPv4转发

	PG_TUNNEL_CNNT_IPV4_PeerFwd = 24,      // 借助P2P节点转发

	PG_TUNNEL_CNNT_IPV6_Pub = 32,          // 公网IPv6地址
	PG_TUNNEL_CNNT_IPV6_Local = 36,        // 私网IPv6地址

	PG_TUNNEL_CNNT_IPV6_TunnelTCP = 40,    // TCPv6转发
	PG_TUNNEL_CNNT_IPV6_TunnelHTTP = 41,   // HTTPv6转发

	PG_TUNNEL_CNNT_P2P = 128,              // P2P连接
	PG_TUNNEL_CNNT_Local = 129,            // 私网连接
	PG_TUNNEL_CNNT_PeerForward = 130,      // 节点转发连接
	PG_TUNNEL_CNNT_RelayForward = 131,     // 中继转发连接

	PG_TUNNEL_CNNT_Offline = 65535,        // 对端不在线

} PG_TUNNEL_CNNT_E;

/**
 *  查询状态的选项
 */
typedef enum tagPG_TUNNEL_GET_STA_E {
	PG_TUNNEL_GET_STA_LOGIN = 0,    // 查询登录状态
} PG_TUNNEL_GET_STA_E;

/**
 *  登录状态定义
 */
typedef enum tagPG_TUNNEL_STA_LOGIN_E {
	PG_TUNNEL_STA_LOGIN_SUCCESS = 0,       // 登录成功
	PG_TUNNEL_STA_LOGIN_CONFIG = 4,        // 加载配置文件失败
	PG_TUNNEL_STA_LOGIN_SYSINFO = 5,       // 系统信息参数错误
	PG_TUNNEL_STA_LOGIN_RESOLUTION = 6,    // 域名解析失败
	PG_TUNNEL_STA_LOGIN_BUILDACCOUNT = 7,  // 生成账号信息失败
	PG_TUNNEL_STA_LOGIN_INITNODE = 8,      // 初始化Peergine node失败
	PG_TUNNEL_STA_LOGIN_INITFAILED = 9,    // 其他初始化失败
	PG_TUNNEL_STA_LOGIN_LOGINFAILED = 10,  // 发送登录请求失败
	PG_TUNNEL_STA_LOGIN_LOGOUTED = 11,     // 已经注销（稍后重试登录请求）
	PG_TUNNEL_STA_LOGIN_REQUESTING = 16,   // 正在请求登录
	PG_TUNNEL_STA_LOGIN_TIMEOUT = 17,      // 登录错误（请求超时）
	PG_TUNNEL_STA_LOGIN_NETWORK = 18,      // 登录错误（网络错误）
	PG_TUNNEL_STA_LOGIN_BADUSER = 19,      // 登录错误（用户名错误）
	PG_TUNNEL_STA_LOGIN_BADPASS = 20,      // 登录错误（密码错误）
	PG_TUNNEL_STA_LOGIN_REJECT = 21,       // 登录错误（拒绝访问）
	PG_TUNNEL_STA_LOGIN_BUSY = 22,         // 登录错误（服务器正忙）
	PG_TUNNEL_STA_LOGIN_FAILED = 23,       // 登录错误（其他登录失败）
	PG_TUNNEL_STA_LOGIN_KICKOUT = 32,      // 用户名冲突被服务器踢下线
	PG_TUNNEL_STA_LOGIN_UNKNOWN = 255,     // 未知状态
	PG_TUNNEL_STA_LOGIN_EXTEND = 256,      // 用户自定义错误码的开始
} PG_TUNNEL_STA_LOGIN_E;


/**
 *  事件ID定义
 */
typedef enum tagPG_TUNNEL_EVENT_E {
	PG_TUNNEL_EVENT_EXIT = 0,                  // Tunnel SDK 退出
	PG_TUNNEL_EVENT_ERROR = 1,                 // 系统错误，错误码参考'PG_TUNNEL_EVENT_ERROR_E'
	PG_TUNNEL_EVENT_LOGIN = 2,                 // 登录（尝试登录）的结果
	PG_TUNNEL_EVENT_LOGOUT = 3,                // 注销登录
	PG_TUNNEL_EVENT_KICKOUT = 4,               // 用户名（ID）冲突被踢下线
	PG_TUNNEL_EVENT_PEER_UP = 5,               // 与对端的P2P通道已连接
	PG_TUNNEL_EVENT_PEER_DOWN = 6,             // 与对端的P2P通道已断开
	PG_TUNNEL_EVENT_PEER_OFFLINE = 7,          // 对端已经离线
	PG_TUNNEL_EVENT_CONNECT_ADD = 8,           // 隧道映射添加
	PG_TUNNEL_EVENT_CONNECT_DELETE = 9,        // 隧道映射删除
	PG_TUNNEL_EVENT_CONNECT_UP = 10,           // 隧道映射已连接
	PG_TUNNEL_EVENT_CONNECT_DOWN = 11,         // 隧道映射已断开
	PG_TUNNEL_EVENT_SERVER_PUSH = 12,          // P2P服务器推送消息
	PG_TUNNEL_EVENT_PEER_INFO = 13,            // P2P连接通道的信息
	PG_TUNNEL_EVENT_CONNECT_USED = 14,         // 隧道映射的端口已经被使用
	PG_TUNNEL_EVENT_PEER_FWD_STATUS = 15,      // 节点转发的状态信息
	PG_TUNNEL_EVENT_PEER_FWD_STATISTIC = 16,   // 节点转发的贡献统计信息
	PG_TUNNEL_EVENT_PEER_FWD_STAT_USED = 17,   // 节点转发的消费统计信息
	PG_TUNNEL_EVENT_SESSION_FAILED = 18,       // TCP会话连接请求失败
} PG_TUNNEL_EVENT_E;

/**
 *  事件 'PG_TUNNEL_EVENT_ERROR' 上报的错误码
 */
typedef enum tagPG_TUNNEL_EVENT_ERROR_E {
	PG_TUNNEL_EVENT_ERROR_OK = 0,
	PG_TUNNEL_EVENT_ERROR_MEMORY_ALLOC = 1,          // 内存分配失败
	PG_TUNNEL_EVENT_ERROR_SOCKET_ACCEPT = 2,         // 调用accept接受TCP client连接失败
	PG_TUNNEL_EVENT_ERROR_SOCKET_CREATE = 3,         // 创建socket失败
	PG_TUNNEL_EVENT_ERROR_SOCKET_OPTION = 4,         // 设置socket option失败
	PG_TUNNEL_EVENT_ERROR_SOCKET_CONNECT = 5,        // 调用connect连接TCP server失败
	PG_TUNNEL_EVENT_ERROR_SOCKET_GETADDR = 6,        // 调用getsockname获取socket绑定的地址失败
	PG_TUNNEL_EVENT_ERROR_SESSION_LIMIT = 7,         // TCP连接数量达到了MaxSess限制
	PG_TUNNEL_EVENT_ERROR_SESSION_RESOLUTION = 8,    // 域名解析失败
	PG_TUNNEL_EVENT_ERROR_SESSION_FILTER = 9,        // 请求被TCP服务器IP地址过滤规则拦截
} PG_TUNNEL_EVENT_ERROR_E;

/**
 *  节点转发的状态
 */
typedef enum tagPG_TUNNEL_PEER_FWD_STA_E {
	PG_TUNNEL_PEER_FWD_STA_DISABLE = 0,    // 节点转发为禁用。
	PG_TUNNEL_PEER_FWD_STA_PAUSE = 1,      // 节点转发为暂停，因为本端正在使用网络带宽。
	PG_TUNNEL_PEER_FWD_STA_IDLE = 2,       // 节点转发为启用，且当前空闲。
	PG_TUNNEL_PEER_FWD_STA_USED = 3,       // 节点转发为启用，且当前正在协助转发。
} PG_TUNNEL_PEER_FWD_STA_E;

/**
 *  控制动作ID定义
 */
typedef enum tagPG_TUNNEL_CONTROL_E {
	PG_TUNNEL_CONTROL_LOGIN_NOW   = 0,     // 中断退避，立即登录
} PG_TUNNEL_CONTROL_E;

/**
 *  传输通道类型定义
 */
typedef enum tagPG_TUNNEL_CHANNEL_E {
	PG_TUNNEL_CHANNEL_AUTO  = 0,           // 自动适应P2P穿透通道和Relay转发通道（默认）
	PG_TUNNEL_CHANNEL_P2P   = 1,           // 只使用P2P穿透通道
	PG_TUNNEL_CHANNEL_RELAY = 2,           // 强制使用Relay转发通道
} PG_TUNNEL_CHANNEL_E;


/**
 * 版本信息结构体
 */
typedef struct tagPG_TUNNEL_VERSION_S {
	char szVersion[64];             // 版本信息
} PG_TUNNEL_VERSION_S;

/**
 * 状态信息结构体
 */
typedef struct tagPG_TUNNEL_STATUS_S {
	unsigned int uStatus;           // 状态信息，见'PG_TUNNEL_STA_LOGIN_E'枚举定义
} PG_TUNNEL_STATUS_S;

/**
 * 域名称结构体
 */
typedef struct tagPG_TUNNEL_DOMAIN_S {
	char szDomain[128];             // 域名称
} PG_TUNNEL_DOMAIN_S;

/**
 * 客户端说明结构体
 */
typedef struct tagPG_TUNNEL_COMMENT_S {
	char szComment[256];            // 客户端说明信息
} PG_TUNNEL_COMMENT_S;

/**
 * P2P通道信息结构体
 */
typedef struct tagPG_TUNNEL_PEER_INFO_S {
	char szPeerID[128];             // 对端的用户ID
	unsigned int uType;             // P2P通道类型，见枚举‘PG_TUNNEL_CNNT_E’定义。
	char szAddrLocal[64];           // 本端的登录地址端口
	char szAddrRemote[64];          // 对端的登录地址端口
	char szTunnelLocal[64];         // 本端的通道地址端口
	char szTunnelRemote[64];        // 对端的通道地址端口
	char szPrivateRemote[64];       // 对端的私网地址端口
} PG_TUNNEL_PEER_INFO_S;

/**
 * 客户端连接地址端口结构体
 */
typedef struct tagPG_TUNNEL_CLIENT_ADDR_S {
	char szClientAddr[64];          // 本端的客户端连接地址端口
} PG_TUNNEL_CLIENT_ADDR_S;

/**
 * 隧道连接信息结构体
 */
typedef struct tagPG_TUNNEL_CONNECT_INFO_S {
	char szPeerID[128];             // 对端的用户ID
	unsigned int uType;             // 隧道连接的类型
	unsigned int uEncrypt;          // 是否加密
	char szListenAddr[64];          // 对端的侦听地址端口
	char szClientAddr[64];          // 本端的客户端地址端口
} PG_TUNNEL_CONNECT_INFO_S;

/**
 * 自定义数据结构体
 */
typedef struct tagPG_TUNNEL_DATA_S {
	unsigned int uSize;             // 指明 'szData' 缓冲区的长度（字节）
	char szData[4];                 // 接收数据的缓冲区
} PG_TUNNEL_DATA_S;

/**
 * 本端的用户P2P ID结构体
 */
typedef struct tagPG_TUNNEL_SELF_S {
	char szSelf[128];               // 本端的用户P2P ID
} PG_TUNNEL_SELF_S;


/**
 *  日志输出回调函数
 *
 *  uLevel：[IN] 日志级别
 *
 *  lpszOut：[IN] 日志输出内容
 */
typedef void (*TfnTunnelLogOut)(unsigned int uLevel, const char* lpszOut);


/**
 *  事件上报回调函数
 *
 *  uEvent：[IN] 事件ID，参考枚举'PG_TUNNEL_EVENT_E'定义
 *
 *  lpszParam：[IN] 事件参数
 */
typedef void (*TfnTunnelEventProc)(unsigned int uEvent, const char* lpszParam);


/**
 *  描述：注册回调函数接口。
 *
 *  阻塞方式：非阻塞，立即返回。
 *
 *  pfnEventProc [IN] 事件上报回调函数的指针。回调函数原型见‘TfnTunnelEventProc’定义。
 */
void pgTunnelCallbackSet(TfnTunnelEventProc pfnEventProc);


/**
 *  描述：启动 Peergine tunnel 模块
 *
 *  阻塞方式：非阻塞，立即返回。
 *
 *  lpszCfgFile：[IN] 配置文件的路径
 *
 *  lpszSysInfo：[IN] 设备的系统信息。可以用pgTunnelSysInfo()辅助函数获取。
 *      格式："(DevID){1234}(MacAddr){}(CpuMHz){1}(MemSize){1}(BrwVer){}(OSVer){}(OSSpk){}(OSType){}"
 *      在花括号中填入参数的值，其中“DevID”是必须的，其他参数是可选的。
 *
 *  lpvParam：[IN] 自定义参数，保留。
 *
 *  pfnLogOut：[IN] 日志输出回调函数的指针。回调函数原型见‘TfnTunnelLogOut’定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelStart(const char* lpszCfgFile, const char* lpszSysInfo,
	void* lpvParam, TfnTunnelLogOut pfnLogOut);


/**
 *  描述：停止 Peergine tunnel 模块。
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 */
void pgTunnelStop();


/**
*  描述：直接设置配置文件参数内容
*       注意：必须在pgTunnelStart()之前调用。
*       因为配置文件里有一些敏感的明文信息，所以有些场景下不希望用户看到配置文件的内容。
*       这种场景下，可以调用此函数直接把配置文件的内容设置保存到SDK的内部变量中，而不需要再提供一个配置文件。
*
*  阻塞方式：非阻塞，立即返回。
*
*  lpszCfgParam：[IN] 配置参数内容(格式和内容参考配置文件参数说明)
*
*  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
*/
int pgTunnelSetCfgParam(const char* lpszCfgParam);


/**
 *  描述：获取当前设备的系统信息。(辅助函数，有些设备或操作系统上没有实现)
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 *  lpszCfgFile：[IN] 配置文件路径。(从配置文件获取沙盒的路径，LOG文件和临时文件将写到沙盒目录)。
 *
 *  lpszInfo：[OUT] 接受系统信息的缓冲区。
 *
 *  uSize：[IN] “lpszInfo”缓冲区的长度。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelSysInfo(const char* lpszCfgFile, char* lpszInfo, unsigned int uSize);


/**
 *  描述：指定使用的网卡。(辅助函数，在LINUX系统有实现。)
 *       注意：必须在pgTunnelStart()之前调用。
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 *  lpszNetCard：[IN] 指定的网卡接口名称，例如：eth0, eth1, ...
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelSetNetCard(const char* lpszNetCard);


/**
 *  描述：获取pgLibTunnel SDK的版本号
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 *  lpstVersion：[OUT] 版本号信息，见'PG_TUNNEL_VERSION_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelVersionGet(PG_TUNNEL_VERSION_S* lpstVersion);


/**
 *  描述：获取登录到P2P服务器的状态
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 *  uOption：[IN] 选项，见'PG_TUNNEL_GET_STA_E'定义。
 *
 *  lpstStatus：[OUT] 状态信息，见'PG_TUNNEL_STATUS_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelStatusGet(unsigned int uOption, PG_TUNNEL_STATUS_S* lpstStatus);


/**
 *  描述：设置域识别码，把本客户端加入到该识别码对应的用户域里。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszPasscode：[IN] 域的识别码。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelDomainSet(const char* lpszPasscode);


/**
 *  描述：获取客户端当前的域名称。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpstDomain：[OUT] 域的名称，见'PG_TUNNEL_DOMAIN_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelDomainGet(PG_TUNNEL_DOMAIN_S* lpstDomain);


/**
 *  描述：设置客户端的说明。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszComment：[IN] 客户端的说明。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelCommentSet(const char* lpszComment);


/**
 *  描述：获取客户端的说明。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpstComment：[OUT] 客户端的说明信息，见'PG_TUNNEL_COMMENT_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelCommentGet(PG_TUNNEL_COMMENT_S* lpstComment);


/**
 *  描述：设置客户端的域识别码和说明。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszPasscode：[IN] 客户端的域识别码。
 *
 *  lpszComment：[IN] 客户端的说明信息。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelTunnelSet(const char* lpszPasscode, const char* lpszComment);


/**
 *  描述：获取本客户端和指定用户ID的远程客户端之间的P2P通道信息。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszPeerID：[IN] 对端客户端的用户ID。
 *
 *  lpstPeerInfo：[OUT] P2P通道的信息，见'PG_TUNNEL_PEER_INFO_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelPeerInfoGet(const char* lpszPeerID, PG_TUNNEL_PEER_INFO_S* lpstPeerInfo);


/**
 *  描述：本客户端和指定用户ID的远程客户端之间添加一条隧道连接。
 *        如果添加成功，返回本端映射的客户端连接地址端口信息。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszSession：[IN] 登录会话ID。
 *      （可选，传空字符串，只有在P2P服务器端开启登录会话验证的时候需要传入有效值）
 *
 *  lpszPeerID：[IN] 对端客户端的用户ID。
 *
 *  uType：[IN] 隧道连接的类型，0:为TCP连接，1为HTTP代理连接
 *
 *  uEncrypt：[IN] 隧道连接是否加密，0为不加密，1为加密。
 *
 *  lpszListenAddr：[IN] 对端TCP服务器的侦听地址端口。
 *
 *  lpszClientAddr：[IN] 本端映射的客户端连接地址端口。
 *      如果传空字符串，则由P2P服务器自动分配地址端口。
 *
 *  lpstClientAddr：[OUT] 客户端连接地址端口信息，见'PG_TUNNEL_CLIENT_ADDR_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelConnectAdd(const char* lpszSession, const char* lpszPeerID,
	unsigned int uType, unsigned int uEncrypt, const char* lpszListenAddr,
	const char* lpszClientAddr, PG_TUNNEL_CLIENT_ADDR_S* lpstClientAddr);


/**
 *  描述：删除一条隧道连接。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszSession：[IN] 登录会话ID。
 *      （可选，传空字符串，只有在P2P服务器端开启登录会话验证的时候需要传入有效值）
 *
 *  lpszPeerID：[IN] 对端客户端的用户ID。
 *
 *  uType：[IN] 隧道连接的类型，0:为TCP连接，1为HTTP代理连接
 *
 *  uEncrypt：[IN] 隧道连接是否加密，0为不加密，1为加密。
 *
 *  lpszListenAddr：[IN] 对端TCP服务器的侦听地址端口。
 *
 *  lpszClientAddr：[IN] 本端映射的客户端连接地址端口。
 *      如果传空字符串，则删除由“lpszPeerID、uType、uEncrypt、lpszListenAddr”这4个参数匹配的隧道连接。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelConnectDelete(const char* lpszSession, const char* lpszPeerID,
	unsigned int uType, unsigned int uEncrypt, const char* lpszListenAddr,
	const char* lpszClientAddr);


/**
 *  描述：获取一条隧道连接的本端映射的客户端连接地址端口。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszPeerID：[IN] 对端客户端的用户ID。
 *
 *  uType：[IN] 隧道连接的类型，0:为TCP连接，1为HTTP代理连接
 *
 *  uEncrypt：[IN] 隧道连接是否加密，0为不加密，1为加密。
 *
 *  lpszListenAddr：[IN] 对端TCP服务器的侦听地址端口。
 *
 *  lpstClientAddr：[OUT] 本端映射的客户端连接地址端口信息，见'PG_TUNNEL_CLIENT_ADDR_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelConnectQuery(const char* lpszPeerID, unsigned int uType, unsigned int uEncrypt,
	const char* lpszListenAddr, PG_TUNNEL_CLIENT_ADDR_S* lpstClientAddr);


/**
 *  描述：根据本端映射的客户端连接地址端口信息删除一条隧道连接。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszSession：[IN] 登录会话ID。
 *      （可选，传空字符串，只有在P2P服务器端开启登录会话验证的时候需要传入有效值）
 *
 *  lpszClientAddr：[IN] 本端映射的客户端连接地址端口。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelConnectLocalDelete(const char* lpszSession, const char* lpszClientAddr);


/**
 *  描述：根据本端映射的客户端连接地址端口信息获取一条隧道连接的全部信息。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszClientAddr：[IN] 本端映射的客户端连接地址端口。
 *
 *  lpstConnectInfo：[OUT] 隧道连接的全部信息，见'PG_TUNNEL_CONNECT_INFO_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelConnectLocalQuery(const char* lpszClientAddr, PG_TUNNEL_CONNECT_INFO_S* lpstConnectInfo);


/**
 *  描述：发送自定义请求给P2P服务器，并接收服务器的应答。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpszRequestData：[IN] 发送给服务器的请求数据。
 *
 *  lpstReplyData：[OUT] 接收到服务器的返回数据。
 *
 *  uTimeout：[IN] 等待超时时间（毫秒）。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelUserExtend(const char* lpszRequestData, PG_TUNNEL_DATA_S* lpstReplyData, unsigned int uTimeout);


/**
 *  描述：接收P2P服务器下发的推送消息。
 * 
 *  阻塞方式：如果客户端的缓冲区中已经有下推的消息数据，则立即返回缓冲区里的消息数据。
 *            如果客户端的缓冲区中还没有下推的消息数据，则等待P2P服务器下推消息数据。
 *
 *  lpstPushData：[OUT] 接收到服务器的推送消息数据。
 *
 *  uTimeout：[IN] 等待超时时间（毫秒）。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelPushGet(PG_TUNNEL_DATA_S* lpstPushData, unsigned int uTimeout);


/**
 *  描述：获取本端的用户ID。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  lpstSelf[OUT] 接收到本端的用户ID。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelSelfGet(PG_TUNNEL_SELF_S* lpstSelf);


/**
 *  描述：根据索引逐条获取隧道连接的全部信息。
 * 
 *  阻塞方式：阻塞，等待服务器执行操作。
 *
 *  uIndex [IN] 隧道的索引号：0, 1, 2, 3, 4, ...
 *
 *  lpstConnectInfo：[OUT] 隧道连接的全部信息，见'PG_TUNNEL_CONNECT_INFO_S'定义。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelConnectEnum(unsigned int uIndex, PG_TUNNEL_CONNECT_INFO_S* lpstConnectInfo);


/**
 *  描述：执行对隧道的控制操作
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 *  uCtrl [IN] 控制动作ID，见'PG_TUNNEL_CONTROL_E'定义。
 *
 *  lpszParam [IN] 控制动作的参数，预留给以后使用。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelControl(unsigned int uCtrl, const char* lpszParam);


/**
 *  描述：设置与对端通信的通道类型
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 *  lpszPeerID：[IN] 对端客户端的用户ID。
 *
 *  uType [IN] 通道类型，见'PG_TUNNEL_CHANNEL_E'定义。
 *
 *  lpszParam [IN] 参数，预留给以后使用。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelChannelSet(const char* lpszPeerID, unsigned int uType, const char* lpszParam);


/**
 *  描述：动态设置节点转发的参数
 * 
 *  阻塞方式：非阻塞，立即返回。
 *
 *  iSpeed [IN] 允许本节点作为转发节点。
 *      小于0：不改变该配置参数，大于0：允许转发的带宽(字节/秒)，0：禁用转发。
 *
 *  iGate [IN] 本节点触发停止协助转发的自用带宽的阈值(字节/秒)。
 *      小于0：不改变该配置参数，大于或等于0：指定阈值。默认：262144
 *
 *  iUse [IN] 本节点是否使用其他节点作为转发节点。
 *      小于0：不改变该配置参数，大于0：是，0：否。默认：1。
 *
 *  iMaxSess [IN] 本节点协助转发最大会话数。
 *      小于0：不改变该配置参数，大于或等于0：指定最大会话数。默认：3。
 *
 *  lpszOption [IN] 选项，预留给以后使用。
 *
 *  返回值：见枚举‘PG_TUNNEL_ERROR_E’的定义
 */
int pgTunnelPeerFwdCfg(int iSpeed, int iGate, int iUse, int iMaxSess, const char* lpszOption);


#ifdef __cplusplus
}
#endif


#endif // _PG_LIB_TUNNEL_H
