mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-28 03:33:42 +00:00
WiP
This commit is contained in:
+26
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+15
-5
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
+18
-10
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user