mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-14 02:22:03 +08:00
Added support for the "new" type of IP6 support in AnyConnect.
If the client sends "X-CSTP-Full-IPv6-Capability: true", then we
use the headers:
X-CSTP-Address-IP6: 2001:db8:1000:1000::1/64
X-CSTP-Split-Include-IP6: 2001:db8:1000:1001::/64
X-CSTP-Split-Include-IP6: 2001:db8:1000:1002::/64
(see corresponding openconnect change)
This commit is contained in:
+3
-3
@@ -112,7 +112,6 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "ipv6-nbns", .type = OPTION_MULTI_LINE, .mandatory = 0 }, /* alias nbns */
|
||||
|
||||
{ .name = "ipv6-network", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "ipv6-netmask", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "ipv6-prefix", .type = OPTION_NUMERIC, .mandatory = 0 },
|
||||
{ .name = "route-add-cmd", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "route-del-cmd", .type = OPTION_STRING, .mandatory = 0 },
|
||||
@@ -416,11 +415,12 @@ unsigned force_cert_auth;
|
||||
READ_STRING("ipv4-netmask", config->network.ipv4_netmask);
|
||||
|
||||
READ_STRING("ipv6-network", config->network.ipv6);
|
||||
READ_STRING("ipv6-netmask", config->network.ipv6_netmask);
|
||||
|
||||
READ_NUMERIC("ipv6-prefix", prefix);
|
||||
if (prefix > 0)
|
||||
if (prefix > 0) {
|
||||
config->network.ipv6_netmask = ipv6_prefix_to_mask(prefix);
|
||||
config->network.ipv6_prefix = prefix;
|
||||
}
|
||||
|
||||
READ_MULTI_LINE("custom-header", config->custom_header, config->custom_header_size);
|
||||
READ_MULTI_LINE("split-dns", config->split_dns, config->split_dns_size);
|
||||
|
||||
+4
-3
@@ -52,7 +52,6 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "ipv6-network", .type = OPTION_STRING },
|
||||
{ .name = "ipv4-netmask", .type = OPTION_STRING },
|
||||
{ .name = "ipv6-prefix", .type = OPTION_NUMERIC },
|
||||
{ .name = "ipv6-netmask", .type = OPTION_STRING },
|
||||
{ .name = "rx-data-per-sec", .type = OPTION_NUMERIC, },
|
||||
{ .name = "tx-data-per-sec", .type = OPTION_NUMERIC, },
|
||||
{ .name = "net-priority", .type = OPTION_STRING, },
|
||||
@@ -168,10 +167,12 @@ unsigned prefix = 0;
|
||||
READ_RAW_STRING("ipv4-network", config->ipv4_network);
|
||||
READ_RAW_STRING("ipv6-network", config->ipv6_network);
|
||||
READ_RAW_STRING("ipv4-netmask", config->ipv4_netmask);
|
||||
READ_RAW_STRING("ipv6-netmask", config->ipv6_netmask);
|
||||
|
||||
READ_RAW_NUMERIC("ipv6-prefix", prefix);
|
||||
if (prefix > 0)
|
||||
if (prefix > 0) {
|
||||
config->ipv6_netmask = ipv6_prefix_to_mask(prefix);
|
||||
config->ipv6_prefix = prefix;
|
||||
}
|
||||
|
||||
READ_RAW_NUMERIC("rx-data-per-sec", config->rx_per_sec);
|
||||
READ_RAW_NUMERIC("tx-data-per-sec", config->tx_per_sec);
|
||||
|
||||
+7
-6
@@ -91,12 +91,13 @@ message auth_reply_msg
|
||||
/* additional config */
|
||||
optional string ipv4_netmask = 15;
|
||||
optional string ipv6_netmask = 16;
|
||||
optional uint32 rx_per_sec = 17;
|
||||
optional uint32 tx_per_sec = 18;
|
||||
optional uint32 net_priority = 19;
|
||||
repeated string routes = 20;
|
||||
repeated string dns = 21;
|
||||
repeated string nbns = 22;
|
||||
optional uint32 ipv6_prefix = 17;
|
||||
optional uint32 rx_per_sec = 18;
|
||||
optional uint32 tx_per_sec = 19;
|
||||
optional uint32 net_priority = 20;
|
||||
repeated string routes = 21;
|
||||
repeated string dns = 22;
|
||||
repeated string nbns = 23;
|
||||
}
|
||||
|
||||
/* RESUME_FETCH_REQ + RESUME_DELETE_REQ */
|
||||
|
||||
@@ -109,6 +109,7 @@ int send_auth_reply(main_server_st* s, struct proc_st* proc,
|
||||
|
||||
msg.ipv4_netmask = proc->config.ipv4_netmask;
|
||||
msg.ipv6_netmask = proc->config.ipv6_netmask;
|
||||
msg.ipv6_prefix = proc->config.ipv6_prefix;
|
||||
if (proc->config.rx_per_sec != 0) {
|
||||
msg.has_rx_per_sec = 1;
|
||||
msg.rx_per_sec = proc->config.rx_per_sec;
|
||||
|
||||
@@ -216,6 +216,10 @@ static int read_additional_config_file(main_server_st * s, struct proc_st *proc,
|
||||
cfg.ipv6_netmask = NULL;
|
||||
}
|
||||
|
||||
if (proc->config.ipv6_prefix != 0) {
|
||||
proc->config.ipv6_prefix = cfg.ipv6_prefix;
|
||||
}
|
||||
|
||||
if (proc->config.cgroup == NULL) {
|
||||
proc->config.cgroup = cfg.cgroup;
|
||||
cfg.cgroup = NULL;
|
||||
|
||||
@@ -125,6 +125,7 @@ struct group_cfg_st {
|
||||
|
||||
char *ipv4_network;
|
||||
char *ipv6_network;
|
||||
unsigned ipv6_prefix;
|
||||
char *ipv4_netmask;
|
||||
char *ipv6_netmask;
|
||||
|
||||
@@ -142,6 +143,8 @@ struct vpn_st {
|
||||
char *ipv4;
|
||||
char *ipv4_local; /* local IPv4 address */
|
||||
char *ipv6_netmask;
|
||||
unsigned ipv6_prefix;
|
||||
|
||||
char *ipv6;
|
||||
char *ipv6_local; /* local IPv6 address */
|
||||
unsigned int mtu;
|
||||
|
||||
@@ -310,6 +310,8 @@ static int recv_auth_reply(worker_st * ws, char *txt, size_t max_txt_size)
|
||||
strdup(msg->ipv6_netmask);
|
||||
}
|
||||
|
||||
ws->config->network.ipv6_prefix = msg->ipv6_prefix;
|
||||
|
||||
if (msg->has_rx_per_sec)
|
||||
ws->config->rx_per_sec = msg->rx_per_sec;
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@ int complete_vpn_info(worker_st * ws, struct vpn_st *vinfo)
|
||||
|
||||
vinfo->ipv4_netmask = ws->config->network.ipv4_netmask;
|
||||
vinfo->ipv6_netmask = ws->config->network.ipv6_netmask;
|
||||
vinfo->ipv6_prefix = ws->config->network.ipv6_prefix;
|
||||
|
||||
if (ws->config->network.mtu != 0) {
|
||||
vinfo->mtu = ws->config->network.mtu;
|
||||
|
||||
+56
-16
@@ -181,6 +181,7 @@ int url_cb(http_parser * parser, const char *at, size_t length)
|
||||
#define STR_HDR_CMTU "X-CSTP-MTU"
|
||||
#define STR_HDR_ATYPE "X-CSTP-Address-Type"
|
||||
#define STR_HDR_HOST "X-CSTP-Hostname"
|
||||
#define STR_HDR_FULL_IPV6 "X-CSTP-Full-IPv6-Capability"
|
||||
|
||||
#define CS_ESALSA20 "OC-DTLS1_2-ESALSA20-SHA"
|
||||
#define CS_SALSA20 "OC-DTLS1_2-SALSA20-SHA"
|
||||
@@ -327,6 +328,11 @@ static void value_check(struct worker_st *ws, struct http_req_st *req)
|
||||
NULL)
|
||||
req->no_ipv6 = 1;
|
||||
break;
|
||||
case HEADER_FULL_IPV6:
|
||||
if (memmem(value, value_length, "true", 4) !=
|
||||
NULL)
|
||||
ws->full_ipv6 = 1;
|
||||
break;
|
||||
case HEADER_DTLS_MTU:
|
||||
req->dtls_mtu = atoi((char *)value);
|
||||
break;
|
||||
@@ -443,6 +449,10 @@ static void header_check(struct http_req_st *req)
|
||||
strncmp((char *)req->header.data, STR_HDR_USER_AGENT,
|
||||
req->header.length) == 0) {
|
||||
req->next_header = HEADER_USER_AGENT;
|
||||
} else if (req->header.length == sizeof(STR_HDR_FULL_IPV6) - 1 &&
|
||||
strncmp((char *)req->header.data, STR_HDR_FULL_IPV6,
|
||||
req->header.length) == 0) {
|
||||
req->next_header = HEADER_FULL_IPV6;
|
||||
} else {
|
||||
req->next_header = 0;
|
||||
}
|
||||
@@ -1024,7 +1034,7 @@ static int connect_handler(worker_st * ws)
|
||||
unsigned tls_pending, dtls_pending = 0, i;
|
||||
time_t udp_recv_time = 0, now;
|
||||
struct timespec tnow;
|
||||
unsigned mtu_overhead = 0;
|
||||
unsigned mtu_overhead = 0, ip6;
|
||||
int sndbuf;
|
||||
socklen_t sl;
|
||||
bandwidth_st b_tx;
|
||||
@@ -1140,16 +1150,23 @@ static int connect_handler(worker_st * ws)
|
||||
|
||||
if (ws->vinfo.ipv6 && req->no_ipv6 == 0) {
|
||||
oclog(ws, LOG_DEBUG, "sending IPv6 %s", ws->vinfo.ipv6);
|
||||
ret =
|
||||
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
||||
ws->vinfo.ipv6);
|
||||
SEND_ERR(ret);
|
||||
|
||||
if (ws->vinfo.ipv6_netmask) {
|
||||
if (ws->full_ipv6 && ws->vinfo.ipv6_prefix) {
|
||||
ret =
|
||||
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
|
||||
ws->vinfo.ipv6_netmask);
|
||||
tls_printf(ws->session, "X-CSTP-Address-IP6: %s/%u\r\n",
|
||||
ws->vinfo.ipv6, ws->vinfo.ipv6_prefix);
|
||||
SEND_ERR(ret);
|
||||
} else {
|
||||
ret =
|
||||
tls_printf(ws->session, "X-CSTP-Address: %s\r\n",
|
||||
ws->vinfo.ipv6);
|
||||
SEND_ERR(ret);
|
||||
|
||||
if (ws->vinfo.ipv6_netmask) {
|
||||
ret =
|
||||
tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n",
|
||||
ws->vinfo.ipv6_netmask);
|
||||
SEND_ERR(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1185,25 +1202,48 @@ static int connect_handler(worker_st * ws)
|
||||
}
|
||||
|
||||
for (i = 0; i < ws->vinfo.routes_size; i++) {
|
||||
if (req->no_ipv6 != 0 && strchr(ws->vinfo.routes[i], ':') != 0)
|
||||
if (strchr(ws->vinfo.routes[i], ':') != 0)
|
||||
ip6 = 1;
|
||||
else
|
||||
ip6 = 0;
|
||||
|
||||
if (req->no_ipv6 != 0 && ip6 != 0)
|
||||
continue;
|
||||
if (req->no_ipv4 != 0 && strchr(ws->vinfo.routes[i], '.') != 0)
|
||||
continue;
|
||||
oclog(ws, LOG_DEBUG, "adding route %s", ws->vinfo.routes[i]);
|
||||
ret = tls_printf(ws->session,
|
||||
"X-CSTP-Split-Include: %s\r\n",
|
||||
ws->vinfo.routes[i]);
|
||||
|
||||
if (ip6 != 0 && ws->full_ipv6) {
|
||||
ret = tls_printf(ws->session,
|
||||
"X-CSTP-Split-Include-IP6: %s\r\n",
|
||||
ws->vinfo.routes[i]);
|
||||
} else {
|
||||
ret = tls_printf(ws->session,
|
||||
"X-CSTP-Split-Include: %s\r\n",
|
||||
ws->vinfo.routes[i]);
|
||||
}
|
||||
SEND_ERR(ret);
|
||||
}
|
||||
|
||||
for (i = 0; i < ws->routes_size; i++) {
|
||||
if (req->no_ipv6 != 0 && strchr(ws->routes[i], ':') != 0)
|
||||
if (strchr(ws->routes[i], ':') != 0)
|
||||
ip6 = 1;
|
||||
else
|
||||
ip6 = 0;
|
||||
|
||||
if (req->no_ipv6 != 0 && ip6 != 0)
|
||||
continue;
|
||||
if (req->no_ipv4 != 0 && strchr(ws->routes[i], '.') != 0)
|
||||
continue;
|
||||
oclog(ws, LOG_DEBUG, "adding private route %s", ws->routes[i]);
|
||||
ret = tls_printf(ws->session,
|
||||
"X-CSTP-Split-Include: %s\r\n", ws->routes[i]);
|
||||
|
||||
if (ip6 != 0 && ws->full_ipv6) {
|
||||
ret = tls_printf(ws->session,
|
||||
"X-CSTP-Split-Include-IP6: %s\r\n", ws->routes[i]);
|
||||
} else {
|
||||
ret = tls_printf(ws->session,
|
||||
"X-CSTP-Split-Include: %s\r\n", ws->routes[i]);
|
||||
}
|
||||
SEND_ERR(ret);
|
||||
}
|
||||
ret =
|
||||
|
||||
@@ -51,6 +51,7 @@ enum {
|
||||
HEADER_DTLS_MTU,
|
||||
HEADER_DTLS_CIPHERSUITE,
|
||||
HEADER_CONNECTION,
|
||||
HEADER_FULL_IPV6,
|
||||
HEADER_USER_AGENT,
|
||||
};
|
||||
|
||||
@@ -146,6 +147,10 @@ typedef struct worker_st {
|
||||
unsigned last_bad_mtu;
|
||||
unsigned conn_mtu;
|
||||
|
||||
/* Indicates whether the new IPv6 headers will
|
||||
* be sent or the old */
|
||||
unsigned full_ipv6;
|
||||
|
||||
/* Buffer used by worker */
|
||||
uint8_t * buffer;
|
||||
unsigned buffer_size;
|
||||
|
||||
Reference in New Issue
Block a user