Mostly minor changes.
Convert the listen queue to a TAILQ to avoid O(n^2) insertion. Should probably be a hash table.
This commit is contained in:
parent
f7f3f4299d
commit
4e8477f520
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: if_x25subr.c,v 1.13 1996/05/09 22:29:25 scottr Exp $ */
|
/* $NetBSD: if_x25subr.c,v 1.14 1996/05/23 23:35:22 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1990, 1993
|
* Copyright (c) 1990, 1993
|
||||||
|
@ -698,10 +698,8 @@ int x25_startproto = 1;
|
||||||
void
|
void
|
||||||
pk_init()
|
pk_init()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* warning, sizeof (struct sockaddr_x25) > 32,
|
TAILQ_INIT(&pk_listenhead);
|
||||||
* but contains no data of interest beyond 32
|
|
||||||
*/
|
|
||||||
if (x25_startproto) {
|
if (x25_startproto) {
|
||||||
pk_protolisten(0xcc, 1, x25_dgram_incoming);
|
pk_protolisten(0xcc, 1, x25_dgram_incoming);
|
||||||
pk_protolisten(0x81, 1, x25_dgram_incoming);
|
pk_protolisten(0x81, 1, x25_dgram_incoming);
|
||||||
|
@ -736,7 +734,7 @@ pk_user_protolisten(info)
|
||||||
|
|
||||||
gotspi:if (info[1])
|
gotspi:if (info[1])
|
||||||
return pk_protolisten(dp->spi, dp->spilen, dp->f);
|
return pk_protolisten(dp->spi, dp->spilen, dp->f);
|
||||||
for (lcp = pk_listenhead; lcp; lcp = lcp->lcd_listen)
|
for (lcp = pk_listenhead.tqh_first; lcp; lcp = lcp->lcd_listen.tqe_next)
|
||||||
if (lcp->lcd_laddr.x25_udlen == dp->spilen &&
|
if (lcp->lcd_laddr.x25_udlen == dp->spilen &&
|
||||||
Bcmp(&dp->spi, lcp->lcd_laddr.x25_udata, dp->spilen) == 0) {
|
Bcmp(&dp->spi, lcp->lcd_laddr.x25_udata, dp->spilen) == 0) {
|
||||||
pk_disconnect(lcp);
|
pk_disconnect(lcp);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pk_input.c,v 1.7 1996/02/13 22:05:21 christos Exp $ */
|
/* $NetBSD: pk_input.c,v 1.8 1996/05/23 23:35:24 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) University of British Columbia, 1984
|
* Copyright (c) University of British Columbia, 1984
|
||||||
|
@ -967,7 +967,7 @@ pk_incoming_call(pkp, m0)
|
||||||
* It does provide a way of multiplexing services at the user level.
|
* It does provide a way of multiplexing services at the user level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (l = pk_listenhead; l; l = l->lcd_listen) {
|
for (l = pk_listenhead.tqh_first; l; l = l->lcd_listen.tqe_next) {
|
||||||
struct sockaddr_x25 *sxp = l->lcd_ceaddr;
|
struct sockaddr_x25 *sxp = l->lcd_ceaddr;
|
||||||
|
|
||||||
if (bcmp(sxp->x25_udata, u, sxp->x25_udlen))
|
if (bcmp(sxp->x25_udata, u, sxp->x25_udlen))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pk_subr.c,v 1.12 1996/03/30 21:54:33 christos Exp $ */
|
/* $NetBSD: pk_subr.c,v 1.13 1996/05/23 23:35:26 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) University of British Columbia, 1984
|
* Copyright (c) University of British Columbia, 1984
|
||||||
|
@ -130,16 +130,10 @@ pk_disconnect(lcp)
|
||||||
register struct pklcd *lcp;
|
register struct pklcd *lcp;
|
||||||
{
|
{
|
||||||
register struct socket *so = lcp->lcd_so;
|
register struct socket *so = lcp->lcd_so;
|
||||||
register struct pklcd *l, *p;
|
|
||||||
|
|
||||||
switch (lcp->lcd_state) {
|
switch (lcp->lcd_state) {
|
||||||
case LISTEN:
|
case LISTEN:
|
||||||
for (p = 0, l = pk_listenhead; l && l != lcp; p = l, l = l->lcd_listen);
|
TAILQ_REMOVE(&pk_listenhead, lcp, lcd_listen);
|
||||||
if (p == 0) {
|
|
||||||
if (l != 0)
|
|
||||||
pk_listenhead = l->lcd_listen;
|
|
||||||
} else if (l != 0)
|
|
||||||
p->lcd_listen = l->lcd_listen;
|
|
||||||
pk_close(lcp);
|
pk_close(lcp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -376,7 +370,7 @@ pk_bind(lcp, nam)
|
||||||
/*
|
/*
|
||||||
* For ISO's sake permit default listeners, but only one such . . .
|
* For ISO's sake permit default listeners, but only one such . . .
|
||||||
*/
|
*/
|
||||||
for (pp = pk_listenhead; pp; pp = pp->lcd_listen) {
|
for (pp = pk_listenhead.tqh_first; pp; pp = pp->lcd_listen.tqe_next) {
|
||||||
register struct sockaddr_x25 *sa2 = pp->lcd_ceaddr;
|
register struct sockaddr_x25 *sa2 = pp->lcd_ceaddr;
|
||||||
if ((sa2->x25_udlen == sa->x25_udlen) &&
|
if ((sa2->x25_udlen == sa->x25_udlen) &&
|
||||||
(sa2->x25_udlen == 0 ||
|
(sa2->x25_udlen == 0 ||
|
||||||
|
@ -406,12 +400,9 @@ pk_listen(lcp)
|
||||||
* Add default listener at end, any others at start.
|
* Add default listener at end, any others at start.
|
||||||
*/
|
*/
|
||||||
if (lcp->lcd_ceaddr->x25_udlen == 0) {
|
if (lcp->lcd_ceaddr->x25_udlen == 0) {
|
||||||
for (pp = &pk_listenhead; *pp;)
|
TAILQ_INSERT_TAIL(&pk_listenhead, lcp, lcd_listen);
|
||||||
pp = &((*pp)->lcd_listen);
|
|
||||||
*pp = lcp;
|
|
||||||
} else {
|
} else {
|
||||||
lcp->lcd_listen = pk_listenhead;
|
TAILQ_INSERT_HEAD(&pk_listenhead, lcp, lcd_listen);
|
||||||
pk_listenhead = lcp;
|
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pk_usrreq.c,v 1.11 1996/05/22 13:55:22 mycroft Exp $ */
|
/* $NetBSD: pk_usrreq.c,v 1.12 1996/05/23 23:35:27 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) University of British Columbia, 1984
|
* Copyright (c) University of British Columbia, 1984
|
||||||
|
@ -65,6 +65,31 @@
|
||||||
|
|
||||||
static void old_to_new __P((struct mbuf *));
|
static void old_to_new __P((struct mbuf *));
|
||||||
static void new_to_old __P((struct mbuf *));
|
static void new_to_old __P((struct mbuf *));
|
||||||
|
|
||||||
|
void
|
||||||
|
pk_setsockaddr(lcp, nam)
|
||||||
|
struct pklcd *lcp;
|
||||||
|
struct mbuf *nam;
|
||||||
|
{
|
||||||
|
|
||||||
|
nam->m_len = sizeof(struct sockaddr_x25);
|
||||||
|
bcopy(lcp->lcd_ceaddr, mtod(nam, caddr_t), (size_t)nam->m_len);
|
||||||
|
if (lcp->lcd_flags & X25_OLDSOCKADDR)
|
||||||
|
new_to_old(nam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pk_setpeeraddr(lcp, nam)
|
||||||
|
struct pklcd *lcp;
|
||||||
|
struct mbuf *nam;
|
||||||
|
{
|
||||||
|
|
||||||
|
nam->m_len = sizeof(struct sockaddr_x25);
|
||||||
|
bcopy(lcp->lcd_craddr, mtod(nam, caddr_t), (size_t)nam->m_len);
|
||||||
|
if (lcp->lcd_flags & X25_OLDSOCKADDR)
|
||||||
|
new_to_old(nam);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* X.25 Packet level protocol interface to socket abstraction.
|
* X.25 Packet level protocol interface to socket abstraction.
|
||||||
|
@ -82,35 +107,39 @@ pk_usrreq(so, req, m, nam, control, p)
|
||||||
struct mbuf *m, *nam, *control;
|
struct mbuf *m, *nam, *control;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
{
|
{
|
||||||
register struct pklcd *lcp = (struct pklcd *) so->so_pcb;
|
register struct pklcd *lcp;
|
||||||
register int error = 0;
|
int s;
|
||||||
|
register int error = 0;
|
||||||
|
|
||||||
if (req == PRU_CONTROL)
|
if (req == PRU_CONTROL)
|
||||||
return (pk_control(so, (long)m, (caddr_t)nam,
|
return (pk_control(so, (long)m, (caddr_t)nam,
|
||||||
(struct ifnet *)control, p));
|
(struct ifnet *)control, p));
|
||||||
if (control && control->m_len) {
|
|
||||||
error = EINVAL;
|
s = splsoftnet();
|
||||||
goto release;
|
lcp = (struct pklcd *)so->so_pcb;
|
||||||
}
|
#ifdef DIAGNOSTIC
|
||||||
if (lcp == NULL && req != PRU_ATTACH) {
|
if (req != PRU_SEND && req != PRU_SENDOOB && control)
|
||||||
|
panic("pk_usrreq: unexpected control mbuf");
|
||||||
|
#endif
|
||||||
|
if (lcp == 0 && req != PRU_ATTACH) {
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pk_trace (pkcbhead, TR_USER, (struct pklcd *)0,
|
pk_trace (pkcbhead, TR_USER, (struct pklcd *)0,
|
||||||
req, (struct x25_packet *)0);
|
req, (struct x25_packet *)0);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (req) {
|
switch (req) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* X.25 attaches to socket via PRU_ATTACH and allocates a
|
* X.25 attaches to socket via PRU_ATTACH and allocates a
|
||||||
* logical channel descriptor. If the socket is to receive
|
* logical channel descriptor. If the socket is to receive
|
||||||
* connections, then the LISTEN state is entered.
|
* connections, then the LISTEN state is entered.
|
||||||
*/
|
*/
|
||||||
case PRU_ATTACH:
|
case PRU_ATTACH:
|
||||||
if (lcp) {
|
if (lcp != 0) {
|
||||||
error = EISCONN;
|
error = EISCONN;
|
||||||
/* Socket already connected. */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lcp = pk_attach(so);
|
lcp = pk_attach(so);
|
||||||
|
@ -151,11 +180,17 @@ pk_usrreq(so, req, m, nam, control, p)
|
||||||
case PRU_CONNECT:
|
case PRU_CONNECT:
|
||||||
if (nam->m_len == sizeof(struct x25_sockaddr))
|
if (nam->m_len == sizeof(struct x25_sockaddr))
|
||||||
old_to_new(nam);
|
old_to_new(nam);
|
||||||
if (pk_checksockaddr(nam))
|
if (pk_checksockaddr(nam)) {
|
||||||
return (EINVAL);
|
error = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
error = pk_connect(lcp, mtod(nam, struct sockaddr_x25 *));
|
error = pk_connect(lcp, mtod(nam, struct sockaddr_x25 *));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PRU_CONNECT2:
|
||||||
|
error = EOPNOTSUPP;
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initiate a disconnect to peer entity via a CLEAR REQUEST
|
* Initiate a disconnect to peer entity via a CLEAR REQUEST
|
||||||
* packet. The socket will be disconnected when we receive a
|
* packet. The socket will be disconnected when we receive a
|
||||||
|
@ -173,11 +208,11 @@ pk_usrreq(so, req, m, nam, control, p)
|
||||||
case PRU_ACCEPT:
|
case PRU_ACCEPT:
|
||||||
if (lcp->lcd_craddr == NULL)
|
if (lcp->lcd_craddr == NULL)
|
||||||
break;
|
break;
|
||||||
bcopy((caddr_t) lcp->lcd_craddr, mtod(nam, caddr_t),
|
pk_setpeeraddr(lcp, nam);
|
||||||
sizeof(struct sockaddr_x25));
|
break;
|
||||||
nam->m_len = sizeof(struct sockaddr_x25);
|
|
||||||
if (lcp->lcd_flags & X25_OLDSOCKADDR)
|
case PRU_SHUTDOWN:
|
||||||
new_to_old(nam);
|
socantsendmore(so);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -187,23 +222,6 @@ pk_usrreq(so, req, m, nam, control, p)
|
||||||
pk_flowcontrol(lcp, /* sbspace (&so -> so_rcv) <= */ 0, 1);
|
pk_flowcontrol(lcp, /* sbspace (&so -> so_rcv) <= */ 0, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
|
||||||
* Send INTERRUPT packet.
|
|
||||||
*/
|
|
||||||
case PRU_SENDOOB:
|
|
||||||
if (m == 0) {
|
|
||||||
MGETHDR(m, M_WAITOK, MT_OOBDATA);
|
|
||||||
m->m_pkthdr.len = m->m_len = 1;
|
|
||||||
*mtod(m, octet *) = 0;
|
|
||||||
}
|
|
||||||
if (m->m_pkthdr.len > 32) {
|
|
||||||
m_freem(m);
|
|
||||||
error = EMSGSIZE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MCHTYPE(m, MT_OOBDATA);
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do send by placing data on the socket output queue.
|
* Do send by placing data on the socket output queue.
|
||||||
*/
|
*/
|
||||||
|
@ -214,8 +232,10 @@ pk_usrreq(so, req, m, nam, control, p)
|
||||||
control->m_data += sizeof(*ch);
|
control->m_data += sizeof(*ch);
|
||||||
error = pk_ctloutput(PRCO_SETOPT, so, ch->cmsg_level,
|
error = pk_ctloutput(PRCO_SETOPT, so, ch->cmsg_level,
|
||||||
ch->cmsg_type, &control);
|
ch->cmsg_type, &control);
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (error == 0 && m)
|
if (m)
|
||||||
error = pk_send(m, lcp);
|
error = pk_send(m, lcp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -227,46 +247,12 @@ pk_usrreq(so, req, m, nam, control, p)
|
||||||
pk_disconnect(lcp);
|
pk_disconnect(lcp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Begin unimplemented hooks. */
|
|
||||||
|
|
||||||
case PRU_SHUTDOWN:
|
|
||||||
error = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_CONTROL:
|
|
||||||
error = EOPNOTSUPP;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_SENSE:
|
case PRU_SENSE:
|
||||||
#ifdef BSD4_3
|
/*
|
||||||
((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
|
* stat: don't bother with a blocksize.
|
||||||
#else
|
*/
|
||||||
error = EOPNOTSUPP;
|
splx(s);
|
||||||
#endif
|
return (0);
|
||||||
break;
|
|
||||||
|
|
||||||
/* End unimplemented hooks. */
|
|
||||||
|
|
||||||
case PRU_SOCKADDR:
|
|
||||||
if (lcp->lcd_ceaddr == 0)
|
|
||||||
return (EADDRNOTAVAIL);
|
|
||||||
nam->m_len = sizeof(struct sockaddr_x25);
|
|
||||||
bcopy((caddr_t) lcp->lcd_ceaddr, mtod(nam, caddr_t),
|
|
||||||
sizeof(struct sockaddr_x25));
|
|
||||||
if (lcp->lcd_flags & X25_OLDSOCKADDR)
|
|
||||||
new_to_old(nam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PRU_PEERADDR:
|
|
||||||
if (lcp->lcd_state != DATA_TRANSFER)
|
|
||||||
return (ENOTCONN);
|
|
||||||
nam->m_len = sizeof(struct sockaddr_x25);
|
|
||||||
bcopy(lcp->lcd_craddr ? (caddr_t) lcp->lcd_craddr :
|
|
||||||
(caddr_t) lcp->lcd_ceaddr,
|
|
||||||
mtod(nam, caddr_t), sizeof(struct sockaddr_x25));
|
|
||||||
if (lcp->lcd_flags & X25_OLDSOCKADDR)
|
|
||||||
new_to_old(nam);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive INTERRUPT packet.
|
* Receive INTERRUPT packet.
|
||||||
|
@ -290,12 +276,47 @@ pk_usrreq(so, req, m, nam, control, p)
|
||||||
*mtod(m, char *) = lcp->lcd_intrdata;
|
*mtod(m, char *) = lcp->lcd_intrdata;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send INTERRUPT packet.
|
||||||
|
*/
|
||||||
|
case PRU_SENDOOB:
|
||||||
|
if (control) {
|
||||||
|
register struct cmsghdr *ch = mtod(m, struct cmsghdr *);
|
||||||
|
control->m_len -= sizeof(*ch);
|
||||||
|
control->m_data += sizeof(*ch);
|
||||||
|
error = pk_ctloutput(PRCO_SETOPT, so, ch->cmsg_level,
|
||||||
|
ch->cmsg_type, &control);
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m) {
|
||||||
|
MCHTYPE(m, MT_OOBDATA);
|
||||||
|
error = pk_send(m, lcp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PRU_SOCKADDR:
|
||||||
|
if (lcp->lcd_ceaddr == 0) {
|
||||||
|
error = EADDRNOTAVAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pk_setsockaddr(lcp, nam);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PRU_PEERADDR:
|
||||||
|
if (lcp->lcd_state != DATA_TRANSFER) {
|
||||||
|
error = ENOTCONN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pk_setpeeraddr(lcp, nam);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("pk_usrreq");
|
panic("pk_usrreq");
|
||||||
}
|
}
|
||||||
|
|
||||||
release:
|
release:
|
||||||
if (control != NULL)
|
splx(s);
|
||||||
m_freem(control);
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pk_var.h,v 1.8 1996/02/13 22:05:47 christos Exp $ */
|
/* $NetBSD: pk_var.h,v 1.9 1996/05/23 23:35:29 mycroft Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Computing Centre, University of British Columbia, 1985
|
* Copyright (c) Computing Centre, University of British Columbia, 1985
|
||||||
|
@ -89,7 +89,7 @@ struct pklcd {
|
||||||
long lcd_txcnt; /* Data packet transmit count */
|
long lcd_txcnt; /* Data packet transmit count */
|
||||||
long lcd_rxcnt; /* Data packet receive count */
|
long lcd_rxcnt; /* Data packet receive count */
|
||||||
short lcd_intrcnt; /* Interrupt packet transmit count */
|
short lcd_intrcnt; /* Interrupt packet transmit count */
|
||||||
struct pklcd *lcd_listen; /* Next lcd on listen queue */
|
TAILQ_ENTRY(pklcd) lcd_listen; /* Next lcd on listen queue */
|
||||||
struct pkcb *lcd_pkp; /* Network this lcd is attached to */
|
struct pkcb *lcd_pkp; /* Network this lcd is attached to */
|
||||||
struct mbuf *lcd_cps; /* Complete Packet Sequence reassembly*/
|
struct mbuf *lcd_cps; /* Complete Packet Sequence reassembly*/
|
||||||
long lcd_cpsmax; /* Max length for CPS */
|
long lcd_cpsmax; /* Max length for CPS */
|
||||||
|
@ -228,8 +228,10 @@ struct mbuf_cache {
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(_KERNEL) && defined(CCITT)
|
#if defined(_KERNEL) && defined(CCITT)
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
extern struct pkcb_q pkcb_q;
|
extern struct pkcb_q pkcb_q;
|
||||||
struct pklcd *pk_listenhead;
|
TAILQ_HEAD(, pklcd) pk_listenhead;
|
||||||
|
|
||||||
extern char *pk_name[], *pk_state[];
|
extern char *pk_name[], *pk_state[];
|
||||||
int pk_t20, pk_t21, pk_t22, pk_t23;
|
int pk_t20, pk_t21, pk_t22, pk_t23;
|
||||||
|
|
Loading…
Reference in New Issue