diff --git a/src/config_parser.c b/src/config_parser.c index c8b0a6d..52aef1c 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -361,6 +361,10 @@ static int parse_server(const char *key, const char *value, struct CFG_SERVER *s srv->so_mark = atoi(value); return 0; } + if (strcmp(key, "fib") == 0) { + srv->fib = atoi(value); + return 0; + } if (strcmp(key, "netif") == 0) { srv->netif_index = get_netif_index(value); return 0; @@ -515,6 +519,7 @@ static struct utun_config* parse_config_internal(FILE *fp, const char *filename) goto error; } strcpy(cur_server->name, name); + cur_server->fib = -1; } else if (cur_section == SECTION_CLIENT) { cur_client = u_calloc(1, sizeof(struct CFG_CLIENT)); if (!cur_client) { diff --git a/src/config_parser.h b/src/config_parser.h index 617219d..2024879 100644 --- a/src/config_parser.h +++ b/src/config_parser.h @@ -33,6 +33,7 @@ struct CFG_SERVER { struct sockaddr_storage ip; // ip:port uint32_t netif_index;// if_nameindex, 0 - no interface specified int so_mark; + int fib; // FreeBSD FIB (routing table), -1 = don't set uint8_t type; // public/nat/private int mtu; int loss_rate; // packet loss rate in percent (0-100), default 0 diff --git a/src/etcp_connections.c b/src/etcp_connections.c index b7e7dc3..b527f5b 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -427,9 +427,18 @@ int etcp_find_free_local_link_id(struct ETCP_CONN* etcp) { // =============================== -struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct sockaddr_storage* ip, uint32_t netif_index, int so_mark, uint8_t type, int mtu, int loss_rate, char* name) { +struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); - if (!instance) return NULL; + if (!instance || !server) return NULL; + + struct sockaddr_storage* ip = &server->ip; + uint32_t netif_index = server->netif_index; + int so_mark = server->so_mark; + int fib = server->fib; + uint8_t type = server->type; + int mtu = server->mtu ? server->mtu : instance->config->global.mtu; + int loss_rate = server->loss_rate; + char* name = server->name; struct ETCP_SOCKET* e_sock = u_calloc(1, sizeof(struct ETCP_SOCKET)); if (!e_sock) { @@ -477,6 +486,15 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka if (so_mark > 0) { socket_set_mark(e_sock->fd, so_mark); } + + // Set FIB for FreeBSD +#ifdef __FreeBSD__ + if (fib > 0) { + if (setsockopt(e_sock->fd, SOL_SOCKET, SO_SETFIB, &fib, sizeof(fib)) < 0) { + DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to set FIB %d: %s", fib, strerror(errno)); + } + } +#endif // Bind to interface if specified (Linux only) #ifndef _WIN32 @@ -1257,7 +1275,7 @@ int init_connections(struct UTUN_INSTANCE* instance) { } } - struct ETCP_SOCKET* e_sock = etcp_socket_add(instance, &server->ip, server->netif_index, server->so_mark, server->type, server->mtu ? server->mtu : instance->config->global.mtu, server->loss_rate, server->name); + struct ETCP_SOCKET* e_sock = etcp_socket_add(instance, server); if (e_sock && default_ip != 0) { struct in_addr addr; addr.s_addr = default_ip; diff --git a/src/etcp_connections.h b/src/etcp_connections.h index b8f9a30..eb097c5 100644 --- a/src/etcp_connections.h +++ b/src/etcp_connections.h @@ -164,7 +164,7 @@ int init_connections(struct UTUN_INSTANCE* instance); // SOCKET FUNCTIONS // добавляет новый версер (сокет для приёма и отправки кодограмм. обслуживает много подключений) -struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct sockaddr_storage* ip, uint32_t netif_index, int so_mark, uint8_t type, int mtu, int loss_rate, char* name); +struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server); // удаляет сокет и освобождает ресурсы (грохает все его подключения и сокет) void etcp_socket_remove(struct ETCP_SOCKET* conn);