diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index d838a4b66d3a..1762323156af 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #define SS_READY -2 /* socket is connectionless */ | 46 | #define SS_READY -2 /* socket is connectionless */ |
47 | 47 | ||
48 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 48 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ |
49 | #define TIPC_FWD_MSG 1 | ||
49 | 50 | ||
50 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); | 51 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); |
51 | static void tipc_data_ready(struct sock *sk); | 52 | static void tipc_data_ready(struct sock *sk); |
@@ -534,6 +535,46 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
534 | } | 535 | } |
535 | 536 | ||
536 | /** | 537 | /** |
538 | * tipc_sk_proto_rcv - receive a connection mng protocol message | ||
539 | * @tsk: receiving socket | ||
540 | * @dnode: node to send response message to, if any | ||
541 | * @buf: buffer containing protocol message | ||
542 | * Returns 0 (TIPC_OK) if message was consumed, 1 (TIPC_FWD_MSG) if | ||
543 | * (CONN_PROBE_REPLY) message should be forwarded. | ||
544 | */ | ||
545 | int tipc_sk_proto_rcv(struct tipc_sock *tsk, u32 *dnode, struct sk_buff *buf) | ||
546 | { | ||
547 | struct tipc_msg *msg = buf_msg(buf); | ||
548 | struct tipc_port *port = &tsk->port; | ||
549 | int wakeable; | ||
550 | |||
551 | /* Ignore if connection cannot be validated: */ | ||
552 | if (!port->connected || !tipc_port_peer_msg(port, msg)) | ||
553 | goto exit; | ||
554 | |||
555 | port->probing_state = TIPC_CONN_OK; | ||
556 | |||
557 | if (msg_type(msg) == CONN_ACK) { | ||
558 | wakeable = tipc_port_congested(port) && port->congested; | ||
559 | port->acked += msg_msgcnt(msg); | ||
560 | if (!tipc_port_congested(port)) { | ||
561 | port->congested = 0; | ||
562 | if (wakeable) | ||
563 | tipc_port_wakeup(port); | ||
564 | } | ||
565 | } else if (msg_type(msg) == CONN_PROBE) { | ||
566 | if (!tipc_msg_reverse(buf, dnode, TIPC_OK)) | ||
567 | return TIPC_OK; | ||
568 | msg_set_type(msg, CONN_PROBE_REPLY); | ||
569 | return TIPC_FWD_MSG; | ||
570 | } | ||
571 | /* Do nothing if msg_type() == CONN_PROBE_REPLY */ | ||
572 | exit: | ||
573 | kfree_skb(buf); | ||
574 | return TIPC_OK; | ||
575 | } | ||
576 | |||
577 | /** | ||
537 | * dest_name_check - verify user is permitted to send to specified port name | 578 | * dest_name_check - verify user is permitted to send to specified port name |
538 | * @dest: destination address | 579 | * @dest: destination address |
539 | * @m: descriptor for message to be sent | 580 | * @m: descriptor for message to be sent |
@@ -1406,7 +1447,7 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf) | |||
1406 | * Called with socket lock already taken; port lock may also be taken. | 1447 | * Called with socket lock already taken; port lock may also be taken. |
1407 | * | 1448 | * |
1408 | * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message | 1449 | * Returns 0 (TIPC_OK) if message was consumed, -TIPC error code if message |
1409 | * to be rejected. | 1450 | * to be rejected, 1 (TIPC_FWD_MSG) if (CONN_MANAGER) message to be forwarded |
1410 | */ | 1451 | */ |
1411 | static int filter_rcv(struct sock *sk, struct sk_buff *buf) | 1452 | static int filter_rcv(struct sock *sk, struct sk_buff *buf) |
1412 | { | 1453 | { |
@@ -1414,12 +1455,11 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1414 | struct tipc_sock *tsk = tipc_sk(sk); | 1455 | struct tipc_sock *tsk = tipc_sk(sk); |
1415 | struct tipc_msg *msg = buf_msg(buf); | 1456 | struct tipc_msg *msg = buf_msg(buf); |
1416 | unsigned int limit = rcvbuf_limit(sk, buf); | 1457 | unsigned int limit = rcvbuf_limit(sk, buf); |
1458 | u32 onode; | ||
1417 | int rc = TIPC_OK; | 1459 | int rc = TIPC_OK; |
1418 | 1460 | ||
1419 | if (unlikely(msg_user(msg) == CONN_MANAGER)) { | 1461 | if (unlikely(msg_user(msg) == CONN_MANAGER)) |
1420 | tipc_port_proto_rcv(&tsk->port, buf); | 1462 | return tipc_sk_proto_rcv(tsk, &onode, buf); |
1421 | return TIPC_OK; | ||
1422 | } | ||
1423 | 1463 | ||
1424 | /* Reject message if it is wrong sort of message for socket */ | 1464 | /* Reject message if it is wrong sort of message for socket */ |
1425 | if (msg_type(msg) > TIPC_DIRECT_MSG) | 1465 | if (msg_type(msg) > TIPC_DIRECT_MSG) |
@@ -1465,10 +1505,16 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) | |||
1465 | 1505 | ||
1466 | rc = filter_rcv(sk, buf); | 1506 | rc = filter_rcv(sk, buf); |
1467 | 1507 | ||
1468 | if (unlikely(rc && tipc_msg_reverse(buf, &onode, -rc))) | 1508 | if (likely(!rc)) { |
1469 | tipc_link_xmit2(buf, onode, 0); | 1509 | if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) |
1470 | else if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) | 1510 | atomic_add(truesize, &tsk->dupl_rcvcnt); |
1471 | atomic_add(truesize, &tsk->dupl_rcvcnt); | 1511 | return 0; |
1512 | } | ||
1513 | |||
1514 | if ((rc < 0) && !tipc_msg_reverse(buf, &onode, -rc)) | ||
1515 | return 0; | ||
1516 | |||
1517 | tipc_link_xmit2(buf, onode, 0); | ||
1472 | 1518 | ||
1473 | return 0; | 1519 | return 0; |
1474 | } | 1520 | } |