]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Don't read from non-readable fds
authorDavid Woodhouse <dwmw2@infradead.org>
Tue, 9 Apr 2019 15:45:33 +0000 (18:45 +0300)
committerDavid Woodhouse <dwmw2@infradead.org>
Mon, 15 Apr 2019 11:04:31 +0000 (12:04 +0100)
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>
cstp.c
dtls.c
esp.c
gpst.c
mainloop.c
oncp.c
openconnect-internal.h

diff --git a/cstp.c b/cstp.c
index 14ed4b4650fb510078cb59aa341e33a1afb5d654..df64ae1ac0df8165a33ce2c536c84057e3559abc 100644 (file)
--- a/cstp.c
+++ b/cstp.c
@@ -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;
@@ -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 */
diff --git a/dtls.c b/dtls.c
index d8e0d2f81b0fb3102d41304e6181c73e90b4e3a3..2f262934f0a3abaf16510d9cf1972c4d8e180052 100644 (file)
--- a/dtls.c
+++ b/dtls.c
@@ -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;
@@ -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;
 
diff --git a/esp.c b/esp.c
index 289c6ebe40c755a95d1f5f7eb1c9893c9cf8d3a5..2a4d1b60888f6555b6c5df77d5b83e3c96f0fc3e 100644 (file)
--- a/esp.c
+++ b/esp.c
@@ -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];
@@ -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;
diff --git a/gpst.c b/gpst.c
index a0dc81fee048d57d10c9c7d589c7505ea4f5cb63..9f1d58460afa013c900067e0fed9a1a24b0886c6 100644 (file)
--- a/gpst.c
+++ b/gpst.c
@@ -981,7 +981,7 @@ out:
        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;
@@ -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 */
index fe185fe205227e9110621e23adbd4b3ee139aee3..b21ff70c779e6d3cfbd2535b2a6d295c2470ab2c 100644 (file)
@@ -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;
@@ -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;
@@ -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;
 
@@ -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;
@@ -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;
 
@@ -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
        }
 
diff --git a/oncp.c b/oncp.c
index 3a878700aa957f9bdb5d4461adc49f766f0f3de9..4c389f5a749d75794e892ca880dfb801c0d53325 100644 (file)
--- a/oncp.c
+++ b/oncp.c
@@ -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;
@@ -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
index 8df7d24d6105322e554929db005c2ab4556a5129..8133e100cd5544911513680389bf1febd2e46f71 100644 (file)
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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);
 
@@ -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);
@@ -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);