diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ee88f2ea5101..01c6364245b7 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -107,8 +107,6 @@ static void sctp_sock_migrate(struct sock *, struct sock *, | |||
107 | struct sctp_association *, sctp_socket_type_t); | 107 | struct sctp_association *, sctp_socket_type_t); |
108 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; | 108 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; |
109 | 109 | ||
110 | extern struct kmem_cache *sctp_bucket_cachep; | ||
111 | |||
112 | /* Get the sndbuf space available at the time on the association. */ | 110 | /* Get the sndbuf space available at the time on the association. */ |
113 | static inline int sctp_wspace(struct sctp_association *asoc) | 111 | static inline int sctp_wspace(struct sctp_association *asoc) |
114 | { | 112 | { |
@@ -433,7 +431,7 @@ out: | |||
433 | * | 431 | * |
434 | * Only sctp_setsockopt_bindx() is supposed to call this function. | 432 | * Only sctp_setsockopt_bindx() is supposed to call this function. |
435 | */ | 433 | */ |
436 | int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt) | 434 | static int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt) |
437 | { | 435 | { |
438 | int cnt; | 436 | int cnt; |
439 | int retval = 0; | 437 | int retval = 0; |
@@ -602,7 +600,7 @@ out: | |||
602 | * | 600 | * |
603 | * Only sctp_setsockopt_bindx() is supposed to call this function. | 601 | * Only sctp_setsockopt_bindx() is supposed to call this function. |
604 | */ | 602 | */ |
605 | int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) | 603 | static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) |
606 | { | 604 | { |
607 | struct sctp_sock *sp = sctp_sk(sk); | 605 | struct sctp_sock *sp = sctp_sk(sk); |
608 | struct sctp_endpoint *ep = sp->ep; | 606 | struct sctp_endpoint *ep = sp->ep; |
@@ -977,7 +975,7 @@ static int __sctp_connect(struct sock* sk, | |||
977 | int err = 0; | 975 | int err = 0; |
978 | int addrcnt = 0; | 976 | int addrcnt = 0; |
979 | int walk_size = 0; | 977 | int walk_size = 0; |
980 | union sctp_addr *sa_addr; | 978 | union sctp_addr *sa_addr = NULL; |
981 | void *addr_buf; | 979 | void *addr_buf; |
982 | unsigned short port; | 980 | unsigned short port; |
983 | unsigned int f_flags = 0; | 981 | unsigned int f_flags = 0; |
@@ -1011,7 +1009,10 @@ static int __sctp_connect(struct sock* sk, | |||
1011 | goto out_free; | 1009 | goto out_free; |
1012 | } | 1010 | } |
1013 | 1011 | ||
1014 | err = sctp_verify_addr(sk, sa_addr, af->sockaddr_len); | 1012 | /* Save current address so we can work with it */ |
1013 | memcpy(&to, sa_addr, af->sockaddr_len); | ||
1014 | |||
1015 | err = sctp_verify_addr(sk, &to, af->sockaddr_len); | ||
1015 | if (err) | 1016 | if (err) |
1016 | goto out_free; | 1017 | goto out_free; |
1017 | 1018 | ||
@@ -1021,12 +1022,11 @@ static int __sctp_connect(struct sock* sk, | |||
1021 | if (asoc && asoc->peer.port && asoc->peer.port != port) | 1022 | if (asoc && asoc->peer.port && asoc->peer.port != port) |
1022 | goto out_free; | 1023 | goto out_free; |
1023 | 1024 | ||
1024 | memcpy(&to, sa_addr, af->sockaddr_len); | ||
1025 | 1025 | ||
1026 | /* Check if there already is a matching association on the | 1026 | /* Check if there already is a matching association on the |
1027 | * endpoint (other than the one created here). | 1027 | * endpoint (other than the one created here). |
1028 | */ | 1028 | */ |
1029 | asoc2 = sctp_endpoint_lookup_assoc(ep, sa_addr, &transport); | 1029 | asoc2 = sctp_endpoint_lookup_assoc(ep, &to, &transport); |
1030 | if (asoc2 && asoc2 != asoc) { | 1030 | if (asoc2 && asoc2 != asoc) { |
1031 | if (asoc2->state >= SCTP_STATE_ESTABLISHED) | 1031 | if (asoc2->state >= SCTP_STATE_ESTABLISHED) |
1032 | err = -EISCONN; | 1032 | err = -EISCONN; |
@@ -1039,7 +1039,7 @@ static int __sctp_connect(struct sock* sk, | |||
1039 | * make sure that there is no peeled-off association matching | 1039 | * make sure that there is no peeled-off association matching |
1040 | * the peer address even on another socket. | 1040 | * the peer address even on another socket. |
1041 | */ | 1041 | */ |
1042 | if (sctp_endpoint_is_peeled_off(ep, sa_addr)) { | 1042 | if (sctp_endpoint_is_peeled_off(ep, &to)) { |
1043 | err = -EADDRNOTAVAIL; | 1043 | err = -EADDRNOTAVAIL; |
1044 | goto out_free; | 1044 | goto out_free; |
1045 | } | 1045 | } |
@@ -1070,7 +1070,7 @@ static int __sctp_connect(struct sock* sk, | |||
1070 | } | 1070 | } |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | scope = sctp_scope(sa_addr); | 1073 | scope = sctp_scope(&to); |
1074 | asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); | 1074 | asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); |
1075 | if (!asoc) { | 1075 | if (!asoc) { |
1076 | err = -ENOMEM; | 1076 | err = -ENOMEM; |
@@ -1079,7 +1079,7 @@ static int __sctp_connect(struct sock* sk, | |||
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | /* Prime the peer's transport structures. */ | 1081 | /* Prime the peer's transport structures. */ |
1082 | transport = sctp_assoc_add_peer(asoc, sa_addr, GFP_KERNEL, | 1082 | transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL, |
1083 | SCTP_UNKNOWN); | 1083 | SCTP_UNKNOWN); |
1084 | if (!transport) { | 1084 | if (!transport) { |
1085 | err = -ENOMEM; | 1085 | err = -ENOMEM; |
@@ -1103,8 +1103,8 @@ static int __sctp_connect(struct sock* sk, | |||
1103 | 1103 | ||
1104 | /* Initialize sk's dport and daddr for getpeername() */ | 1104 | /* Initialize sk's dport and daddr for getpeername() */ |
1105 | inet_sk(sk)->dport = htons(asoc->peer.port); | 1105 | inet_sk(sk)->dport = htons(asoc->peer.port); |
1106 | af = sctp_get_af_specific(to.sa.sa_family); | 1106 | af = sctp_get_af_specific(sa_addr->sa.sa_family); |
1107 | af->to_sk_daddr(&to, sk); | 1107 | af->to_sk_daddr(sa_addr, sk); |
1108 | sk->sk_err = 0; | 1108 | sk->sk_err = 0; |
1109 | 1109 | ||
1110 | /* in-kernel sockets don't generally have a file allocated to them | 1110 | /* in-kernel sockets don't generally have a file allocated to them |
@@ -1531,7 +1531,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1531 | goto out_unlock; | 1531 | goto out_unlock; |
1532 | } | 1532 | } |
1533 | if (sinfo_flags & SCTP_ABORT) { | 1533 | if (sinfo_flags & SCTP_ABORT) { |
1534 | struct sctp_chunk *chunk; | ||
1535 | 1534 | ||
1536 | chunk = sctp_make_abort_user(asoc, msg, msg_len); | 1535 | chunk = sctp_make_abort_user(asoc, msg, msg_len); |
1537 | if (!chunk) { | 1536 | if (!chunk) { |
@@ -4353,7 +4352,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4353 | space_left, &bytes_copied); | 4352 | space_left, &bytes_copied); |
4354 | if (cnt < 0) { | 4353 | if (cnt < 0) { |
4355 | err = cnt; | 4354 | err = cnt; |
4356 | goto error; | 4355 | goto error_lock; |
4357 | } | 4356 | } |
4358 | goto copy_getaddrs; | 4357 | goto copy_getaddrs; |
4359 | } | 4358 | } |
@@ -4367,7 +4366,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4367 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4366 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
4368 | if (space_left < addrlen) { | 4367 | if (space_left < addrlen) { |
4369 | err = -ENOMEM; /*fixme: right error?*/ | 4368 | err = -ENOMEM; /*fixme: right error?*/ |
4370 | goto error; | 4369 | goto error_lock; |
4371 | } | 4370 | } |
4372 | memcpy(buf, &temp, addrlen); | 4371 | memcpy(buf, &temp, addrlen); |
4373 | buf += addrlen; | 4372 | buf += addrlen; |
@@ -4381,15 +4380,21 @@ copy_getaddrs: | |||
4381 | 4380 | ||
4382 | if (copy_to_user(to, addrs, bytes_copied)) { | 4381 | if (copy_to_user(to, addrs, bytes_copied)) { |
4383 | err = -EFAULT; | 4382 | err = -EFAULT; |
4384 | goto error; | 4383 | goto out; |
4385 | } | 4384 | } |
4386 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) { | 4385 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) { |
4387 | err = -EFAULT; | 4386 | err = -EFAULT; |
4388 | goto error; | 4387 | goto out; |
4389 | } | 4388 | } |
4390 | if (put_user(bytes_copied, optlen)) | 4389 | if (put_user(bytes_copied, optlen)) |
4391 | err = -EFAULT; | 4390 | err = -EFAULT; |
4392 | error: | 4391 | |
4392 | goto out; | ||
4393 | |||
4394 | error_lock: | ||
4395 | sctp_read_unlock(addr_lock); | ||
4396 | |||
4397 | out: | ||
4393 | kfree(addrs); | 4398 | kfree(addrs); |
4394 | return err; | 4399 | return err; |
4395 | } | 4400 | } |
@@ -5964,7 +5969,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo) | |||
5964 | return err; | 5969 | return err; |
5965 | } | 5970 | } |
5966 | 5971 | ||
5967 | void sctp_wait_for_close(struct sock *sk, long timeout) | 5972 | static void sctp_wait_for_close(struct sock *sk, long timeout) |
5968 | { | 5973 | { |
5969 | DEFINE_WAIT(wait); | 5974 | DEFINE_WAIT(wait); |
5970 | 5975 | ||