@@ -1644,6 +1644,12 @@ static int sctp_sendmsg_parse(struct sock *sk, struct sctp_cmsgs *cmsgs,
16441644 srinfo -> sinfo_assoc_id = cmsgs -> sinfo -> snd_assoc_id ;
16451645 }
16461646
1647+ if (cmsgs -> prinfo ) {
1648+ srinfo -> sinfo_timetolive = cmsgs -> prinfo -> pr_value ;
1649+ SCTP_PR_SET_POLICY (srinfo -> sinfo_flags ,
1650+ cmsgs -> prinfo -> pr_policy );
1651+ }
1652+
16471653 sflags = srinfo -> sinfo_flags ;
16481654 if (!sflags && msg_len )
16491655 return 0 ;
@@ -1670,6 +1676,7 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
16701676 struct net * net = sock_net (sk );
16711677 struct sctp_association * asoc ;
16721678 enum sctp_scope scope ;
1679+ struct cmsghdr * cmsg ;
16731680 int err = - EINVAL ;
16741681
16751682 * tp = NULL ;
@@ -1735,6 +1742,67 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
17351742 goto free ;
17361743 }
17371744
1745+ if (!cmsgs -> addrs_msg )
1746+ return 0 ;
1747+
1748+ /* sendv addr list parse */
1749+ for_each_cmsghdr (cmsg , cmsgs -> addrs_msg ) {
1750+ struct sctp_transport * transport ;
1751+ struct sctp_association * old ;
1752+ union sctp_addr _daddr ;
1753+ int dlen ;
1754+
1755+ if (cmsg -> cmsg_level != IPPROTO_SCTP ||
1756+ (cmsg -> cmsg_type != SCTP_DSTADDRV4 &&
1757+ cmsg -> cmsg_type != SCTP_DSTADDRV6 ))
1758+ continue ;
1759+
1760+ daddr = & _daddr ;
1761+ memset (daddr , 0 , sizeof (* daddr ));
1762+ dlen = cmsg -> cmsg_len - sizeof (struct cmsghdr );
1763+ if (cmsg -> cmsg_type == SCTP_DSTADDRV4 ) {
1764+ if (dlen < sizeof (struct in_addr ))
1765+ goto free ;
1766+
1767+ dlen = sizeof (struct in_addr );
1768+ daddr -> v4 .sin_family = AF_INET ;
1769+ daddr -> v4 .sin_port = htons (asoc -> peer .port );
1770+ memcpy (& daddr -> v4 .sin_addr , CMSG_DATA (cmsg ), dlen );
1771+ } else {
1772+ if (dlen < sizeof (struct in6_addr ))
1773+ goto free ;
1774+
1775+ dlen = sizeof (struct in6_addr );
1776+ daddr -> v6 .sin6_family = AF_INET6 ;
1777+ daddr -> v6 .sin6_port = htons (asoc -> peer .port );
1778+ memcpy (& daddr -> v6 .sin6_addr , CMSG_DATA (cmsg ), dlen );
1779+ }
1780+ err = sctp_verify_addr (sk , daddr , sizeof (* daddr ));
1781+ if (err )
1782+ goto free ;
1783+
1784+ old = sctp_endpoint_lookup_assoc (ep , daddr , & transport );
1785+ if (old && old != asoc ) {
1786+ if (old -> state >= SCTP_STATE_ESTABLISHED )
1787+ err = - EISCONN ;
1788+ else
1789+ err = - EALREADY ;
1790+ goto free ;
1791+ }
1792+
1793+ if (sctp_endpoint_is_peeled_off (ep , daddr )) {
1794+ err = - EADDRNOTAVAIL ;
1795+ goto free ;
1796+ }
1797+
1798+ transport = sctp_assoc_add_peer (asoc , daddr , GFP_KERNEL ,
1799+ SCTP_UNKNOWN );
1800+ if (!transport ) {
1801+ err = - ENOMEM ;
1802+ goto free ;
1803+ }
1804+ }
1805+
17381806 return 0 ;
17391807
17401808free :
@@ -1752,6 +1820,10 @@ static int sctp_sendmsg_check_sflags(struct sctp_association *asoc,
17521820 if (sctp_state (asoc , CLOSED ) && sctp_style (sk , TCP ))
17531821 return - EPIPE ;
17541822
1823+ if ((sflags & SCTP_SENDALL ) && sctp_style (sk , UDP ) &&
1824+ !sctp_state (asoc , ESTABLISHED ))
1825+ return 0 ;
1826+
17551827 if (sflags & SCTP_EOF ) {
17561828 pr_debug ("%s: shutting down association:%p\n" , __func__ , asoc );
17571829 sctp_primitive_SHUTDOWN (net , asoc , NULL );
@@ -1901,9 +1973,12 @@ static void sctp_sendmsg_update_sinfo(struct sctp_association *asoc,
19011973 sinfo -> sinfo_ppid = asoc -> default_ppid ;
19021974 sinfo -> sinfo_context = asoc -> default_context ;
19031975 sinfo -> sinfo_assoc_id = sctp_assoc2id (asoc );
1976+
1977+ if (!cmsgs -> prinfo )
1978+ sinfo -> sinfo_flags = asoc -> default_flags ;
19041979 }
19051980
1906- if (!cmsgs -> srinfo )
1981+ if (!cmsgs -> srinfo && ! cmsgs -> prinfo )
19071982 sinfo -> sinfo_timetolive = asoc -> default_timetolive ;
19081983}
19091984
@@ -1936,6 +2011,29 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
19362011
19372012 lock_sock (sk );
19382013
2014+ /* SCTP_SENDALL process */
2015+ if ((sflags & SCTP_SENDALL ) && sctp_style (sk , UDP )) {
2016+ list_for_each_entry (asoc , & ep -> asocs , asocs ) {
2017+ err = sctp_sendmsg_check_sflags (asoc , sflags , msg ,
2018+ msg_len );
2019+ if (err == 0 )
2020+ continue ;
2021+ if (err < 0 )
2022+ goto out_unlock ;
2023+
2024+ sctp_sendmsg_update_sinfo (asoc , sinfo , & cmsgs );
2025+
2026+ err = sctp_sendmsg_to_asoc (asoc , msg , msg_len ,
2027+ NULL , sinfo );
2028+ if (err < 0 )
2029+ goto out_unlock ;
2030+
2031+ iov_iter_revert (& msg -> msg_iter , err );
2032+ }
2033+
2034+ goto out_unlock ;
2035+ }
2036+
19392037 /* Get and check or create asoc */
19402038 if (daddr ) {
19412039 asoc = sctp_endpoint_lookup_assoc (ep , daddr , & transport );
@@ -7721,8 +7819,8 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
77217819
77227820 if (cmsgs -> srinfo -> sinfo_flags &
77237821 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
7724- SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
7725- SCTP_ABORT | SCTP_EOF ))
7822+ SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
7823+ SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF ))
77267824 return - EINVAL ;
77277825 break ;
77287826
@@ -7745,10 +7843,45 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
77457843
77467844 if (cmsgs -> sinfo -> snd_flags &
77477845 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
7748- SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
7749- SCTP_ABORT | SCTP_EOF ))
7846+ SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
7847+ SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF ))
77507848 return - EINVAL ;
77517849 break ;
7850+ case SCTP_PRINFO :
7851+ /* SCTP Socket API Extension
7852+ * 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO)
7853+ *
7854+ * This cmsghdr structure specifies SCTP options for sendmsg().
7855+ *
7856+ * cmsg_level cmsg_type cmsg_data[]
7857+ * ------------ ------------ ---------------------
7858+ * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo
7859+ */
7860+ if (cmsg -> cmsg_len != CMSG_LEN (sizeof (struct sctp_prinfo )))
7861+ return - EINVAL ;
7862+
7863+ cmsgs -> prinfo = CMSG_DATA (cmsg );
7864+ if (cmsgs -> prinfo -> pr_policy & ~SCTP_PR_SCTP_MASK )
7865+ return - EINVAL ;
7866+
7867+ if (cmsgs -> prinfo -> pr_policy == SCTP_PR_SCTP_NONE )
7868+ cmsgs -> prinfo -> pr_value = 0 ;
7869+ break ;
7870+ case SCTP_DSTADDRV4 :
7871+ case SCTP_DSTADDRV6 :
7872+ /* SCTP Socket API Extension
7873+ * 5.3.9/10 SCTP Destination IPv4/6 Address Structure (SCTP_DSTADDRV4/6)
7874+ *
7875+ * This cmsghdr structure specifies SCTP options for sendmsg().
7876+ *
7877+ * cmsg_level cmsg_type cmsg_data[]
7878+ * ------------ ------------ ---------------------
7879+ * IPPROTO_SCTP SCTP_DSTADDRV4 struct in_addr
7880+ * ------------ ------------ ---------------------
7881+ * IPPROTO_SCTP SCTP_DSTADDRV6 struct in6_addr
7882+ */
7883+ cmsgs -> addrs_msg = my_msg ;
7884+ break ;
77527885 default :
77537886 return - EINVAL ;
77547887 }
0 commit comments