mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-25 11:37:56 +00:00
Refactor TCP_CONGESTION setsockopt handling:
- Use M_TEMP instead of stack variable. - Unroll error handling, removing several levels of indentation.
This commit is contained in:
parent
2de3e790f5
commit
73e263b182
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=294536
@ -1479,7 +1479,7 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
|
||||
u_int ui;
|
||||
struct tcp_info ti;
|
||||
struct cc_algo *algo;
|
||||
char buf[TCP_CA_NAME_MAX];
|
||||
char *buf;
|
||||
|
||||
switch (sopt->sopt_dir) {
|
||||
case SOPT_SET:
|
||||
@ -1574,50 +1574,47 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
|
||||
|
||||
case TCP_CONGESTION:
|
||||
INP_WUNLOCK(inp);
|
||||
bzero(buf, sizeof(buf));
|
||||
error = sooptcopyin(sopt, &buf, sizeof(buf), 1);
|
||||
if (error)
|
||||
buf = malloc(TCP_CA_NAME_MAX, M_TEMP, M_WAITOK|M_ZERO);
|
||||
error = sooptcopyin(sopt, buf, TCP_CA_NAME_MAX, 1);
|
||||
if (error) {
|
||||
free(buf, M_TEMP);
|
||||
break;
|
||||
}
|
||||
CC_LIST_RLOCK();
|
||||
STAILQ_FOREACH(algo, &cc_list, entries)
|
||||
if (strncmp(buf, algo->name,
|
||||
TCP_CA_NAME_MAX) == 0)
|
||||
break;
|
||||
CC_LIST_RUNLOCK();
|
||||
free(buf, M_TEMP);
|
||||
if (algo == NULL) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
INP_WLOCK_RECHECK(inp);
|
||||
/*
|
||||
* Return EINVAL if we can't find the requested cc algo.
|
||||
* We hold a write lock over the tcb so it's safe to
|
||||
* do these things without ordering concerns.
|
||||
*/
|
||||
error = EINVAL;
|
||||
CC_LIST_RLOCK();
|
||||
STAILQ_FOREACH(algo, &cc_list, entries) {
|
||||
if (strncmp(buf, algo->name, TCP_CA_NAME_MAX)
|
||||
== 0) {
|
||||
/* We've found the requested algo. */
|
||||
error = 0;
|
||||
/*
|
||||
* We hold a write lock over the tcb
|
||||
* so it's safe to do these things
|
||||
* without ordering concerns.
|
||||
*/
|
||||
if (CC_ALGO(tp)->cb_destroy != NULL)
|
||||
CC_ALGO(tp)->cb_destroy(tp->ccv);
|
||||
CC_ALGO(tp) = algo;
|
||||
/*
|
||||
* If something goes pear shaped
|
||||
* initialising the new algo,
|
||||
* fall back to newreno (which
|
||||
* does not require initialisation).
|
||||
*/
|
||||
if (algo->cb_init != NULL)
|
||||
if (algo->cb_init(tp->ccv) > 0) {
|
||||
CC_ALGO(tp) = &newreno_cc_algo;
|
||||
/*
|
||||
* The only reason init
|
||||
* should fail is
|
||||
* because of malloc.
|
||||
*/
|
||||
error = ENOMEM;
|
||||
}
|
||||
break; /* Break the STAILQ_FOREACH. */
|
||||
}
|
||||
if (CC_ALGO(tp)->cb_destroy != NULL)
|
||||
CC_ALGO(tp)->cb_destroy(tp->ccv);
|
||||
CC_ALGO(tp) = algo;
|
||||
/*
|
||||
* If something goes pear shaped initialising the new
|
||||
* algo, fall back to newreno (which does not
|
||||
* require initialisation).
|
||||
*/
|
||||
if (algo->cb_init != NULL &&
|
||||
algo->cb_init(tp->ccv) != 0) {
|
||||
CC_ALGO(tp) = &newreno_cc_algo;
|
||||
/*
|
||||
* The only reason init should fail is
|
||||
* because of malloc.
|
||||
*/
|
||||
error = ENOMEM;
|
||||
}
|
||||
CC_LIST_RUNLOCK();
|
||||
goto unlock_and_done;
|
||||
INP_WUNLOCK(inp);
|
||||
break;
|
||||
|
||||
case TCP_KEEPIDLE:
|
||||
case TCP_KEEPINTVL:
|
||||
@ -1763,10 +1760,9 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
|
||||
error = sooptcopyout(sopt, &ti, sizeof ti);
|
||||
break;
|
||||
case TCP_CONGESTION:
|
||||
bzero(buf, sizeof(buf));
|
||||
strlcpy(buf, CC_ALGO(tp)->name, TCP_CA_NAME_MAX);
|
||||
INP_WUNLOCK(inp);
|
||||
error = sooptcopyout(sopt, buf, TCP_CA_NAME_MAX);
|
||||
error = sooptcopyout(sopt, CC_ALGO(tp)->name,
|
||||
TCP_CA_NAME_MAX);
|
||||
break;
|
||||
case TCP_KEEPIDLE:
|
||||
case TCP_KEEPINTVL:
|
||||
|
Loading…
Reference in New Issue
Block a user