Ejemplo n.º 1
0
Archivo: rudp.c Proyecto: Shamar/harvey
void
rudpadvise(Proto *rudp, Block *bp, char *msg)
{
	Udphdr *h;
	uint8_t source[IPaddrlen], dest[IPaddrlen];
	uint16_t psource, pdest;
	Conv *s, **p;

	h = (Udphdr*)(bp->rp);

	v4tov6(dest, h->udpdst);
	v4tov6(source, h->udpsrc);
	psource = nhgets(h->udpsport);
	pdest = nhgets(h->udpdport);

	/* Look for a connection */
	for(p = rudp->conv; *p; p++) {
		s = *p;
		if(s->rport == pdest)
		if(s->lport == psource)
		if(ipcmp(s->raddr, dest) == 0)
		if(ipcmp(s->laddr, source) == 0){
			qhangup(s->rq, msg);
			qhangup(s->wq, msg);
			break;
		}
	}
	freeblist(bp);
}
Ejemplo n.º 2
0
/*
 *  we save up input characters till clock time to reduce
 *  per character interrupt overhead.
 */
static void
uartclock(void)
{
	Uart *p;

	ilock(&uartalloc);
	for(p = uartalloc.elist; p; p = p->elist){

		/* this hopefully amortizes cost of qproduce to many chars */
		if(p->iw != p->ir){
			ilock(&p->rlock);
			uartstageinput(p);
			iunlock(&p->rlock);
		}

		/* hang up if requested */
		if(p->dohup){
			qhangup(p->iq, 0);
			qhangup(p->oq, 0);
			p->dohup = 0;
		}

		/* this adds hysteresis to hardware/software flow control */
		if(p->ctsbackoff){
			ilock(&p->tlock);
			if(p->ctsbackoff){
				if(--(p->ctsbackoff) == 0)
					(*p->phys->kick)(p);
			}
			iunlock(&p->tlock);
		}
		uartkick(p);		/* keep it moving */
	}
	iunlock(&uartalloc);
}
Ejemplo n.º 3
0
void
udpadvise(Proto *udp, Block *bp, char *msg)
{
	Udp4hdr *h4;
	Udp6hdr *h6;
	uchar source[IPaddrlen], dest[IPaddrlen];
	ushort psource, pdest;
	Conv *s, **p;
	int version;

	h4 = (Udp4hdr*)(bp->rp);
	version = ((h4->vihl&0xF0)==IP_VER6) ? 6 : 4;

	switch(version) {
	case V4:
		v4tov6(dest, h4->udpdst);
		v4tov6(source, h4->udpsrc);
		psource = nhgets(h4->udpsport);
		pdest = nhgets(h4->udpdport);
		break;
	case V6:
		h6 = (Udp6hdr*)(bp->rp);
		ipmove(dest, h6->udpdst);
		ipmove(source, h6->udpsrc);
		psource = nhgets(h6->udpsport);
		pdest = nhgets(h6->udpdport);
		break;
	default:
		panic("udpadvise: version %d", version);
		return;	/* to avoid a warning */
	}

	/* Look for a connection */
	qlock(udp);
	for(p = udp->conv; *p; p++) {
		s = *p;
		if(s->rport == pdest)
		if(s->lport == psource)
		if(ipcmp(s->raddr, dest) == 0)
		if(ipcmp(s->laddr, source) == 0){
			if(s->ignoreadvice)
				break;
			qlock(s);
			qunlock(udp);
			qhangup(s->rq, msg);
			qhangup(s->wq, msg);
			qunlock(s);
			freeblist(bp);
			return;
		}
	}
	qunlock(udp);
	freeblist(bp);
}
Ejemplo n.º 4
0
Archivo: esp.c Proyecto: npe9/harvey
static char*
espconnect(Conv *c, char **argv, int argc)
{
	char *p, *pp, *e = nil;
	uint32_t spi;
	Espcb *ecb = (Espcb*)c->ptcl;

	switch(argc) {
	default:
		e = "bad args to connect";
		break;
	case 2:
		p = strchr(argv[1], '!');
		if(p == nil){
			e = "malformed address";
			break;
		}
		*p++ = 0;
		if (parseip(c->raddr, argv[1]) == -1) {
			e = Ebadip;
			break;
		}
		findlocalip(c->p->f, c->laddr, c->raddr);
		ecb->incoming = 0;
		ecb->seq = 0;
		if(strcmp(p, "*") == 0) {
			qlock(c->p);
			for(;;) {
				spi = nrand(1<<16) + 256;
				if(convlookup(c->p, spi) == nil)
					break;
			}
			qunlock(c->p);
			ecb->spi = spi;
			ecb->incoming = 1;
			qhangup(c->wq, nil);
		} else {
			spi = strtoul(p, &pp, 10);
			if(pp == p) {
				e = "malformed address";
				break;
			}
			ecb->spi = spi;
			qhangup(c->rq, nil);
		}
		nullespinit(ecb, "null", nil, 0);
		nullahinit(ecb, "null", nil, 0);
	}
	Fsconnected(c, e);

	return e;
}
Ejemplo n.º 5
0
static void
pipeclose(Chan *c)
{
	Pipe *p;

	p = c->aux;
	qlock(p);

	if(c->flag & COPEN){
		/*
		 *  closing either side hangs up the stream
		 */
		switch(NETTYPE(c->qid.path)){
		case Qdata0:
			p->qref[0]--;
			if(p->qref[0] == 0){
				qhangup(p->q[1], 0);
				qclose(p->q[0]);
			}
			break;
		case Qdata1:
			p->qref[1]--;
			if(p->qref[1] == 0){
				qhangup(p->q[0], 0);
				qclose(p->q[1]);
			}
			break;
		}
	}


	/*
	 *  if both sides are closed, they are reusable
	 */
	if(p->qref[0] == 0 && p->qref[1] == 0){
		qreopen(p->q[0]);
		qreopen(p->q[1]);
	}

	/*
	 *  free the structure on last close
	 */
	p->ref--;
	if(p->ref == 0){
		qunlock(p);
		free(p->q[0]);
		free(p->q[1]);
		free(p);
	} else
		qunlock(p);
}
Ejemplo n.º 6
0
static void
uartclose(Chan *c)
{
	Uart *p;

	if(c->qid.type & QTDIR)
		return;
	if((c->flag & COPEN) == 0)
		return;
	switch(NETTYPE(c->qid.path)){
	case Ndataqid:
	case Nctlqid:
		p = uart[NETID(c->qid.path)];
		qlock(p);
		if(--(p->opens) == 0){
			qclose(p->iq);
			ilock(&p->rlock);
			p->ir = p->iw = p->istage;
			iunlock(&p->rlock);

			/*
			 */
			qhangup(p->oq, nil);
			if(!waserror()){
				uartdrainoutput(p);
				poperror();
			}
			qclose(p->oq);
			uartdisable(p);
			p->dcd = p->dsr = p->dohup = 0;
		}
		qunlock(p);
		break;
	}
}
Ejemplo n.º 7
0
Archivo: esp.c Proyecto: npe9/harvey
/* called from icmp(v6) for unreachable hosts, time exceeded, etc. */
void
espadvise(Proto *esp, Block *bp, char *msg)
{
	Conv *c;
	Versdep vers;

	getverslens(pktipvers(esp->f, &bp), &vers);
	getpktspiaddrs(bp->rp, &vers);

	qlock(esp);
	c = convlookup(esp, vers.spi);
	if(c != nil) {
		qhangup(c->rq, msg);
		qhangup(c->wq, msg);
	}
	qunlock(esp);
	freeblist(bp);
}
Ejemplo n.º 8
0
Archivo: esp.c Proyecto: 8l/inferno
void
espadvise(Proto *esp, Block *bp, char *msg)
{
	Esphdr *h;
	Conv *c;
	ulong spi;

	h = (Esphdr*)(bp->rp);

	spi = nhgets(h->espspi);
	qlock(esp);
	c = convlookup(esp, spi);
	if(c != nil) {
		qhangup(c->rq, msg);
		qhangup(c->wq, msg);
	}
	qunlock(esp);
	freeblist(bp);
}
Ejemplo n.º 9
0
static void
consclose(Chan *c)
{
	switch((ulong)c->qid.path){
	/* close of kprint allows other opens */
	case Qkprint:
		if(c->flag & COPEN){
			kprintinuse = 0;
			qhangup(kprintoq, nil);
		}
		break;
	}
}
Ejemplo n.º 10
0
static void consclose(struct chan *c)
{
    switch ((uint32_t) c->qid.path) {
    /* last close of control file turns off raw */
    case Qconsctl:
        if (c->flag & COPEN) {
            if (kref_put(&kbd.ctl) == 0)
                kbd.raw = 0;
        }
        break;

    /* close of kprint allows other opens */
    case Qkprint:
        if (c->flag & COPEN) {
            kprintinuse = 0;
            qhangup(kprintoq, NULL);
        }
        break;
    }
}
Ejemplo n.º 11
0
static void
consclose(Chan *c)
{
	switch((ulong)c->qid.path){
	/* last close of control file turns off raw */
	case Qconsctl:
		if(c->flag&COPEN){
			if(decref(&kbd.ctl) == 0)
				kbd.raw = 0;
		}
		break;

	/* close of kprint allows other opens */
	case Qkprint:
		if(c->flag & COPEN){
			kprintinuse = 0;
			qhangup(kprintoq, nil);
		}
		break;
	}
}
Ejemplo n.º 12
0
static void
loopbackclose(Chan *c)
{
	Loop *lb;
	int ref, chan;

	lb = c->aux;

	qlock(lb);

	/*
	 * closing either side hangs up the stream
	 */
	if((c->flag & COPEN) && TYPE(c->qid.path) == Qdata){
		chan = ID(c->qid.path);
		if(--lb->link[chan].ref == 0){
			qhangup(lb->link[chan ^ 1].oq, nil);
			looper(lb);
		}
	}


	/*
	 *  if both sides are closed, they are reusable
	 */
	if(lb->link[0].ref == 0 && lb->link[1].ref == 0){
		for(chan = 0; chan < 2; chan++){
			closelink(&lb->link[chan], 0);
			qreopen(lb->link[chan].iq);
			qreopen(lb->link[chan].oq);
			qsetlimit(lb->link[chan].oq, lb->link[chan].limit);
			qsetlimit(lb->link[chan].iq, lb->link[chan].limit);
		}
	}
	ref = --lb->ref;
	if(ref == 0)
		freelb(lb);
	qunlock(lb);
}
Ejemplo n.º 13
0
/*
 * move blocks between queues if they are ready.
 * schedule an interrupt for the next interesting time.
 *
 * must be called with the link ilocked.
 */
static void
pushlink(Link *link, vlong now)
{
	Block *bp;
	vlong tout, tin;

	/*
	 * put another block in the link queue
	 */
	ilock(link);
	if(link->iq == nil || link->oq == nil){
		iunlock(link);
		return;

	}
	timerdel(&link->ci);

	/*
	 * put more blocks into the xmit queue
	 * use the time the last packet was supposed to go out
	 * as the start time for the next packet, rather than
	 * the current time.  this more closely models a network
	 * device which can queue multiple output packets.
	 */
	tout = link->tout;
	if(!tout)
		tout = now;
	while(tout <= now){
		bp = qget(link->oq);
		if(bp == nil){
			tout = 0;
			break;
		}

		/*
		 * can't send the packet before it gets queued
		 */
		tin = gtime(bp->rp);
		if(tin > tout)
			tout = tin;
		tout = tout + (BLEN(bp) - Tmsize) * link->delayn;

		/*
		 * drop packets
		 */
		if(link->droprate && nrand(link->droprate) == 0)
			link->drops++;
		else{
			ptime(bp->rp, tout + link->delay0ns);
			if(link->tq == nil)
				link->tq = bp;
			else
				link->tqtail->next = bp;
			link->tqtail = bp;
		}
	}

	/*
	 * record the next time a packet can be sent,
	 * but don't schedule an interrupt if none is waiting
	 */
	link->tout = tout;
	if(!qcanread(link->oq))
		tout = 0;

	/*
	 * put more blocks into the receive queue
	 */
	tin = 0;
	while(bp = link->tq){
		tin = gtime(bp->rp);
		if(tin > now)
			break;
		bp->rp += Tmsize;
		link->tq = bp->next;
		bp->next = nil;
		if(!link->indrop)
			qpassnolim(link->iq, bp);
		else if(qpass(link->iq, bp) < 0)
			link->soverflows++;
		tin = 0;
	}
	if(bp == nil && qisclosed(link->oq) && !qcanread(link->oq) && !qisclosed(link->iq))
		qhangup(link->iq, nil);
	link->tin = tin;
	if(!tin || tin > tout && tout)
		tin = tout;

	link->ci.ns = tin - now;
	if(tin){
		if(tin < now)
			panic("loopback unfinished business");
		timeradd(&link->ci);
	}
	iunlock(link);
}
Ejemplo n.º 14
0
int
uartctl(Uart *p, char *cmd)
{
	char *f[16];
	int i, n, nf;

	nf = tokenize(cmd, f, nelem(f));
	for(i = 0; i < nf; i++){
		if(strncmp(f[i], "break", 5) == 0){
			(*p->phys->dobreak)(p, 0);
			continue;
		}

		n = atoi(f[i]+1);
		switch(*f[i]){
		case 'B':
		case 'b':
			uartdrainoutput(p);
			if((*p->phys->baud)(p, n) < 0)
				return -1;
			break;
		case 'C':
		case 'c':
			p->hup_dcd = n;
			break;
		case 'D':
		case 'd':
			uartdrainoutput(p);
			(*p->phys->dtr)(p, n);
			break;
		case 'E':
		case 'e':
			p->hup_dsr = n;
			break;
		case 'F':
		case 'f':
			if(p->oq != nil)
				qflush(p->oq);
			break;
		case 'H':
		case 'h':
			if(p->iq != nil)
				qhangup(p->iq, 0);
			if(p->oq != nil)
				qhangup(p->oq, 0);
			break;
		case 'I':
		case 'i':
			uartdrainoutput(p);
			(*p->phys->fifo)(p, n);
			break;
		case 'K':
		case 'k':
			uartdrainoutput(p);
			(*p->phys->dobreak)(p, n);
			break;
		case 'L':
		case 'l':
			uartdrainoutput(p);
			if((*p->phys->bits)(p, n) < 0)
				return -1;
			break;
		case 'M':
		case 'm':
			uartdrainoutput(p);
			(*p->phys->modemctl)(p, n);
			break;
		case 'N':
		case 'n':
			if(p->oq != nil)
				qnoblock(p->oq, n);
			break;
		case 'P':
		case 'p':
			uartdrainoutput(p);
			if((*p->phys->parity)(p, *(f[i]+1)) < 0)
				return -1;
			break;
		case 'Q':
		case 'q':
			if(p->iq != nil)
				qsetlimit(p->iq, n);
			if(p->oq != nil)
				qsetlimit(p->oq, n);
			break;
		case 'R':
		case 'r':
			uartdrainoutput(p);
			(*p->phys->rts)(p, n);
			break;
		case 'S':
		case 's':
			uartdrainoutput(p);
			if((*p->phys->stop)(p, n) < 0)
				return -1;
			break;
		case 'W':
		case 'w':
			if(uarttimer == nil || n < 1)
				return -1;
			uarttimer->tns = (int64_t)n * 100000LL;
			break;
		case 'X':
		case 'x':
			if(p->enabled){
				ilock(&p->tlock);
				p->xonoff = n;
				iunlock(&p->tlock);
			}
			break;
		}
	}
	return 0;
}
Ejemplo n.º 15
0
Archivo: devuart.c Proyecto: 8l/inferno
static void
uartctl(Uart *p, char *cmd)
{
	int i, n;

	/* let output drain for a while (up to 4 secs) */
	for(i = 0; i < 200 && (qlen(p->oq) || (readstatus(p) & USTAT_TC) == 0); i++)
		tsleep(&up->sleep, return0, 0, 20);

	if(strncmp(cmd, "break", 5) == 0){
		uartbreak(p, 0);
		return;
	}

	n = atoi(cmd+1);
	switch(*cmd){
	case 'B':
	case 'b':
		if(n <= 0) 
			error(Ebadarg);
		p->bps = n;
		uartset(p);
		break;
	case 'f':
	case 'F':
		qflush(p->oq);
		break;
	case 'H':
	case 'h':
		qhangup(p->iq, 0);
		qhangup(p->oq, 0);
		break;
	case 'L':
	case 'l':
		if(n < 7 || n > 8)
			error(Ebadarg);
		p->bits = n;
		uartset(p);
		break;
	case 'n':
	case 'N':
		qnoblock(p->oq, n);
		break;
	case 'P':
	case 'p':
		p->parity = *(cmd+1);
		uartset(p);
		break;
	case 'K':
	case 'k':
		uartbreak(p, n);
		break;
	case 'Q':
	case 'q':
		qsetlimit(p->iq, n);
		qsetlimit(p->oq, n);
		break;
	case 's':
	case 'S':
		if(n < 1 || n > 2)
			error(Ebadarg);
		p->stop = n;
		uartset(p);
		break;
	}
}