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:
mycroft 1996-05-23 23:35:22 +00:00
parent f7f3f4299d
commit 4e8477f520
5 changed files with 114 additions and 102 deletions

View File

@ -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
@ -698,10 +698,8 @@ int x25_startproto = 1;
void
pk_init()
{
/*
* warning, sizeof (struct sockaddr_x25) > 32,
* but contains no data of interest beyond 32
*/
TAILQ_INIT(&pk_listenhead);
if (x25_startproto) {
pk_protolisten(0xcc, 1, x25_dgram_incoming);
pk_protolisten(0x81, 1, x25_dgram_incoming);
@ -736,7 +734,7 @@ pk_user_protolisten(info)
gotspi:if (info[1])
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 &&
Bcmp(&dp->spi, lcp->lcd_laddr.x25_udata, dp->spilen) == 0) {
pk_disconnect(lcp);

View File

@ -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
@ -967,7 +967,7 @@ pk_incoming_call(pkp, m0)
* 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;
if (bcmp(sxp->x25_udata, u, sxp->x25_udlen))

View File

@ -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
@ -130,16 +130,10 @@ pk_disconnect(lcp)
register struct pklcd *lcp;
{
register struct socket *so = lcp->lcd_so;
register struct pklcd *l, *p;
switch (lcp->lcd_state) {
case LISTEN:
for (p = 0, l = pk_listenhead; l && l != lcp; p = l, l = l->lcd_listen);
if (p == 0) {
if (l != 0)
pk_listenhead = l->lcd_listen;
} else if (l != 0)
p->lcd_listen = l->lcd_listen;
TAILQ_REMOVE(&pk_listenhead, lcp, lcd_listen);
pk_close(lcp);
break;
@ -376,7 +370,7 @@ pk_bind(lcp, nam)
/*
* 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;
if ((sa2->x25_udlen == sa->x25_udlen) &&
(sa2->x25_udlen == 0 ||
@ -406,12 +400,9 @@ pk_listen(lcp)
* Add default listener at end, any others at start.
*/
if (lcp->lcd_ceaddr->x25_udlen == 0) {
for (pp = &pk_listenhead; *pp;)
pp = &((*pp)->lcd_listen);
*pp = lcp;
TAILQ_INSERT_TAIL(&pk_listenhead, lcp, lcd_listen);
} else {
lcp->lcd_listen = pk_listenhead;
pk_listenhead = lcp;
TAILQ_INSERT_HEAD(&pk_listenhead, lcp, lcd_listen);
}
return (0);
}

View File

@ -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
@ -65,6 +65,31 @@
static void old_to_new __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.
@ -82,35 +107,39 @@ pk_usrreq(so, req, m, nam, control, p)
struct mbuf *m, *nam, *control;
struct proc *p;
{
register struct pklcd *lcp = (struct pklcd *) so->so_pcb;
register int error = 0;
register struct pklcd *lcp;
int s;
register int error = 0;
if (req == PRU_CONTROL)
return (pk_control(so, (long)m, (caddr_t)nam,
(struct ifnet *)control, p));
if (control && control->m_len) {
error = EINVAL;
goto release;
}
if (lcp == NULL && req != PRU_ATTACH) {
s = splsoftnet();
lcp = (struct pklcd *)so->so_pcb;
#ifdef DIAGNOSTIC
if (req != PRU_SEND && req != PRU_SENDOOB && control)
panic("pk_usrreq: unexpected control mbuf");
#endif
if (lcp == 0 && req != PRU_ATTACH) {
error = EINVAL;
goto release;
}
/*
pk_trace (pkcbhead, TR_USER, (struct pklcd *)0,
req, (struct x25_packet *)0);
*/
switch (req) {
/*
* X.25 attaches to socket via PRU_ATTACH and allocates a
* logical channel descriptor. If the socket is to receive
* connections, then the LISTEN state is entered.
*/
case PRU_ATTACH:
if (lcp) {
if (lcp != 0) {
error = EISCONN;
/* Socket already connected. */
break;
}
lcp = pk_attach(so);
@ -151,11 +180,17 @@ pk_usrreq(so, req, m, nam, control, p)
case PRU_CONNECT:
if (nam->m_len == sizeof(struct x25_sockaddr))
old_to_new(nam);
if (pk_checksockaddr(nam))
return (EINVAL);
if (pk_checksockaddr(nam)) {
error = EINVAL;
break;
}
error = pk_connect(lcp, mtod(nam, struct sockaddr_x25 *));
break;
case PRU_CONNECT2:
error = EOPNOTSUPP;
break;
/*
* Initiate a disconnect to peer entity via a CLEAR REQUEST
* 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:
if (lcp->lcd_craddr == NULL)
break;
bcopy((caddr_t) lcp->lcd_craddr, mtod(nam, caddr_t),
sizeof(struct sockaddr_x25));
nam->m_len = sizeof(struct sockaddr_x25);
if (lcp->lcd_flags & X25_OLDSOCKADDR)
new_to_old(nam);
pk_setpeeraddr(lcp, nam);
break;
case PRU_SHUTDOWN:
socantsendmore(so);
break;
/*
@ -187,23 +222,6 @@ pk_usrreq(so, req, m, nam, control, p)
pk_flowcontrol(lcp, /* sbspace (&so -> so_rcv) <= */ 0, 1);
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.
*/
@ -214,8 +232,10 @@ pk_usrreq(so, req, m, nam, control, p)
control->m_data += sizeof(*ch);
error = pk_ctloutput(PRCO_SETOPT, so, ch->cmsg_level,
ch->cmsg_type, &control);
if (error)
break;
}
if (error == 0 && m)
if (m)
error = pk_send(m, lcp);
break;
@ -227,46 +247,12 @@ pk_usrreq(so, req, m, nam, control, p)
pk_disconnect(lcp);
break;
/* Begin unimplemented hooks. */
case PRU_SHUTDOWN:
error = EOPNOTSUPP;
break;
case PRU_CONTROL:
error = EOPNOTSUPP;
break;
case PRU_SENSE:
#ifdef BSD4_3
((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
#else
error = EOPNOTSUPP;
#endif
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;
/*
* stat: don't bother with a blocksize.
*/
splx(s);
return (0);
/*
* Receive INTERRUPT packet.
@ -290,12 +276,47 @@ pk_usrreq(so, req, m, nam, control, p)
*mtod(m, char *) = lcp->lcd_intrdata;
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:
panic("pk_usrreq");
}
release:
if (control != NULL)
m_freem(control);
splx(s);
return (error);
}

View File

@ -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
@ -89,7 +89,7 @@ struct pklcd {
long lcd_txcnt; /* Data packet transmit count */
long lcd_rxcnt; /* Data packet receive 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 mbuf *lcd_cps; /* Complete Packet Sequence reassembly*/
long lcd_cpsmax; /* Max length for CPS */
@ -228,8 +228,10 @@ struct mbuf_cache {
};
#if defined(_KERNEL) && defined(CCITT)
#include <sys/queue.h>
extern struct pkcb_q pkcb_q;
struct pklcd *pk_listenhead;
TAILQ_HEAD(, pklcd) pk_listenhead;
extern char *pk_name[], *pk_state[];
int pk_t20, pk_t21, pk_t22, pk_t23;