diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 155 |
1 files changed, 62 insertions, 93 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e9f0d5004483..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 | ||
| 81 | static struct proto tipc_proto; | 69 | static struct proto tipc_proto; |
| 82 | 70 | ||
| 83 | static int sockets_enabled = 0; | 71 | static int sockets_enabled; |
| 84 | 72 | ||
| 85 | static atomic_t tipc_queue_size = ATOMIC_INIT(0); | 73 | static 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 | ||
| 393 | static int get_name(struct socket *sock, struct sockaddr *uaddr, | 381 | static int get_name(struct socket *sock, struct sockaddr *uaddr, |
| @@ -404,7 +392,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
| 404 | addr->addr.id.ref = tsock->peer_name.ref; | 392 | addr->addr.id.ref = tsock->peer_name.ref; |
| 405 | addr->addr.id.node = tsock->peer_name.node; | 393 | addr->addr.id.node = tsock->peer_name.node; |
| 406 | } else { | 394 | } else { |
| 407 | tipc_ownidentity(tsock->p->ref, &addr->addr.id); | 395 | addr->addr.id.ref = tsock->p->ref; |
| 396 | addr->addr.id.node = tipc_own_addr; | ||
| 408 | } | 397 | } |
| 409 | 398 | ||
| 410 | *uaddr_len = sizeof(*addr); | 399 | *uaddr_len = sizeof(*addr); |
| @@ -574,37 +563,35 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
| 574 | 563 | ||
| 575 | do { | 564 | do { |
| 576 | if (dest->addrtype == TIPC_ADDR_NAME) { | 565 | if (dest->addrtype == TIPC_ADDR_NAME) { |
| 577 | if ((res = dest_name_check(dest, m))) | 566 | res = dest_name_check(dest, m); |
| 567 | if (res) | ||
| 578 | break; | 568 | break; |
| 579 | res = tipc_send2name(tport->ref, | 569 | res = tipc_send2name(tport->ref, |
| 580 | &dest->addr.name.name, | 570 | &dest->addr.name.name, |
| 581 | dest->addr.name.domain, | 571 | dest->addr.name.domain, |
| 582 | m->msg_iovlen, | 572 | m->msg_iovlen, |
| 583 | m->msg_iov); | 573 | m->msg_iov); |
| 584 | } | 574 | } else if (dest->addrtype == TIPC_ADDR_ID) { |
| 585 | else if (dest->addrtype == TIPC_ADDR_ID) { | ||
| 586 | res = tipc_send2port(tport->ref, | 575 | res = tipc_send2port(tport->ref, |
| 587 | &dest->addr.id, | 576 | &dest->addr.id, |
| 588 | m->msg_iovlen, | 577 | m->msg_iovlen, |
| 589 | m->msg_iov); | 578 | m->msg_iov); |
| 590 | } | 579 | } else if (dest->addrtype == TIPC_ADDR_MCAST) { |
| 591 | else if (dest->addrtype == TIPC_ADDR_MCAST) { | ||
| 592 | if (needs_conn) { | 580 | if (needs_conn) { |
| 593 | res = -EOPNOTSUPP; | 581 | res = -EOPNOTSUPP; |
| 594 | break; | 582 | break; |
| 595 | } | 583 | } |
| 596 | if ((res = dest_name_check(dest, m))) | 584 | res = dest_name_check(dest, m); |
| 585 | if (res) | ||
| 597 | break; | 586 | break; |
| 598 | res = tipc_multicast(tport->ref, | 587 | res = tipc_multicast(tport->ref, |
| 599 | &dest->addr.nameseq, | 588 | &dest->addr.nameseq, |
| 600 | 0, | ||
| 601 | m->msg_iovlen, | 589 | m->msg_iovlen, |
| 602 | m->msg_iov); | 590 | m->msg_iov); |
| 603 | } | 591 | } |
| 604 | if (likely(res != -ELINKCONG)) { | 592 | if (likely(res != -ELINKCONG)) { |
| 605 | if (needs_conn && (res >= 0)) { | 593 | if (needs_conn && (res >= 0)) |
| 606 | sock->state = SS_CONNECTING; | 594 | sock->state = SS_CONNECTING; |
| 607 | } | ||
| 608 | break; | 595 | break; |
| 609 | } | 596 | } |
| 610 | if (m->msg_flags & MSG_DONTWAIT) { | 597 | if (m->msg_flags & MSG_DONTWAIT) { |
| @@ -663,9 +650,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
| 663 | } | 650 | } |
| 664 | 651 | ||
| 665 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); | 652 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); |
| 666 | if (likely(res != -ELINKCONG)) { | 653 | if (likely(res != -ELINKCONG)) |
| 667 | break; | 654 | break; |
| 668 | } | ||
| 669 | if (m->msg_flags & MSG_DONTWAIT) { | 655 | if (m->msg_flags & MSG_DONTWAIT) { |
| 670 | res = -EWOULDBLOCK; | 656 | res = -EWOULDBLOCK; |
| 671 | break; | 657 | break; |
| @@ -764,7 +750,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
| 764 | bytes_to_send = curr_left; | 750 | bytes_to_send = curr_left; |
| 765 | my_iov.iov_base = curr_start; | 751 | my_iov.iov_base = curr_start; |
| 766 | my_iov.iov_len = bytes_to_send; | 752 | my_iov.iov_len = bytes_to_send; |
| 767 | if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { | 753 | res = send_packet(NULL, sock, &my_msg, 0); |
| 754 | if (res < 0) { | ||
| 768 | if (bytes_sent) | 755 | if (bytes_sent) |
| 769 | res = bytes_sent; | 756 | res = bytes_sent; |
| 770 | goto exit; | 757 | goto exit; |
| @@ -824,8 +811,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) | |||
| 824 | addr->addrtype = TIPC_ADDR_ID; | 811 | addr->addrtype = TIPC_ADDR_ID; |
| 825 | addr->addr.id.ref = msg_origport(msg); | 812 | addr->addr.id.ref = msg_origport(msg); |
| 826 | addr->addr.id.node = msg_orignode(msg); | 813 | addr->addr.id.node = msg_orignode(msg); |
| 827 | addr->addr.name.domain = 0; /* could leave uninitialized */ | 814 | addr->addr.name.domain = 0; /* could leave uninitialized */ |
| 828 | addr->scope = 0; /* could leave uninitialized */ | 815 | addr->scope = 0; /* could leave uninitialized */ |
| 829 | m->msg_namelen = sizeof(struct sockaddr_tipc); | 816 | m->msg_namelen = sizeof(struct sockaddr_tipc); |
| 830 | } | 817 | } |
| 831 | } | 818 | } |
| @@ -859,12 +846,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
| 859 | if (unlikely(err)) { | 846 | if (unlikely(err)) { |
| 860 | anc_data[0] = err; | 847 | anc_data[0] = err; |
| 861 | anc_data[1] = msg_data_sz(msg); | 848 | anc_data[1] = msg_data_sz(msg); |
| 862 | if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) | 849 | res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data); |
| 863 | return res; | 850 | if (res) |
| 864 | if (anc_data[1] && | ||
| 865 | (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], | ||
| 866 | msg_data(msg)))) | ||
| 867 | 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 | } | ||
| 868 | } | 858 | } |
| 869 | 859 | ||
| 870 | /* Optionally capture message destination object */ | 860 | /* Optionally capture message destination object */ |
| @@ -892,9 +882,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
| 892 | default: | 882 | default: |
| 893 | has_name = 0; | 883 | has_name = 0; |
| 894 | } | 884 | } |
| 895 | if (has_name && | 885 | if (has_name) { |
| 896 | (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) | 886 | res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data); |
| 897 | return res; | 887 | if (res) |
| 888 | return res; | ||
| 889 | } | ||
| 898 | 890 | ||
| 899 | return 0; | 891 | return 0; |
| 900 | } | 892 | } |
| @@ -1227,42 +1219,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
| 1227 | */ | 1219 | */ |
| 1228 | 1220 | ||
| 1229 | if (sock->state == SS_READY) { | 1221 | if (sock->state == SS_READY) { |
| 1230 | if (msg_connected(msg)) { | 1222 | if (msg_connected(msg)) |
| 1231 | msg_dbg(msg, "dispatch filter 1\n"); | ||
| 1232 | return TIPC_ERR_NO_PORT; | 1223 | return TIPC_ERR_NO_PORT; |
| 1233 | } | ||
| 1234 | } else { | 1224 | } else { |
| 1235 | if (msg_mcast(msg)) { | 1225 | if (msg_mcast(msg)) |
| 1236 | msg_dbg(msg, "dispatch filter 2\n"); | ||
| 1237 | return TIPC_ERR_NO_PORT; | 1226 | return TIPC_ERR_NO_PORT; |
| 1238 | } | ||
| 1239 | if (sock->state == SS_CONNECTED) { | 1227 | if (sock->state == SS_CONNECTED) { |
| 1240 | if (!msg_connected(msg)) { | 1228 | if (!msg_connected(msg)) |
| 1241 | msg_dbg(msg, "dispatch filter 3\n"); | ||
| 1242 | return TIPC_ERR_NO_PORT; | 1229 | return TIPC_ERR_NO_PORT; |
| 1243 | } | 1230 | } else if (sock->state == SS_CONNECTING) { |
| 1244 | } | 1231 | if (!msg_connected(msg) && (msg_errcode(msg) == 0)) |
| 1245 | else if (sock->state == SS_CONNECTING) { | ||
| 1246 | if (!msg_connected(msg) && (msg_errcode(msg) == 0)) { | ||
| 1247 | msg_dbg(msg, "dispatch filter 4\n"); | ||
| 1248 | return TIPC_ERR_NO_PORT; | 1232 | return TIPC_ERR_NO_PORT; |
| 1249 | } | 1233 | } else if (sock->state == SS_LISTENING) { |
| 1250 | } | 1234 | if (msg_connected(msg) || msg_errcode(msg)) |
| 1251 | else if (sock->state == SS_LISTENING) { | ||
| 1252 | if (msg_connected(msg) || msg_errcode(msg)) { | ||
| 1253 | msg_dbg(msg, "dispatch filter 5\n"); | ||
| 1254 | return TIPC_ERR_NO_PORT; | 1235 | return TIPC_ERR_NO_PORT; |
| 1255 | } | 1236 | } else if (sock->state == SS_DISCONNECTING) { |
| 1256 | } | ||
| 1257 | else if (sock->state == SS_DISCONNECTING) { | ||
| 1258 | msg_dbg(msg, "dispatch filter 6\n"); | ||
| 1259 | return TIPC_ERR_NO_PORT; | 1237 | return TIPC_ERR_NO_PORT; |
| 1260 | } | 1238 | } else /* (sock->state == SS_UNCONNECTED) */ { |
| 1261 | else /* (sock->state == SS_UNCONNECTED) */ { | 1239 | if (msg_connected(msg) || msg_errcode(msg)) |
| 1262 | if (msg_connected(msg) || msg_errcode(msg)) { | ||
| 1263 | msg_dbg(msg, "dispatch filter 7\n"); | ||
| 1264 | return TIPC_ERR_NO_PORT; | 1240 | return TIPC_ERR_NO_PORT; |
| 1265 | } | ||
| 1266 | } | 1241 | } |
| 1267 | } | 1242 | } |
| 1268 | 1243 | ||
| @@ -1281,7 +1256,6 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
| 1281 | 1256 | ||
| 1282 | /* Enqueue message (finally!) */ | 1257 | /* Enqueue message (finally!) */ |
| 1283 | 1258 | ||
| 1284 | msg_dbg(msg, "<DISP<: "); | ||
| 1285 | TIPC_SKB_CB(buf)->handle = msg_data(msg); | 1259 | TIPC_SKB_CB(buf)->handle = msg_data(msg); |
| 1286 | atomic_inc(&tipc_queue_size); | 1260 | atomic_inc(&tipc_queue_size); |
| 1287 | __skb_queue_tail(&sk->sk_receive_queue, buf); | 1261 | __skb_queue_tail(&sk->sk_receive_queue, buf); |
| @@ -1442,9 +1416,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
| 1442 | m.msg_name = dest; | 1416 | m.msg_name = dest; |
| 1443 | m.msg_namelen = destlen; | 1417 | m.msg_namelen = destlen; |
| 1444 | res = send_msg(NULL, sock, &m, 0); | 1418 | res = send_msg(NULL, sock, &m, 0); |
| 1445 | if (res < 0) { | 1419 | if (res < 0) |
| 1446 | goto exit; | 1420 | goto exit; |
| 1447 | } | ||
| 1448 | 1421 | ||
| 1449 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ | 1422 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ |
| 1450 | 1423 | ||
| @@ -1466,11 +1439,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
| 1466 | advance_rx_queue(sk); | 1439 | advance_rx_queue(sk); |
| 1467 | } | 1440 | } |
| 1468 | } else { | 1441 | } else { |
| 1469 | if (sock->state == SS_CONNECTED) { | 1442 | if (sock->state == SS_CONNECTED) |
| 1470 | res = -EISCONN; | 1443 | res = -EISCONN; |
| 1471 | } else { | 1444 | else |
| 1472 | res = -ECONNREFUSED; | 1445 | res = -ECONNREFUSED; |
| 1473 | } | ||
| 1474 | } | 1446 | } |
| 1475 | } else { | 1447 | } else { |
| 1476 | if (res == 0) | 1448 | if (res == 0) |
| @@ -1589,7 +1561,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 1589 | * Respond to 'SYN+' by queuing it on new socket. | 1561 | * Respond to 'SYN+' by queuing it on new socket. |
| 1590 | */ | 1562 | */ |
| 1591 | 1563 | ||
| 1592 | msg_dbg(msg,"<ACC<: "); | ||
| 1593 | if (!msg_data_sz(msg)) { | 1564 | if (!msg_data_sz(msg)) { |
| 1594 | struct msghdr m = {NULL,}; | 1565 | struct msghdr m = {NULL,}; |
| 1595 | 1566 | ||
| @@ -1697,7 +1668,8 @@ static int setsockopt(struct socket *sock, | |||
| 1697 | return -ENOPROTOOPT; | 1668 | return -ENOPROTOOPT; |
| 1698 | if (ol < sizeof(value)) | 1669 | if (ol < sizeof(value)) |
| 1699 | return -EINVAL; | 1670 | return -EINVAL; |
| 1700 | if ((res = get_user(value, (u32 __user *)ov))) | 1671 | res = get_user(value, (u32 __user *)ov); |
| 1672 | if (res) | ||
| 1701 | return res; | 1673 | return res; |
| 1702 | 1674 | ||
| 1703 | lock_sock(sk); | 1675 | lock_sock(sk); |
| @@ -1755,7 +1727,8 @@ static int getsockopt(struct socket *sock, | |||
| 1755 | return put_user(0, ol); | 1727 | return put_user(0, ol); |
| 1756 | if (lvl != SOL_TIPC) | 1728 | if (lvl != SOL_TIPC) |
| 1757 | return -ENOPROTOOPT; | 1729 | return -ENOPROTOOPT; |
| 1758 | if ((res = get_user(len, ol))) | 1730 | res = get_user(len, ol); |
| 1731 | if (res) | ||
| 1759 | return res; | 1732 | return res; |
| 1760 | 1733 | ||
| 1761 | lock_sock(sk); | 1734 | lock_sock(sk); |
| @@ -1774,10 +1747,10 @@ static int getsockopt(struct socket *sock, | |||
| 1774 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); | 1747 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); |
| 1775 | /* no need to set "res", since already 0 at this point */ | 1748 | /* no need to set "res", since already 0 at this point */ |
| 1776 | break; | 1749 | break; |
| 1777 | case TIPC_NODE_RECVQ_DEPTH: | 1750 | case TIPC_NODE_RECVQ_DEPTH: |
| 1778 | value = (u32)atomic_read(&tipc_queue_size); | 1751 | value = (u32)atomic_read(&tipc_queue_size); |
| 1779 | break; | 1752 | break; |
| 1780 | case TIPC_SOCK_RECVQ_DEPTH: | 1753 | case TIPC_SOCK_RECVQ_DEPTH: |
| 1781 | value = skb_queue_len(&sk->sk_receive_queue); | 1754 | value = skb_queue_len(&sk->sk_receive_queue); |
| 1782 | break; | 1755 | break; |
| 1783 | default: | 1756 | default: |
| @@ -1786,20 +1759,16 @@ static int getsockopt(struct socket *sock, | |||
| 1786 | 1759 | ||
| 1787 | release_sock(sk); | 1760 | release_sock(sk); |
| 1788 | 1761 | ||
| 1789 | if (res) { | 1762 | if (res) |
| 1790 | /* "get" failed */ | 1763 | return res; /* "get" failed */ |
| 1791 | } | ||
| 1792 | else if (len < sizeof(value)) { | ||
| 1793 | res = -EINVAL; | ||
| 1794 | } | ||
| 1795 | else if (copy_to_user(ov, &value, sizeof(value))) { | ||
| 1796 | res = -EFAULT; | ||
| 1797 | } | ||
| 1798 | else { | ||
| 1799 | res = put_user(sizeof(value), ol); | ||
| 1800 | } | ||
| 1801 | 1764 | ||
| 1802 | 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); | ||
| 1803 | } | 1772 | } |
| 1804 | 1773 | ||
| 1805 | /** | 1774 | /** |
| @@ -1807,7 +1776,7 @@ static int getsockopt(struct socket *sock, | |||
| 1807 | */ | 1776 | */ |
| 1808 | 1777 | ||
| 1809 | static const struct proto_ops msg_ops = { | 1778 | static const struct proto_ops msg_ops = { |
| 1810 | .owner = THIS_MODULE, | 1779 | .owner = THIS_MODULE, |
| 1811 | .family = AF_TIPC, | 1780 | .family = AF_TIPC, |
| 1812 | .release = release, | 1781 | .release = release, |
| 1813 | .bind = bind, | 1782 | .bind = bind, |
| @@ -1828,7 +1797,7 @@ static const struct proto_ops msg_ops = { | |||
| 1828 | }; | 1797 | }; |
| 1829 | 1798 | ||
| 1830 | static const struct proto_ops packet_ops = { | 1799 | static const struct proto_ops packet_ops = { |
| 1831 | .owner = THIS_MODULE, | 1800 | .owner = THIS_MODULE, |
| 1832 | .family = AF_TIPC, | 1801 | .family = AF_TIPC, |
| 1833 | .release = release, | 1802 | .release = release, |
| 1834 | .bind = bind, | 1803 | .bind = bind, |
| @@ -1849,7 +1818,7 @@ static const struct proto_ops packet_ops = { | |||
| 1849 | }; | 1818 | }; |
| 1850 | 1819 | ||
| 1851 | static const struct proto_ops stream_ops = { | 1820 | static const struct proto_ops stream_ops = { |
| 1852 | .owner = THIS_MODULE, | 1821 | .owner = THIS_MODULE, |
| 1853 | .family = AF_TIPC, | 1822 | .family = AF_TIPC, |
| 1854 | .release = release, | 1823 | .release = release, |
| 1855 | .bind = bind, | 1824 | .bind = bind, |
| @@ -1870,7 +1839,7 @@ static const struct proto_ops stream_ops = { | |||
| 1870 | }; | 1839 | }; |
| 1871 | 1840 | ||
| 1872 | static const struct net_proto_family tipc_family_ops = { | 1841 | static const struct net_proto_family tipc_family_ops = { |
| 1873 | .owner = THIS_MODULE, | 1842 | .owner = THIS_MODULE, |
| 1874 | .family = AF_TIPC, | 1843 | .family = AF_TIPC, |
| 1875 | .create = tipc_create | 1844 | .create = tipc_create |
| 1876 | }; | 1845 | }; |
