diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 231 |
1 files changed, 97 insertions, 134 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e9f0d5004483..29d94d53198d 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-2008, Wind River Systems | 5 | * Copyright (c) 2004-2008, 2010-2011, 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 |
@@ -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 */ |
@@ -70,6 +58,9 @@ struct tipc_sock { | |||
70 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) | 58 | #define tipc_sk(sk) ((struct tipc_sock *)(sk)) |
71 | #define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) | 59 | #define tipc_sk_port(sk) ((struct tipc_port *)(tipc_sk(sk)->p)) |
72 | 60 | ||
61 | #define tipc_rx_ready(sock) (!skb_queue_empty(&sock->sk->sk_receive_queue) || \ | ||
62 | (sock->state == SS_DISCONNECTING)) | ||
63 | |||
73 | static int backlog_rcv(struct sock *sk, struct sk_buff *skb); | 64 | static int backlog_rcv(struct sock *sk, struct sk_buff *skb); |
74 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); | 65 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); |
75 | static void wakeupdispatch(struct tipc_port *tport); | 66 | static void wakeupdispatch(struct tipc_port *tport); |
@@ -80,7 +71,7 @@ static const struct proto_ops msg_ops; | |||
80 | 71 | ||
81 | static struct proto tipc_proto; | 72 | static struct proto tipc_proto; |
82 | 73 | ||
83 | static int sockets_enabled = 0; | 74 | static int sockets_enabled; |
84 | 75 | ||
85 | static atomic_t tipc_queue_size = ATOMIC_INIT(0); | 76 | static atomic_t tipc_queue_size = ATOMIC_INIT(0); |
86 | 77 | ||
@@ -253,7 +244,6 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
253 | tipc_set_portunreliable(tp_ptr->ref, 1); | 244 | tipc_set_portunreliable(tp_ptr->ref, 1); |
254 | } | 245 | } |
255 | 246 | ||
256 | atomic_inc(&tipc_user_count); | ||
257 | return 0; | 247 | return 0; |
258 | } | 248 | } |
259 | 249 | ||
@@ -302,7 +292,7 @@ static int release(struct socket *sock) | |||
302 | if (buf == NULL) | 292 | if (buf == NULL) |
303 | break; | 293 | break; |
304 | atomic_dec(&tipc_queue_size); | 294 | atomic_dec(&tipc_queue_size); |
305 | if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) | 295 | if (TIPC_SKB_CB(buf)->handle != 0) |
306 | buf_discard(buf); | 296 | buf_discard(buf); |
307 | else { | 297 | else { |
308 | if ((sock->state == SS_CONNECTING) || | 298 | if ((sock->state == SS_CONNECTING) || |
@@ -333,7 +323,6 @@ static int release(struct socket *sock) | |||
333 | sock_put(sk); | 323 | sock_put(sk); |
334 | sock->sk = NULL; | 324 | sock->sk = NULL; |
335 | 325 | ||
336 | atomic_dec(&tipc_user_count); | ||
337 | return res; | 326 | return res; |
338 | } | 327 | } |
339 | 328 | ||
@@ -387,7 +376,7 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | |||
387 | * | 376 | * |
388 | * NOTE: This routine doesn't need to take the socket lock since it only | 377 | * 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 | 378 | * accesses socket information that is unchanging (or which changes in |
390 | * a completely predictable manner). | 379 | * a completely predictable manner). |
391 | */ | 380 | */ |
392 | 381 | ||
393 | static int get_name(struct socket *sock, struct sockaddr *uaddr, | 382 | static int get_name(struct socket *sock, struct sockaddr *uaddr, |
@@ -404,7 +393,8 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
404 | addr->addr.id.ref = tsock->peer_name.ref; | 393 | addr->addr.id.ref = tsock->peer_name.ref; |
405 | addr->addr.id.node = tsock->peer_name.node; | 394 | addr->addr.id.node = tsock->peer_name.node; |
406 | } else { | 395 | } else { |
407 | tipc_ownidentity(tsock->p->ref, &addr->addr.id); | 396 | addr->addr.id.ref = tsock->p->ref; |
397 | addr->addr.id.node = tipc_own_addr; | ||
408 | } | 398 | } |
409 | 399 | ||
410 | *uaddr_len = sizeof(*addr); | 400 | *uaddr_len = sizeof(*addr); |
@@ -506,6 +496,8 @@ static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m) | |||
506 | if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) | 496 | if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) |
507 | return -EACCES; | 497 | return -EACCES; |
508 | 498 | ||
499 | if (!m->msg_iovlen || (m->msg_iov[0].iov_len < sizeof(hdr))) | ||
500 | return -EMSGSIZE; | ||
509 | if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) | 501 | if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) |
510 | return -EFAULT; | 502 | return -EFAULT; |
511 | if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN))) | 503 | if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN))) |
@@ -574,37 +566,35 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
574 | 566 | ||
575 | do { | 567 | do { |
576 | if (dest->addrtype == TIPC_ADDR_NAME) { | 568 | if (dest->addrtype == TIPC_ADDR_NAME) { |
577 | if ((res = dest_name_check(dest, m))) | 569 | res = dest_name_check(dest, m); |
570 | if (res) | ||
578 | break; | 571 | break; |
579 | res = tipc_send2name(tport->ref, | 572 | res = tipc_send2name(tport->ref, |
580 | &dest->addr.name.name, | 573 | &dest->addr.name.name, |
581 | dest->addr.name.domain, | 574 | dest->addr.name.domain, |
582 | m->msg_iovlen, | 575 | m->msg_iovlen, |
583 | m->msg_iov); | 576 | m->msg_iov); |
584 | } | 577 | } else if (dest->addrtype == TIPC_ADDR_ID) { |
585 | else if (dest->addrtype == TIPC_ADDR_ID) { | ||
586 | res = tipc_send2port(tport->ref, | 578 | res = tipc_send2port(tport->ref, |
587 | &dest->addr.id, | 579 | &dest->addr.id, |
588 | m->msg_iovlen, | 580 | m->msg_iovlen, |
589 | m->msg_iov); | 581 | m->msg_iov); |
590 | } | 582 | } else if (dest->addrtype == TIPC_ADDR_MCAST) { |
591 | else if (dest->addrtype == TIPC_ADDR_MCAST) { | ||
592 | if (needs_conn) { | 583 | if (needs_conn) { |
593 | res = -EOPNOTSUPP; | 584 | res = -EOPNOTSUPP; |
594 | break; | 585 | break; |
595 | } | 586 | } |
596 | if ((res = dest_name_check(dest, m))) | 587 | res = dest_name_check(dest, m); |
588 | if (res) | ||
597 | break; | 589 | break; |
598 | res = tipc_multicast(tport->ref, | 590 | res = tipc_multicast(tport->ref, |
599 | &dest->addr.nameseq, | 591 | &dest->addr.nameseq, |
600 | 0, | ||
601 | m->msg_iovlen, | 592 | m->msg_iovlen, |
602 | m->msg_iov); | 593 | m->msg_iov); |
603 | } | 594 | } |
604 | if (likely(res != -ELINKCONG)) { | 595 | if (likely(res != -ELINKCONG)) { |
605 | if (needs_conn && (res >= 0)) { | 596 | if (needs_conn && (res >= 0)) |
606 | sock->state = SS_CONNECTING; | 597 | sock->state = SS_CONNECTING; |
607 | } | ||
608 | break; | 598 | break; |
609 | } | 599 | } |
610 | if (m->msg_flags & MSG_DONTWAIT) { | 600 | if (m->msg_flags & MSG_DONTWAIT) { |
@@ -663,9 +653,8 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
663 | } | 653 | } |
664 | 654 | ||
665 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); | 655 | res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov); |
666 | if (likely(res != -ELINKCONG)) { | 656 | if (likely(res != -ELINKCONG)) |
667 | break; | 657 | break; |
668 | } | ||
669 | if (m->msg_flags & MSG_DONTWAIT) { | 658 | if (m->msg_flags & MSG_DONTWAIT) { |
670 | res = -EWOULDBLOCK; | 659 | res = -EWOULDBLOCK; |
671 | break; | 660 | break; |
@@ -764,7 +753,8 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
764 | bytes_to_send = curr_left; | 753 | bytes_to_send = curr_left; |
765 | my_iov.iov_base = curr_start; | 754 | my_iov.iov_base = curr_start; |
766 | my_iov.iov_len = bytes_to_send; | 755 | my_iov.iov_len = bytes_to_send; |
767 | if ((res = send_packet(NULL, sock, &my_msg, 0)) < 0) { | 756 | res = send_packet(NULL, sock, &my_msg, 0); |
757 | if (res < 0) { | ||
768 | if (bytes_sent) | 758 | if (bytes_sent) |
769 | res = bytes_sent; | 759 | res = bytes_sent; |
770 | goto exit; | 760 | goto exit; |
@@ -824,8 +814,8 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) | |||
824 | addr->addrtype = TIPC_ADDR_ID; | 814 | addr->addrtype = TIPC_ADDR_ID; |
825 | addr->addr.id.ref = msg_origport(msg); | 815 | addr->addr.id.ref = msg_origport(msg); |
826 | addr->addr.id.node = msg_orignode(msg); | 816 | addr->addr.id.node = msg_orignode(msg); |
827 | addr->addr.name.domain = 0; /* could leave uninitialized */ | 817 | addr->addr.name.domain = 0; /* could leave uninitialized */ |
828 | addr->scope = 0; /* could leave uninitialized */ | 818 | addr->scope = 0; /* could leave uninitialized */ |
829 | m->msg_namelen = sizeof(struct sockaddr_tipc); | 819 | m->msg_namelen = sizeof(struct sockaddr_tipc); |
830 | } | 820 | } |
831 | } | 821 | } |
@@ -859,12 +849,15 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
859 | if (unlikely(err)) { | 849 | if (unlikely(err)) { |
860 | anc_data[0] = err; | 850 | anc_data[0] = err; |
861 | anc_data[1] = msg_data_sz(msg); | 851 | anc_data[1] = msg_data_sz(msg); |
862 | if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data))) | 852 | res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data); |
863 | return res; | 853 | 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; | 854 | return res; |
855 | if (anc_data[1]) { | ||
856 | res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], | ||
857 | msg_data(msg)); | ||
858 | if (res) | ||
859 | return res; | ||
860 | } | ||
868 | } | 861 | } |
869 | 862 | ||
870 | /* Optionally capture message destination object */ | 863 | /* Optionally capture message destination object */ |
@@ -892,9 +885,11 @@ static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | |||
892 | default: | 885 | default: |
893 | has_name = 0; | 886 | has_name = 0; |
894 | } | 887 | } |
895 | if (has_name && | 888 | if (has_name) { |
896 | (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data))) | 889 | res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data); |
897 | return res; | 890 | if (res) |
891 | return res; | ||
892 | } | ||
898 | 893 | ||
899 | return 0; | 894 | return 0; |
900 | } | 895 | } |
@@ -919,15 +914,13 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, | |||
919 | struct tipc_port *tport = tipc_sk_port(sk); | 914 | struct tipc_port *tport = tipc_sk_port(sk); |
920 | struct sk_buff *buf; | 915 | struct sk_buff *buf; |
921 | struct tipc_msg *msg; | 916 | struct tipc_msg *msg; |
917 | long timeout; | ||
922 | unsigned int sz; | 918 | unsigned int sz; |
923 | u32 err; | 919 | u32 err; |
924 | int res; | 920 | int res; |
925 | 921 | ||
926 | /* Catch invalid receive requests */ | 922 | /* Catch invalid receive requests */ |
927 | 923 | ||
928 | if (m->msg_iovlen != 1) | ||
929 | return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */ | ||
930 | |||
931 | if (unlikely(!buf_len)) | 924 | if (unlikely(!buf_len)) |
932 | return -EINVAL; | 925 | return -EINVAL; |
933 | 926 | ||
@@ -938,6 +931,7 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, | |||
938 | goto exit; | 931 | goto exit; |
939 | } | 932 | } |
940 | 933 | ||
934 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | ||
941 | restart: | 935 | restart: |
942 | 936 | ||
943 | /* Look for a message in receive queue; wait if necessary */ | 937 | /* Look for a message in receive queue; wait if necessary */ |
@@ -947,17 +941,15 @@ restart: | |||
947 | res = -ENOTCONN; | 941 | res = -ENOTCONN; |
948 | goto exit; | 942 | goto exit; |
949 | } | 943 | } |
950 | if (flags & MSG_DONTWAIT) { | 944 | if (timeout <= 0L) { |
951 | res = -EWOULDBLOCK; | 945 | res = timeout ? timeout : -EWOULDBLOCK; |
952 | goto exit; | 946 | goto exit; |
953 | } | 947 | } |
954 | release_sock(sk); | 948 | release_sock(sk); |
955 | res = wait_event_interruptible(*sk_sleep(sk), | 949 | timeout = wait_event_interruptible_timeout(*sk_sleep(sk), |
956 | (!skb_queue_empty(&sk->sk_receive_queue) || | 950 | tipc_rx_ready(sock), |
957 | (sock->state == SS_DISCONNECTING))); | 951 | timeout); |
958 | lock_sock(sk); | 952 | lock_sock(sk); |
959 | if (res) | ||
960 | goto exit; | ||
961 | } | 953 | } |
962 | 954 | ||
963 | /* Look at first message in receive queue */ | 955 | /* Look at first message in receive queue */ |
@@ -999,11 +991,10 @@ restart: | |||
999 | sz = buf_len; | 991 | sz = buf_len; |
1000 | m->msg_flags |= MSG_TRUNC; | 992 | m->msg_flags |= MSG_TRUNC; |
1001 | } | 993 | } |
1002 | if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), | 994 | res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg), |
1003 | sz))) { | 995 | m->msg_iov, sz); |
1004 | res = -EFAULT; | 996 | if (res) |
1005 | goto exit; | 997 | goto exit; |
1006 | } | ||
1007 | res = sz; | 998 | res = sz; |
1008 | } else { | 999 | } else { |
1009 | if ((sock->state == SS_READY) || | 1000 | if ((sock->state == SS_READY) || |
@@ -1046,19 +1037,15 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1046 | struct tipc_port *tport = tipc_sk_port(sk); | 1037 | struct tipc_port *tport = tipc_sk_port(sk); |
1047 | struct sk_buff *buf; | 1038 | struct sk_buff *buf; |
1048 | struct tipc_msg *msg; | 1039 | struct tipc_msg *msg; |
1040 | long timeout; | ||
1049 | unsigned int sz; | 1041 | unsigned int sz; |
1050 | int sz_to_copy, target, needed; | 1042 | int sz_to_copy, target, needed; |
1051 | int sz_copied = 0; | 1043 | int sz_copied = 0; |
1052 | char __user *crs = m->msg_iov->iov_base; | ||
1053 | unsigned char *buf_crs; | ||
1054 | u32 err; | 1044 | u32 err; |
1055 | int res = 0; | 1045 | int res = 0; |
1056 | 1046 | ||
1057 | /* Catch invalid receive attempts */ | 1047 | /* Catch invalid receive attempts */ |
1058 | 1048 | ||
1059 | if (m->msg_iovlen != 1) | ||
1060 | return -EOPNOTSUPP; /* Don't do multiple iovec entries yet */ | ||
1061 | |||
1062 | if (unlikely(!buf_len)) | 1049 | if (unlikely(!buf_len)) |
1063 | return -EINVAL; | 1050 | return -EINVAL; |
1064 | 1051 | ||
@@ -1071,7 +1058,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1071 | } | 1058 | } |
1072 | 1059 | ||
1073 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); | 1060 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); |
1074 | 1061 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | |
1075 | restart: | 1062 | restart: |
1076 | 1063 | ||
1077 | /* Look for a message in receive queue; wait if necessary */ | 1064 | /* Look for a message in receive queue; wait if necessary */ |
@@ -1081,17 +1068,15 @@ restart: | |||
1081 | res = -ENOTCONN; | 1068 | res = -ENOTCONN; |
1082 | goto exit; | 1069 | goto exit; |
1083 | } | 1070 | } |
1084 | if (flags & MSG_DONTWAIT) { | 1071 | if (timeout <= 0L) { |
1085 | res = -EWOULDBLOCK; | 1072 | res = timeout ? timeout : -EWOULDBLOCK; |
1086 | goto exit; | 1073 | goto exit; |
1087 | } | 1074 | } |
1088 | release_sock(sk); | 1075 | release_sock(sk); |
1089 | res = wait_event_interruptible(*sk_sleep(sk), | 1076 | timeout = wait_event_interruptible_timeout(*sk_sleep(sk), |
1090 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1077 | tipc_rx_ready(sock), |
1091 | (sock->state == SS_DISCONNECTING))); | 1078 | timeout); |
1092 | lock_sock(sk); | 1079 | lock_sock(sk); |
1093 | if (res) | ||
1094 | goto exit; | ||
1095 | } | 1080 | } |
1096 | 1081 | ||
1097 | /* Look at first message in receive queue */ | 1082 | /* Look at first message in receive queue */ |
@@ -1120,24 +1105,25 @@ restart: | |||
1120 | /* Capture message data (if valid) & compute return value (always) */ | 1105 | /* Capture message data (if valid) & compute return value (always) */ |
1121 | 1106 | ||
1122 | if (!err) { | 1107 | if (!err) { |
1123 | buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); | 1108 | u32 offset = (u32)(unsigned long)(TIPC_SKB_CB(buf)->handle); |
1124 | sz = (unsigned char *)msg + msg_size(msg) - buf_crs; | ||
1125 | 1109 | ||
1110 | sz -= offset; | ||
1126 | needed = (buf_len - sz_copied); | 1111 | needed = (buf_len - sz_copied); |
1127 | sz_to_copy = (sz <= needed) ? sz : needed; | 1112 | sz_to_copy = (sz <= needed) ? sz : needed; |
1128 | if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { | 1113 | |
1129 | res = -EFAULT; | 1114 | res = skb_copy_datagram_iovec(buf, msg_hdr_sz(msg) + offset, |
1115 | m->msg_iov, sz_to_copy); | ||
1116 | if (res) | ||
1130 | goto exit; | 1117 | goto exit; |
1131 | } | 1118 | |
1132 | sz_copied += sz_to_copy; | 1119 | sz_copied += sz_to_copy; |
1133 | 1120 | ||
1134 | if (sz_to_copy < sz) { | 1121 | if (sz_to_copy < sz) { |
1135 | if (!(flags & MSG_PEEK)) | 1122 | if (!(flags & MSG_PEEK)) |
1136 | TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; | 1123 | TIPC_SKB_CB(buf)->handle = |
1124 | (void *)(unsigned long)(offset + sz_to_copy); | ||
1137 | goto exit; | 1125 | goto exit; |
1138 | } | 1126 | } |
1139 | |||
1140 | crs += sz_to_copy; | ||
1141 | } else { | 1127 | } else { |
1142 | if (sz_copied != 0) | 1128 | if (sz_copied != 0) |
1143 | goto exit; /* can't add error msg to valid data */ | 1129 | goto exit; /* can't add error msg to valid data */ |
@@ -1227,42 +1213,25 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1227 | */ | 1213 | */ |
1228 | 1214 | ||
1229 | if (sock->state == SS_READY) { | 1215 | if (sock->state == SS_READY) { |
1230 | if (msg_connected(msg)) { | 1216 | if (msg_connected(msg)) |
1231 | msg_dbg(msg, "dispatch filter 1\n"); | ||
1232 | return TIPC_ERR_NO_PORT; | 1217 | return TIPC_ERR_NO_PORT; |
1233 | } | ||
1234 | } else { | 1218 | } else { |
1235 | if (msg_mcast(msg)) { | 1219 | if (msg_mcast(msg)) |
1236 | msg_dbg(msg, "dispatch filter 2\n"); | ||
1237 | return TIPC_ERR_NO_PORT; | 1220 | return TIPC_ERR_NO_PORT; |
1238 | } | ||
1239 | if (sock->state == SS_CONNECTED) { | 1221 | if (sock->state == SS_CONNECTED) { |
1240 | if (!msg_connected(msg)) { | 1222 | if (!msg_connected(msg)) |
1241 | msg_dbg(msg, "dispatch filter 3\n"); | ||
1242 | return TIPC_ERR_NO_PORT; | 1223 | return TIPC_ERR_NO_PORT; |
1243 | } | 1224 | } else if (sock->state == SS_CONNECTING) { |
1244 | } | 1225 | 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; | 1226 | return TIPC_ERR_NO_PORT; |
1249 | } | 1227 | } else if (sock->state == SS_LISTENING) { |
1250 | } | 1228 | 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; | 1229 | return TIPC_ERR_NO_PORT; |
1255 | } | 1230 | } 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; | 1231 | return TIPC_ERR_NO_PORT; |
1260 | } | 1232 | } else /* (sock->state == SS_UNCONNECTED) */ { |
1261 | else /* (sock->state == SS_UNCONNECTED) */ { | 1233 | 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; | 1234 | return TIPC_ERR_NO_PORT; |
1265 | } | ||
1266 | } | 1235 | } |
1267 | } | 1236 | } |
1268 | 1237 | ||
@@ -1281,8 +1250,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1281 | 1250 | ||
1282 | /* Enqueue message (finally!) */ | 1251 | /* Enqueue message (finally!) */ |
1283 | 1252 | ||
1284 | msg_dbg(msg, "<DISP<: "); | 1253 | TIPC_SKB_CB(buf)->handle = 0; |
1285 | TIPC_SKB_CB(buf)->handle = msg_data(msg); | ||
1286 | atomic_inc(&tipc_queue_size); | 1254 | atomic_inc(&tipc_queue_size); |
1287 | __skb_queue_tail(&sk->sk_receive_queue, buf); | 1255 | __skb_queue_tail(&sk->sk_receive_queue, buf); |
1288 | 1256 | ||
@@ -1442,9 +1410,8 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1442 | m.msg_name = dest; | 1410 | m.msg_name = dest; |
1443 | m.msg_namelen = destlen; | 1411 | m.msg_namelen = destlen; |
1444 | res = send_msg(NULL, sock, &m, 0); | 1412 | res = send_msg(NULL, sock, &m, 0); |
1445 | if (res < 0) { | 1413 | if (res < 0) |
1446 | goto exit; | 1414 | goto exit; |
1447 | } | ||
1448 | 1415 | ||
1449 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ | 1416 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ |
1450 | 1417 | ||
@@ -1466,11 +1433,10 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1466 | advance_rx_queue(sk); | 1433 | advance_rx_queue(sk); |
1467 | } | 1434 | } |
1468 | } else { | 1435 | } else { |
1469 | if (sock->state == SS_CONNECTED) { | 1436 | if (sock->state == SS_CONNECTED) |
1470 | res = -EISCONN; | 1437 | res = -EISCONN; |
1471 | } else { | 1438 | else |
1472 | res = -ECONNREFUSED; | 1439 | res = -ECONNREFUSED; |
1473 | } | ||
1474 | } | 1440 | } |
1475 | } else { | 1441 | } else { |
1476 | if (res == 0) | 1442 | if (res == 0) |
@@ -1589,7 +1555,6 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1589 | * Respond to 'SYN+' by queuing it on new socket. | 1555 | * Respond to 'SYN+' by queuing it on new socket. |
1590 | */ | 1556 | */ |
1591 | 1557 | ||
1592 | msg_dbg(msg,"<ACC<: "); | ||
1593 | if (!msg_data_sz(msg)) { | 1558 | if (!msg_data_sz(msg)) { |
1594 | struct msghdr m = {NULL,}; | 1559 | struct msghdr m = {NULL,}; |
1595 | 1560 | ||
@@ -1637,7 +1602,7 @@ restart: | |||
1637 | buf = __skb_dequeue(&sk->sk_receive_queue); | 1602 | buf = __skb_dequeue(&sk->sk_receive_queue); |
1638 | if (buf) { | 1603 | if (buf) { |
1639 | atomic_dec(&tipc_queue_size); | 1604 | atomic_dec(&tipc_queue_size); |
1640 | if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { | 1605 | if (TIPC_SKB_CB(buf)->handle != 0) { |
1641 | buf_discard(buf); | 1606 | buf_discard(buf); |
1642 | goto restart; | 1607 | goto restart; |
1643 | } | 1608 | } |
@@ -1697,7 +1662,8 @@ static int setsockopt(struct socket *sock, | |||
1697 | return -ENOPROTOOPT; | 1662 | return -ENOPROTOOPT; |
1698 | if (ol < sizeof(value)) | 1663 | if (ol < sizeof(value)) |
1699 | return -EINVAL; | 1664 | return -EINVAL; |
1700 | if ((res = get_user(value, (u32 __user *)ov))) | 1665 | res = get_user(value, (u32 __user *)ov); |
1666 | if (res) | ||
1701 | return res; | 1667 | return res; |
1702 | 1668 | ||
1703 | lock_sock(sk); | 1669 | lock_sock(sk); |
@@ -1755,7 +1721,8 @@ static int getsockopt(struct socket *sock, | |||
1755 | return put_user(0, ol); | 1721 | return put_user(0, ol); |
1756 | if (lvl != SOL_TIPC) | 1722 | if (lvl != SOL_TIPC) |
1757 | return -ENOPROTOOPT; | 1723 | return -ENOPROTOOPT; |
1758 | if ((res = get_user(len, ol))) | 1724 | res = get_user(len, ol); |
1725 | if (res) | ||
1759 | return res; | 1726 | return res; |
1760 | 1727 | ||
1761 | lock_sock(sk); | 1728 | lock_sock(sk); |
@@ -1774,10 +1741,10 @@ static int getsockopt(struct socket *sock, | |||
1774 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); | 1741 | value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); |
1775 | /* no need to set "res", since already 0 at this point */ | 1742 | /* no need to set "res", since already 0 at this point */ |
1776 | break; | 1743 | break; |
1777 | case TIPC_NODE_RECVQ_DEPTH: | 1744 | case TIPC_NODE_RECVQ_DEPTH: |
1778 | value = (u32)atomic_read(&tipc_queue_size); | 1745 | value = (u32)atomic_read(&tipc_queue_size); |
1779 | break; | 1746 | break; |
1780 | case TIPC_SOCK_RECVQ_DEPTH: | 1747 | case TIPC_SOCK_RECVQ_DEPTH: |
1781 | value = skb_queue_len(&sk->sk_receive_queue); | 1748 | value = skb_queue_len(&sk->sk_receive_queue); |
1782 | break; | 1749 | break; |
1783 | default: | 1750 | default: |
@@ -1786,20 +1753,16 @@ static int getsockopt(struct socket *sock, | |||
1786 | 1753 | ||
1787 | release_sock(sk); | 1754 | release_sock(sk); |
1788 | 1755 | ||
1789 | if (res) { | 1756 | if (res) |
1790 | /* "get" failed */ | 1757 | 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 | 1758 | ||
1802 | return res; | 1759 | if (len < sizeof(value)) |
1760 | return -EINVAL; | ||
1761 | |||
1762 | if (copy_to_user(ov, &value, sizeof(value))) | ||
1763 | return -EFAULT; | ||
1764 | |||
1765 | return put_user(sizeof(value), ol); | ||
1803 | } | 1766 | } |
1804 | 1767 | ||
1805 | /** | 1768 | /** |
@@ -1807,7 +1770,7 @@ static int getsockopt(struct socket *sock, | |||
1807 | */ | 1770 | */ |
1808 | 1771 | ||
1809 | static const struct proto_ops msg_ops = { | 1772 | static const struct proto_ops msg_ops = { |
1810 | .owner = THIS_MODULE, | 1773 | .owner = THIS_MODULE, |
1811 | .family = AF_TIPC, | 1774 | .family = AF_TIPC, |
1812 | .release = release, | 1775 | .release = release, |
1813 | .bind = bind, | 1776 | .bind = bind, |
@@ -1828,7 +1791,7 @@ static const struct proto_ops msg_ops = { | |||
1828 | }; | 1791 | }; |
1829 | 1792 | ||
1830 | static const struct proto_ops packet_ops = { | 1793 | static const struct proto_ops packet_ops = { |
1831 | .owner = THIS_MODULE, | 1794 | .owner = THIS_MODULE, |
1832 | .family = AF_TIPC, | 1795 | .family = AF_TIPC, |
1833 | .release = release, | 1796 | .release = release, |
1834 | .bind = bind, | 1797 | .bind = bind, |
@@ -1849,7 +1812,7 @@ static const struct proto_ops packet_ops = { | |||
1849 | }; | 1812 | }; |
1850 | 1813 | ||
1851 | static const struct proto_ops stream_ops = { | 1814 | static const struct proto_ops stream_ops = { |
1852 | .owner = THIS_MODULE, | 1815 | .owner = THIS_MODULE, |
1853 | .family = AF_TIPC, | 1816 | .family = AF_TIPC, |
1854 | .release = release, | 1817 | .release = release, |
1855 | .bind = bind, | 1818 | .bind = bind, |
@@ -1870,7 +1833,7 @@ static const struct proto_ops stream_ops = { | |||
1870 | }; | 1833 | }; |
1871 | 1834 | ||
1872 | static const struct net_proto_family tipc_family_ops = { | 1835 | static const struct net_proto_family tipc_family_ops = { |
1873 | .owner = THIS_MODULE, | 1836 | .owner = THIS_MODULE, |
1874 | .family = AF_TIPC, | 1837 | .family = AF_TIPC, |
1875 | .create = tipc_create | 1838 | .create = tipc_create |
1876 | }; | 1839 | }; |