sctp: factor out sctp_connect_add_peer
In this function factored out from sctp_sendmsg_new_asoc() and __sctp_connect(), it adds a peer with the other addr into the asoc after this asoc is created with the 1st addr. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									f26f995122
								
							
						
					
					
						commit
						a64e59c72c
					
				| @ -1111,6 +1111,33 @@ free: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int sctp_connect_add_peer(struct sctp_association *asoc, | ||||
| 				 union sctp_addr *daddr, int addr_len) | ||||
| { | ||||
| 	struct sctp_endpoint *ep = asoc->ep; | ||||
| 	struct sctp_association *old; | ||||
| 	struct sctp_transport *t; | ||||
| 	int err; | ||||
| 
 | ||||
| 	err = sctp_verify_addr(ep->base.sk, daddr, addr_len); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 
 | ||||
| 	old = sctp_endpoint_lookup_assoc(ep, daddr, &t); | ||||
| 	if (old && old != asoc) | ||||
| 		return old->state >= SCTP_STATE_ESTABLISHED ? -EISCONN | ||||
| 							    : -EALREADY; | ||||
| 
 | ||||
| 	if (sctp_endpoint_is_peeled_off(ep, daddr)) | ||||
| 		return -EADDRNOTAVAIL; | ||||
| 
 | ||||
| 	t = sctp_assoc_add_peer(asoc, daddr, GFP_KERNEL, SCTP_UNKNOWN); | ||||
| 	if (!t) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* __sctp_connect(struct sock* sk, struct sockaddr *kaddrs, int addrs_size)
 | ||||
|  * | ||||
|  * Common routine for handling connect() and sctp_connectx(). | ||||
| @ -1119,10 +1146,10 @@ free: | ||||
| static int __sctp_connect(struct sock *sk, struct sockaddr *kaddrs, | ||||
| 			  int addrs_size, int flags, sctp_assoc_t *assoc_id) | ||||
| { | ||||
| 	struct sctp_association *old, *asoc; | ||||
| 	struct sctp_sock *sp = sctp_sk(sk); | ||||
| 	struct sctp_endpoint *ep = sp->ep; | ||||
| 	struct sctp_transport *transport; | ||||
| 	struct sctp_association *asoc; | ||||
| 	void *addr_buf = kaddrs; | ||||
| 	union sctp_addr *daddr; | ||||
| 	struct sctp_af *af; | ||||
| @ -1167,29 +1194,10 @@ static int __sctp_connect(struct sock *sk, struct sockaddr *kaddrs, | ||||
| 		if (asoc->peer.port != ntohs(daddr->v4.sin_port)) | ||||
| 			goto out_free; | ||||
| 
 | ||||
| 		err = sctp_verify_addr(sk, daddr, af->sockaddr_len); | ||||
| 		err = sctp_connect_add_peer(asoc, daddr, af->sockaddr_len); | ||||
| 		if (err) | ||||
| 			goto out_free; | ||||
| 
 | ||||
| 		old = sctp_endpoint_lookup_assoc(ep, daddr, &transport); | ||||
| 		if (old && old != asoc) { | ||||
| 			err = old->state >= SCTP_STATE_ESTABLISHED ? -EISCONN | ||||
| 								   : -EALREADY; | ||||
| 			goto out_free; | ||||
| 		} | ||||
| 
 | ||||
| 		if (sctp_endpoint_is_peeled_off(ep, daddr)) { | ||||
| 			err = -EADDRNOTAVAIL; | ||||
| 			goto out_free; | ||||
| 		} | ||||
| 
 | ||||
| 		transport = sctp_assoc_add_peer(asoc, daddr, GFP_KERNEL, | ||||
| 						SCTP_UNKNOWN); | ||||
| 		if (!transport) { | ||||
| 			err = -ENOMEM; | ||||
| 			goto out_free; | ||||
| 		} | ||||
| 
 | ||||
| 		addr_buf  += af->sockaddr_len; | ||||
| 		walk_size += af->sockaddr_len; | ||||
| 	} | ||||
| @ -1683,8 +1691,6 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags, | ||||
| 
 | ||||
| 	/* sendv addr list parse */ | ||||
| 	for_each_cmsghdr(cmsg, cmsgs->addrs_msg) { | ||||
| 		struct sctp_transport *transport; | ||||
| 		struct sctp_association *old; | ||||
| 		union sctp_addr _daddr; | ||||
| 		int dlen; | ||||
| 
 | ||||
| @ -1718,30 +1724,10 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags, | ||||
| 			daddr->v6.sin6_port = htons(asoc->peer.port); | ||||
| 			memcpy(&daddr->v6.sin6_addr, CMSG_DATA(cmsg), dlen); | ||||
| 		} | ||||
| 		err = sctp_verify_addr(sk, daddr, sizeof(*daddr)); | ||||
| 
 | ||||
| 		err = sctp_connect_add_peer(asoc, daddr, sizeof(*daddr)); | ||||
| 		if (err) | ||||
| 			goto free; | ||||
| 
 | ||||
| 		old = sctp_endpoint_lookup_assoc(ep, daddr, &transport); | ||||
| 		if (old && old != asoc) { | ||||
| 			if (old->state >= SCTP_STATE_ESTABLISHED) | ||||
| 				err = -EISCONN; | ||||
| 			else | ||||
| 				err = -EALREADY; | ||||
| 			goto free; | ||||
| 		} | ||||
| 
 | ||||
| 		if (sctp_endpoint_is_peeled_off(ep, daddr)) { | ||||
| 			err = -EADDRNOTAVAIL; | ||||
| 			goto free; | ||||
| 		} | ||||
| 
 | ||||
| 		transport = sctp_assoc_add_peer(asoc, daddr, GFP_KERNEL, | ||||
| 						SCTP_UNKNOWN); | ||||
| 		if (!transport) { | ||||
| 			err = -ENOMEM; | ||||
| 			goto free; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user