[PATCH/RFC V2 18/26] library: Export VPN IP information to callers
Kevin Cernekee
cernekee at gmail.com
Sun Aug 11 21:49:19 EDT 2013
Move the IP and split tunnel configuration into "struct oc_ip_info", and
make a new library call for obtaining it.
Signed-off-by: Kevin Cernekee <cernekee at gmail.com>
---
cstp.c | 95 ++++++++++++++++++++++++------------------------
dtls.c | 6 +--
libopenconnect.map.in | 1 +
library.c | 5 +++
main.c | 8 ++--
openconnect-internal.h | 19 +---------
openconnect.h | 22 +++++++++++
tun.c | 72 ++++++++++++++++++------------------
8 files changed, 122 insertions(+), 106 deletions(-)
diff --git a/cstp.c b/cstp.c
index af66fd8..7adb501 100644
--- a/cstp.c
+++ b/cstp.c
@@ -151,24 +151,25 @@ static void calculate_mtu(struct openconnect_info *vpninfo, int *base_mtu, int *
void cstp_free_splits(struct openconnect_info *vpninfo)
{
- struct split_include *inc;
+ struct oc_split_include *inc;
- for (inc = vpninfo->split_includes; inc; ) {
- struct split_include *next = inc->next;
+ for (inc = vpninfo->ip_info.split_includes; inc; ) {
+ struct oc_split_include *next = inc->next;
free(inc);
inc = next;
}
- for (inc = vpninfo->split_excludes; inc; ) {
- struct split_include *next = inc->next;
+ for (inc = vpninfo->ip_info.split_excludes; inc; ) {
+ struct oc_split_include *next = inc->next;
free(inc);
inc = next;
}
- for (inc = vpninfo->split_dns; inc; ) {
- struct split_include *next = inc->next;
+ for (inc = vpninfo->ip_info.split_dns; inc; ) {
+ struct oc_split_include *next = inc->next;
free(inc);
inc = next;
}
- vpninfo->split_dns = vpninfo->split_includes = vpninfo->split_excludes = NULL;
+ vpninfo->ip_info.split_dns = vpninfo->ip_info.split_includes =
+ vpninfo->ip_info.split_excludes = NULL;
}
static int start_cstp_connection(struct openconnect_info *vpninfo)
@@ -180,21 +181,21 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
struct vpn_option **next_cstp_option = &vpninfo->cstp_options;
struct vpn_option *old_cstp_opts = vpninfo->cstp_options;
struct vpn_option *old_dtls_opts = vpninfo->dtls_options;
- const char *old_addr = vpninfo->vpn_addr;
- const char *old_netmask = vpninfo->vpn_netmask;
- const char *old_addr6 = vpninfo->vpn_addr6;
- const char *old_netmask6 = vpninfo->vpn_netmask6;
+ const char *old_addr = vpninfo->ip_info.addr;
+ const char *old_netmask = vpninfo->ip_info.netmask;
+ const char *old_addr6 = vpninfo->ip_info.addr6;
+ const char *old_netmask6 = vpninfo->ip_info.netmask6;
int base_mtu, mtu;
/* Clear old options which will be overwritten */
- vpninfo->vpn_addr = vpninfo->vpn_netmask = NULL;
- vpninfo->vpn_addr6 = vpninfo->vpn_netmask6 = NULL;
+ vpninfo->ip_info.addr = vpninfo->ip_info.netmask = NULL;
+ vpninfo->ip_info.addr6 = vpninfo->ip_info.netmask6 = NULL;
vpninfo->cstp_options = vpninfo->dtls_options = NULL;
- vpninfo->vpn_domain = vpninfo->vpn_proxy_pac = NULL;
+ vpninfo->ip_info.domain = vpninfo->ip_info.proxy_pac = NULL;
vpninfo->banner = NULL;
for (i = 0; i < 3; i++)
- vpninfo->vpn_dns[i] = vpninfo->vpn_nbns[i] = NULL;
+ vpninfo->ip_info.dns[i] = vpninfo->ip_info.nbns[i] = NULL;
cstp_free_splits(vpninfo);
/* Create (new) random master key for DTLS connection, if needed */
@@ -375,58 +376,58 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
} else if (!strcmp(buf + 7, "Address")) {
if (strchr(new_option->value, ':')) {
if (!vpninfo->disable_ipv6)
- vpninfo->vpn_addr6 = new_option->value;
+ vpninfo->ip_info.addr6 = new_option->value;
} else
- vpninfo->vpn_addr = new_option->value;
+ vpninfo->ip_info.addr = new_option->value;
} else if (!strcmp(buf + 7, "Netmask")) {
if (strchr(new_option->value, ':')) {
if (!vpninfo->disable_ipv6)
- vpninfo->vpn_netmask6 = new_option->value;
+ vpninfo->ip_info.netmask6 = new_option->value;
} else
- vpninfo->vpn_netmask = new_option->value;
+ vpninfo->ip_info.netmask = new_option->value;
} else if (!strcmp(buf + 7, "DNS")) {
int j;
for (j = 0; j < 3; j++) {
- if (!vpninfo->vpn_dns[j]) {
- vpninfo->vpn_dns[j] = new_option->value;
+ if (!vpninfo->ip_info.dns[j]) {
+ vpninfo->ip_info.dns[j] = new_option->value;
break;
}
}
} else if (!strcmp(buf + 7, "NBNS")) {
int j;
for (j = 0; j < 3; j++) {
- if (!vpninfo->vpn_nbns[j]) {
- vpninfo->vpn_nbns[j] = new_option->value;
+ if (!vpninfo->ip_info.nbns[j]) {
+ vpninfo->ip_info.nbns[j] = new_option->value;
break;
}
}
} else if (!strcmp(buf + 7, "Default-Domain")) {
- vpninfo->vpn_domain = new_option->value;
+ vpninfo->ip_info.domain = new_option->value;
} else if (!strcmp(buf + 7, "MSIE-Proxy-PAC-URL")) {
- vpninfo->vpn_proxy_pac = new_option->value;
+ vpninfo->ip_info.proxy_pac = new_option->value;
} else if (!strcmp(buf + 7, "Banner")) {
vpninfo->banner = new_option->value;
} else if (!strcmp(buf + 7, "Split-DNS")) {
- struct split_include *dns = malloc(sizeof(*dns));
+ struct oc_split_include *dns = malloc(sizeof(*dns));
if (!dns)
continue;
dns->route = new_option->value;
- dns->next = vpninfo->split_dns;
- vpninfo->split_dns = dns;
+ dns->next = vpninfo->ip_info.split_dns;
+ vpninfo->ip_info.split_dns = dns;
} else if (!strcmp(buf + 7, "Split-Include")) {
- struct split_include *inc = malloc(sizeof(*inc));
+ struct oc_split_include *inc = malloc(sizeof(*inc));
if (!inc)
continue;
inc->route = new_option->value;
- inc->next = vpninfo->split_includes;
- vpninfo->split_includes = inc;
+ inc->next = vpninfo->ip_info.split_includes;
+ vpninfo->ip_info.split_includes = inc;
} else if (!strcmp(buf + 7, "Split-Exclude")) {
- struct split_include *exc = malloc(sizeof(*exc));
+ struct oc_split_include *exc = malloc(sizeof(*exc));
if (!exc)
continue;
exc->route = new_option->value;
- exc->next = vpninfo->split_excludes;
- vpninfo->split_excludes = exc;
+ exc->next = vpninfo->ip_info.split_excludes;
+ vpninfo->ip_info.split_excludes = exc;
}
}
@@ -435,42 +436,42 @@ static int start_cstp_connection(struct openconnect_info *vpninfo)
_("No MTU received. Aborting\n"));
return -EINVAL;
}
- vpninfo->actual_mtu = mtu;
+ vpninfo->ip_info.mtu = mtu;
- if (!vpninfo->vpn_addr && !vpninfo->vpn_addr6) {
+ if (!vpninfo->ip_info.addr && !vpninfo->ip_info.addr6) {
vpn_progress(vpninfo, PRG_ERR,
_("No IP address received. Aborting\n"));
return -EINVAL;
}
if (old_addr) {
- if (strcmp(old_addr, vpninfo->vpn_addr)) {
+ if (strcmp(old_addr, vpninfo->ip_info.addr)) {
vpn_progress(vpninfo, PRG_ERR,
_("Reconnect gave different Legacy IP address (%s != %s)\n"),
- vpninfo->vpn_addr, old_addr);
+ vpninfo->ip_info.addr, old_addr);
return -EINVAL;
}
}
if (old_netmask) {
- if (strcmp(old_netmask, vpninfo->vpn_netmask)) {
+ if (strcmp(old_netmask, vpninfo->ip_info.netmask)) {
vpn_progress(vpninfo, PRG_ERR,
_("Reconnect gave different Legacy IP netmask (%s != %s)\n"),
- vpninfo->vpn_netmask, old_netmask);
+ vpninfo->ip_info.netmask, old_netmask);
return -EINVAL;
}
}
if (old_addr6) {
- if (strcmp(old_addr6, vpninfo->vpn_addr6)) {
+ if (strcmp(old_addr6, vpninfo->ip_info.addr6)) {
vpn_progress(vpninfo, PRG_ERR,
_("Reconnect gave different IPv6 address (%s != %s)\n"),
- vpninfo->vpn_addr6, old_addr6);
+ vpninfo->ip_info.addr6, old_addr6);
return -EINVAL;
}
}
if (old_netmask6) {
- if (strcmp(old_netmask6, vpninfo->vpn_netmask6)) {
+ if (strcmp(old_netmask6, vpninfo->ip_info.netmask6)) {
vpn_progress(vpninfo, PRG_ERR,
_("Reconnect gave different IPv6 netmask (%s != %s)\n"),
- vpninfo->vpn_netmask6, old_netmask6);
+ vpninfo->ip_info.netmask6, old_netmask6);
return -EINVAL;
}
}
@@ -587,7 +588,7 @@ int cstp_reconnect(struct openconnect_info *vpninfo)
static int inflate_and_queue_packet(struct openconnect_info *vpninfo,
unsigned char *buf, int len)
{
- struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->actual_mtu);
+ struct pkt *new = malloc(sizeof(struct pkt) + vpninfo->ip_info.mtu);
uint32_t pkt_sum;
if (!new)
@@ -599,7 +600,7 @@ static int inflate_and_queue_packet(struct openconnect_info *vpninfo,
vpninfo->inflate_strm.avail_in = len - 4;
vpninfo->inflate_strm.next_out = new->data;
- vpninfo->inflate_strm.avail_out = vpninfo->actual_mtu;
+ vpninfo->inflate_strm.avail_out = vpninfo->ip_info.mtu;
vpninfo->inflate_strm.total_out = 0;
if (inflate(&vpninfo->inflate_strm, Z_SYNC_FLUSH)) {
diff --git a/dtls.c b/dtls.c
index e08b2bf..28773ca 100644
--- a/dtls.c
+++ b/dtls.c
@@ -423,7 +423,7 @@ int dtls_try_handshake(struct openconnect_info *vpninfo)
#ifdef HAVE_GNUTLS_DTLS_SET_DATA_MTU
/* Make sure GnuTLS's idea of the MTU is sufficient to take
a full VPN MTU (with 1-byte header) in a data record. */
- err = gnutls_dtls_set_data_mtu(vpninfo->new_dtls_ssl, vpninfo->actual_mtu + 1);
+ err = gnutls_dtls_set_data_mtu(vpninfo->new_dtls_ssl, vpninfo->ip_info.mtu + 1);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to set DTLS MTU: %s\n"),
@@ -436,7 +436,7 @@ int dtls_try_handshake(struct openconnect_info *vpninfo)
We only support AES128-CBC and DES-CBC3-SHA anyway, so
working out the worst case isn't hard. */
gnutls_dtls_set_mtu(vpninfo->new_dtls_ssl,
- vpninfo->actual_mtu + 1 /* packet + header */
+ vpninfo->ip_info.mtu + 1 /* packet + header */
+ 13 /* DTLS header */
+ 20 /* biggest supported MAC (SHA1) */
+ 16 /* biggest supported IV (AES-128) */
@@ -698,7 +698,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
char magic_pkt;
while (1) {
- int len = vpninfo->actual_mtu;
+ int len = vpninfo->ip_info.mtu;
unsigned char *buf;
if (!dtls_pkt) {
diff --git a/libopenconnect.map.in b/libopenconnect.map.in
index 0b0bf74..ef03c9b 100644
--- a/libopenconnect.map.in
+++ b/libopenconnect.map.in
@@ -55,6 +55,7 @@ OPENCONNECT_2.3 {
openconnect_set_server_cert_sha1;
openconnect_get_ifname;
openconnect_set_reqmtu;
+ openconnect_get_ip_info;
} OPENCONNECT_2.2;
OPENCONNECT_PRIVATE {
diff --git a/library.c b/library.c
index 7d59cd5..15cedd4 100644
--- a/library.c
+++ b/library.c
@@ -242,6 +242,11 @@ void openconnect_set_reqmtu(struct openconnect_info *vpninfo, int reqmtu)
vpninfo->reqmtu = reqmtu;
}
+const struct oc_ip_info *openconnect_get_ip_info(struct openconnect_info *vpninfo)
+{
+ return &vpninfo->ip_info;
+}
+
void openconnect_setup_csd(struct openconnect_info *vpninfo, uid_t uid, int silent, char *wrapper)
{
vpninfo->uid_csd = uid;
diff --git a/main.c b/main.c
index ce72622..53c5fae 100644
--- a/main.c
+++ b/main.c
@@ -487,6 +487,7 @@ int main(int argc, char **argv)
char *proxy = getenv("https_proxy");
int script_tun = 0;
char *vpnc_script = NULL, *ifname = NULL;
+ const struct oc_ip_info *ip_info;
int autoproxy = 0;
uid_t uid = getuid();
int opt;
@@ -906,11 +907,12 @@ int main(int argc, char **argv)
if (use_dtls && openconnect_setup_dtls(vpninfo, 60))
fprintf(stderr, _("Set up DTLS failed; using SSL instead\n"));
+ ip_info = openconnect_get_ip_info(vpninfo);
vpn_progress(vpninfo, PRG_INFO,
_("Connected %s as %s%s%s, using %s\n"), openconnect_get_ifname(vpninfo),
- vpninfo->vpn_addr?:"",
- (vpninfo->vpn_addr6 && vpninfo->vpn_addr) ? " + " : "",
- vpninfo->vpn_addr6 ? : "",
+ ip_info->addr?:"",
+ (ip_info->addr6 && ip_info->addr) ? " + " : "",
+ ip_info->addr6 ? : "",
(vpninfo->dtls_fd == -1) ?
(vpninfo->deflate ? "SSL + deflate" : "SSL")
: "DTLS");
diff --git a/openconnect-internal.h b/openconnect-internal.h
index db90ae6..c4cc0e6 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -111,11 +111,6 @@ struct keepalive_info {
time_t last_dpd;
};
-struct split_include {
- char *route;
- struct split_include *next;
-};
-
struct pin_cache {
struct pin_cache *next;
char *token;
@@ -266,20 +261,10 @@ struct openconnect_info {
int script_tun;
char *ifname;
- int actual_mtu;
int reqmtu, basemtu;
const char *banner;
- const char *vpn_addr;
- const char *vpn_netmask;
- const char *vpn_addr6;
- const char *vpn_netmask6;
- const char *vpn_dns[3];
- const char *vpn_nbns[3];
- const char *vpn_domain;
- const char *vpn_proxy_pac;
- struct split_include *split_dns;
- struct split_include *split_includes;
- struct split_include *split_excludes;
+
+ struct oc_ip_info ip_info;
int select_nfds;
fd_set select_rfds;
diff --git a/openconnect.h b/openconnect.h
index 7a55f1f..6941320 100644
--- a/openconnect.h
+++ b/openconnect.h
@@ -131,6 +131,27 @@ struct oc_auth_form {
struct oc_form_opt *opts;
};
+struct oc_split_include {
+ char *route;
+ struct oc_split_include *next;
+};
+
+struct oc_ip_info {
+ const char *addr;
+ const char *netmask;
+ const char *addr6;
+ const char *netmask6;
+ const char *dns[3];
+ const char *nbns[3];
+ const char *domain;
+ const char *proxy_pac;
+ int mtu;
+
+ struct oc_split_include *split_dns;
+ struct oc_split_include *split_includes;
+ struct oc_split_include *split_excludes;
+};
+
/****************************************************************************/
#define PRG_ERR 0
@@ -193,6 +214,7 @@ void openconnect_set_client_cert(struct openconnect_info *, char *cert, char *ss
void openconnect_set_server_cert_sha1(struct openconnect_info *, char *);
const char *openconnect_get_ifname(struct openconnect_info *);
void openconnect_set_reqmtu(struct openconnect_info *, int reqmtu);
+const struct oc_ip_info *openconnect_get_ip_info(struct openconnect_info *);
/* This is *not* yours and must not be destroyed with X509_free(). It
* will be valid when a cookie has been obtained successfully, and will
diff --git a/tun.c b/tun.c
index 2edb8d9..74c467b 100644
--- a/tun.c
+++ b/tun.c
@@ -91,7 +91,7 @@ static int set_tun_mtu(struct openconnect_info *vpninfo)
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, vpninfo->ifname, sizeof(ifr.ifr_name) - 1);
- ifr.ifr_mtu = vpninfo->actual_mtu;
+ ifr.ifr_mtu = vpninfo->ip_info.mtu;
if (ioctl(net_fd, SIOCSIFMTU, &ifr) < 0)
perror(_("SIOCSIFMTU"));
@@ -259,62 +259,62 @@ static void set_script_env(struct openconnect_info *vpninfo)
unsetenv("CISCO_SPLIT_INC");
unsetenv("CISCO_SPLIT_EXC");
- setenv_int("INTERNAL_IP4_MTU", vpninfo->actual_mtu);
+ setenv_int("INTERNAL_IP4_MTU", vpninfo->ip_info.mtu);
- if (vpninfo->vpn_addr) {
- setenv("INTERNAL_IP4_ADDRESS", vpninfo->vpn_addr, 1);
- if (vpninfo->vpn_netmask) {
+ if (vpninfo->ip_info.addr) {
+ setenv("INTERNAL_IP4_ADDRESS", vpninfo->ip_info.addr, 1);
+ if (vpninfo->ip_info.netmask) {
struct in_addr addr;
struct in_addr mask;
- if (inet_aton(vpninfo->vpn_addr, &addr) &&
- inet_aton(vpninfo->vpn_netmask, &mask)) {
+ if (inet_aton(vpninfo->ip_info.addr, &addr) &&
+ inet_aton(vpninfo->ip_info.netmask, &mask)) {
char *netaddr;
addr.s_addr &= mask.s_addr;
netaddr = inet_ntoa(addr);
setenv("INTERNAL_IP4_NETADDR", netaddr, 1);
- setenv("INTERNAL_IP4_NETMASK", vpninfo->vpn_netmask, 1);
+ setenv("INTERNAL_IP4_NETMASK", vpninfo->ip_info.netmask, 1);
setenv_int("INTERNAL_IP4_NETMASKLEN", netmasklen(mask));
}
}
}
- if (vpninfo->vpn_addr6) {
- setenv("INTERNAL_IP6_ADDRESS", vpninfo->vpn_addr6, 1);
- setenv("INTERNAL_IP6_NETMASK", vpninfo->vpn_netmask6, 1);
+ if (vpninfo->ip_info.addr6) {
+ setenv("INTERNAL_IP6_ADDRESS", vpninfo->ip_info.addr6, 1);
+ setenv("INTERNAL_IP6_NETMASK", vpninfo->ip_info.netmask6, 1);
}
- if (vpninfo->vpn_dns[0])
- setenv("INTERNAL_IP4_DNS", vpninfo->vpn_dns[0], 1);
+ if (vpninfo->ip_info.dns[0])
+ setenv("INTERNAL_IP4_DNS", vpninfo->ip_info.dns[0], 1);
else
unsetenv("INTERNAL_IP4_DNS");
- if (vpninfo->vpn_dns[1])
- appendenv("INTERNAL_IP4_DNS", vpninfo->vpn_dns[1]);
- if (vpninfo->vpn_dns[2])
- appendenv("INTERNAL_IP4_DNS", vpninfo->vpn_dns[2]);
+ if (vpninfo->ip_info.dns[1])
+ appendenv("INTERNAL_IP4_DNS", vpninfo->ip_info.dns[1]);
+ if (vpninfo->ip_info.dns[2])
+ appendenv("INTERNAL_IP4_DNS", vpninfo->ip_info.dns[2]);
- if (vpninfo->vpn_nbns[0])
- setenv("INTERNAL_IP4_NBNS", vpninfo->vpn_nbns[0], 1);
+ if (vpninfo->ip_info.nbns[0])
+ setenv("INTERNAL_IP4_NBNS", vpninfo->ip_info.nbns[0], 1);
else
unsetenv("INTERNAL_IP4_NBNS");
- if (vpninfo->vpn_nbns[1])
- appendenv("INTERNAL_IP4_NBNS", vpninfo->vpn_nbns[1]);
- if (vpninfo->vpn_nbns[2])
- appendenv("INTERNAL_IP4_NBNS", vpninfo->vpn_nbns[2]);
+ if (vpninfo->ip_info.nbns[1])
+ appendenv("INTERNAL_IP4_NBNS", vpninfo->ip_info.nbns[1]);
+ if (vpninfo->ip_info.nbns[2])
+ appendenv("INTERNAL_IP4_NBNS", vpninfo->ip_info.nbns[2]);
- if (vpninfo->vpn_domain)
- setenv("CISCO_DEF_DOMAIN", vpninfo->vpn_domain, 1);
+ if (vpninfo->ip_info.domain)
+ setenv("CISCO_DEF_DOMAIN", vpninfo->ip_info.domain, 1);
else
unsetenv("CISCO_DEF_DOMAIN");
- if (vpninfo->vpn_proxy_pac)
- setenv("CISCO_PROXY_PAC", vpninfo->vpn_proxy_pac, 1);
+ if (vpninfo->ip_info.proxy_pac)
+ setenv("CISCO_PROXY_PAC", vpninfo->ip_info.proxy_pac, 1);
- if (vpninfo->split_dns) {
+ if (vpninfo->ip_info.split_dns) {
char *list;
int len = 0;
- struct split_include *dns = vpninfo->split_dns;
+ struct oc_split_include *dns = vpninfo->ip_info.split_dns;
while (dns) {
len += strlen(dns->route) + 1;
@@ -324,7 +324,7 @@ static void set_script_env(struct openconnect_info *vpninfo)
if (list) {
char *p = list;
- dns = vpninfo->split_dns;
+ dns = vpninfo->ip_info.split_dns;
while (1) {
strcpy(p, dns->route);
p += strlen(p);
@@ -337,8 +337,8 @@ static void set_script_env(struct openconnect_info *vpninfo)
free(list);
}
}
- if (vpninfo->split_includes) {
- struct split_include *this = vpninfo->split_includes;
+ if (vpninfo->ip_info.split_includes) {
+ struct oc_split_include *this = vpninfo->ip_info.split_includes;
int nr_split_includes = 0;
int nr_v6_split_includes = 0;
@@ -353,8 +353,8 @@ static void set_script_env(struct openconnect_info *vpninfo)
if (nr_v6_split_includes)
setenv_int("CISCO_IPV6_SPLIT_INC", nr_v6_split_includes);
}
- if (vpninfo->split_excludes) {
- struct split_include *this = vpninfo->split_excludes;
+ if (vpninfo->ip_info.split_excludes) {
+ struct oc_split_include *this = vpninfo->ip_info.split_excludes;
int nr_split_excludes = 0;
int nr_v6_split_excludes = 0;
@@ -555,7 +555,7 @@ static int os_setup_tun(struct openconnect_info *vpninfo)
return -EIO;
}
- if (vpninfo->vpn_addr6) {
+ if (vpninfo->ip_info.addr6) {
vpninfo->ip6_fd = link_proto(unit_nr, "/dev/udp6", IFF_IPV6);
if (vpninfo->ip6_fd < 0) {
close(tun_fd);
@@ -719,7 +719,7 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
if (FD_ISSET(vpninfo->tun_fd, &vpninfo->select_rfds)) {
while (1) {
- int len = vpninfo->actual_mtu;
+ int len = vpninfo->ip_info.mtu;
if (!out_pkt) {
out_pkt = malloc(sizeof(struct pkt) + len);
--
1.7.9.5
More information about the openconnect-devel
mailing list