mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-30 22:13:49 +00:00
add trasparent proxy support
This commit is contained in:
+18
-19
@@ -99,18 +99,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *buf = remote->buf;
|
||||
int *buf_len = &remote->buf_len;
|
||||
if (server->stage != 5) {
|
||||
buf = server->buf;
|
||||
buf_len = &server->buf_len;
|
||||
}
|
||||
|
||||
ssize_t r = recv(server->fd, buf, BUF_SIZE, 0);
|
||||
ssize_t r = recv(server->fd, remote->buf, BUF_SIZE, 0);
|
||||
|
||||
if (r == 0) {
|
||||
// connection closed
|
||||
*buf_len = 0;
|
||||
remote->buf_len = 0;
|
||||
close_and_free_server(EV_A_ server);
|
||||
if (remote != NULL) {
|
||||
ev_io_start(EV_A_ &remote->send_ctx->io);
|
||||
@@ -162,7 +155,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
server->stage = 1;
|
||||
return;
|
||||
} else if (server->stage == 1) {
|
||||
struct socks5_request *request = (struct socks5_request *)server->buf;
|
||||
struct socks5_request *request = (struct socks5_request *)remote->buf;
|
||||
|
||||
if (request->cmd != 1) {
|
||||
LOGE("unsupported cmd: %d", request->cmd);
|
||||
@@ -186,24 +179,24 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
if (request->atyp == 1) {
|
||||
// IP V4
|
||||
size_t in_addr_len = sizeof(struct in_addr);
|
||||
memcpy(addr_to_send + addr_len, server->buf + 4, in_addr_len + 2);
|
||||
memcpy(addr_to_send + addr_len, remote->buf + 4, in_addr_len + 2);
|
||||
addr_len += in_addr_len + 2;
|
||||
|
||||
} else if (request->atyp == 3) {
|
||||
// Domain name
|
||||
uint8_t name_len = *(uint8_t *)(server->buf + 4);
|
||||
uint8_t name_len = *(uint8_t *)(remote->buf + 4);
|
||||
addr_to_send[addr_len++] = name_len;
|
||||
memcpy(addr_to_send + addr_len, server->buf + 4 + 1, name_len);
|
||||
memcpy(addr_to_send + addr_len, remote->buf + 4 + 1, name_len);
|
||||
addr_len += name_len;
|
||||
|
||||
// get port
|
||||
addr_to_send[addr_len++] = *(uint8_t *)(server->buf + 4 + 1 + name_len);
|
||||
addr_to_send[addr_len++] = *(uint8_t *)(server->buf + 4 + 1 + name_len + 1);
|
||||
addr_to_send[addr_len++] = *(uint8_t *)(remote->buf + 4 + 1 + name_len);
|
||||
addr_to_send[addr_len++] = *(uint8_t *)(remote->buf + 4 + 1 + name_len + 1);
|
||||
|
||||
} else if (request->atyp == 4) {
|
||||
// IP V6
|
||||
size_t in6_addr_len = sizeof(struct in6_addr);
|
||||
memcpy(addr_to_send + addr_len, server->buf + 4, in6_addr_len + 2);
|
||||
memcpy(addr_to_send + addr_len, remote->buf + 4, in6_addr_len + 2);
|
||||
addr_len += in6_addr_len + 2;
|
||||
|
||||
} else {
|
||||
@@ -214,7 +207,13 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
}
|
||||
|
||||
encrypt_ctx(addr_to_send, addr_len, server->e_ctx);
|
||||
send(remote->fd, addr_to_send, addr_len, 0);
|
||||
int s = send(remote->fd, addr_to_send, addr_len, 0);
|
||||
if (s < addr_len) {
|
||||
LOGE("failed to send remote addr.");
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fake reply
|
||||
struct socks5_response response;
|
||||
@@ -230,9 +229,9 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
memset(server->buf + 4, 0, sizeof(struct in_addr) + sizeof(uint16_t));
|
||||
|
||||
int reply_size = 4 + sizeof(struct in_addr) + sizeof(uint16_t);
|
||||
int s = send(server->fd, server->buf, reply_size, 0);
|
||||
s = send(server->fd, server->buf, reply_size, 0);
|
||||
if (s < reply_size) {
|
||||
LOGE("header not complete sent");
|
||||
LOGE("failed to send fake reply.");
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user