Skip to content

Commit ac0074e

Browse files
Jon Paul Maloydavem330
authored andcommitted
tipc: clean up connection protocol reception function
We simplify the code for receiving connection probes, leveraging the recently introduced tipc_msg_reverse() function. We also stick to the principle of sending a possible response message directly from the calling (tipc_sk_rcv or backlog_rcv) functions, hence making the call chain shallower and easier to follow. We make one small protocol change here, allowed according to the spec. If a protocol message arrives from a remote socket that is not the one we are connected to, we are currently generating a connection abort message and send it to the source. This behavior is unnecessary, and might even be a security risk, so instead we now choose to only ignore the message. The consequnce for the sender is that he will need longer time to discover his mistake (until the next timeout), but this is an extreme corner case, and may happen anyway under other circumstances, so we deem this change acceptable. Signed-off-by: Jon Maloy <[email protected]> Reviewed-by: Erik Hugne <[email protected]> Reviewed-by: Ying Xue <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ec8a2e5 commit ac0074e

File tree

5 files changed

+68
-63
lines changed

5 files changed

+68
-63
lines changed

net/tipc/msg.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,17 @@ bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err)
348348
struct tipc_msg ohdr;
349349
uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE);
350350

351-
if (skb_linearize(buf) || !msg_isdata(msg))
351+
if (skb_linearize(buf))
352+
goto exit;
353+
if (msg_dest_droppable(msg))
352354
goto exit;
353-
if (msg_dest_droppable(msg) || msg_errcode(msg))
355+
if (msg_errcode(msg))
354356
goto exit;
355357

356358
memcpy(&ohdr, msg, msg_hdr_sz(msg));
357-
msg_set_importance(msg, min_t(uint, ++imp, TIPC_CRITICAL_IMPORTANCE));
359+
imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
360+
if (msg_isdata(msg))
361+
msg_set_importance(msg, imp);
358362
msg_set_errcode(msg, err);
359363
msg_set_origport(msg, msg_destport(&ohdr));
360364
msg_set_destport(msg, msg_origport(&ohdr));

net/tipc/port.c

Lines changed: 3 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@
4242

4343
/* Connection management: */
4444
#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */
45-
#define CONFIRMED 0
46-
#define PROBING 1
4745

4846
#define MAX_REJECT_SIZE 1024
4947

@@ -299,11 +297,11 @@ static void port_timeout(unsigned long ref)
299297
}
300298

301299
/* Last probe answered ? */
302-
if (p_ptr->probing_state == PROBING) {
300+
if (p_ptr->probing_state == TIPC_CONN_PROBING) {
303301
buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT);
304302
} else {
305303
buf = port_build_proto_msg(p_ptr, CONN_PROBE, 0);
306-
p_ptr->probing_state = PROBING;
304+
p_ptr->probing_state = TIPC_CONN_PROBING;
307305
k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
308306
}
309307
tipc_port_unlock(p_ptr);
@@ -365,51 +363,6 @@ static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 er
365363
return buf;
366364
}
367365

368-
void tipc_port_proto_rcv(struct tipc_port *p_ptr, struct sk_buff *buf)
369-
{
370-
struct tipc_msg *msg = buf_msg(buf);
371-
struct sk_buff *r_buf = NULL;
372-
u32 destport = msg_destport(msg);
373-
int wakeable;
374-
375-
/* Validate connection */
376-
if (!p_ptr || !p_ptr->connected || !tipc_port_peer_msg(p_ptr, msg)) {
377-
r_buf = tipc_buf_acquire(BASIC_H_SIZE);
378-
if (r_buf) {
379-
msg = buf_msg(r_buf);
380-
tipc_msg_init(msg, TIPC_HIGH_IMPORTANCE, TIPC_CONN_MSG,
381-
BASIC_H_SIZE, msg_orignode(msg));
382-
msg_set_errcode(msg, TIPC_ERR_NO_PORT);
383-
msg_set_origport(msg, destport);
384-
msg_set_destport(msg, msg_origport(msg));
385-
}
386-
goto exit;
387-
}
388-
389-
/* Process protocol message sent by peer */
390-
switch (msg_type(msg)) {
391-
case CONN_ACK:
392-
wakeable = tipc_port_congested(p_ptr) && p_ptr->congested;
393-
p_ptr->acked += msg_msgcnt(msg);
394-
if (!tipc_port_congested(p_ptr)) {
395-
p_ptr->congested = 0;
396-
if (wakeable)
397-
tipc_port_wakeup(p_ptr);
398-
}
399-
break;
400-
case CONN_PROBE:
401-
r_buf = port_build_proto_msg(p_ptr, CONN_PROBE_REPLY, 0);
402-
break;
403-
default:
404-
/* CONN_PROBE_REPLY or unrecognized - no action required */
405-
break;
406-
}
407-
p_ptr->probing_state = CONFIRMED;
408-
exit:
409-
tipc_link_xmit2(r_buf, msg_destnode(msg), msg_link_selector(msg));
410-
kfree_skb(buf);
411-
}
412-
413366
static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id)
414367
{
415368
struct publication *publ;
@@ -613,7 +566,7 @@ int __tipc_port_connect(u32 ref, struct tipc_port *p_ptr,
613566
msg_set_hdr_sz(msg, SHORT_H_SIZE);
614567

615568
p_ptr->probing_interval = PROBING_INTERVAL;
616-
p_ptr->probing_state = CONFIRMED;
569+
p_ptr->probing_state = TIPC_CONN_OK;
617570
p_ptr->connected = 1;
618571
k_start_timer(&p_ptr->timer, p_ptr->probing_interval);
619572

net/tipc/port.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ int tipc_port_mcast_xmit(struct tipc_port *port,
140140
unsigned int len);
141141

142142
struct sk_buff *tipc_port_get_ports(void);
143-
void tipc_port_proto_rcv(struct tipc_port *port, struct sk_buff *buf);
144143
void tipc_port_mcast_rcv(struct sk_buff *buf, struct tipc_port_list *dp);
145144
void tipc_port_reinit(void);
146145

net/tipc/socket.c

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#define SS_READY -2 /* socket is connectionless */
4747

4848
#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
49+
#define TIPC_FWD_MSG 1
4950

5051
static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
5152
static void tipc_data_ready(struct sock *sk);
@@ -533,6 +534,46 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
533534
return mask;
534535
}
535536

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+
536577
/**
537578
* dest_name_check - verify user is permitted to send to specified port name
538579
* @dest: destination address
@@ -1406,20 +1447,19 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf)
14061447
* Called with socket lock already taken; port lock may also be taken.
14071448
*
14081449
* 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
14101451
*/
14111452
static int filter_rcv(struct sock *sk, struct sk_buff *buf)
14121453
{
14131454
struct socket *sock = sk->sk_socket;
14141455
struct tipc_sock *tsk = tipc_sk(sk);
14151456
struct tipc_msg *msg = buf_msg(buf);
14161457
unsigned int limit = rcvbuf_limit(sk, buf);
1458+
u32 onode;
14171459
int rc = TIPC_OK;
14181460

1419-
if (unlikely(msg_user(msg) == CONN_MANAGER)) {
1420-
tipc_port_proto_rcv(&tsk->port, buf);
1421-
return TIPC_OK;
1422-
}
1461+
if (unlikely(msg_user(msg) == CONN_MANAGER))
1462+
return tipc_sk_proto_rcv(tsk, &onode, buf);
14231463

14241464
/* Reject message if it is wrong sort of message for socket */
14251465
if (msg_type(msg) > TIPC_DIRECT_MSG)
@@ -1465,10 +1505,16 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
14651505

14661506
rc = filter_rcv(sk, buf);
14671507

1468-
if (unlikely(rc && tipc_msg_reverse(buf, &onode, -rc)))
1469-
tipc_link_xmit2(buf, onode, 0);
1470-
else if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT)
1471-
atomic_add(truesize, &tsk->dupl_rcvcnt);
1508+
if (likely(!rc)) {
1509+
if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT)
1510+
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);
14721518

14731519
return 0;
14741520
}

net/tipc/socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include "port.h"
3939
#include <net/sock.h>
4040

41+
#define TIPC_CONN_OK 0
42+
#define TIPC_CONN_PROBING 1
43+
4144
/**
4245
* struct tipc_sock - TIPC socket structure
4346
* @sk: socket - interacts with 'port' and with user via the socket API

0 commit comments

Comments
 (0)