Skip to content

Commit

Permalink
add socks4 support
Browse files Browse the repository at this point in the history
  • Loading branch information
zhengyao-lin committed Nov 7, 2018
1 parent b12323b commit 04c5cfe
Show file tree
Hide file tree
Showing 31 changed files with 841 additions and 504 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[inbound]
proto = "socks5"
proto = "socks"
local = "0.0.0.0"
port = "3133"

Expand Down
9 changes: 9 additions & 0 deletions app/config/socks-socks4.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[inbound]
proto = "socks"
local = "0.0.0.0"
port = "3132"

[outbound]
proto = "socks5"
proxy = "127.0.0.1"
port = "3133"
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[inbound]
proto = "socks5"
proto = "socks"
local = "0.0.0.0"
port = "3133"

Expand Down
12 changes: 6 additions & 6 deletions app/test/socks5/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

#include "pub/type.h"

#include "proto/socks5/outbound.h"
#include "proto/socks5/socks5.h"
#include "proto/socks5/tcp.h"
#include "proto/socks/outbound.h"
#include "proto/socks/socks5.h"
#include "proto/socks/tcp.h"
#include "proto/relay/tcp.h"

int main()
{
target_id_t *proxy;
socks5_tcp_socket_t *sock;
socks_tcp_socket_t *sock;

byte_t data[] =
"GET / HTTP/1.1\r\n"
Expand All @@ -23,9 +23,9 @@ int main()

proxy = target_id_new_ipv4((byte_t []) { 127, 0, 0, 1 }, 3133);

sock = socks5_tcp_socket_new();
sock = socks_tcp_socket_new(SOCKS_VERSION_5);

socks5_tcp_socket_set_proxy(sock, proxy);
socks_tcp_socket_set_proxy(sock, proxy);

while (tcp_socket_connect(sock, "www.google.com", "80")) {
sleep(1);
Expand Down
10 changes: 5 additions & 5 deletions app/test/socks5/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

#include "pub/type.h"

#include "proto/socks5/inbound.h"
#include "proto/socks5/socks5.h"
#include "proto/socks5/tcp.h"
#include "proto/socks/inbound.h"
#include "proto/socks/socks5.h"
#include "proto/socks/tcp.h"

#include "proto/native/outbound.h"

Expand All @@ -16,15 +16,15 @@ int main()
signal(SIGPIPE, SIG_IGN);

target_id_t *local;
socks5_tcp_inbound_t *inbound;
socks_tcp_inbound_t *inbound;
native_tcp_outbound_t *outbound;

tcp_relay_config_t *relay_conf;

local = target_id_new_ipv4((byte_t[]) { 0, 0, 0, 0 }, 3133);

relay_conf = tcp_relay_config_new_default();
inbound = socks5_tcp_inbound_new(local);
inbound = socks_tcp_inbound_new(local);
outbound = native_tcp_outbound_new();

tcp_relay(relay_conf, (tcp_inbound_t *)inbound, (tcp_outbound_t *)outbound);
Expand Down
2 changes: 1 addition & 1 deletion app/vhook/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "pub/type.h"
#include "pub/socket.h"

#include "proto/socks5/tcp.h"
#include "proto/socks/tcp.h"

#include "hook.h"

Expand Down
11 changes: 5 additions & 6 deletions app/vhook/hook.def
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ HOOK(connect, fd_t, (fd_t fd, const struct sockaddr *addr, socklen_t addrlen), {
uint32_t ip;
uint16_t port;

socks5_tcp_socket_t *sock;
socks_tcp_socket_t *sock;

target_id_t *target;

Expand All @@ -28,9 +28,9 @@ HOOK(connect, fd_t, (fd_t fd, const struct sockaddr *addr, socklen_t addrlen), {

// proxy = target_id_new_ipv4((byte_t []) { 127, 0, 0, 1 }, 3133);
target = target_id_new_ipv4((byte_t *)&ip, port);
sock = socks5_tcp_socket_new();
sock = socks_tcp_socket_new(SOCKS_VERSION_ANY);

socks5_tcp_socket_set_proxy(sock, target_proxy);
socks_tcp_socket_set_proxy(sock, target_proxy);

if (tcp_socket_connect_target(sock, target)) {
perror("failed to connect to proxy");
Expand All @@ -45,16 +45,15 @@ HOOK(connect, fd_t, (fd_t fd, const struct sockaddr *addr, socklen_t addrlen), {
return -1;
}

fprintf(stderr, "connected ");
print_target(target);
print_target("connected", target);

proxy_on = true;

target_id_free(target);

// substitute the original fd

fake_fd = socks5_to_socket(sock);
fake_fd = socks_to_socket(sock);

flags = fcntl(fd, F_GETFL, 0);
fake_flags = fcntl(fake_fd, F_GETFL, 0);
Expand Down
34 changes: 26 additions & 8 deletions app/vmecs/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
#include "proto/vmess/inbound.h"
#include "proto/vmess/outbound.h"

#include "proto/socks5/inbound.h"
#include "proto/socks5/outbound.h"
#include "proto/socks/inbound.h"
#include "proto/socks/outbound.h"
#include "proto/socks/tcp.h"

#include "proto/native/outbound.h"

Expand Down Expand Up @@ -229,30 +230,45 @@ tcp_outbound_t *vmess_outbound_builder(toml_object_t *config)
return (tcp_outbound_t *)outbound;
}

tcp_inbound_t *socks5_inbound_builder(toml_object_t *config)
tcp_inbound_t *socks_inbound_builder(toml_object_t *config)
{
target_id_t *local;
socks5_tcp_inbound_t *inbound;
socks_tcp_inbound_t *inbound;

local = load_inbound_param(config);
if (!local) return NULL;

inbound = socks5_tcp_inbound_new(local);
inbound = socks_tcp_inbound_new(local);

target_id_free(local);

return (tcp_inbound_t *)inbound;
}

tcp_outbound_t *socks4_outbound_builder(toml_object_t *config)
{
target_id_t *proxy;
socks_tcp_outbound_t *outbound;

proxy = load_outbound_param(config);
if (!proxy) return NULL;

outbound = socks_tcp_outbound_new(proxy, SOCKS_VERSION_4);

target_id_free(proxy);

return (tcp_outbound_t *)outbound;
}

tcp_outbound_t *socks5_outbound_builder(toml_object_t *config)
{
target_id_t *proxy;
socks5_tcp_outbound_t *outbound;
socks_tcp_outbound_t *outbound;

proxy = load_outbound_param(config);
if (!proxy) return NULL;

outbound = socks5_tcp_outbound_new(proxy);
outbound = socks_tcp_outbound_new(proxy, SOCKS_VERSION_5);

target_id_free(proxy);

Expand All @@ -270,7 +286,9 @@ struct {
outbound_builder_t out_build;
} proto_map[] = {
{ "vmess", vmess_inbound_builder, vmess_outbound_builder },
{ "socks5", socks5_inbound_builder, socks5_outbound_builder },
{ "socks", socks_inbound_builder, NULL },
{ "socks4", socks_inbound_builder, socks4_outbound_builder },
{ "socks5", socks_inbound_builder, socks5_outbound_builder },
{ "native", NULL, native_outbound_builder }
};

Expand Down
2 changes: 1 addition & 1 deletion proto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# proto

add_lib_batch(vmecs-proto STATIC "*.c" "vmess/*.c" "native/*.c" "relay/*.c" "socks5/*.c")
add_lib_batch(vmecs-proto STATIC "*.c" "vmess/*.c" "native/*.c" "relay/*.c" "socks/*.c")

target_link_libraries(vmecs-proto vmecs-crypto vmecs-pub)
11 changes: 11 additions & 0 deletions proto/buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ _rbuffer_expand(rbuffer_t *buf)
buf->buf = realloc(buf->buf, buf->size);
}

void
rbuffer_push(rbuffer_t *buf, const byte_t *data, size_t size)
{
while (buf->w_idx + size >= buf->size) {
_rbuffer_expand(buf);
}

memcpy(buf->buf + buf->w_idx, data, size);
buf->w_idx += size;
}

rbuffer_result_t
rbuffer_read(rbuffer_t *buf, fd_t fd, decoder_t decoder, void *context, void *result)
{
Expand Down
3 changes: 3 additions & 0 deletions proto/buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ rbuffer_new(size_t init);
rbuffer_result_t
rbuffer_read(rbuffer_t *buf, fd_t fd, decoder_t decoder, void *context, void *result);

void
rbuffer_push(rbuffer_t *buf, const byte_t *data, size_t size);

void
rbuffer_free(rbuffer_t *buf);

Expand Down
4 changes: 2 additions & 2 deletions proto/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ target_id_t *_target_id_new(byte_t type, uint16_t port)
return id;
}

target_id_t *target_id_new_ipv4(uint8_t addr[4], uint16_t port)
target_id_t *target_id_new_ipv4(const uint8_t addr[4], uint16_t port)
{
target_id_t *id = _target_id_new(ADDR_TYPE_IPV4, port);
memcpy(id->addr.ipv4, addr, sizeof(id->addr.ipv4));
return id;
}

target_id_t *target_id_new_ipv6(uint8_t addr[16], uint16_t port)
target_id_t *target_id_new_ipv6(const uint8_t addr[16], uint16_t port)
{
target_id_t *id = _target_id_new(ADDR_TYPE_IPV6, port);
memcpy(id->addr.ipv6, addr, sizeof(id->addr.ipv6));
Expand Down
8 changes: 4 additions & 4 deletions proto/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ typedef struct {
byte_t addr_type;
} target_id_t;

target_id_t *target_id_new_ipv4(uint8_t addr[4], uint16_t port);
target_id_t *target_id_new_ipv6(uint8_t addr[16], uint16_t port);
target_id_t *target_id_new_ipv4(const uint8_t addr[4], uint16_t port);
target_id_t *target_id_new_ipv6(const uint8_t addr[16], uint16_t port);
target_id_t *target_id_new_domain(const char *domain, uint64_t port);

target_id_t *target_id_parse(const char *node, const char *service);
Expand Down Expand Up @@ -81,11 +81,11 @@ target_id_port(const target_id_t *target, char buf[TARGET_ID_MAX_PORT])
}

INLINE void
print_target(const target_id_t *target)
print_target(const char *prompt, const target_id_t *target)
{
char buf[TARGET_ID_MAX_DOMAIN + 1];
target_id_node(target, buf);
printf("%s:%d\n", buf, target->port);
printf("%s: %s:%d\n", prompt, buf, target->port);
}

typedef struct {
Expand Down
4 changes: 2 additions & 2 deletions proto/relay/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "tcp.h"

#define DEFAULT_BACKLOG 1024
#define DEFAULT_BACKLOG 128
#define DEFAULT_BUFFER (8 * 1024)

tcp_relay_config_t *
Expand Down Expand Up @@ -135,7 +135,7 @@ _tcp_relay_handler(void *arg)
int retry = 0;

target = tcp_socket_target(job->in_sock);
print_target(target);
print_target("request", target);

while (!(job->out_sock = tcp_outbound_client(job->outbound, target))) {
perror("connect");
Expand Down
45 changes: 45 additions & 0 deletions proto/socks/inbound.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <time.h>

#include "pub/socket.h"

#include "proto/common.h"

#include "socks5.h"
#include "inbound.h"
#include "tcp.h"

static tcp_socket_t *
_socks_tcp_inbound_server(tcp_inbound_t *_inbound)
{
socks_tcp_inbound_t *inbound = (socks_tcp_inbound_t *)_inbound;
tcp_socket_t *sock = (tcp_socket_t *)socks_tcp_socket_new(SOCKS_VERSION_ANY);

while (tcp_socket_bind_target(sock, inbound->local))
sleep(1);

return sock;
}

static void
_socks_tcp_inbound_free(tcp_inbound_t *_inbound)
{
socks_tcp_inbound_t *inbound = (socks_tcp_inbound_t *)_inbound;

if (inbound) {
target_id_free(inbound->local);
free(inbound);
}
}

socks_tcp_inbound_t *
socks_tcp_inbound_new(target_id_t *local)
{
socks_tcp_inbound_t *ret = malloc(sizeof(*ret));
ASSERT(ret, "out of mem");

ret->server_func = _socks_tcp_inbound_server;
ret->free_func = _socks_tcp_inbound_free;
ret->local = target_id_copy(local);

return ret;
}
10 changes: 5 additions & 5 deletions proto/socks5/inbound.h → proto/socks/inbound.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef _PROTO_SOCKS5_INBOUND_H_
#define _PROTO_SOCKS5_INBOUND_H_
#ifndef _PROTO_SOCKS_INBOUND_H_
#define _PROTO_SOCKS_INBOUND_H_

#include "pub/type.h"

Expand All @@ -10,9 +10,9 @@
typedef struct {
TCP_INBOUND_HEADER
target_id_t *local; // local bind address
} socks5_tcp_inbound_t;
} socks_tcp_inbound_t;

socks5_tcp_inbound_t *
socks5_tcp_inbound_new(target_id_t *local);
socks_tcp_inbound_t *
socks_tcp_inbound_new(target_id_t *local);

#endif
Loading

0 comments on commit 04c5cfe

Please sign in to comment.