aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c62
1 files changed, 33 insertions, 29 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 230f9ca2ad6b..1848693ebb82 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2,7 +2,7 @@
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2007, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2004-2007, Wind River Systems 5 * Copyright (c) 2004-2008, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -63,6 +63,7 @@
63struct tipc_sock { 63struct tipc_sock {
64 struct sock sk; 64 struct sock sk;
65 struct tipc_port *p; 65 struct tipc_port *p;
66 struct tipc_portid peer_name;
66}; 67};
67 68
68#define tipc_sk(sk) ((struct tipc_sock *)(sk)) 69#define tipc_sk(sk) ((struct tipc_sock *)(sk))
@@ -188,7 +189,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
188 const struct proto_ops *ops; 189 const struct proto_ops *ops;
189 socket_state state; 190 socket_state state;
190 struct sock *sk; 191 struct sock *sk;
191 u32 portref; 192 struct tipc_port *tp_ptr;
192 193
193 /* Validate arguments */ 194 /* Validate arguments */
194 195
@@ -224,9 +225,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
224 225
225 /* Allocate TIPC port for socket to use */ 226 /* Allocate TIPC port for socket to use */
226 227
227 portref = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, 228 tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch,
228 TIPC_LOW_IMPORTANCE); 229 TIPC_LOW_IMPORTANCE);
229 if (unlikely(portref == 0)) { 230 if (unlikely(!tp_ptr)) {
230 sk_free(sk); 231 sk_free(sk);
231 return -ENOMEM; 232 return -ENOMEM;
232 } 233 }
@@ -239,12 +240,14 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol)
239 sock_init_data(sock, sk); 240 sock_init_data(sock, sk);
240 sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); 241 sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT);
241 sk->sk_backlog_rcv = backlog_rcv; 242 sk->sk_backlog_rcv = backlog_rcv;
242 tipc_sk(sk)->p = tipc_get_port(portref); 243 tipc_sk(sk)->p = tp_ptr;
244
245 spin_unlock_bh(tp_ptr->lock);
243 246
244 if (sock->state == SS_READY) { 247 if (sock->state == SS_READY) {
245 tipc_set_portunreturnable(portref, 1); 248 tipc_set_portunreturnable(tp_ptr->ref, 1);
246 if (sock->type == SOCK_DGRAM) 249 if (sock->type == SOCK_DGRAM)
247 tipc_set_portunreliable(portref, 1); 250 tipc_set_portunreliable(tp_ptr->ref, 1);
248 } 251 }
249 252
250 atomic_inc(&tipc_user_count); 253 atomic_inc(&tipc_user_count);
@@ -375,27 +378,29 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
375 * @sock: socket structure 378 * @sock: socket structure
376 * @uaddr: area for returned socket address 379 * @uaddr: area for returned socket address
377 * @uaddr_len: area for returned length of socket address 380 * @uaddr_len: area for returned length of socket address
378 * @peer: 0 to obtain socket name, 1 to obtain peer socket name 381 * @peer: 0 = own ID, 1 = current peer ID, 2 = current/former peer ID
379 * 382 *
380 * Returns 0 on success, errno otherwise 383 * Returns 0 on success, errno otherwise
381 * 384 *
382 * NOTE: This routine doesn't need to take the socket lock since it doesn't 385 * NOTE: This routine doesn't need to take the socket lock since it only
383 * access any non-constant socket information. 386 * accesses socket information that is unchanging (or which changes in
387 * a completely predictable manner).
384 */ 388 */
385 389
386static int get_name(struct socket *sock, struct sockaddr *uaddr, 390static int get_name(struct socket *sock, struct sockaddr *uaddr,
387 int *uaddr_len, int peer) 391 int *uaddr_len, int peer)
388{ 392{
389 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 393 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
390 u32 portref = tipc_sk_port(sock->sk)->ref; 394 struct tipc_sock *tsock = tipc_sk(sock->sk);
391 u32 res;
392 395
393 if (peer) { 396 if (peer) {
394 res = tipc_peer(portref, &addr->addr.id); 397 if ((sock->state != SS_CONNECTED) &&
395 if (res) 398 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
396 return res; 399 return -ENOTCONN;
400 addr->addr.id.ref = tsock->peer_name.ref;
401 addr->addr.id.node = tsock->peer_name.node;
397 } else { 402 } else {
398 tipc_ownidentity(portref, &addr->addr.id); 403 tipc_ownidentity(tsock->p->ref, &addr->addr.id);
399 } 404 }
400 405
401 *uaddr_len = sizeof(*addr); 406 *uaddr_len = sizeof(*addr);
@@ -764,18 +769,17 @@ exit:
764 769
765static int auto_connect(struct socket *sock, struct tipc_msg *msg) 770static int auto_connect(struct socket *sock, struct tipc_msg *msg)
766{ 771{
767 struct tipc_port *tport = tipc_sk_port(sock->sk); 772 struct tipc_sock *tsock = tipc_sk(sock->sk);
768 struct tipc_portid peer;
769 773
770 if (msg_errcode(msg)) { 774 if (msg_errcode(msg)) {
771 sock->state = SS_DISCONNECTING; 775 sock->state = SS_DISCONNECTING;
772 return -ECONNREFUSED; 776 return -ECONNREFUSED;
773 } 777 }
774 778
775 peer.ref = msg_origport(msg); 779 tsock->peer_name.ref = msg_origport(msg);
776 peer.node = msg_orignode(msg); 780 tsock->peer_name.node = msg_orignode(msg);
777 tipc_connect2port(tport->ref, &peer); 781 tipc_connect2port(tsock->p->ref, &tsock->peer_name);
778 tipc_set_portimportance(tport->ref, msg_importance(msg)); 782 tipc_set_portimportance(tsock->p->ref, msg_importance(msg));
779 sock->state = SS_CONNECTED; 783 sock->state = SS_CONNECTED;
780 return 0; 784 return 0;
781} 785}
@@ -1131,7 +1135,7 @@ restart:
1131 /* Loop around if more data is required */ 1135 /* Loop around if more data is required */
1132 1136
1133 if ((sz_copied < buf_len) /* didn't get all requested data */ 1137 if ((sz_copied < buf_len) /* didn't get all requested data */
1134 && (!skb_queue_empty(&sock->sk->sk_receive_queue) || 1138 && (!skb_queue_empty(&sk->sk_receive_queue) ||
1135 (flags & MSG_WAITALL)) 1139 (flags & MSG_WAITALL))
1136 /* ... and more is ready or required */ 1140 /* ... and more is ready or required */
1137 && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ 1141 && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */
@@ -1527,9 +1531,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1527 res = tipc_create(sock_net(sock->sk), new_sock, 0); 1531 res = tipc_create(sock_net(sock->sk), new_sock, 0);
1528 if (!res) { 1532 if (!res) {
1529 struct sock *new_sk = new_sock->sk; 1533 struct sock *new_sk = new_sock->sk;
1530 struct tipc_port *new_tport = tipc_sk_port(new_sk); 1534 struct tipc_sock *new_tsock = tipc_sk(new_sk);
1535 struct tipc_port *new_tport = new_tsock->p;
1531 u32 new_ref = new_tport->ref; 1536 u32 new_ref = new_tport->ref;
1532 struct tipc_portid id;
1533 struct tipc_msg *msg = buf_msg(buf); 1537 struct tipc_msg *msg = buf_msg(buf);
1534 1538
1535 lock_sock(new_sk); 1539 lock_sock(new_sk);
@@ -1543,9 +1547,9 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1543 1547
1544 /* Connect new socket to it's peer */ 1548 /* Connect new socket to it's peer */
1545 1549
1546 id.ref = msg_origport(msg); 1550 new_tsock->peer_name.ref = msg_origport(msg);
1547 id.node = msg_orignode(msg); 1551 new_tsock->peer_name.node = msg_orignode(msg);
1548 tipc_connect2port(new_ref, &id); 1552 tipc_connect2port(new_ref, &new_tsock->peer_name);
1549 new_sock->state = SS_CONNECTED; 1553 new_sock->state = SS_CONNECTED;
1550 1554
1551 tipc_set_portimportance(new_ref, msg_importance(msg)); 1555 tipc_set_portimportance(new_ref, msg_importance(msg));