Commit becef9b1 authored by Xin Long's avatar Xin Long Committed by David S. Miller
Browse files

sctp: factor out sctp_sendmsg_get_daddr from sctp_sendmsg



This patch is to move the codes for trying to get daddr from
msg->msg_name into sctp_sendmsg_get_daddr.

Note that after adding 'daddr', 'to' and 'msg_name' can be
deleted.

Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c2666de1
Loading
Loading
Loading
Loading
+34 −24
Original line number Original line Diff line number Diff line
@@ -1814,14 +1814,35 @@ err:
	return err;
	return err;
}
}


static union sctp_addr *sctp_sendmsg_get_daddr(struct sock *sk,
					       const struct msghdr *msg,
					       struct sctp_cmsgs *cmsgs)
{
	union sctp_addr *daddr = NULL;
	int err;

	if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
		int len = msg->msg_namelen;

		if (len > sizeof(*daddr))
			len = sizeof(*daddr);

		daddr = (union sctp_addr *)msg->msg_name;

		err = sctp_verify_addr(sk, daddr, len);
		if (err)
			return ERR_PTR(err);
	}

	return daddr;
}

static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
{
{
	struct sctp_sock *sp;
	struct sctp_sock *sp;
	struct sctp_endpoint *ep;
	struct sctp_endpoint *ep;
	struct sctp_association *new_asoc = NULL, *asoc = NULL;
	struct sctp_association *new_asoc = NULL, *asoc = NULL;
	struct sctp_transport *transport, *chunk_tp;
	struct sctp_transport *transport, *chunk_tp;
	union sctp_addr to;
	struct sockaddr *msg_name = NULL;
	struct sctp_sndrcvinfo default_sinfo;
	struct sctp_sndrcvinfo default_sinfo;
	struct sctp_sndrcvinfo *sinfo;
	struct sctp_sndrcvinfo *sinfo;
	struct sctp_initmsg *sinit;
	struct sctp_initmsg *sinit;
@@ -1829,6 +1850,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
	struct sctp_cmsgs cmsgs = { NULL };
	struct sctp_cmsgs cmsgs = { NULL };
	bool fill_sinfo_ttl = false;
	bool fill_sinfo_ttl = false;
	__u16 sinfo_flags = 0;
	__u16 sinfo_flags = 0;
	union sctp_addr *daddr;
	int err;
	int err;


	err = 0;
	err = 0;
@@ -1851,23 +1873,11 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
		goto out_nounlock;
		goto out_nounlock;
	}
	}


	/* Fetch the destination address for this packet.  This
	/* Get daddr from msg */
	 * address only selects the association--it is not necessarily
	daddr = sctp_sendmsg_get_daddr(sk, msg, &cmsgs);
	 * the address we will send to.
	if (IS_ERR(daddr)) {
	 * For a peeled-off socket, msg_name is ignored.
		err = PTR_ERR(daddr);
	 */
		goto out_nounlock;
	if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
		int msg_namelen = msg->msg_namelen;

		err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name,
				       msg_namelen);
		if (err)
			return err;

		if (msg_namelen > sizeof(to))
			msg_namelen = sizeof(to);
		memcpy(&to, msg->msg_name, msg_namelen);
		msg_name = msg->msg_name;
	}
	}


	sinit = cmsgs.init;
	sinit = cmsgs.init;
@@ -1925,9 +1935,9 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
	lock_sock(sk);
	lock_sock(sk);


	/* If a msg_name has been specified, assume this is to be used.  */
	/* If a msg_name has been specified, assume this is to be used.  */
	if (msg_name) {
	if (daddr) {
		/* Look for a matching association on the endpoint. */
		/* Look for a matching association on the endpoint. */
		asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport);
		asoc = sctp_endpoint_lookup_assoc(ep, daddr, &transport);
	} else {
	} else {
		asoc = sctp_id2assoc(sk, associd);
		asoc = sctp_id2assoc(sk, associd);
		if (!asoc) {
		if (!asoc) {
@@ -1945,7 +1955,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)


	/* Do we need to create the association?  */
	/* Do we need to create the association?  */
	if (!asoc) {
	if (!asoc) {
		err = sctp_sendmsg_new_asoc(sk, sinfo_flags, &cmsgs, &to,
		err = sctp_sendmsg_new_asoc(sk, sinfo_flags, &cmsgs, daddr,
					    &transport);
					    &transport);
		if (err)
		if (err)
			goto out_unlock;
			goto out_unlock;
@@ -1989,9 +1999,9 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
	 * to override the primary destination address in the TCP model, or
	 * to override the primary destination address in the TCP model, or
	 * when SCTP_ADDR_OVER flag is set in the UDP model.
	 * when SCTP_ADDR_OVER flag is set in the UDP model.
	 */
	 */
	if ((sctp_style(sk, TCP) && msg_name) ||
	if ((sctp_style(sk, TCP) && daddr) ||
	    (sinfo_flags & SCTP_ADDR_OVER)) {
	    (sinfo_flags & SCTP_ADDR_OVER)) {
		chunk_tp = sctp_assoc_lookup_paddr(asoc, &to);
		chunk_tp = sctp_assoc_lookup_paddr(asoc, daddr);
		if (!chunk_tp) {
		if (!chunk_tp) {
			err = -EINVAL;
			err = -EINVAL;
			goto out_free;
			goto out_free;