public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: Marcel Holtmann <marcel@holtmann.org>
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: regression introduced on v2.6.30-rc1
Date: Tue, 23 Jun 2009 10:51:43 -0300	[thread overview]
Message-ID: <2d5a2c100906230651m679ccfat5bf4bfb20c130955@mail.gmail.com> (raw)
In-Reply-To: <2d5a2c100906221608v5e3e3d8aydf66b13826ad88fa@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 353 bytes --]

Cleanup version, which include code style fixing suggested by Johan on irc.

There are 2 other things that comes to my mind that need discussing:

 - 20 sec timeout is perhaps too big
 - clear the timer on rfcomm_session_close is perhaps not save then we
can move it to rfcomm_session_del

-- 
Luiz Augusto von Dentz
Engenheiro de Computação

[-- Attachment #2: 0001-bluetooth-Fix-rejected-connection-to-not-disconnect-.patch --]
[-- Type: text/x-diff, Size: 4110 bytes --]

From 781c3df5d0926aaa517cf845baf71dc0e5720d81 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.dentz@openbossa.org>
Date: Tue, 23 Jun 2009 10:31:57 -0300
Subject: [PATCH] bluetooth: Fix rejected connection to not disconnect ACL.

When using DEFER_SETUP on a RFCOMM socket a SABM frame triggers
authorization which when rejected send a DM as response. This is fine
accourding to the RFCOMM spec:

"the responding implementation may replace the "proper" response on
the Multiplexer Control channel with a DM frame, sent on the referenced
DLCI to indicate that the DLCI is not open, and that the responder would
not grant a request to open it later either."

But some stacks doesn't seems to cope with this leaving DLCI 0 open after
receiving DM frame.

To fix it properly a timer was introduced to rfcomm_session which is used
to set a timeout when the last active DLC of a session is unlinked, this
will give the remote stack some time to reply with a proper DISC frame on
DLCI 0 avoiding both sides sending DISC to each other on stacks that
follow the specification and taking care of those who don't by taking
down DLCI 0.

Signed-off-by: Luiz Augusto von Dentz <luiz.dentz@openbossa.org>
---
 include/net/bluetooth/rfcomm.h |    1 +
 net/bluetooth/rfcomm/core.c    |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 8007261..a32883f 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -154,6 +154,7 @@ struct rfcomm_msc {
 struct rfcomm_session {
 	struct list_head list;
 	struct socket   *sock;
+	struct timer_list timer;
 	unsigned long    state;
 	unsigned long    flags;
 	atomic_t         refcnt;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 374536e..73035b6 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -244,6 +244,33 @@ static inline int rfcomm_check_security(struct rfcomm_dlc *d)
 								auth_type);
 }
 
+static void rfcomm_session_timeout(unsigned long arg)
+{
+	struct rfcomm_session *s = (void *) arg;
+
+	BT_DBG("session %p state %ld", s, s->state);
+
+	set_bit(RFCOMM_TIMED_OUT, &s->flags);
+	rfcomm_session_put(s);
+	rfcomm_schedule(RFCOMM_SCHED_TIMEO);
+}
+
+static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
+{
+	BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
+
+	if (!mod_timer(&s->timer, jiffies + timeout))
+		rfcomm_session_hold(s);
+}
+
+static void rfcomm_session_clear_timer(struct rfcomm_session *s)
+{
+	BT_DBG("session %p state %ld", s, s->state);
+
+	if (timer_pending(&s->timer) && del_timer(&s->timer))
+		rfcomm_session_put(s);
+}
+
 /* ---- RFCOMM DLCs ---- */
 static void rfcomm_dlc_timeout(unsigned long arg)
 {
@@ -320,6 +347,7 @@ static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
 
 	rfcomm_session_hold(s);
 
+	rfcomm_session_clear_timer(s);
 	rfcomm_dlc_hold(d);
 	list_add(&d->list, &s->dlcs);
 	d->session = s;
@@ -335,6 +363,9 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
 	d->session = NULL;
 	rfcomm_dlc_put(d);
 
+	if (list_empty(&s->dlcs))
+		rfcomm_session_set_timer(s, RFCOMM_DISC_TIMEOUT);
+
 	rfcomm_session_put(s);
 }
 
@@ -567,6 +598,8 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
 
 	BT_DBG("session %p sock %p", s, sock);
 
+	setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long)s);
+
 	INIT_LIST_HEAD(&s->dlcs);
 	s->state = state;
 	s->sock  = sock;
@@ -639,6 +672,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err)
 		__rfcomm_dlc_close(d, err);
 	}
 
+	rfcomm_session_clear_timer(s);
 	rfcomm_session_put(s);
 }
 
@@ -1879,6 +1913,11 @@ static inline void rfcomm_process_sessions(void)
 		struct rfcomm_session *s;
 		s = list_entry(p, struct rfcomm_session, list);
 
+		if (test_bit(RFCOMM_TIMED_OUT, &s->flags)) {
+			rfcomm_session_put(s);
+			continue;
+		}
+
 		if (s->state == BT_LISTEN) {
 			rfcomm_accept_connection(s);
 			continue;
-- 
1.6.3.1


  reply	other threads:[~2009-06-23 13:51 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-09 13:17 regression introduced on v2.6.30-rc1 Luiz Augusto von Dentz
2009-06-21 14:08 ` Luiz Augusto von Dentz
2009-06-21 14:48   ` Marcel Holtmann
2009-06-21 16:30     ` Luiz Augusto von Dentz
2009-06-21 16:58       ` Marcel Holtmann
2009-06-21 17:47         ` Luiz Augusto von Dentz
2009-06-21 19:04           ` Marcel Holtmann
2009-06-22 21:49             ` Luiz Augusto von Dentz
2009-06-22 23:08               ` Luiz Augusto von Dentz
2009-06-23 13:51                 ` Luiz Augusto von Dentz [this message]
2009-06-23 14:40                   ` Marcel Holtmann
2009-06-23 15:01                     ` Luiz Augusto von Dentz
2009-06-23 15:06                       ` Marcel Holtmann
2009-06-23 18:04                     ` Stefan Seyfried
2009-06-23 18:13                       ` Luiz Augusto von Dentz
2009-06-23 18:56                         ` Luiz Augusto von Dentz
2009-06-25 13:14                           ` Luiz Augusto von Dentz
2009-06-30 20:18                             ` Luiz Augusto von Dentz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2d5a2c100906230651m679ccfat5bf4bfb20c130955@mail.gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=marcel@holtmann.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox