works, but buggy

This commit is contained in:
Max Lv
2013-08-18 20:55:19 +08:00
parent 8eb0b9b118
commit 1d044b9ada
3 changed files with 42 additions and 47 deletions
+11 -6
View File
@@ -39,7 +39,7 @@
#define BUF_SIZE 512
#endif
static int verbose = 0;
int verbose = 0;
static int setnonblocking(int fd) {
int flags;
@@ -182,7 +182,13 @@ 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;
struct sockaddr_in s_addr;
memset(&s_addr, 0, sizeof(s_addr));
if (request->cmd == 3) {
socklen_t addr_len = sizeof(s_addr);
getsockname(server->fd, (struct sockaddr *)&s_addr,
&addr_len);
if (verbose) {
LOGD("udp assc request accepted.");
}
@@ -282,13 +288,12 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
response.rsv = 0;
response.atyp = 1;
struct in_addr sin_addr;
memset(&sin_addr, 0, sizeof(struct in_addr));
memcpy(server->buf, &response, sizeof(struct socks5_response));
memset(server->buf + sizeof(struct socks5_response), 0, sizeof(struct in_addr) + sizeof(uint16_t));
memcpy(server->buf + sizeof(struct socks5_response), &s_addr.sin_addr, sizeof(s_addr.sin_addr));
memcpy(server->buf + sizeof(struct socks5_response) + sizeof(s_addr.sin_addr),
&s_addr.sin_port, sizeof(s_addr.sin_port));
int reply_size = sizeof(struct socks5_response) + sizeof(struct in_addr) + sizeof(uint16_t);
int reply_size = sizeof(struct socks5_response) + sizeof(s_addr.sin_addr) + sizeof(s_addr.sin_port);
int s = send(server->fd, server->buf, reply_size, 0);
if (s < reply_size) {
LOGE("failed to send fake reply.");
+2 -2
View File
@@ -39,7 +39,7 @@
#define BUF_SIZE 512
#endif
static int verbose = 0;
int verbose = 0;
static int remote_conn = 0;
static int server_conn = 0;
@@ -886,7 +886,7 @@ int main (int argc, char **argv) {
}
// Setup UDP
udprelay(server_host[0], server_port, m, iface);
udprelay(server_host[0], server_port, asyncns, m, iface);
// start ev loop
ev_run (loop, 0);
+29 -39
View File
@@ -30,22 +30,6 @@
#include "udprelay.h"
#include "cache.h"
#ifdef UDPRELAY_REMOTE
struct udprelay_header {
uint8_t atyp;
};
#else
#ifdef UDPRELAY_LOCAL
struct udprelay_header {
uint16_t rsv;
uint8_t frag;
uint8_t atyp;
};
#else
#error "No UDPRELAY defined"
#endif
#endif
#ifdef UDPRELAY_REMOTE
#ifdef UDPRELAY_LOCAL
#error "UDPRELAY_REMOTE and UDPRELAY_LOCAL should not be both defined"
@@ -62,7 +46,7 @@ struct udprelay_header {
#define BUF_SIZE MAX_UDP_PACKET_SIZE
static int verbose = 0;
extern int verbose;
static int remote_conn = 0;
static int server_conn = 0;
@@ -96,10 +80,10 @@ static char *hash_key(const char *header, const int header_len, const struct soc
return (char*) MD5((const uint8_t *)key, sizeof(struct sockaddr) + header_len, NULL);
}
static int parse_udprealy_header(const char* buf, const int buf_len,
const int atyp, char *host, char *port) {
static int parse_udprealy_header(const char* buf, const int buf_len, char *host, char *port) {
int offset = 0;
const uint8_t atyp = *(uint8_t*)buf;
int offset = 1;
// get remote addr and port
if (atyp == 1) {
// IP V4
@@ -132,7 +116,7 @@ static int parse_udprealy_header(const char* buf, const int buf_len,
}
}
if (offset == 0){
if (offset == 1){
LOGE("invalid header with addr type %d", atyp);
return 0;
}
@@ -327,7 +311,7 @@ static void query_resolve_cb(EV_P_ ev_timer *watcher, int revents) {
}
if (verbose) {
LOGD("asyncns resolved.");
LOGD("[udp] asyncns resolved.");
}
ev_timer_stop(EV_A_ watcher);
@@ -422,21 +406,19 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) {
}
if (verbose) {
LOGD("receive a packet.");
LOGD("[udp] remote receive a packet.");
}
#ifdef UDPRELAY_LOCAL
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method);
uint8_t atyp = *(uint8_t*)buf;
int offset = 1;
int len = parse_udprealy_header(buf + offset,
buf_len - offset, atyp, NULL, NULL);
int len = parse_udprealy_header(buf, buf_len, NULL, NULL);
if (len == 0 || len != addr_header_len) {
// error in parse header
return;
}
buf_len = buf_len - offset - addr_header_len;
memmove(buf, buf + offset + addr_header_len, buf_len);
buf_len -= addr_header_len;
memmove(buf, buf + addr_header_len, buf_len);
#endif
#ifdef UDPRELAY_REMOTE
@@ -446,19 +428,20 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) {
free(buf);
buf = tmpbuf;
buf_len += addr_header_len;
ss_encrypt_all(BLOCK_SIZE, buf, &buf_len, server_ctx->method);
#endif
int s = sendto(remote_ctx->fd, buf, buf_len, 0, &remote_ctx->src_addr, sizeof(remote_ctx->src_addr));
if (s == -1) {
ERROR("udprelay_sendto_remote");
ERROR("udprelay_sendto_local");
}
}
static void server_recv_cb (EV_P_ ev_io *w, int revents) {
struct server_ctx *server_ctx = (struct server_ctx *)w;
struct udprelay_header *udprelay_header;
struct sockaddr src_addr;
char *buf = server_ctx->buf;
@@ -477,15 +460,17 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
}
if (verbose) {
LOGD("receive a packet.");
LOGD("[udp] server receive a packet.");
}
#ifdef UDPRELAY_REMOTE
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method);
#endif
udprelay_header = (struct udprelay_header *)buf;
offset += sizeof(struct udprelay_header);
#ifdef UDPRELAY_LOCAL
uint8_t frag = *(uint8_t*)(buf + 2);
offset += 3;
#endif
/*
*
@@ -530,19 +515,19 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
char port[64] = {0};
int addr_header_len = parse_udprealy_header(buf + offset,
buf_len - offset, udprelay_header->atyp, host, port);
buf_len - offset, host, port);
if (addr_header_len == 0) {
// error in parse header
return;
}
char *addr_header = buf + offset - sizeof(udprelay_header->atyp);
char *addr_header = buf + offset;
char *key = hash_key(addr_header, addr_header_len, &src_addr);
struct cache *conn_cache = server_ctx->conn_cache;
#ifdef UDPRELAY_LOCAL
if (udprelay_header->frag) {
LOGE("drop a message since frag is not 0");
if (frag) {
LOGE("drop a message since frag is not 0, but %d", frag);
return;
}
@@ -610,7 +595,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
memmove(buf, buf + offset, buf_len);
if (verbose) {
LOGD("send to: %s:%s", host, port);
LOGD("[udp] send to: %s:%s", host, port);
}
struct remote_ctx *remote_ctx = NULL;
@@ -654,6 +639,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;
if (verbose) {
LOGD("free a remote ctx");
}
close_and_free_remote(EV_DEFAULT, remote_ctx);
}