Exemple #1
0
int
vtsrvhello(VtConn *z)
{
	VtFcall tx, rx;
	Packet *p;

	if((p = vtrecv(z)) == nil)
		return -1;

	if(vtfcallunpack(&tx, p) < 0){
		packetfree(p);
		return -1;
	}
	packetfree(p);

	if(tx.msgtype != VtThello){
		vtfcallclear(&tx);
		werrstr("bad packet type %d; want Thello %d", tx.msgtype, VtThello);
		return -1;
	}
	if(tx.tag != 0){
		vtfcallclear(&tx);
		werrstr("bad tag in hello");
		return -1;
	}
	if(strcmp(tx.version, z->version) != 0){
		vtfcallclear(&tx);
		werrstr("bad version in hello");
		return -1;
	}
	vtfree(z->uid);
	z->uid = tx.uid;
	tx.uid = nil;
	vtfcallclear(&tx);

	memset(&rx, 0, sizeof rx);
	rx.msgtype = VtRhello;
	rx.tag = tx.tag;
	rx.sid = "anonymous";
	if((p = vtfcallpack(&rx)) == nil)
		return -1;
	if(vtsend(z, p) < 0)
		return -1;

	return 0;
}
Exemple #2
0
static void
connproc(void *v)
{
	VtSconn *sc;
	VtConn *c;
	Packet *p;
	VtReq *r;
	int fd;
static int first=1;

if(first && chattyventi){
	first=0;
	fmtinstall('F', vtfcallfmt);
}
	r = nil;
	sc = v;
	sc->c = nil;
	if(0) fprint(2, "new call %s on %d\n", sc->dir, sc->ctl);
	fd = accept(sc->ctl, sc->dir);
	close(sc->ctl);
	if(fd < 0){
		fprint(2, "accept %s: %r\n", sc->dir);
		goto out;
	}

	c = vtconn(fd, fd);
	sc->c = c;
	if(vtversion(c) < 0){
		fprint(2, "vtversion %s: %r\n", sc->dir);
		goto out;
	}
	if(vtsrvhello(c) < 0){
		fprint(2, "vtsrvhello %s: %r\n", sc->dir);
		goto out;
	}

	if(0) fprint(2, "new proc %s\n", sc->dir);
	proccreate(vtsendproc, c, STACK);
	qlock(&c->lk);
	while(!c->writeq)
		rsleep(&c->rpcfork);
	qunlock(&c->lk);

	while((p = vtrecv(c)) != nil){
		r = vtmallocz(sizeof(VtReq));
		if(vtfcallunpack(&r->tx, p) < 0){
			vtlog(VtServerLog, "<font size=-1>%T %s:</font> recv bad packet %p: %r<br>\n", c->addr, p);
			fprint(2, "bad packet on %s: %r\n", sc->dir);
			packetfree(p);
			continue;
		}
		vtlog(VtServerLog, "<font size=-1>%T %s:</font> recv packet %p (%F)<br>\n", c->addr, p, &r->tx);
		if(chattyventi)
			fprint(2, "%s <- %F\n", argv0, &r->tx);
		packetfree(p);
		if(r->tx.msgtype == VtTgoodbye)
			break;
		r->rx.tag = r->tx.tag;
		r->sc = sc;
		scincref(sc);
		if(_vtqsend(sc->srv->q, r) < 0){
			scdecref(sc);
			fprint(2, "hungup queue\n");
			break;
		}
		r = nil;
	}

	if(0) fprint(2, "eof on %s\n", sc->dir);

out:
	if(r){
		vtfcallclear(&r->tx);
		vtfree(r);
	}
	if(0) fprint(2, "freed %s\n", sc->dir);
	scdecref(sc);
	return;
}