diff --git a/src/udprelay.c b/src/udprelay.c index 3ad70d5a..1341684f 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -86,6 +86,8 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents); static void remote_recv_cb(EV_P_ ev_io *w, int revents); static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents); +static void protect_cb(int ret, void *data); + static char *hash_key(const int af, const struct sockaddr_storage *addr); #ifdef UDPRELAY_REMOTE static void query_resolve_cb(struct sockaddr *addr, void *data); @@ -98,6 +100,42 @@ extern int verbose; static int server_num = 0; static struct server_ctx *server_ctx_list[MAX_REMOTE_NUM] = { NULL }; +#ifdef ANDROID +static struct protect_ctx *new_protect_ctx(char *buf, int buf_len, + struct sockaddr *addr, int addr_len) { + struct protect_ctx *protect_ctx = (struct protect_ctx *)malloc(sizeof(struct protect_ctx)); + memset(protect_ctx, 0, sizeof(struct protect_ctx)); + + protect_ctx->buf = malloc(buf_len); + memcpy(protect_ctx->buf, buf, buf_len); + protect_ctx->buf_len = buf_len; + + memcpy(&protect_ctx->addr, (const char*)addr, addr_len); + protect_ctx->addr_len = addr_len; + + return protect_ctx; +} + +static void free_protect_ctx(struct protect_ctx *protect_ctx) { + if (protect_ctx != NULL) { + free(protect_ctx->buf); + free(protect_ctx); + } +} + +static void protect_cb(int ret, void *data) { + struct protect_ctx *protect_ctx = (struct protect_ctx*)data; + if (ret != -1) { + int s = sendto(protect_ctx->remote_ctx->fd, protect_ctx->buf, + protect_ctx->buf_len, 0, protect_ctx->addr, protect_ctx->addr_len); + if (s == -1) { + ERROR("[udp] sendto_remote"); + } + } + free_protect_ctx(protect_ctx); +} +#endif + #ifndef __MINGW32__ static int setnonblocking(int fd) { @@ -1058,11 +1096,17 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); +#ifdef ANDROID + struct protect_ctx *protect_ctx = new_protect_ctx(buf, buf_len, &remote_addr, remote_addr_len); + protect_ctx->remote_ctx = remote_ctx; + protect_socket(protect_cb, (void*)protect_ctx, remote_ctx->fd); +#else int s = sendto(remote_ctx->fd, buf, buf_len, 0, remote_addr, remote_addr_len); if (s == -1) { ERROR("[udp] sendto_remote"); } +#endif #else diff --git a/src/udprelay.h b/src/udprelay.h index 4745162e..a6f89a37 100644 --- a/src/udprelay.h +++ b/src/udprelay.h @@ -82,4 +82,14 @@ struct remote_ctx { struct server_ctx *server_ctx; }; +#ifdef ANDROID +struct protect_ctx { + int buf_len; + char *buf; + struct sockaddr_storage addr; + int addr_len; + struct remote_ctx *remote_ctx; +} +#endif + #endif // _UDPRELAY_H