diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index e13519e9df80..fee06b99a4da 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2115,6 +2115,12 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
2115 | sctp_skb_pull(skb, copied); | 2115 | sctp_skb_pull(skb, copied); |
2116 | skb_queue_head(&sk->sk_receive_queue, skb); | 2116 | skb_queue_head(&sk->sk_receive_queue, skb); |
2117 | 2117 | ||
2118 | /* When only partial message is copied to the user, increase | ||
2119 | * rwnd by that amount. If all the data in the skb is read, | ||
2120 | * rwnd is updated when the event is freed. | ||
2121 | */ | ||
2122 | if (!sctp_ulpevent_is_notification(event)) | ||
2123 | sctp_assoc_rwnd_increase(event->asoc, copied); | ||
2118 | goto out; | 2124 | goto out; |
2119 | } else if ((event->msg_flags & MSG_NOTIFICATION) || | 2125 | } else if ((event->msg_flags & MSG_NOTIFICATION) || |
2120 | (event->msg_flags & MSG_EOR)) | 2126 | (event->msg_flags & MSG_EOR)) |
@@ -3315,10 +3321,10 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3315 | char __user *optval, | 3321 | char __user *optval, |
3316 | unsigned int optlen) | 3322 | unsigned int optlen) |
3317 | { | 3323 | { |
3318 | struct net *net = sock_net(sk); | 3324 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3319 | struct sctp_authchunk val; | 3325 | struct sctp_authchunk val; |
3320 | 3326 | ||
3321 | if (!net->sctp.auth_enable) | 3327 | if (!ep->auth_enable) |
3322 | return -EACCES; | 3328 | return -EACCES; |
3323 | 3329 | ||
3324 | if (optlen != sizeof(struct sctp_authchunk)) | 3330 | if (optlen != sizeof(struct sctp_authchunk)) |
@@ -3335,7 +3341,7 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3335 | } | 3341 | } |
3336 | 3342 | ||
3337 | /* add this chunk id to the endpoint */ | 3343 | /* add this chunk id to the endpoint */ |
3338 | return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk); | 3344 | return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk); |
3339 | } | 3345 | } |
3340 | 3346 | ||
3341 | /* | 3347 | /* |
@@ -3348,12 +3354,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3348 | char __user *optval, | 3354 | char __user *optval, |
3349 | unsigned int optlen) | 3355 | unsigned int optlen) |
3350 | { | 3356 | { |
3351 | struct net *net = sock_net(sk); | 3357 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3352 | struct sctp_hmacalgo *hmacs; | 3358 | struct sctp_hmacalgo *hmacs; |
3353 | u32 idents; | 3359 | u32 idents; |
3354 | int err; | 3360 | int err; |
3355 | 3361 | ||
3356 | if (!net->sctp.auth_enable) | 3362 | if (!ep->auth_enable) |
3357 | return -EACCES; | 3363 | return -EACCES; |
3358 | 3364 | ||
3359 | if (optlen < sizeof(struct sctp_hmacalgo)) | 3365 | if (optlen < sizeof(struct sctp_hmacalgo)) |
@@ -3370,7 +3376,7 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3370 | goto out; | 3376 | goto out; |
3371 | } | 3377 | } |
3372 | 3378 | ||
3373 | err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs); | 3379 | err = sctp_auth_ep_set_hmacs(ep, hmacs); |
3374 | out: | 3380 | out: |
3375 | kfree(hmacs); | 3381 | kfree(hmacs); |
3376 | return err; | 3382 | return err; |
@@ -3386,12 +3392,12 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3386 | char __user *optval, | 3392 | char __user *optval, |
3387 | unsigned int optlen) | 3393 | unsigned int optlen) |
3388 | { | 3394 | { |
3389 | struct net *net = sock_net(sk); | 3395 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3390 | struct sctp_authkey *authkey; | 3396 | struct sctp_authkey *authkey; |
3391 | struct sctp_association *asoc; | 3397 | struct sctp_association *asoc; |
3392 | int ret; | 3398 | int ret; |
3393 | 3399 | ||
3394 | if (!net->sctp.auth_enable) | 3400 | if (!ep->auth_enable) |
3395 | return -EACCES; | 3401 | return -EACCES; |
3396 | 3402 | ||
3397 | if (optlen <= sizeof(struct sctp_authkey)) | 3403 | if (optlen <= sizeof(struct sctp_authkey)) |
@@ -3412,7 +3418,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3412 | goto out; | 3418 | goto out; |
3413 | } | 3419 | } |
3414 | 3420 | ||
3415 | ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); | 3421 | ret = sctp_auth_set_key(ep, asoc, authkey); |
3416 | out: | 3422 | out: |
3417 | kzfree(authkey); | 3423 | kzfree(authkey); |
3418 | return ret; | 3424 | return ret; |
@@ -3428,11 +3434,11 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3428 | char __user *optval, | 3434 | char __user *optval, |
3429 | unsigned int optlen) | 3435 | unsigned int optlen) |
3430 | { | 3436 | { |
3431 | struct net *net = sock_net(sk); | 3437 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3432 | struct sctp_authkeyid val; | 3438 | struct sctp_authkeyid val; |
3433 | struct sctp_association *asoc; | 3439 | struct sctp_association *asoc; |
3434 | 3440 | ||
3435 | if (!net->sctp.auth_enable) | 3441 | if (!ep->auth_enable) |
3436 | return -EACCES; | 3442 | return -EACCES; |
3437 | 3443 | ||
3438 | if (optlen != sizeof(struct sctp_authkeyid)) | 3444 | if (optlen != sizeof(struct sctp_authkeyid)) |
@@ -3444,8 +3450,7 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3444 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) | 3450 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) |
3445 | return -EINVAL; | 3451 | return -EINVAL; |
3446 | 3452 | ||
3447 | return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc, | 3453 | return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber); |
3448 | val.scact_keynumber); | ||
3449 | } | 3454 | } |
3450 | 3455 | ||
3451 | /* | 3456 | /* |
@@ -3457,11 +3462,11 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3457 | char __user *optval, | 3462 | char __user *optval, |
3458 | unsigned int optlen) | 3463 | unsigned int optlen) |
3459 | { | 3464 | { |
3460 | struct net *net = sock_net(sk); | 3465 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3461 | struct sctp_authkeyid val; | 3466 | struct sctp_authkeyid val; |
3462 | struct sctp_association *asoc; | 3467 | struct sctp_association *asoc; |
3463 | 3468 | ||
3464 | if (!net->sctp.auth_enable) | 3469 | if (!ep->auth_enable) |
3465 | return -EACCES; | 3470 | return -EACCES; |
3466 | 3471 | ||
3467 | if (optlen != sizeof(struct sctp_authkeyid)) | 3472 | if (optlen != sizeof(struct sctp_authkeyid)) |
@@ -3473,8 +3478,7 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3473 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) | 3478 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) |
3474 | return -EINVAL; | 3479 | return -EINVAL; |
3475 | 3480 | ||
3476 | return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc, | 3481 | return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber); |
3477 | val.scact_keynumber); | ||
3478 | 3482 | ||
3479 | } | 3483 | } |
3480 | 3484 | ||
@@ -5381,16 +5385,16 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5381 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | 5385 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, |
5382 | char __user *optval, int __user *optlen) | 5386 | char __user *optval, int __user *optlen) |
5383 | { | 5387 | { |
5384 | struct net *net = sock_net(sk); | 5388 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5385 | struct sctp_hmacalgo __user *p = (void __user *)optval; | 5389 | struct sctp_hmacalgo __user *p = (void __user *)optval; |
5386 | struct sctp_hmac_algo_param *hmacs; | 5390 | struct sctp_hmac_algo_param *hmacs; |
5387 | __u16 data_len = 0; | 5391 | __u16 data_len = 0; |
5388 | u32 num_idents; | 5392 | u32 num_idents; |
5389 | 5393 | ||
5390 | if (!net->sctp.auth_enable) | 5394 | if (!ep->auth_enable) |
5391 | return -EACCES; | 5395 | return -EACCES; |
5392 | 5396 | ||
5393 | hmacs = sctp_sk(sk)->ep->auth_hmacs_list; | 5397 | hmacs = ep->auth_hmacs_list; |
5394 | data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); | 5398 | data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5395 | 5399 | ||
5396 | if (len < sizeof(struct sctp_hmacalgo) + data_len) | 5400 | if (len < sizeof(struct sctp_hmacalgo) + data_len) |
@@ -5411,11 +5415,11 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | |||
5411 | static int sctp_getsockopt_active_key(struct sock *sk, int len, | 5415 | static int sctp_getsockopt_active_key(struct sock *sk, int len, |
5412 | char __user *optval, int __user *optlen) | 5416 | char __user *optval, int __user *optlen) |
5413 | { | 5417 | { |
5414 | struct net *net = sock_net(sk); | 5418 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5415 | struct sctp_authkeyid val; | 5419 | struct sctp_authkeyid val; |
5416 | struct sctp_association *asoc; | 5420 | struct sctp_association *asoc; |
5417 | 5421 | ||
5418 | if (!net->sctp.auth_enable) | 5422 | if (!ep->auth_enable) |
5419 | return -EACCES; | 5423 | return -EACCES; |
5420 | 5424 | ||
5421 | if (len < sizeof(struct sctp_authkeyid)) | 5425 | if (len < sizeof(struct sctp_authkeyid)) |
@@ -5430,7 +5434,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5430 | if (asoc) | 5434 | if (asoc) |
5431 | val.scact_keynumber = asoc->active_key_id; | 5435 | val.scact_keynumber = asoc->active_key_id; |
5432 | else | 5436 | else |
5433 | val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; | 5437 | val.scact_keynumber = ep->active_key_id; |
5434 | 5438 | ||
5435 | len = sizeof(struct sctp_authkeyid); | 5439 | len = sizeof(struct sctp_authkeyid); |
5436 | if (put_user(len, optlen)) | 5440 | if (put_user(len, optlen)) |
@@ -5444,7 +5448,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5444 | static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | 5448 | static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, |
5445 | char __user *optval, int __user *optlen) | 5449 | char __user *optval, int __user *optlen) |
5446 | { | 5450 | { |
5447 | struct net *net = sock_net(sk); | 5451 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5448 | struct sctp_authchunks __user *p = (void __user *)optval; | 5452 | struct sctp_authchunks __user *p = (void __user *)optval; |
5449 | struct sctp_authchunks val; | 5453 | struct sctp_authchunks val; |
5450 | struct sctp_association *asoc; | 5454 | struct sctp_association *asoc; |
@@ -5452,7 +5456,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5452 | u32 num_chunks = 0; | 5456 | u32 num_chunks = 0; |
5453 | char __user *to; | 5457 | char __user *to; |
5454 | 5458 | ||
5455 | if (!net->sctp.auth_enable) | 5459 | if (!ep->auth_enable) |
5456 | return -EACCES; | 5460 | return -EACCES; |
5457 | 5461 | ||
5458 | if (len < sizeof(struct sctp_authchunks)) | 5462 | if (len < sizeof(struct sctp_authchunks)) |
@@ -5489,7 +5493,7 @@ num: | |||
5489 | static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | 5493 | static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, |
5490 | char __user *optval, int __user *optlen) | 5494 | char __user *optval, int __user *optlen) |
5491 | { | 5495 | { |
5492 | struct net *net = sock_net(sk); | 5496 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5493 | struct sctp_authchunks __user *p = (void __user *)optval; | 5497 | struct sctp_authchunks __user *p = (void __user *)optval; |
5494 | struct sctp_authchunks val; | 5498 | struct sctp_authchunks val; |
5495 | struct sctp_association *asoc; | 5499 | struct sctp_association *asoc; |
@@ -5497,7 +5501,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5497 | u32 num_chunks = 0; | 5501 | u32 num_chunks = 0; |
5498 | char __user *to; | 5502 | char __user *to; |
5499 | 5503 | ||
5500 | if (!net->sctp.auth_enable) | 5504 | if (!ep->auth_enable) |
5501 | return -EACCES; | 5505 | return -EACCES; |
5502 | 5506 | ||
5503 | if (len < sizeof(struct sctp_authchunks)) | 5507 | if (len < sizeof(struct sctp_authchunks)) |
@@ -5514,7 +5518,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5514 | if (asoc) | 5518 | if (asoc) |
5515 | ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; | 5519 | ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; |
5516 | else | 5520 | else |
5517 | ch = sctp_sk(sk)->ep->auth_chunk_list; | 5521 | ch = ep->auth_chunk_list; |
5518 | 5522 | ||
5519 | if (!ch) | 5523 | if (!ch) |
5520 | goto num; | 5524 | goto num; |