very low throughput on Mac OS X
Tom Rodriguez
tom.rodriguez at oracle.com
Mon Aug 22 11:57:50 PDT 2016
> On Aug 19, 2016, at 5:38 AM, David Woodhouse <dwmw2 at infradead.org> wrote:
>
> On Thu, 2016-08-18 at 10:13 -0700, Tom Rodriguez wrote:
>>
>> I’m actually using ocproxy to handle the traffic so I don’t think I’m
>> going through the tunnel device. So does that mean the packets are
>> being lost on the datagram socket connecting me to ocproxy?
>
> Yes, kind of. They're not being lost on the datagram socket. They're
> lost in OpenConnect because we deliberately drop them when the queue
> *into* the datagram socket gets full. Purely because *if* we were on
> Linux, and *if* it was a kernel tun device not a UNIX socket, we
> wouldn't be able to poll() to tell when we *can* next write to that
> file description.
>
> Which seems kind of silly, when you put it like that :)
>
> Your problem is the *drop* not the fact that the queue gets full, per
> se.
>
> We really should fix that. Can you confirm that this works, *without*
> tweaking the buffer sizes (and indeed even if you reduce them)?
The patch applied on top of 7.07 seems to resolve the problem. I lowered the buffer size to 4096 and still got the good throughput, though of course I got a lot more of the "No buffer space available” messages. If those no longer represent a hard failure it would be nice to suppress them. Thanks!
tom
>
> diff --git a/mainloop.c b/mainloop.c
> index a474861..6a1e7d6 100644
> --- a/mainloop.c
> +++ b/mainloop.c
> @@ -92,6 +92,8 @@ int tun_mainloop(struct openconnect_info *vpninfo, int *timeout)
>
> while ((this = dequeue_packet(&vpninfo->incoming_queue))) {
>
> + unmonitor_write_fd(vpninfo, tun);
> +
> if (os_write_tun(vpninfo, this)) {
> requeue_packet(&vpninfo->incoming_queue, this);
> break;
> diff --git a/tun.c b/tun.c
> index b9a7465..91a1dcf 100644
> --- a/tun.c
> +++ b/tun.c
> @@ -557,9 +557,16 @@ int os_write_tun(struct openconnect_info *vpninfo, struct pkt *pkt)
> vpn_progress(vpninfo, PRG_ERR,
> _("Failed to write incoming packet: %s\n"),
> strerror(errno));
> - /* The kernel returns -ENOMEM when the queue is full, so theoretically
> - we could handle that and retry... but it doesn't let us poll() for
> - the no-longer-full situation, so let's not bother. */
> + if (errno == ENOMEM) {
> + /* The kernel returns -ENOMEM when the queue is full,
> + so theoretically we could handle that and retry...
> + but it doesn't let us poll() for the no-longer-full
> + situation, so let's not bother. */
> + return 0;
> + }
> + /* Other cases make it sane to retry (hopefully) */
> + monitor_write_fd(vpninfo, tun);
> + return -1;
> }
> return 0;
>
> --
> David Woodhouse Open Source Technology Centre
> David.Woodhouse at intel.com Intel Corporation
More information about the openconnect-devel
mailing list