Skip to content

Commit

Permalink
resolver: full ares support
Browse files Browse the repository at this point in the history
Signed-off-by: hexian000 <hexian000@outlook.com>
  • Loading branch information
hexian000 committed Aug 16, 2023
1 parent ac21fe4 commit 6cc11af
Show file tree
Hide file tree
Showing 22 changed files with 405 additions and 219 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ If you downloaded a *-static build in the [Releases](https://github.com/hexian00

```sh
# Debian & Ubuntu
sudo apt install -y libev4
sudo apt install libev4 libc-ares2
# OpenWRT
opkg install libev
opkg install libev libcares
```

*Lua is always statically linked.*
Expand All @@ -99,7 +99,9 @@ opkg install libev

```sh
# Debian & Ubuntu
sudo apt install -y libev-dev liblua5.4-dev
sudo apt install libev-dev liblua5.4-dev libc-ares-dev
# Alpine Linux
apk add libev-dev lua5.4-dev c-ares-dev
```

### Building with CMake
Expand Down
2 changes: 2 additions & 0 deletions ruleset.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ _G.redirect_name = {
_G.redirect = {
-- redirect API address, or loopback will be rejected
[1] = {match.exact("127.0.1.1:80"), rule.redirect("127.0.1.1:9080")},
-- redirect TCP DNS to local cache
[2] = {match.exact("1.1.1.1:53"), rule.redirect("127.0.0.53:53")},
-- no default action, go to _G.route
[0] = nil
}
Expand Down
22 changes: 10 additions & 12 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,10 @@ if(BUILD_STATIC OR LINK_STATIC_LIBS)
else()
find_library(LIBEV_LIBRARY NAMES ev)
endif()
if((EXISTS ${LIBEV_INCLUDE_DIR}) AND (EXISTS ${LIBEV_LIBRARY}))
message(STATUS "libev: ${LIBEV_LIBRARY}")
else()
if((NOT EXISTS ${LIBEV_INCLUDE_DIR}) OR (NOT EXISTS ${LIBEV_LIBRARY}))
message(FATAL_ERROR "libev not found")
endif()
message(STATUS "libev: ${LIBEV_LIBRARY}")
target_include_directories(neosocksd SYSTEM PRIVATE ${LIBEV_INCLUDE_DIR})
target_link_libraries(neosocksd PRIVATE ${LIBEV_LIBRARY})

Expand All @@ -76,14 +75,14 @@ if(BUILD_STATIC OR LINK_STATIC_LIBS)
else()
find_library(LIBCARES_LIBRARY NAMES cares)
endif()
if((EXISTS ${LIBCARES_INCLUDE_DIR}) AND (EXISTS ${LIBCARES_LIBRARY}))
message(STATUS "c-ares: ${LIBCARES_LIBRARY}")
set(WITH_CARES ON)
if((NOT EXISTS ${LIBCARES_INCLUDE_DIR}) OR (NOT EXISTS ${LIBCARES_LIBRARY}))
message(WARNING "c-ares not found, asynchronous name resolution is unavailable")
else()
message(FATAL_ERROR "c-ares not found")
message(STATUS "c-ares: ${LIBCARES_LIBRARY}")
set(WITH_CARES 1)
target_include_directories(neosocksd SYSTEM PRIVATE ${LIBCARES_INCLUDE_DIR})
target_link_libraries(neosocksd PRIVATE ${LIBCARES_LIBRARY})
endif()
target_include_directories(neosocksd SYSTEM PRIVATE ${LIBCARES_INCLUDE_DIR})
target_link_libraries(neosocksd PRIVATE ${LIBCARES_LIBRARY})

# find lua
find_path(LUA_INCLUDE_DIR
Expand All @@ -103,11 +102,10 @@ find_library(LUA_LIBRARY
lib/lua53 lib/lua5.3 lib/lua-5.3
lib/lua lib
)
if((EXISTS ${LUA_INCLUDE_DIR}) AND (EXISTS ${LUA_LIBRARY}))
message(STATUS "Lua: ${LUA_LIBRARY}")
else()
if((NOT EXISTS ${LUA_INCLUDE_DIR}) OR (NOT EXISTS ${LUA_LIBRARY}))
message(FATAL_ERROR "Lua not found")
endif()
message(STATUS "Lua: ${LUA_LIBRARY}")
target_include_directories(neosocksd SYSTEM PRIVATE ${LUA_INCLUDE_DIR})
target_link_libraries(neosocksd PRIVATE ${LUA_LIBRARY} ${CMAKE_DL_LIBS})

Expand Down
4 changes: 3 additions & 1 deletion src/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
struct config {
const char *listen;
const char *forward;
const char *nameserver;
const char *restapi;
const char *ruleset;
const char *user_name;
#if WITH_CARES
const char *nameserver;
#endif
#if WITH_NETDEVICE
const char *netdev;
#endif
Expand Down
42 changes: 28 additions & 14 deletions src/dialer.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#include "dialer.h"
#include "net/http.h"
#include "proto/domain.h"
#include "resolver.h"
#include "utils/buffer.h"
#include "utils/serialize.h"
#include "utils/slog.h"
#include "utils/check.h"
#include "net/addr.h"
#include "net/url.h"
#include "net/http.h"
#include "proto/domain.h"
#include "proto/socks.h"
#include "conf.h"
#include "sockutil.h"
#include "util.h"
#include "resolver.h"

#include <ev.h>
#include <errno.h>
Expand Down Expand Up @@ -175,6 +175,9 @@ static void dialer_cancel(struct dialer *restrict d, struct ev_loop *loop)
switch (d->state) {
case STATE_INIT:
break;
case STATE_RESOLVE:
resolve_cancel(&d->resolve_query);
/* fallthrough */
case STATE_CONNECT:
case STATE_HANDSHAKE1:
case STATE_HANDSHAKE2: {
Expand Down Expand Up @@ -760,16 +763,15 @@ static bool connect_sa(
return true;
}

static void
resolve_cb(struct ev_loop *loop, const struct sockaddr *sa, void *data)
static void resolve_cb(struct ev_loop *loop, void *data)
{
struct dialer *restrict d = data;
const struct domain_name *restrict domain =
d->req->num_proxy > 0 ? &d->req->proxy[0].addr.domain :
&d->req->addr.domain;
const struct dialaddr *restrict addr =
d->req->num_proxy > 0 ? &d->req->proxy[0].addr : &d->req->addr;
const struct sockaddr *sa = resolve_get(&d->resolve_query);
if (sa == NULL) {
LOGE_F("name resolution failed: \"%.*s\"", (int)domain->len,
domain->name);
LOGE_F("name resolution failed: \"%.*s\"",
(int)addr->domain.len, addr->domain.name);
return;
}

Expand All @@ -787,11 +789,13 @@ resolve_cb(struct ev_loop *loop, const struct sockaddr *sa, void *data)
FAIL();
}

if (LOGLEVEL(LOG_LEVEL_DEBUG)) {
if (LOGLEVEL(LOG_LEVEL_VERBOSE)) {
char node_str[addr->domain.len + 1 + 5 + 1];
dialaddr_format(addr, node_str, sizeof(node_str));
char addr_str[64];
format_sa(sa, addr_str, sizeof(addr_str));
LOG_F(LOG_LEVEL_DEBUG, "resolve: \"%.*s\" is \"%s\"",
(int)domain->len, domain->name, addr_str);
LOG_F(LOG_LEVEL_VERBOSE, "resolve: \"%s\" is %s", node_str,
addr_str);
}

if (!connect_sa(d, loop, sa)) {
Expand Down Expand Up @@ -864,7 +868,17 @@ bool dialer_start(
memcpy(host, addr->domain.name, addr->domain.len);
host[addr->domain.len] = '\0';
d->state = STATE_RESOLVE;
resolver_do(loop, host, d->conf->resolve_pf, resolve_cb, d);
struct resolve_query *q = &d->resolve_query;
resolve_init(
G.resolver, q,
(struct event_cb){
.cb = resolve_cb,
.ctx = d,
});
const int family = d->conf->resolve_pf;
if (!resolve_start(q, host, NULL, family)) {
return false;
}
} break;
default:
FAIL();
Expand Down
3 changes: 2 additions & 1 deletion src/dialer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "proto/socks.h"
#include "utils/minmax.h"
#include "utils/buffer.h"
#include "net/url.h"
#include "resolver.h"
#include "sockutil.h"
#include "util.h"

Expand Down Expand Up @@ -74,6 +74,7 @@ struct dialer {
const struct config *conf;
struct event_cb done_cb;
struct dialreq *req;
struct resolve_query resolve_query;
size_t jump;
int state;
enum dialer_error err;
Expand Down
7 changes: 3 additions & 4 deletions src/forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
* This code is licensed under MIT license (see LICENSE for details) */

#include "forward.h"
#include "utils/check.h"
#include "utils/slog.h"
#include "conf.h"
#include "util.h"
#include "server.h"
#include "dialer.h"
#include "sockutil.h"
#include "transfer.h"
#include "util.h"
#include "utils/check.h"
#include "utils/slog.h"

#include <ev.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
Expand Down
2 changes: 1 addition & 1 deletion src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
#include "http.h"
#include "http_impl.h"
#include "net/http.h"
#include "server.h"
#include "utils/minmax.h"
#include "utils/buffer.h"
#include "utils/slog.h"
#include "utils/check.h"
#include "server.h"
#include "transfer.h"
#include "dialer.h"
#include "util.h"
Expand Down
36 changes: 25 additions & 11 deletions src/http_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
#include "net/url.h"
#include "utils/formats.h"
#include "utils/slog.h"
#include "resolver.h"
#include "ruleset.h"

#include <stdint.h>

static void handle_ruleset_stats(struct http_ctx *restrict ctx, const double dt)
{
struct ruleset *restrict ruleset = ctx->s->ruleset;
struct ruleset *restrict ruleset = G.ruleset;
if (ruleset == NULL) {
return;
}
Expand Down Expand Up @@ -68,6 +71,8 @@ static void http_handle_stats(
const struct server *restrict s_ = ctx->s->data;
const struct server_stats *restrict stats = &s_->stats;
const struct listener_stats *restrict lstats = &s_->l.stats;
const struct resolver_stats *restrict resolv_stats =
resolver_stats(G.resolver);
const ev_tstamp now = ev_now(loop);
const double uptime = now - stats->started;
const time_t server_time = time(NULL);
Expand All @@ -91,6 +96,8 @@ static void http_handle_stats(

const double uptime_hrs = uptime / 3600.0;
const double avgreq_hrs = (double)(stats->num_request) / uptime_hrs;
const double avgresolv_hrs =
(double)(resolv_stats->num_query) / uptime_hrs;
FORMAT_BYTES(avgbw_up, ((double)stats->byt_up) / uptime_hrs);
FORMAT_BYTES(avgbw_down, ((double)stats->byt_down) / uptime_hrs);

Expand All @@ -99,22 +106,25 @@ static void http_handle_stats(
"Server Time : %s\n"
"Uptime : %s\n"
"Num Sessions : %zu (+%zu)\n"
"Listener Accepts : %ju (+%ju rejected)\n"
"Requests : %ju (+%ju)\n"
"Avg Requests : %.1f/hrs\n"
"Conn Accepts : %ju (+%ju)\n"
"Requests : %ju (+%ju), %.1f/hrs\n"
"Name Resolves : %ju (+%ju), %.1f/hrs\n"
"Traffic : Up %s, Down %s\n"
"Avg Bandwidth : Up %s/hrs, Down %s/hrs\n",
timestamp, str_uptime, stats->num_sessions, stats->num_halfopen,
lstats->num_serve, num_reject, stats->num_success,
stats->num_request - stats->num_success, avgreq_hrs, xfer_up,
xfer_down, avgbw_up, avgbw_down);
stats->num_request - stats->num_success, avgreq_hrs,
resolv_stats->num_success,
resolv_stats->num_query - resolv_stats->num_success,
avgresolv_hrs, xfer_up, xfer_down, avgbw_up, avgbw_down);

if (stateless) {
return;
}

static struct {
uintmax_t num_success;
uintmax_t num_failure;
uintmax_t xfer_up, xfer_down;
uintmax_t num_accept;
uintmax_t num_reject;
Expand All @@ -133,18 +143,22 @@ static void http_handle_stats(
(double)(lstats->num_accept - last.num_accept) / dt;
const double reject_rate = (double)(num_reject - last.num_reject) / dt;

const uintmax_t num_failure = stats->num_request - stats->num_success;
const double success_rate =
(double)(stats->num_success - last.num_success) / dt;
const double failure_rate =
(double)(num_failure - last.num_failure) / dt;

BUF_APPENDF(
ctx->wbuf,
"Incoming Conns : %.1f/s (%+.1f/s rejected)\n"
"Request Success : %.1f/s\n"
"Accept Rate : %.1f/s (%+.1f/s)\n"
"Request Rate : %.1f/s (%+.1f/s)\n"
"Bandwidth : Up %s/s, Down %s/s\n",
accept_rate, reject_rate, success_rate, xfer_rate_up,
xfer_rate_down);
accept_rate, reject_rate, success_rate, failure_rate,
xfer_rate_up, xfer_rate_down);

last.num_success = stats->num_success;
last.num_failure = num_failure;
last.xfer_up = stats->byt_up;
last.xfer_down = stats->byt_down;
last.num_accept = lstats->num_accept;
Expand Down Expand Up @@ -181,7 +195,7 @@ static void http_handle_ruleset(
struct url *restrict uri)
{
UNUSED(loop);
struct ruleset *ruleset = ctx->s->ruleset;
struct ruleset *ruleset = G.ruleset;
if (ruleset == NULL) {
RESPHDR_POST(ctx->wbuf, HTTP_INTERNAL_SERVER_ERROR);
BUF_APPENDF(
Expand Down
3 changes: 1 addition & 2 deletions src/http_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ static bool proxy_dial(
struct http_ctx *restrict ctx, struct ev_loop *loop,
const char *addr_str)
{
struct server *restrict s = ctx->s;
struct ruleset *ruleset = s->ruleset;
struct ruleset *ruleset = G.ruleset;

struct dialreq *req = NULL;
if (ruleset == NULL) {
Expand Down
Loading

0 comments on commit 6cc11af

Please sign in to comment.