mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-25 10:13:44 +00:00
Simplify the handshake part
This commit is contained in:
+29
-68
@@ -182,17 +182,6 @@ create_and_bind(const char *addr, const char *port)
|
||||
return listen_sock;
|
||||
}
|
||||
|
||||
static void
|
||||
delayed_connect_cb(EV_P_ ev_timer *watcher, int revents)
|
||||
{
|
||||
server_t *server = cork_container_of(watcher, server_t,
|
||||
delayed_connect_watcher);
|
||||
remote_t *remote = server->remote;
|
||||
|
||||
if (server->abuf != NULL)
|
||||
remote_send_cb(EV_A_ & remote->send_ctx->io, revents);
|
||||
}
|
||||
|
||||
static void
|
||||
server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
{
|
||||
@@ -236,14 +225,6 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
return;
|
||||
}
|
||||
|
||||
if (server->abuf != NULL) {
|
||||
ev_timer_stop(EV_A_ & server->delayed_connect_watcher);
|
||||
bprepend(remote->buf, server->abuf, BUF_SIZE);
|
||||
bfree(server->abuf);
|
||||
ss_free(server->abuf);
|
||||
server->abuf = NULL;
|
||||
}
|
||||
|
||||
int s = send(remote->fd, remote->buf->data, remote->buf->len, 0);
|
||||
|
||||
if (s == -1) {
|
||||
@@ -413,12 +394,10 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
|
||||
int r = getpeername(remote->fd, (struct sockaddr *)&addr, &len);
|
||||
if (r == 0) {
|
||||
remote_send_ctx->connected = 1;
|
||||
ev_io_stop(EV_A_ & remote_send_ctx->io);
|
||||
ev_timer_stop(EV_A_ & remote_send_ctx->watcher);
|
||||
|
||||
server->abuf = (buffer_t *)ss_malloc(sizeof(buffer_t));
|
||||
buffer_t *abuf = server->abuf;
|
||||
balloc(abuf, BUF_SIZE);
|
||||
assert(remote->buf->len == 0);
|
||||
buffer_t *abuf = remote->buf;
|
||||
|
||||
ss_addr_t *sa = &server->destaddr;
|
||||
struct cork_ip ip;
|
||||
@@ -467,18 +446,14 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
|
||||
int err = crypto->encrypt(abuf, server->e_ctx, BUF_SIZE);
|
||||
|
||||
if (err) {
|
||||
bfree(abuf);
|
||||
LOGE("invalid password or cipher");
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
|
||||
ev_timer_start(EV_A_ & server->delayed_connect_watcher);
|
||||
ev_io_start(EV_A_ & remote->recv_ctx->io);
|
||||
ev_io_start(EV_A_ & server->recv_ctx->io);
|
||||
|
||||
return;
|
||||
} else {
|
||||
ERROR("getpeername");
|
||||
// not connected
|
||||
@@ -486,43 +461,36 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (remote->buf->len == 0) {
|
||||
// close and free
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
} else {
|
||||
if (remote->buf->len == 0 && server->abuf->len == 0) {
|
||||
// close and free
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
// has data to send
|
||||
ssize_t s = send(remote->fd, remote->buf->data + remote->buf->idx,
|
||||
remote->buf->len, 0);
|
||||
if (s == -1) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
ERROR("send");
|
||||
// close and free
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
}
|
||||
return;
|
||||
} else if (s < remote->buf->len) {
|
||||
// partly sent, move memory, wait for the next time to send
|
||||
remote->buf->len -= s;
|
||||
remote->buf->idx += s;
|
||||
return;
|
||||
} else {
|
||||
// has data to send
|
||||
if (server->abuf != NULL) {
|
||||
assert(remote->buf->len == 0);
|
||||
bprepend(remote->buf, server->abuf, BUF_SIZE);
|
||||
bfree(server->abuf);
|
||||
ss_free(server->abuf);
|
||||
server->abuf = NULL;
|
||||
}
|
||||
ssize_t s = send(remote->fd, remote->buf->data + remote->buf->idx,
|
||||
remote->buf->len, 0);
|
||||
if (s == -1) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
ERROR("send");
|
||||
// close and free
|
||||
close_and_free_remote(EV_A_ remote);
|
||||
close_and_free_server(EV_A_ server);
|
||||
}
|
||||
return;
|
||||
} else if (s < remote->buf->len) {
|
||||
// partly sent, move memory, wait for the next time to send
|
||||
remote->buf->len -= s;
|
||||
remote->buf->idx += s;
|
||||
return;
|
||||
} else {
|
||||
// all sent out, wait for reading
|
||||
remote->buf->len = 0;
|
||||
remote->buf->idx = 0;
|
||||
ev_io_stop(EV_A_ & remote_send_ctx->io);
|
||||
ev_io_start(EV_A_ & server->recv_ctx->io);
|
||||
}
|
||||
// all sent out, wait for reading
|
||||
remote->buf->len = 0;
|
||||
remote->buf->idx = 0;
|
||||
ev_io_stop(EV_A_ & remote_send_ctx->io);
|
||||
ev_io_start(EV_A_ & server->recv_ctx->io);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -606,9 +574,6 @@ new_server(int fd)
|
||||
ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ);
|
||||
ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE);
|
||||
|
||||
ev_timer_init(&server->delayed_connect_watcher,
|
||||
delayed_connect_cb, 0.05, 0);
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
@@ -626,10 +591,6 @@ free_server(server_t *server)
|
||||
crypto->ctx_release(server->d_ctx);
|
||||
ss_free(server->d_ctx);
|
||||
}
|
||||
if (server->abuf != NULL) {
|
||||
bfree(server->abuf);
|
||||
ss_free(server->abuf);
|
||||
}
|
||||
if (server->buf != NULL) {
|
||||
bfree(server->buf);
|
||||
ss_free(server->buf);
|
||||
|
||||
@@ -55,15 +55,12 @@ typedef struct server {
|
||||
int fd;
|
||||
|
||||
buffer_t *buf;
|
||||
buffer_t *abuf;
|
||||
cipher_ctx_t *e_ctx;
|
||||
cipher_ctx_t *d_ctx;
|
||||
struct server_ctx *recv_ctx;
|
||||
struct server_ctx *send_ctx;
|
||||
struct remote *remote;
|
||||
ss_addr_t destaddr;
|
||||
|
||||
ev_timer delayed_connect_watcher;
|
||||
} server_t;
|
||||
|
||||
typedef struct remote_ctx {
|
||||
|
||||
Reference in New Issue
Block a user