The route configuration directive accepts the keyword 'default'

In that case it will return a default route irrespective of any other
route directives. That allows overriding existing routes with a default
route for specific users and groups.
This commit is contained in:
Nikos Mavrogiannopoulos
2014-05-19 09:58:37 +02:00
parent 0f0f96ef5c
commit 6bc625df81
7 changed files with 82 additions and 37 deletions
+4
View File
@@ -17,6 +17,10 @@
- Added the predictable-ips configuration option. That option allows - Added the predictable-ips configuration option. That option allows
to disable the default "stable" IP assignment, and use completely to disable the default "stable" IP assignment, and use completely
random assignment. random assignment.
- The route configuration directive accepts the keyword 'default',
and will return a default route irrespective of any other route
directives. That allows overriding existing routes with a default
route for specific users and groups.
* Version 0.3.4 (released 2014-05-01) * Version 0.3.4 (released 2014-05-01)
+9 -5
View File
@@ -254,7 +254,7 @@ static void parse_cfg_file(const char* file, struct cfg_st *config)
{ {
tOptionValue const * pov; tOptionValue const * pov;
const tOptionValue* val, *prev; const tOptionValue* val, *prev;
unsigned j, mand; unsigned j, i, mand;
char** auth = NULL; char** auth = NULL;
unsigned auth_size = 0; unsigned auth_size = 0;
unsigned prefix = 0; unsigned prefix = 0;
@@ -482,12 +482,16 @@ unsigned force_cert_auth;
READ_MULTI_LINE("route", config->network.routes, config->network.routes_size); READ_MULTI_LINE("route", config->network.routes, config->network.routes_size);
for (j=0;j<config->network.routes_size;j++) { for (j=0;j<config->network.routes_size;j++) {
if (strstr(config->network.routes[j], "0.0.0.0/0") != 0) { if (strcmp(config->network.routes[j], "0.0.0.0/0") == 0 ||
fprintf(stderr, "Illegal route '%s' detected; to set a default route remove all route directives\n", strcmp(config->network.routes[j], "default") == 0) {
config->network.routes[j]); /* set default route */
exit(1); for (i=0;i<j;i++)
free(config->network.routes[i]);
config->network.routes_size = 0;
break;
} }
} }
READ_MULTI_LINE("dns", config->network.dns, config->network.dns_size); READ_MULTI_LINE("dns", config->network.dns, config->network.dns_size);
if (config->network.dns_size == 0) { if (config->network.dns_size == 0) {
/* try the aliases */ /* try the aliases */
+3 -1
View File
@@ -338,7 +338,9 @@ ping-leases = false
# config-per-user/group or even connect and disconnect scripts. # config-per-user/group or even connect and disconnect scripts.
# #
# To set the server as the default gateway for the client just # To set the server as the default gateway for the client just
# comment out all routes from the server. # comment out all routes from the server, or use the special keyword
# 'default'.
route = 192.168.1.0/255.255.255.0 route = 192.168.1.0/255.255.255.0
route = 192.168.5.0/255.255.255.0 route = 192.168.5.0/255.255.255.0
#route = fef4:db8:1000:1001::/64 #route = fef4:db8:1000:1001::/64
+14
View File
@@ -327,8 +327,22 @@ static int recv_cookie_auth_reply(worker_st * ws)
for (i = 0; i < ws->routes_size; i++) { for (i = 0; i < ws->routes_size; i++) {
ws->routes[i] = ws->routes[i] =
talloc_strdup(ws, msg->routes[i]); talloc_strdup(ws, msg->routes[i]);
/* If a default route is detected */
if (ws->routes[i] != NULL &&
(strcmp(ws->routes[i], "default") == 0 ||
strcmp(ws->routes[i], "0.0.0.0/0") == 0)) {
/* disable all routes */
ws->routes_size = 0;
ws->default_route = 1;
break;
}
} }
if (check_if_default_route(ws->routes, ws->routes_size))
ws->default_route = 1;
ws->dns_size = msg->n_dns; ws->dns_size = msg->n_dns;
for (i = 0; i < ws->dns_size; i++) { for (i = 0; i < ws->dns_size; i++) {
+16
View File
@@ -171,6 +171,19 @@ udp_fd_fail:
return -1; return -1;
} }
unsigned check_if_default_route(char **routes, unsigned routes_size)
{
unsigned i;
for (i=0;i<routes_size;i++) {
if (strcmp(routes[i], "default") == 0 ||
strcmp(routes[i], "0.0.0.0/0") == 0)
return 1;
}
return 0;
}
/* Completes the VPN device information. /* Completes the VPN device information.
* *
* Returns 0 on success. * Returns 0 on success.
@@ -196,6 +209,9 @@ int complete_vpn_info(worker_st * ws, struct vpn_st *vinfo)
if (ws->config->network.routes_size > 0) if (ws->config->network.routes_size > 0)
vinfo->routes = ws->config->network.routes; vinfo->routes = ws->config->network.routes;
if (check_if_default_route(vinfo->routes, vinfo->routes_size))
ws->default_route = 1;
vinfo->ipv4_netmask = ws->config->network.ipv4_netmask; vinfo->ipv4_netmask = ws->config->network.ipv4_netmask;
vinfo->ipv6_netmask = ws->config->network.ipv6_netmask; vinfo->ipv6_netmask = ws->config->network.ipv6_netmask;
vinfo->ipv6_prefix = ws->config->network.ipv6_prefix; vinfo->ipv6_prefix = ws->config->network.ipv6_prefix;
+34 -31
View File
@@ -1496,53 +1496,56 @@ static int connect_handler(worker_st * ws)
SEND_ERR(ret); SEND_ERR(ret);
} }
for (i = 0; i < ws->vinfo.routes_size; i++) { if (ws->default_route == 0) {
if (strchr(ws->vinfo.routes[i], ':') != 0) for (i = 0; i < ws->vinfo.routes_size; i++) {
ip6 = 1; if (strchr(ws->vinfo.routes[i], ':') != 0)
else ip6 = 1;
ip6 = 0; else
ip6 = 0;
if (req->no_ipv6 != 0 && ip6 != 0) if (req->no_ipv6 != 0 && ip6 != 0)
continue; continue;
if (req->no_ipv4 != 0 && ip6 == 0) if (req->no_ipv4 != 0 && ip6 == 0)
continue; continue;
oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]); oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]);
if (ip6 != 0 && ws->full_ipv6) { if (ip6 != 0 && ws->full_ipv6) {
ret = tls_printf(ws->session, ret = tls_printf(ws->session,
"X-CSTP-Split-Include-IP6: %s\r\n", "X-CSTP-Split-Include-IP6: %s\r\n",
ws->vinfo.routes[i]); ws->vinfo.routes[i]);
} else { } else {
ret = tls_printf(ws->session, ret = tls_printf(ws->session,
"X-CSTP-Split-Include: %s\r\n", "X-CSTP-Split-Include: %s\r\n",
ws->vinfo.routes[i]); ws->vinfo.routes[i]);
}
SEND_ERR(ret);
} }
SEND_ERR(ret);
}
for (i = 0; i < ws->routes_size; i++) { for (i = 0; i < ws->routes_size; i++) {
if (strchr(ws->routes[i], ':') != 0) if (strchr(ws->routes[i], ':') != 0)
ip6 = 1; ip6 = 1;
else else
ip6 = 0; ip6 = 0;
if (req->no_ipv6 != 0 && ip6 != 0) if (req->no_ipv6 != 0 && ip6 != 0)
continue; continue;
if (req->no_ipv4 != 0 && ip6 == 0) if (req->no_ipv4 != 0 && ip6 == 0)
continue; continue;
oclog(ws, LOG_DEBUG, "adding private route %s", ws->routes[i]); oclog(ws, LOG_DEBUG, "adding private route %s", ws->routes[i]);
if (ip6 != 0 && ws->full_ipv6) { if (ip6 != 0 && ws->full_ipv6) {
ret = tls_printf(ws->session, ret = tls_printf(ws->session,
"X-CSTP-Split-Include-IP6: %s\r\n", "X-CSTP-Split-Include-IP6: %s\r\n",
ws->routes[i]); ws->routes[i]);
} else { } else {
ret = tls_printf(ws->session, ret = tls_printf(ws->session,
"X-CSTP-Split-Include: %s\r\n", "X-CSTP-Split-Include: %s\r\n",
ws->routes[i]); ws->routes[i]);
}
SEND_ERR(ret);
} }
SEND_ERR(ret);
} }
ret = ret =
tls_printf(ws->session, "X-CSTP-Keepalive: %u\r\n", tls_printf(ws->session, "X-CSTP-Keepalive: %u\r\n",
ws->config->keepalive); ws->config->keepalive);
+2
View File
@@ -212,6 +212,7 @@ typedef struct worker_st {
/* information on the tun device addresses and network */ /* information on the tun device addresses and network */
struct vpn_st vinfo; struct vpn_st vinfo;
unsigned default_route;
/* additional data - received per user or per group */ /* additional data - received per user or per group */
unsigned routes_size; unsigned routes_size;
@@ -253,6 +254,7 @@ void __attribute__ ((format(printf, 3, 4)))
int complete_vpn_info(worker_st * ws, int complete_vpn_info(worker_st * ws,
struct vpn_st* vinfo); struct vpn_st* vinfo);
unsigned check_if_default_route(char **routes, unsigned routes_size);
int send_tun_mtu(worker_st *ws, unsigned int mtu); int send_tun_mtu(worker_st *ws, unsigned int mtu);
int handle_worker_commands(struct worker_st *ws); int handle_worker_commands(struct worker_st *ws);