diff options
author | wollman <wollman@FreeBSD.org> | 1998-08-23 03:07:17 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1998-08-23 03:07:17 +0000 |
commit | a76fb5eefabdc9418c911bf0b61768d533c15cbd (patch) | |
tree | 02b1e59b8833c25c113cc2a72ebb74ec057423bb /sys/netinet/tcp_usrreq.c | |
parent | 3846bf0ec8c81eca47577791dff72e8b96928749 (diff) | |
download | FreeBSD-src-a76fb5eefabdc9418c911bf0b61768d533c15cbd.zip FreeBSD-src-a76fb5eefabdc9418c911bf0b61768d533c15cbd.tar.gz |
Yow! Completely change the way socket options are handled, eliminating
another specialized mbuf type in the process. Also clean up some
of the cruft surrounding IPFW, multicast routing, RSVP, and other
ill-explored corners.
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 117 |
1 files changed, 60 insertions, 57 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index cc94bbb..ba0c012 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94 - * $Id: tcp_usrreq.c,v 1.36 1997/12/18 09:50:38 davidg Exp $ + * $Id: tcp_usrreq.c,v 1.37 1998/01/27 09:15:11 davidg Exp $ */ #include "opt_tcpdebug.h" @@ -560,104 +560,107 @@ tcp_connect(tp, nam, p) return 0; } +/* + * The new sockopt interface makes it possible for us to block in the + * copyin/out step (if we take a page fault). Taking a page fault at + * splnet() is probably a Bad Thing. (Since sockets and pcbs both now + * use TSM, there probably isn't any need for this function to run at + * splnet() any more. This needs more examination.) + */ int -tcp_ctloutput(op, so, level, optname, mp, p) - int op; +tcp_ctloutput(so, sopt) struct socket *so; - int level, optname; - struct mbuf **mp; - struct proc *p; + struct sockopt *sopt; { - int error = 0, s; - struct inpcb *inp; - register struct tcpcb *tp; - register struct mbuf *m; - register int i; + int error, opt, optval, s; + struct inpcb *inp; + struct tcpcb *tp; + struct mbuf *m; - s = splnet(); + error = 0; + s = splnet(); /* XXX */ inp = sotoinpcb(so); if (inp == NULL) { splx(s); - if (op == PRCO_SETOPT && *mp) - (void) m_free(*mp); return (ECONNRESET); } - if (level != IPPROTO_TCP) { - error = ip_ctloutput(op, so, level, optname, mp, p); + if (sopt->sopt_level != IPPROTO_TCP) { + error = ip_ctloutput(so, sopt); splx(s); return (error); } tp = intotcpcb(inp); - switch (op) { - - case PRCO_SETOPT: - m = *mp; - switch (optname) { - + switch (sopt->sopt_dir) { + case SOPT_SET: + switch (sopt->sopt_name) { case TCP_NODELAY: - if (m == NULL || m->m_len < sizeof (int)) - error = EINVAL; - else if (*mtod(m, int *)) - tp->t_flags |= TF_NODELAY; + case TCP_NOOPT: + case TCP_NOPUSH: + error = sooptcopyin(sopt, &optval, sizeof optval, + sizeof optval); + if (error) + break; + + switch (sopt->sopt_name) { + case TCP_NODELAY: + opt = TF_NODELAY; + break; + case TCP_NOOPT: + opt = TF_NOOPT; + break; + case TCP_NOPUSH: + opt = TF_NOPUSH; + break; + default: + opt = 0; /* dead code to fool gcc */ + break; + } + + if (optval) + tp->t_flags |= opt; else - tp->t_flags &= ~TF_NODELAY; + tp->t_flags &= ~opt; break; case TCP_MAXSEG: - if (m && (i = *mtod(m, int *)) > 0 && i <= tp->t_maxseg) - tp->t_maxseg = i; - else - error = EINVAL; - break; + error = sooptcopyin(sopt, &optval, sizeof optval, + sizeof optval); + if (error) + break; - case TCP_NOOPT: - if (m == NULL || m->m_len < sizeof (int)) - error = EINVAL; - else if (*mtod(m, int *)) - tp->t_flags |= TF_NOOPT; + if (optval > 0 && optval <= tp->t_maxseg) + tp->t_maxseg = optval; else - tp->t_flags &= ~TF_NOOPT; - break; - - case TCP_NOPUSH: - if (m == NULL || m->m_len < sizeof (int)) error = EINVAL; - else if (*mtod(m, int *)) - tp->t_flags |= TF_NOPUSH; - else - tp->t_flags &= ~TF_NOPUSH; break; default: error = ENOPROTOOPT; break; } - if (m) - (void) m_free(m); break; - case PRCO_GETOPT: - *mp = m = m_get(M_WAIT, MT_SOOPTS); - m->m_len = sizeof(int); - - switch (optname) { + case SOPT_GET: + switch (sopt->sopt_name) { case TCP_NODELAY: - *mtod(m, int *) = tp->t_flags & TF_NODELAY; + optval = tp->t_flags & TF_NODELAY; break; case TCP_MAXSEG: - *mtod(m, int *) = tp->t_maxseg; + optval = tp->t_maxseg; break; case TCP_NOOPT: - *mtod(m, int *) = tp->t_flags & TF_NOOPT; + optval = tp->t_flags & TF_NOOPT; break; case TCP_NOPUSH: - *mtod(m, int *) = tp->t_flags & TF_NOPUSH; + optval = tp->t_flags & TF_NOPUSH; break; default: error = ENOPROTOOPT; break; } + if (error == 0) + error = sooptcopyout(sopt, &optval, sizeof optval); break; } splx(s); |