diff options
author | Brian Norris <computersforpeace@gmail.com> | 2017-05-15 14:19:19 -0400 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2017-05-15 14:19:19 -0400 |
commit | c316cf670491def52a396d3bdc5a63ad01f7fefa (patch) | |
tree | bf22299ce777088d190b532629b1bd647d28fab6 /net/tipc/socket.c | |
parent | 6c51a52eeb58befd2e9be2ed7ee2c4c04139b336 (diff) | |
parent | 2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff) |
Merge 'v4.12-rc1' into MTD
Bring a few queued patches in sync for -next development.
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 342 |
1 files changed, 185 insertions, 157 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 43e4045e72bc..0d4f2f455a7c 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #define TIPC_FWD_MSG 1 | 51 | #define TIPC_FWD_MSG 1 |
52 | #define TIPC_MAX_PORT 0xffffffff | 52 | #define TIPC_MAX_PORT 0xffffffff |
53 | #define TIPC_MIN_PORT 1 | 53 | #define TIPC_MIN_PORT 1 |
54 | #define TIPC_ACK_RATE 4 /* ACK at 1/4 of of rcv window size */ | ||
54 | 55 | ||
55 | enum { | 56 | enum { |
56 | TIPC_LISTEN = TCP_LISTEN, | 57 | TIPC_LISTEN = TCP_LISTEN, |
@@ -115,7 +116,8 @@ static void tipc_data_ready(struct sock *sk); | |||
115 | static void tipc_write_space(struct sock *sk); | 116 | static void tipc_write_space(struct sock *sk); |
116 | static void tipc_sock_destruct(struct sock *sk); | 117 | static void tipc_sock_destruct(struct sock *sk); |
117 | static int tipc_release(struct socket *sock); | 118 | static int tipc_release(struct socket *sock); |
118 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); | 119 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, |
120 | bool kern); | ||
119 | static void tipc_sk_timeout(unsigned long data); | 121 | static void tipc_sk_timeout(unsigned long data); |
120 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, | 122 | static int tipc_sk_publish(struct tipc_sock *tsk, uint scope, |
121 | struct tipc_name_seq const *seq); | 123 | struct tipc_name_seq const *seq); |
@@ -865,6 +867,14 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb, | |||
865 | if (!tsk_peer_msg(tsk, hdr)) | 867 | if (!tsk_peer_msg(tsk, hdr)) |
866 | goto exit; | 868 | goto exit; |
867 | 869 | ||
870 | if (unlikely(msg_errcode(hdr))) { | ||
871 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | ||
872 | tipc_node_remove_conn(sock_net(sk), tsk_peer_node(tsk), | ||
873 | tsk_peer_port(tsk)); | ||
874 | sk->sk_state_change(sk); | ||
875 | goto exit; | ||
876 | } | ||
877 | |||
868 | tsk->probe_unacked = false; | 878 | tsk->probe_unacked = false; |
869 | 879 | ||
870 | if (mtyp == CONN_PROBE) { | 880 | if (mtyp == CONN_PROBE) { |
@@ -1082,7 +1092,7 @@ static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dlen) | |||
1082 | } | 1092 | } |
1083 | } while (sent < dlen && !rc); | 1093 | } while (sent < dlen && !rc); |
1084 | 1094 | ||
1085 | return rc ? rc : sent; | 1095 | return sent ? sent : rc; |
1086 | } | 1096 | } |
1087 | 1097 | ||
1088 | /** | 1098 | /** |
@@ -1258,7 +1268,10 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1258 | struct sock *sk = sock->sk; | 1268 | struct sock *sk = sock->sk; |
1259 | DEFINE_WAIT(wait); | 1269 | DEFINE_WAIT(wait); |
1260 | long timeo = *timeop; | 1270 | long timeo = *timeop; |
1261 | int err; | 1271 | int err = sock_error(sk); |
1272 | |||
1273 | if (err) | ||
1274 | return err; | ||
1262 | 1275 | ||
1263 | for (;;) { | 1276 | for (;;) { |
1264 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 1277 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
@@ -1280,6 +1293,10 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1280 | err = sock_intr_errno(timeo); | 1293 | err = sock_intr_errno(timeo); |
1281 | if (signal_pending(current)) | 1294 | if (signal_pending(current)) |
1282 | break; | 1295 | break; |
1296 | |||
1297 | err = sock_error(sk); | ||
1298 | if (err) | ||
1299 | break; | ||
1283 | } | 1300 | } |
1284 | finish_wait(sk_sleep(sk), &wait); | 1301 | finish_wait(sk_sleep(sk), &wait); |
1285 | *timeop = timeo; | 1302 | *timeop = timeo; |
@@ -1289,7 +1306,7 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1289 | /** | 1306 | /** |
1290 | * tipc_recvmsg - receive packet-oriented message | 1307 | * tipc_recvmsg - receive packet-oriented message |
1291 | * @m: descriptor for message info | 1308 | * @m: descriptor for message info |
1292 | * @buf_len: total size of user buffer area | 1309 | * @buflen: length of user buffer area |
1293 | * @flags: receive flags | 1310 | * @flags: receive flags |
1294 | * | 1311 | * |
1295 | * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages. | 1312 | * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages. |
@@ -1297,95 +1314,85 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1297 | * | 1314 | * |
1298 | * Returns size of returned message data, errno otherwise | 1315 | * Returns size of returned message data, errno otherwise |
1299 | */ | 1316 | */ |
1300 | static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len, | 1317 | static int tipc_recvmsg(struct socket *sock, struct msghdr *m, |
1301 | int flags) | 1318 | size_t buflen, int flags) |
1302 | { | 1319 | { |
1303 | struct sock *sk = sock->sk; | 1320 | struct sock *sk = sock->sk; |
1304 | struct tipc_sock *tsk = tipc_sk(sk); | 1321 | struct tipc_sock *tsk = tipc_sk(sk); |
1305 | struct sk_buff *buf; | 1322 | struct sk_buff *skb; |
1306 | struct tipc_msg *msg; | 1323 | struct tipc_msg *hdr; |
1307 | bool is_connectionless = tipc_sk_type_connectionless(sk); | 1324 | bool connected = !tipc_sk_type_connectionless(sk); |
1308 | long timeo; | 1325 | int rc, err, hlen, dlen, copy; |
1309 | unsigned int sz; | 1326 | long timeout; |
1310 | u32 err; | ||
1311 | int res, hlen; | ||
1312 | 1327 | ||
1313 | /* Catch invalid receive requests */ | 1328 | /* Catch invalid receive requests */ |
1314 | if (unlikely(!buf_len)) | 1329 | if (unlikely(!buflen)) |
1315 | return -EINVAL; | 1330 | return -EINVAL; |
1316 | 1331 | ||
1317 | lock_sock(sk); | 1332 | lock_sock(sk); |
1318 | 1333 | if (unlikely(connected && sk->sk_state == TIPC_OPEN)) { | |
1319 | if (!is_connectionless && unlikely(sk->sk_state == TIPC_OPEN)) { | 1334 | rc = -ENOTCONN; |
1320 | res = -ENOTCONN; | ||
1321 | goto exit; | 1335 | goto exit; |
1322 | } | 1336 | } |
1337 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | ||
1323 | 1338 | ||
1324 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | 1339 | do { |
1325 | restart: | 1340 | /* Look at first msg in receive queue; wait if necessary */ |
1326 | 1341 | rc = tipc_wait_for_rcvmsg(sock, &timeout); | |
1327 | /* Look for a message in receive queue; wait if necessary */ | 1342 | if (unlikely(rc)) |
1328 | res = tipc_wait_for_rcvmsg(sock, &timeo); | 1343 | goto exit; |
1329 | if (res) | 1344 | skb = skb_peek(&sk->sk_receive_queue); |
1330 | goto exit; | 1345 | hdr = buf_msg(skb); |
1331 | 1346 | dlen = msg_data_sz(hdr); | |
1332 | /* Look at first message in receive queue */ | 1347 | hlen = msg_hdr_sz(hdr); |
1333 | buf = skb_peek(&sk->sk_receive_queue); | 1348 | err = msg_errcode(hdr); |
1334 | msg = buf_msg(buf); | 1349 | if (likely(dlen || err)) |
1335 | sz = msg_data_sz(msg); | 1350 | break; |
1336 | hlen = msg_hdr_sz(msg); | ||
1337 | err = msg_errcode(msg); | ||
1338 | |||
1339 | /* Discard an empty non-errored message & try again */ | ||
1340 | if ((!sz) && (!err)) { | ||
1341 | tsk_advance_rx_queue(sk); | 1351 | tsk_advance_rx_queue(sk); |
1342 | goto restart; | 1352 | } while (1); |
1343 | } | ||
1344 | |||
1345 | /* Capture sender's address (optional) */ | ||
1346 | set_orig_addr(m, msg); | ||
1347 | 1353 | ||
1348 | /* Capture ancillary data (optional) */ | 1354 | /* Collect msg meta data, including error code and rejected data */ |
1349 | res = tipc_sk_anc_data_recv(m, msg, tsk); | 1355 | set_orig_addr(m, hdr); |
1350 | if (res) | 1356 | rc = tipc_sk_anc_data_recv(m, hdr, tsk); |
1357 | if (unlikely(rc)) | ||
1351 | goto exit; | 1358 | goto exit; |
1352 | 1359 | ||
1353 | /* Capture message data (if valid) & compute return value (always) */ | 1360 | /* Capture data if non-error msg, otherwise just set return value */ |
1354 | if (!err) { | 1361 | if (likely(!err)) { |
1355 | if (unlikely(buf_len < sz)) { | 1362 | copy = min_t(int, dlen, buflen); |
1356 | sz = buf_len; | 1363 | if (unlikely(copy != dlen)) |
1357 | m->msg_flags |= MSG_TRUNC; | 1364 | m->msg_flags |= MSG_TRUNC; |
1358 | } | 1365 | rc = skb_copy_datagram_msg(skb, hlen, m, copy); |
1359 | res = skb_copy_datagram_msg(buf, hlen, m, sz); | ||
1360 | if (res) | ||
1361 | goto exit; | ||
1362 | res = sz; | ||
1363 | } else { | 1366 | } else { |
1364 | if (is_connectionless || err == TIPC_CONN_SHUTDOWN || | 1367 | copy = 0; |
1365 | m->msg_control) | 1368 | rc = 0; |
1366 | res = 0; | 1369 | if (err != TIPC_CONN_SHUTDOWN && connected && !m->msg_control) |
1367 | else | 1370 | rc = -ECONNRESET; |
1368 | res = -ECONNRESET; | ||
1369 | } | 1371 | } |
1372 | if (unlikely(rc)) | ||
1373 | goto exit; | ||
1370 | 1374 | ||
1375 | /* Caption of data or error code/rejected data was successful */ | ||
1371 | if (unlikely(flags & MSG_PEEK)) | 1376 | if (unlikely(flags & MSG_PEEK)) |
1372 | goto exit; | 1377 | goto exit; |
1373 | 1378 | ||
1374 | if (likely(!is_connectionless)) { | ||
1375 | tsk->rcv_unacked += tsk_inc(tsk, hlen + sz); | ||
1376 | if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4))) | ||
1377 | tipc_sk_send_ack(tsk); | ||
1378 | } | ||
1379 | tsk_advance_rx_queue(sk); | 1379 | tsk_advance_rx_queue(sk); |
1380 | if (likely(!connected)) | ||
1381 | goto exit; | ||
1382 | |||
1383 | /* Send connection flow control ack when applicable */ | ||
1384 | tsk->rcv_unacked += tsk_inc(tsk, hlen + dlen); | ||
1385 | if (tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE) | ||
1386 | tipc_sk_send_ack(tsk); | ||
1380 | exit: | 1387 | exit: |
1381 | release_sock(sk); | 1388 | release_sock(sk); |
1382 | return res; | 1389 | return rc ? rc : copy; |
1383 | } | 1390 | } |
1384 | 1391 | ||
1385 | /** | 1392 | /** |
1386 | * tipc_recv_stream - receive stream-oriented data | 1393 | * tipc_recvstream - receive stream-oriented data |
1387 | * @m: descriptor for message info | 1394 | * @m: descriptor for message info |
1388 | * @buf_len: total size of user buffer area | 1395 | * @buflen: total size of user buffer area |
1389 | * @flags: receive flags | 1396 | * @flags: receive flags |
1390 | * | 1397 | * |
1391 | * Used for SOCK_STREAM messages only. If not enough data is available | 1398 | * Used for SOCK_STREAM messages only. If not enough data is available |
@@ -1393,111 +1400,98 @@ exit: | |||
1393 | * | 1400 | * |
1394 | * Returns size of returned message data, errno otherwise | 1401 | * Returns size of returned message data, errno otherwise |
1395 | */ | 1402 | */ |
1396 | static int tipc_recv_stream(struct socket *sock, struct msghdr *m, | 1403 | static int tipc_recvstream(struct socket *sock, struct msghdr *m, |
1397 | size_t buf_len, int flags) | 1404 | size_t buflen, int flags) |
1398 | { | 1405 | { |
1399 | struct sock *sk = sock->sk; | 1406 | struct sock *sk = sock->sk; |
1400 | struct tipc_sock *tsk = tipc_sk(sk); | 1407 | struct tipc_sock *tsk = tipc_sk(sk); |
1401 | struct sk_buff *buf; | 1408 | struct sk_buff *skb; |
1402 | struct tipc_msg *msg; | 1409 | struct tipc_msg *hdr; |
1403 | long timeo; | 1410 | struct tipc_skb_cb *skb_cb; |
1404 | unsigned int sz; | 1411 | bool peek = flags & MSG_PEEK; |
1405 | int target; | 1412 | int offset, required, copy, copied = 0; |
1406 | int sz_copied = 0; | 1413 | int hlen, dlen, err, rc; |
1407 | u32 err; | 1414 | long timeout; |
1408 | int res = 0, hlen; | ||
1409 | 1415 | ||
1410 | /* Catch invalid receive attempts */ | 1416 | /* Catch invalid receive attempts */ |
1411 | if (unlikely(!buf_len)) | 1417 | if (unlikely(!buflen)) |
1412 | return -EINVAL; | 1418 | return -EINVAL; |
1413 | 1419 | ||
1414 | lock_sock(sk); | 1420 | lock_sock(sk); |
1415 | 1421 | ||
1416 | if (unlikely(sk->sk_state == TIPC_OPEN)) { | 1422 | if (unlikely(sk->sk_state == TIPC_OPEN)) { |
1417 | res = -ENOTCONN; | 1423 | rc = -ENOTCONN; |
1418 | goto exit; | ||
1419 | } | ||
1420 | |||
1421 | target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); | ||
1422 | timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | ||
1423 | |||
1424 | restart: | ||
1425 | /* Look for a message in receive queue; wait if necessary */ | ||
1426 | res = tipc_wait_for_rcvmsg(sock, &timeo); | ||
1427 | if (res) | ||
1428 | goto exit; | 1424 | goto exit; |
1429 | |||
1430 | /* Look at first message in receive queue */ | ||
1431 | buf = skb_peek(&sk->sk_receive_queue); | ||
1432 | msg = buf_msg(buf); | ||
1433 | sz = msg_data_sz(msg); | ||
1434 | hlen = msg_hdr_sz(msg); | ||
1435 | err = msg_errcode(msg); | ||
1436 | |||
1437 | /* Discard an empty non-errored message & try again */ | ||
1438 | if ((!sz) && (!err)) { | ||
1439 | tsk_advance_rx_queue(sk); | ||
1440 | goto restart; | ||
1441 | } | 1425 | } |
1426 | required = sock_rcvlowat(sk, flags & MSG_WAITALL, buflen); | ||
1427 | timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); | ||
1442 | 1428 | ||
1443 | /* Optionally capture sender's address & ancillary data of first msg */ | 1429 | do { |
1444 | if (sz_copied == 0) { | 1430 | /* Look at first msg in receive queue; wait if necessary */ |
1445 | set_orig_addr(m, msg); | 1431 | rc = tipc_wait_for_rcvmsg(sock, &timeout); |
1446 | res = tipc_sk_anc_data_recv(m, msg, tsk); | 1432 | if (unlikely(rc)) |
1447 | if (res) | 1433 | break; |
1448 | goto exit; | 1434 | skb = skb_peek(&sk->sk_receive_queue); |
1449 | } | 1435 | skb_cb = TIPC_SKB_CB(skb); |
1450 | 1436 | hdr = buf_msg(skb); | |
1451 | /* Capture message data (if valid) & compute return value (always) */ | 1437 | dlen = msg_data_sz(hdr); |
1452 | if (!err) { | 1438 | hlen = msg_hdr_sz(hdr); |
1453 | u32 offset = TIPC_SKB_CB(buf)->bytes_read; | 1439 | err = msg_errcode(hdr); |
1454 | u32 needed; | 1440 | |
1455 | int sz_to_copy; | 1441 | /* Discard any empty non-errored (SYN-) message */ |
1456 | 1442 | if (unlikely(!dlen && !err)) { | |
1457 | sz -= offset; | 1443 | tsk_advance_rx_queue(sk); |
1458 | needed = (buf_len - sz_copied); | 1444 | continue; |
1459 | sz_to_copy = min(sz, needed); | 1445 | } |
1460 | |||
1461 | res = skb_copy_datagram_msg(buf, hlen + offset, m, sz_to_copy); | ||
1462 | if (res) | ||
1463 | goto exit; | ||
1464 | 1446 | ||
1465 | sz_copied += sz_to_copy; | 1447 | /* Collect msg meta data, incl. error code and rejected data */ |
1448 | if (!copied) { | ||
1449 | set_orig_addr(m, hdr); | ||
1450 | rc = tipc_sk_anc_data_recv(m, hdr, tsk); | ||
1451 | if (rc) | ||
1452 | break; | ||
1453 | } | ||
1466 | 1454 | ||
1467 | if (sz_to_copy < sz) { | 1455 | /* Copy data if msg ok, otherwise return error/partial data */ |
1468 | if (!(flags & MSG_PEEK)) | 1456 | if (likely(!err)) { |
1469 | TIPC_SKB_CB(buf)->bytes_read = | 1457 | offset = skb_cb->bytes_read; |
1470 | offset + sz_to_copy; | 1458 | copy = min_t(int, dlen - offset, buflen - copied); |
1471 | goto exit; | 1459 | rc = skb_copy_datagram_msg(skb, hlen + offset, m, copy); |
1460 | if (unlikely(rc)) | ||
1461 | break; | ||
1462 | copied += copy; | ||
1463 | offset += copy; | ||
1464 | if (unlikely(offset < dlen)) { | ||
1465 | if (!peek) | ||
1466 | skb_cb->bytes_read = offset; | ||
1467 | break; | ||
1468 | } | ||
1469 | } else { | ||
1470 | rc = 0; | ||
1471 | if ((err != TIPC_CONN_SHUTDOWN) && !m->msg_control) | ||
1472 | rc = -ECONNRESET; | ||
1473 | if (copied || rc) | ||
1474 | break; | ||
1472 | } | 1475 | } |
1473 | } else { | ||
1474 | if (sz_copied != 0) | ||
1475 | goto exit; /* can't add error msg to valid data */ | ||
1476 | 1476 | ||
1477 | if ((err == TIPC_CONN_SHUTDOWN) || m->msg_control) | 1477 | if (unlikely(peek)) |
1478 | res = 0; | 1478 | break; |
1479 | else | ||
1480 | res = -ECONNRESET; | ||
1481 | } | ||
1482 | 1479 | ||
1483 | if (unlikely(flags & MSG_PEEK)) | 1480 | tsk_advance_rx_queue(sk); |
1484 | goto exit; | ||
1485 | 1481 | ||
1486 | tsk->rcv_unacked += tsk_inc(tsk, hlen + sz); | 1482 | /* Send connection flow control advertisement when applicable */ |
1487 | if (unlikely(tsk->rcv_unacked >= (tsk->rcv_win / 4))) | 1483 | tsk->rcv_unacked += tsk_inc(tsk, hlen + dlen); |
1488 | tipc_sk_send_ack(tsk); | 1484 | if (unlikely(tsk->rcv_unacked >= tsk->rcv_win / TIPC_ACK_RATE)) |
1489 | tsk_advance_rx_queue(sk); | 1485 | tipc_sk_send_ack(tsk); |
1490 | 1486 | ||
1491 | /* Loop around if more data is required */ | 1487 | /* Exit if all requested data or FIN/error received */ |
1492 | if ((sz_copied < buf_len) && /* didn't get all requested data */ | 1488 | if (copied == buflen || err) |
1493 | (!skb_queue_empty(&sk->sk_receive_queue) || | 1489 | break; |
1494 | (sz_copied < target)) && /* and more is ready or required */ | ||
1495 | (!err)) /* and haven't reached a FIN */ | ||
1496 | goto restart; | ||
1497 | 1490 | ||
1491 | } while (!skb_queue_empty(&sk->sk_receive_queue) || copied < required); | ||
1498 | exit: | 1492 | exit: |
1499 | release_sock(sk); | 1493 | release_sock(sk); |
1500 | return sz_copied ? sz_copied : res; | 1494 | return copied ? copied : rc; |
1501 | } | 1495 | } |
1502 | 1496 | ||
1503 | /** | 1497 | /** |
@@ -1550,6 +1544,8 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
1550 | struct sock *sk = &tsk->sk; | 1544 | struct sock *sk = &tsk->sk; |
1551 | struct net *net = sock_net(sk); | 1545 | struct net *net = sock_net(sk); |
1552 | struct tipc_msg *hdr = buf_msg(skb); | 1546 | struct tipc_msg *hdr = buf_msg(skb); |
1547 | u32 pport = msg_origport(hdr); | ||
1548 | u32 pnode = msg_orignode(hdr); | ||
1553 | 1549 | ||
1554 | if (unlikely(msg_mcast(hdr))) | 1550 | if (unlikely(msg_mcast(hdr))) |
1555 | return false; | 1551 | return false; |
@@ -1557,18 +1553,28 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
1557 | switch (sk->sk_state) { | 1553 | switch (sk->sk_state) { |
1558 | case TIPC_CONNECTING: | 1554 | case TIPC_CONNECTING: |
1559 | /* Accept only ACK or NACK message */ | 1555 | /* Accept only ACK or NACK message */ |
1560 | if (unlikely(!msg_connected(hdr))) | 1556 | if (unlikely(!msg_connected(hdr))) { |
1561 | return false; | 1557 | if (pport != tsk_peer_port(tsk) || |
1558 | pnode != tsk_peer_node(tsk)) | ||
1559 | return false; | ||
1560 | |||
1561 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | ||
1562 | sk->sk_err = ECONNREFUSED; | ||
1563 | sk->sk_state_change(sk); | ||
1564 | return true; | ||
1565 | } | ||
1562 | 1566 | ||
1563 | if (unlikely(msg_errcode(hdr))) { | 1567 | if (unlikely(msg_errcode(hdr))) { |
1564 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | 1568 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); |
1565 | sk->sk_err = ECONNREFUSED; | 1569 | sk->sk_err = ECONNREFUSED; |
1570 | sk->sk_state_change(sk); | ||
1566 | return true; | 1571 | return true; |
1567 | } | 1572 | } |
1568 | 1573 | ||
1569 | if (unlikely(!msg_isdata(hdr))) { | 1574 | if (unlikely(!msg_isdata(hdr))) { |
1570 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | 1575 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); |
1571 | sk->sk_err = EINVAL; | 1576 | sk->sk_err = EINVAL; |
1577 | sk->sk_state_change(sk); | ||
1572 | return true; | 1578 | return true; |
1573 | } | 1579 | } |
1574 | 1580 | ||
@@ -1580,8 +1586,7 @@ static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb) | |||
1580 | return true; | 1586 | return true; |
1581 | 1587 | ||
1582 | /* If empty 'ACK-' message, wake up sleeping connect() */ | 1588 | /* If empty 'ACK-' message, wake up sleeping connect() */ |
1583 | if (waitqueue_active(sk_sleep(sk))) | 1589 | sk->sk_data_ready(sk); |
1584 | wake_up_interruptible(sk_sleep(sk)); | ||
1585 | 1590 | ||
1586 | /* 'ACK-' message is neither accepted nor rejected: */ | 1591 | /* 'ACK-' message is neither accepted nor rejected: */ |
1587 | msg_set_dest_droppable(hdr, 1); | 1592 | msg_set_dest_droppable(hdr, 1); |
@@ -2029,7 +2034,8 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) | |||
2029 | * | 2034 | * |
2030 | * Returns 0 on success, errno otherwise | 2035 | * Returns 0 on success, errno otherwise |
2031 | */ | 2036 | */ |
2032 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | 2037 | static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags, |
2038 | bool kern) | ||
2033 | { | 2039 | { |
2034 | struct sock *new_sk, *sk = sock->sk; | 2040 | struct sock *new_sk, *sk = sock->sk; |
2035 | struct sk_buff *buf; | 2041 | struct sk_buff *buf; |
@@ -2051,7 +2057,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
2051 | 2057 | ||
2052 | buf = skb_peek(&sk->sk_receive_queue); | 2058 | buf = skb_peek(&sk->sk_receive_queue); |
2053 | 2059 | ||
2054 | res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 0); | 2060 | res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, kern); |
2055 | if (res) | 2061 | if (res) |
2056 | goto exit; | 2062 | goto exit; |
2057 | security_sk_clone(sock->sk, new_sock->sk); | 2063 | security_sk_clone(sock->sk, new_sock->sk); |
@@ -2509,6 +2515,28 @@ static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
2509 | } | 2515 | } |
2510 | } | 2516 | } |
2511 | 2517 | ||
2518 | static int tipc_socketpair(struct socket *sock1, struct socket *sock2) | ||
2519 | { | ||
2520 | struct tipc_sock *tsk2 = tipc_sk(sock2->sk); | ||
2521 | struct tipc_sock *tsk1 = tipc_sk(sock1->sk); | ||
2522 | u32 onode = tipc_own_addr(sock_net(sock1->sk)); | ||
2523 | |||
2524 | tsk1->peer.family = AF_TIPC; | ||
2525 | tsk1->peer.addrtype = TIPC_ADDR_ID; | ||
2526 | tsk1->peer.scope = TIPC_NODE_SCOPE; | ||
2527 | tsk1->peer.addr.id.ref = tsk2->portid; | ||
2528 | tsk1->peer.addr.id.node = onode; | ||
2529 | tsk2->peer.family = AF_TIPC; | ||
2530 | tsk2->peer.addrtype = TIPC_ADDR_ID; | ||
2531 | tsk2->peer.scope = TIPC_NODE_SCOPE; | ||
2532 | tsk2->peer.addr.id.ref = tsk1->portid; | ||
2533 | tsk2->peer.addr.id.node = onode; | ||
2534 | |||
2535 | tipc_sk_finish_conn(tsk1, tsk2->portid, onode); | ||
2536 | tipc_sk_finish_conn(tsk2, tsk1->portid, onode); | ||
2537 | return 0; | ||
2538 | } | ||
2539 | |||
2512 | /* Protocol switches for the various types of TIPC sockets */ | 2540 | /* Protocol switches for the various types of TIPC sockets */ |
2513 | 2541 | ||
2514 | static const struct proto_ops msg_ops = { | 2542 | static const struct proto_ops msg_ops = { |
@@ -2517,7 +2545,7 @@ static const struct proto_ops msg_ops = { | |||
2517 | .release = tipc_release, | 2545 | .release = tipc_release, |
2518 | .bind = tipc_bind, | 2546 | .bind = tipc_bind, |
2519 | .connect = tipc_connect, | 2547 | .connect = tipc_connect, |
2520 | .socketpair = sock_no_socketpair, | 2548 | .socketpair = tipc_socketpair, |
2521 | .accept = sock_no_accept, | 2549 | .accept = sock_no_accept, |
2522 | .getname = tipc_getname, | 2550 | .getname = tipc_getname, |
2523 | .poll = tipc_poll, | 2551 | .poll = tipc_poll, |
@@ -2538,7 +2566,7 @@ static const struct proto_ops packet_ops = { | |||
2538 | .release = tipc_release, | 2566 | .release = tipc_release, |
2539 | .bind = tipc_bind, | 2567 | .bind = tipc_bind, |
2540 | .connect = tipc_connect, | 2568 | .connect = tipc_connect, |
2541 | .socketpair = sock_no_socketpair, | 2569 | .socketpair = tipc_socketpair, |
2542 | .accept = tipc_accept, | 2570 | .accept = tipc_accept, |
2543 | .getname = tipc_getname, | 2571 | .getname = tipc_getname, |
2544 | .poll = tipc_poll, | 2572 | .poll = tipc_poll, |
@@ -2559,7 +2587,7 @@ static const struct proto_ops stream_ops = { | |||
2559 | .release = tipc_release, | 2587 | .release = tipc_release, |
2560 | .bind = tipc_bind, | 2588 | .bind = tipc_bind, |
2561 | .connect = tipc_connect, | 2589 | .connect = tipc_connect, |
2562 | .socketpair = sock_no_socketpair, | 2590 | .socketpair = tipc_socketpair, |
2563 | .accept = tipc_accept, | 2591 | .accept = tipc_accept, |
2564 | .getname = tipc_getname, | 2592 | .getname = tipc_getname, |
2565 | .poll = tipc_poll, | 2593 | .poll = tipc_poll, |
@@ -2569,7 +2597,7 @@ static const struct proto_ops stream_ops = { | |||
2569 | .setsockopt = tipc_setsockopt, | 2597 | .setsockopt = tipc_setsockopt, |
2570 | .getsockopt = tipc_getsockopt, | 2598 | .getsockopt = tipc_getsockopt, |
2571 | .sendmsg = tipc_sendstream, | 2599 | .sendmsg = tipc_sendstream, |
2572 | .recvmsg = tipc_recv_stream, | 2600 | .recvmsg = tipc_recvstream, |
2573 | .mmap = sock_no_mmap, | 2601 | .mmap = sock_no_mmap, |
2574 | .sendpage = sock_no_sendpage | 2602 | .sendpage = sock_no_sendpage |
2575 | }; | 2603 | }; |
@@ -2842,7 +2870,7 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
2842 | 2870 | ||
2843 | err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, | 2871 | err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX, |
2844 | attrs[TIPC_NLA_SOCK], | 2872 | attrs[TIPC_NLA_SOCK], |
2845 | tipc_nl_sock_policy); | 2873 | tipc_nl_sock_policy, NULL); |
2846 | if (err) | 2874 | if (err) |
2847 | return err; | 2875 | return err; |
2848 | 2876 | ||