Modify the kernel to use the new pr_usrreqs interface rather than the old
pr_usrreq mechanism which was poorly designed and error-prone. This commit renames pr_usrreq to pr_ousrreq so that old code which depended on it would break in an obvious manner. This commit also implements the new interface for TCP, although the old function is left as an example (#ifdef'ed out). This commit ALSO fixes a longstanding bug in the TCP timer processing (introduced by davidg on 1995/04/12) which caused timer processing on a TCB to always stop after a single timer had expired (because it misinterpreted the return value from tcp_usrreq() to indicate that the TCB had been deleted). Finally, some code related to polling has been deleted from if.c because it is not relevant t -current and doesn't look at all like my current code.
This commit is contained in:
parent
ca3f215d18
commit
a1455b782f
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sys_socket.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: sys_socket.c,v 1.6 1995/12/14 08:31:49 phk Exp $
|
||||
* $Id: sys_socket.c,v 1.7 1996/03/11 15:12:43 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -138,8 +138,7 @@ soo_ioctl(fp, cmd, data, p)
|
||||
return (ifioctl(so, cmd, data, p));
|
||||
if (IOCGROUP(cmd) == 'r')
|
||||
return (rtioctl(cmd, data, p));
|
||||
return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
|
||||
(struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)0));
|
||||
return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, 0));
|
||||
}
|
||||
|
||||
int
|
||||
@ -192,9 +191,7 @@ soo_stat(so, ub)
|
||||
|
||||
bzero((caddr_t)ub, sizeof (*ub));
|
||||
ub->st_mode = S_IFSOCK;
|
||||
return ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
|
||||
(struct mbuf *)ub, (struct mbuf *)0,
|
||||
(struct mbuf *)0));
|
||||
return ((*so->so_proto->pr_usrreqs->pru_sense)(so, ub));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
|
||||
* $Id: uipc_domain.c,v 1.12 1995/12/16 02:13:50 bde Exp $
|
||||
* $Id: uipc_domain.c,v 1.13 1996/07/09 19:12:51 wollman Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -106,10 +106,8 @@ domaininit(dummy)
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++){
|
||||
#ifdef PRU_OLDSTYLE
|
||||
/* See comments in uipc_socket2.c. */
|
||||
if (pr->pr_usrreqs == 0)
|
||||
if (pr->pr_usrreqs == 0 && pr->pr_ousrreq)
|
||||
pr->pr_usrreqs = &pru_oldstyle;
|
||||
else if(pr->pr_usrreq == 0)
|
||||
pr->pr_usrreq = pr_newstyle_usrreq;
|
||||
#endif
|
||||
if (pr->pr_init)
|
||||
(*pr->pr_init)();
|
||||
|
@ -186,8 +186,7 @@ sonewconn1(head, connstatus)
|
||||
so->so_state |= SS_INCOMP;
|
||||
}
|
||||
head->so_qlen++;
|
||||
if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) {
|
||||
if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
|
||||
if (so->so_state & SS_COMP) {
|
||||
TAILQ_REMOVE(&head->so_comp, so, so_list);
|
||||
} else {
|
||||
@ -768,19 +767,19 @@ sbdroprecord(sb)
|
||||
static int
|
||||
old_abort(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_ABORT, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ABORT, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_accept(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_ACCEPT, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ACCEPT, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_attach(struct socket *so, int proto)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_ATTACH, nomb,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ATTACH, nomb,
|
||||
(struct mbuf *)proto, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
@ -788,57 +787,58 @@ old_attach(struct socket *so, int proto)
|
||||
static int
|
||||
old_bind(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_BIND, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_BIND, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_connect(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_CONNECT, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_CONNECT, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_connect2(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
return so1->so_proto->pr_usrreq(so1, PRU_CONNECT2, nomb,
|
||||
return so1->so_proto->pr_ousrreq(so1, PRU_CONNECT2, nomb,
|
||||
(struct mbuf *)so2, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_control(struct socket *so, int cmd, caddr_t data)
|
||||
old_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_CONTROL, (struct mbuf *)cmd,
|
||||
(struct mbuf *)data, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_CONTROL, (struct mbuf *)cmd,
|
||||
(struct mbuf *)data,
|
||||
(struct mbuf *)ifp);
|
||||
}
|
||||
|
||||
static int
|
||||
old_detach(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_DETACH, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_DETACH, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_disconnect(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_DISCONNECT, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_DISCONNECT, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_listen(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_LISTEN, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_LISTEN, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_peeraddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_PEERADDR, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_PEERADDR, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_rcvd(struct socket *so, int flags)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_RCVD, nomb,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_RCVD, nomb,
|
||||
(struct mbuf *)flags, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
@ -846,7 +846,7 @@ old_rcvd(struct socket *so, int flags)
|
||||
static int
|
||||
old_rcvoob(struct socket *so, struct mbuf *m, int flags)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_RCVOOB, m,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_RCVOOB, m,
|
||||
(struct mbuf *)flags, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
@ -864,26 +864,26 @@ old_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *addr,
|
||||
} else {
|
||||
req = PRU_SEND;
|
||||
}
|
||||
return so->so_proto->pr_usrreq(so, req, m, addr, control);
|
||||
return so->so_proto->pr_ousrreq(so, req, m, addr, control);
|
||||
}
|
||||
|
||||
static int
|
||||
old_sense(struct socket *so, struct stat *sb)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_SENSE, (struct mbuf *)sb,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SENSE, (struct mbuf *)sb,
|
||||
nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_shutdown(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_sockaddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_SOCKADDR, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SOCKADDR, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
struct pr_usrreqs pru_oldstyle = {
|
||||
@ -893,82 +893,14 @@ struct pr_usrreqs pru_oldstyle = {
|
||||
old_sense, old_shutdown, old_sockaddr
|
||||
};
|
||||
|
||||
#endif /* PRU_OLDSTYLE */
|
||||
|
||||
/*
|
||||
* This function is glue going the other way. It is present to allow
|
||||
* for this interface to be actively developed from both directions
|
||||
* (i.e., work on the kernel and protocol stacks proceeds simultaneously).
|
||||
* It is expected that this function will probably cease to exist much
|
||||
* sooner than the pru_oldstyle interface, above, will, because once the
|
||||
* all of the high-kernel use of pr_usrreq() is removed the function is
|
||||
* no longer needed.
|
||||
* Some routines that return EOPNOTSUPP for entry points that are not
|
||||
* supported by a protocol. Fill in as needed.
|
||||
*/
|
||||
int
|
||||
pr_newstyle_usrreq(struct socket *so, int req, struct mbuf *m,
|
||||
struct mbuf *nam, struct mbuf *control)
|
||||
pru_connect2_notsupp(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
struct pr_usrreqs *pru = so->so_proto->pr_usrreqs;
|
||||
|
||||
switch(req) {
|
||||
case PRU_ABORT:
|
||||
return pru->pru_abort(so);
|
||||
|
||||
case PRU_ACCEPT:
|
||||
return pru->pru_accept(so, nam);
|
||||
|
||||
case PRU_ATTACH:
|
||||
return pru->pru_attach(so, (int)nam);
|
||||
|
||||
case PRU_BIND:
|
||||
return pru->pru_bind(so, nam);
|
||||
|
||||
case PRU_CONNECT:
|
||||
return pru->pru_connect(so, nam);
|
||||
|
||||
case PRU_CONNECT2:
|
||||
return pru->pru_connect2(so, (struct socket *)nam);
|
||||
|
||||
case PRU_CONTROL:
|
||||
return pru->pru_control(so, (int)m, (caddr_t)nam);
|
||||
|
||||
case PRU_DETACH:
|
||||
return pru->pru_detach(so);
|
||||
|
||||
case PRU_DISCONNECT:
|
||||
return pru->pru_disconnect(so);
|
||||
|
||||
case PRU_LISTEN:
|
||||
return pru->pru_listen(so);
|
||||
|
||||
case PRU_PEERADDR:
|
||||
return pru->pru_peeraddr(so, nam);
|
||||
|
||||
case PRU_RCVD:
|
||||
return pru->pru_rcvd(so, (int)nam);
|
||||
|
||||
case PRU_RCVOOB:
|
||||
return pru->pru_rcvoob(so, m, (int)nam);
|
||||
|
||||
case PRU_SEND:
|
||||
return pru->pru_send(so, 0, m, nam, control);
|
||||
|
||||
case PRU_SENDOOB:
|
||||
return pru->pru_send(so, PRUS_OOB, m, nam, control);
|
||||
|
||||
case PRU_SEND_EOF:
|
||||
return pru->pru_send(so, PRUS_EOF, m, nam, control);
|
||||
|
||||
case PRU_SENSE:
|
||||
return pru->pru_sense(so, (struct stat *)m);
|
||||
|
||||
case PRU_SHUTDOWN:
|
||||
return pru->pru_shutdown(so);
|
||||
|
||||
case PRU_SOCKADDR:
|
||||
return pru->pru_sockaddr(so, nam);
|
||||
|
||||
}
|
||||
|
||||
panic("pru_newstyle_usrreq: unhandled request %d", req);
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif /* PRU_OLDSTYLE */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
|
||||
* $Id: uipc_socket.c,v 1.17 1996/04/16 03:50:08 davidg Exp $
|
||||
* $Id: uipc_socket.c,v 1.18 1996/05/09 20:14:57 wollman Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -77,7 +77,7 @@ socreate(dom, aso, type, proto, p)
|
||||
prp = pffindproto(dom, proto, type);
|
||||
else
|
||||
prp = pffindtype(dom, type);
|
||||
if (prp == 0 || prp->pr_usrreq == 0)
|
||||
if (prp == 0 || prp->pr_usrreqs == 0)
|
||||
return (EPROTONOSUPPORT);
|
||||
if (prp->pr_type != type)
|
||||
return (EPROTOTYPE);
|
||||
@ -89,9 +89,7 @@ socreate(dom, aso, type, proto, p)
|
||||
if (p->p_ucred->cr_uid == 0)
|
||||
so->so_state = SS_PRIV;
|
||||
so->so_proto = prp;
|
||||
error =
|
||||
(*prp->pr_usrreq)(so, PRU_ATTACH,
|
||||
(struct mbuf *)0, (struct mbuf *)proto, (struct mbuf *)0);
|
||||
error = (*prp->pr_usrreqs->pru_attach)(so, proto);
|
||||
if (error) {
|
||||
so->so_state |= SS_NOFDREF;
|
||||
sofree(so);
|
||||
@ -109,9 +107,7 @@ sobind(so, nam)
|
||||
int s = splnet();
|
||||
int error;
|
||||
|
||||
error =
|
||||
(*so->so_proto->pr_usrreq)(so, PRU_BIND,
|
||||
(struct mbuf *)0, nam, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_bind)(so, nam);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
@ -123,9 +119,7 @@ solisten(so, backlog)
|
||||
{
|
||||
int s = splnet(), error;
|
||||
|
||||
error =
|
||||
(*so->so_proto->pr_usrreq)(so, PRU_LISTEN,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_listen)(so);
|
||||
if (error) {
|
||||
splx(s);
|
||||
return (error);
|
||||
@ -210,9 +204,7 @@ soclose(so)
|
||||
}
|
||||
drop:
|
||||
if (so->so_pcb) {
|
||||
int error2 =
|
||||
(*so->so_proto->pr_usrreq)(so, PRU_DETACH,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
|
||||
int error2 = (*so->so_proto->pr_usrreqs->pru_detach)(so);
|
||||
if (error == 0)
|
||||
error = error2;
|
||||
}
|
||||
@ -233,9 +225,7 @@ soabort(so)
|
||||
struct socket *so;
|
||||
{
|
||||
|
||||
return (
|
||||
(*so->so_proto->pr_usrreq)(so, PRU_ABORT,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
|
||||
return (*so->so_proto->pr_usrreqs->pru_abort)(so);
|
||||
}
|
||||
|
||||
int
|
||||
@ -249,8 +239,7 @@ soaccept(so, nam)
|
||||
if ((so->so_state & SS_NOFDREF) == 0)
|
||||
panic("soaccept: !NOFDREF");
|
||||
so->so_state &= ~SS_NOFDREF;
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT,
|
||||
(struct mbuf *)0, nam, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
@ -277,8 +266,7 @@ soconnect(so, nam)
|
||||
(error = sodisconnect(so))))
|
||||
error = EISCONN;
|
||||
else
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
|
||||
(struct mbuf *)0, nam, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_connect)(so, nam);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
@ -291,8 +279,7 @@ soconnect2(so1, so2)
|
||||
int s = splnet();
|
||||
int error;
|
||||
|
||||
error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
|
||||
(struct mbuf *)0, (struct mbuf *)so2, (struct mbuf *)0);
|
||||
error = (*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
@ -312,8 +299,7 @@ sodisconnect(so)
|
||||
error = EALREADY;
|
||||
goto bad;
|
||||
}
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_disconnect)(so);
|
||||
bad:
|
||||
splx(s);
|
||||
return (error);
|
||||
@ -472,8 +458,8 @@ sosend(so, addr, uio, top, control, flags)
|
||||
if (dontroute)
|
||||
so->so_options |= SO_DONTROUTE;
|
||||
s = splnet(); /* XXX */
|
||||
error = (*so->so_proto->pr_usrreq)(so,
|
||||
(flags & MSG_OOB) ? PRU_SENDOOB :
|
||||
error = (*so->so_proto->pr_usrreqs->pru_send)(so,
|
||||
(flags & MSG_OOB) ? PRUS_OOB :
|
||||
/*
|
||||
* If the user set MSG_EOF, the protocol
|
||||
* understands this flag and nothing left to
|
||||
@ -482,7 +468,7 @@ sosend(so, addr, uio, top, control, flags)
|
||||
((flags & MSG_EOF) &&
|
||||
(so->so_proto->pr_flags & PR_IMPLOPCL) &&
|
||||
(resid <= 0)) ?
|
||||
PRU_SEND_EOF : PRU_SEND,
|
||||
PRUS_EOF : 0,
|
||||
top, addr, control);
|
||||
splx(s);
|
||||
if (dontroute)
|
||||
@ -549,8 +535,7 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp)
|
||||
flags = 0;
|
||||
if (flags & MSG_OOB) {
|
||||
m = m_get(M_WAIT, MT_DATA);
|
||||
error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
|
||||
m, (struct mbuf *)(flags & MSG_PEEK), (struct mbuf *)0);
|
||||
error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK);
|
||||
if (error)
|
||||
goto bad;
|
||||
do {
|
||||
@ -566,8 +551,7 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp)
|
||||
if (mp)
|
||||
*mp = (struct mbuf *)0;
|
||||
if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
|
||||
(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
|
||||
(struct mbuf *)0, (struct mbuf *)0);
|
||||
(*pr->pr_usrreqs->pru_rcvd)(so, 0);
|
||||
|
||||
restart:
|
||||
error = sblock(&so->so_rcv, SBLOCKWAIT(flags));
|
||||
@ -804,8 +788,7 @@ soreceive(so, paddr, uio, mp0, controlp, flagsp)
|
||||
if (m == 0)
|
||||
so->so_rcv.sb_mb = nextrecord;
|
||||
if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
|
||||
(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
|
||||
(struct mbuf *)flags, (struct mbuf *)0);
|
||||
(*pr->pr_usrreqs->pru_rcvd)(so, flags);
|
||||
}
|
||||
if (orig_resid == uio->uio_resid && orig_resid &&
|
||||
(flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
|
||||
@ -833,8 +816,7 @@ soshutdown(so, how)
|
||||
if (how & FREAD)
|
||||
sorflush(so);
|
||||
if (how & FWRITE)
|
||||
return ((*pr->pr_usrreq)(so, PRU_SHUTDOWN,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0));
|
||||
return ((*pr->pr_usrreqs->pru_shutdown)(so));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -186,8 +186,7 @@ sonewconn1(head, connstatus)
|
||||
so->so_state |= SS_INCOMP;
|
||||
}
|
||||
head->so_qlen++;
|
||||
if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0)) {
|
||||
if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
|
||||
if (so->so_state & SS_COMP) {
|
||||
TAILQ_REMOVE(&head->so_comp, so, so_list);
|
||||
} else {
|
||||
@ -768,19 +767,19 @@ sbdroprecord(sb)
|
||||
static int
|
||||
old_abort(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_ABORT, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ABORT, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_accept(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_ACCEPT, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ACCEPT, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_attach(struct socket *so, int proto)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_ATTACH, nomb,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ATTACH, nomb,
|
||||
(struct mbuf *)proto, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
@ -788,57 +787,58 @@ old_attach(struct socket *so, int proto)
|
||||
static int
|
||||
old_bind(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_BIND, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_BIND, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_connect(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_CONNECT, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_CONNECT, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_connect2(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
return so1->so_proto->pr_usrreq(so1, PRU_CONNECT2, nomb,
|
||||
return so1->so_proto->pr_ousrreq(so1, PRU_CONNECT2, nomb,
|
||||
(struct mbuf *)so2, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_control(struct socket *so, int cmd, caddr_t data)
|
||||
old_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_CONTROL, (struct mbuf *)cmd,
|
||||
(struct mbuf *)data, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_CONTROL, (struct mbuf *)cmd,
|
||||
(struct mbuf *)data,
|
||||
(struct mbuf *)ifp);
|
||||
}
|
||||
|
||||
static int
|
||||
old_detach(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_DETACH, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_DETACH, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_disconnect(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_DISCONNECT, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_DISCONNECT, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_listen(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_LISTEN, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_LISTEN, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_peeraddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_PEERADDR, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_PEERADDR, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_rcvd(struct socket *so, int flags)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_RCVD, nomb,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_RCVD, nomb,
|
||||
(struct mbuf *)flags, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
@ -846,7 +846,7 @@ old_rcvd(struct socket *so, int flags)
|
||||
static int
|
||||
old_rcvoob(struct socket *so, struct mbuf *m, int flags)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_RCVOOB, m,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_RCVOOB, m,
|
||||
(struct mbuf *)flags, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
@ -864,26 +864,26 @@ old_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *addr,
|
||||
} else {
|
||||
req = PRU_SEND;
|
||||
}
|
||||
return so->so_proto->pr_usrreq(so, req, m, addr, control);
|
||||
return so->so_proto->pr_ousrreq(so, req, m, addr, control);
|
||||
}
|
||||
|
||||
static int
|
||||
old_sense(struct socket *so, struct stat *sb)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_SENSE, (struct mbuf *)sb,
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SENSE, (struct mbuf *)sb,
|
||||
nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_shutdown(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_sockaddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_usrreq(so, PRU_SOCKADDR, nomb, nam, nomb);
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SOCKADDR, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
struct pr_usrreqs pru_oldstyle = {
|
||||
@ -893,82 +893,14 @@ struct pr_usrreqs pru_oldstyle = {
|
||||
old_sense, old_shutdown, old_sockaddr
|
||||
};
|
||||
|
||||
#endif /* PRU_OLDSTYLE */
|
||||
|
||||
/*
|
||||
* This function is glue going the other way. It is present to allow
|
||||
* for this interface to be actively developed from both directions
|
||||
* (i.e., work on the kernel and protocol stacks proceeds simultaneously).
|
||||
* It is expected that this function will probably cease to exist much
|
||||
* sooner than the pru_oldstyle interface, above, will, because once the
|
||||
* all of the high-kernel use of pr_usrreq() is removed the function is
|
||||
* no longer needed.
|
||||
* Some routines that return EOPNOTSUPP for entry points that are not
|
||||
* supported by a protocol. Fill in as needed.
|
||||
*/
|
||||
int
|
||||
pr_newstyle_usrreq(struct socket *so, int req, struct mbuf *m,
|
||||
struct mbuf *nam, struct mbuf *control)
|
||||
pru_connect2_notsupp(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
struct pr_usrreqs *pru = so->so_proto->pr_usrreqs;
|
||||
|
||||
switch(req) {
|
||||
case PRU_ABORT:
|
||||
return pru->pru_abort(so);
|
||||
|
||||
case PRU_ACCEPT:
|
||||
return pru->pru_accept(so, nam);
|
||||
|
||||
case PRU_ATTACH:
|
||||
return pru->pru_attach(so, (int)nam);
|
||||
|
||||
case PRU_BIND:
|
||||
return pru->pru_bind(so, nam);
|
||||
|
||||
case PRU_CONNECT:
|
||||
return pru->pru_connect(so, nam);
|
||||
|
||||
case PRU_CONNECT2:
|
||||
return pru->pru_connect2(so, (struct socket *)nam);
|
||||
|
||||
case PRU_CONTROL:
|
||||
return pru->pru_control(so, (int)m, (caddr_t)nam);
|
||||
|
||||
case PRU_DETACH:
|
||||
return pru->pru_detach(so);
|
||||
|
||||
case PRU_DISCONNECT:
|
||||
return pru->pru_disconnect(so);
|
||||
|
||||
case PRU_LISTEN:
|
||||
return pru->pru_listen(so);
|
||||
|
||||
case PRU_PEERADDR:
|
||||
return pru->pru_peeraddr(so, nam);
|
||||
|
||||
case PRU_RCVD:
|
||||
return pru->pru_rcvd(so, (int)nam);
|
||||
|
||||
case PRU_RCVOOB:
|
||||
return pru->pru_rcvoob(so, m, (int)nam);
|
||||
|
||||
case PRU_SEND:
|
||||
return pru->pru_send(so, 0, m, nam, control);
|
||||
|
||||
case PRU_SENDOOB:
|
||||
return pru->pru_send(so, PRUS_OOB, m, nam, control);
|
||||
|
||||
case PRU_SEND_EOF:
|
||||
return pru->pru_send(so, PRUS_EOF, m, nam, control);
|
||||
|
||||
case PRU_SENSE:
|
||||
return pru->pru_sense(so, (struct stat *)m);
|
||||
|
||||
case PRU_SHUTDOWN:
|
||||
return pru->pru_shutdown(so);
|
||||
|
||||
case PRU_SOCKADDR:
|
||||
return pru->pru_sockaddr(so, nam);
|
||||
|
||||
}
|
||||
|
||||
panic("pru_newstyle_usrreq: unhandled request %d", req);
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif /* PRU_OLDSTYLE */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
|
||||
* $Id: uipc_syscalls.c,v 1.16 1996/03/11 15:37:33 davidg Exp $
|
||||
* $Id: uipc_syscalls.c,v 1.17 1996/05/09 20:14:59 wollman Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
@ -1126,7 +1126,7 @@ getsockname1(p, uap, retval, compat)
|
||||
m = m_getclr(M_WAIT, MT_SONAME);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m);
|
||||
if (error)
|
||||
goto bad;
|
||||
if (len > m->m_len)
|
||||
@ -1199,7 +1199,7 @@ getpeername1(p, uap, retval, compat)
|
||||
m = m_getclr(M_WAIT, MT_SONAME);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m);
|
||||
if (error)
|
||||
goto bad;
|
||||
if (len > m->m_len)
|
||||
|
33
sys/net/if.c
33
sys/net/if.c
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if.c 8.3 (Berkeley) 1/4/94
|
||||
* $Id: if.c,v 1.31 1996/06/10 23:07:26 gpalmer Exp $
|
||||
* $Id: if.c,v 1.32 1996/06/12 19:23:59 gpalmer Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -162,18 +162,6 @@ if_attach(ifp)
|
||||
while (namelen != 0)
|
||||
sdl->sdl_data[--namelen] = 0xff;
|
||||
}
|
||||
/*
|
||||
* If they provided a slow input queue, initialize it.
|
||||
*/
|
||||
if (ifp->if_poll_slowq) {
|
||||
struct ifqueue *ifq = ifp->if_poll_slowq;
|
||||
|
||||
bzero(ifq, sizeof *ifq);
|
||||
ifq->ifq_maxlen = ifqmaxlen;
|
||||
#ifdef POLLING
|
||||
ifq->if_poll_recv = if_poll_recv_slow;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Locate an interface based on a complete address.
|
||||
@ -583,9 +571,9 @@ ifioctl(so, cmd, data, p)
|
||||
if (so->so_proto == 0)
|
||||
return (EOPNOTSUPP);
|
||||
#ifndef COMPAT_43
|
||||
return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
|
||||
(struct mbuf *)cmd, (struct mbuf *)data,
|
||||
(struct mbuf *)ifp));
|
||||
return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
|
||||
data,
|
||||
ifp));
|
||||
#else
|
||||
{
|
||||
int ocmd = cmd;
|
||||
@ -623,14 +611,10 @@ ifioctl(so, cmd, data, p)
|
||||
case OSIOCGIFNETMASK:
|
||||
cmd = SIOCGIFNETMASK;
|
||||
}
|
||||
error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
|
||||
/*
|
||||
* XXX callees reverse the following bogus casts,
|
||||
* but it would be easier to use a separate
|
||||
* interface that is guaranteed to work.
|
||||
*/
|
||||
(struct mbuf *)cmd, (struct mbuf *)data,
|
||||
(struct mbuf *)ifp));
|
||||
error = ((*so->so_proto->pr_usrreqs->pru_control)(so,
|
||||
cmd,
|
||||
data,
|
||||
ifp));
|
||||
switch (ocmd) {
|
||||
|
||||
case OSIOCGIFADDR:
|
||||
@ -759,3 +743,4 @@ ifconf(cmd, data)
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
|
||||
SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)in_proto.c 8.2 (Berkeley) 2/9/95
|
||||
* $Id: in_proto.c,v 1.31 1996/06/20 17:52:32 fenner Exp $
|
||||
* $Id: in_proto.c,v 1.32 1996/07/10 19:44:21 julian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -105,8 +105,9 @@ struct protosw inetsw[] = {
|
||||
{ SOCK_STREAM, &inetdomain, IPPROTO_TCP,
|
||||
PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD,
|
||||
tcp_input, 0, tcp_ctlinput, tcp_ctloutput,
|
||||
tcp_usrreq,
|
||||
tcp_init, tcp_fasttimo, tcp_slowtimo, tcp_drain
|
||||
0,
|
||||
tcp_init, tcp_fasttimo, tcp_slowtimo, tcp_drain,
|
||||
&tcp_usrreqs
|
||||
},
|
||||
{ SOCK_RAW, &inetdomain, IPPROTO_RAW, PR_ATOMIC|PR_ADDR,
|
||||
rip_input, 0, 0, rip_ctloutput,
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tcp_timer.c 8.2 (Berkeley) 5/24/95
|
||||
* $Id: tcp_timer.c,v 1.16 1996/04/15 03:46:33 davidg Exp $
|
||||
* $Id: tcp_timer.c,v 1.17 1996/06/03 15:37:52 jdp Exp $
|
||||
*/
|
||||
|
||||
#ifndef TUBA_INCLUDE
|
||||
@ -122,6 +122,9 @@ tcp_slowtimo()
|
||||
register struct tcpcb *tp;
|
||||
register int i;
|
||||
int s;
|
||||
#ifdef TCPDEBUG
|
||||
int ostate;
|
||||
#endif
|
||||
|
||||
s = splnet();
|
||||
|
||||
@ -142,10 +145,19 @@ tcp_slowtimo()
|
||||
continue;
|
||||
for (i = 0; i < TCPT_NTIMERS; i++) {
|
||||
if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
|
||||
if (tcp_usrreq(tp->t_inpcb->inp_socket,
|
||||
PRU_SLOWTIMO, (struct mbuf *)0,
|
||||
(struct mbuf *)i, (struct mbuf *)0) == NULL)
|
||||
#ifdef TCPDEBUG
|
||||
ostate = tp->t_state;
|
||||
#endif
|
||||
tp = tcp_timers(tp, i);
|
||||
if (tp == NULL)
|
||||
goto tpgone;
|
||||
#ifdef TCPDEBUG
|
||||
if (tp->t_inpcb->inp_socket->so_options
|
||||
& SO_DEBUG)
|
||||
tcp_trace(TA_USER, ostate, tp,
|
||||
(struct tcpiphdr *)0,
|
||||
PRU_SLOWTIMO);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
tp->t_idle++;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
|
||||
* $Id: tcp_usrreq.c,v 1.21 1995/12/06 23:37:42 bde Exp $
|
||||
* $Id: tcp_usrreq.c,v 1.22 1996/03/11 15:13:37 davidg Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -77,6 +77,8 @@ static struct tcpcb *
|
||||
tcp_disconnect __P((struct tcpcb *));
|
||||
static struct tcpcb *
|
||||
tcp_usrclosed __P((struct tcpcb *));
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* Process a TCP user request for TCP tb. If this is a send request
|
||||
* then m is the mbuf chain of send data. If this is a timer expiration
|
||||
@ -391,6 +393,431 @@ tcp_usrreq(so, req, m, nam, control)
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TCPDEBUG
|
||||
#define TCPDEBUG0 int ostate
|
||||
#define TCPDEBUG1() ostate = tp ? tp->t_state : 0
|
||||
#define TCPDEBUG2(req) if (tp && (so->so_options & SO_DEBUG)) && \
|
||||
tcp_trace(TA_USER, ostate, tp, 0, req)
|
||||
#else
|
||||
#define TCPDEBUG0
|
||||
#define TCPDEBUG1()
|
||||
#define TCPDEBUG2(req)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TCP attaches to socket via pru_attach(), reserving space,
|
||||
* and an internet control block.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_attach(struct socket *so, int proto)
|
||||
{
|
||||
int s = splnet();
|
||||
int error;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp = 0;
|
||||
TCPDEBUG0;
|
||||
|
||||
TCPDEBUG1();
|
||||
if (inp) {
|
||||
error = EISCONN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = tcp_attach(so);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
if ((so->so_options & SO_LINGER) && so->so_linger == 0)
|
||||
so->so_linger = TCP_LINGERTIME * hz;
|
||||
tp = sototcpcb(so);
|
||||
out:
|
||||
TCPDEBUG2(PRU_ATTACH);
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* pru_detach() detaches the TCP protocol from the socket.
|
||||
* If the protocol state is non-embryonic, then can't
|
||||
* do this directly: have to initiate a pru_disconnect(),
|
||||
* which may finish later; embryonic TCB's can just
|
||||
* be discarded here.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_detach(struct socket *so)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
TCPDEBUG0;
|
||||
|
||||
if (inp == 0) {
|
||||
splx(s);
|
||||
return EINVAL; /* XXX */
|
||||
}
|
||||
tp = intotcpcb(inp);
|
||||
TCPDEBUG1();
|
||||
if (tp->t_state > TCPS_LISTEN)
|
||||
tp = tcp_disconnect(tp);
|
||||
else
|
||||
tp = tcp_close(tp);
|
||||
|
||||
TCPDEBUG2(PRU_DETACH);
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
#define COMMON_START() TCPDEBUG0; \
|
||||
do { \
|
||||
if (inp == 0) { \
|
||||
splx(s); \
|
||||
return EINVAL; \
|
||||
} \
|
||||
tp = intotcpcb(inp); \
|
||||
TCPDEBUG1(); \
|
||||
} while(0)
|
||||
|
||||
#define COMMON_END(req) out: TCPDEBUG2(req); splx(s); return error; goto out
|
||||
|
||||
|
||||
/*
|
||||
* Give the socket an address.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_bind(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
struct sockaddr_in *sinp;
|
||||
|
||||
COMMON_START();
|
||||
|
||||
/*
|
||||
* Must check for multicast addresses and disallow binding
|
||||
* to them.
|
||||
*/
|
||||
sinp = mtod(nam, struct sockaddr_in *);
|
||||
if (sinp->sin_family == AF_INET &&
|
||||
IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
|
||||
error = EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
error = in_pcbbind(inp, nam);
|
||||
if (error)
|
||||
goto out;
|
||||
COMMON_END(PRU_BIND);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare to accept connections.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_listen(struct socket *so)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
if (inp->inp_lport == 0)
|
||||
error = in_pcbbind(inp, NULL);
|
||||
if (error == 0)
|
||||
tp->t_state = TCPS_LISTEN;
|
||||
COMMON_END(PRU_LISTEN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiate connection to peer.
|
||||
* Create a template for use in transmissions on this connection.
|
||||
* Enter SYN_SENT state, and mark socket as connecting.
|
||||
* Start keep-alive timer, and seed output sequence space.
|
||||
* Send initial segment on connection.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_connect(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
struct sockaddr_in *sinp;
|
||||
|
||||
COMMON_START();
|
||||
|
||||
/*
|
||||
* Must disallow TCP ``connections'' to multicast addresses.
|
||||
*/
|
||||
sinp = mtod(nam, struct sockaddr_in *);
|
||||
if (sinp->sin_family == AF_INET
|
||||
&& IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
|
||||
error = EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((error = tcp_connect(tp, nam)) != 0)
|
||||
goto out;
|
||||
error = tcp_output(tp);
|
||||
COMMON_END(PRU_CONNECT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiate disconnect from peer.
|
||||
* If connection never passed embryonic stage, just drop;
|
||||
* else if don't need to let data drain, then can just drop anyways,
|
||||
* else have to begin TCP shutdown process: mark socket disconnecting,
|
||||
* drain unread data, state switch to reflect user close, and
|
||||
* send segment (e.g. FIN) to peer. Socket will be really disconnected
|
||||
* when peer sends FIN and acks ours.
|
||||
*
|
||||
* SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_disconnect(struct socket *so)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
tp = tcp_disconnect(tp);
|
||||
COMMON_END(PRU_DISCONNECT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept a connection. Essentially all the work is
|
||||
* done at higher levels; just return the address
|
||||
* of the peer, storing through addr.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_accept(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
in_setpeeraddr(inp, nam);
|
||||
COMMON_END(PRU_ACCEPT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the connection as being incapable of further output.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_shutdown(struct socket *so)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
socantsendmore(so);
|
||||
tp = tcp_usrclosed(tp);
|
||||
if (tp)
|
||||
error = tcp_output(tp);
|
||||
COMMON_END(PRU_SHUTDOWN);
|
||||
}
|
||||
|
||||
/*
|
||||
* After a receive, possibly send window update to peer.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_rcvd(struct socket *so, int flags)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
tcp_output(tp);
|
||||
COMMON_END(PRU_RCVD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a send by putting data in output queue and updating urgent
|
||||
* marker if URG set. Possibly send more data.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam,
|
||||
struct mbuf *control)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
if (control && control->m_len) {
|
||||
m_freem(control); /* XXX shouldn't caller do this??? */
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if(!(flags & PRUS_OOB)) {
|
||||
sbappend(&so->so_snd, m);
|
||||
if (nam && tp->t_state < TCPS_SYN_SENT) {
|
||||
/*
|
||||
* Do implied connect if not yet connected,
|
||||
* initialize window to default value, and
|
||||
* initialize maxseg/maxopd using peer's cached
|
||||
* MSS.
|
||||
*/
|
||||
error = tcp_connect(tp, nam);
|
||||
if (error)
|
||||
goto out;
|
||||
tp->snd_wnd = TTCP_CLIENT_SND_WND;
|
||||
tcp_mss(tp, -1);
|
||||
}
|
||||
|
||||
if (flags & PRUS_EOF) {
|
||||
/*
|
||||
* Close the send side of the connection after
|
||||
* the data is sent.
|
||||
*/
|
||||
socantsendmore(so);
|
||||
tp = tcp_usrclosed(tp);
|
||||
}
|
||||
if (tp != NULL)
|
||||
error = tcp_output(tp);
|
||||
} else {
|
||||
if (sbspace(&so->so_snd) < -512) {
|
||||
m_freem(m);
|
||||
error = ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* According to RFC961 (Assigned Protocols),
|
||||
* the urgent pointer points to the last octet
|
||||
* of urgent data. We continue, however,
|
||||
* to consider it to indicate the first octet
|
||||
* of data past the urgent section.
|
||||
* Otherwise, snd_up should be one lower.
|
||||
*/
|
||||
sbappend(&so->so_snd, m);
|
||||
tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
|
||||
tp->t_force = 1;
|
||||
error = tcp_output(tp);
|
||||
tp->t_force = 0;
|
||||
}
|
||||
COMMON_END((flags & PRUS_OOB) ? PRU_SENDOOB :
|
||||
((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND));
|
||||
}
|
||||
|
||||
/*
|
||||
* Abort the TCP.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_abort(struct socket *so)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
tp = tcp_drop(tp, ECONNABORTED);
|
||||
COMMON_END(PRU_ABORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in st_bklsize for fstat() operations on a socket.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_sense(struct socket *so, struct stat *sb)
|
||||
{
|
||||
int s = splnet();
|
||||
|
||||
sb->st_blksize = so->so_snd.sb_hiwat;
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive out-of-band data.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_rcvoob(struct socket *so, struct mbuf *m, int flags)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
if ((so->so_oobmark == 0 &&
|
||||
(so->so_state & SS_RCVATMARK) == 0) ||
|
||||
so->so_options & SO_OOBINLINE ||
|
||||
tp->t_oobflags & TCPOOB_HADDATA) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if ((tp->t_oobflags & TCPOOB_HAVEDATA) == 0) {
|
||||
error = EWOULDBLOCK;
|
||||
goto out;
|
||||
}
|
||||
m->m_len = 1;
|
||||
*mtod(m, caddr_t) = tp->t_iobc;
|
||||
if ((flags & MSG_PEEK) == 0)
|
||||
tp->t_oobflags ^= (TCPOOB_HAVEDATA | TCPOOB_HADDATA);
|
||||
COMMON_END(PRU_RCVOOB);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_usr_sockaddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
in_setsockaddr(inp, nam);
|
||||
COMMON_END(PRU_SOCKADDR);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_usr_peeraddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
int s = splnet();
|
||||
int error = 0;
|
||||
struct inpcb *inp = sotoinpcb(so);
|
||||
struct tcpcb *tp;
|
||||
|
||||
COMMON_START();
|
||||
in_setpeeraddr(inp, nam);
|
||||
COMMON_END(PRU_PEERADDR);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX - this should just be a call to in_control, but we need to get
|
||||
* the types worked out.
|
||||
*/
|
||||
static int
|
||||
tcp_usr_control(struct socket *so, int cmd, caddr_t arg, struct ifnet *ifp)
|
||||
{
|
||||
return in_control(so, cmd, arg, ifp);
|
||||
}
|
||||
|
||||
/* xxx - should be const */
|
||||
struct pr_usrreqs tcp_usrreqs = {
|
||||
tcp_usr_abort, tcp_usr_accept, tcp_usr_attach, tcp_usr_bind,
|
||||
tcp_usr_connect, pru_connect2_notsupp, tcp_usr_control, tcp_usr_detach,
|
||||
tcp_usr_disconnect, tcp_usr_listen, tcp_usr_peeraddr, tcp_usr_rcvd,
|
||||
tcp_usr_rcvoob, tcp_usr_send, tcp_usr_sense, tcp_usr_shutdown,
|
||||
tcp_usr_sockaddr
|
||||
};
|
||||
|
||||
/*
|
||||
* Common subroutine to open a TCP connection to remote host specified
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tcp_var.h 8.4 (Berkeley) 5/24/95
|
||||
* $Id: tcp_var.h,v 1.32 1996/04/26 18:32:58 wollman Exp $
|
||||
* $Id: tcp_var.h,v 1.33 1996/06/05 16:57:38 wollman Exp $
|
||||
*/
|
||||
|
||||
#ifndef _NETINET_TCP_VAR_H_
|
||||
@ -362,9 +362,8 @@ struct tcpiphdr *
|
||||
struct tcpcb *
|
||||
tcp_timers __P((struct tcpcb *, int));
|
||||
void tcp_trace __P((int, int, struct tcpcb *, struct tcpiphdr *, int));
|
||||
int tcp_usrreq __P((struct socket *,
|
||||
int, struct mbuf *, struct mbuf *, struct mbuf *));
|
||||
|
||||
extern struct pr_usrreqs tcp_usrreqs;
|
||||
extern u_long tcp_sendspace;
|
||||
extern u_long tcp_recvspace;
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94
|
||||
* $Id: nfs_socket.c,v 1.15 1996/02/13 18:16:28 wollman Exp $
|
||||
* $Id: nfs_socket.c,v 1.16 1996/06/14 11:13:18 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1347,11 +1347,12 @@ nfs_timer(arg)
|
||||
nmp->nm_sent < nmp->nm_cwnd) &&
|
||||
(m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))){
|
||||
if ((nmp->nm_flag & NFSMNT_NOCONN) == 0)
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
|
||||
(struct mbuf *)0, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_send)
|
||||
(so, 0, m, (struct mbuf *)0,
|
||||
(struct mbuf *)0);
|
||||
else
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
|
||||
nmp->nm_nam, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_send)
|
||||
(so, 0, m, nmp->nm_nam, (struct mbuf *)0);
|
||||
if (error) {
|
||||
if (NFSIGNORE_SOERROR(nmp->nm_soflags, error))
|
||||
so->so_error = 0;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94
|
||||
* $Id: nfs_socket.c,v 1.15 1996/02/13 18:16:28 wollman Exp $
|
||||
* $Id: nfs_socket.c,v 1.16 1996/06/14 11:13:18 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1347,11 +1347,12 @@ nfs_timer(arg)
|
||||
nmp->nm_sent < nmp->nm_cwnd) &&
|
||||
(m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))){
|
||||
if ((nmp->nm_flag & NFSMNT_NOCONN) == 0)
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
|
||||
(struct mbuf *)0, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_send)
|
||||
(so, 0, m, (struct mbuf *)0,
|
||||
(struct mbuf *)0);
|
||||
else
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
|
||||
nmp->nm_nam, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_send)
|
||||
(so, 0, m, nmp->nm_nam, (struct mbuf *)0);
|
||||
if (error) {
|
||||
if (NFSIGNORE_SOERROR(nmp->nm_soflags, error))
|
||||
so->so_error = 0;
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94
|
||||
* $Id: nfs_socket.c,v 1.15 1996/02/13 18:16:28 wollman Exp $
|
||||
* $Id: nfs_socket.c,v 1.16 1996/06/14 11:13:18 phk Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1347,11 +1347,12 @@ nfs_timer(arg)
|
||||
nmp->nm_sent < nmp->nm_cwnd) &&
|
||||
(m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))){
|
||||
if ((nmp->nm_flag & NFSMNT_NOCONN) == 0)
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
|
||||
(struct mbuf *)0, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_send)
|
||||
(so, 0, m, (struct mbuf *)0,
|
||||
(struct mbuf *)0);
|
||||
else
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, m,
|
||||
nmp->nm_nam, (struct mbuf *)0);
|
||||
error = (*so->so_proto->pr_usrreqs->pru_send)
|
||||
(so, 0, m, nmp->nm_nam, (struct mbuf *)0);
|
||||
if (error) {
|
||||
if (NFSIGNORE_SOERROR(nmp->nm_soflags, error))
|
||||
so->so_error = 0;
|
||||
|
@ -80,8 +80,8 @@ struct protosw {
|
||||
struct mbuf **));
|
||||
/* control output (from above) */
|
||||
/* user-protocol hook */
|
||||
int (*pr_usrreq) __P((struct socket *, int, struct mbuf *,
|
||||
struct mbuf *, struct mbuf *));
|
||||
int (*pr_ousrreq) __P((struct socket *, int, struct mbuf *,
|
||||
struct mbuf *, struct mbuf *));
|
||||
/* user request: see list below */
|
||||
/* utility hooks */
|
||||
void (*pr_init) __P((void)); /* initialization hook */
|
||||
@ -166,6 +166,7 @@ char *prurequests[] = {
|
||||
|
||||
#ifdef KERNEL /* users shouldn't see this decl */
|
||||
struct stat;
|
||||
struct ifnet;
|
||||
|
||||
/*
|
||||
* If the ordering here looks odd, that's because it's alphabetical.
|
||||
@ -177,13 +178,15 @@ struct pr_usrreqs {
|
||||
int (*pru_bind) __P((struct socket *so, struct mbuf *nam));
|
||||
int (*pru_connect) __P((struct socket *so, struct mbuf *nam));
|
||||
int (*pru_connect2) __P((struct socket *so1, struct socket *so2));
|
||||
int (*pru_control) __P((struct socket *so, int cmd, caddr_t data));
|
||||
int (*pru_control) __P((struct socket *so, int cmd, caddr_t data,
|
||||
struct ifnet *ifp));
|
||||
int (*pru_detach) __P((struct socket *so));
|
||||
int (*pru_disconnect) __P((struct socket *so));
|
||||
int (*pru_listen) __P((struct socket *so));
|
||||
int (*pru_peeraddr) __P((struct socket *so, struct mbuf *nam));
|
||||
int (*pru_rcvd) __P((struct socket *so, int flags));
|
||||
int (*pru_rcvoob) __P((struct socket *so, struct mbuf *m, int flags));
|
||||
int (*pru_rcvoob) __P((struct socket *so, struct mbuf *m,
|
||||
int flags));
|
||||
/*
|
||||
* The `m' parameter here is almost certainly going to become a
|
||||
* `struct uio' at some point in the future. Similar changes
|
||||
@ -198,6 +201,8 @@ struct pr_usrreqs {
|
||||
int (*pru_sockaddr) __P((struct socket *so, struct mbuf *nam));
|
||||
};
|
||||
|
||||
int pru_connect2_notsupp __P((struct socket *so1, struct socket *so2));
|
||||
|
||||
#define PRU_OLDSTYLE
|
||||
|
||||
#ifdef PRU_OLDSTYLE
|
||||
@ -207,8 +212,6 @@ struct pr_usrreqs {
|
||||
* appropriate arguments.
|
||||
*/
|
||||
extern struct pr_usrreqs pru_oldstyle;
|
||||
int pr_newstyle_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
|
||||
struct mbuf *);
|
||||
#endif /* PRU_OLDSTYLE */
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
Loading…
Reference in New Issue
Block a user