add trasparent proxy support

This commit is contained in:
Max Lv
2013-04-05 10:08:28 +08:00
parent cdcf527c77
commit d35c771fe2
7 changed files with 795 additions and 31 deletions
+18 -19
View File
@@ -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;