summaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2018-03-01 16:05:12 +0100
committerDavid S. Miller <davem@davemloft.net>2018-03-04 19:00:56 +0100
commitc2666de1fde3a02583c2c4d4af4bc54f7252e891 (patch)
treefddbe84db484a8ad895bffe70b06104fd105c2ba /net/sctp
parentsctp: factor out sctp_sendmsg_new_asoc from sctp_sendmsg (diff)
downloadlinux-c2666de1fde3a02583c2c4d4af4bc54f7252e891.tar.xz
linux-c2666de1fde3a02583c2c4d4af4bc54f7252e891.zip
sctp: factor out sctp_sendmsg_check_sflags from sctp_sendmsg
This patch is to move the codes for checking sinfo_flags on one asoc after this asoc has been found into sctp_sendmsg_check_sflags. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/socket.c72
1 files changed, 36 insertions, 36 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 58bb55dce8f6..93cff9963614 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1687,6 +1687,39 @@ free:
return err;
}
+static int sctp_sendmsg_check_sflags(struct sctp_association *asoc,
+ __u16 sflags, struct msghdr *msg,
+ size_t msg_len)
+{
+ struct sock *sk = asoc->base.sk;
+ struct net *net = sock_net(sk);
+
+ if (sctp_state(asoc, CLOSED) && sctp_style(sk, TCP))
+ return -EPIPE;
+
+ if (sflags & SCTP_EOF) {
+ pr_debug("%s: shutting down association:%p\n", __func__, asoc);
+ sctp_primitive_SHUTDOWN(net, asoc, NULL);
+
+ return 0;
+ }
+
+ if (sflags & SCTP_ABORT) {
+ struct sctp_chunk *chunk;
+
+ chunk = sctp_make_abort_user(asoc, msg, msg_len);
+ if (!chunk)
+ return -ENOMEM;
+
+ pr_debug("%s: aborting association:%p\n", __func__, asoc);
+ sctp_primitive_ABORT(net, asoc, chunk);
+
+ return 0;
+ }
+
+ return 1;
+}
+
static int sctp_sendmsg_to_asoc(struct sctp_association *asoc,
struct msghdr *msg, size_t msg_len,
struct sctp_transport *transport,
@@ -1783,12 +1816,10 @@ err:
static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
{
- struct net *net = sock_net(sk);
struct sctp_sock *sp;
struct sctp_endpoint *ep;
struct sctp_association *new_asoc = NULL, *asoc = NULL;
struct sctp_transport *transport, *chunk_tp;
- struct sctp_chunk *chunk;
union sctp_addr to;
struct sockaddr *msg_name = NULL;
struct sctp_sndrcvinfo default_sinfo;
@@ -1906,41 +1937,10 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
}
if (asoc) {
- pr_debug("%s: just looked up association:%p\n", __func__, asoc);
-
- /* We cannot send a message on a TCP-style SCTP_SS_ESTABLISHED
- * socket that has an association in CLOSED state. This can
- * happen when an accepted socket has an association that is
- * already CLOSED.
- */
- if (sctp_state(asoc, CLOSED) && sctp_style(sk, TCP)) {
- err = -EPIPE;
- goto out_unlock;
- }
-
- if (sinfo_flags & SCTP_EOF) {
- pr_debug("%s: shutting down association:%p\n",
- __func__, asoc);
-
- sctp_primitive_SHUTDOWN(net, asoc, NULL);
- err = 0;
+ err = sctp_sendmsg_check_sflags(asoc, sinfo_flags, msg,
+ msg_len);
+ if (err <= 0)
goto out_unlock;
- }
- if (sinfo_flags & SCTP_ABORT) {
-
- chunk = sctp_make_abort_user(asoc, msg, msg_len);
- if (!chunk) {
- err = -ENOMEM;
- goto out_unlock;
- }
-
- pr_debug("%s: aborting association:%p\n",
- __func__, asoc);
-
- sctp_primitive_ABORT(net, asoc, chunk);
- err = 0;
- goto out_unlock;
- }
}
/* Do we need to create the association? */