Skip to content

Commit

Permalink
Don't read from non-readable fds
Browse files Browse the repository at this point in the history
By removing the unneeded reads from file descriptors that we know aren't
readable, ESP TX performance goes from 1700Mb/s to 1760Mb/s on my current
test setup.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
  • Loading branch information
dwmw2 committed Apr 15, 2019
1 parent f296ba1 commit 7d14e11
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 24 deletions.
4 changes: 2 additions & 2 deletions cstp.c
Expand Up @@ -894,7 +894,7 @@ int compress_packet(struct openconnect_info *vpninfo, int compr_type, struct pkt
return 0;
}

int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
{
int ret;
int work_done = 0;
Expand All @@ -908,7 +908,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
we should probably remove POLLIN from the events we're looking for,
and add POLLOUT. As it is, though, it'll just chew CPU time in that
fairly unlikely situation, until the write backlog clears. */
while (1) {
while (readable) {
/* Some servers send us packets that are larger than
negotiated MTU. We reserve some extra space to
handle that */
Expand Down
4 changes: 2 additions & 2 deletions dtls.c
Expand Up @@ -242,7 +242,7 @@ int dtls_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
return 0;
}

int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
{
int work_done = 0;
char magic_pkt;
Expand Down Expand Up @@ -271,7 +271,7 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
return 0;
}

while (1) {
while (readable) {
int len = vpninfo->ip_info.mtu;
unsigned char *buf;

Expand Down
4 changes: 2 additions & 2 deletions esp.c
Expand Up @@ -94,7 +94,7 @@ int esp_setup(struct openconnect_info *vpninfo, int dtls_attempt_period)
return 0;
}

int esp_mainloop(struct openconnect_info *vpninfo, int *timeout)
int esp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
{
struct esp *esp = &vpninfo->esp_in[vpninfo->current_esp_in];
struct esp *old_esp = &vpninfo->esp_in[vpninfo->current_esp_in ^ 1];
Expand All @@ -118,7 +118,7 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout)
if (vpninfo->dtls_fd == -1)
return 0;

while (1) {
while (readable) {
int len = receive_mtu + vpninfo->pkt_trailer;
int i;
struct pkt *pkt;
Expand Down
4 changes: 2 additions & 2 deletions gpst.c
Expand Up @@ -981,7 +981,7 @@ int gpst_setup(struct openconnect_info *vpninfo)
return ret;
}

int gpst_mainloop(struct openconnect_info *vpninfo, int *timeout)
int gpst_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
{
int ret;
int work_done = 0;
Expand Down Expand Up @@ -1028,7 +1028,7 @@ int gpst_mainloop(struct openconnect_info *vpninfo, int *timeout)
if (vpninfo->ssl_fd == -1)
goto do_reconnect;

while (1) {
while (readable) {
/* Some servers send us packets that are larger than
negotiated MTU. We reserve some extra space to
handle that */
Expand Down
18 changes: 12 additions & 6 deletions mainloop.c
Expand Up @@ -45,7 +45,7 @@ int queue_new_packet(struct pkt_q *q, void *buf, int len)

/* This is here because it's generic and hence can't live in either of the
tun*.c files for specific platforms */
int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
int tun_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
{
struct pkt *this;
int work_done = 0;
Expand All @@ -58,7 +58,7 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
return 0;
}

if (read_fd_monitored(vpninfo, tun)) {
if (readable && read_fd_monitored(vpninfo, tun)) {
struct pkt *out_pkt = vpninfo->tun_pkt;
while (1) {
int len = vpninfo->ip_info.mtu;
Expand Down Expand Up @@ -177,7 +177,7 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
int reconnect_interval)
{
int ret = 0;

int tun_r = 1, udp_r = 1, tcp_r = 1;
vpninfo->reconnect_timeout = reconnect_timeout;
vpninfo->reconnect_interval = reconnect_interval;

Expand Down Expand Up @@ -217,7 +217,7 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
}
}

ret = vpninfo->proto->udp_mainloop(vpninfo, &timeout);
ret = vpninfo->proto->udp_mainloop(vpninfo, &timeout, udp_r);
if (vpninfo->quit_reason)
break;
did_work += ret;
Expand All @@ -229,14 +229,14 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
break;
}

ret = vpninfo->proto->tcp_mainloop(vpninfo, &timeout);
ret = vpninfo->proto->tcp_mainloop(vpninfo, &timeout, tcp_r);
if (vpninfo->quit_reason)
break;
did_work += ret;

/* Tun must be last because it will set/clear its bit
in the select_rfds according to the queue length */
did_work += tun_mainloop(vpninfo, &timeout);
did_work += tun_mainloop(vpninfo, &timeout, tun_r);
if (vpninfo->quit_reason)
break;

Expand Down Expand Up @@ -304,6 +304,12 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
tv.tv_usec = (timeout % 1000) * 1000;

select(vpninfo->_select_nfds, &rfds, &wfds, &efds, &tv);
if (vpninfo->tun_fd >= 0)
tun_r = FD_ISSET(vpninfo->tun_fd, &rfds);
if (vpninfo->dtls_fd >= 0)
udp_r = FD_ISSET(vpninfo->dtls_fd, &rfds);
if (vpninfo->ssl_fd >= 0)
tcp_r = FD_ISSET(vpninfo->ssl_fd, &rfds);
#endif
}

Expand Down
4 changes: 2 additions & 2 deletions oncp.c
Expand Up @@ -886,7 +886,7 @@ static int oncp_record_read(struct openconnect_info *vpninfo, void *buf, int len
return ret;
}

int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout)
int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
{
int ret;
int work_done = 0;
Expand All @@ -900,7 +900,7 @@ int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout)
we should probably remove POLLIN from the events we're looking for,
and add POLLOUT. As it is, though, it'll just chew CPU time in that
fairly unlikely situation, until the write backlog clears. */
while (1) {
while (readable) {
int len, kmp, kmplen, iplen;
/* Some servers send us packets that are larger than
negitiated MTU. We reserve some estra space to
Expand Down
16 changes: 8 additions & 8 deletions openconnect-internal.h
Expand Up @@ -263,7 +263,7 @@ struct vpn_proto {
/* Establish the TCP connection (and obtain configuration) */
int (*tcp_connect)(struct openconnect_info *vpninfo);

int (*tcp_mainloop)(struct openconnect_info *vpninfo, int *timeout);
int (*tcp_mainloop)(struct openconnect_info *vpninfo, int *timeout, int readable);

/* Add headers common to each HTTP request */
void (*add_http_headers)(struct openconnect_info *vpninfo, struct oc_text_buf *buf);
Expand All @@ -273,7 +273,7 @@ struct vpn_proto {

/* This will actually complete the UDP connection setup/handshake on the wire,
as well as transporting packets */
int (*udp_mainloop)(struct openconnect_info *vpninfo, int *timeout);
int (*udp_mainloop)(struct openconnect_info *vpninfo, int *timeout, int readable);

/* Close the connection but leave the session setup so it restarts */
void (*udp_close)(struct openconnect_info *vpninfo);
Expand Down Expand Up @@ -831,7 +831,7 @@ void dtls_ssl_free(struct openconnect_info *vpninfo);

/* dtls.c */
int dtls_setup(struct openconnect_info *vpninfo, int dtls_attempt_period);
int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout);
int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
void dtls_close(struct openconnect_info *vpninfo);
void dtls_shutdown(struct openconnect_info *vpninfo);
void gather_dtls_ciphers(struct openconnect_info *vpninfo, struct oc_text_buf *buf, struct oc_text_buf *buf12);
Expand All @@ -844,7 +844,7 @@ char *openconnect_bin2base64(const char *prefix, const uint8_t *data, unsigned l
/* cstp.c */
void cstp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *buf);
int cstp_connect(struct openconnect_info *vpninfo);
int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout);
int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
int cstp_bye(struct openconnect_info *vpninfo, const char *reason);
int decompress_and_queue_packet(struct openconnect_info *vpninfo, int compr_type,
unsigned char *buf, int len);
Expand All @@ -856,7 +856,7 @@ void oncp_common_headers(struct openconnect_info *vpninfo, struct oc_text_buf *b

/* oncp.c */
int oncp_connect(struct openconnect_info *vpninfo);
int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout);
int oncp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
int oncp_bye(struct openconnect_info *vpninfo, const char *reason);
void oncp_esp_close(struct openconnect_info *vpninfo);
int oncp_esp_send_probes(struct openconnect_info *vpninfo);
Expand All @@ -873,7 +873,7 @@ int gpst_xml_or_error(struct openconnect_info *vpninfo, char *response,
int (*challenge_cb)(struct openconnect_info *, char *prompt, char *inputStr, void *cb_data),
void *cb_data);
int gpst_setup(struct openconnect_info *vpninfo);
int gpst_mainloop(struct openconnect_info *vpninfo, int *timeout);
int gpst_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
int gpst_esp_send_probes(struct openconnect_info *vpninfo);
int gpst_esp_catch_probe(struct openconnect_info *vpninfo, struct pkt *pkt);

Expand Down Expand Up @@ -925,7 +925,7 @@ int load_pkcs11_certificate(struct openconnect_info *vpninfo);
int verify_packet_seqno(struct openconnect_info *vpninfo,
struct esp *esp, uint32_t seq);
int esp_setup(struct openconnect_info *vpninfo, int dtls_attempt_period);
int esp_mainloop(struct openconnect_info *vpninfo, int *timeout);
int esp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
void esp_close(struct openconnect_info *vpninfo);
void esp_shutdown(struct openconnect_info *vpninfo);
int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct esp *esp);
Expand Down Expand Up @@ -963,7 +963,7 @@ int hotp_hmac(struct openconnect_info *vpninfo, const void *challenge);
#endif

/* mainloop.c */
int tun_mainloop(struct openconnect_info *vpninfo, int *timeout);
int tun_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
int queue_new_packet(struct pkt_q *q, void *buf, int len);
int keepalive_action(struct keepalive_info *ka, int *timeout);
int ka_stalled_action(struct keepalive_info *ka, int *timeout);
Expand Down

0 comments on commit 7d14e11

Please sign in to comment.