Browse Source

tcp_proxy_server: add fib/so_mark/netif/bind_ip socket options

topo_upd
Evgeny 2 months ago
parent
commit
5a404fbc97
  1. 18
      src/config_parser.c
  2. 4
      src/config_parser.h
  3. 25
      src/proxy/tcp_proxy_server.c
  4. 5
      utun.conf.sample

18
src/config_parser.c

@ -1197,7 +1197,23 @@ struct utun_config* parse_config_from_buf(const char *buf, size_t len, const cha
case SECTION_ALLOWED_KEYS: if (strcmp(key, "allow_all") == 0) cfg->global.allowed_keys_allow_all = strcasecmp(value, "yes") == 0 || strcasecmp(value, "1") == 0 || strcasecmp(value, "true") == 0; else if (strcmp(key, "key") == 0) { struct CFG_ALLOWED_KEY *nk = u_calloc(1, sizeof(struct CFG_ALLOWED_KEY)); if (nk && strlen(value) == SC_PUBKEY_SIZE * 2 && hex_to_binary(value, nk->key_bin, SC_PUBKEY_SIZE) == 0) { nk->next = cfg->global.allowed_keys; cfg->global.allowed_keys = nk; cfg->global.allowed_keys_count++; } else u_free(nk); } else DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: Unknown allowed_keys option '%s'", filename, line_num, key); break;
case SECTION_NAT: cfg->global.nat_enabled = 1; parse_nat(key, value, &cfg->global, filename, line_num); break;
case SECTION_TCP_PROXY_CLIENT: cfg->global.tcp_proxy_client_enabled = 1; parse_tcp_proxy_client(key, value, &cfg->global, filename, line_num); break;
case SECTION_TCP_PROXY_SERVER: cfg->global.tcp_proxy_server_enabled = 1; if (strcmp(key, "tcp_recv_buf") == 0) cfg->global.tcp_recv_buf = atoi(value); break;
case SECTION_TCP_PROXY_SERVER:
cfg->global.tcp_proxy_server_enabled = 1;
if (strcmp(key, "tcp_recv_buf") == 0) {
cfg->global.tcp_recv_buf = atoi(value);
} else if (strcmp(key, "fib") == 0) {
cfg->global.tcp_proxy_server_fib = atoi(value);
} else if (strcmp(key, "so_mark") == 0) {
cfg->global.tcp_proxy_server_so_mark = atoi(value);
} else if (strcmp(key, "netif") == 0) {
cfg->global.tcp_proxy_server_netif_index = get_netif_index(value);
} else if (strcmp(key, "bind_ip") == 0) {
strncpy(cfg->global.tcp_proxy_server_bind_ip, value, sizeof(cfg->global.tcp_proxy_server_bind_ip) - 1);
cfg->global.tcp_proxy_server_bind_ip[sizeof(cfg->global.tcp_proxy_server_bind_ip) - 1] = '\0';
} else {
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: Unknown tcp_proxy_server option '%s'. Valid: tcp_recv_buf, fib, so_mark, netif, bind_ip", filename, line_num, key);
}
break;
case SECTION_NETWORK: if (cur_network) parse_network(key, value, cur_network, filename, line_num); break;
case SECTION_NTP: if (strcmp(key, "enabled") == 0) cfg->global.ntp_enabled = strcasecmp(value, "yes") == 0 || strcasecmp(value, "1") == 0 || strcasecmp(value, "true") == 0; else if (strcmp(key, "server") == 0) { struct CFG_NTP_SERVER *ns = u_calloc(1, sizeof(struct CFG_NTP_SERVER)); if (ns) { strncpy(ns->name, value, sizeof(ns->name) - 1); ns->name[sizeof(ns->name) - 1] = '\0'; ns->next = cfg->global.ntp_servers; cfg->global.ntp_servers = ns; cfg->global.ntp_server_count++; } } else if (strcmp(key, "interval") == 0) { cfg->global.ntp_resync_interval = atoi(value); if (cfg->global.ntp_resync_interval < 60) cfg->global.ntp_resync_interval = 60; } else DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: Unknown ntp option '%s'", filename, line_num, key); break;
case SECTION_CHATSERVER: cfg->global.chatserver_enabled = 1; cfg->global.db_sync_enabled = 1; if (strcmp(key, "db_path") == 0) assign_string(cfg->global.db_path, sizeof(cfg->global.db_path), value); else if (parse_chatserver(key, value, &cfg->global, filename, line_num) < 0 && chat_setting_set(key, value) < 0) { DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "%s:%d: Unknown chatserver option '%s'. Valid: db_path, join_password, allowed_groups, storage_total_size, storage_unit_size, storage_autoload, opus_codec_preset, compressor_enabled, compressor_max_gain_db, compressor_rise_rate, media_download_max_peers", filename, line_num, key); } break;

4
src/config_parser.h

@ -191,6 +191,10 @@ struct global_config {
int tcp_proxy_server_enabled;
int auto_sockets; // 1 = auto-create sockets from interfaces, skip [server]
int tcp_recv_buf; // SO_RCVBUF для TCP сокетов (0=default ОС)
int tcp_proxy_server_fib; // FreeBSD SO_SETFIB, 0=не менять
int tcp_proxy_server_so_mark; // Linux SO_MARK, 0=не менять
uint32_t tcp_proxy_server_netif_index; // Linux SO_BINDTODEVICE, 0=нет
char tcp_proxy_server_bind_ip[64]; // IP для bind() перед connect()
// NTP configuration ([ntp] section)
int ntp_enabled;

25
src/proxy/tcp_proxy_server.c

@ -13,6 +13,7 @@
#include "../lib/ll_queue.h"
#include "../lib/mem.h"
#include "../lib/tcp_io.h"
#include "../lib/socket_compat.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@ -21,6 +22,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <fcntl.h>
#endif
@ -372,6 +374,29 @@ int tcp_proxy_server_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry*
(int)sock, stream_id, dest_ip[0],dest_ip[1],dest_ip[2],dest_ip[3],ntohs(dest_port), ctx->conn_count);
socket_set_nonblocking(sock);
struct global_config* g = &inst->config->global;
if (g->tcp_proxy_server_bind_ip[0]) {
struct sockaddr_in local_addr = {.sin_family = AF_INET, .sin_port = 0};
if (inet_pton(AF_INET, g->tcp_proxy_server_bind_ip, &local_addr.sin_addr) == 1) {
if (bind(sock, (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy server: bind(%s) failed: %s", g->tcp_proxy_server_bind_ip, strerror(errno));
socket_close_wrapper(sock); ctx->conn_count--; u_free(rc); queue_dgram_free(entry); queue_entry_free(entry); return -1;
}
} else {
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy server: invalid bind_ip=%s", g->tcp_proxy_server_bind_ip);
}
}
if (g->tcp_proxy_server_so_mark > 0) socket_set_mark(sock, g->tcp_proxy_server_so_mark);
#ifdef __FreeBSD__
if (g->tcp_proxy_server_fib > 0) {
setsockopt(sock, SOL_SOCKET, SO_SETFIB, &g->tcp_proxy_server_fib, sizeof(g->tcp_proxy_server_fib));
}
#endif
if (g->tcp_proxy_server_netif_index > 0) {
char ifname[IF_NAMESIZE];
if (if_indextoname(g->tcp_proxy_server_netif_index, ifname)) socket_bind_to_device(sock, ifname);
}
rc->tc = tcp_conn_create(inst->ua, sock, 1500, 8192, 4, 0, inst->config->global.tcp_recv_buf, on_fin_cb, on_error_cb, rc);
if (!rc->tc) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy server: tcp_conn_create failed"); socket_close_wrapper(sock); ctx->conn_count--; u_free(rc); queue_dgram_free(entry); queue_entry_free(entry); return -1; }
rc->tc->on_closed = on_closed_cb;

5
utun.conf.sample

@ -107,6 +107,11 @@ allow=all
# Принимает CONNECT-запросы от других нод и открывает OS сокеты к адресатам.
#[tcp_proxy_server]
#enabled=yes
#tcp_recv_buf=65536
#fib=1 ; FreeBSD: SO_SETFIB (routing table number)
#so_mark=100 ; Linux: SO_MARK (socket mark/fwmark)
#netif=eth1 ; Linux: SO_BINDTODEVICE (interface name)
#bind_ip=10.0.0.1 ; bind() local IP before connect()
# --- Chatserver: headless supernode config ---
#[chatserver]

Loading…
Cancel
Save