static void client_send_cb(uv_write_t *req, int status) { struct client_context *client = req->data; struct remote_context *remote = client->remote; if (status == 0) { if (client->stage == XSTAGE_REQUEST) { receive_from_client(client); } else if (client->stage == XSTAGE_FORWARD) { receive_from_remote(remote); } else if (client->stage == XSTAGE_TERMINATE) { close_client(client); close_remote(remote); } } else { char addrbuf[INET6_ADDRSTRLEN + 1] = {0}; int port = ip_name(&client->addr, addrbuf, sizeof addrbuf); if (client->stage == XSTAGE_FORWARD) { logger_log(LOG_ERR, "%s:%d <- %s failed: %s", addrbuf, port, client->target_addr, uv_strerror(status)); } else { logger_log(LOG_ERR, "forward to %s:%d failed: %s", addrbuf, port, uv_strerror(status)); } } free(req); }
static void remote_connect_cb(uv_connect_t *req, int status) { struct remote_context *remote = (struct remote_context *)req->data; struct client_context *client = remote->client; if (status == 0) { remote->stage = XSTAGE_FORWARD; reset_timer(remote); receive_from_client(client); receive_from_remote(remote); } else { if (status != UV_ECANCELED) { logger_log(LOG_ERR, "connect to server failed: %s", uv_strerror(status)); request_ack(client, S5_REP_HOST_UNREACHABLE); } } }
static void remote_connect_cb(uv_connect_t *req, int status) { struct remote_context *remote = (struct remote_context *)req->data; struct client_context *client = remote->client; if (status == 0) { reset_timer(remote); client->stage = XSTAGE_FORWARD; remote->stage = XSTAGE_FORWARD; request_to_server(remote); receive_from_remote(remote); } else { if (status != UV_ECANCELED) { char addrbuf[INET6_ADDRSTRLEN + 1]; ip_name(&server_addr, addrbuf, sizeof(addrbuf)); logger_log(LOG_ERR, "connect to %s failed: %s", addrbuf, uv_strerror(status)); close_client(client); close_remote(remote); } } }
static void remote_connect_cb(uv_connect_t *req, int status) { struct remote_context *remote = (struct remote_context *)req->data; struct client_context *client = remote->client; if (status == 0) { reset_timer(remote); client->stage = XSTAGE_FORWARD; remote->stage = XSTAGE_FORWARD; receive_from_client(client); receive_from_remote(remote); } else { if (status != UV_ECANCELED) { // TODO: handle RST logger_log(LOG_ERR, "connect to %s failed: %s", client->target_addr, uv_strerror(status)); close_client(client); close_remote(remote); } } }