aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2011-01-14 08:12:37 -0500
committerPatrick McHardy <kaber@trash.net>2011-01-14 08:12:37 -0500
commit0134e89c7bcc9fde1da962c82a120691e185619f (patch)
tree3e03335cf001019a2687d161e956de4f73379984 /net/tipc/socket.c
parentc7066f70d9610df0b9406cc635fc09e86136e714 (diff)
parent6faee60a4e82075853a437831768cc9e2e563e4e (diff)
Merge branch 'master' of git://1984.lsi.us.es/net-next-2.6
Conflicts: net/ipv4/route.c Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c156
1 files changed, 63 insertions, 93 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 33217fc3d697..2b02a3a80313 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -34,25 +34,13 @@
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <linux/module.h>
38#include <linux/types.h>
39#include <linux/net.h>
40#include <linux/socket.h>
41#include <linux/errno.h>
42#include <linux/mm.h>
43#include <linux/poll.h>
44#include <linux/fcntl.h>
45#include <linux/gfp.h>
46#include <asm/string.h>
47#include <asm/atomic.h>
48#include <net/sock.h> 37#include <net/sock.h>
49 38
50#include <linux/tipc.h> 39#include <linux/tipc.h>
51#include <linux/tipc_config.h> 40#include <linux/tipc_config.h>
52#include <net/tipc/tipc_msg.h>
53#include <net/tipc/tipc_port.h>
54 41
55#include "core.h" 42#include "core.h"
43#include "port.h"
56 44
57#define SS_LISTENING -1 /* socket is listening */ 45#define SS_LISTENING -1 /* socket is listening */
58#define SS_READY -2 /* socket is connectionless */ 46#define SS_READY -2 /* socket is connectionless */
@@ -80,7 +68,7 @@ static const struct proto_ops msg_ops;
80 68
81static struct proto tipc_proto; 69static struct proto tipc_proto;
82 70
83static int sockets_enabled = 0; 71static int sockets_enabled;
84 72
85static atomic_t tipc_queue_size = ATOMIC_INIT(0); 73static atomic_t tipc_queue_size = ATOMIC_INIT(0);
86 74
@@ -387,7 +375,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
387 * 375 *
388 * NOTE: This routine doesn't need to take the socket lock since it only 376 * NOTE: This routine doesn't need to take the socket lock since it only
389 * accesses socket information that is unchanging (or which changes in 377 * accesses socket information that is unchanging (or which changes in
390 * a completely predictable manner). 378 * a completely predictable manner).
391 */ 379 */
392 380
393static int get_name(struct socket *sock, struct sockaddr *uaddr, 381static int get_name(struct socket *sock, struct sockaddr *uaddr,
@@ -396,6 +384,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
396 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; 384 struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
397 struct tipc_sock *tsock = tipc_sk(sock->sk); 385 struct tipc_sock *tsock = tipc_sk(sock->sk);
398 386
387 memset(addr, 0, sizeof(*addr));
399 if (peer) { 388 if (peer) {
400 if ((sock->state != SS_CONNECTED) && 389 if ((sock->state != SS_CONNECTED) &&
401 ((peer != 2) || (sock->state != SS_DISCONNECTING))) 390 ((peer != 2) || (sock->state != SS_DISCONNECTING)))
@@ -403,7 +392,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr,
403 addr->addr.id.ref = tsock->peer_name.ref; 392 addr->addr.id.ref = tsock->peer_name.ref;
404 addr->addr.id.node = tsock->peer_name.node; 393 addr->addr.id.node = tsock->peer_name.node;
405 } else { 394 } else {
406 tipc_ownidentity(tsock->p->ref, &addr->addr.id); 395 addr->addr.id.ref = tsock->p->ref;
396 addr->addr.id.node = tipc_own_addr;
407 } 397 }
408 398
409 *uaddr_len = sizeof(*addr); 399 *uaddr_len = sizeof(*addr);
@@ -573,37 +563,35 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
573 563
574 do { 564 do {
575 if (dest->addrtype == TIPC_ADDR_NAME) { 565 if (dest->addrtype == TIPC_ADDR_NAME) {
576 if ((res = dest_name_check(dest, m))) 566 res = dest_name_check(dest, m);
567 if (res)
577 break; 568 break;
578 res = tipc_send2name(tport->ref, 569 res = tipc_send2name(tport->ref,
579 &dest->addr.name.name, 570 &dest->addr.name.name,
580 dest->addr.name.domain, 571 dest->addr.name.domain,
581 m->msg_iovlen, 572 m->msg_iovlen,
582 m->msg_iov); 573 m->msg_iov);
583 } 574 } else if (dest->addrtype == TIPC_ADDR_ID) {
584 else if (dest->addrtype == TIPC_ADDR_ID) {
585 res = tipc_send2port(tport->ref, 575 res = tipc_send2port(tport->ref,
586 &dest->addr.id, 576 &dest->addr.id,
587 m->msg_iovlen, 577 m->msg_iovlen,
588 m->msg_iov); 578 m->msg_iov);
589 } 579 } else if (dest->addrtype == TIPC_ADDR_MCAST) {
590 else if (dest->addrtype == TIPC_ADDR_MCAST) {
591 if (needs_conn) { 580 if (needs_conn) {
592 res = -EOPNOTSUPP; 581 res = -EOPNOTSUPP;
593 break; 582 break;
594 } 583 }
595 if ((res = dest_name_check(dest, m))) 584 res = dest_name_check(dest, m);
585 if (res)
596 break; 586 break;
597 res = tipc_multicast(tport->ref, 587 res = tipc_multicast(tport->ref,
598 &dest->addr.nameseq, 588 &dest->addr.nameseq,
599 0,
600 m->msg_iovlen, 589 m->msg_iovlen,
601 m->msg_iov); 590 m->msg_iov);
602 } 591 }
603 if (likely(res != -ELINKCONG)) { 592 if (likely(res != -ELINKCONG)) {
604 if (needs_conn && (res >= 0)) { 593 if (needs_conn && (res >= 0))
605 sock->state = SS_CONNECTING; 594 sock->state = SS_CONNECTING;
606 }
607 break; 595 break;
608 } 596 }
609 if (m->msg_flags & MSG_DONTWAIT) { 597 if (m->msg_flags & MSG_DONTWAIT) {
@@ -662,9 +650,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
662 } 650 }
663 651
664 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); 652 res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov);
665 if (likely(res != -ELINKCONG)) { 653 if (likely(res != -ELINKCONG))
666 break; 654 break;
667 }
668 if (m->msg_flags & MSG_DONTWAIT) { 655 if (m->msg_flags & MSG_DONTWAIT) {
669 res = -EWOULDBLOCK; 656 res = -EWOULDBLOCK;
670 break; 657 break;
@@ -763,7 +750,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
763 bytes_to_send = curr_left; 750 bytes_to_send = curr_left;
764 my_iov.iov_base = curr_start; 751 my_iov.iov_base = curr_start;
765 my_iov.iov_len = bytes_to_send; 752 my_iov.iov_len = bytes_to_send;
766 if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { 753 res = send_packet(NULL, sock, &my_msg, 0);
754 if (res < 0) {
767 if (bytes_sent) 755 if (bytes_sent)
768 res = bytes_sent; 756 res = bytes_sent;
769 goto exit; 757 goto exit;
@@ -823,8 +811,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
823 addr->addrtype = TIPC_ADDR_ID; 811 addr->addrtype = TIPC_ADDR_ID;
824 addr->addr.id.ref = msg_origport(msg); 812 addr->addr.id.ref = msg_origport(msg);
825 addr->addr.id.node = msg_orignode(msg); 813 addr->addr.id.node = msg_orignode(msg);
826 addr->addr.name.domain = 0; /* could leave uninitialized */ 814 addr->addr.name.domain = 0; /* could leave uninitialized */
827 addr->scope = 0; /* could leave uninitialized */ 815 addr->scope = 0; /* could leave uninitialized */
828 m->msg_namelen = sizeof(struct sockaddr_tipc); 816 m->msg_namelen = sizeof(struct sockaddr_tipc);
829 } 817 }
830} 818}
@@ -858,12 +846,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
858 if (unlikely(err)) { 846 if (unlikely(err)) {
859 anc_data[0] = err; 847 anc_data[0] = err;
860 anc_data[1] = msg_data_sz(msg); 848 anc_data[1] = msg_data_sz(msg);
861 if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) 849 res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data);
862 return res; 850 if (res)
863 if (anc_data[1] &&
864 (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
865 msg_data(msg))))
866 return res; 851 return res;
852 if (anc_data[1]) {
853 res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1],
854 msg_data(msg));
855 if (res)
856 return res;
857 }
867 } 858 }
868 859
869 /* Optionally capture message destination object */ 860 /* Optionally capture message destination object */
@@ -891,9 +882,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
891 default: 882 default:
892 has_name = 0; 883 has_name = 0;
893 } 884 }
894 if (has_name && 885 if (has_name) {
895 (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) 886 res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data);
896 return res; 887 if (res)
888 return res;
889 }
897 890
898 return 0; 891 return 0;
899} 892}
@@ -1226,42 +1219,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1226 */ 1219 */
1227 1220
1228 if (sock->state == SS_READY) { 1221 if (sock->state == SS_READY) {
1229 if (msg_connected(msg)) { 1222 if (msg_connected(msg))
1230 msg_dbg(msg, "dispatch filter 1\n");
1231 return TIPC_ERR_NO_PORT; 1223 return TIPC_ERR_NO_PORT;
1232 }
1233 } else { 1224 } else {
1234 if (msg_mcast(msg)) { 1225 if (msg_mcast(msg))
1235 msg_dbg(msg, "dispatch filter 2\n");
1236 return TIPC_ERR_NO_PORT; 1226 return TIPC_ERR_NO_PORT;
1237 }
1238 if (sock->state == SS_CONNECTED) { 1227 if (sock->state == SS_CONNECTED) {
1239 if (!msg_connected(msg)) { 1228 if (!msg_connected(msg))
1240 msg_dbg(msg, "dispatch filter 3\n");
1241 return TIPC_ERR_NO_PORT; 1229 return TIPC_ERR_NO_PORT;
1242 } 1230 } else if (sock->state == SS_CONNECTING) {
1243 } 1231 if (!msg_connected(msg) && (msg_errcode(msg) == 0))
1244 else if (sock->state == SS_CONNECTING) {
1245 if (!msg_connected(msg) && (msg_errcode(msg) == 0)) {
1246 msg_dbg(msg, "dispatch filter 4\n");
1247 return TIPC_ERR_NO_PORT; 1232 return TIPC_ERR_NO_PORT;
1248 } 1233 } else if (sock->state == SS_LISTENING) {
1249 } 1234 if (msg_connected(msg) || msg_errcode(msg))
1250 else if (sock->state == SS_LISTENING) {
1251 if (msg_connected(msg) || msg_errcode(msg)) {
1252 msg_dbg(msg, "dispatch filter 5\n");
1253 return TIPC_ERR_NO_PORT; 1235 return TIPC_ERR_NO_PORT;
1254 } 1236 } else if (sock->state == SS_DISCONNECTING) {
1255 }
1256 else if (sock->state == SS_DISCONNECTING) {
1257 msg_dbg(msg, "dispatch filter 6\n");
1258 return TIPC_ERR_NO_PORT; 1237 return TIPC_ERR_NO_PORT;
1259 } 1238 } else /* (sock->state == SS_UNCONNECTED) */ {
1260 else /* (sock->state == SS_UNCONNECTED) */ { 1239 if (msg_connected(msg) || msg_errcode(msg))
1261 if (msg_connected(msg) || msg_errcode(msg)) {
1262 msg_dbg(msg, "dispatch filter 7\n");
1263 return TIPC_ERR_NO_PORT; 1240 return TIPC_ERR_NO_PORT;
1264 }
1265 } 1241 }
1266 } 1242 }
1267 1243
@@ -1280,7 +1256,6 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
1280 1256
1281 /* Enqueue message (finally!) */ 1257 /* Enqueue message (finally!) */
1282 1258
1283 msg_dbg(msg, "<DISP<: ");
1284 TIPC_SKB_CB(buf)->handle = msg_data(msg); 1259 TIPC_SKB_CB(buf)->handle = msg_data(msg);
1285 atomic_inc(&tipc_queue_size); 1260 atomic_inc(&tipc_queue_size);
1286 __skb_queue_tail(&sk->sk_receive_queue, buf); 1261 __skb_queue_tail(&sk->sk_receive_queue, buf);
@@ -1441,9 +1416,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1441 m.msg_name = dest; 1416 m.msg_name = dest;
1442 m.msg_namelen = destlen; 1417 m.msg_namelen = destlen;
1443 res = send_msg(NULL, sock, &m, 0); 1418 res = send_msg(NULL, sock, &m, 0);
1444 if (res < 0) { 1419 if (res < 0)
1445 goto exit; 1420 goto exit;
1446 }
1447 1421
1448 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ 1422 /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */
1449 1423
@@ -1465,11 +1439,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen,
1465 advance_rx_queue(sk); 1439 advance_rx_queue(sk);
1466 } 1440 }
1467 } else { 1441 } else {
1468 if (sock->state == SS_CONNECTED) { 1442 if (sock->state == SS_CONNECTED)
1469 res = -EISCONN; 1443 res = -EISCONN;
1470 } else { 1444 else
1471 res = -ECONNREFUSED; 1445 res = -ECONNREFUSED;
1472 }
1473 } 1446 }
1474 } else { 1447 } else {
1475 if (res == 0) 1448 if (res == 0)
@@ -1588,7 +1561,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags)
1588 * Respond to 'SYN+' by queuing it on new socket. 1561 * Respond to 'SYN+' by queuing it on new socket.
1589 */ 1562 */
1590 1563
1591 msg_dbg(msg,"<ACC<: ");
1592 if (!msg_data_sz(msg)) { 1564 if (!msg_data_sz(msg)) {
1593 struct msghdr m = {NULL,}; 1565 struct msghdr m = {NULL,};
1594 1566
@@ -1696,7 +1668,8 @@ static int setsockopt(struct socket *sock,
1696 return -ENOPROTOOPT; 1668 return -ENOPROTOOPT;
1697 if (ol < sizeof(value)) 1669 if (ol < sizeof(value))
1698 return -EINVAL; 1670 return -EINVAL;
1699 if ((res = get_user(value, (u32 __user *)ov))) 1671 res = get_user(value, (u32 __user *)ov);
1672 if (res)
1700 return res; 1673 return res;
1701 1674
1702 lock_sock(sk); 1675 lock_sock(sk);
@@ -1754,7 +1727,8 @@ static int getsockopt(struct socket *sock,
1754 return put_user(0, ol); 1727 return put_user(0, ol);
1755 if (lvl != SOL_TIPC) 1728 if (lvl != SOL_TIPC)
1756 return -ENOPROTOOPT; 1729 return -ENOPROTOOPT;
1757 if ((res = get_user(len, ol))) 1730 res = get_user(len, ol);
1731 if (res)
1758 return res; 1732 return res;
1759 1733
1760 lock_sock(sk); 1734 lock_sock(sk);
@@ -1773,10 +1747,10 @@ static int getsockopt(struct socket *sock,
1773 value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); 1747 value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout);
1774 /* no need to set "res", since already 0 at this point */ 1748 /* no need to set "res", since already 0 at this point */
1775 break; 1749 break;
1776 case TIPC_NODE_RECVQ_DEPTH: 1750 case TIPC_NODE_RECVQ_DEPTH:
1777 value = (u32)atomic_read(&tipc_queue_size); 1751 value = (u32)atomic_read(&tipc_queue_size);
1778 break; 1752 break;
1779 case TIPC_SOCK_RECVQ_DEPTH: 1753 case TIPC_SOCK_RECVQ_DEPTH:
1780 value = skb_queue_len(&sk->sk_receive_queue); 1754 value = skb_queue_len(&sk->sk_receive_queue);
1781 break; 1755 break;
1782 default: 1756 default:
@@ -1785,20 +1759,16 @@ static int getsockopt(struct socket *sock,
1785 1759
1786 release_sock(sk); 1760 release_sock(sk);
1787 1761
1788 if (res) { 1762 if (res)
1789 /* "get" failed */ 1763 return res; /* "get" failed */
1790 }
1791 else if (len < sizeof(value)) {
1792 res = -EINVAL;
1793 }
1794 else if (copy_to_user(ov, &value, sizeof(value))) {
1795 res = -EFAULT;
1796 }
1797 else {
1798 res = put_user(sizeof(value), ol);
1799 }
1800 1764
1801 return res; 1765 if (len < sizeof(value))
1766 return -EINVAL;
1767
1768 if (copy_to_user(ov, &value, sizeof(value)))
1769 return -EFAULT;
1770
1771 return put_user(sizeof(value), ol);
1802} 1772}
1803 1773
1804/** 1774/**
@@ -1806,7 +1776,7 @@ static int getsockopt(struct socket *sock,
1806 */ 1776 */
1807 1777
1808static const struct proto_ops msg_ops = { 1778static const struct proto_ops msg_ops = {
1809 .owner = THIS_MODULE, 1779 .owner = THIS_MODULE,
1810 .family = AF_TIPC, 1780 .family = AF_TIPC,
1811 .release = release, 1781 .release = release,
1812 .bind = bind, 1782 .bind = bind,
@@ -1827,7 +1797,7 @@ static const struct proto_ops msg_ops = {
1827}; 1797};
1828 1798
1829static const struct proto_ops packet_ops = { 1799static const struct proto_ops packet_ops = {
1830 .owner = THIS_MODULE, 1800 .owner = THIS_MODULE,
1831 .family = AF_TIPC, 1801 .family = AF_TIPC,
1832 .release = release, 1802 .release = release,
1833 .bind = bind, 1803 .bind = bind,
@@ -1848,7 +1818,7 @@ static const struct proto_ops packet_ops = {
1848}; 1818};
1849 1819
1850static const struct proto_ops stream_ops = { 1820static const struct proto_ops stream_ops = {
1851 .owner = THIS_MODULE, 1821 .owner = THIS_MODULE,
1852 .family = AF_TIPC, 1822 .family = AF_TIPC,
1853 .release = release, 1823 .release = release,
1854 .bind = bind, 1824 .bind = bind,
@@ -1869,7 +1839,7 @@ static const struct proto_ops stream_ops = {
1869}; 1839};
1870 1840
1871static const struct net_proto_family tipc_family_ops = { 1841static const struct net_proto_family tipc_family_ops = {
1872 .owner = THIS_MODULE, 1842 .owner = THIS_MODULE,
1873 .family = AF_TIPC, 1843 .family = AF_TIPC,
1874 .create = tipc_create 1844 .create = tipc_create
1875}; 1845};