当前位置:编程学习 > 网站相关 >>

socks5协议转http协议源码

作者:无双   来源:http://www.loveunix.net/

socks5代理可以看rfc 1928
socks5的用户名口令认证方法看rfc 1929

http代理可以看 rfc2616
socks5代理可以支持tcp和udp 而http只支持tcp

所以这个代理转换器只支持tcp


写作原因
很多软件都有socks5认证方法 但是它们不支持http认证方法
而从原理上可以使用http认证方法(因为它们没有使用udp)
所以写这个软件可以方便的使其它程序可以使用http代理

如联众 或是foxmail

 

CODE

#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#define INIT_SOCKET(){WSADATA   wsadata;WSAStartup(MAKEWORD(2,2),&wsadata);}
#define CLOSESOCKET(x) closesocket(x)
#define CLEAN_SOCKET()  {WSACleanup();}
//  http.c  实现http代理功能

#define PROTO_EXCHANGE_TIMEOUT 15
#define PROTO_RECVRESP_TIMEOUT 75
#define PROTO_SENDRESP_TIMEOUT 10

#define WAIT_AND_RECV(sd,buf,len,waittime,recvflags)    do{
   struct fd_set sset;
   struct timeval waited;
   waited.tv_sec   = waittime;waited.tv_usec   = 0;
   FD_ZERO(&sset);FD_SET(sd,&sset);
   if(select(sd+1,&sset,NULL,NULL,&waited) != 1 || (len = recv(sd,buf,len,recvflags)) == -1 )
   len = -1;
}while(0);

#define DEBUG_DUMP      printf

static int httpproxy_connect(const char*proxyaddr,int proxyport,
       const char*dstaddr,int dstport)
{
   int                 proxysd = -1;
   char                buf[2048];
   int                 len;
   char                *ptoken;
   int                 status;

   struct  sockaddr_in inaddr;

   if( !proxyaddr || !proxyaddr[0] || proxyport < 1
           ||!dstaddr || !dstaddr[0] )
       return -1;

   DEBUG_DUMP("代理:%s:%d,目标:%s:%d ",proxyaddr,proxyport,dstaddr,dstport);

   len                 = sizeof(inaddr);
   memset(&inaddr,0,len);
   if( (inaddr.sin_addr.s_addr = inet_addr(proxyaddr) ) == INADDR_NONE )
       return -1;

   inaddr.sin_family    = AF_INET;
   inaddr.sin_port      = htons(proxyport);

   //  connect to proxy
   if((proxysd = socket(AF_INET,SOCK_STREAM,0)) == -1 )
       return -1;
   if( connect(proxysd,(struct sockaddr*)&inaddr,len))
       goto errorparse;

   //  发送connect请求并判断返回,根据HTTP协议说明,详细内容请看RFC2616
   //  HTTP代理使用CONNECT指令实现,CONNECT时指定选端的地址与端口号,
   //  当代理服务器返回成功后(状态值是2xx),后面的代理服务器不再对此连接的数据
   //  进行HTTP协议处理
   if( dstport > 0 )
       len = sprintf(buf,"CONNECT %s:%d HTTP/1.1 ",dstaddr,dstport);
   else
       len = sprintf(buf,"CONNECT %s HTTP/1.1 ",dstaddr);

   if( send(proxysd,buf,len,0) != len ){
       DEBUG_DUMP("发送CONNECT请求失败:包内容:%s ",buf);
       goto errorparse;
   }

   len = sizeof(buf)-1;
   WAIT_AND_RECV(proxysd,buf,len,PROTO_RECVRESP_TIMEOUT,MSG_PEEK);
   if( len == -1){
       DEBUG_DUMP("接收CONNECT响应失败 ");
       goto errorparse;
   }

   buf[len]    = 0;
   DEBUG_DUMP("CONNECT响应为:%s| ",buf);
   if( strnicmp(buf,"HTTP/1.",7)
           || (!strstr(buf," ") && !strstr(buf," ")))
       goto errorparse;

   ptoken  = buf;
   while(!isspace(*ptoken) && *ptoken) ptoken ++;
   status  = atoi(ptoken);
   if( status < 300 && status > 199 ){
       ptoken  = strstr(buf," ");
       if( ptoken )
           len  = ptoken - buf +4;
       else{
           ptoken = strstr(buf," ");
           len  = ptoken - buf +2;
       }
       WAIT_AND_RECV(proxysd,buf,len,PROTO_RECVRESP_TIMEOUT,0);
       return proxysd;
   }

errorparse:
   CLOSESOCKET(proxysd);
   return -1;
}

//  sd          [in]    使用socks5的客户端的连接id
//  proxyaddr   [in]    http代理地址
//  proxyport   [in]    http代理端口
//  return:
//          -1  失败
//          >=0 与http代理的连接id
static int socks5_accept(int sd,const char *proxyaddr,int proxyport)
{
   unsigned char       buf[512];
   int                 len = 2;
   int                 i   = 0;
   char                dstaddr[260];
   int                 dstport;

   if( !proxyaddr || !proxyaddr[0] || proxyport <1 )
       return -1;

   //  处理协商,现在只处理无认证情况,无论对方会不会处理这种情况
   //  没有要求无认证方式,sorry,那我就不理它
   //  另外只处理SOCKS5的CONNECT命令,其它不处理
   WAIT_AND_RECV(sd,(char*)buf,len,PROTO_EXCHANGE_TIMEOUT,0);
   if( len != 2 || buf[0] != 5 ){
       DEBUG_DUMP("接收socks5协商包失败,len:%d,buf[0]:%d ",len,buf[0]);
       return -1;
   }
   len = buf[1];
   i   = len;
   WAIT_AND_RECV(sd,(char*)buf,i,PROTO_EXCHANGE_TIMEOUT,0);
   if( len != i ){
       DEBUG_DUMP("接收socks5协商包失败,想接收%d,收到:%d ",len,i);
       return -1;
   }

   for( i = 0;i< len && buf[i];i++ );

   if( i == l

补充:综合编程 , 安全编程 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,