Browse Source

WiP

pull/14/head
Max Lv 11 years ago
parent
commit
c0cd5120cb
2 changed files with 44 additions and 63 deletions
  1. 83
      src/udprelay.c
  2. 24
      src/udprelay.h

83
src/udprelay.c

@ -61,11 +61,11 @@ int setinterface(int socket_fd, const char* interface_name)
int create_and_bind(const char *host, const char *port) { int create_and_bind(const char *host, const char *port) {
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *result, *rp; struct addrinfo *result, *rp;
int s, listen_sock;
int s, server_sock;
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ 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); s = getaddrinfo(host, port, &hints, &result);
if (s != 0) { 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) { 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; continue;
int opt = 1; 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 #ifdef SO_NOSIGPIPE
setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
setsockopt(server_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif #endif
s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen);
s = bind(server_sock, rp->ai_addr, rp->ai_addrlen);
if (s == 0) { if (s == 0) {
/* We managed to bind successfully! */ /* We managed to bind successfully! */
break; break;
@ -93,7 +92,7 @@ int create_and_bind(const char *host, const char *port) {
ERROR("bind"); ERROR("bind");
} }
close(listen_sock);
close(server_sock);
} }
if (rp == NULL) { if (rp == NULL) {
@ -103,7 +102,7 @@ int create_and_bind(const char *host, const char *port) {
freeaddrinfo(result); freeaddrinfo(result);
return listen_sock;
return server_sock;
} }
struct client *connect_to_client(struct addrinfo *res, const char *iface) { 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_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
query = asyncns_getaddrinfo(server->shadowsocks_ctx->asyncns,
query = asyncns_getaddrinfo(server->server_ctx->asyncns,
host, port, &hints); host, port, &hints);
if (query == NULL) { 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) { static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
int err; int err;
struct addrinfo *result, *rp; 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; asyncns_query_t *query = server->query;
if (asyncns == NULL || query == NULL) { if (asyncns == NULL || query == NULL) {
@ -428,7 +425,7 @@ static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
rp = result; 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) { if (client == NULL) {
LOGE("connect error."); 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++; server_conn++;
struct server *server; struct server *server;
server = malloc(sizeof(struct server)); server = malloc(sizeof(struct server));
server->buf = malloc(BUF_SIZE); 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->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->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->e_ctx = malloc(sizeof(struct enc_ctx));
server->d_ctx = malloc(sizeof(struct enc_ctx)); server->d_ctx = malloc(sizeof(struct enc_ctx));
enc_ctx_init(listener->method, server->e_ctx, 1); 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); int serverfd = accept(listener->fd, NULL, NULL);
if (serverfd == -1) { if (serverfd == -1) {
ERROR("accept"); ERROR("accept");
@ -737,7 +724,6 @@ static void accept_cb (EV_P_ ev_io *w, int revents) {
setnonblocking(serverfd); setnonblocking(serverfd);
int opt = 1; int opt = 1;
setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
#ifdef SO_NOSIGPIPE #ifdef SO_NOSIGPIPE
setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif #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); 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 // inilitialize ev loop
struct ev_loop *loop = EV_DEFAULT; struct ev_loop *loop = EV_DEFAULT;
@ -766,24 +750,21 @@ int udprelay(char *server_host, int server_num, char *server_port,
// Bind to port // Bind to port
int serverfd = create_and_bind(host, server_port); int serverfd = create_and_bind(host, server_port);
if (listenfd < 0) {
FATAL("bind() error..");
if (serverfd < 0) {
FATAL("udprelay bind() error..");
} }
setnonblocking(serverfd); setnonblocking(serverfd);
LOGD("server listening at port %s.", server_port);
// Setup proxy context // 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;
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);
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;
ev_io_init (&server_ctx.io, server_recv_cb, serverfd, EV_READ);
ev_io_start (loop, &server_ctx.io);
} }
// start ev loop // start ev loop

24
src/udprelay.h

@ -8,24 +8,26 @@
#include "jconf.h" #include "jconf.h"
#include "asyncns.h" #include "asyncns.h"
#define MAX_UDP_PACKET_SIZE (64 * 1024)
struct server_ctx { struct server_ctx {
ev_io io; ev_io io;
ev_timer watcher;
int connected;
struct server *server;
asyncns_t *asyncns;
int fd;
int method;
int timeout;
char *iface;
}; };
struct server { struct server {
int fd;
ev_timer watcher;
asyncns_query_t *query;
int buf_len; int buf_len;
int buf_idx; int buf_idx;
int timeout;
int method;
char *iface;
char *buf; // server send from, client recv into 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; struct client *client;
}; };
@ -39,8 +41,6 @@ struct client {
int buf_len; int buf_len;
int buf_idx; int buf_idx;
char *buf; // client send from, server recv into 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 *recv_ctx;
struct client_ctx *send_ctx; struct client_ctx *send_ctx;
struct server *server; struct server *server;

Loading…
Cancel
Save