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 * 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);

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 * 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))

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 * 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);
} }

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 * 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);
} }

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 * 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;