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;
}
/** 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
@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_lookup(struct cache *cache, char *key, void *result);
extern int cache_insert(struct cache *cache, char *key, void *data);
extern int cache_remove(struct cache *cache, char *key);
#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) {
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);
struct socks5_response response;
response.ver = SVERSION;
@ -251,7 +256,6 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
return;
}
addr_to_send = ss_encrypt(addr_to_send, &addr_len, server->e_ctx);
if (addr_to_send == NULL) {
LOGE("invalid password or cipher");
@ -269,6 +273,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
return;
}
server->stage = 5;
ev_io_start(EV_A_ &remote->recv_ctx->io);
fake_reply:
// Fake reply
struct socks5_response response;
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);
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_start (loop, &listen_ctx.io);
// Setup UDP
udprelay(local_addr, local_port, remote_host[0], remote_port, m, iface);
ev_run (loop, 0);
return 0;
}

3
src/server.c

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

28
src/udprelay.c

@ -49,7 +49,7 @@ struct remote *remote = NULL;
#ifdef UDPRELAY_REMOTE
#ifdef UDPRELAY_LOCAL
#error "Both UDPRELAY_REMOTE and UDPRELAY_LOCAL defined"
#error "UDPRELAY_REMOTE and UDPRELAY_LOCAL should not be both defined"
#endif
#endif
@ -89,11 +89,12 @@ static char *hash_key(const char *header, const int header_len, const sockaddr *
char key[384];
// calculate hash key
// assert header_len < 256
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,
@ -122,7 +123,7 @@ static int parse_udprealy_header(const char* buf, const int buf_len,
}
} else if (atyp == 4) {
// 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 (host != NULL) {
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) {
if (ctx != NULL) {
close(ctx->fd);
@ -287,7 +290,6 @@ void close_and_free_remote(EN_P_ struct remote_ctx *ctx) {
free(ctx);
}
}
#endif
static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents) {
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");
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) {
@ -546,7 +549,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
}
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) {
@ -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,
#ifdef UDPRELAY_LOCAL
const char *remote_host, const char *remote_port,

Loading…
Cancel
Save