summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorratchov <ratchov@openbsd.org>2009-10-22 21:41:30 +0000
committerratchov <ratchov@openbsd.org>2009-10-22 21:41:30 +0000
commit43d27ea74e8e06559b86a64ceed1f972180e6f19 (patch)
tree88f0aad892f748f1fad728436e7bb74c3cf5667e
parentuse .Ux in midicat.1, as we do for aucat.1 now (diff)
downloadwireguard-openbsd-43d27ea74e8e06559b86a64ceed1f972180e6f19.tar.xz
wireguard-openbsd-43d27ea74e8e06559b86a64ceed1f972180e6f19.zip
When starting playback, the client tries to write ``bufsz'' frames
instead of ``appbufsz'', which violates the flow control mechanism. Fix this longstanding bug by enabling negative values in AMSG_MOVE messages, this way the client is notified when its stream is attached to the mixer, and can update its max transfer limit. Since this fix changes the AMSG_MOVE message format, we crank the protocol version, and thus remove code specific to the old protocol.
-rw-r--r--lib/libsndio/aucat.c23
-rw-r--r--usr.bin/aucat/amsg.h4
-rw-r--r--usr.bin/aucat/sock.c51
3 files changed, 30 insertions, 48 deletions
diff --git a/lib/libsndio/aucat.c b/lib/libsndio/aucat.c
index cc1e977b1f1..681411700de 100644
--- a/lib/libsndio/aucat.c
+++ b/lib/libsndio/aucat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: aucat.c,v 1.29 2009/10/17 10:55:43 ratchov Exp $ */
+/* $OpenBSD: aucat.c,v 1.30 2009/10/22 21:41:30 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -43,6 +43,9 @@ struct aucat_hdl {
int maxwrite; /* latency constraint */
int events; /* events the user requested */
unsigned curvol, reqvol; /* current and requested volume */
+ unsigned devbufsz; /* server side buffer size (in frames) */
+ unsigned attached; /* stream attached to device */
+ int delta; /* some of received deltas */
};
static void aucat_close(struct sio_hdl *);
@@ -150,8 +153,17 @@ aucat_runmsg(struct aucat_hdl *hdl)
hdl->rtodo = hdl->rmsg.u.data.size;
break;
case AMSG_MOVE:
- hdl->maxwrite += hdl->rmsg.u.ts.delta * (int)hdl->wbpf;
- sio_onmove_cb(&hdl->sio, hdl->rmsg.u.ts.delta);
+ if (!hdl->attached) {
+ DPRINTF("aucat_runmsg: attached\n");
+ hdl->maxwrite += hdl->devbufsz * hdl->wbpf;
+ hdl->attached = 1;
+ }
+ hdl->delta += hdl->rmsg.u.ts.delta;
+ if (hdl->delta >= 0) {
+ hdl->maxwrite += hdl->delta * hdl->wbpf;
+ sio_onmove_cb(&hdl->sio, hdl->delta);
+ hdl->delta = 0;
+ }
hdl->rstate = STATE_MSG;
hdl->rtodo = sizeof(struct amsg);
break;
@@ -303,7 +315,10 @@ aucat_start(struct sio_hdl *sh)
return 0;
hdl->wbpf = par.bps * par.pchan;
hdl->rbpf = par.bps * par.rchan;
- hdl->maxwrite = hdl->wbpf * par.bufsz;
+ hdl->maxwrite = hdl->wbpf * par.appbufsz;
+ hdl->devbufsz = par.bufsz - par.appbufsz;
+ hdl->attached = 0;
+ hdl->delta = 0;
AMSG_INIT(&hdl->wmsg);
hdl->wmsg.cmd = AMSG_START;
diff --git a/usr.bin/aucat/amsg.h b/usr.bin/aucat/amsg.h
index 9492f2bb8d1..fa971543c30 100644
--- a/usr.bin/aucat/amsg.h
+++ b/usr.bin/aucat/amsg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amsg.h,v 1.11 2009/10/17 10:55:43 ratchov Exp $ */
+/* $OpenBSD: amsg.h,v 1.12 2009/10/22 21:41:30 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -89,7 +89,7 @@ struct amsg {
#define AMSG_MIDIOUT 0x8 /* MIDI thru output */
#define AMSG_MIXER 0x10 /* MIDI mixer */
uint16_t proto; /* protocol type */
-#define AMSG_VERSION 0
+#define AMSG_VERSION 1
uint8_t version; /* protocol version */
uint8_t reserved1[5]; /* for future use */
char opt[12]; /* profile name */
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c
index 5248d8b3528..0611755a477 100644
--- a/usr.bin/aucat/sock.c
+++ b/usr.bin/aucat/sock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.c,v 1.32 2009/10/21 05:43:41 ratchov Exp $ */
+/* $OpenBSD: sock.c,v 1.33 2009/10/22 21:41:30 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -130,13 +130,6 @@ rsock_opos(struct aproc *p, struct abuf *obuf, int delta)
return;
f->delta += delta;
- /*
- * Negative deltas are xrun notifications for internal uses
- * only. Don't generate a packet for this, the client will be
- * notified later.
- */
- if (delta < 0)
- return;
f->tickpending++;
for (;;) {
if (!sock_write(f))
@@ -228,14 +221,7 @@ wsock_ipos(struct aproc *p, struct abuf *obuf, int delta)
return;
f->delta += delta;
- /*
- * Negative deltas are xrun notifications for internal uses
- * only. Don't generate a packet for this, the client will be
- * notified later.
- */
- if (delta < 0)
- return;
- f->tickpending++;
+ f->tickpending++;
for (;;) {
if (!sock_write(f))
break;
@@ -550,21 +536,6 @@ sock_setpar(struct sock *f)
struct amsg_par *p = &f->rmsg.u.par;
unsigned min, max, rate;
- if (AMSG_ISSET(p->legacy_mode)) {
- /*
- * allow old clients that don't support HELLO to work
- * XXX: remove this.
- */
- if ((p->legacy_mode & ~(AMSG_PLAY | AMSG_REC)) ||
- (p->legacy_mode == 0)) {
- return 0;
- }
- f->mode = 0;
- if ((p->legacy_mode & AMSG_PLAY) && dev_mix)
- f->mode |= AMSG_PLAY;
- if ((p->legacy_mode & AMSG_REC) && dev_sub)
- f->mode |= AMSG_REC;
- }
if (AMSG_ISSET(p->bits)) {
if (p->bits < BITS_MIN || p->bits > BITS_MAX) {
return 0;
@@ -674,9 +645,12 @@ sock_hello(struct sock *f)
{
struct amsg_hello *p = &f->rmsg.u.hello;
- /* XXX : set file name to p->who */
- /* XXX : dev_midi can no longer be NULL, right ? */
-
+ if (p->version != AMSG_VERSION) {
+ return 0;
+ }
+ /*
+ * XXX : dev_midi can no longer be NULL, right ?
+ */
if (dev_midi && (p->proto & (AMSG_MIDIIN | AMSG_MIDIOUT))) {
if (p->proto & ~(AMSG_MIDIIN | AMSG_MIDIOUT)) {
return 0;
@@ -729,13 +703,6 @@ sock_execmsg(struct sock *f)
{
struct amsg *m = &f->rmsg;
- /*
- * XXX: allow old clients to work without hello on the default socket
- */
- if (f->pstate == SOCK_HELLO && m->cmd != AMSG_HELLO && f->opt != NULL) {
- f->pstate = SOCK_INIT;
- }
-
switch (m->cmd) {
case AMSG_DATA:
if (f->pstate != SOCK_RUN && f->pstate != SOCK_START) {
@@ -899,7 +866,7 @@ sock_buildmsg(struct sock *f)
/*
* If pos changed, build a MOVE message.
*/
- if (f->tickpending && f->delta >= 0) {
+ if (f->tickpending) {
AMSG_INIT(&f->wmsg);
f->wmsg.cmd = AMSG_MOVE;
f->wmsg.u.ts.delta = f->delta;