Skip to content

Commit

Permalink
adjust code style
Browse files Browse the repository at this point in the history
  • Loading branch information
Ken committed Jun 16, 2015
1 parent c371569 commit 2ba4c11
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 22 deletions.
58 changes: 43 additions & 15 deletions src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,19 @@ verify_request(char *buf, ssize_t buflen) {
struct socks5_request *req = (struct socks5_request *)buf;

if (req->atyp == S5_ATYP_IPV4) {
if ((req->cmd == S5_CMD_CONNECT) && (strncmp(buf + 4, "\x0\x0\x0\x0", 4) == 0)) {
if ((req->cmd == S5_CMD_CONNECT)
&& (strncmp(buf + 4, "\x0\x0\x0\x0", 4) == 0)) {
return 0;
}
len = sizeof(struct socks5_request) + sizeof(struct in_addr) + 2;

} else if (req->atyp == S5_ATYP_HOST) {
uint8_t name_len = *(uint8_t *)(req->addr);
len = sizeof(struct socks5_request) + 1 + name_len + 2;

} else if (req->atyp == S5_ATYP_IPV6) {
len = sizeof(struct socks5_request) + sizeof(struct in6_addr) + 2;

} else {
len = 0;
}
Expand All @@ -80,24 +84,28 @@ analyse_request_addr(struct socks5_request *req, struct sockaddr *dest, char *de
struct sockaddr_in6 addr6;
} addr;
int addrlen;
uint16_t portlen = 2; // network byte order port number, 2 bytes
/* network byte order port number, 2 bytes */
uint16_t portlen = 2;

memset(&addr, 0, sizeof(addr));

if (req->atyp == S5_ATYP_IPV4) {
size_t in_addr_len = sizeof(struct in_addr); // 4 bytes for IPv4 address
/* 4 bytes for IPv4 address */
size_t in_addr_len = sizeof(struct in_addr);
addr.addr4.sin_family = AF_INET;
memcpy(&addr.addr4.sin_addr, req->addr, in_addr_len);
memcpy(&addr.addr4.sin_port, req->addr + in_addr_len, portlen);

uv_inet_ntop(AF_INET, (const void *)(req->addr), dest_buf, INET_ADDRSTRLEN);
uv_inet_ntop(AF_INET, (const void *)(req->addr), dest_buf,
INET_ADDRSTRLEN);
uint16_t port = read_size((uint8_t*)(req->addr + in_addr_len));
sprintf(dest_buf, "%s:%u", dest_buf, port);

addrlen = 4;

} else if (req->atyp == S5_ATYP_HOST) {
uint8_t namelen = *(uint8_t *)(req->addr); // 1 byte of name length
/* 1 byte of name length */
uint8_t namelen = *(uint8_t *)(req->addr);
if (namelen > 0xFF) {
return 0;
}
Expand All @@ -112,11 +120,13 @@ analyse_request_addr(struct socks5_request *req, struct sockaddr *dest, char *de
addrlen = 1 + namelen;

} else if (req->atyp == S5_ATYP_IPV6) {
size_t in6_addr_len = sizeof(struct in6_addr); // 16 bytes for IPv6 address
/* 16 bytes for IPv6 address */
size_t in6_addr_len = sizeof(struct in6_addr);
memcpy(&addr.addr6.sin6_addr, req->addr, in6_addr_len);
memcpy(&addr.addr6.sin6_port, req->addr + in6_addr_len, portlen);

uv_inet_ntop(AF_INET6, (const void *)(req->addr), dest_buf, INET_ADDRSTRLEN);
uv_inet_ntop(AF_INET6, (const void *)(req->addr), dest_buf,
INET_ADDRSTRLEN);
uint16_t port = read_size((uint8_t*)(req->addr + in6_addr_len));
sprintf(dest_buf, "%s:%u", dest_buf, port);

Expand All @@ -136,7 +146,8 @@ send_to_client(struct client_context *client, char *buf, int buflen) {
client->write_req.data = client;
uv_write_t *write_req = malloc(sizeof(*write_req));
write_req->data = client;
int rc = uv_write(write_req, &client->handle.stream, &reply, 1, client_send_cb);
int rc = uv_write(write_req, &client->handle.stream, &reply, 1,
client_send_cb);
if (rc) {
logger_log(LOG_ERR, "write to client error: %s", uv_strerror(rc));
}
Expand Down Expand Up @@ -166,17 +177,23 @@ request_ack(struct client_context *client, enum s5_rep rep) {
buf[2] = 0x00; // RSV

memset(&addr, 0, sizeof(addr));

if (client->cmd == S5_CMD_UDP_ASSOCIATE) {
uv_tcp_getsockname(&client->handle.tcp, (struct sockaddr *) &addr, &addrlen);
uv_tcp_getsockname(&client->handle.tcp, (struct sockaddr *) &addr,
&addrlen);

} else {
uv_tcp_getsockname(&remote->handle.tcp, (struct sockaddr *) &addr, &addrlen);
uv_tcp_getsockname(&remote->handle.tcp, (struct sockaddr *) &addr,
&addrlen);
}

if (addrlen == sizeof(struct sockaddr_in6)) {
buf[3] = 0x04; /* atyp - IPv6. */
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)&addr;
memcpy(buf + 4, &addr6->sin6_addr, 16); /* BND.ADDR */
memcpy(buf + 20, &addr6->sin6_port, 2); /* BND.PORT */
buflen = 22;

} else {
buf[3] = 0x01; /* atyp - IPv4. */
const struct sockaddr_in *addr4 = (const struct sockaddr_in *)&addr;
Expand All @@ -191,6 +208,7 @@ request_ack(struct client_context *client, enum s5_rep rep) {
} else {
client->stage = S5_STAGE_UDP_RELAY;
}

} else {
client->stage = S5_STAGE_TERMINATE;
}
Expand Down Expand Up @@ -221,7 +239,8 @@ request_start(struct client_context *client, char *buf, ssize_t buflen) {

client->cmd = request->cmd;

if (request->cmd != S5_CMD_CONNECT && request->cmd != S5_CMD_UDP_ASSOCIATE) {
if (request->cmd != S5_CMD_CONNECT &&
request->cmd != S5_CMD_UDP_ASSOCIATE) {
logger_log(LOG_ERR, "unsupported cmd: 0x%02x", request->cmd);
request_ack(client, S5_REP_CMD_NOT_SUPPORTED);
return;
Expand All @@ -233,7 +252,8 @@ request_start(struct client_context *client, char *buf, ssize_t buflen) {
}

char host[256] = {0};
int addrlen = analyse_request_addr(request, &remote->addr, client->target_addr, host);
int addrlen = analyse_request_addr(request, &remote->addr,
client->target_addr, host);
if (addrlen < 1) {
logger_log(LOG_ERR, "unsupported address type: 0x%02x", request->atyp);
request_ack(client, S5_REP_ADDRESS_TYPE_NOT_SUPPORTED);
Expand Down Expand Up @@ -274,6 +294,7 @@ client_send_cb(uv_write_t *req, int status) {
if (client->stage == S5_STAGE_FORWARD) {
reset_timer(remote);
receive_from_remote(remote);

} else if (client->stage == S5_STAGE_TERMINATE) {
close_client(client);
close_remote(remote);
Expand All @@ -282,7 +303,8 @@ client_send_cb(uv_write_t *req, int status) {
} else {
char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
uint16_t port = ip_name(&client->addr, addrbuf, sizeof addrbuf);
logger_log(LOG_ERR, "%s:%d <- %s failed: %s", addrbuf, port, client->target_addr, uv_strerror(status));
logger_log(LOG_ERR, "%s:%d <- %s failed: %s", addrbuf, port,
client->target_addr, uv_strerror(status));
}

free(req);
Expand All @@ -295,6 +317,7 @@ client_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {

if (nread > 0) {
switch (client->stage) {

case S5_STAGE_HANDSHAKE:
if (verify_methods(buf->base, nread)) {
handshake(client);
Expand All @@ -304,6 +327,7 @@ client_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
close_remote(remote);
}
break;

case S5_STAGE_REQUEST:
if (verify_request(buf->base, nread)) {
request_start(client, buf->base, nread);
Expand All @@ -313,10 +337,12 @@ client_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
close_remote(remote);
}
break;

case S5_STAGE_FORWARD:
uv_read_stop(&client->handle.stream);
forward_to_remote(remote, buf->base, nread);
break;

default:
break;
}
Expand All @@ -325,7 +351,8 @@ client_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
if (nread != UV_EOF) {
char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
uint16_t port = ip_name(&client->addr, addrbuf, sizeof addrbuf);
logger_log(LOG_ERR, "receive from %s:%d failed: %s", addrbuf, port, uv_strerror(nread));
logger_log(LOG_ERR, "receive from %s:%d failed: %s", addrbuf, port,
uv_strerror(nread));
}
close_client(client);
close_remote(remote);
Expand All @@ -350,7 +377,8 @@ client_accept_cb(uv_stream_t *server, int status) {
uv_tcp_getpeername(&client->handle.tcp, &client->addr, &namelen);
reset_timer(remote);
client->handle.stream.data = client;
rc = uv_read_start(&client->handle.stream, client_alloc_cb, client_recv_cb);
rc = uv_read_start(&client->handle.stream, client_alloc_cb,
client_recv_cb);
} else {
logger_log(LOG_ERR, "accept error: %s", uv_strerror(rc));
close_client(client);
Expand Down
12 changes: 12 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,41 @@ parse_opts(int argc, char *argv[]) {
int opt = 0, longindex = 0;

while ((opt = getopt_long(argc, argv, _optString, _lopts, &longindex)) != -1) {

switch (opt) {

case 'v':
printf("socksd version: %s \n", SOCKSD_VER);
exit(0);
break;

case 'h':
case '?':
print_usage(argv[0]);
break;

case 'l':
local_addrbuf = optarg;
break;

case 'c':
concurrency = strtol(optarg, NULL, 10);
break;

case 'd':
if (nameserver_num < MAX_DNS_NUM) {
nameservers[nameserver_num++] = optarg;
}
break;

case 'p':
pidfile = optarg;
break;

case 'n':
daemon_mode = 0;
break;

case 's':
xsignal = optarg;
if (strcmp(xsignal, "stop") == 0
Expand All @@ -102,12 +111,15 @@ parse_opts(int argc, char *argv[]) {
fprintf(stderr, "invalid option: -s %s\n", xsignal);
print_usage(argv[0]);
break;

case 't':
idle_timeout = strtol(optarg, NULL, 10);
break;

case 'V':
verbose = 1;
break;

default:
print_usage(argv[0]);
break;
Expand Down
23 changes: 16 additions & 7 deletions src/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ remote_timer_expire(uv_timer_t *handle) {
} else {
char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
uint16_t port = ip_name(&client->addr, addrbuf, sizeof addrbuf);
logger_log(LOG_WARNING, "%s:%d <-> %s connection timeout", addrbuf, port, client->target_addr);
logger_log(LOG_WARNING, "%s:%d <-> %s connection timeout", addrbuf,
port, client->target_addr);
}
}
request_ack(remote->client, S5_REP_TTL_EXPIRED);
Expand Down Expand Up @@ -105,9 +106,11 @@ remote_connect_cb(uv_connect_t *req, int status) {
request_ack(client, S5_REP_SUCCESSED);
remote->handle.stream.data = remote;
uv_read_start(&remote->handle.stream, remote_alloc_cb, remote_recv_cb);

} else {
if (status != UV_ECANCELED) {
logger_log(LOG_ERR, "connect to %s failed: %s", client->target_addr, uv_strerror(status));
logger_log(LOG_ERR, "connect to %s failed: %s", client->target_addr,
uv_strerror(status));
request_ack(client, S5_REP_HOST_UNREACHABLE);
}
}
Expand All @@ -123,16 +126,19 @@ void
forward_to_remote(struct remote_context *remote, char *buf, int buflen) {
uv_buf_t request = uv_buf_init(buf, buflen);
remote->write_req.data = remote;
uv_write(&remote->write_req, &remote->handle.stream, &request, 1, remote_send_cb);
uv_write(&remote->write_req, &remote->handle.stream, &request, 1,
remote_send_cb);
}

void
connect_to_remote(struct remote_context *remote) {
remote->stage = S5_STAGE_CONNECT;
remote->connect_req.data = remote;
int rc = uv_tcp_connect(&remote->connect_req, &remote->handle.tcp, &remote->addr, remote_connect_cb);
int rc = uv_tcp_connect(&remote->connect_req, &remote->handle.tcp,
&remote->addr, remote_connect_cb);
if (rc) {
logger_log(LOG_ERR, "connect to %s error: %s", remote->client->target_addr, uv_strerror(rc));
logger_log(LOG_ERR, "connect to %s error: %s",
remote->client->target_addr, uv_strerror(rc));
request_ack(remote->client, S5_REP_NETWORK_UNREACHABLE);
}
}
Expand Down Expand Up @@ -184,7 +190,8 @@ remote_send_cb(uv_write_t *req, int status) {
if (verbose) {
char addrbuf[INET6_ADDRSTRLEN + 1] = {0};
uint16_t port = ip_name(&client->addr, addrbuf, sizeof addrbuf);
logger_log(LOG_ERR, "%s:%d -> failed: %s", addrbuf, port, client->target_addr, uv_strerror(status));
logger_log(LOG_ERR, "%s:%d -> failed: %s", addrbuf, port,
client->target_addr, uv_strerror(status));
}
}
}
Expand All @@ -200,9 +207,11 @@ remote_recv_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
if (nread > 0) {
uv_read_stop(&remote->handle.stream);
forward_to_client(client, buf->base, nread);

} else if (nread < 0){
if (nread != UV_EOF && verbose) {
logger_log(LOG_ERR, "receive from %s failed: %s", client->target_addr, uv_strerror(nread));
logger_log(LOG_ERR, "receive from %s failed: %s",
client->target_addr, uv_strerror(nread));
}
close_client(client);
close_remote(remote);
Expand Down

0 comments on commit 2ba4c11

Please sign in to comment.