Date: Thu, 21 Jan 2016 22:53:12 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r294536 - head/sys/netinet Message-ID: <201601212253.u0LMrC7B016136@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601212253.u0LMrC7B016136>