|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * net/tipc/socket.c: TIPC socket API
|
|
|
+* net/tipc/socket.c: TIPC socket API
|
|
|
*
|
|
|
* Copyright (c) 2001-2007, 2012-2014, Ericsson AB
|
|
|
* Copyright (c) 2004-2008, 2010-2013, Wind River Systems
|
|
@@ -45,7 +45,7 @@
|
|
|
|
|
|
#define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */
|
|
|
|
|
|
-static int backlog_rcv(struct sock *sk, struct sk_buff *skb);
|
|
|
+static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
|
|
|
static void tipc_data_ready(struct sock *sk);
|
|
|
static void tipc_write_space(struct sock *sk);
|
|
|
static int tipc_release(struct socket *sock);
|
|
@@ -196,11 +196,12 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
|
|
|
sock->state = state;
|
|
|
|
|
|
sock_init_data(sock, sk);
|
|
|
- sk->sk_backlog_rcv = backlog_rcv;
|
|
|
+ sk->sk_backlog_rcv = tipc_backlog_rcv;
|
|
|
sk->sk_rcvbuf = sysctl_tipc_rmem[1];
|
|
|
sk->sk_data_ready = tipc_data_ready;
|
|
|
sk->sk_write_space = tipc_write_space;
|
|
|
- tipc_sk(sk)->conn_timeout = CONN_TIMEOUT_DEFAULT;
|
|
|
+ tsk->conn_timeout = CONN_TIMEOUT_DEFAULT;
|
|
|
+ atomic_set(&tsk->dupl_rcvcnt, 0);
|
|
|
tipc_port_unlock(port);
|
|
|
|
|
|
if (sock->state == SS_READY) {
|
|
@@ -1416,7 +1417,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * backlog_rcv - handle incoming message from backlog queue
|
|
|
+ * tipc_backlog_rcv - handle incoming message from backlog queue
|
|
|
* @sk: socket
|
|
|
* @buf: message
|
|
|
*
|
|
@@ -1424,13 +1425,18 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
|
|
|
*
|
|
|
* Returns 0
|
|
|
*/
|
|
|
-static int backlog_rcv(struct sock *sk, struct sk_buff *buf)
|
|
|
+static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf)
|
|
|
{
|
|
|
u32 res;
|
|
|
+ struct tipc_sock *tsk = tipc_sk(sk);
|
|
|
|
|
|
res = filter_rcv(sk, buf);
|
|
|
- if (res)
|
|
|
+ if (unlikely(res))
|
|
|
tipc_reject_msg(buf, res);
|
|
|
+
|
|
|
+ if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT)
|
|
|
+ atomic_add(buf->truesize, &tsk->dupl_rcvcnt);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1445,8 +1451,9 @@ static int backlog_rcv(struct sock *sk, struct sk_buff *buf)
|
|
|
*/
|
|
|
u32 tipc_sk_rcv(struct sock *sk, struct sk_buff *buf)
|
|
|
{
|
|
|
+ struct tipc_sock *tsk = tipc_sk(sk);
|
|
|
u32 res;
|
|
|
-
|
|
|
+ uint limit;
|
|
|
/*
|
|
|
* Process message if socket is unlocked; otherwise add to backlog queue
|
|
|
*
|
|
@@ -1457,7 +1464,10 @@ u32 tipc_sk_rcv(struct sock *sk, struct sk_buff *buf)
|
|
|
if (!sock_owned_by_user(sk)) {
|
|
|
res = filter_rcv(sk, buf);
|
|
|
} else {
|
|
|
- if (sk_add_backlog(sk, buf, rcvbuf_limit(sk, buf)))
|
|
|
+ if (sk->sk_backlog.len == 0)
|
|
|
+ atomic_set(&tsk->dupl_rcvcnt, 0);
|
|
|
+ limit = rcvbuf_limit(sk, buf) + atomic_read(&tsk->dupl_rcvcnt);
|
|
|
+ if (sk_add_backlog(sk, buf, limit))
|
|
|
res = TIPC_ERR_OVERLOAD;
|
|
|
else
|
|
|
res = TIPC_OK;
|