├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── client.c ├── client.h ├── common.c ├── common.h ├── config.c ├── config.h ├── exception.h ├── main.c ├── server.c ├── server.h ├── sock5.c └── sock5.h /.gitignore: -------------------------------------------------------------------------------- 1 | cmake-build-debug/ 2 | CMakeFiles/ 3 | cmake_install.cmake 4 | CMakeCache.txt 5 | Makefile 6 | tawdemo-socks5-c 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7) 2 | project(tawdemo-socks5-c C) 3 | 4 | set(CMAKE_C_STANDARD 99) 5 | 6 | add_executable(tawdemo-socks5-c main.c sock5.c sock5.h config.c config.h exception.h common.h common.c client.c client.h server.c server.h) 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 lyytaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tawdemo-socks5-c 2 | 3 | tawdemo-socks5-c为一个C语言编写的sock5代理工具DEMO,需要同时部署客户端和服务端。 4 | 5 | 本项目仅作研究linux底层网络通信学习使用。不具备生产特性,请勿用于生产环境。 6 | 7 | ps: 个人并不是专业写C语言的,使用C语言只是为了加深对网络协议底层处理的了解,因此项目代码风格非常糟糕,请勿随意模仿,还请见谅 8 | 9 | ### 环境 10 | 11 | 系统:linux或mac 12 | 13 | ### 使用方式 14 | 15 | ##### 1. 构建编译 16 | 17 | ```bash 18 | git clone tawdemo-socks5-c 19 | cd tawdemo-socks5-c 20 | cmake . 21 | make 22 | ``` 23 | 24 | ##### 2. 使用 25 | 26 | **客户端** 27 | 28 | ```bash 29 | ./tawdemo-socks5-c -P [本地监听端口] -c -h [服务器地址] -p [服务器端口] 30 | ``` 31 | 32 | **服务端** 33 | 34 | ```bash 35 | ./tawdemo-socks5-c -P [本地监听端口] -s 36 | ``` 37 | 38 | ### 版本信息 39 | 40 | ##### v1.0 41 | 42 | 初版,仅支持不设密码的sock5协议,仅支持TCP代理,客户端与服务端之间未做压缩/加密处理。只具备初步可用性。 43 | 44 | ### 协议 45 | 46 | 本项目使用[MIT协议](https://github.com/lyytaw/tawdemo-socks5-c/blob/master/LICENSE)。 47 | -------------------------------------------------------------------------------- /client.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-20. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "client.h" 11 | #include "common.h" 12 | #include "config.h" 13 | 14 | int handleUserRequest(struct Config config, int userSock) { 15 | int serverSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 16 | if (serverSock < 0) { 17 | return -1; 18 | } 19 | 20 | struct sockaddr_in remoteAddr; 21 | remoteAddr.sin_family = AF_INET; 22 | remoteAddr.sin_port = htons(config.serverPort); 23 | struct hostent *dstHost = gethostbyname(config.serverHost); 24 | remoteAddr.sin_addr.s_addr = *(in_addr_t *)dstHost->h_addr; 25 | 26 | if (retryConnect(serverSock, (struct sockaddr*)&remoteAddr, sizeof(remoteAddr)) < 0) { 27 | return -1; 28 | } 29 | 30 | if (fork() == 0) { 31 | forwardData(userSock, serverSock, 1); 32 | exit(0); 33 | } 34 | if (fork() == 0) { 35 | forwardData(serverSock, userSock, 0); 36 | exit(0); 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | void clientLoop(struct Config config, int clientSock) { 43 | printf("client loop...\n"); 44 | struct sockaddr_in userAddr; 45 | socklen_t clientAddrLength = sizeof(userAddr); 46 | 47 | while (1) { 48 | printf("wait for user...\n"); 49 | int userSock = accept(clientSock, (struct sockaddr *)&userAddr, &clientAddrLength); 50 | if (userSock == -1) { 51 | continue; 52 | } 53 | if (fork() == 0) { 54 | close(clientSock); 55 | handleUserRequest(config, userSock); 56 | exit(0); 57 | } 58 | close(userSock); 59 | } 60 | } 61 | 62 | void startClient(struct Config config) { 63 | printf("start client...\n"); 64 | int clientSock = createListeningSocket(config.localPort); 65 | if (clientSock < 0) { 66 | printf("Cannot create listening socket on port %d.\n", config.localPort); 67 | exit(clientSock); 68 | } 69 | 70 | clientLoop(config, clientSock); 71 | } -------------------------------------------------------------------------------- /client.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-20. 3 | // 4 | 5 | #ifndef MZZ_BRIDGE_C_CLIENT_H 6 | #define MZZ_BRIDGE_C_CLIENT_H 7 | 8 | #include "config.h" 9 | 10 | void startClient(struct Config config); 11 | 12 | #endif //MZZ_BRIDGE_C_CLIENT_H 13 | -------------------------------------------------------------------------------- /common.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-17. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "common.h" 10 | #include "exception.h" 11 | 12 | #define RETRY_TIME 10 13 | 14 | Byte* Byte_copyN(Byte *dst, const Byte *src, size_t n) { 15 | memcpy(dst, src, n); 16 | return dst; 17 | } 18 | 19 | char* Byte_arrayToStr(Byte *src, size_t n) { 20 | char* result = (char *)malloc(n + 1); 21 | memcpy(result, src, n); 22 | result[n] = '\0'; 23 | return result; 24 | } 25 | 26 | int retryConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { 27 | for (int i = 0; i < RETRY_TIME; i++) { 28 | int result = connect(sockfd, addr, addrlen); 29 | if (result >= 0) { 30 | return result; 31 | } 32 | } 33 | return -1; 34 | } 35 | 36 | ssize_t retryRecv(int sockfd, void *buf, size_t len) { 37 | for (int i = 0; i < RETRY_TIME; i++) { 38 | ssize_t result = recv(sockfd, buf, len, 0); 39 | if (result >= 0) { 40 | return result; 41 | } 42 | } 43 | return -1; 44 | } 45 | 46 | ssize_t retrySend(int sockfd, const void *buf, size_t len) { 47 | for (int i = 0; i < RETRY_TIME; i++) { 48 | ssize_t result = send(sockfd, buf, len, 0); 49 | if (result >= 0) { 50 | return result; 51 | } 52 | } 53 | return -1; 54 | } 55 | 56 | int createListeningSocket(int port) { 57 | int listeningSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 58 | if (listeningSock < 0) { 59 | return SERVER_SOCKET_CREATE_ERROR; 60 | } 61 | 62 | int optval; 63 | setsockopt(listeningSock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); 64 | 65 | struct sockaddr_in serverAddr; 66 | memset(&serverAddr, 0, sizeof(serverAddr)); 67 | serverAddr.sin_family = AF_INET; 68 | serverAddr.sin_port = htons(port); 69 | serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); 70 | 71 | if (bind(listeningSock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) != 0) { 72 | return SERVER_SOCKET_BIND_ERROR; 73 | } 74 | 75 | if (listen(listeningSock, 30) != 0) { 76 | return SERVER_SOCKET_LISTEN_ERROR; 77 | } 78 | 79 | return listeningSock; 80 | } 81 | 82 | void forwardData(int srcSock, int dstSock, int encryption) { 83 | char buffer[8192]; 84 | ssize_t n; 85 | while ((n = retryRecv(srcSock, buffer, 8000)) > 0) { 86 | if (retrySend(dstSock, buffer, (size_t)n) < 0) { 87 | break; 88 | } 89 | } 90 | shutdown(srcSock, SHUT_RDWR); 91 | shutdown(dstSock, SHUT_RDWR); 92 | } -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-17. 3 | // 4 | 5 | #ifndef MZZ_BRIDGE_C_COMMON_H 6 | #define MZZ_BRIDGE_C_COMMON_H 7 | 8 | #include 9 | #include 10 | 11 | typedef unsigned char Byte; 12 | 13 | /** 14 | * 拷贝n个字节,不忽略'\0' 15 | * @param dst 目标串 16 | * @param src 源串 17 | * @param n 拷贝长度 18 | * @return 目标串的地址 19 | */ 20 | Byte* Byte_copyN(Byte *dst, const Byte *src, size_t n); 21 | 22 | /** 23 | * 将Byte数组转换成字符串 24 | * @param src 25 | * @param n 26 | * @return 27 | */ 28 | char* Byte_arrayToStr(Byte *src, size_t n); 29 | 30 | int retryConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 31 | 32 | ssize_t retryRecv(int sockfd, void *buf, size_t len); 33 | 34 | ssize_t retrySend(int sockfd, const void *buf, size_t len); 35 | 36 | /** 37 | * 创建监听socket 38 | * @param port 39 | * @return 40 | */ 41 | int createListeningSocket(int port); 42 | 43 | /** 44 | * 传输数据 45 | * @param srcSock 46 | * @param dstSock 47 | * @param encryption 1.加密 0.解密 48 | */ 49 | void forwardData(int srcSock, int dstSock, int encryption); 50 | 51 | #endif //MZZ_BRIDGE_C_COMMON_H 52 | -------------------------------------------------------------------------------- /config.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-15. 3 | // 4 | 5 | #include "config.h" 6 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-15. 3 | // 4 | 5 | #ifndef MZZ_BRIDGE_C_CONFIG_H 6 | #define MZZ_BRIDGE_C_CONFIG_H 7 | 8 | struct Config { 9 | int localPort; // -p [port], 本地监听端口 10 | int client; // 客户端模式 11 | int server; // 服务端模式 12 | char* serverHost; // 客户端模式下,需要指定服务端地址 13 | int serverPort; // 客户端模式下,需要指定服务端端口 14 | }; 15 | 16 | #endif //MZZ_BRIDGE_C_CONFIG_H 17 | -------------------------------------------------------------------------------- /exception.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-15. 3 | // 4 | 5 | #ifndef MZZ_BRIDGE_C_EXCEPTION_H 6 | #define MZZ_BRIDGE_C_EXCEPTION_H 7 | 8 | #define SERVER_SOCKET_CREATE_ERROR -1 9 | #define SERVER_SOCKET_BIND_ERROR -2 10 | #define SERVER_SOCKET_LISTEN_ERROR -3 11 | 12 | #endif //MZZ_BRIDGE_C_EXCEPTION_H 13 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "config.h" 6 | #include "client.h" 7 | #include "server.h" 8 | 9 | int main(int argc, char *argv[]) { 10 | struct Config config; 11 | int opt; 12 | opterr = 0; 13 | while ((opt = getopt(argc, argv, "P:csh:p:")) != EOF) { 14 | switch (opt) { 15 | case 'P': config.localPort = atoi(optarg); break; 16 | case 'c': config.client = 1; config.server = 0; break; 17 | case 's': config.client = 0; config.server = 1; break; 18 | case 'h': config.serverHost = optarg; break; 19 | case 'p': config.serverPort = atoi(optarg); break; 20 | } 21 | } 22 | signal(SIGCHLD, SIG_IGN); 23 | if (config.client) { 24 | startClient(config); 25 | } else if (config.server) { 26 | startServer(config); 27 | } 28 | return 0; 29 | } -------------------------------------------------------------------------------- /server.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-20. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "server.h" 11 | #include "common.h" 12 | #include "sock5.h" 13 | 14 | int validateSock5Connection(int clientSock) { 15 | printf("validate sock5 connection.\n"); 16 | char buffer[SOCK5_VALIDATE_REQUEST_MAX_LENGTH]; 17 | 18 | if (retryRecv(clientSock, buffer, SOCK5_VALIDATE_REQUEST_MAX_LENGTH) < 0) { 19 | return -1; 20 | } 21 | 22 | struct Sock5ValidateRequest request = Sock5ValidateRequest_read((Byte *)buffer); 23 | 24 | int ok = 1; 25 | 26 | ok &= request.version == 0x05; // 验证客户端协议版本是否正确 27 | 28 | // 验证客户端是否支持无验证方式的请求 29 | int allowNoAuth = 0; 30 | for (int i = 0; i < request.methodNum; i++) { 31 | if (request.methods[i] == 0x00) { 32 | allowNoAuth = 1; 33 | break; 34 | } 35 | } 36 | ok &= allowNoAuth; 37 | 38 | struct Sock5ValidateResponse response; 39 | response.version = 0x05; 40 | response.method = ok ? (Byte)0x00 : (Byte)0xFF; 41 | return (int)retrySend(clientSock, Sock5ValidateResponse_toString(response), 2); 42 | } 43 | 44 | int createSock5Connection(struct Config config, int clientSock) { 45 | printf("create sock5 connection.\n"); 46 | char buffer[SOCK5_BUILD_REQUEST_MAX_LENGTH]; 47 | if (retryRecv(clientSock, buffer, SOCK5_BUILD_REQUEST_MAX_LENGTH) < 0) { 48 | return -1; 49 | } 50 | 51 | struct Sock5BuildRequest request = Sock5BuildRequest_read((Byte *)buffer); 52 | if (request.version < 0) { 53 | return -1; 54 | } 55 | if (request.cmd != 0x01) { // 目前支持CONNECT方式,后续扩展 56 | return -1; 57 | } 58 | 59 | // 代理服务器创建到远程主机的连接 60 | int remoteSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 61 | if (remoteSock < 0) { 62 | return -1; 63 | } 64 | 65 | struct sockaddr_in remoteAddr; 66 | remoteAddr.sin_family = AF_INET; 67 | remoteAddr.sin_port = htons(request.dstPort); 68 | if (request.atyp == 0x01) { 69 | in_addr_t ip; 70 | memcpy(&ip, request.dstAddr, 4); 71 | remoteAddr.sin_addr.s_addr = htonl(ip); 72 | } else if (request.atyp == 0x03) { 73 | struct hostent *dstHost = gethostbyname(Byte_arrayToStr(request.dstAddr, request.addrLength)); 74 | remoteAddr.sin_addr.s_addr = *(in_addr_t *)dstHost->h_addr; 75 | } else { 76 | return -1; 77 | } 78 | 79 | if (retryConnect(remoteSock, (struct sockaddr*)&remoteAddr, sizeof(remoteAddr)) < 0) { 80 | return -1; 81 | } 82 | 83 | // 响应客户端 84 | struct Sock5BuildResponse response; 85 | response.version = 0x05; 86 | response.rep = 0x00; 87 | response.rsv = 0x00; 88 | response.atyp = 0x01; 89 | response.addrLength = 4; 90 | uint ip = (127U << 24) + 1; 91 | response.bndAddr = (Byte *)&ip; 92 | response.bndPort = (ushort)config.localPort; 93 | char* responseStr = Sock5BuildResponse_toString(response); 94 | if (retrySend(clientSock, responseStr, Sock5BuildResponse_getLength(response)) < 0) { 95 | return -1; 96 | } 97 | 98 | return remoteSock; 99 | } 100 | 101 | void handleClientRequest(struct Config config, int clientSock) { 102 | printf("handle client socket.\n"); 103 | if (validateSock5Connection(clientSock) < 0) { 104 | return; 105 | } 106 | int remoteSock = createSock5Connection(config, clientSock); 107 | if (remoteSock < 0) { 108 | return; 109 | } 110 | 111 | if (fork() == 0) { 112 | forwardData(clientSock, remoteSock, 0); 113 | exit(0); 114 | } 115 | if (fork() == 0) { 116 | forwardData(remoteSock, clientSock, 1); 117 | exit(0); 118 | } 119 | } 120 | 121 | 122 | void serverLoop(struct Config config, int serverSock) { 123 | printf("server loop...\n"); 124 | struct sockaddr_in clientAddr; 125 | socklen_t clientAddrLength = sizeof(clientAddr); 126 | 127 | while (1) { 128 | printf("wait for client...\n"); 129 | int clientSock = accept(serverSock, (struct sockaddr*)&clientAddr, &clientAddrLength); 130 | if (clientSock == -1) { 131 | continue; 132 | } 133 | printf("client sock: %d\n", clientSock); 134 | if (fork() == 0) { 135 | close(serverSock); 136 | handleClientRequest(config, clientSock); 137 | exit(0); 138 | } 139 | close(clientSock); 140 | } 141 | } 142 | 143 | void startServer(struct Config config) { 144 | printf("start server...\n"); 145 | int serverSock = createListeningSocket(config.localPort); 146 | if (serverSock < 0) { 147 | printf("Cannot create server socket."); 148 | exit(serverSock); 149 | } 150 | 151 | serverLoop(config, serverSock); 152 | } 153 | -------------------------------------------------------------------------------- /server.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-20. 3 | // 4 | 5 | #ifndef MZZ_BRIDGE_C_SERVERR_H 6 | #define MZZ_BRIDGE_C_SERVERR_H 7 | 8 | #include "config.h" 9 | 10 | void startServer(struct Config config); 11 | 12 | #endif //MZZ_BRIDGE_C_SERVERR_H 13 | -------------------------------------------------------------------------------- /sock5.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-15. 3 | // 4 | 5 | #include 6 | #include 7 | #include "sock5.h" 8 | #include "common.h" 9 | 10 | struct Sock5ValidateRequest Sock5ValidateRequest_read(Byte *buffer) { 11 | struct Sock5ValidateRequest request; 12 | request.version = buffer[0]; 13 | request.methodNum = buffer[1]; 14 | request.methods = (Byte *)malloc(request.methodNum); 15 | Byte_copyN(request.methods, buffer + 2, request.methodNum); 16 | return request; 17 | } 18 | 19 | size_t Sock5ValidateResponse_getLength(struct Sock5ValidateResponse response) { 20 | return 2; 21 | } 22 | 23 | char* Sock5ValidateResponse_toString(struct Sock5ValidateResponse response) { 24 | Byte *result = (Byte *)malloc(3); 25 | int p = 0; 26 | result[p++] = response.version; 27 | result[p] = response.method; 28 | return (char *)result; 29 | } 30 | 31 | struct Sock5BuildRequest Sock5BuildRequest_read(Byte *buffer) { 32 | struct Sock5BuildRequest request; 33 | int p = 0; 34 | request.version = buffer[p++]; 35 | request.cmd = buffer[p++]; 36 | request.rsv = buffer[p++]; 37 | request.atyp = buffer[p++]; 38 | switch (request.atyp) { 39 | case 0x01: request.addrLength = 4; break; 40 | case 0x03: request.addrLength = buffer[p++]; break; 41 | case 0x04: request.addrLength = 16; break; 42 | default: request.addrLength = 0; 43 | } 44 | request.dstAddr = (Byte *)malloc(request.addrLength); 45 | Byte_copyN(request.dstAddr, buffer + p, request.addrLength); 46 | p += request.addrLength; 47 | request.dstPort = (buffer[p] << 8) + buffer[p+1]; 48 | return request; 49 | } 50 | 51 | size_t Sock5BuildResponse_getLength(struct Sock5BuildResponse response) { 52 | return response.addrLength + (response.atyp == 0x03 ? 7 : 6); 53 | } 54 | 55 | char* Sock5BuildResponse_toString(struct Sock5BuildResponse response) { 56 | Byte *result = (Byte *)malloc(Sock5BuildResponse_getLength(response)); 57 | int p = 0; 58 | result[p++] = response.version; 59 | result[p++] = response.rep; 60 | result[p++] = response.rsv; 61 | result[p++] = response.atyp; 62 | if (response.atyp == 0x03) { 63 | result[p++] = response.addrLength; 64 | } 65 | Byte_copyN(result + p, response.bndAddr, response.addrLength); 66 | p += response.addrLength; 67 | result[p++] = (Byte)(response.bndPort >> 8); 68 | result[p] = (Byte)(response.bndPort & 0xff); 69 | return (char *)result; 70 | } 71 | -------------------------------------------------------------------------------- /sock5.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by cayun on 2019-03-15. 3 | // 4 | 5 | #ifndef MZZ_BRIDGE_C_SOCK5_H 6 | #define MZZ_BRIDGE_C_SOCK5_H 7 | 8 | #include "common.h" 9 | 10 | #define SOCK5_VALIDATE_REQUEST_MAX_LENGTH 3 11 | #define SOCK5_BUILD_REQUEST_MAX_LENGTH 263 12 | 13 | struct Sock5ValidateRequest { 14 | Byte version; 15 | Byte methodNum; 16 | Byte *methods; 17 | }; 18 | 19 | struct Sock5ValidateResponse { 20 | Byte version; 21 | Byte method; 22 | }; 23 | 24 | struct Sock5BuildRequest { 25 | Byte version; 26 | Byte cmd; 27 | Byte rsv; 28 | Byte atyp; 29 | Byte addrLength; // 地址长度 30 | Byte *dstAddr; 31 | ushort dstPort; 32 | }; 33 | 34 | struct Sock5BuildResponse { 35 | Byte version; 36 | Byte rep; 37 | Byte rsv; 38 | Byte atyp; 39 | Byte addrLength; // 地址长度 40 | Byte *bndAddr; 41 | ushort bndPort; 42 | }; 43 | 44 | /** 45 | * 读取sock5验证请求 46 | * @param buffer 47 | * @return 48 | */ 49 | struct Sock5ValidateRequest Sock5ValidateRequest_read(Byte *buffer); 50 | 51 | /** 52 | * 获取Sock5ValidateResponse的总长度 53 | * @param response 54 | * @return 55 | */ 56 | size_t Sock5ValidateResponse_getLength(struct Sock5ValidateResponse response); 57 | 58 | /** 59 | * 将sock5验证响应转换为字符串 60 | * @param response 61 | * @return 62 | */ 63 | char* Sock5ValidateResponse_toString(struct Sock5ValidateResponse response); 64 | 65 | /** 66 | * 读取sock5建立连接请求 67 | * @param buffer 68 | * @return 69 | */ 70 | struct Sock5BuildRequest Sock5BuildRequest_read(Byte *buffer); 71 | 72 | /** 73 | * 获取Sock5BuildResponse的总长度 74 | * @param response 75 | * @return 76 | */ 77 | size_t Sock5BuildResponse_getLength(struct Sock5BuildResponse response); 78 | 79 | /** 80 | * 将sock5建立连接请求转换为字符串 81 | * @param response 82 | * @return 83 | */ 84 | char* Sock5BuildResponse_toString(struct Sock5BuildResponse response); 85 | 86 | #endif //MZZ_BRIDGE_C_SOCK5_H 87 | --------------------------------------------------------------------------------