UDP下的SOCK5代理实现

Author:zfive5(zhaozidong)
Email :zfive5@yahoo.com.cn

前些时间,以前同事叫我帮忙写一个upd下的sock5代理,由于一些原因
没有帮成他的忙,我在这里再次对他说抱歉! 关于sock5代理的包文和数据
格式可以参考以下url中的内容:
http://www.vckbase.net/document/viewdoc/?id=853
http://www.vckbase.net/document/viewdoc/?id=852
http://www.china-pub.com/computers/eMook/emooknew/rfctxt/RFC1928.txt


牙看来还是拔不了呀!医院的口腔科星期天居然没有人!!!大早晨在公交车
上一来一回8圆钱啊!

upd Sock5代理下的包数据:

client:
ver( 1 byte)+num method( 1 byte)+ methods(1 -255 byte)
(05 02 00 02)

server:

ver( 1 byte)+ num method(1 byte)
(05 00 ) or ( 05 02)

*client( 当返回 02 时):

ver(1 byte)+ name len(1 byte) +name (1-255 byte) +pass len(1 byte)+password(1 -255 byte)
( 01 01 61 01 61)

*server( 当返回 02 时):
ver(1 byte)+status(1 byte)
(05 00 )or (05 XX)

client:

ver( 1 byte)+cmd(1 byte)+rsv( 1 byte)+address type( 1 byte)+ addrss( ?? byte) +port( 2 byte)

(05 03 00 01 7f 00 00 01 0f A0)

server:
ver(1 byte)+reponse(1 byte)+rsv(1 byte)+address type(1 byte)+address(?? byte)+port( 2 byte)
(05 00 00 01 7f 00 00 01 0f A0)

client:
rsv (2 byte) + fragment( 1 byte)+ address type (1 byte)+ addr(?? byte)+ port( 2 byte) +data(??)
(00 00 00 01 7f 00 00 01 0f a0 .....)
server:
rsv (2 byte) + fragment( 1 byte)+ address type (1 byte)+ addr(?? byte)+ port( 2 byte) +data(??)
(00 00 00 01 7f 00 00 01 0f a0 .....)
....

test server代码:

SOCKET s=socket(AF_INET,SOCK_DGRAM,0);
if(s==INVALID_SOCKET)
{
closesocket(s);
return 0;
}
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=ADDR_ANY;
addr.sin_port=htons(4000);
if(bind(s,(struct sockaddr *)&addr,sizeof(struct sockaddr))==SOCKET_ERROR)
{
closesocket(s);
return 0;
}

while(1==1)
{
char sz_buf[1024];
struct sockaddr in;
int n_len=sizeof(struct sockaddr);
if(recvfrom(s,sz_buf,1024,0,(struct sockaddr *)&in,&n_len)==SOCKET_ERROR)
{
closesocket(s);
return 0;
}

if(sendto(s,"Hello World",strlen("Hello World"),0,(struct sockaddr *)&in,sizeof(struct sockaddr_in))==SOCKET_ERROR)
{
closesocket(s);
return 0;
}
}

closesocket(s);
return 0;


test client:

SOCKET s=socket(AF_INET,SOCK_DGRAM,0);
if(s==INVALID_SOCKET)
{
closesocket(s);
return;
}

struct sockaddr_in addr1;
addr1.sin_family=AF_INET;
addr1.sin_addr.s_addr=ADDR_ANY;
addr1.sin_port=htons(4001);
if(bind(s,(struct sockaddr *)&addr1,sizeof(struct sockaddr_in))==SOCKET_ERROR)
{
closesocket(s);
return;
}

zf5_sock5_udp udp;
strcpy(udp.m_sz_name,"a");
strcpy(udp.m_sz_pass,"a");
if(udp.connect_sock5_udp("127.0.0.1",1080,&addr1)<0)
{
closesocket(s);
return;
}

struct sockaddr_in addr2;
addr2.sin_family=AF_INET;
addr2.sin_addr.s_addr=inet_addr("127.0.0.1");
addr2.sin_port=htons(4000);
if(udp.send_sock5_udp(s,"hello",strlen("hello"),&addr2)<0)
{
closesocket(s);
return;
}

char sz_buf[1024]="";
memset(sz_buf,0,1024);
struct sockaddr_in addr3;
if(udp.recv_sock5_udp(s,sz_buf,&addr3)<0)
{
closesocket(s);
return;
}

AfxMessageBox(sz_buf);
return;


zf5_sock5_udp.h文件:

#pragma once
#pragma comment(lib,"ws2_32.lib")

#include <winsock2.h>
#define ZF5_BUFFER_SIZE1 255
#define ZF5_BUFFER_SIZE2 1024
#define ZF5_BUFFER_SIZE3 8192
class zf5_sock5_udp
{
public:

//构造函数
zf5_sock5_udp(void);

//析构函数
virtual ~zf5_sock5_udp(void);

//创建sock5的upd代理
int connect_sock5_udp(char *sz_addr_proxy,int n_port_proxy,struct sockaddr_in *p_addr);

//通过sock5发送udp数据
int send_sock5_udp(int s_udp,char *sz_buf,int n_len,struct sockaddr_in *p_addr);

//通过sock5接收udp数据
int recv_sock5_udp(int s_udp,char *sz_buf,struct sockaddr_in *p_addr);

//关闭sock5的udp代理
int close_sock5_udp();

//代理服务器用户名称
char m_sz_name[ZF5_BUFFER_SIZE1+2];

//代理服务器用户密码
char m_sz_pass[ZF5_BUFFER_SIZE1+2];

private:
//远端udp服务器地址
char m_sz_udp_srv[ZF5_BUFFER_SIZE2+2];

//远端udp服务器端口
int m_n_port;

//地址类型
int m_n_addrtype;

//sock5代理的tcp连接
int m_n_sock5;
};

zf5_sock5_udp.cpp文件:


#include "stdafx.h"
#include "./zf5_sock5_udp.h"

//构造函数
zf5_sock5_udp::zf5_sock5_udp(void)
{
WSADATA wsa;
WSAStartup(MAKEWORD(1,1),&wsa);
m_n_addrtype=-1;
m_n_port=0;
m_n_sock5=INVALID_SOCKET;
m_sz_name[0]=0;
m_sz_pass[0]=0;
m_sz_udp_srv[0]=0;

}

//析构函数
zf5_sock5_udp::~zf5_sock5_udp(void)
{
close_sock5_udp();
WSACleanup();
}

//创建sock5的upd代理
int zf5_sock5_udp::connect_sock5_udp(char *sz_addr_proxy,int n_port_proxy,struct sockaddr_in *p_addr)
{
SOCKET s_sock5_tcp=INVALID_SOCKET;

s_sock5_tcp=socket(AF_INET,SOCK_STREAM,0);
if(s_sock5_tcp==INVALID_SOCKET)
{
return -1;
}

timeval tv;
tv.tv_sec=10;
tv.tv_usec=0;
if(setsockopt(s_sock5_tcp,SOL_SOCKET,SO_RCVTIMEO,(char *)&tv,sizeof(timeval))==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

struct sockaddr_in sa_1;
sa_1.sin_family=AF_INET;
sa_1.sin_addr.s_addr=inet_addr(sz_addr_proxy);
sa_1.sin_port=htons(n_port_proxy);
if(sa_1.sin_addr.s_addr==INADDR_NONE)
{
struct hostent *p=gethostbyname(sz_addr_proxy);
if(p==NULL)
{
closesocket(s_sock5_tcp);
return -1;
}
sa_1.sin_addr.s_addr=((LPIN_ADDR)p->h_addr)->s_addr;
}

if(connect(s_sock5_tcp,(struct sockaddr *)&sa_1,sizeof(struct sockaddr_in))==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

char sz_buf[ZF5_BUFFER_SIZE2+2];

memset(sz_buf,0,ZF5_BUFFER_SIZE2);
sz_buf[0]=0x05;
sz_buf[1]=0x02;
sz_buf[2]=0x00;
sz_buf[3]=0x02;
if(send(s_sock5_tcp,sz_buf,4,0)==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

memset(sz_buf,0,ZF5_BUFFER_SIZE2);
if(recv(s_sock5_tcp,sz_buf,ZF5_BUFFER_SIZE2,0)==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

if(sz_buf[0]==0x05&&sz_buf[1]==0x02)
{
int n_temp1=0;
int n_temp2=0;
memset(sz_buf,0,ZF5_BUFFER_SIZE2);
n_temp1=strlen(m_sz_name);
sz_buf[0]=0x01;
sz_buf[1]=n_temp1;
memcpy((void *)&(sz_buf[2]),(void *)&(m_sz_name[0]),n_temp1);
n_temp2=strlen(m_sz_pass);
sz_buf[1+n_temp1+1]=n_temp2;
memcpy((void *)&(sz_buf[1+n_temp1+2]),(void *)&(m_sz_pass[0]),n_temp2);
if(send(s_sock5_tcp,sz_buf,n_temp1+n_temp2+3,0)==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

memset(sz_buf,0,ZF5_BUFFER_SIZE2);
if(recv(s_sock5_tcp,sz_buf,ZF5_BUFFER_SIZE2,0)==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

if(sz_buf[0]!=0x01||sz_buf[1]!=0x00)
{
closesocket(s_sock5_tcp);
return -1;
}
}
else if(sz_buf[0]!=0x05||sz_buf[1]!=0x00)
{
closesocket(s_sock5_tcp);
return -1;
}

memset(sz_buf,0,ZF5_BUFFER_SIZE2);
sz_buf[0]=0x05;
sz_buf[1]=0x03;
sz_buf[2]=0x00;
sz_buf[3]=0x01;

*((int *)(&sz_buf[4]))=p_addr->sin_addr.s_addr;
*((short *)(&(sz_buf[8])))=(short)p_addr->sin_port;

if(send(s_sock5_tcp,sz_buf,10,0)==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

memset(sz_buf,0,ZF5_BUFFER_SIZE2);
if(recv(s_sock5_tcp,sz_buf,ZF5_BUFFER_SIZE2,0)==SOCKET_ERROR)
{
closesocket(s_sock5_tcp);
return -1;
}

if(sz_buf[0]!=0x05||sz_buf[1]!=0x00)
{
closesocket(s_sock5_tcp);
return -1;
}

if(sz_buf[3]==0x01)
{
int n_ip=*((int *)&sz_buf[4]);
struct in_addr in;
in.S_un.S_addr=n_ip;
memset((void *)m_sz_udp_srv,0,sizeof(m_sz_udp_srv));
strcpy(m_sz_udp_srv,inet_ntoa(in));
m_n_port=htons(*((short *)&(sz_buf[8])));
m_n_addrtype=0x01;
}
else if(sz_buf[3]==0x03)
{
memset((void *)m_sz_udp_srv,0,sizeof(m_sz_udp_srv));
strncpy(m_sz_udp_srv,&sz_buf[5],sz_buf[4]);
m_n_port=htons(*((short *)&(sz_buf[5+sz_buf[4]])));
m_n_addrtype=0x03;
}
else
{
closesocket(s_sock5_tcp);
return -1;
}

m_n_sock5=s_sock5_tcp;

return 0;
}

//通过sock5发送udp数据
int zf5_sock5_udp::send_sock5_udp(int s_udp,char *sz_buf,int n_len,struct sockaddr_in *p_addr)
{
char sz_buf1[ZF5_BUFFER_SIZE3+2];
int n_len1=0;
sz_buf1[0]=0x00;
sz_buf1[1]=0x00;
sz_buf1[2]=0x00;
sz_buf1[3]=0x01;
memcpy((void *)&sz_buf1[4],(void *)&(p_addr->sin_addr.s_addr),4);
memcpy((void *)&sz_buf1[8],(void *)&(p_addr->sin_port),2);
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(m_sz_udp_srv);
addr.sin_port=htons(m_n_port);
if(addr.sin_addr.s_addr==INADDR_NONE)
{
struct hostent *p=gethostbyname(m_sz_udp_srv);
if(p==NULL)
{
return -1;
}
addr.sin_addr.s_addr=((LPIN_ADDR)p->h_addr)->s_addr;
}

memcpy(&sz_buf1[10],sz_buf,n_len);

int n_ret=-1;
n_ret=sendto(s_udp,sz_buf1,n_len+10,0,(struct sockaddr *)&addr,sizeof(struct sockaddr_in ));

return n_ret;
}

//通过sock5接收udp数据
int zf5_sock5_udp::recv_sock5_udp(int s_udp,char *sz_buf,struct sockaddr_in *p_addr)
{
char sz_buf1[ZF5_BUFFER_SIZE3+2];
struct sockaddr_in addr;
int n_ret=-1;
int n_len1=0;
int n_len2=sizeof(struct sockaddr_in);
n_ret=recvfrom(s_udp,sz_buf1,ZF5_BUFFER_SIZE3,0,(struct sockaddr *)&addr,&n_len2);
if(n_ret==SOCKET_ERROR)
{
return -1;
}

if(sz_buf1[3]==0x01)
{
p_addr->sin_family=AF_INET;
p_addr->sin_addr.s_addr=*((int *)&(sz_buf1[4]));
p_addr->sin_port=*((short *)&(sz_buf1[8]));
n_ret-=10;
memcpy(sz_buf,&sz_buf1[10],n_ret);
}
else if(sz_buf1[3]==0x03)
{
char sz_buf2[ZF5_BUFFER_SIZE2+2];
memset(sz_buf2,0,ZF5_BUFFER_SIZE2);
strncpy(sz_buf2,sz_buf2,sz_buf1[4]);
struct hostent *p=gethostbyname(sz_buf2);
if(p==NULL)
{
return -1;
}
n_len1=4+sz_buf1[4];
p_addr->sin_family=AF_INET;
p_addr->sin_addr.s_addr=((LPIN_ADDR)p->h_addr)->s_addr;
p_addr->sin_port=*((short *)&(sz_buf1[n_len1]));

n_ret-=(n_len1+2);
memcpy((void *)sz_buf,(void *)&sz_buf1[n_len1],n_ret);

n_ret-=(4+2+1+sz_buf1[4]);
}
else
{
return -1;
}

return n_ret;
}

//关闭sock5的udp代理
int zf5_sock5_udp::close_sock5_udp()
{
if(m_n_sock5!=INVALID_SOCKET)
{
closesocket(m_n_sock5);
m_n_sock5=INVALID_SOCKET;
}

return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的 C 语言实现 SOCKS5 代理程序的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #define PORT 8888 int main(int argc, char const *argv[]) { int proxy_sock, client_sock, server_sock, valread; struct sockaddr_in proxy_addr, client_addr, server_addr; char buffer[1024] = {0}; // 创建代理服务器 socket if ((proxy_sock = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 设置代理服务器地址 proxy_addr.sin_family = AF_INET; proxy_addr.sin_addr.s_addr = INADDR_ANY; proxy_addr.sin_port = htons(PORT); // 绑定代理服务器 socket if (bind(proxy_sock, (struct sockaddr *)&proxy_addr, sizeof(proxy_addr)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 开始监听 if (listen(proxy_sock, 3) < 0) { perror("listen failed"); exit(EXIT_FAILURE); } while (1) { printf("Waiting for incoming connection...\n"); int addr_len = sizeof(client_addr); // 接受客户端连接 if ((client_sock = accept(proxy_sock, (struct sockaddr *)&client_addr, (socklen_t *)&addr_len)) < 0) { perror("accept failed"); exit(EXIT_FAILURE); } printf("Client connected from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); // 读取客户端请求 valread = read(client_sock, buffer, 1024); printf("%s\n", buffer); // 连接目标服务器 if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 设置目标服务器地址 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(80); if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) { perror("inet_pton failed"); exit(EXIT_FAILURE); } // 连接目标服务器 if (connect(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("connect failed"); exit(EXIT_FAILURE); } // 将客户端请求转发给目标服务器 send(server_sock, buffer, strlen(buffer), 0); printf("Request forwarded to server\n"); // 读取目标服务器响应 valread = read(server_sock, buffer, 1024); printf("Response received from server\n"); // 将目标服务器响应转发给客户端 send(client_sock, buffer, strlen(buffer), 0); printf("Response forwarded to client\n"); close(client_sock); close(server_sock); } return 0; } ``` 这段代码创建了一个 SOCKS5 代理服务器,监听指定端口号。当客户端连接到该端口时,代理服务器会读取客户端请求并连接到目标服务器,将客户端请求转发给目标服务器,并读取目标服务器响应并将其转发给客户端。注意,该示例代码中的目标服务器地址和端口号是硬编码的,需要根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值