Finalize socks5
This commit is contained in:
parent
e3653112a6
commit
00e37ceb88
2 changed files with 118 additions and 35 deletions
144
src/socks5.c
144
src/socks5.c
|
@ -376,31 +376,32 @@ error:
|
|||
int on_socks5_server_recv_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
struct socks5_ctx* s5ctx = fdinfo->other;
|
||||
|
||||
// 1. We have read the whole buffer, change category
|
||||
if (s5ctx->ch_cursor > 2 && s5ctx->ch_cursor >= s5ctx->ch.nmethods + 2) {
|
||||
printf("[%s][socks5] read client handshake version: %d, nmethods: %d\n", current_human_datetime (), s5ctx->ch.ver, s5ctx->ch.nmethods);
|
||||
for (int i = 0; i < s5ctx->ch.nmethods; i++) {
|
||||
if (s5ctx->ch.methods[i] == METHOD_NOAUTH) {
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-send-handshake");
|
||||
return EVT_CORE_FD_EXHAUSTED; // Success, we are compatible with client, moving to next state
|
||||
}
|
||||
}
|
||||
// We failed to find a NOAUTH
|
||||
fprintf(stderr, "Unable to find a NOAUTH method in the list of available method\n");
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
// 1. We need to read more
|
||||
if (s5ctx->ch_cursor < 2 || s5ctx->ch_cursor < s5ctx->ch.nmethods + 2) {
|
||||
size_t to_read = 0;
|
||||
if (s5ctx->ch_cursor < 2) to_read = 2 - s5ctx->ch_cursor;
|
||||
else to_read = s5ctx->ch.nmethods - (s5ctx->ch_cursor - 2);
|
||||
ssize_t nread = recv(fdinfo->fd, ((void*)&s5ctx->ch) + s5ctx->ch_cursor, to_read, 0);
|
||||
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nread == -1) goto serv_handshake_err;
|
||||
s5ctx->ch_cursor += nread;
|
||||
return EVT_CORE_FD_UNFINISHED;
|
||||
}
|
||||
|
||||
// 2. We need to read more
|
||||
size_t to_read = 0;
|
||||
if (s5ctx->ch_cursor < 2) to_read = 2 - s5ctx->ch_cursor;
|
||||
else to_read = s5ctx->ch.nmethods - (s5ctx->ch_cursor - 2);
|
||||
ssize_t nread = recv(fdinfo->fd, ((void*)&s5ctx->ch) + s5ctx->ch_cursor, to_read, 0);
|
||||
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nread == -1) goto serv_handshake_err;
|
||||
s5ctx->ch_cursor += nread;
|
||||
printf("[%s][socks5] read client handshake version: %d, nmethods: %d\n", current_human_datetime (), s5ctx->ch.ver, s5ctx->ch.nmethods);
|
||||
for (int i = 0; i < s5ctx->ch.nmethods; i++) {
|
||||
if (s5ctx->ch.methods[i] == METHOD_NOAUTH) goto success;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unable to find a NOAUTH method in the list of available method\n");
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
|
||||
success:
|
||||
printf("[%s][socks5] received client handshake handshake\n", current_human_datetime ());
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-send-handshake");
|
||||
return EVT_CORE_FD_EXHAUSTED; // Success, we are compatible with client, moving to next state
|
||||
|
||||
return EVT_CORE_FD_UNFINISHED;
|
||||
serv_handshake_err:
|
||||
perror("[socks5] unable to read handshake from socket.");
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
|
||||
|
@ -410,19 +411,18 @@ serv_handshake_err:
|
|||
int on_socks5_server_send_handshake(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
struct socks5_ctx* s5ctx = fdinfo->other;
|
||||
|
||||
// 1. We have sent the whole buffer
|
||||
if (s5ctx->sh_cursor >= sizeof(s5ctx->sh)) {
|
||||
printf("[%s][socks5] sent server handshake\n", current_human_datetime ());
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-recv-client-req");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
if (s5ctx->sh_cursor < sizeof(s5ctx->sh)) {
|
||||
ssize_t nsent = send(fdinfo->fd, &s5ctx->sh, sizeof(s5ctx->sh) - s5ctx->sh_cursor, 0);
|
||||
if (nsent == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nsent == -1) goto send_hs_error;
|
||||
s5ctx->sh_cursor += nsent;
|
||||
return EVT_CORE_FD_UNFINISHED;
|
||||
}
|
||||
|
||||
ssize_t nsent = send(fdinfo->fd, &s5ctx->sh, sizeof(s5ctx->sh) - s5ctx->sh_cursor, 0);
|
||||
if (nsent == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nsent == -1) goto send_hs_error;
|
||||
s5ctx->sh_cursor += nsent;
|
||||
printf("[%s][socks5] sent server handshake\n", current_human_datetime ());
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-recv-client-req");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
|
||||
return EVT_CORE_FD_UNFINISHED;
|
||||
send_hs_error:
|
||||
perror("[socks5] unable to send handshake to socket.");
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
|
||||
|
@ -431,15 +431,89 @@ send_hs_error:
|
|||
|
||||
int on_socks5_server_recv_client_req(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
struct socks5_ctx* s5ctx = fdinfo->other;
|
||||
ssize_t nread = 0;
|
||||
size_t to_read = 0;
|
||||
|
||||
if (s5ctx->cr_cursor )
|
||||
size_t fixed_size = ((void*)&s5ctx->cr.dest_addr) - ((void*)&s5ctx->cr);
|
||||
if (s5ctx->cr_cursor < fixed_size) {
|
||||
to_read = fixed_size - s5ctx->cr_cursor;
|
||||
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr) + s5ctx->cr_cursor, to_read, 0);
|
||||
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nread == -1) goto recv_client_req_error;
|
||||
s5ctx->cr_cursor += nread;
|
||||
if (nread == to_read) s5ctx->cr_cursor = 0;
|
||||
else return EVT_CORE_FD_UNFINISHED;
|
||||
}
|
||||
|
||||
return EVT_CORE_FD_UNFINISHED;
|
||||
if (!s5ctx->cr_host_read && s5ctx->cr.atyp == ATYP_DOMAINNAME) {
|
||||
to_read = sizeof(s5ctx->cr.dest_addr.dns.len) + s5ctx->cr.dest_addr.dns.len - s5ctx->cr_cursor;
|
||||
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.dest_addr.dns) + s5ctx->cr_cursor, to_read, 0);
|
||||
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nread == -1) goto recv_client_req_error;
|
||||
s5ctx->cr_cursor += nread;
|
||||
if (to_read == nread) {
|
||||
s5ctx->cr_host_read = TRUE;
|
||||
s5ctx->cr_cursor = 0;
|
||||
} else return EVT_CORE_FD_UNFINISHED;
|
||||
} else if (!s5ctx->cr_host_read && s5ctx->cr.atyp == ATYP_IPV4) {
|
||||
to_read = sizeof(s5ctx->cr.dest_addr.ipv4) - s5ctx->cr_cursor;
|
||||
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.dest_addr.ipv4) + s5ctx->cr_cursor, to_read, 0);
|
||||
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nread == -1) goto recv_client_req_error;
|
||||
s5ctx->cr_cursor += nread;
|
||||
if (to_read == nread) {
|
||||
s5ctx->cr_host_read = TRUE;
|
||||
s5ctx->cr_cursor = 0;
|
||||
} else return EVT_CORE_FD_UNFINISHED;
|
||||
} else if (!s5ctx->cr_host_read && s5ctx->cr.atyp == ATYP_IPV6) {
|
||||
to_read = sizeof(s5ctx->cr.dest_addr.ipv6) - s5ctx->cr_cursor;
|
||||
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.dest_addr.ipv6) + s5ctx->cr_cursor, to_read, 0);
|
||||
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nread == -1) goto recv_client_req_error;
|
||||
s5ctx->cr_cursor += nread;
|
||||
if (to_read == nread) {
|
||||
s5ctx->cr_host_read = TRUE;
|
||||
s5ctx->cr_cursor = 0;
|
||||
} else return EVT_CORE_FD_UNFINISHED;
|
||||
} else if (!s5ctx->cr_host_read) goto recv_client_req_error;
|
||||
|
||||
to_read = ((void*)&s5ctx->cr+1) - ((void*)&s5ctx->cr.port) - s5ctx->cr_cursor;
|
||||
nread = recv(fdinfo->fd, ((void*)&s5ctx->cr.port) + s5ctx->cr_cursor, to_read, 0);
|
||||
if (nread == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nread == -1) goto recv_client_req_error;
|
||||
s5ctx->cr_cursor += nread;
|
||||
if (to_read != nread) return EVT_CORE_FD_UNFINISHED;
|
||||
|
||||
printf("[%s][socks5] received client request atyp=%s: ", current_human_datetime (), atyp_str[s5ctx->cr.atyp]);
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-send-server-reply");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
|
||||
recv_client_req_error:
|
||||
perror("[socks5] unable to receive client request from socket.");
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
}
|
||||
|
||||
int on_socks5_server_send_server_reply(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo) {
|
||||
struct socks5_ctx* s5ctx = fdinfo->other;
|
||||
ssize_t nsent = 0;
|
||||
size_t to_send = s5ctx->sr_size - s5ctx->sr_cursor;
|
||||
|
||||
return EVT_CORE_FD_UNFINISHED;
|
||||
nsent = send(fdinfo->fd, s5ctx->sr_buffer + s5ctx->sr_cursor, to_send, 0);
|
||||
if (nsent == -1 && errno == EAGAIN) return EVT_CORE_FD_EXHAUSTED;
|
||||
if (nsent == -1) goto send_server_rep_error;
|
||||
s5ctx->sr_cursor += nsent;
|
||||
|
||||
if (nsent != to_send) return EVT_CORE_FD_UNFINISHED;
|
||||
|
||||
printf("[%s][socks5] sent server reply\n", current_human_datetime ());
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-sucess");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
|
||||
send_server_rep_error:
|
||||
perror("[socks5] unable to send server reply to socket.");
|
||||
evt_core_mv_fd2 (ctx, fdinfo, "socks5-server-failed");
|
||||
return EVT_CORE_FD_EXHAUSTED;
|
||||
}
|
||||
|
||||
void socks5_server_init(struct evt_core_ctx* ctx) {
|
||||
|
|
|
@ -29,6 +29,14 @@ enum atyp {
|
|||
ATYP_IPV6 = 0x04
|
||||
};
|
||||
|
||||
static char *atyp_str[] = {
|
||||
"INVALID",
|
||||
"IPV4",
|
||||
"INVALID"
|
||||
"DOMAIN NAME",
|
||||
"IPV6"
|
||||
};
|
||||
|
||||
enum ver {
|
||||
VER_SOCKS5 = 0x05
|
||||
};
|
||||
|
@ -129,6 +137,7 @@ struct socks5_ctx {
|
|||
size_t cr_size;
|
||||
size_t sr_size;
|
||||
uint8_t sr_host_read;
|
||||
uint8_t cr_host_read;
|
||||
};
|
||||
|
||||
void socks5_init(struct evt_core_ctx* ctx);
|
||||
|
|
Loading…
Reference in a new issue