aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-01-15 15:52:16 -0500
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 00:14:23 -0500
commitc4f912e155504e94dd4f3d63c378dab0ff03dbda (patch)
treedb544bdd0dfc8ca890193a29b161b551f20f543c
parentd58daf42d29a3a4a4d4be46cf47ceee096789680 (diff)
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>
-rw-r--r--include/net/bluetooth/bluetooth.h3
-rw-r--r--net/bluetooth/af_bluetooth.c8
2 files changed, 9 insertions, 2 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index a04f8463ac7e..847e9e6df08b 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -53,6 +53,8 @@
53#define SOL_SCO 17 53#define SOL_SCO 17
54#define SOL_RFCOMM 18 54#define SOL_RFCOMM 18
55 55
56#define BT_DEFER_SETUP 7
57
56#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) 58#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
57#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) 59#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
58#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) 60#define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
@@ -108,6 +110,7 @@ struct bt_sock {
108 bdaddr_t dst; 110 bdaddr_t dst;
109 struct list_head accept_q; 111 struct list_head accept_q;
110 struct sock *parent; 112 struct sock *parent;
113 u32 defer_setup;
111}; 114};
112 115
113struct bt_sock_list { 116struct bt_sock_list {
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)
217 continue; 217 continue;
218 } 218 }
219 219
220 if (sk->sk_state == BT_CONNECTED || !newsock) { 220 if (sk->sk_state == BT_CONNECTED || !newsock ||
221 bt_sk(parent)->defer_setup) {
221 bt_accept_unlink(sk); 222 bt_accept_unlink(sk);
222 if (newsock) 223 if (newsock)
223 sock_graft(sk, newsock); 224 sock_graft(sk, newsock);
@@ -232,7 +233,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
232EXPORT_SYMBOL(bt_accept_dequeue); 233EXPORT_SYMBOL(bt_accept_dequeue);
233 234
234int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, 235int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
235 struct msghdr *msg, size_t len, int flags) 236 struct msghdr *msg, size_t len, int flags)
236{ 237{
237 int noblock = flags & MSG_DONTWAIT; 238 int noblock = flags & MSG_DONTWAIT;
238 struct sock *sk = sock->sk; 239 struct sock *sk = sock->sk;
@@ -275,6 +276,9 @@ static inline unsigned int bt_accept_poll(struct sock *parent)
275 struct list_head *p, *n; 276 struct list_head *p, *n;
276 struct sock *sk; 277 struct sock *sk;
277 278
279 if (bt_sk(parent)->defer_setup)
280 return POLLIN | POLLRDNORM;
281
278 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { 282 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
279 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); 283 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
280 if (sk->sk_state == BT_CONNECTED) 284 if (sk->sk_state == BT_CONNECTED)