diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-01-15 23:52:16 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-02-27 08:14:23 +0300 |
commit | c4f912e155504e94dd4f3d63c378dab0ff03dbda (patch) | |
tree | db544bdd0dfc8ca890193a29b161b551f20f543c /net/bluetooth/af_bluetooth.c | |
parent | d58daf42d29a3a4a4d4be46cf47ceee096789680 (diff) | |
download | linux-c4f912e155504e94dd4f3d63c378dab0ff03dbda.tar.xz |
Bluetooth: Add global deferred socket parameter
The L2CAP and RFCOMM applications require support for authorization
and the ability of rejecting incoming connection requests. The socket
interface is not really able to support this.
This patch does the ground work for a socket option to defer connection
setup. Setting this option allows calling of accept() and then the
first read() will trigger the final connection setup. Calling close()
would reject the connection.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/af_bluetooth.c')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 744ed3f07ef3..7c0031ff8cfb 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -217,7 +217,8 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) continue; } - if (sk->sk_state == BT_CONNECTED || !newsock) { + if (sk->sk_state == BT_CONNECTED || !newsock || + bt_sk(parent)->defer_setup) { bt_accept_unlink(sk); if (newsock) sock_graft(sk, newsock); @@ -232,7 +233,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) EXPORT_SYMBOL(bt_accept_dequeue); int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) + struct msghdr *msg, size_t len, int flags) { int noblock = flags & MSG_DONTWAIT; struct sock *sk = sock->sk; @@ -275,6 +276,9 @@ static inline unsigned int bt_accept_poll(struct sock *parent) struct list_head *p, *n; struct sock *sk; + if (bt_sk(parent)->defer_setup) + return POLLIN | POLLRDNORM; + list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); if (sk->sk_state == BT_CONNECTED) |