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