diff --git a/core/main.c b/core/main.c index 711394a2..a8caa244 100644 --- a/core/main.c +++ b/core/main.c @@ -28,7 +28,8 @@ int main(int argc, char **argv) exit(1); } parseCoreSettings(core_file_content); - + free(core_file_content); + // [Runtime setup] { hv_mkdir_p(getCoreSettings()->log_path); @@ -72,7 +73,7 @@ int main(int argc, char **argv) if (cfile == NULL) { - LOGF("Core: could not read core file \"%s\" ", *k.ref); + LOGF("Core: could not read file \"%s\" ", *k.ref); exit(1); } diff --git a/tunnels/adapters/connector/udp.c b/tunnels/adapters/connector/udp.c index 1b3903e1..96387104 100644 --- a/tunnels/adapters/connector/udp.c +++ b/tunnels/adapters/connector/udp.c @@ -1,199 +1,184 @@ +#include "loggers/network_logger.h" #include "types.h" #include "utils/sockutils.h" -#include "loggers/network_logger.h" -static void on_recv(hio_t *io, void *buf, int readbytes) -{ - connector_con_state_t *cstate = (connector_con_state_t *)(hevent_userdata(io)); +static void on_recv(hio_t *io, void *buf, int readbytes) { + connector_con_state_t *cstate = + (connector_con_state_t *)(hevent_userdata(io)); - shift_buffer_t *payload = popBuffer(cstate->buffer_pool); - setLen(payload, readbytes); - writeRaw(payload,buf,readbytes); + shift_buffer_t *payload = popBuffer(cstate->buffer_pool); + setLen(payload, readbytes); + writeRaw(payload, buf, readbytes); - tunnel_t *self = (cstate)->tunnel; - line_t *line = (cstate)->line; + tunnel_t *self = (cstate)->tunnel; + line_t *line = (cstate)->line; - struct sockaddr *destaddr = hio_peeraddr(io); + struct sockaddr *destaddr = hio_peeraddr(io); - enum socket_address_type atype; + enum socket_address_type atype; - if (destaddr->sa_family == AF_INET6) - atype = SAT_IPV6; - else - atype = SAT_IPV4; + if (destaddr->sa_family == AF_INET6) + atype = SAT_IPV6; + else + atype = SAT_IPV4; - if (!cstate->established) - { - cstate->established = true; - context_t *est_context = newContext(line); - est_context->est = true; - est_context->src_io = io; - self->packetDownStream(self, est_context); - if (hevent_userdata(io) == NULL) - return; - } + if (!cstate->established) { + cstate->established = true; + context_t *est_context = newContext(line); + est_context->est = true; + est_context->src_io = io; + self->packetDownStream(self, est_context); + if (hevent_userdata(io) == NULL) + return; + } - context_t *context = newContext(line); - context->src_io = io; - context->payload = payload; + context_t *context = newContext(line); + context->src_io = io; + context->payload = payload; - self->packetDownStream(self, context); + self->packetDownStream(self, context); } -void connectorPacketUpStream(tunnel_t *self, context_t *c) -{ - connector_con_state_t *cstate = CSTATE(c); - - if (c->payload != NULL) - { - int bytes = bufLen(c->payload); +void connectorPacketUpStream(tunnel_t *self, context_t *c) { + connector_con_state_t *cstate = CSTATE(c); - if (hio_is_closed(cstate->io)) - { - free(CSTATE(c)); - CSTATE_MUT(c) = NULL; - DISCARD_CONTEXT(c); - goto fail; - } + if (c->payload != NULL) { + int bytes = bufLen(c->payload); - size_t nwrite = hio_write(cstate->io, rawBuf(c->payload), bytes); - if (nwrite >= 0 && nwrite < bytes) - { - assert(false); // should not happen - } + if (hio_is_closed(cstate->io)) { + free(CSTATE(c)); + CSTATE_MUT(c) = NULL; + DISCARD_CONTEXT(c); + goto fail; + } - DISCARD_CONTEXT(c); - destroyContext(c); + size_t nwrite = hio_write(cstate->io, rawBuf(c->payload), bytes); + if (nwrite >= 0 && nwrite < bytes) { + assert(false); // should not happen } - else - { - if (c->init) - { - CSTATE_MUT(c) = malloc(sizeof(connector_con_state_t)); - memset(CSTATE(c), 0, sizeof(connector_con_state_t)); - connector_con_state_t *cstate = CSTATE(c); - - cstate->buffer_pool = buffer_pools[c->line->tid]; - cstate->tunnel = self; - cstate->line = c->line; - cstate->write_paused = false; - cstate->data_queue = NULL; - cstate->finished_queue = NULL; - - // sockaddr_set_ipport(&(dest->addr),"www.gstatic.com",80); - - hloop_t *loop = loops[c->line->tid]; - - sockaddr_u host_addr = {0}; - sockaddr_set_ipport(&host_addr, "0.0.0.0", 0); - - int sockfd = socket(host_addr.sa.sa_family, SOCK_DGRAM, 0); - if (sockfd < 0) - { - LOGE("Connector: socket fd < 0"); - free(CSTATE(c)); - CSTATE_MUT(c) = NULL; - goto fail; - } + + DISCARD_CONTEXT(c); + destroyContext(c); + } else { + if (c->init) { + CSTATE_MUT(c) = malloc(sizeof(connector_con_state_t)); + memset(CSTATE(c), 0, sizeof(connector_con_state_t)); + connector_con_state_t *cstate = CSTATE(c); + + cstate->buffer_pool = buffer_pools[c->line->tid]; + cstate->tunnel = self; + cstate->line = c->line; + cstate->write_paused = false; + cstate->data_queue = NULL; + cstate->finished_queue = NULL; + + // sockaddr_set_ipport(&(dest->addr),"www.gstatic.com",80); + + hloop_t *loop = loops[c->line->tid]; + + sockaddr_u host_addr = {0}; + sockaddr_set_ipport(&host_addr, "0.0.0.0", 0); + + int sockfd = socket(host_addr.sa.sa_family, SOCK_DGRAM, 0); + if (sockfd < 0) { + LOGE("Connector: socket fd < 0"); + free(CSTATE(c)); + CSTATE_MUT(c) = NULL; + goto fail; + } #ifdef OS_UNIX - so_reuseaddr(sockfd, 1); + so_reuseaddr(sockfd, 1); #endif - sockaddr_u addr; - - sockaddr_set_ipport(&addr, "0.0.0.0", 0); - - if (bind(sockfd, &addr.sa, sockaddr_len(&addr)) < 0) - { - LOGE("UDP bind failed;"); - closesocket(sockfd); - goto fail; - } - - hio_t *upstream_io = hio_get(loop, sockfd); - assert(upstream_io != NULL); - - cstate->io = upstream_io; - hevent_set_userdata(upstream_io, cstate); - hio_setcb_read(upstream_io, on_recv); - hio_read(upstream_io); - - socket_context_t final_ctx = {0}; - // fill the final_ctx address based on settings - { - socket_context_t *src_ctx = &(c->line->src_ctx); - socket_context_t *dest_ctx = &(c->line->dest_ctx); - connector_state_t *state = STATE(self); - - if (state->dest_addr.status == cdvs_from_source) - copySocketContextAddr(&final_ctx, &src_ctx); - else if (state->dest_addr.status == cdvs_from_dest) - copySocketContextAddr(&final_ctx, &dest_ctx); - else - { - final_ctx.atype = state->dest_atype; - if (state->dest_atype == SAT_DOMAINNAME) - { - final_ctx.domain = malloc(state->dest_domain_len + 1); - memcpy(final_ctx.domain, state->dest_addr.value_ptr, state->dest_domain_len + 1); - final_ctx.resolved = false; - final_ctx.addr.sa.sa_family = AF_INET; // addr resolve will change this - } - else - sockaddr_set_ip(&(final_ctx.addr), state->dest_addr.value_ptr); - } - - if (state->dest_port.status == cdvs_from_source) - sockaddr_set_port(&(final_ctx.addr), sockaddr_port(&(src_ctx->addr))); - else if (state->dest_port.status == cdvs_from_dest) - sockaddr_set_port(&(final_ctx.addr), sockaddr_port(&(dest_ctx->addr))); - else - sockaddr_set_port(&(final_ctx.addr), state->dest_port.value); - } - - if (final_ctx.atype == SAT_DOMAINNAME) - { - if (!final_ctx.resolved) - { - if (!connectorResolvedomain(&(final_ctx))) - { - free(final_ctx.domain); - free(CSTATE(c)); - CSTATE_MUT(c) = NULL; - DISCARD_CONTEXT(c); - goto fail; - } - } - free(final_ctx.domain); - } - hio_set_peeraddr(cstate->io, &(final_ctx.addr.sa), sockaddr_len(&(final_ctx.addr))); - - destroyContext(c); + sockaddr_u addr; + + sockaddr_set_ipport(&addr, "0.0.0.0", 0); + + if (bind(sockfd, &addr.sa, sockaddr_len(&addr)) < 0) { + LOGE("UDP bind failed;"); + closesocket(sockfd); + goto fail; + } + + hio_t *upstream_io = hio_get(loop, sockfd); + assert(upstream_io != NULL); + + cstate->io = upstream_io; + hevent_set_userdata(upstream_io, cstate); + hio_setcb_read(upstream_io, on_recv); + hio_read(upstream_io); + + socket_context_t resolved_dest_context = {0}; + // fill the resolved_dest_context address based on settings + { + socket_context_t *src_ctx = &(c->line->src_ctx); + socket_context_t *dest_ctx = &(c->line->dest_ctx); + connector_state_t *state = STATE(self); + + if (state->dest_addr.status == cdvs_from_source) + copySocketContextAddr(&resolved_dest_context, &src_ctx); + else if (state->dest_addr.status == cdvs_from_dest) + copySocketContextAddr(&resolved_dest_context, &dest_ctx); + else { + resolved_dest_context.atype = state->dest_atype; + if (state->dest_atype == SAT_DOMAINNAME) { + resolved_dest_context.domain = state->dest_addr.value_ptr; + resolved_dest_context.domain_len = state->dest_domain_len; + resolved_dest_context.domain_is_constant_memory = true; + resolved_dest_context.resolved = false; + } else + sockaddr_set_ip(&(resolved_dest_context.addr), + state->dest_addr.value_ptr); } - else if (c->fin) - { - hio_t *io = cstate->io; - hevent_set_userdata(io, NULL); + + if (state->dest_port.status == cdvs_from_source) + sockaddr_set_port(&(resolved_dest_context.addr), + sockaddr_port(&(src_ctx->addr))); + else if (state->dest_port.status == cdvs_from_dest) + sockaddr_set_port(&(resolved_dest_context.addr), + sockaddr_port(&(dest_ctx->addr))); + else + sockaddr_set_port(&(resolved_dest_context.addr), + state->dest_port.value); + } + + if (resolved_dest_context.atype == SAT_DOMAINNAME) { + if (!resolved_dest_context.resolved) { + if (!connectorResolvedomain(&(resolved_dest_context))) { + free(resolved_dest_context.domain); free(CSTATE(c)); CSTATE_MUT(c) = NULL; - destroyContext(c); - hio_close(io); + DISCARD_CONTEXT(c); + goto fail; + } } + free(resolved_dest_context.domain); + } + hio_set_peeraddr(cstate->io, &(resolved_dest_context.addr.sa), + sockaddr_len(&(resolved_dest_context.addr))); + + destroyContext(c); + } else if (c->fin) { + hio_t *io = cstate->io; + hevent_set_userdata(io, NULL); + free(CSTATE(c)); + CSTATE_MUT(c) = NULL; + destroyContext(c); + hio_close(io); } - return; + } + return; fail:; - self->dw->downStream(self->dw, newFinContext(c->line)); - destroyContext(c); + self->dw->downStream(self->dw, newFinContext(c->line)); + destroyContext(c); } -void connectorPacketDownStream(tunnel_t *self, context_t *c) -{ - if (c->fin) - { - hio_t *io = CSTATE(c)->io; - hevent_set_userdata(io, NULL); - free(CSTATE(c)); - CSTATE_MUT(c) = NULL; - } - self->dw->downStream(self->dw, c); +void connectorPacketDownStream(tunnel_t *self, context_t *c) { + if (c->fin) { + hio_t *io = CSTATE(c)->io; + hevent_set_userdata(io, NULL); + free(CSTATE(c)); + CSTATE_MUT(c) = NULL; + } + self->dw->downStream(self->dw, c); } diff --git a/ww/basic_types.h b/ww/basic_types.h index a5afd450..9e233f6d 100644 --- a/ww/basic_types.h +++ b/ww/basic_types.h @@ -116,6 +116,8 @@ typedef struct socket_context_s enum socket_address_cmd acmd; enum socket_address_type atype; char *domain; + unsigned int *domain_len; + bool domain_is_constant_memory; bool resolved; sockaddr_u addr; diff --git a/ww/loggers/dns_logger.h b/ww/loggers/dns_logger.h deleted file mode 100644 index fcf6c426..00000000 --- a/ww/loggers/dns_logger.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "hv/hlog.h" -#include - - - -#if !defined(ANDROID) || !defined(__ANDROID__) -#undef hlog -#define hlog getDnsLogger() - - -// FUCK ISO C99 WARNING -#ifdef DEBUG -#undef hlogd -#undef hlogi -#undef hlogw -#undef hloge -#undef hlogf -#define hlogd(...) logger_print(hlog, LOG_LEVEL_DEBUG, ## __VA_ARGS__) -#define hlogi(...) logger_print(hlog, LOG_LEVEL_INFO, ## __VA_ARGS__) -#define hlogw(...) logger_print(hlog, LOG_LEVEL_WARN, ## __VA_ARGS__) -#define hloge(...) logger_print(hlog, LOG_LEVEL_ERROR, ## __VA_ARGS__) -#define hlogf(...) logger_print(hlog, LOG_LEVEL_FATAL, ## __VA_ARGS__) -#endif - - -#endif // android - - - - -logger_t *getDnsLogger(); -void setDnsLogger(logger_t * newlogger); - -logger_t * createDnsLogger(const char * log_file,const char* log_level, bool console); diff --git a/ww/sync_dns.c b/ww/sync_dns.c new file mode 100644 index 00000000..1b0d1153 --- /dev/null +++ b/ww/sync_dns.c @@ -0,0 +1,45 @@ +#include "sync_dns.h" +#include "types.h" +#include "loggers/dns_logger.h" + +static inline bool resolve(socket_context_t *dest) +{ + // we need to get and set port again because resolved ip can be v6/v4 which have different sizes + uint16_t old_port = sockaddr_port(&(dest->addr)); +#ifdef PROFILE + struct timeval tv1, tv2; + gettimeofday(&tv1, NULL); +#endif + /* resolve domain */ + { + if (sockaddr_set_ip_port(&(dest->addr), dest->domain,old_port) != 0) + { + LOGE("Connector: resolve failed %s", dest->domain); + return false; + } + else + { + if (logger_will_write_level(LOG_LEVEL_INFO)) + { + char ip[60]; + sockaddr_str(&(dest->addr), ip, 60); + LOGI("Connector: %s resolved to %s", dest->domain, ip); + } + } + } +#ifdef PROFILE + gettimeofday(&tv2, NULL); + double time_spent = (double)(tv2.tv_usec - tv1.tv_usec) / 1000000 + (double)(tv2.tv_sec - tv1.tv_sec); + LOGD("Connector: dns resolve took %lf sec", time_spent); +#endif + + dest->resolved = true; + return true; +} + +bool resolveContextSync(socekt_context_t *s_ctx) +{ + // please check these before calling this function -> more performance + assert(s_ctx.atype == SAT_DOMAINNAME && s_ctx.resolved == false && dest->domain != NULL); + return resolve(s_ctx); +} \ No newline at end of file diff --git a/ww/sync_dns.h b/ww/sync_dns.h new file mode 100644 index 00000000..bbb5fb25 --- /dev/null +++ b/ww/sync_dns.h @@ -0,0 +1,5 @@ +#pragma once +#include "basic_types.h" + +bool resolveContextSync(socekt_context_t *s_ctx); + diff --git a/ww/tunnel.h b/ww/tunnel.h index a8da21a2..e23152d4 100644 --- a/ww/tunnel.h +++ b/ww/tunnel.h @@ -5,7 +5,7 @@ #include "hv/hloop.h" #include "buffer_pool.h" -#define MAX_CHAIN_LEN 50 +#define MAX_CHAIN_LEN 30 #define DISCARD_CONTEXT(x) \ do \ @@ -15,27 +15,28 @@ x->payload = NULL; \ } while (0) +// no memset 0 typedef struct line_s { hloop_t *loop; - socket_context_t src_ctx; - socket_context_t dest_ctx; - uint16_t tid; uint16_t refc; uint16_t lcid; uint8_t auth_cur; uint8_t auth_max; + + socket_context_t src_ctx; + socket_context_t dest_ctx; void *chains_state[]; } line_t; +// no memset 0 typedef struct context_s { - hio_t *src_io; line_t *line; + hio_t *src_io; shift_buffer_t *payload; - int fd; bool init; bool est; @@ -72,14 +73,17 @@ inline line_t *newLine(uint16_t tid) { size_t size = sizeof(line_t) + (sizeof(void *) * MAX_CHAIN_LEN); line_t *result = malloc(size); - memset(result, 0, size); + // memset(result, 0, size); result->tid = tid; result->refc = 1; result->lcid = MAX_CHAIN_LEN - 1; + result->auth_cur = 0; + result->auth_max = 0; result->loop = loops[tid]; - result->loop = loops[tid]; - result->dest_ctx.addr.sa.sa_family = AF_INET; - result->src_ctx.addr.sa.sa_family = AF_INET; + result->chains_state = {0}; + // to set a port we need to know the AF family, default v4 + result->dest_ctx.addr.sa = (struct sockaddr){.sa_family = AF_INET, .sa_data = {0}}; + result->src_ctx.addr.sa = (struct sockaddr){.sa_family = AF_INET, .sa_data = {0}}; return result; } inline size_t reserveChainStateIndex(line_t *l) @@ -101,24 +105,26 @@ inline void destroyLine(line_t *l) { assert(l->chains_state[i] == NULL); } + + if (l->dest_ctx.domain != NULL && !l->dest_ctx.domain_is_constant_memory) + assert(l->dest_ctx.domain == NULL); + #endif - if (l->dest_ctx.domain != NULL) - free(l->dest_ctx.domain); + + // if (l->dest_ctx.domain != NULL && !l->dest_ctx.domain_is_constant_memory) + // free(l->dest_ctx.domain); free(l); } inline void destroyContext(context_t *c) { assert(c->payload == NULL); - destroyLine(c->line); - free(c); } inline context_t *newContext(line_t *line) { context_t *new_ctx = malloc(sizeof(context_t)); - memset(new_ctx, 0, sizeof(context_t)); - new_ctx->line = line; + *new_ctx = (context_t){.line = line}; // yes, everything else is zero line->refc += 1; return new_ctx; } @@ -173,4 +179,4 @@ static inline void unLockLine(line_t *line) { destroyLine(line); } static inline void markAuthenticationNodePresence(line_t *line) { line->auth_max += 1; } static inline void markAuthenticated(line_t *line) { line->auth_cur += 1; } static inline bool isAuthenticated(line_t *line) { return line->auth_cur > 0; } -static inline bool isFullyAuthenticated(line_t *line) { return line->auth_cur >= line->auth_max; } +static inline bool isFullyAuthenticated(line_t *line) { return line->auth_cur >= line->auth_max; } diff --git a/ww/utils/utils.c b/ww/utils/utils.c index db6d0dfa..73c0fd37 100644 --- a/ww/utils/utils.c +++ b/ww/utils/utils.c @@ -212,7 +212,7 @@ void copySocketContextAddr(socket_context_t *dest, socket_context_t **source) if ((*source)->domain != NULL) { dest->domain = (*source)->domain; - (*source)->domain = NULL; + // (*source)->domain = NULL; // this copies the pointer and the caller is awair } break;