mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 03:33:42 +00:00
WiP
This commit is contained in:
+31
-50
@@ -61,11 +61,11 @@ int setinterface(int socket_fd, const char* interface_name)
|
||||
int create_and_bind(const char *host, const char *port) {
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
int s, listen_sock;
|
||||
int s, server_sock;
|
||||
|
||||
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_socktype = SOCK_DGRAM; /* We want a UDP socket */
|
||||
|
||||
s = getaddrinfo(host, port, &hints, &result);
|
||||
if (s != 0) {
|
||||
@@ -74,18 +74,17 @@ int create_and_bind(const char *host, const char *port) {
|
||||
}
|
||||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
listen_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (listen_sock == -1)
|
||||
server_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (server_sock == -1)
|
||||
continue;
|
||||
|
||||
int opt = 1;
|
||||
setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
|
||||
setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
#ifdef SO_NOSIGPIPE
|
||||
setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
|
||||
setsockopt(server_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
|
||||
#endif
|
||||
|
||||
s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen);
|
||||
s = bind(server_sock, rp->ai_addr, rp->ai_addrlen);
|
||||
if (s == 0) {
|
||||
/* We managed to bind successfully! */
|
||||
break;
|
||||
@@ -93,7 +92,7 @@ int create_and_bind(const char *host, const char *port) {
|
||||
ERROR("bind");
|
||||
}
|
||||
|
||||
close(listen_sock);
|
||||
close(server_sock);
|
||||
}
|
||||
|
||||
if (rp == NULL) {
|
||||
@@ -103,7 +102,7 @@ int create_and_bind(const char *host, const char *port) {
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
return listen_sock;
|
||||
return server_sock;
|
||||
}
|
||||
|
||||
struct client *connect_to_client(struct addrinfo *res, const char *iface) {
|
||||
@@ -288,7 +287,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
query = asyncns_getaddrinfo(server->shadowsocks_ctx->asyncns,
|
||||
query = asyncns_getaddrinfo(server->server_ctx->asyncns,
|
||||
host, port, &hints);
|
||||
|
||||
if (query == NULL) {
|
||||
@@ -385,10 +384,8 @@ static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
int err;
|
||||
struct addrinfo *result, *rp;
|
||||
struct server_ctx *server_ctx = (struct server_ctx *) (((void*)watcher)
|
||||
- sizeof(ev_io));
|
||||
struct server *server = server_ctx->server;
|
||||
asyncns_t *asyncns = server->shadowsocks_ctx->asyncns;
|
||||
struct server *server = (struct server *) ((void*)watcher);
|
||||
asyncns_t *asyncns = server->asyncns;
|
||||
asyncns_query_t *query = server->query;
|
||||
|
||||
if (asyncns == NULL || query == NULL) {
|
||||
@@ -428,7 +425,7 @@ static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
|
||||
rp = result;
|
||||
}
|
||||
|
||||
struct client *client = connect_to_client(rp, server->shadowsocks_ctx->iface);
|
||||
struct client *client = connect_to_client(rp, server->server_ctx->iface);
|
||||
|
||||
if (client == NULL) {
|
||||
LOGE("connect error.");
|
||||
@@ -656,26 +653,16 @@ void close_and_free_client(EV_P_ struct client *client) {
|
||||
}
|
||||
}
|
||||
|
||||
struct server* new_server(int fd, struct shadowsocks_ctx *listener) {
|
||||
struct server* new_server(int fd, struct server_ctx *ctx) {
|
||||
server_conn++;
|
||||
struct server *server;
|
||||
server = malloc(sizeof(struct server));
|
||||
server->buf = malloc(BUF_SIZE);
|
||||
server->recv_ctx = malloc(sizeof(struct server_ctx));
|
||||
server->send_ctx = malloc(sizeof(struct server_ctx));
|
||||
server->fd = 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->send_ctx->watcher, server_resolve_cb, 0.2, 0.5);
|
||||
ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, listener->timeout, listener->timeout * 5);
|
||||
server->recv_ctx->server = server;
|
||||
server->recv_ctx->connected = 0;
|
||||
server->send_ctx->server = server;
|
||||
server->send_ctx->connected = 0;
|
||||
server->stage = 0;
|
||||
ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, ctx->timeout, ctx->timeout * 5);
|
||||
server->query = NULL;
|
||||
server->shadowsocks_ctx = listener;
|
||||
if (listener->method) {
|
||||
server->server_ctx = ctx;
|
||||
if (ctx->method) {
|
||||
server->e_ctx = malloc(sizeof(struct enc_ctx));
|
||||
server->d_ctx = malloc(sizeof(struct enc_ctx));
|
||||
enc_ctx_init(listener->method, server->e_ctx, 1);
|
||||
@@ -727,8 +714,8 @@ void close_and_free_server(EV_P_ struct server *server) {
|
||||
}
|
||||
}
|
||||
|
||||
static void accept_cb (EV_P_ ev_io *w, int revents) {
|
||||
struct shadowsocks_ctx *listener = (struct shadowsocks_ctx *)w;
|
||||
static void server_cb (EV_P_ ev_io *w, int revents) {
|
||||
struct server_ctx *listener = (struct server_ctx *)w;
|
||||
int serverfd = accept(listener->fd, NULL, NULL);
|
||||
if (serverfd == -1) {
|
||||
ERROR("accept");
|
||||
@@ -737,7 +724,6 @@ static void accept_cb (EV_P_ ev_io *w, int revents) {
|
||||
setnonblocking(serverfd);
|
||||
|
||||
int opt = 1;
|
||||
setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
|
||||
#ifdef SO_NOSIGPIPE
|
||||
setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
|
||||
#endif
|
||||
@@ -751,10 +737,8 @@ static void accept_cb (EV_P_ ev_io *w, int revents) {
|
||||
ev_timer_start(EV_A_ &server->recv_ctx->watcher);
|
||||
}
|
||||
|
||||
int udprelay(char *server_host, int server_num, char *server_port,
|
||||
int method, int timeout, char *iface) {
|
||||
|
||||
int i, c;
|
||||
int udprelay(const char *server_host, int server_num, const char *server_port,
|
||||
int method, int timeout, const char *iface) {
|
||||
|
||||
// inilitialize ev loop
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
@@ -766,24 +750,21 @@ int udprelay(char *server_host, int server_num, char *server_port,
|
||||
|
||||
// Bind to port
|
||||
int serverfd = create_and_bind(host, server_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error..");
|
||||
if (serverfd < 0) {
|
||||
FATAL("udprelay bind() error..");
|
||||
}
|
||||
setnonblocking(serverfd);
|
||||
LOGD("server listening at port %s.", server_port);
|
||||
|
||||
// Setup proxy context
|
||||
struct shadowsocks_ctx shadowsocks_ctx;
|
||||
shadowsocks_ctx.timeout = timeout;
|
||||
shadowsocks_ctx.method = method;
|
||||
shadowsocks_ctx.iface = iface;
|
||||
struct server_ctx *server_ctx = malloc(sizeof(struct server_ctx));
|
||||
server_ctx->fd = serverfd;
|
||||
server_ctx->timeout = timeout;
|
||||
server_ctx->method = method;
|
||||
server_ctx->iface = iface;
|
||||
server_ctx->asyncns = asyncns;
|
||||
|
||||
struct server_ctx server_ctx;
|
||||
server_ctx.asyncns = asyncns;
|
||||
server_ctx.shadowsocks_ctx =
|
||||
|
||||
ev_io_init (&shadowsocks_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start (loop, &shadowsocks_ctx.io);
|
||||
ev_io_init (&server_ctx.io, server_recv_cb, serverfd, EV_READ);
|
||||
ev_io_start (loop, &server_ctx.io);
|
||||
}
|
||||
|
||||
// start ev loop
|
||||
|
||||
+12
-12
@@ -8,24 +8,26 @@
|
||||
#include "jconf.h"
|
||||
#include "asyncns.h"
|
||||
|
||||
#define MAX_UDP_PACKET_SIZE (64 * 1024)
|
||||
|
||||
struct server_ctx {
|
||||
ev_io io;
|
||||
ev_timer watcher;
|
||||
int connected;
|
||||
struct server *server;
|
||||
asyncns_t *asyncns;
|
||||
int fd;
|
||||
int method;
|
||||
int timeout;
|
||||
char *iface;
|
||||
};
|
||||
|
||||
struct server {
|
||||
int fd;
|
||||
ev_timer watcher;
|
||||
asyncns_query_t *query;
|
||||
int buf_len;
|
||||
int buf_idx;
|
||||
int timeout;
|
||||
int method;
|
||||
char *iface;
|
||||
char *buf; // server send from, client recv into
|
||||
struct server_ctx *recv_ctx;
|
||||
struct server_ctx *send_ctx;
|
||||
asyncns_query_t *query;
|
||||
struct enc_ctx *e_ctx;
|
||||
struct enc_ctx *d_ctx;
|
||||
struct server_ctx *server_ctx;
|
||||
struct client *client;
|
||||
};
|
||||
|
||||
@@ -39,8 +41,6 @@ struct client {
|
||||
int buf_len;
|
||||
int buf_idx;
|
||||
char *buf; // client send from, server recv into
|
||||
struct enc_ctx *e_ctx;
|
||||
struct enc_ctx *d_ctx;
|
||||
struct client_ctx *recv_ctx;
|
||||
struct client_ctx *send_ctx;
|
||||
struct server *server;
|
||||
|
||||
Reference in New Issue
Block a user