mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 08:46:58 +08:00
Added support for LZ4 compression
This commit is contained in:
20
configure.ac
20
configure.ac
@@ -358,6 +358,25 @@ LIBS="$oldlibs"
|
|||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(LOCAL_HTTP_PARSER, test "x$with_local_http_parser" != xno)
|
AM_CONDITIONAL(LOCAL_HTTP_PARSER, test "x$with_local_http_parser" != xno)
|
||||||
|
|
||||||
|
dnl LZ4
|
||||||
|
AC_ARG_WITH(lz4,
|
||||||
|
AS_HELP_STRING([--without-lz4], [disable support for LZ4 compression]),
|
||||||
|
test_for_lz4=$withval,
|
||||||
|
test_for_lz4=yes)
|
||||||
|
|
||||||
|
enable_lz4=no
|
||||||
|
if test "$test_for_lz4" = yes;then
|
||||||
|
PKG_CHECK_MODULES([LIBLZ4], [liblz4], [
|
||||||
|
enable_lz4=yes
|
||||||
|
AC_DEFINE([HAVE_LZ4], [], [LZ4 was found])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_WARN([[
|
||||||
|
***
|
||||||
|
*** lz4 not found. Will disable compression support.
|
||||||
|
*** ]])
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl needed in the included PCL
|
dnl needed in the included PCL
|
||||||
AC_C_VOLATILE
|
AC_C_VOLATILE
|
||||||
@@ -453,6 +472,7 @@ AC_MSG_NOTICE([
|
|||||||
Experimental options:
|
Experimental options:
|
||||||
seccomp: ${seccomp_enabled}
|
seccomp: ${seccomp_enabled}
|
||||||
Linux namespaces: ${linux_ns_enabled}
|
Linux namespaces: ${linux_ns_enabled}
|
||||||
|
LZ4 compression: ${enable_lz4}
|
||||||
Anyconnect compat: ${anyconnect_enabled}
|
Anyconnect compat: ${anyconnect_enabled}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ SUBDIRS =
|
|||||||
AM_CPPFLAGS = -I$(srcdir)/../gl/ -I$(builddir)/../gl/ \
|
AM_CPPFLAGS = -I$(srcdir)/../gl/ -I$(builddir)/../gl/ \
|
||||||
-I$(srcdir)/ -I$(builddir)/../ $(LIBOPTS_CFLAGS) \
|
-I$(srcdir)/ -I$(builddir)/../ $(LIBOPTS_CFLAGS) \
|
||||||
$(LIBGNUTLS_CFLAGS) \
|
$(LIBGNUTLS_CFLAGS) \
|
||||||
$(LIBPROTOBUF_C_CFLAGS) \
|
$(LIBPROTOBUF_C_CFLAGS) $(LIBLZ4_CFLAGS) \
|
||||||
$(LIBNL3_CFLAGS) $(LIBREADLINE_CFLAGS) \
|
$(LIBNL3_CFLAGS) $(LIBREADLINE_CFLAGS) \
|
||||||
$(LIBTALLOC_CFLAGS) $(LIBDBUS_CFLAGS)
|
$(LIBTALLOC_CFLAGS) $(LIBDBUS_CFLAGS)
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ ocserv_LDADD = ../gl/libgnu.a $(NEEDED_LIBOPTS) libcmd-ocserv.a
|
|||||||
ocserv_LDADD += $(LIBGNUTLS_LIBS) $(PAM_LIBS) $(LIBUTIL) \
|
ocserv_LDADD += $(LIBGNUTLS_LIBS) $(PAM_LIBS) $(LIBUTIL) \
|
||||||
$(LIBSECCOMP) $(LIBWRAP) $(LIBCRYPT) $(NEEDED_HTTP_PARSER_LIBS) \
|
$(LIBSECCOMP) $(LIBWRAP) $(LIBCRYPT) $(NEEDED_HTTP_PARSER_LIBS) \
|
||||||
$(LIBPROTOBUF_C_LIBS) $(LIBSYSTEMD_DAEMON) $(LIBTALLOC_LIBS) \
|
$(LIBPROTOBUF_C_LIBS) $(LIBSYSTEMD_DAEMON) $(LIBTALLOC_LIBS) \
|
||||||
$(FREERADIUS_CLIENT_LIBS)
|
$(FREERADIUS_CLIENT_LIBS) $(LIBLZ4_LIBS)
|
||||||
|
|
||||||
|
|
||||||
if PCL
|
if PCL
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ typedef enum {
|
|||||||
SOCK_TYPE_UNIX
|
SOCK_TYPE_UNIX
|
||||||
} sock_type_t;
|
} sock_type_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OC_COMP_NULL = 0,
|
||||||
|
OC_COMP_LZ4,
|
||||||
|
OC_COMP_LZS,
|
||||||
|
} comp_type_t;
|
||||||
|
|
||||||
#define DEBUG_BASIC 1
|
#define DEBUG_BASIC 1
|
||||||
#define DEBUG_HTTP 2
|
#define DEBUG_HTTP 2
|
||||||
#define DEBUG_TRANSFERRED 5
|
#define DEBUG_TRANSFERRED 5
|
||||||
|
|||||||
210
src/worker-vpn.c
210
src/worker-vpn.c
@@ -46,6 +46,9 @@
|
|||||||
#include <c-strcase.h>
|
#include <c-strcase.h>
|
||||||
#include <c-ctype.h>
|
#include <c-ctype.h>
|
||||||
#include <worker-bandwidth.h>
|
#include <worker-bandwidth.h>
|
||||||
|
#ifdef HAVE_LZ4
|
||||||
|
# include <lz4.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include "ipc.pb-c.h"
|
#include "ipc.pb-c.h"
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
/* The number of DPD packets a client skips before he's kicked */
|
/* The number of DPD packets a client skips before he's kicked */
|
||||||
#define DPD_TRIES 2
|
#define DPD_TRIES 2
|
||||||
#define DPD_MAX_TRIES 3
|
#define DPD_MAX_TRIES 3
|
||||||
|
#define MIN_COMPRESSED_SIZE 40
|
||||||
|
|
||||||
/* HTTP requests prior to disconnection */
|
/* HTTP requests prior to disconnection */
|
||||||
#define MAX_HTTP_REQUESTS 16
|
#define MAX_HTTP_REQUESTS 16
|
||||||
@@ -181,6 +185,34 @@ int url_cb(http_parser * parser, const char *at, size_t length)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LZ4
|
||||||
|
static
|
||||||
|
int lz4_decompress(void *dst, int dstlen, const void *src, int srclen)
|
||||||
|
{
|
||||||
|
return LZ4_decompress_safe(src, dst, srclen, dstlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int lz4_compress(void *dst, int dstlen, const void *src, int srclen)
|
||||||
|
{
|
||||||
|
if (dstlen < LZ4_compressBound(srclen))
|
||||||
|
return -1;
|
||||||
|
return LZ4_compress(src, dst, srclen);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct compression_method_st comp_methods[] = {
|
||||||
|
#ifdef HAVE_LZ4
|
||||||
|
{
|
||||||
|
.id = OC_COMP_LZ4,
|
||||||
|
.name = "oc-lz4",
|
||||||
|
.decompress = lz4_decompress,
|
||||||
|
.compress = lz4_compress,
|
||||||
|
.server_prio = 90,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#define CS_AES128_GCM "OC-DTLS1_2-AES128-GCM"
|
#define CS_AES128_GCM "OC-DTLS1_2-AES128-GCM"
|
||||||
#define CS_AES256_GCM "OC-DTLS1_2-AES256-GCM"
|
#define CS_AES256_GCM "OC-DTLS1_2-AES256-GCM"
|
||||||
|
|
||||||
@@ -234,6 +266,7 @@ static void value_check(struct worker_st *ws, struct http_req_st *req)
|
|||||||
char *token, *value;
|
char *token, *value;
|
||||||
char *str, *p;
|
char *str, *p;
|
||||||
const dtls_ciphersuite_st *cand = NULL;
|
const dtls_ciphersuite_st *cand = NULL;
|
||||||
|
const compression_method_st *comp_cand = NULL;
|
||||||
gnutls_cipher_algorithm_t want_cipher;
|
gnutls_cipher_algorithm_t want_cipher;
|
||||||
gnutls_mac_algorithm_t want_mac;
|
gnutls_mac_algorithm_t want_mac;
|
||||||
|
|
||||||
@@ -337,6 +370,52 @@ static void value_check(struct worker_st *ws, struct http_req_st *req)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HEADER_DTLS_ENCODING:
|
||||||
|
ws->dtls_selected_comp = NULL;
|
||||||
|
|
||||||
|
str = (char *)value;
|
||||||
|
while ((token = strtok(str, ",")) != NULL) {
|
||||||
|
for (i = 0;
|
||||||
|
i < sizeof(comp_methods) / sizeof(comp_methods[0]);
|
||||||
|
i++) {
|
||||||
|
if (strcasecmp(token, comp_methods[i].name) == 0) {
|
||||||
|
if (comp_cand == NULL ||
|
||||||
|
comp_cand->server_prio <
|
||||||
|
comp_methods[i].server_prio) {
|
||||||
|
comp_cand =
|
||||||
|
&comp_methods[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str = NULL;
|
||||||
|
}
|
||||||
|
ws->dtls_selected_comp = comp_cand;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HEADER_CSTP_ENCODING:
|
||||||
|
ws->cstp_selected_comp = NULL;
|
||||||
|
|
||||||
|
str = (char *)value;
|
||||||
|
while ((token = strtok(str, ",")) != NULL) {
|
||||||
|
for (i = 0;
|
||||||
|
i < sizeof(comp_methods) / sizeof(comp_methods[0]);
|
||||||
|
i++) {
|
||||||
|
if (strcasecmp(token, comp_methods[i].name) == 0) {
|
||||||
|
if (comp_cand == NULL ||
|
||||||
|
comp_cand->server_prio <
|
||||||
|
comp_methods[i].server_prio) {
|
||||||
|
comp_cand =
|
||||||
|
&comp_methods[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str = NULL;
|
||||||
|
}
|
||||||
|
ws->cstp_selected_comp = comp_cand;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case HEADER_CSTP_BASE_MTU:
|
case HEADER_CSTP_BASE_MTU:
|
||||||
req->base_mtu = atoi((char *)value);
|
req->base_mtu = atoi((char *)value);
|
||||||
break;
|
break;
|
||||||
@@ -479,6 +558,14 @@ static void header_check(struct http_req_st *req)
|
|||||||
strncmp((char *)req->header.data, STR_HDR_USER_AGENT,
|
strncmp((char *)req->header.data, STR_HDR_USER_AGENT,
|
||||||
req->header.length) == 0) {
|
req->header.length) == 0) {
|
||||||
req->next_header = HEADER_USER_AGENT;
|
req->next_header = HEADER_USER_AGENT;
|
||||||
|
} else if (req->header.length == sizeof(STR_HDR_CSTP_ENCODING) - 1 &&
|
||||||
|
strncmp((char *)req->header.data, STR_HDR_CSTP_ENCODING,
|
||||||
|
req->header.length) == 0) {
|
||||||
|
req->next_header = HEADER_CSTP_ENCODING;
|
||||||
|
} else if (req->header.length == sizeof(STR_HDR_DTLS_ENCODING) - 1 &&
|
||||||
|
strncmp((char *)req->header.data, STR_HDR_DTLS_ENCODING,
|
||||||
|
req->header.length) == 0) {
|
||||||
|
req->next_header = HEADER_DTLS_ENCODING;
|
||||||
} else if (req->header.length == sizeof(STR_HDR_FULL_IPV6) - 1 &&
|
} else if (req->header.length == sizeof(STR_HDR_FULL_IPV6) - 1 &&
|
||||||
strncmp((char *)req->header.data, STR_HDR_FULL_IPV6,
|
strncmp((char *)req->header.data, STR_HDR_FULL_IPV6,
|
||||||
req->header.length) == 0) {
|
req->header.length) == 0) {
|
||||||
@@ -1388,7 +1475,7 @@ static int tls_mainloop(struct worker_st *ws, struct timespec *tnow)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == AC_PKT_DATA && ws->udp_state == UP_ACTIVE) {
|
if ((ret == AC_PKT_DATA || ret == AC_PKT_COMPRESSED) && ws->udp_state == UP_ACTIVE) {
|
||||||
/* client switched to TLS for some reason */
|
/* client switched to TLS for some reason */
|
||||||
if (tnow->tv_sec - ws->udp_recv_time >
|
if (tnow->tv_sec - ws->udp_recv_time >
|
||||||
UDP_SWITCH_TIME)
|
UDP_SWITCH_TIME)
|
||||||
@@ -1431,6 +1518,10 @@ static int tun_mainloop(struct worker_st *ws, struct timespec *tnow)
|
|||||||
{
|
{
|
||||||
int ret, l, e;
|
int ret, l, e;
|
||||||
unsigned tls_retry;
|
unsigned tls_retry;
|
||||||
|
int dtls_type = AC_PKT_DATA;
|
||||||
|
int cstp_type = AC_PKT_DATA;
|
||||||
|
gnutls_datum_t dtls_to_send;
|
||||||
|
gnutls_datum_t cstp_to_send;
|
||||||
|
|
||||||
l = read(ws->tun_fd, ws->buffer + 8, ws->conn_mtu);
|
l = read(ws->tun_fd, ws->buffer + 8, ws->conn_mtu);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
@@ -1445,23 +1536,64 @@ static int tun_mainloop(struct worker_st *ws, struct timespec *tnow)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l == 0) {
|
if (l == 0) {
|
||||||
oclog(ws, LOG_INFO, "TUN device returned zero");
|
oclog(ws, LOG_INFO, "TUN device returned zero");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dtls_to_send.data = ws->buffer;
|
||||||
|
dtls_to_send.size = l;
|
||||||
|
|
||||||
|
cstp_to_send.data = ws->buffer;
|
||||||
|
cstp_to_send.size = l;
|
||||||
|
|
||||||
|
if (ws->udp_state == UP_ACTIVE && ws->dtls_selected_comp != NULL && l > MIN_COMPRESSED_SIZE) {
|
||||||
|
/* otherwise don't compress */
|
||||||
|
ret = ws->dtls_selected_comp->compress(ws->decomp+8, sizeof(ws->decomp)-8, ws->buffer, l);
|
||||||
|
if (ret <= 0) {
|
||||||
|
oclog(ws, LOG_ERR, "error in %s compression %d\n", ws->dtls_selected_comp->name, ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dtls_to_send.data = ws->decomp;
|
||||||
|
dtls_to_send.size = ret;
|
||||||
|
dtls_type = AC_PKT_COMPRESSED;
|
||||||
|
|
||||||
|
if (ws->cstp_selected_comp) {
|
||||||
|
if (ws->cstp_selected_comp->id == ws->dtls_selected_comp->id) {
|
||||||
|
cstp_to_send.data = ws->decomp;
|
||||||
|
cstp_to_send.size = ret;
|
||||||
|
cstp_type = AC_PKT_COMPRESSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ws->cstp_selected_comp != NULL && l > MIN_COMPRESSED_SIZE) {
|
||||||
|
/* otherwise don't compress */
|
||||||
|
ret = ws->cstp_selected_comp->compress(ws->decomp+8, sizeof(ws->decomp)-8, ws->buffer, l);
|
||||||
|
if (ret <= 0) {
|
||||||
|
oclog(ws, LOG_ERR, "error in %s compression %d\n", ws->dtls_selected_comp->name, ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cstp_to_send.data = ws->decomp;
|
||||||
|
cstp_to_send.size = ret;
|
||||||
|
cstp_type = AC_PKT_COMPRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
/* only transmit if allowed */
|
/* only transmit if allowed */
|
||||||
if (bandwidth_update(&ws->b_tx, l, ws->conn_mtu, tnow)
|
if (bandwidth_update(&ws->b_tx, dtls_to_send.size, ws->conn_mtu, tnow)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
tls_retry = 0;
|
tls_retry = 0;
|
||||||
|
|
||||||
ws->tun_bytes_out += l;
|
|
||||||
oclog(ws, LOG_TRANSFER_DEBUG, "sending %d byte(s)\n", l);
|
oclog(ws, LOG_TRANSFER_DEBUG, "sending %d byte(s)\n", l);
|
||||||
|
|
||||||
if (ws->udp_state == UP_ACTIVE) {
|
if (ws->udp_state == UP_ACTIVE) {
|
||||||
|
|
||||||
ws->buffer[7] = AC_PKT_DATA;
|
ws->tun_bytes_out += dtls_to_send.size;
|
||||||
|
|
||||||
ret = dtls_send(ws, ws->buffer + 7, l + 1);
|
dtls_to_send.data[7] = dtls_type;
|
||||||
|
ret = dtls_send(ws, dtls_to_send.data + 7, dtls_to_send.size + 1);
|
||||||
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
GNUTLS_FATAL_ERR_CMD(ret, exit_worker(ws));
|
||||||
|
|
||||||
if (ret == GNUTLS_E_LARGE_PACKET) {
|
if (ret == GNUTLS_E_LARGE_PACKET) {
|
||||||
@@ -1477,16 +1609,18 @@ static int tun_mainloop(struct worker_st *ws, struct timespec *tnow)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ws->udp_state != UP_ACTIVE || tls_retry != 0) {
|
if (ws->udp_state != UP_ACTIVE || tls_retry != 0) {
|
||||||
ws->buffer[0] = 'S';
|
cstp_to_send.data[0] = 'S';
|
||||||
ws->buffer[1] = 'T';
|
cstp_to_send.data[1] = 'T';
|
||||||
ws->buffer[2] = 'F';
|
cstp_to_send.data[2] = 'F';
|
||||||
ws->buffer[3] = 1;
|
cstp_to_send.data[3] = 1;
|
||||||
ws->buffer[4] = l >> 8;
|
cstp_to_send.data[4] = cstp_to_send.size >> 8;
|
||||||
ws->buffer[5] = l & 0xff;
|
cstp_to_send.data[5] = cstp_to_send.size & 0xff;
|
||||||
ws->buffer[6] = AC_PKT_DATA;
|
cstp_to_send.data[6] = cstp_type;
|
||||||
ws->buffer[7] = 0;
|
cstp_to_send.data[7] = 0;
|
||||||
|
|
||||||
ret = cstp_send(ws, ws->buffer, l + 8);
|
ws->tun_bytes_out += cstp_to_send.size;
|
||||||
|
|
||||||
|
ret = cstp_send(ws, cstp_to_send.data, cstp_to_send.size + 8);
|
||||||
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
|
FATAL_ERR_CMD(ws, ret, exit_worker(ws));
|
||||||
}
|
}
|
||||||
ws->last_nc_msg = tnow->tv_sec;
|
ws->last_nc_msg = tnow->tv_sec;
|
||||||
@@ -2063,6 +2197,23 @@ static int connect_handler(worker_st * ws)
|
|||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send any compression methods */
|
||||||
|
if (ws->dtls_selected_comp) {
|
||||||
|
oclog(ws, LOG_DEBUG, "selected DTLS compression method %s\n", ws->dtls_selected_comp->name);
|
||||||
|
ret =
|
||||||
|
cstp_printf(ws, "X-DTLS-Content-Encoding: %s\r\n",
|
||||||
|
ws->dtls_selected_comp->name);
|
||||||
|
SEND_ERR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ws->cstp_selected_comp) {
|
||||||
|
oclog(ws, LOG_DEBUG, "selected CSTP compression method %s\n", ws->cstp_selected_comp->name);
|
||||||
|
ret =
|
||||||
|
cstp_printf(ws, "X-CSTP-Content-Encoding: %s\r\n",
|
||||||
|
ws->cstp_selected_comp->name);
|
||||||
|
SEND_ERR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
ret = cstp_puts(ws, "\r\n");
|
ret = cstp_puts(ws, "\r\n");
|
||||||
SEND_ERR(ret);
|
SEND_ERR(ret);
|
||||||
|
|
||||||
@@ -2157,16 +2308,13 @@ static int connect_handler(worker_st * ws)
|
|||||||
ret = tun_mainloop(ws, &tnow);
|
ret = tun_mainloop(ws, &tnow);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read pending data from TCP channel */
|
/* read pending data from TCP channel */
|
||||||
if (FD_ISSET(ws->conn_fd, &rfds) || tls_pending != 0) {
|
if (FD_ISSET(ws->conn_fd, &rfds) || tls_pending != 0) {
|
||||||
|
|
||||||
ret = tls_mainloop(ws, &tnow);
|
ret = tls_mainloop(ws, &tnow);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read data from UDP channel */
|
/* read data from UDP channel */
|
||||||
@@ -2214,6 +2362,8 @@ static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interfac
|
|||||||
uint8_t head, uint8_t * buf, size_t buf_size, time_t now)
|
uint8_t head, uint8_t * buf, size_t buf_size, time_t now)
|
||||||
{
|
{
|
||||||
int ret, e;
|
int ret, e;
|
||||||
|
uint8_t *plain = buf;
|
||||||
|
ssize_t plain_size = buf_size;
|
||||||
|
|
||||||
switch (head) {
|
switch (head) {
|
||||||
case AC_PKT_DPD_RESP:
|
case AC_PKT_DPD_RESP:
|
||||||
@@ -2260,10 +2410,34 @@ static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interfac
|
|||||||
oclog(ws, LOG_DEBUG, "received BYE packet; exiting");
|
oclog(ws, LOG_DEBUG, "received BYE packet; exiting");
|
||||||
exit_worker(ws);
|
exit_worker(ws);
|
||||||
break;
|
break;
|
||||||
|
case AC_PKT_COMPRESSED:
|
||||||
|
/* decompress */
|
||||||
|
if (ws->session == ts) { /* CSTP */
|
||||||
|
if (ws->cstp_selected_comp == NULL) {
|
||||||
|
oclog(ws, LOG_ERR, "received compression data but no compression was negotiated");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
plain_size = ws->cstp_selected_comp->decompress(ws->decomp, sizeof(ws->decomp), buf, buf_size);
|
||||||
|
} else { /* DTLS */
|
||||||
|
if (ws->dtls_selected_comp == NULL) {
|
||||||
|
oclog(ws, LOG_ERR, "received compression data but no compression was negotiated");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
plain_size = ws->dtls_selected_comp->decompress(ws->decomp, sizeof(ws->decomp), buf, buf_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plain_size <= 0) {
|
||||||
|
oclog(ws, LOG_ERR, "decompression error %d", (int)plain_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
plain = ws->decomp;
|
||||||
|
/* fall through */
|
||||||
case AC_PKT_DATA:
|
case AC_PKT_DATA:
|
||||||
oclog(ws, LOG_TRANSFER_DEBUG, "writing %d byte(s) to TUN",
|
oclog(ws, LOG_TRANSFER_DEBUG, "writing %d byte(s) to TUN",
|
||||||
(int)buf_size);
|
(int)buf_size);
|
||||||
ret = force_write(ws->tun_fd, buf, buf_size);
|
ret = force_write(ws->tun_fd, plain, plain_size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
e = errno;
|
e = errno;
|
||||||
oclog(ws, LOG_ERR, "could not write data to tun: %s",
|
oclog(ws, LOG_ERR, "could not write data to tun: %s",
|
||||||
|
|||||||
20
src/worker.h
20
src/worker.h
@@ -47,6 +47,8 @@ typedef enum {
|
|||||||
|
|
||||||
#define STR_HDR_COOKIE "Cookie"
|
#define STR_HDR_COOKIE "Cookie"
|
||||||
#define STR_HDR_USER_AGENT "User-Agent"
|
#define STR_HDR_USER_AGENT "User-Agent"
|
||||||
|
#define STR_HDR_CSTP_ENCODING "X-CSTP-Accept-Encoding"
|
||||||
|
#define STR_HDR_DTLS_ENCODING "X-DTLS-Accept-Encoding"
|
||||||
#define STR_HDR_CONNECTION "Connection"
|
#define STR_HDR_CONNECTION "Connection"
|
||||||
#define STR_HDR_MS "X-DTLS-Master-Secret"
|
#define STR_HDR_MS "X-DTLS-Master-Secret"
|
||||||
#define STR_HDR_CS "X-DTLS-CipherSuite"
|
#define STR_HDR_CS "X-DTLS-CipherSuite"
|
||||||
@@ -67,6 +69,8 @@ enum {
|
|||||||
HEADER_CONNECTION,
|
HEADER_CONNECTION,
|
||||||
HEADER_FULL_IPV6,
|
HEADER_FULL_IPV6,
|
||||||
HEADER_USER_AGENT,
|
HEADER_USER_AGENT,
|
||||||
|
HEADER_CSTP_ENCODING,
|
||||||
|
HEADER_DTLS_ENCODING
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -89,6 +93,17 @@ enum {
|
|||||||
AGENT_OPENCONNECT
|
AGENT_OPENCONNECT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef int (*decompress_fn)(void* dst, int maxDstSize, const void* src, int src_size);
|
||||||
|
typedef int (*compress_fn)(void* dst, int dst_size, const void* src, int src_size);
|
||||||
|
|
||||||
|
typedef struct compression_method_st {
|
||||||
|
comp_type_t id;
|
||||||
|
const char *name;
|
||||||
|
decompress_fn decompress;
|
||||||
|
compress_fn compress;
|
||||||
|
unsigned server_prio; /* the highest the more we want to negotiate that */
|
||||||
|
} compression_method_st;
|
||||||
|
|
||||||
typedef struct dtls_ciphersuite_st {
|
typedef struct dtls_ciphersuite_st {
|
||||||
const char* oc_name;
|
const char* oc_name;
|
||||||
const char* gnutls_name; /* the gnutls priority string to set */
|
const char* gnutls_name; /* the gnutls priority string to set */
|
||||||
@@ -140,6 +155,9 @@ typedef struct worker_st {
|
|||||||
gnutls_session_t session;
|
gnutls_session_t session;
|
||||||
gnutls_session_t dtls_session;
|
gnutls_session_t dtls_session;
|
||||||
|
|
||||||
|
const compression_method_st *dtls_selected_comp;
|
||||||
|
const compression_method_st *cstp_selected_comp;
|
||||||
|
|
||||||
struct http_req_st req;
|
struct http_req_st req;
|
||||||
|
|
||||||
/* inique session identifier */
|
/* inique session identifier */
|
||||||
@@ -204,6 +222,8 @@ typedef struct worker_st {
|
|||||||
|
|
||||||
/* Buffer used by worker */
|
/* Buffer used by worker */
|
||||||
uint8_t buffer[16*1024];
|
uint8_t buffer[16*1024];
|
||||||
|
/* Buffer used for decompression */
|
||||||
|
uint8_t decomp[16*1024];
|
||||||
unsigned buffer_size;
|
unsigned buffer_size;
|
||||||
|
|
||||||
/* the following are set only if authentication is complete */
|
/* the following are set only if authentication is complete */
|
||||||
|
|||||||
Reference in New Issue
Block a user