mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 16:57:00 +08:00
Revert "check sockets for writability and use that information to discard packets rather than block."
This reverts commit 449302afe2.
This commit is contained in:
131
src/worker-vpn.c
131
src/worker-vpn.c
@@ -73,17 +73,11 @@
|
||||
#define CSTP_DTLS_OVERHEAD 1
|
||||
#define CSTP_OVERHEAD 8
|
||||
|
||||
typedef struct {
|
||||
unsigned dtls_writable;
|
||||
unsigned tls_writable;
|
||||
unsigned tun_writable;
|
||||
} fd_status_st;
|
||||
|
||||
static int terminate = 0;
|
||||
static int parse_cstp_data(struct worker_st *ws, uint8_t * buf, size_t buf_size,
|
||||
time_t, fd_status_st *);
|
||||
time_t);
|
||||
static int parse_dtls_data(struct worker_st *ws, uint8_t * buf, size_t buf_size,
|
||||
time_t, fd_status_st *);
|
||||
time_t);
|
||||
|
||||
static void handle_alarm(int signo)
|
||||
{
|
||||
@@ -297,8 +291,8 @@ static void value_check(struct worker_st *ws, struct http_req_st *req)
|
||||
i++) {
|
||||
if (strcmp(token, ciphersuites[i].oc_name) == 0) {
|
||||
if (req->selected_ciphersuite == NULL ||
|
||||
req->
|
||||
selected_ciphersuite->server_prio <
|
||||
req->selected_ciphersuite->
|
||||
server_prio <
|
||||
ciphersuites[i].server_prio) {
|
||||
req->selected_ciphersuite =
|
||||
&ciphersuites[i];
|
||||
@@ -541,8 +535,8 @@ static int setup_dtls_connection(struct worker_st *ws)
|
||||
|
||||
ret =
|
||||
gnutls_priority_set_direct(session,
|
||||
ws->req.
|
||||
selected_ciphersuite->gnutls_name, NULL);
|
||||
ws->req.selected_ciphersuite->
|
||||
gnutls_name, NULL);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_ERR, "could not set TLS priority: %s",
|
||||
gnutls_strerror(ret));
|
||||
@@ -550,14 +544,13 @@ static int setup_dtls_connection(struct worker_st *ws)
|
||||
}
|
||||
|
||||
ret = gnutls_session_set_premaster(session, GNUTLS_SERVER,
|
||||
ws->req.
|
||||
selected_ciphersuite->gnutls_version,
|
||||
GNUTLS_KX_RSA,
|
||||
ws->req.
|
||||
selected_ciphersuite->gnutls_cipher,
|
||||
ws->req.
|
||||
selected_ciphersuite->gnutls_mac,
|
||||
GNUTLS_COMP_NULL, &master, &sid);
|
||||
ws->req.selected_ciphersuite->
|
||||
gnutls_version, GNUTLS_KX_RSA,
|
||||
ws->req.selected_ciphersuite->
|
||||
gnutls_cipher,
|
||||
ws->req.selected_ciphersuite->
|
||||
gnutls_mac, GNUTLS_COMP_NULL,
|
||||
&master, &sid);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_ERR, "could not set TLS premaster: %s",
|
||||
gnutls_strerror(ret));
|
||||
@@ -1031,8 +1024,7 @@ static void set_net_priority(worker_st * ws, int fd, int priority)
|
||||
|
||||
#define SEND_ERR(x) if (x<0) goto send_error
|
||||
|
||||
static int dtls_mainloop(worker_st * ws, struct timespec *tnow,
|
||||
fd_status_st * fds)
|
||||
static int dtls_mainloop(worker_st * ws, struct timespec *tnow)
|
||||
{
|
||||
int ret, l;
|
||||
|
||||
@@ -1064,8 +1056,8 @@ static int dtls_mainloop(worker_st * ws, struct timespec *tnow,
|
||||
|
||||
do {
|
||||
ret = gnutls_handshake(ws->dtls_session);
|
||||
} while (ret == GNUTLS_E_AGAIN ||
|
||||
ret == GNUTLS_E_INTERRUPTED);
|
||||
} while (ret == GNUTLS_E_AGAIN
|
||||
|| ret == GNUTLS_E_INTERRUPTED);
|
||||
|
||||
GNUTLS_FATAL_ERR(ret);
|
||||
oclog(ws, LOG_INFO, "DTLS rehandshake completed");
|
||||
@@ -1079,7 +1071,7 @@ static int dtls_mainloop(worker_st * ws, struct timespec *tnow,
|
||||
(&ws->b_rx, l - 1, ws->conn_mtu, tnow) != 0) {
|
||||
ret =
|
||||
parse_dtls_data(ws, ws->buffer, l,
|
||||
tnow->tv_sec, fds);
|
||||
tnow->tv_sec);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_INFO,
|
||||
"error parsing CSTP data");
|
||||
@@ -1153,8 +1145,7 @@ static int dtls_mainloop(worker_st * ws, struct timespec *tnow,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tls_mainloop(struct worker_st *ws, struct timespec *tnow,
|
||||
fd_status_st * fds)
|
||||
static int tls_mainloop(struct worker_st *ws, struct timespec *tnow)
|
||||
{
|
||||
int ret, l;
|
||||
|
||||
@@ -1169,10 +1160,7 @@ static int tls_mainloop(struct worker_st *ws, struct timespec *tnow,
|
||||
oclog(ws, LOG_TRANSFER_DEBUG, "received %d byte(s) (TLS)", l);
|
||||
|
||||
if (bandwidth_update(&ws->b_rx, l - 8, ws->conn_mtu, tnow) != 0) {
|
||||
|
||||
ret =
|
||||
parse_cstp_data(ws, ws->buffer, l, tnow->tv_sec,
|
||||
fds);
|
||||
ret = parse_cstp_data(ws, ws->buffer, l, tnow->tv_sec);
|
||||
if (ret < 0) {
|
||||
oclog(ws, LOG_ERR, "error parsing CSTP data");
|
||||
return ret;
|
||||
@@ -1211,8 +1199,7 @@ static int tls_mainloop(struct worker_st *ws, struct timespec *tnow,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tun_mainloop(struct worker_st *ws, struct timespec *tnow,
|
||||
fd_status_st * fds)
|
||||
static int tun_mainloop(struct worker_st *ws, struct timespec *tnow)
|
||||
{
|
||||
int ret, l, e;
|
||||
unsigned tls_retry;
|
||||
@@ -1239,10 +1226,10 @@ static int tun_mainloop(struct worker_st *ws, struct timespec *tnow,
|
||||
/* only transmit if allowed */
|
||||
if (bandwidth_update(&ws->b_tx, l, ws->conn_mtu, tnow)
|
||||
!= 0) {
|
||||
tls_retry = 1;
|
||||
tls_retry = 0;
|
||||
oclog(ws, LOG_TRANSFER_DEBUG, "sending %d byte(s)\n", l);
|
||||
if (ws->udp_state == UP_ACTIVE) {
|
||||
|
||||
if (fds->dtls_writable && ws->udp_state == UP_ACTIVE) {
|
||||
ws->buffer[7] = AC_PKT_DATA;
|
||||
|
||||
ret = dtls_send_data(ws->dtls_session, ws->buffer + 7, l, ws->conn_mtu+1);
|
||||
@@ -1253,16 +1240,14 @@ static int tun_mainloop(struct worker_st *ws, struct timespec *tnow,
|
||||
|
||||
oclog(ws, LOG_TRANSFER_DEBUG,
|
||||
"retrying (TLS) %d\n", l);
|
||||
} else {
|
||||
tls_retry = 0;
|
||||
if (ret >= ws->conn_mtu
|
||||
&& ws->config->try_mtu != 0)
|
||||
mtu_ok(ws);
|
||||
tls_retry = 1;
|
||||
} else if (ret >= ws->conn_mtu &&
|
||||
ws->config->try_mtu != 0) {
|
||||
mtu_ok(ws);
|
||||
}
|
||||
}
|
||||
|
||||
if (fds->tls_writable
|
||||
&& (ws->udp_state != UP_ACTIVE || tls_retry != 0)) {
|
||||
if (ws->udp_state != UP_ACTIVE || tls_retry != 0) {
|
||||
ws->buffer[0] = 'S';
|
||||
ws->buffer[1] = 'T';
|
||||
ws->buffer[2] = 'F';
|
||||
@@ -1297,7 +1282,6 @@ static int connect_handler(worker_st * ws)
|
||||
{
|
||||
struct http_req_st *req = &ws->req;
|
||||
fd_set rfds;
|
||||
fd_set wfds;
|
||||
int e, max, ret, t;
|
||||
char *p;
|
||||
#ifdef HAVE_PSELECT
|
||||
@@ -1305,7 +1289,6 @@ static int connect_handler(worker_st * ws)
|
||||
#else
|
||||
struct timeval tv;
|
||||
#endif
|
||||
fd_status_st fd_status;
|
||||
unsigned tls_pending, dtls_pending = 0, i;
|
||||
struct timespec tnow;
|
||||
unsigned proto_overhead = 0, ip6;
|
||||
@@ -1706,10 +1689,10 @@ static int connect_handler(worker_st * ws)
|
||||
|
||||
/* crypto overhead for DTLS */
|
||||
ws->crypto_overhead =
|
||||
tls_get_overhead(ws->req.
|
||||
selected_ciphersuite->gnutls_version,
|
||||
ws->req.
|
||||
selected_ciphersuite->gnutls_cipher,
|
||||
tls_get_overhead(ws->req.selected_ciphersuite->
|
||||
gnutls_version,
|
||||
ws->req.selected_ciphersuite->
|
||||
gnutls_cipher,
|
||||
ws->req.selected_ciphersuite->gnutls_mac);
|
||||
ws->crypto_overhead += CSTP_DTLS_OVERHEAD;
|
||||
|
||||
@@ -1781,19 +1764,15 @@ static int connect_handler(worker_st * ws)
|
||||
/* worker main loop */
|
||||
for (;;) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
|
||||
FD_SET(ws->conn_fd, &rfds);
|
||||
FD_SET(ws->cmd_fd, &rfds);
|
||||
FD_SET(ws->tun_fd, &rfds);
|
||||
FD_SET(ws->tun_fd, &wfds);
|
||||
FD_SET(ws->conn_fd, &wfds);
|
||||
max = MAX(ws->cmd_fd, ws->conn_fd);
|
||||
max = MAX(max, ws->tun_fd);
|
||||
|
||||
if (ws->udp_state > UP_WAIT_FD) {
|
||||
FD_SET(ws->udp_fd, &rfds);
|
||||
FD_SET(ws->udp_fd, &wfds);
|
||||
max = MAX(max, ws->udp_fd);
|
||||
}
|
||||
|
||||
@@ -1824,13 +1803,12 @@ static int connect_handler(worker_st * ws)
|
||||
tv.tv_nsec = 0;
|
||||
tv.tv_sec = 10;
|
||||
ret =
|
||||
pselect(max + 1, &rfds, &wfds, NULL, &tv,
|
||||
&emptyset);
|
||||
pselect(max + 1, &rfds, NULL, NULL, &tv, &emptyset);
|
||||
#else
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 10;
|
||||
sigprocmask(SIG_UNBLOCK, &blockset, NULL);
|
||||
ret = select(max + 1, &rfds, &wfds, NULL, &tv);
|
||||
ret = select(max + 1, &rfds, NULL, NULL, &tv);
|
||||
sigprocmask(SIG_BLOCK, &blockset, NULL);
|
||||
#endif
|
||||
if (ret == -1) {
|
||||
@@ -1846,13 +1824,9 @@ static int connect_handler(worker_st * ws)
|
||||
ws->config->dpd) < 0)
|
||||
goto exit;
|
||||
|
||||
fd_status.dtls_writable = FD_ISSET(ws->udp_fd, &wfds);
|
||||
fd_status.tls_writable = FD_ISSET(ws->conn_fd, &wfds);
|
||||
fd_status.tun_writable = FD_ISSET(ws->tun_fd, &wfds);
|
||||
|
||||
/* read pending data from tun device */
|
||||
/* send pending data from tun device */
|
||||
if (FD_ISSET(ws->tun_fd, &rfds)) {
|
||||
ret = tun_mainloop(ws, &tnow, &fd_status);
|
||||
ret = tun_mainloop(ws, &tnow);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
@@ -1860,7 +1834,8 @@ static int connect_handler(worker_st * ws)
|
||||
|
||||
/* read pending data from TCP channel */
|
||||
if (FD_ISSET(ws->conn_fd, &rfds) || tls_pending != 0) {
|
||||
ret = tls_mainloop(ws, &tnow, &fd_status);
|
||||
|
||||
ret = tls_mainloop(ws, &tnow);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
|
||||
@@ -1869,7 +1844,8 @@ static int connect_handler(worker_st * ws)
|
||||
/* read data from UDP channel */
|
||||
if (ws->udp_state > UP_WAIT_FD
|
||||
&& (FD_ISSET(ws->udp_fd, &rfds) || dtls_pending != 0)) {
|
||||
ret = dtls_mainloop(ws, &tnow, &fd_status);
|
||||
|
||||
ret = dtls_mainloop(ws, &tnow);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
}
|
||||
@@ -1904,8 +1880,7 @@ static int connect_handler(worker_st * ws)
|
||||
}
|
||||
|
||||
static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interface of recv */
|
||||
uint8_t head, uint8_t * buf, size_t buf_size, time_t now,
|
||||
fd_status_st * fds)
|
||||
uint8_t head, uint8_t * buf, size_t buf_size, time_t now)
|
||||
{
|
||||
int ret, e;
|
||||
|
||||
@@ -1951,16 +1926,12 @@ static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interfac
|
||||
case AC_PKT_DATA:
|
||||
oclog(ws, LOG_TRANSFER_DEBUG, "writing %d byte(s) to TUN",
|
||||
(int)buf_size);
|
||||
|
||||
if (fds->tun_writable != 0) {
|
||||
ret = force_write(ws->tun_fd, buf, buf_size);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
oclog(ws, LOG_ERR,
|
||||
"could not write data to tun: %s",
|
||||
strerror(e));
|
||||
return -1;
|
||||
}
|
||||
ret = force_write(ws->tun_fd, buf, buf_size);
|
||||
if (ret == -1) {
|
||||
e = errno;
|
||||
oclog(ws, LOG_ERR, "could not write data to tun: %s",
|
||||
strerror(e));
|
||||
return -1;
|
||||
}
|
||||
ws->last_nc_msg = now;
|
||||
|
||||
@@ -1974,8 +1945,7 @@ static int parse_data(struct worker_st *ws, gnutls_session_t ts, /* the interfac
|
||||
}
|
||||
|
||||
static int parse_cstp_data(struct worker_st *ws,
|
||||
uint8_t * buf, size_t buf_size, time_t now,
|
||||
fd_status_st * fds)
|
||||
uint8_t * buf, size_t buf_size, time_t now)
|
||||
{
|
||||
int pktlen, ret;
|
||||
|
||||
@@ -1998,7 +1968,7 @@ static int parse_cstp_data(struct worker_st *ws,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = parse_data(ws, ws->session, buf[6], buf + 8, pktlen, now, fds);
|
||||
ret = parse_data(ws, ws->session, buf[6], buf + 8, pktlen, now);
|
||||
/* whatever we received treat it as DPD response.
|
||||
* it indicates that the channel is alive */
|
||||
ws->last_msg_tcp = now;
|
||||
@@ -2007,8 +1977,7 @@ static int parse_cstp_data(struct worker_st *ws,
|
||||
}
|
||||
|
||||
static int parse_dtls_data(struct worker_st *ws,
|
||||
uint8_t * buf, size_t buf_size, time_t now,
|
||||
fd_status_st * fds)
|
||||
uint8_t * buf, size_t buf_size, time_t now)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -2021,7 +1990,7 @@ static int parse_dtls_data(struct worker_st *ws,
|
||||
|
||||
ret =
|
||||
parse_data(ws, ws->dtls_session, buf[0], buf + 1, buf_size - 1,
|
||||
now, fds);
|
||||
now);
|
||||
ws->last_msg_udp = now;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user