SCCS-vsn: sys/netns/spp_usrreq.c 6.13
SCCS-vsn: sys/netns/spp_usrreq.c 6.13
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
- * @(#)spp_usrreq.c 6.12 (Berkeley) %G%
+ * @(#)spp_usrreq.c 6.13 (Berkeley) %G%
int traceallspps = 0;
extern int sppconsdebug;
int spp_hardnosed;
int traceallspps = 0;
extern int sppconsdebug;
int spp_hardnosed;
/*ARGSUSED*/
spp_input(m, nsp, ifp)
/*ARGSUSED*/
spp_input(m, nsp, ifp)
m->m_len -= sizeof (struct idp);
m->m_off += sizeof (struct idp);
m->m_len -= sizeof (struct idp);
m->m_off += sizeof (struct idp);
- if (spp_reass(cb,si)) {
+ if (spp_reass(cb, si)) {
- (void) spp_output(cb,(struct mbuf *)0);
+ (void) spp_output(cb, (struct mbuf *)0);
* but its function is somewhat different: It merely queues
* packets up, and suppresses duplicates.
*/
* but its function is somewhat different: It merely queues
* packets up, and suppresses duplicates.
*/
register struct sppcb *cb;
register struct spidp *si;
{
register struct sppcb *cb;
register struct spidp *si;
{
* Update our news from them.
*/
if (si->si_cc & SP_SA)
* Update our news from them.
*/
if (si->si_cc & SP_SA)
- cb->s_flags |= SF_DELACK;
- if (SSEQ_GT(si->si_ack,cb->s_rack)) {
+ cb->s_flags |= (spp_use_delack ? SF_DELACK : SF_AK);
+ if (SSEQ_GT(si->si_ack, cb->s_rack)) {
- cb->s_timer[TCPT_REXMT] = 0;
-
+ /*
+ * If there are other packets outstanding,
+ * restart the timer for them.
+ */
+ if (SSEQ_GEQ(cb->s_snt, si->si_ack)) {
+ TCPT_RANGESET(cb->s_timer[TCPT_REXMT],
+ tcp_beta * cb->s_srtt, TCPTV_MIN,
+ TCPTV_MAX);
+ cb->s_rxtshift = 0;
+ } else
+ cb->s_timer[TCPT_REXMT] = 0;
/*
* If transmit timer is running and timed sequence
* number was acked, update smoothed round trip time.
/*
* If transmit timer is running and timed sequence
* number was acked, update smoothed round trip time.
- if (SSEQ_GT(si->si_alo,cb->s_ralo)) {
+ if (SSEQ_GT(si->si_alo, cb->s_ralo)) {
cb->s_ralo = si->si_alo;
cb->s_timer[TCPT_PERSIST] = 0;
}
cb->s_ralo = si->si_alo;
cb->s_timer[TCPT_PERSIST] = 0;
}
* than that of the first packet not yet seen coming
* from them, this must be a duplicate, so drop.
*/
* than that of the first packet not yet seen coming
* from them, this must be a duplicate, so drop.
*/
- if (SSEQ_LT(si->si_seq,cb->s_ack)) {
+ if (SSEQ_LT(si->si_seq, cb->s_ack)) {
spp_istat.bdreas++;
if (si->si_seq == cb->s_ack-1)
spp_istat.lstdup++;
spp_istat.bdreas++;
if (si->si_seq == cb->s_ack-1)
spp_istat.lstdup++;
* If this packet number is higher than that which
* we have allocated refuse it, unless urgent
*/
* If this packet number is higher than that which
* we have allocated refuse it, unless urgent
*/
- if (SSEQ_GT(si->si_seq,cb->s_alo) && (!(si->si_cc & SP_OB))) {
- spp_istat.notyet++;
- return (1);
- }
- /*
- * If this packet is urgent, inform process
- */
- if (si->si_cc & SP_OB) {
- cb->s_iobc = ((char *)si)[1 + sizeof(*si)];
- sohasoutofband(so);
+ if (SSEQ_GT(si->si_seq, cb->s_alo)) {
+ if (si->si_cc & SP_OB) {
+ if (SSEQ_GT(si->si_seq, cb->s_alo + 60)) {
+ ns_error(dtom(si), NS_ERR_FULLUP, 0);
+ return (0);
+ } /* else queue this packet; */
+ } else {
+ spp_istat.notyet++;
+ return (1);
+ }
for (q = cb->s_q.si_next; q!=&cb->s_q; q = q->si_next) {
if (si->si_seq == SI(q)->si_seq) return (1); /*duplicate */
for (q = cb->s_q.si_next; q!=&cb->s_q; q = q->si_next) {
if (si->si_seq == SI(q)->si_seq) return (1); /*duplicate */
- if (SSEQ_LT(si->si_seq,SI(q)->si_seq)) break;
+ if (SSEQ_LT(si->si_seq, SI(q)->si_seq)) break;
+ }
+ insque(si, q->si_prev);
+ /*
+ * If this packet is urgent, inform process
+ */
+ if (si->si_cc & SP_OB) {
+ cb->s_iobc = ((char *)si)[1 + sizeof(*si)];
+ sohasoutofband(so);
+ cb->s_oobflags |= SF_IOOB;
- insque(si,q->si_prev);
-
present:
#define SPINC sizeof(struct sphdr)
/*
present:
#define SPINC sizeof(struct sphdr)
/*
cb->s_ack++;
m = dtom(q);
if (SI(q)->si_cc & SP_OB) {
cb->s_ack++;
m = dtom(q);
if (SI(q)->si_cc & SP_OB) {
+ cb->s_oobflags &= ~SF_IOOB;
if (sb->sb_cc)
so->so_oobmark = sb->sb_cc;
else
if (sb->sb_cc)
so->so_oobmark = sb->sb_cc;
else
remque(q->si_next);
wakeup = 1;
if (packetp) {
remque(q->si_next);
wakeup = 1;
if (packetp) {
} else {
cb->s_rhdr = *mtod(m, struct sphdr *);
m->m_off += SPINC;
m->m_len -= SPINC;
} else {
cb->s_rhdr = *mtod(m, struct sphdr *);
m->m_off += SPINC;
m->m_len -= SPINC;
/*
* queue stuff up for output
*/
/*
* queue stuff up for output
*/
si->si_seq = cb->s_snt + 1;
si->si_len = htons(sizeof (*si));
si->si_cc |= SP_SP;
si->si_seq = cb->s_snt + 1;
si->si_len = htons(sizeof (*si));
si->si_cc |= SP_SP;
}
/*
* Stuff checksum and output datagram.
*/
if (si) {
}
/*
* Stuff checksum and output datagram.
*/
if (si) {
+ if (cb->s_flags & (SF_AK|SF_DELACK))
+ cb->s_flags &= ~(SF_AK|SF_DELACK);
/*
* If we are almost out of allocation
* or one of the timers has gone off
/*
* If we are almost out of allocation
* or one of the timers has gone off
break;
nsp = sotonspcb(so);
{
break;
nsp = sotonspcb(so);
{
- struct mbuf *mm = m_getclr(M_DONTWAIT,MT_PCB);
+ struct mbuf *mm = m_getclr(M_DONTWAIT, MT_PCB);
if (mm == NULL) {
error = ENOBUFS;
if (mm == NULL) {
error = ENOBUFS;
- if (so->so_oobmark == 0 &&
- (so->so_state & SS_RCVATMARK) == 0) {
- error = EINVAL;
+ if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark ||
+ (so->so_state & SS_RCVATMARK)) {
+ m->m_len = 1;
+ *mtod(m, caddr_t) = cb->s_iobc;
- if ( ! (cb->s_oobflags & SF_IOOB) ) {
- error = EWOULDBLOCK;
- break;
- }
- m->m_len = 1;
- *mtod(m, caddr_t) = cb->s_iobc;
- if (((int)nam & MSG_PEEK) == 0)
- cb->s_oobflags &= ~ SF_IOOB;
cb->s_oobflags |= SF_SOOB;
error = spp_output(cb, m);
m = NULL;
cb->s_oobflags |= SF_SOOB;
error = spp_output(cb, m);
m = NULL;
- cb->s_oobflags &= ~SF_SOOB;
break;
case PRU_SOCKADDR:
break;
case PRU_SOCKADDR: