diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 62 |
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 @@ | |||
63 | struct tipc_sock { | 63 | struct 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 | ||
386 | static int get_name(struct socket *sock, struct sockaddr *uaddr, | 390 | static 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 | ||
765 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) | 770 | static 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)); |