代码拉取完成,页面将自动刷新
#include "udp.h"
#include "ngrok.h"
#include "mytime.h"
#if WIN32
#include <windows.h>
#else
#include <arpa/inet.h>
#endif // WIN32
#if UDPTUNNEL
int GetUdpRemoteAddr(int localport,char *url){
map<string,TunnelReq*>::iterator it;
//进行迭代遍历
for(it=udpInfo.G_TunnelAddr.begin();it!=udpInfo.G_TunnelAddr.end();++it)
{
TunnelReq *tunnelreq =(TunnelReq*)it->second;
if(tunnelreq->localport==localport&&strncasecmp(tunnelreq->url,"udp",3)==0){
memcpy(url,tunnelreq->url,strlen(tunnelreq->url));
return 0;
}
}
return -1;
}
int SendUdpPack(int sock, struct sockaddr_in servAddr,const char *msgstr)
{
unsigned char buffer[strlen(msgstr)+9];
memset(buffer,0,strlen(msgstr)+9);
#if WIN32
unsigned __int64 packlen;
#else
unsigned long long packlen;
#endif
packlen=strlen(msgstr);
packlen=LittleEndian_64(packlen);
memcpy(buffer,&packlen,8);
memcpy(buffer+8,msgstr,strlen(msgstr));
setnonblocking(sock,0);
int len=sendto(sock, (const char *)buffer, 8+strlen(msgstr), 0, (const sockaddr *)&servAddr, sizeof(servAddr));
setnonblocking(sock,1);
return len;
}
int SendUdpAuth(int sock)
{
// string str="{\"Type\":\"Auth\",\"Payload\":{\"Version\":\"2\",\"MmVersion\":\"1.7\",\"User\":\""+user+"\",\"Password\": \"\",\"OS\":\"darwin\",\"Arch\":\"amd64\",\"ClientId\":\""+ClientId+"\"}}";
char str[255];
memset(str,0,255);
sprintf(str,"{\"Type\":\"Auth\",\"Payload\":{\"Version\":\"2\",\"MmVersion\":\"1.7\",\"User\":\"%s\",\"Password\": \"%s\",\"OS\":\"darwin\",\"Arch\":\"amd64\",\"ClientId\":\"%s\"}}",udpInfo.authtoken.c_str(),udpInfo.password_c.c_str(),udpInfo.ClientId.c_str());
return SendUdpPack(sock,udpInfo.servAddr,str);
}
int SendUdpProxy(int sock,struct sockaddr_in servAddr,char* Data,char* Url,const char* ClientAddr)
{
// string str="{\"Type\":\"Auth\",\"Payload\":{\"Version\":\"2\",\"MmVersion\":\"1.7\",\"User\":\""+user+"\",\"Password\": \"\",\"OS\":\"darwin\",\"Arch\":\"amd64\",\"ClientId\":\""+ClientId+"\"}}";
char str[255];
memset(str,0,255);
sprintf(str,"{\"Type\":\"UdpProxy\",\"Payload\":{\"Data\":\"%s\",\"Url\":\"%s\",\"ClientAddr\":\"%s\"}}",Data,Url,ClientAddr);
return SendUdpPack(sock,servAddr,str);
}
int SendUdpPing(int sock)
{
return SendUdpPack(sock,udpInfo.servAddr,"{\"Type\":\"Ping\",\"Payload\":{}}");
}
int SendUdpReqTunnel(int sock,TunnelInfo* tunnelinfo)
{
if(strlen(tunnelinfo->ReqId)==0){
char guid[20]={0};
rand_str(guid,5);
memcpy(tunnelinfo->ReqId,guid,strlen(guid));//copy
}
char str[1024];
memset(str,0,1024);
sprintf(str,"{\"Type\":\"ReqTunnel\",\"Payload\":{\"Protocol\":\"%s\",\"ReqId\":\"%s\",\"Hostname\": \"\",\"Subdomain\":\"\",\"HttpAuth\":\"\",\"RemotePort\":%d,\"authtoken\":\"%s\"}}",tunnelinfo->protocol,tunnelinfo->ReqId,tunnelinfo->remoteport,udpInfo.authtoken.c_str());
return SendUdpPack(sock,udpInfo.servAddr,str);
}
/*检测ping*/
int CheckUdpPing(int sock){
if(mainInfo.udp==0){
return 0;
}
if(udpInfo.pingtime+udpInfo.ping<getUnixTime()&&udpInfo.auth!=0)
{
SendUdpPing(sock);
udpInfo.pingtime=getUnixTime();
}
//检测掉线,超过60秒
if(udpInfo.pongtime!=0&&udpInfo.pongtime+60<getUnixTime()){
udpInfo.auth=0;
udpInfo.authtime=0;
udpInfo.regTunnel=0;
udpInfo.G_TunnelAddr.clear();
}
return 0;
}
int CheckUdpAuth(int sock){
if(mainInfo.udp==0){
return 0;
}
if(udpInfo.auth==0&&(udpInfo.authtime==0||udpInfo.authtime+5<getUnixTime())){
SendUdpAuth(sock);
udpInfo.authtime=getUnixTime();
udpInfo.pongtime=0;
}
return 0;
}
int CheckRegTunnel(int sock){
if(mainInfo.udp==0){
return 0;
}
TunnelInfo *tunnelinfo;
list<TunnelInfo*>::iterator listit;
if(udpInfo.auth==1&&udpInfo.regTunnel==0){
for ( listit = G_TunnelList.begin(); listit != G_TunnelList.end(); ++listit )
{
tunnelinfo =(TunnelInfo *)*listit;
if(strcasecmp(tunnelinfo->protocol,"udp")==0){
SendUdpReqTunnel(sock,tunnelinfo);
}
}
udpInfo.regTunnel=1;
}
return 0;
}
int UdpRecv(fd_set* readSet){
if(mainInfo.udp==0){
return 0;
}
sockaddr_in fromAddr;
#if WIN32
int addrLen=sizeof(fromAddr);
#else
socklen_t addrLen=sizeof(fromAddr);
#endif
char buffer[65535] = {0};
char srcdata[65535] = {0};
memset( srcdata, 0, 65535 );
memset( srcdata, 0, 65535 );
if(FD_ISSET(udpInfo.msock,readSet)){
memset(&fromAddr, 0, sizeof(struct sockaddr_in));
int strLen = recvfrom(udpInfo.msock, buffer, 65534, 0, (struct sockaddr *)&fromAddr, &addrLen);
if(strLen>0&&strLen!=-1){
printf("udp:%s\r\n",buffer+8);
cJSON *json = cJSON_Parse( buffer+8);
if(json)
{
cJSON *Type = cJSON_GetObjectItem( json, "Type" );
if ( strcasecmp( Type->valuestring, "NewTunnel" ) == 0 )
{
NewTunnel(json);
}
else if(strcasecmp( Type->valuestring, "AuthResp" ) == 0 )
{
cJSON *Payload = cJSON_GetObjectItem( json, "Payload" );
char *error = cJSON_GetObjectItem( Payload, "Error" )->valuestring;
if(strcasecmp(error,"")==0)
{
udpInfo.auth=1;
}
}
else if(strcasecmp( Type->valuestring, "Pong" ) == 0 )
{
udpInfo.pongtime = getUnixTime();
}
else if(strcasecmp( Type->valuestring, "UdpProxy" ) == 0 )
{
cJSON *Payload = cJSON_GetObjectItem( json, "Payload" );
char *Url = cJSON_GetObjectItem( Payload, "Url" )->valuestring;
char *Data = cJSON_GetObjectItem( Payload, "Data" )->valuestring;
if(udpInfo.G_TunnelAddr.count(string(Url))>0)
{
//创建网络通信对象
TunnelReq *tunnelreq= udpInfo.G_TunnelAddr[string(Url)];
struct sockaddr_in addr;
memset(&addr, 0, sizeof(struct sockaddr_in)); //每个字节都用0填充
addr.sin_family =AF_INET;
addr.sin_port =htons(tunnelreq->localport);
addr.sin_addr.s_addr = inet_addr(tunnelreq->localhost);
int len = 0;
memset(srcdata,0,65535);
base64_decode(Data, (int)strlen(Data), srcdata, &len);
setnonblocking(udpInfo.lsock,0);
sendto(udpInfo.lsock, (const char *)srcdata, len, 0, (const sockaddr *)&addr, sizeof(struct sockaddr_in));
setnonblocking(udpInfo.lsock,1);
}else{
}
}
}
}
}
if(FD_ISSET(udpInfo.lsock,readSet)){
memset(&fromAddr, 0, sizeof(struct sockaddr_in));
int strLen = recvfrom(udpInfo.lsock, buffer, 65534, 0,(struct sockaddr *) &fromAddr, &addrLen);
memset(srcdata,0,65535);
int len = 0;
base64_encode(buffer, strLen, srcdata, &len);
if(strLen>0){
sockaddr_in sin;
memset(&sin, 0, sizeof(sockaddr_in));
memcpy(&sin, &fromAddr, sizeof(sin));
char TmpUri[255]={0};
if(GetUdpRemoteAddr(ntohs(fromAddr.sin_port),TmpUri)==0)
{
SendUdpProxy(udpInfo.msock,udpInfo.servAddr,srcdata,TmpUri,"");
}
}
}
return 0;
}
int initUdp(){
if(mainInfo.udp==0){
return 0;
}
//创建套接字
udpInfo.msock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP );
//服务器地址信息
memset(&udpInfo.servAddr, 0, sizeof(struct sockaddr_in)); //每个字节都用0填充
net_dns( &udpInfo.servAddr, mainInfo.udphost, mainInfo.udpport);
//创建socket对象
udpInfo.lsock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP );
setnonblocking(udpInfo.msock,1);
setnonblocking(udpInfo.lsock,1);
return 0;
}
/*不实际使用,保留参考*/
int UdpClient(){
initUdp();
fd_set readSet;
struct timeval timeout;
timeout.tv_sec=0;
timeout.tv_usec=0;
int SelectRcv;
while(1){
//login
CheckUdpAuth(udpInfo.msock);
//reg tunnel
CheckRegTunnel(udpInfo.msock);
CheckUdpPing(udpInfo.msock);//ping
FD_ZERO(&readSet);//总是这样先清空一个描述符集
FD_SET(udpInfo.msock,&readSet); //把sock放入要测试的描述符集
FD_SET(udpInfo.lsock,&readSet); //把sock放入要测试的描述符集
int maxfd=udpInfo.msock>udpInfo.lsock?udpInfo.msock:udpInfo.lsock;
SelectRcv = select(maxfd+1,&readSet,0,0, &timeout); //检查该套接字是否可读
if (SelectRcv > 0)
{
UdpRecv(&readSet);
}
sleeps(2);
}
}
#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。