svn commit: r294536 - head/sys/netinet
Gleb Smirnoff
glebius at FreeBSD.org
Thu Jan 21 22:53:13 UTC 2016
Author: glebius
Date: Thu Jan 21 22:53:12 2016
New Revision: 294536
URL: https://svnweb.freebsd.org/changeset/base/294536
Log:
Refactor TCP_CONGESTION setsockopt handling:
- Use M_TEMP instead of stack variable.
- Unroll error handling, removing several levels of indentation.
Modified:
head/sys/netinet/tcp_usrreq.c
Modified: head/sys/netinet/tcp_usrreq.c
==============================================================================
--- head/sys/netinet/tcp_usrreq.c Thu Jan 21 22:34:51 2016 (r294535)
+++ head/sys/netinet/tcp_usrreq.c Thu Jan 21 22:53:12 2016 (r294536)
@@ -1479,7 +1479,7 @@ tcp_default_ctloutput(struct socket *so,
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 @@ unlock_and_done:
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 @@ unlock_and_done:
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:
More information about the svn-src-all
mailing list