From c7dd2f9a86a2f890c0932373050957198a1162e0 Mon Sep 17 00:00:00 2001 From: Max Lv Date: Wed, 26 Dec 2012 17:51:52 +0800 Subject: [PATCH] fix shadowsocks-libev --- jni/Android.mk | 22 +- jni/shadowsocks/local.c | 715 +++++++++++++++++++++++----------------- jni/shadowsocks/local.h | 1 + libs/armeabi/libexec.so | Bin 17576 -> 17576 bytes libs/armeabi/libnode.so | Bin 13432 -> 13432 bytes 5 files changed, 427 insertions(+), 311 deletions(-) diff --git a/jni/Android.mk b/jni/Android.mk index 9471b577..d88ba4ca 100755 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -34,17 +34,17 @@ LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/pdnsd include $(BUILD_EXECUTABLE) -#include $(CLEAR_VARS) +include $(CLEAR_VARS) -#LOCAL_MODULE := shadowsocks -#LOCAL_SRC_FILES := shadowsocks/local.c shadowsocks/encrypt.c -#LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/libev/ -I$(LOCAL_PATH)/openssl/include -std=c99 +LOCAL_MODULE := shadowsocks +LOCAL_SRC_FILES := shadowsocks/local.c shadowsocks/encrypt.c +LOCAL_CFLAGS := -Wall -O2 -I$(LOCAL_PATH)/libev/ -I$(LOCAL_PATH)/openssl/include -std=c99 -#LOCAL_STATIC_LIBRARIES := libev libcrypto +LOCAL_STATIC_LIBRARIES := libev libcrypto -#LOCAL_LDLIBS := -llog +LOCAL_LDLIBS := -llog -#include $(BUILD_EXECUTABLE) +include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) @@ -68,9 +68,9 @@ LOCAL_LDLIBS := -ldl include $(BUILD_SHARED_LIBRARY) -#subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \ - #crypto \ - #)) +subdirs := $(addprefix $(LOCAL_PATH)/openssl/,$(addsuffix /Android.mk, \ + crypto \ + )) -#include $(subdirs) +include $(subdirs) diff --git a/jni/shadowsocks/local.c b/jni/shadowsocks/local.c index 761f5766..97de12d6 100644 --- a/jni/shadowsocks/local.c +++ b/jni/shadowsocks/local.c @@ -19,6 +19,7 @@ #include #include "local.h" +#include "socks5.h" #include "encrypt.h" #include "android.h" @@ -53,7 +54,6 @@ int create_and_bind(const char *port) { memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ - hints.ai_flags = AI_PASSIVE; /* All interfaces */ s = getaddrinfo("0.0.0.0", port, &hints, &result); if (s != 0) { @@ -90,330 +90,445 @@ int create_and_bind(const char *port) { } static void server_recv_cb (EV_P_ ev_io *w, int revents) { - struct server_ctx *server_recv_ctx = (struct server_ctx *)w; - struct server *server = server_recv_ctx->server; - struct remote *remote = server->remote; + struct server_ctx *server_recv_ctx = (struct server_ctx *)w; + struct server *server = server_recv_ctx->server; + struct remote *remote = server->remote; + if (remote == NULL) { close_and_free_server(EV_A_ server); return; } - while (1) { - ssize_t r = recv(server->fd, remote->buf, BUF_SIZE, 0); - if (r == 0) { - // connection closed - remote->buf_len = 0; - close_and_free_server(EV_A_ server); - if (remote != NULL) { - ev_io_start(EV_A_ &remote->send_ctx->io); - } - return; - } else if(r < 0) { - perror("recv"); - if (errno == EAGAIN) { - // no data - // continue to wait for recv - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } - encrypt(remote->buf, r); - int w = send(remote->fd, remote->buf, r, MSG_NOSIGNAL); - if(w == -1) { - perror("send"); - if (errno == EAGAIN) { - // no data, wait for send - ev_io_stop(EV_A_ &server_recv_ctx->io); - ev_io_start(EV_A_ &remote->send_ctx->io); - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } else if(w < r) { - char *pt; - for (pt = remote->buf; pt < pt + min(w, BUF_SIZE); pt++) { - *pt = *(pt + w); - } - remote->buf_len = r - w; - ev_io_stop(EV_A_ &server_recv_ctx->io); - ev_io_start(EV_A_ &remote->send_ctx->io); - break; - } + + char *buf = remote->buf; + int *buf_len = &remote->buf_len; + if (server->stage != 5) { + buf = server->buf; + buf_len = &server->buf_len; } + + while (1) { + ssize_t r = recv(server->fd, buf, BUF_SIZE, 0); + + if (r == 0) { + // connection closed + *buf_len = 0; + close_and_free_server(EV_A_ server); + if (remote != NULL) { + ev_io_start(EV_A_ &remote->send_ctx->io); + } + return; + } else if(r < 0) { + if (errno == EAGAIN) { + // no data + // continue to wait for recv + break; + } else { + perror("server recv"); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + } + + // local socks5 server + if (server->stage == 5) { + encrypt(remote->buf, r); + int w = send(remote->fd, remote->buf, r, 0); + if(w == -1) { + if (errno == EAGAIN) { + // no data, wait for send + ev_io_stop(EV_A_ &server_recv_ctx->io); + ev_io_start(EV_A_ &remote->send_ctx->io); + break; + } else { + perror("send"); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + } else if(w < r) { + char *pt = remote->buf; + char *et = pt + min(w, BUF_SIZE); + while (pt < et) { + *pt = *(pt + w); + pt++; + } + remote->buf_len = r - w; + ev_io_stop(EV_A_ &server_recv_ctx->io); + ev_io_start(EV_A_ &remote->send_ctx->io); + break; + } + } else if (server->stage == 0) { + struct method_select_response response; + response.ver = VERSION; + response.method = 0; + char *send_buf = (char *)&response; + send(server->fd, send_buf, sizeof(response), MSG_NOSIGNAL); + server->stage = 1; + return; + } else if (server->stage == 1) { + struct socks5_request *request = (struct socks5_request *)server->buf; + + if (request->cmd != 1) { + LOGE("unsupported cmd: %d\n", request->cmd); + struct socks5_response response; + response.ver = VERSION; + response.rep = CMD_NOT_SUPPORTED; + response.rsv = 0; + response.atyp = 1; + char *send_buf = (char *)&response; + send(server->fd, send_buf, 4, MSG_NOSIGNAL); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + + char addr_to_send[256]; + unsigned char addr_len = 0; + addr_to_send[addr_len++] = request->atyp; + + // get remote addr and port + if (request->atyp == 1) { + + // IP V4 + struct in_addr *in_addr; + in_addr = (struct in_addr *)(server->buf + 4); + char* addr_buf = inet_ntoa(*in_addr); + unsigned char name_len = strlen(addr_buf); + memcpy(addr_to_send + addr_len, addr_buf, name_len); + addr_len += name_len; + + // get port + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 4); + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 4 + 1); + addr_to_send[addr_len] = 0; + + } else if (request->atyp == 3) { + // Domain name + unsigned char name_len = *(unsigned char *)(server->buf + 4); + addr_to_send[addr_len++] = name_len; + memcpy(addr_to_send + addr_len, server->buf + 4 + 1, name_len); + addr_len += name_len; + + // get port + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 1 + name_len); + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 1 + name_len + 1); + addr_to_send[addr_len] = 0; + } else { + LOGE("unsupported addrtype: %d\n", request->atyp); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + + send_encrypt(remote->fd, addr_to_send, addr_len, 0); + + // Fake reply + struct socks5_response response; + response.ver = VERSION; + response.rep = 0; + response.rsv = 0; + response.atyp = 1; + + struct in_addr sin_addr; + inet_aton("0.0.0.0", &sin_addr); + + memcpy(server->buf, &response, 4); + memcpy(server->buf + 4, &sin_addr, sizeof(struct in_addr)); + *((unsigned short *)(server->buf + 4 + sizeof(struct in_addr))) + = (unsigned short) htons(atoi(_remote_port)); + + int reply_size = 4 + sizeof(struct in_addr) + sizeof(unsigned short); + int r = send(server->fd, server->buf, reply_size, MSG_NOSIGNAL); + if (r < reply_size) { + LOGE("header not complete sent\n"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + + server->stage = 5; + + } + } } + static void server_send_cb (EV_P_ ev_io *w, int revents) { - struct server_ctx *server_send_ctx = (struct server_ctx *)w; - struct server *server = server_send_ctx->server; - struct remote *remote = server->remote; - if (server->buf_len == 0) { - // close and free - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } else { - // has data to send - ssize_t r = send(server->fd, server->buf, - server->buf_len, 0); - if (r < 0) { - perror("send"); - if (errno != EAGAIN) { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - return; - } - if (r < server->buf_len) { - LOGD("r=%d\n", r); - LOGD("server->buf_len=%d\n", server->buf_len); - // partly sent, move memory, wait for the next time to send - char *pt; - for (pt = server->buf; pt < pt + min(r, BUF_SIZE); pt++) { - *pt = *(pt + r); - } - server->buf_len -= r; - return; - } else { - // all sent out, wait for reading - ev_io_stop(EV_A_ &server_send_ctx->io); - if (remote != NULL) { - ev_io_start(EV_A_ &remote->recv_ctx->io); - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } - } - -} -static void remote_recv_cb (EV_P_ ev_io *w, int revents) { - struct remote_ctx *remote_recv_ctx = (struct remote_ctx *)w; - struct remote *remote = remote_recv_ctx->remote; - struct server *server = remote->server; - if (server == NULL) { - close_and_free_remote(EV_A_ remote); - return; - } - while (1) { - ssize_t r = recv(remote->fd, server->buf, BUF_SIZE, 0); - /*LOGD("after recv: r=%d\n", r);*/ - if (r == 0) { - // connection closed - server->buf_len = 0; - close_and_free_remote(EV_A_ remote); - if (server != NULL) { - ev_io_start(EV_A_ &server->send_ctx->io); - } - return; - } else if(r < 0) { - perror("recv"); - if (errno == EAGAIN) { - // no data - // continue to wait for recv - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } - decrypt(server->buf, r); - int w = send(server->fd, server->buf, r, MSG_NOSIGNAL); - /*LOGD("after send: w=%d\n", w);*/ - if(w == -1) { - perror("send"); - if (errno == EAGAIN) { - // no data, wait for send - ev_io_stop(EV_A_ &remote_recv_ctx->io); - ev_io_start(EV_A_ &server->send_ctx->io); - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } else if(w < r) { - char *pt; - for (pt = server->buf; pt < pt + min(w, BUF_SIZE); pt++) { - *pt = *(pt + w); - } - server->buf_len = r - w; - ev_io_stop(EV_A_ &remote_recv_ctx->io); - ev_io_start(EV_A_ &server->send_ctx->io); - break; - } - } -} -static void remote_send_cb (EV_P_ ev_io *w, int revents) { - struct remote_ctx *remote_send_ctx = (struct remote_ctx *)w; - struct remote *remote = remote_send_ctx->remote; - struct server *server = remote->server; - if (!remote_send_ctx->connected) { - socklen_t len; - struct sockaddr_storage addr; - len = sizeof addr; - 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_io_start(EV_A_ &server->recv_ctx->io); - ev_io_start(EV_A_ &remote->recv_ctx->io); - } else { - perror("getpeername"); - // not connected - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } - } else { - if (remote->buf_len == 0) { - // close and free - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } else { - // has data to send - ssize_t r = send(remote->fd, remote->buf, - remote->buf_len, 0); - if (r < 0) { + struct server_ctx *server_send_ctx = (struct server_ctx *)w; + struct server *server = server_send_ctx->server; + struct remote *remote = server->remote; + if (server->buf_len == 0) { + // close and free + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } else { + // has data to send + ssize_t r = send(server->fd, server->buf, + server->buf_len, 0); + if (r < 0) { + if (errno != EAGAIN) { perror("send"); - if (errno != EAGAIN) { - // close and free - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } - return; - } - if (r < remote->buf_len) { - // partly sent, move memory, wait for the next time to send - char *pt; - for (pt = remote->buf; pt < pt + min(r, BUF_SIZE); pt++) { - *pt = *(pt + r); - } - remote->buf_len -= r; - return; - } else { - // all sent out, wait for reading - ev_io_stop(EV_A_ &remote_send_ctx->io); - if (server != NULL) { - ev_io_start(EV_A_ &server->recv_ctx->io); - } else { - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } - } - } + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + return; + } + if (r < server->buf_len) { + // partly sent, move memory, wait for the next time to send + char *pt = server->buf; + char *et = pt + min(r, BUF_SIZE); + while (pt < et) { + *pt = *(pt + r); + pt++; + } + server->buf_len -= r; + return; + } else { + // all sent out, wait for reading + ev_io_stop(EV_A_ &server_send_ctx->io); + if (remote != NULL) { + ev_io_start(EV_A_ &remote->recv_ctx->io); + } else { + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + } + } - } +} + +static void remote_recv_cb (EV_P_ ev_io *w, int revents) { + struct remote_ctx *remote_recv_ctx = (struct remote_ctx *)w; + struct remote *remote = remote_recv_ctx->remote; + struct server *server = remote->server; + if (server == NULL) { + close_and_free_remote(EV_A_ remote); + return; + } + while (1) { + ssize_t r = recv(remote->fd, server->buf, BUF_SIZE, 0); + + if (r == 0) { + // connection closed + server->buf_len = 0; + close_and_free_remote(EV_A_ remote); + if (server != NULL) { + ev_io_start(EV_A_ &server->send_ctx->io); + } + return; + } else if(r < 0) { + if (errno == EAGAIN) { + // no data + // continue to wait for recv + break; + } else { + perror("remote recv"); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + } + decrypt(server->buf, r); + int w = send(server->fd, server->buf, r, MSG_NOSIGNAL); + if(w == -1) { + if (errno == EAGAIN) { + // no data, wait for send + ev_io_stop(EV_A_ &remote_recv_ctx->io); + ev_io_start(EV_A_ &server->send_ctx->io); + break; + } else { + perror("send"); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + } else if(w < r) { + char *pt = server->buf; + char *et = pt + min(w, BUF_SIZE); + while (pt < et) { + *pt = *(pt + w); + pt++; + } + server->buf_len = r - w; + ev_io_stop(EV_A_ &remote_recv_ctx->io); + ev_io_start(EV_A_ &server->send_ctx->io); + break; + } + } +} + +static void remote_send_cb (EV_P_ ev_io *w, int revents) { + struct remote_ctx *remote_send_ctx = (struct remote_ctx *)w; + struct remote *remote = remote_send_ctx->remote; + struct server *server = remote->server; + + if (!remote_send_ctx->connected) { + + socklen_t len; + struct sockaddr_storage addr; + len = sizeof addr; + 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_io_start(EV_A_ &server->recv_ctx->io); + ev_io_start(EV_A_ &remote->recv_ctx->io); + } else { + perror("getpeername"); + // not connected + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } else { + if (remote->buf_len == 0) { + // close and free + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } else { + // has data to send + ssize_t r = send(remote->fd, remote->buf, + remote->buf_len, 0); + if (r < 0) { + if (errno != EAGAIN) { + perror("send"); + // close and free + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + return; + } + if (r < remote->buf_len) { + // partly sent, move memory, wait for the next time to send + char *pt = remote->buf; + char *et = pt + min(r, BUF_SIZE); + while (pt < et) { + *pt = *(pt + r); + pt++; + } + remote->buf_len -= r; + return; + } else { + // all sent out, wait for reading + ev_io_stop(EV_A_ &remote_send_ctx->io); + if (server != NULL) { + ev_io_start(EV_A_ &server->recv_ctx->io); + } else { + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; + } + } + } + + } } struct remote* new_remote(int fd) { - struct remote *remote; - remote = malloc(sizeof(struct remote)); - remote->fd = fd; - remote->recv_ctx = malloc(sizeof(struct remote_ctx)); - remote->send_ctx = malloc(sizeof(struct remote_ctx)); - ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); - ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); - remote->recv_ctx->remote = remote; - remote->recv_ctx->connected = 0; - remote->send_ctx->remote = remote; - remote->send_ctx->connected = 0; - return remote; + struct remote *remote; + remote = malloc(sizeof(struct remote)); + remote->fd = fd; + remote->recv_ctx = malloc(sizeof(struct remote_ctx)); + remote->send_ctx = malloc(sizeof(struct remote_ctx)); + ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); + ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); + remote->recv_ctx->remote = remote; + remote->recv_ctx->connected = 0; + remote->send_ctx->remote = remote; + remote->send_ctx->connected = 0; + return remote; } void free_remote(struct remote *remote) { - if (remote != NULL) { - if (remote->server != NULL) { - remote->server->remote = NULL; - } - free(remote->recv_ctx); - free(remote->send_ctx); - free(remote); - } + if (remote != NULL) { + if (remote->server != NULL) { + remote->server->remote = NULL; + } + free(remote->recv_ctx); + free(remote->send_ctx); + free(remote); + } } void close_and_free_remote(EV_P_ struct remote *remote) { - if (remote != NULL) { - ev_io_stop(EV_A_ &remote->send_ctx->io); - ev_io_stop(EV_A_ &remote->recv_ctx->io); - close(remote->fd); - free_remote(remote); - } + if (remote != NULL) { + ev_io_stop(EV_A_ &remote->send_ctx->io); + ev_io_stop(EV_A_ &remote->recv_ctx->io); + close(remote->fd); + free_remote(remote); + } } struct server* new_server(int fd) { - struct server *server; - server = malloc(sizeof(struct server)); - server->fd = fd; - server->recv_ctx = malloc(sizeof(struct server_ctx)); - server->send_ctx = malloc(sizeof(struct server_ctx)); - 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); - server->recv_ctx->server = server; - server->recv_ctx->connected = 0; - server->send_ctx->server = server; - server->send_ctx->connected = 0; - return server; + struct server *server; + server = malloc(sizeof(struct server)); + server->fd = fd; + server->recv_ctx = malloc(sizeof(struct server_ctx)); + server->send_ctx = malloc(sizeof(struct server_ctx)); + 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); + server->recv_ctx->server = server; + server->recv_ctx->connected = 0; + server->send_ctx->server = server; + server->send_ctx->connected = 0; + server->stage = 0; + return server; } void free_server(struct server *server) { - if (server != NULL) { - if (server->remote != NULL) { - server->remote->server = NULL; - } - free(server->recv_ctx); - free(server->send_ctx); - free(server); - } + if (server != NULL) { + if (server->remote != NULL) { + server->remote->server = NULL; + } + free(server->recv_ctx); + free(server->send_ctx); + free(server); + } } void close_and_free_server(EV_P_ struct server *server) { - if (server != NULL) { - ev_io_stop(EV_A_ &server->send_ctx->io); - ev_io_stop(EV_A_ &server->recv_ctx->io); - close(server->fd); - free_server(server); - } + if (server != NULL) { + ev_io_stop(EV_A_ &server->send_ctx->io); + ev_io_stop(EV_A_ &server->recv_ctx->io); + close(server->fd); + free_server(server); + } } - static void accept_cb (EV_P_ ev_io *w, int revents) { - struct listen_ctx *listener = (struct listen_ctx *)w; - int serverfd; - while (1) { - serverfd = accept(listener->fd, NULL, NULL); - if (serverfd == -1) { - perror("accept"); - break; - } - setnonblocking(serverfd); - struct server *server = new_server(serverfd); - struct addrinfo hints, *res; - int sockfd; - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - getaddrinfo(_server, _remote_port, &hints, &res); - sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sockfd < 0) { - perror("socket"); - close(sockfd); - free_server(server); - continue; - } - setnonblocking(sockfd); - struct remote *remote = new_remote(sockfd); - server->remote = remote; - remote->server = server; - connect(sockfd, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - // listen to remote connected event - ev_io_start(EV_A_ &remote->send_ctx->io); - break; - } + struct listen_ctx *listener = (struct listen_ctx *)w; + int serverfd; + while (1) { + serverfd = accept(listener->fd, NULL, NULL); + if (serverfd == -1) { + perror("accept"); + break; + } + setnonblocking(serverfd); + struct server *server = new_server(serverfd); + struct addrinfo hints, *res; + int sockfd; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + getaddrinfo(_server, _remote_port, &hints, &res); + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sockfd < 0) { + perror("socket"); + close(sockfd); + free_server(server); + continue; + } + setnonblocking(sockfd); + struct remote *remote = new_remote(sockfd); + server->remote = remote; + remote->server = server; + connect(sockfd, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + // listen to remote connected event + ev_io_start(EV_A_ &remote->send_ctx->io); + break; + } } int main (int argc, char **argv) diff --git a/jni/shadowsocks/local.h b/jni/shadowsocks/local.h index bae4a19a..0fd5409b 100644 --- a/jni/shadowsocks/local.h +++ b/jni/shadowsocks/local.h @@ -13,6 +13,7 @@ struct listen_ctx { struct server { int fd; char buf[BUF_SIZE]; // server send from, remote recv into + char stage; int buf_len; struct server_ctx *recv_ctx; struct server_ctx *send_ctx; diff --git a/libs/armeabi/libexec.so b/libs/armeabi/libexec.so index 54d9372b768fb06724fe31680e57508c89913ed0..302f782cbfce24870f59734fa275fc62eba61952 100755 GIT binary patch delta 3381 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 P@}5>@WZeAFXgVVRXAWwkbo P@}5>@WZC@CXgVVR