|
|
@ -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); |
|
|
|