diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 501 |
1 files changed, 287 insertions, 214 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index fd5f042dbff4..515ce38e4f4c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
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, 2012 Ericsson AB |
5 | * Copyright (c) 2004-2008, 2010-2011, Wind River Systems | 5 | * Copyright (c) 2004-2008, 2010-2012, 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 |
@@ -43,7 +43,8 @@ | |||
43 | #define SS_LISTENING -1 /* socket is listening */ | 43 | #define SS_LISTENING -1 /* socket is listening */ |
44 | #define SS_READY -2 /* socket is connectionless */ | 44 | #define SS_READY -2 /* socket is connectionless */ |
45 | 45 | ||
46 | #define OVERLOAD_LIMIT_BASE 5000 | 46 | #define CONN_OVERLOAD_LIMIT ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \ |
47 | SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) | ||
47 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 48 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ |
48 | 49 | ||
49 | struct tipc_sock { | 50 | struct tipc_sock { |
@@ -62,6 +63,8 @@ struct tipc_sock { | |||
62 | static int backlog_rcv(struct sock *sk, struct sk_buff *skb); | 63 | static int backlog_rcv(struct sock *sk, struct sk_buff *skb); |
63 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); | 64 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); |
64 | static void wakeupdispatch(struct tipc_port *tport); | 65 | static void wakeupdispatch(struct tipc_port *tport); |
66 | static void tipc_data_ready(struct sock *sk, int len); | ||
67 | static void tipc_write_space(struct sock *sk); | ||
65 | 68 | ||
66 | static const struct proto_ops packet_ops; | 69 | static const struct proto_ops packet_ops; |
67 | static const struct proto_ops stream_ops; | 70 | static const struct proto_ops stream_ops; |
@@ -71,8 +74,6 @@ static struct proto tipc_proto; | |||
71 | 74 | ||
72 | static int sockets_enabled; | 75 | static int sockets_enabled; |
73 | 76 | ||
74 | static atomic_t tipc_queue_size = ATOMIC_INIT(0); | ||
75 | |||
76 | /* | 77 | /* |
77 | * Revised TIPC socket locking policy: | 78 | * Revised TIPC socket locking policy: |
78 | * | 79 | * |
@@ -126,22 +127,6 @@ static atomic_t tipc_queue_size = ATOMIC_INIT(0); | |||
126 | static void advance_rx_queue(struct sock *sk) | 127 | static void advance_rx_queue(struct sock *sk) |
127 | { | 128 | { |
128 | kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); | 129 | kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); |
129 | atomic_dec(&tipc_queue_size); | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * discard_rx_queue - discard all buffers in socket receive queue | ||
134 | * | ||
135 | * Caller must hold socket lock | ||
136 | */ | ||
137 | static void discard_rx_queue(struct sock *sk) | ||
138 | { | ||
139 | struct sk_buff *buf; | ||
140 | |||
141 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) { | ||
142 | atomic_dec(&tipc_queue_size); | ||
143 | kfree_skb(buf); | ||
144 | } | ||
145 | } | 130 | } |
146 | 131 | ||
147 | /** | 132 | /** |
@@ -153,10 +138,8 @@ static void reject_rx_queue(struct sock *sk) | |||
153 | { | 138 | { |
154 | struct sk_buff *buf; | 139 | struct sk_buff *buf; |
155 | 140 | ||
156 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) { | 141 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) |
157 | tipc_reject_msg(buf, TIPC_ERR_NO_PORT); | 142 | tipc_reject_msg(buf, TIPC_ERR_NO_PORT); |
158 | atomic_dec(&tipc_queue_size); | ||
159 | } | ||
160 | } | 143 | } |
161 | 144 | ||
162 | /** | 145 | /** |
@@ -220,7 +203,8 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
220 | 203 | ||
221 | sock_init_data(sock, sk); | 204 | sock_init_data(sock, sk); |
222 | sk->sk_backlog_rcv = backlog_rcv; | 205 | sk->sk_backlog_rcv = backlog_rcv; |
223 | sk->sk_rcvbuf = TIPC_FLOW_CONTROL_WIN * 2 * TIPC_MAX_USER_MSG_SIZE * 2; | 206 | sk->sk_data_ready = tipc_data_ready; |
207 | sk->sk_write_space = tipc_write_space; | ||
224 | tipc_sk(sk)->p = tp_ptr; | 208 | tipc_sk(sk)->p = tp_ptr; |
225 | tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT; | 209 | tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT; |
226 | 210 | ||
@@ -276,7 +260,6 @@ static int release(struct socket *sock) | |||
276 | buf = __skb_dequeue(&sk->sk_receive_queue); | 260 | buf = __skb_dequeue(&sk->sk_receive_queue); |
277 | if (buf == NULL) | 261 | if (buf == NULL) |
278 | break; | 262 | break; |
279 | atomic_dec(&tipc_queue_size); | ||
280 | if (TIPC_SKB_CB(buf)->handle != 0) | 263 | if (TIPC_SKB_CB(buf)->handle != 0) |
281 | kfree_skb(buf); | 264 | kfree_skb(buf); |
282 | else { | 265 | else { |
@@ -296,7 +279,7 @@ static int release(struct socket *sock) | |||
296 | res = tipc_deleteport(tport->ref); | 279 | res = tipc_deleteport(tport->ref); |
297 | 280 | ||
298 | /* Discard any remaining (connection-based) messages in receive queue */ | 281 | /* Discard any remaining (connection-based) messages in receive queue */ |
299 | discard_rx_queue(sk); | 282 | __skb_queue_purge(&sk->sk_receive_queue); |
300 | 283 | ||
301 | /* Reject any messages that accumulated in backlog queue */ | 284 | /* Reject any messages that accumulated in backlog queue */ |
302 | sock->state = SS_DISCONNECTING; | 285 | sock->state = SS_DISCONNECTING; |
@@ -408,7 +391,7 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, | |||
408 | * socket state flags set | 391 | * socket state flags set |
409 | * ------------ --------- | 392 | * ------------ --------- |
410 | * unconnected no read flags | 393 | * unconnected no read flags |
411 | * no write flags | 394 | * POLLOUT if port is not congested |
412 | * | 395 | * |
413 | * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue | 396 | * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue |
414 | * no write flags | 397 | * no write flags |
@@ -435,9 +418,13 @@ static unsigned int poll(struct file *file, struct socket *sock, | |||
435 | struct sock *sk = sock->sk; | 418 | struct sock *sk = sock->sk; |
436 | u32 mask = 0; | 419 | u32 mask = 0; |
437 | 420 | ||
438 | poll_wait(file, sk_sleep(sk), wait); | 421 | sock_poll_wait(file, sk_sleep(sk), wait); |
439 | 422 | ||
440 | switch ((int)sock->state) { | 423 | switch ((int)sock->state) { |
424 | case SS_UNCONNECTED: | ||
425 | if (!tipc_sk_port(sk)->congested) | ||
426 | mask |= POLLOUT; | ||
427 | break; | ||
441 | case SS_READY: | 428 | case SS_READY: |
442 | case SS_CONNECTED: | 429 | case SS_CONNECTED: |
443 | if (!tipc_sk_port(sk)->congested) | 430 | if (!tipc_sk_port(sk)->congested) |
@@ -516,8 +503,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
516 | if (unlikely((m->msg_namelen < sizeof(*dest)) || | 503 | if (unlikely((m->msg_namelen < sizeof(*dest)) || |
517 | (dest->family != AF_TIPC))) | 504 | (dest->family != AF_TIPC))) |
518 | return -EINVAL; | 505 | return -EINVAL; |
519 | if ((total_len > TIPC_MAX_USER_MSG_SIZE) || | 506 | if (total_len > TIPC_MAX_USER_MSG_SIZE) |
520 | (m->msg_iovlen > (unsigned int)INT_MAX)) | ||
521 | return -EMSGSIZE; | 507 | return -EMSGSIZE; |
522 | 508 | ||
523 | if (iocb) | 509 | if (iocb) |
@@ -625,8 +611,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock, | |||
625 | if (unlikely(dest)) | 611 | if (unlikely(dest)) |
626 | return send_msg(iocb, sock, m, total_len); | 612 | return send_msg(iocb, sock, m, total_len); |
627 | 613 | ||
628 | if ((total_len > TIPC_MAX_USER_MSG_SIZE) || | 614 | if (total_len > TIPC_MAX_USER_MSG_SIZE) |
629 | (m->msg_iovlen > (unsigned int)INT_MAX)) | ||
630 | return -EMSGSIZE; | 615 | return -EMSGSIZE; |
631 | 616 | ||
632 | if (iocb) | 617 | if (iocb) |
@@ -711,8 +696,7 @@ static int send_stream(struct kiocb *iocb, struct socket *sock, | |||
711 | goto exit; | 696 | goto exit; |
712 | } | 697 | } |
713 | 698 | ||
714 | if ((total_len > (unsigned int)INT_MAX) || | 699 | if (total_len > (unsigned int)INT_MAX) { |
715 | (m->msg_iovlen > (unsigned int)INT_MAX)) { | ||
716 | res = -EMSGSIZE; | 700 | res = -EMSGSIZE; |
717 | goto exit; | 701 | goto exit; |
718 | } | 702 | } |
@@ -775,16 +759,19 @@ exit: | |||
775 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) | 759 | static int auto_connect(struct socket *sock, struct tipc_msg *msg) |
776 | { | 760 | { |
777 | struct tipc_sock *tsock = tipc_sk(sock->sk); | 761 | struct tipc_sock *tsock = tipc_sk(sock->sk); |
778 | 762 | struct tipc_port *p_ptr; | |
779 | if (msg_errcode(msg)) { | ||
780 | sock->state = SS_DISCONNECTING; | ||
781 | return -ECONNREFUSED; | ||
782 | } | ||
783 | 763 | ||
784 | tsock->peer_name.ref = msg_origport(msg); | 764 | tsock->peer_name.ref = msg_origport(msg); |
785 | tsock->peer_name.node = msg_orignode(msg); | 765 | tsock->peer_name.node = msg_orignode(msg); |
786 | tipc_connect2port(tsock->p->ref, &tsock->peer_name); | 766 | p_ptr = tipc_port_deref(tsock->p->ref); |
787 | tipc_set_portimportance(tsock->p->ref, msg_importance(msg)); | 767 | if (!p_ptr) |
768 | return -EINVAL; | ||
769 | |||
770 | __tipc_connect(tsock->p->ref, p_ptr, &tsock->peer_name); | ||
771 | |||
772 | if (msg_importance(msg) > TIPC_CRITICAL_IMPORTANCE) | ||
773 | return -EINVAL; | ||
774 | msg_set_importance(&p_ptr->phdr, (u32)msg_importance(msg)); | ||
788 | sock->state = SS_CONNECTED; | 775 | sock->state = SS_CONNECTED; |
789 | return 0; | 776 | return 0; |
790 | } | 777 | } |
@@ -803,6 +790,7 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) | |||
803 | if (addr) { | 790 | if (addr) { |
804 | addr->family = AF_TIPC; | 791 | addr->family = AF_TIPC; |
805 | addr->addrtype = TIPC_ADDR_ID; | 792 | addr->addrtype = TIPC_ADDR_ID; |
793 | memset(&addr->addr, 0, sizeof(addr->addr)); | ||
806 | addr->addr.id.ref = msg_origport(msg); | 794 | addr->addr.id.ref = msg_origport(msg); |
807 | addr->addr.id.node = msg_orignode(msg); | 795 | addr->addr.id.node = msg_orignode(msg); |
808 | addr->addr.name.domain = 0; /* could leave uninitialized */ | 796 | addr->addr.name.domain = 0; /* could leave uninitialized */ |
@@ -917,6 +905,9 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock, | |||
917 | goto exit; | 905 | goto exit; |
918 | } | 906 | } |
919 | 907 | ||
908 | /* will be updated in set_orig_addr() if needed */ | ||
909 | m->msg_namelen = 0; | ||
910 | |||
920 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 911 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
921 | restart: | 912 | restart: |
922 | 913 | ||
@@ -943,13 +934,6 @@ restart: | |||
943 | sz = msg_data_sz(msg); | 934 | sz = msg_data_sz(msg); |
944 | err = msg_errcode(msg); | 935 | err = msg_errcode(msg); |
945 | 936 | ||
946 | /* Complete connection setup for an implied connect */ | ||
947 | if (unlikely(sock->state == SS_CONNECTING)) { | ||
948 | res = auto_connect(sock, msg); | ||
949 | if (res) | ||
950 | goto exit; | ||
951 | } | ||
952 | |||
953 | /* Discard an empty non-errored message & try again */ | 937 | /* Discard an empty non-errored message & try again */ |
954 | if ((!sz) && (!err)) { | 938 | if ((!sz) && (!err)) { |
955 | advance_rx_queue(sk); | 939 | advance_rx_queue(sk); |
@@ -1033,6 +1017,9 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1033 | goto exit; | 1017 | goto exit; |
1034 | } | 1018 | } |
1035 | 1019 | ||
1020 | /* will be updated in set_orig_addr() if needed */ | ||
1021 | m->msg_namelen = 0; | ||
1022 | |||
1036 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); | 1023 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); |
1037 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 1024 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); |
1038 | 1025 | ||
@@ -1126,31 +1113,143 @@ exit: | |||
1126 | } | 1113 | } |
1127 | 1114 | ||
1128 | /** | 1115 | /** |
1129 | * rx_queue_full - determine if receive queue can accept another message | 1116 | * tipc_write_space - wake up thread if port congestion is released |
1130 | * @msg: message to be added to queue | 1117 | * @sk: socket |
1131 | * @queue_size: current size of queue | 1118 | */ |
1132 | * @base: nominal maximum size of queue | 1119 | static void tipc_write_space(struct sock *sk) |
1120 | { | ||
1121 | struct socket_wq *wq; | ||
1122 | |||
1123 | rcu_read_lock(); | ||
1124 | wq = rcu_dereference(sk->sk_wq); | ||
1125 | if (wq_has_sleeper(wq)) | ||
1126 | wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | | ||
1127 | POLLWRNORM | POLLWRBAND); | ||
1128 | rcu_read_unlock(); | ||
1129 | } | ||
1130 | |||
1131 | /** | ||
1132 | * tipc_data_ready - wake up threads to indicate messages have been received | ||
1133 | * @sk: socket | ||
1134 | * @len: the length of messages | ||
1135 | */ | ||
1136 | static void tipc_data_ready(struct sock *sk, int len) | ||
1137 | { | ||
1138 | struct socket_wq *wq; | ||
1139 | |||
1140 | rcu_read_lock(); | ||
1141 | wq = rcu_dereference(sk->sk_wq); | ||
1142 | if (wq_has_sleeper(wq)) | ||
1143 | wake_up_interruptible_sync_poll(&wq->wait, POLLIN | | ||
1144 | POLLRDNORM | POLLRDBAND); | ||
1145 | rcu_read_unlock(); | ||
1146 | } | ||
1147 | |||
1148 | /** | ||
1149 | * filter_connect - Handle all incoming messages for a connection-based socket | ||
1150 | * @tsock: TIPC socket | ||
1151 | * @msg: message | ||
1133 | * | 1152 | * |
1134 | * Returns 1 if queue is unable to accept message, 0 otherwise | 1153 | * Returns TIPC error status code and socket error status code |
1154 | * once it encounters some errors | ||
1135 | */ | 1155 | */ |
1136 | static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base) | 1156 | static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) |
1137 | { | 1157 | { |
1138 | u32 threshold; | 1158 | struct socket *sock = tsock->sk.sk_socket; |
1139 | u32 imp = msg_importance(msg); | 1159 | struct tipc_msg *msg = buf_msg(*buf); |
1140 | 1160 | struct sock *sk = &tsock->sk; | |
1141 | if (imp == TIPC_LOW_IMPORTANCE) | 1161 | u32 retval = TIPC_ERR_NO_PORT; |
1142 | threshold = base; | 1162 | int res; |
1143 | else if (imp == TIPC_MEDIUM_IMPORTANCE) | ||
1144 | threshold = base * 2; | ||
1145 | else if (imp == TIPC_HIGH_IMPORTANCE) | ||
1146 | threshold = base * 100; | ||
1147 | else | ||
1148 | return 0; | ||
1149 | 1163 | ||
1150 | if (msg_connected(msg)) | 1164 | if (msg_mcast(msg)) |
1151 | threshold *= 4; | 1165 | return retval; |
1152 | 1166 | ||
1153 | return queue_size >= threshold; | 1167 | switch ((int)sock->state) { |
1168 | case SS_CONNECTED: | ||
1169 | /* Accept only connection-based messages sent by peer */ | ||
1170 | if (msg_connected(msg) && tipc_port_peer_msg(tsock->p, msg)) { | ||
1171 | if (unlikely(msg_errcode(msg))) { | ||
1172 | sock->state = SS_DISCONNECTING; | ||
1173 | __tipc_disconnect(tsock->p); | ||
1174 | } | ||
1175 | retval = TIPC_OK; | ||
1176 | } | ||
1177 | break; | ||
1178 | case SS_CONNECTING: | ||
1179 | /* Accept only ACK or NACK message */ | ||
1180 | if (unlikely(msg_errcode(msg))) { | ||
1181 | sock->state = SS_DISCONNECTING; | ||
1182 | sk->sk_err = -ECONNREFUSED; | ||
1183 | retval = TIPC_OK; | ||
1184 | break; | ||
1185 | } | ||
1186 | |||
1187 | if (unlikely(!msg_connected(msg))) | ||
1188 | break; | ||
1189 | |||
1190 | res = auto_connect(sock, msg); | ||
1191 | if (res) { | ||
1192 | sock->state = SS_DISCONNECTING; | ||
1193 | sk->sk_err = res; | ||
1194 | retval = TIPC_OK; | ||
1195 | break; | ||
1196 | } | ||
1197 | |||
1198 | /* If an incoming message is an 'ACK-', it should be | ||
1199 | * discarded here because it doesn't contain useful | ||
1200 | * data. In addition, we should try to wake up | ||
1201 | * connect() routine if sleeping. | ||
1202 | */ | ||
1203 | if (msg_data_sz(msg) == 0) { | ||
1204 | kfree_skb(*buf); | ||
1205 | *buf = NULL; | ||
1206 | if (waitqueue_active(sk_sleep(sk))) | ||
1207 | wake_up_interruptible(sk_sleep(sk)); | ||
1208 | } | ||
1209 | retval = TIPC_OK; | ||
1210 | break; | ||
1211 | case SS_LISTENING: | ||
1212 | case SS_UNCONNECTED: | ||
1213 | /* Accept only SYN message */ | ||
1214 | if (!msg_connected(msg) && !(msg_errcode(msg))) | ||
1215 | retval = TIPC_OK; | ||
1216 | break; | ||
1217 | case SS_DISCONNECTING: | ||
1218 | break; | ||
1219 | default: | ||
1220 | pr_err("Unknown socket state %u\n", sock->state); | ||
1221 | } | ||
1222 | return retval; | ||
1223 | } | ||
1224 | |||
1225 | /** | ||
1226 | * rcvbuf_limit - get proper overload limit of socket receive queue | ||
1227 | * @sk: socket | ||
1228 | * @buf: message | ||
1229 | * | ||
1230 | * For all connection oriented messages, irrespective of importance, | ||
1231 | * the default overload value (i.e. 67MB) is set as limit. | ||
1232 | * | ||
1233 | * For all connectionless messages, by default new queue limits are | ||
1234 | * as belows: | ||
1235 | * | ||
1236 | * TIPC_LOW_IMPORTANCE (5MB) | ||
1237 | * TIPC_MEDIUM_IMPORTANCE (10MB) | ||
1238 | * TIPC_HIGH_IMPORTANCE (20MB) | ||
1239 | * TIPC_CRITICAL_IMPORTANCE (40MB) | ||
1240 | * | ||
1241 | * Returns overload limit according to corresponding message importance | ||
1242 | */ | ||
1243 | static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf) | ||
1244 | { | ||
1245 | struct tipc_msg *msg = buf_msg(buf); | ||
1246 | unsigned int limit; | ||
1247 | |||
1248 | if (msg_connected(msg)) | ||
1249 | limit = CONN_OVERLOAD_LIMIT; | ||
1250 | else | ||
1251 | limit = sk->sk_rcvbuf << (msg_importance(msg) + 5); | ||
1252 | return limit; | ||
1154 | } | 1253 | } |
1155 | 1254 | ||
1156 | /** | 1255 | /** |
@@ -1169,7 +1268,8 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1169 | { | 1268 | { |
1170 | struct socket *sock = sk->sk_socket; | 1269 | struct socket *sock = sk->sk_socket; |
1171 | struct tipc_msg *msg = buf_msg(buf); | 1270 | struct tipc_msg *msg = buf_msg(buf); |
1172 | u32 recv_q_len; | 1271 | unsigned int limit = rcvbuf_limit(sk, buf); |
1272 | u32 res = TIPC_OK; | ||
1173 | 1273 | ||
1174 | /* Reject message if it is wrong sort of message for socket */ | 1274 | /* Reject message if it is wrong sort of message for socket */ |
1175 | if (msg_type(msg) > TIPC_DIRECT_MSG) | 1275 | if (msg_type(msg) > TIPC_DIRECT_MSG) |
@@ -1179,51 +1279,21 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1179 | if (msg_connected(msg)) | 1279 | if (msg_connected(msg)) |
1180 | return TIPC_ERR_NO_PORT; | 1280 | return TIPC_ERR_NO_PORT; |
1181 | } else { | 1281 | } else { |
1182 | if (msg_mcast(msg)) | 1282 | res = filter_connect(tipc_sk(sk), &buf); |
1183 | return TIPC_ERR_NO_PORT; | 1283 | if (res != TIPC_OK || buf == NULL) |
1184 | if (sock->state == SS_CONNECTED) { | 1284 | return res; |
1185 | if (!msg_connected(msg) || | ||
1186 | !tipc_port_peer_msg(tipc_sk_port(sk), msg)) | ||
1187 | return TIPC_ERR_NO_PORT; | ||
1188 | } else if (sock->state == SS_CONNECTING) { | ||
1189 | if (!msg_connected(msg) && (msg_errcode(msg) == 0)) | ||
1190 | return TIPC_ERR_NO_PORT; | ||
1191 | } else if (sock->state == SS_LISTENING) { | ||
1192 | if (msg_connected(msg) || msg_errcode(msg)) | ||
1193 | return TIPC_ERR_NO_PORT; | ||
1194 | } else if (sock->state == SS_DISCONNECTING) { | ||
1195 | return TIPC_ERR_NO_PORT; | ||
1196 | } else /* (sock->state == SS_UNCONNECTED) */ { | ||
1197 | if (msg_connected(msg) || msg_errcode(msg)) | ||
1198 | return TIPC_ERR_NO_PORT; | ||
1199 | } | ||
1200 | } | 1285 | } |
1201 | 1286 | ||
1202 | /* Reject message if there isn't room to queue it */ | 1287 | /* Reject message if there isn't room to queue it */ |
1203 | recv_q_len = (u32)atomic_read(&tipc_queue_size); | 1288 | if (sk_rmem_alloc_get(sk) + buf->truesize >= limit) |
1204 | if (unlikely(recv_q_len >= OVERLOAD_LIMIT_BASE)) { | 1289 | return TIPC_ERR_OVERLOAD; |
1205 | if (rx_queue_full(msg, recv_q_len, OVERLOAD_LIMIT_BASE)) | ||
1206 | return TIPC_ERR_OVERLOAD; | ||
1207 | } | ||
1208 | recv_q_len = skb_queue_len(&sk->sk_receive_queue); | ||
1209 | if (unlikely(recv_q_len >= (OVERLOAD_LIMIT_BASE / 2))) { | ||
1210 | if (rx_queue_full(msg, recv_q_len, OVERLOAD_LIMIT_BASE / 2)) | ||
1211 | return TIPC_ERR_OVERLOAD; | ||
1212 | } | ||
1213 | 1290 | ||
1214 | /* Enqueue message (finally!) */ | 1291 | /* Enqueue message */ |
1215 | TIPC_SKB_CB(buf)->handle = 0; | 1292 | TIPC_SKB_CB(buf)->handle = 0; |
1216 | atomic_inc(&tipc_queue_size); | ||
1217 | __skb_queue_tail(&sk->sk_receive_queue, buf); | 1293 | __skb_queue_tail(&sk->sk_receive_queue, buf); |
1294 | skb_set_owner_r(buf, sk); | ||
1218 | 1295 | ||
1219 | /* Initiate connection termination for an incoming 'FIN' */ | 1296 | sk->sk_data_ready(sk, 0); |
1220 | if (unlikely(msg_errcode(msg) && (sock->state == SS_CONNECTED))) { | ||
1221 | sock->state = SS_DISCONNECTING; | ||
1222 | tipc_disconnect_port(tipc_sk_port(sk)); | ||
1223 | } | ||
1224 | |||
1225 | if (waitqueue_active(sk_sleep(sk))) | ||
1226 | wake_up_interruptible(sk_sleep(sk)); | ||
1227 | return TIPC_OK; | 1297 | return TIPC_OK; |
1228 | } | 1298 | } |
1229 | 1299 | ||
@@ -1270,7 +1340,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | |||
1270 | if (!sock_owned_by_user(sk)) { | 1340 | if (!sock_owned_by_user(sk)) { |
1271 | res = filter_rcv(sk, buf); | 1341 | res = filter_rcv(sk, buf); |
1272 | } else { | 1342 | } else { |
1273 | if (sk_add_backlog(sk, buf, sk->sk_rcvbuf)) | 1343 | if (sk_add_backlog(sk, buf, rcvbuf_limit(sk, buf))) |
1274 | res = TIPC_ERR_OVERLOAD; | 1344 | res = TIPC_ERR_OVERLOAD; |
1275 | else | 1345 | else |
1276 | res = TIPC_OK; | 1346 | res = TIPC_OK; |
@@ -1290,8 +1360,7 @@ static void wakeupdispatch(struct tipc_port *tport) | |||
1290 | { | 1360 | { |
1291 | struct sock *sk = (struct sock *)tport->usr_handle; | 1361 | struct sock *sk = (struct sock *)tport->usr_handle; |
1292 | 1362 | ||
1293 | if (waitqueue_active(sk_sleep(sk))) | 1363 | sk->sk_write_space(sk); |
1294 | wake_up_interruptible(sk_sleep(sk)); | ||
1295 | } | 1364 | } |
1296 | 1365 | ||
1297 | /** | 1366 | /** |
@@ -1309,8 +1378,6 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1309 | struct sock *sk = sock->sk; | 1378 | struct sock *sk = sock->sk; |
1310 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; | 1379 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; |
1311 | struct msghdr m = {NULL,}; | 1380 | struct msghdr m = {NULL,}; |
1312 | struct sk_buff *buf; | ||
1313 | struct tipc_msg *msg; | ||
1314 | unsigned int timeout; | 1381 | unsigned int timeout; |
1315 | int res; | 1382 | int res; |
1316 | 1383 | ||
@@ -1322,26 +1389,6 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1322 | goto exit; | 1389 | goto exit; |
1323 | } | 1390 | } |
1324 | 1391 | ||
1325 | /* For now, TIPC does not support the non-blocking form of connect() */ | ||
1326 | if (flags & O_NONBLOCK) { | ||
1327 | res = -EOPNOTSUPP; | ||
1328 | goto exit; | ||
1329 | } | ||
1330 | |||
1331 | /* Issue Posix-compliant error code if socket is in the wrong state */ | ||
1332 | if (sock->state == SS_LISTENING) { | ||
1333 | res = -EOPNOTSUPP; | ||
1334 | goto exit; | ||
1335 | } | ||
1336 | if (sock->state == SS_CONNECTING) { | ||
1337 | res = -EALREADY; | ||
1338 | goto exit; | ||
1339 | } | ||
1340 | if (sock->state != SS_UNCONNECTED) { | ||
1341 | res = -EISCONN; | ||
1342 | goto exit; | ||
1343 | } | ||
1344 | |||
1345 | /* | 1392 | /* |
1346 | * Reject connection attempt using multicast address | 1393 | * Reject connection attempt using multicast address |
1347 | * | 1394 | * |
@@ -1353,49 +1400,66 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, | |||
1353 | goto exit; | 1400 | goto exit; |
1354 | } | 1401 | } |
1355 | 1402 | ||
1356 | /* Reject any messages already in receive queue (very unlikely) */ | 1403 | timeout = (flags & O_NONBLOCK) ? 0 : tipc_sk(sk)->conn_timeout; |
1357 | reject_rx_queue(sk); | ||
1358 | 1404 | ||
1359 | /* Send a 'SYN-' to destination */ | 1405 | switch (sock->state) { |
1360 | m.msg_name = dest; | 1406 | case SS_UNCONNECTED: |
1361 | m.msg_namelen = destlen; | 1407 | /* Send a 'SYN-' to destination */ |
1362 | res = send_msg(NULL, sock, &m, 0); | 1408 | m.msg_name = dest; |
1363 | if (res < 0) | 1409 | m.msg_namelen = destlen; |
1410 | |||
1411 | /* If connect is in non-blocking case, set MSG_DONTWAIT to | ||
1412 | * indicate send_msg() is never blocked. | ||
1413 | */ | ||
1414 | if (!timeout) | ||
1415 | m.msg_flags = MSG_DONTWAIT; | ||
1416 | |||
1417 | res = send_msg(NULL, sock, &m, 0); | ||
1418 | if ((res < 0) && (res != -EWOULDBLOCK)) | ||
1419 | goto exit; | ||
1420 | |||
1421 | /* Just entered SS_CONNECTING state; the only | ||
1422 | * difference is that return value in non-blocking | ||
1423 | * case is EINPROGRESS, rather than EALREADY. | ||
1424 | */ | ||
1425 | res = -EINPROGRESS; | ||
1426 | break; | ||
1427 | case SS_CONNECTING: | ||
1428 | res = -EALREADY; | ||
1429 | break; | ||
1430 | case SS_CONNECTED: | ||
1431 | res = -EISCONN; | ||
1432 | break; | ||
1433 | default: | ||
1434 | res = -EINVAL; | ||
1364 | goto exit; | 1435 | goto exit; |
1436 | } | ||
1365 | 1437 | ||
1366 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ | 1438 | if (sock->state == SS_CONNECTING) { |
1367 | timeout = tipc_sk(sk)->conn_timeout; | 1439 | if (!timeout) |
1368 | release_sock(sk); | 1440 | goto exit; |
1369 | res = wait_event_interruptible_timeout(*sk_sleep(sk), | ||
1370 | (!skb_queue_empty(&sk->sk_receive_queue) || | ||
1371 | (sock->state != SS_CONNECTING)), | ||
1372 | timeout ? (long)msecs_to_jiffies(timeout) | ||
1373 | : MAX_SCHEDULE_TIMEOUT); | ||
1374 | lock_sock(sk); | ||
1375 | 1441 | ||
1376 | if (res > 0) { | 1442 | /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ |
1377 | buf = skb_peek(&sk->sk_receive_queue); | 1443 | release_sock(sk); |
1378 | if (buf != NULL) { | 1444 | res = wait_event_interruptible_timeout(*sk_sleep(sk), |
1379 | msg = buf_msg(buf); | 1445 | sock->state != SS_CONNECTING, |
1380 | res = auto_connect(sock, msg); | 1446 | timeout ? (long)msecs_to_jiffies(timeout) |
1381 | if (!res) { | 1447 | : MAX_SCHEDULE_TIMEOUT); |
1382 | if (!msg_data_sz(msg)) | 1448 | lock_sock(sk); |
1383 | advance_rx_queue(sk); | 1449 | if (res <= 0) { |
1384 | } | 1450 | if (res == 0) |
1385 | } else { | 1451 | res = -ETIMEDOUT; |
1386 | if (sock->state == SS_CONNECTED) | ||
1387 | res = -EISCONN; | ||
1388 | else | 1452 | else |
1389 | res = -ECONNREFUSED; | 1453 | ; /* leave "res" unchanged */ |
1454 | goto exit; | ||
1390 | } | 1455 | } |
1391 | } else { | ||
1392 | if (res == 0) | ||
1393 | res = -ETIMEDOUT; | ||
1394 | else | ||
1395 | ; /* leave "res" unchanged */ | ||
1396 | sock->state = SS_DISCONNECTING; | ||
1397 | } | 1456 | } |
1398 | 1457 | ||
1458 | if (unlikely(sock->state == SS_DISCONNECTING)) | ||
1459 | res = sock_error(sk); | ||
1460 | else | ||
1461 | res = 0; | ||
1462 | |||
1399 | exit: | 1463 | exit: |
1400 | release_sock(sk); | 1464 | release_sock(sk); |
1401 | return res; | 1465 | return res; |
@@ -1436,8 +1500,13 @@ static int listen(struct socket *sock, int len) | |||
1436 | */ | 1500 | */ |
1437 | static int accept(struct socket *sock, struct socket *new_sock, int flags) | 1501 | static int accept(struct socket *sock, struct socket *new_sock, int flags) |
1438 | { | 1502 | { |
1439 | struct sock *sk = sock->sk; | 1503 | struct sock *new_sk, *sk = sock->sk; |
1440 | struct sk_buff *buf; | 1504 | struct sk_buff *buf; |
1505 | struct tipc_sock *new_tsock; | ||
1506 | struct tipc_port *new_tport; | ||
1507 | struct tipc_msg *msg; | ||
1508 | u32 new_ref; | ||
1509 | |||
1441 | int res; | 1510 | int res; |
1442 | 1511 | ||
1443 | lock_sock(sk); | 1512 | lock_sock(sk); |
@@ -1463,48 +1532,52 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1463 | buf = skb_peek(&sk->sk_receive_queue); | 1532 | buf = skb_peek(&sk->sk_receive_queue); |
1464 | 1533 | ||
1465 | res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); | 1534 | res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); |
1466 | if (!res) { | 1535 | if (res) |
1467 | struct sock *new_sk = new_sock->sk; | 1536 | goto exit; |
1468 | struct tipc_sock *new_tsock = tipc_sk(new_sk); | ||
1469 | struct tipc_port *new_tport = new_tsock->p; | ||
1470 | u32 new_ref = new_tport->ref; | ||
1471 | struct tipc_msg *msg = buf_msg(buf); | ||
1472 | |||
1473 | lock_sock(new_sk); | ||
1474 | |||
1475 | /* | ||
1476 | * Reject any stray messages received by new socket | ||
1477 | * before the socket lock was taken (very, very unlikely) | ||
1478 | */ | ||
1479 | reject_rx_queue(new_sk); | ||
1480 | |||
1481 | /* Connect new socket to it's peer */ | ||
1482 | new_tsock->peer_name.ref = msg_origport(msg); | ||
1483 | new_tsock->peer_name.node = msg_orignode(msg); | ||
1484 | tipc_connect2port(new_ref, &new_tsock->peer_name); | ||
1485 | new_sock->state = SS_CONNECTED; | ||
1486 | |||
1487 | tipc_set_portimportance(new_ref, msg_importance(msg)); | ||
1488 | if (msg_named(msg)) { | ||
1489 | new_tport->conn_type = msg_nametype(msg); | ||
1490 | new_tport->conn_instance = msg_nameinst(msg); | ||
1491 | } | ||
1492 | 1537 | ||
1493 | /* | 1538 | new_sk = new_sock->sk; |
1494 | * Respond to 'SYN-' by discarding it & returning 'ACK'-. | 1539 | new_tsock = tipc_sk(new_sk); |
1495 | * Respond to 'SYN+' by queuing it on new socket. | 1540 | new_tport = new_tsock->p; |
1496 | */ | 1541 | new_ref = new_tport->ref; |
1497 | if (!msg_data_sz(msg)) { | 1542 | msg = buf_msg(buf); |
1498 | struct msghdr m = {NULL,}; | ||
1499 | 1543 | ||
1500 | advance_rx_queue(sk); | 1544 | /* we lock on new_sk; but lockdep sees the lock on sk */ |
1501 | send_packet(NULL, new_sock, &m, 0); | 1545 | lock_sock_nested(new_sk, SINGLE_DEPTH_NESTING); |
1502 | } else { | 1546 | |
1503 | __skb_dequeue(&sk->sk_receive_queue); | 1547 | /* |
1504 | __skb_queue_head(&new_sk->sk_receive_queue, buf); | 1548 | * Reject any stray messages received by new socket |
1505 | } | 1549 | * before the socket lock was taken (very, very unlikely) |
1506 | release_sock(new_sk); | 1550 | */ |
1551 | reject_rx_queue(new_sk); | ||
1552 | |||
1553 | /* Connect new socket to it's peer */ | ||
1554 | new_tsock->peer_name.ref = msg_origport(msg); | ||
1555 | new_tsock->peer_name.node = msg_orignode(msg); | ||
1556 | tipc_connect(new_ref, &new_tsock->peer_name); | ||
1557 | new_sock->state = SS_CONNECTED; | ||
1558 | |||
1559 | tipc_set_portimportance(new_ref, msg_importance(msg)); | ||
1560 | if (msg_named(msg)) { | ||
1561 | new_tport->conn_type = msg_nametype(msg); | ||
1562 | new_tport->conn_instance = msg_nameinst(msg); | ||
1563 | } | ||
1564 | |||
1565 | /* | ||
1566 | * Respond to 'SYN-' by discarding it & returning 'ACK'-. | ||
1567 | * Respond to 'SYN+' by queuing it on new socket. | ||
1568 | */ | ||
1569 | if (!msg_data_sz(msg)) { | ||
1570 | struct msghdr m = {NULL,}; | ||
1571 | |||
1572 | advance_rx_queue(sk); | ||
1573 | send_packet(NULL, new_sock, &m, 0); | ||
1574 | } else { | ||
1575 | __skb_dequeue(&sk->sk_receive_queue); | ||
1576 | __skb_queue_head(&new_sk->sk_receive_queue, buf); | ||
1577 | skb_set_owner_r(buf, new_sk); | ||
1507 | } | 1578 | } |
1579 | release_sock(new_sk); | ||
1580 | |||
1508 | exit: | 1581 | exit: |
1509 | release_sock(sk); | 1582 | release_sock(sk); |
1510 | return res; | 1583 | return res; |
@@ -1539,7 +1612,6 @@ restart: | |||
1539 | /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ | 1612 | /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ |
1540 | buf = __skb_dequeue(&sk->sk_receive_queue); | 1613 | buf = __skb_dequeue(&sk->sk_receive_queue); |
1541 | if (buf) { | 1614 | if (buf) { |
1542 | atomic_dec(&tipc_queue_size); | ||
1543 | if (TIPC_SKB_CB(buf)->handle != 0) { | 1615 | if (TIPC_SKB_CB(buf)->handle != 0) { |
1544 | kfree_skb(buf); | 1616 | kfree_skb(buf); |
1545 | goto restart; | 1617 | goto restart; |
@@ -1556,10 +1628,11 @@ restart: | |||
1556 | 1628 | ||
1557 | case SS_DISCONNECTING: | 1629 | case SS_DISCONNECTING: |
1558 | 1630 | ||
1559 | /* Discard any unreceived messages; wake up sleeping tasks */ | 1631 | /* Discard any unreceived messages */ |
1560 | discard_rx_queue(sk); | 1632 | __skb_queue_purge(&sk->sk_receive_queue); |
1561 | if (waitqueue_active(sk_sleep(sk))) | 1633 | |
1562 | wake_up_interruptible(sk_sleep(sk)); | 1634 | /* Wake up anyone sleeping in poll */ |
1635 | sk->sk_state_change(sk); | ||
1563 | res = 0; | 1636 | res = 0; |
1564 | break; | 1637 | break; |
1565 | 1638 | ||
@@ -1677,7 +1750,7 @@ static int getsockopt(struct socket *sock, | |||
1677 | /* no need to set "res", since already 0 at this point */ | 1750 | /* no need to set "res", since already 0 at this point */ |
1678 | break; | 1751 | break; |
1679 | case TIPC_NODE_RECVQ_DEPTH: | 1752 | case TIPC_NODE_RECVQ_DEPTH: |
1680 | value = (u32)atomic_read(&tipc_queue_size); | 1753 | value = 0; /* was tipc_queue_size, now obsolete */ |
1681 | break; | 1754 | break; |
1682 | case TIPC_SOCK_RECVQ_DEPTH: | 1755 | case TIPC_SOCK_RECVQ_DEPTH: |
1683 | value = skb_queue_len(&sk->sk_receive_queue); | 1756 | value = skb_queue_len(&sk->sk_receive_queue); |