linux下最简单多线程单文件socks5代理proxy服务器程序(仅一个c文件,带详细注解)

2020.9.11

网上看的都比较复杂,GITHUB找了一个多线程的相对简单的MicroSocks项目,花了几周时间(没办法,菜鸟一个)改了一下,改成单文件,测试OK。

 

 

/* wxl_socks5_proxy_server_v1.0
linux下最简单多线程单文件socks5代理proxy服务器程序(仅一个c文件,带详细注解)
wxleasyland@sina.com
2020.9
说明:
编译方法:gcc xxxx.c -pthread -o xxxx
一个线程对应一个客户端。
只支持TCP CONNECT方式和无用户验证。
*/


/* 感谢原作者。
程序主要在github开源项目MicroSocks基础上修改得到的:
https://github.com/rofl0r/microsocks

也少量参考了github开源项目HevSocks5Server:
https://github.com/heiher/hev-socks5-server
*/


/*
firefox可以选socks4还是socks5。

chrome 设置代理是在IE。 然后打开网页失败,抓包发现chrome是走SOCKS4版本。
     在IE的“代理服务器设置”的“套接字”中,写成socks5://xxx.xxx.xxx.xxx就可以了,
     chrome就会走SOCKS5版本了。  如果写成socks4://xxx.xxx.xxx.xxx,就又会走SOCKS4版本了。

firefox一下打开好几个网页窗口,大约线程数是接近200个,突发起来还是挺猛的。
chrome一下打开好几个网页窗口,大约线程数是50个,看来对socket的数量控制得比较好。

取单个线程堆栈为64K,占用内存不大,自己用用可以。
*/


#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stddef.h>


union sockaddr_union 
{
    struct sockaddr_in  v4;
    struct sockaddr_in6 v6;
};


// static pthread_mutex_t auth_ips_mutex = PTHREAD_MUTEX_INITIALIZER;    //静态初始化互斥锁(暂未用到)

int g_totalthread=0;   //总线程数量统计
int g_proxymode=0;     //1表示正常CONNECT类型   4表示我自定义的DNS获取IP地址


int my_resolve(const char *host, unsigned short port, struct addrinfo** addr)   //主要是getaddrinfo()得到远程主机的IP
{
    struct addrinfo hints = 
    {
        .ai_family = AF_UNSPEC,  // AF_INET是IPV4   //AF_INET6是IPV6
        .ai_socktype = SOCK_STREAM,
        .ai_flags = AI_PASSIVE,
    };
    
    char port_buf[8];
    snprintf(port_buf, sizeof port_buf, "%u", port);
    
    return getaddrinfo(host, port_buf, &hints, addr);  
       //getaddrinfo函数用域名或主机名获取IP地址,返回的是一个sockaddr结构的链表。
       //int getaddrinfo( const char *hostname,  const char *service,  const struct addrinfo *hints, struct addrinfo **result );
       //返回值:0——成功,非0——出错
}

//ssize_t   recv(int sockfd, void *buf, size_t len, int flags);
//return the number of bytes received, or -1 if an error occurred.
//When a stream socket peer has performed an orderly shutdown, the return value will be 0
ssize_t  my_recv_all (int fd, void *buf, size_t len)      //引用自HevSocks5Server项目
{
    ssize_t s;
    size_t size = 0;

if(len<=0) return len;

retry:
    s = recv (fd, buf + size, len - size, MSG_WAITALL);
    if (s < 0)   //阻塞下出错
    {
            return s;
    }
    if (s == 0)  //对方中止连接
        return -1;

    size += s;
    if (size < len)
        goto retry;

    return size;
}

void send_error1(int fd, unsigned char d)    //返回错误信息给客户
{
    unsig

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值