Browse Source

WiP

pull/14/head
Max Lv 11 years ago
parent
commit
6784fbd3f8
5 changed files with 63 additions and 15 deletions
  1. 26
      src/cache.c
  2. 1
      src/cache.h
  3. 20
      src/local.c
  4. 3
      src/server.c
  5. 28
      src/udprelay.c

26
src/cache.c

@ -70,6 +70,32 @@ int cache_delete(struct cache *cache, int keep_data)
return 0; return 0;
} }
/** Removes a cache entry
@param cache
The cache object
@param key
The key of the entry to remove
@return EINVAL if cache is NULL, 0 otherwise
*/
int cache_remove(struct cache *cache, char *key)
{
struct cache_entry *tmp;
if (!cache || !key)
return EINVAL;
HASH_FIND_STR(cache->entries, key, tmp);
if (tmp) {
HASH_DEL(cache->entries, tmp);
}
return 0;
}
/** Checks if a given key is in the cache /** Checks if a given key is in the cache
@param cache @param cache

1
src/cache.h

@ -33,5 +33,6 @@ extern int cache_create(struct cache **dst, const size_t capacity,
extern int cache_delete(struct cache *cache, int keep_data); extern int cache_delete(struct cache *cache, int keep_data);
extern int cache_lookup(struct cache *cache, char *key, void *result); extern int cache_lookup(struct cache *cache, char *key, void *result);
extern int cache_insert(struct cache *cache, char *key, void *data); extern int cache_insert(struct cache *cache, char *key, void *data);
extern int cache_remove(struct cache *cache, char *key);
#endif #endif

20
src/local.c

@ -182,7 +182,12 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
} else if (server->stage == 1) { } else if (server->stage == 1) {
struct socks5_request *request = (struct socks5_request *)remote->buf; struct socks5_request *request = (struct socks5_request *)remote->buf;
if (request->cmd != 1) {
if (request->cmd == 3) {
if (verbose) {
LOGD("udp assc request accepted.");
}
goto fake_reply;
} else if (request->cmd != 1) {
LOGE("unsupported cmd: %d", request->cmd); LOGE("unsupported cmd: %d", request->cmd);
struct socks5_response response; struct socks5_response response;
response.ver = SVERSION; response.ver = SVERSION;
@ -251,7 +256,6 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
return; return;
} }
addr_to_send = ss_encrypt(addr_to_send, &addr_len, server->e_ctx); addr_to_send = ss_encrypt(addr_to_send, &addr_len, server->e_ctx);
if (addr_to_send == NULL) { if (addr_to_send == NULL) {
LOGE("invalid password or cipher"); LOGE("invalid password or cipher");
@ -269,6 +273,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
return; return;
} }
server->stage = 5;
ev_io_start(EV_A_ &remote->recv_ctx->io);
fake_reply:
// Fake reply // Fake reply
struct socks5_response response; struct socks5_response response;
response.ver = SVERSION; response.ver = SVERSION;
@ -290,9 +299,6 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
close_and_free_server(EV_A_ server); close_and_free_server(EV_A_ server);
return; return;
} }
server->stage = 5;
ev_io_start(EV_A_ &remote->recv_ctx->io);
} }
} }
@ -778,6 +784,10 @@ int main (int argc, char **argv) {
} }
ev_io_init (&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_init (&listen_ctx.io, accept_cb, listenfd, EV_READ);
ev_io_start (loop, &listen_ctx.io); ev_io_start (loop, &listen_ctx.io);
// Setup UDP
udprelay(local_addr, local_port, remote_host[0], remote_port, m, iface);
ev_run (loop, 0); ev_run (loop, 0);
return 0; return 0;
} }

3
src/server.c

@ -885,6 +885,9 @@ int main (int argc, char **argv) {
ev_io_start (loop, &listen_ctx.io); ev_io_start (loop, &listen_ctx.io);
} }
// Setup UDP
udprelay(server_host[0], server_port, m, iface);
// start ev loop // start ev loop
ev_run (loop, 0); ev_run (loop, 0);
return 0; return 0;

28
src/udprelay.c

@ -49,7 +49,7 @@ struct remote *remote = NULL;
#ifdef UDPRELAY_REMOTE #ifdef UDPRELAY_REMOTE
#ifdef UDPRELAY_LOCAL #ifdef UDPRELAY_LOCAL
#error "Both UDPRELAY_REMOTE and UDPRELAY_LOCAL defined"
#error "UDPRELAY_REMOTE and UDPRELAY_LOCAL should not be both defined"
#endif #endif
#endif #endif
@ -89,11 +89,12 @@ static char *hash_key(const char *header, const int header_len, const sockaddr *
char key[384]; char key[384];
// calculate hash key // calculate hash key
// assert header_len < 256
memset(key, 0, 384); memset(key, 0, 384);
memcpy(key, addr.sa_data, 14);
memcpy(key + 14, header, header_len);
memcpy(key, addr, sizeof(sockaddr));
memcpy(key + sizeof(sockaddr), header, header_len);
return (char*) MD5((const uint8_t *)key, 14 + header_len, NULL);
return (char*) MD5((const uint8_t *)key, sizeof(sockaddr) + header_len, NULL);
} }
static int parse_udprealy_header(const char* buf, const int buf_len, static int parse_udprealy_header(const char* buf, const int buf_len,
@ -122,7 +123,7 @@ static int parse_udprealy_header(const char* buf, const int buf_len,
} }
} else if (atyp == 4) { } else if (atyp == 4) {
// IP V6 // IP V6
size_t in6_addbuf_len_len = sizeof(stbuf_lenuct in6_addbuf_len);
size_t in6_addr_len = sizeof(struct in6_addr);
if (buf_len > in6_addbuf_len_len) { if (buf_len > in6_addbuf_len_len) {
if (host != NULL) { if (host != NULL) {
inet_ntop(AF_INET6, (const void*)(buf + offset), inet_ntop(AF_INET6, (const void*)(buf + offset),
@ -274,6 +275,8 @@ void close_and_free_query(EN_P_ struct query_ctx *ctx) {
} }
} }
#endif
void close_and_free_remote(EN_P_ struct remote_ctx *ctx) { void close_and_free_remote(EN_P_ struct remote_ctx *ctx) {
if (ctx != NULL) { if (ctx != NULL) {
close(ctx->fd); close(ctx->fd);
@ -287,7 +290,6 @@ void close_and_free_remote(EN_P_ struct remote_ctx *ctx) {
free(ctx); free(ctx);
} }
} }
#endif
static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) { static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) {
struct remote_ctx *remote_ctx = (struct remote_ctx *) (((void*)watcher) struct remote_ctx *remote_ctx = (struct remote_ctx *) (((void*)watcher)
@ -295,9 +297,10 @@ static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) {
LOGE("UDP connection timeout"); LOGE("UDP connection timeout");
ev_timer_stop(EV_A_ watcher);
close_and_free_remote(EV_A_ remote_ctx);
char *key = hash_key(remote_ctx->addr_header,
remote_ctx->addr_header_len, &remote_ctx->src_addr);
cache_remove(remote_ctx->server_ctx->conn_cache, key);
close_and_free_remote(remote_ctx);
} }
static void query_resolve_cb(EV_P_ ev_timer *watcher, int revents) { static void query_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
@ -546,7 +549,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
} }
struct remote_ctx *remote_ctx = NULL; struct remote_ctx *remote_ctx = NULL;
cache_lookup(conn_cache, key, (void*)remote_ctx);
cache_lookup(conn_cache, key, (void*)&remote_ctx);
if (remote_ctx == NULL) { if (remote_ctx == NULL) {
@ -651,6 +654,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
} }
void free_cb(void *element) {
struct remote_ctx *remote_ctx = (struct remote_ctx *)element;
close_and_free_remote(remote_ctx);
}
int udprelay(const char *server_host, const char *server_port, int udprelay(const char *server_host, const char *server_port,
#ifdef UDPRELAY_LOCAL #ifdef UDPRELAY_LOCAL
const char *remote_host, const char *remote_port, const char *remote_host, const char *remote_port,

Loading…
Cancel
Save