M boot/boot.h => boot/boot.h +1 -0
@@ 15,6 15,7 @@ extern int cpuflag;
extern char cputype[];
extern int fflag;
extern int kflag;
+extern int pushfcall(int);
extern Method method[];
extern void (*pword)(int, Method*);
extern char sys[];
M boot/bootip.c => boot/bootip.c +18 -17
@@ 97,54 97,55 @@ configip(void)
}
void
-configtcp(Method*)
+configil(Method*)
{
- sleep(100);
- print("t");
- sleep(100);
configip();
- sleep(100);
- print(".");
- sleep(100);
}
int
-authtcp(void)
+authil(void)
{
- return -1;
+ char buf[2*NAMELEN];
+
+ sprint(buf, "il!%I!566", auip);
+ return dial(buf, 0, 0, 0);
}
int
-connecttcp(void)
+connectil(void)
{
char buf[2*NAMELEN];
- sprint(buf, "tcp!%I!564", fsip);
+ sprint(buf, "il!%I!17008", fsip);
return dial(buf, 0, 0, 0);
}
void
-configil(Method*)
+configtcp(Method*)
{
configip();
}
int
-authil(void)
+authtcp(void)
{
char buf[2*NAMELEN];
- sprint(buf, "il!%I!566", auip);
+ sprint(buf, "tcp!%I!567", auip);
return dial(buf, 0, 0, 0);
}
int
-connectil(void)
+connecttcp(void)
{
char buf[2*NAMELEN];
+ int fd;
- sprint(buf, "il!%I!17008", fsip);
- return dial(buf, 0, 0, 0);
+ sprint(buf, "tcp!%I!564", fsip);
+ fd = dial(buf, 0, 0, 0);
+ if(fd < 0)
+ return -1;
+ return pushfcall(fd);
}
static int
A boot/fcall.c => boot/fcall.c +171 -0
@@ 0,0 1,171 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+#include <fcall.h>
+#include <ip.h>
+
+#include "boot.h"
+
+/*
+ * reassemble 9P messages for stream based protocols
+ * interposed between devmnt and the network by srv for tcp connections
+ * fcall expects devmnt on fd0, network fd1
+ */
+static uchar msglen[256] =
+{
+ [Tnop] 3,
+ [Rnop] 3,
+ [Tsession] 3+CHALLEN,
+ [Rsession] 3+NAMELEN+DOMLEN+CHALLEN,
+ [Terror] 0,
+ [Rerror] 67,
+ [Tflush] 5,
+ [Rflush] 3,
+ [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN,
+ [Rattach] 13+AUTHENTLEN,
+ [Tclone] 7,
+ [Rclone] 5,
+ [Twalk] 33,
+ [Rwalk] 13,
+ [Topen] 6,
+ [Ropen] 13,
+ [Tcreate] 38,
+ [Rcreate] 13,
+ [Tread] 15,
+ [Rread] 8,
+ [Twrite] 16,
+ [Rwrite] 7,
+ [Tclunk] 5,
+ [Rclunk] 5,
+ [Tremove] 5,
+ [Rremove] 5,
+ [Tstat] 5,
+ [Rstat] 121,
+ [Twstat] 121,
+ [Rwstat] 5,
+ [Tclwalk] 35,
+ [Rclwalk] 13,
+};
+
+enum
+{
+ Twritehdr = 16, /* Min bytes for Twrite */
+ Rreadhdr = 8, /* Min bytes for Rread */
+ Twritecnt = 13, /* Offset in byte stream of write count */
+ Rreadcnt = 5, /* Offset for Readcnt */
+};
+
+void
+echo(int f, int t)
+{
+ int n;
+ char buf[MAXRPC];
+
+ for(;;) {
+ n = read9p(f, buf, MAXRPC);
+ if(n <= 0)
+ break;
+ if(write(t, buf, n) < n)
+ break;
+ }
+}
+
+int
+mntrpclen(uchar *d, int n)
+{
+ uchar t;
+ int len, off;
+
+ if(n < 1)
+ return 0;
+
+ t = d[0];
+ switch(t) { /* This is the type */
+ default:
+ len = msglen[t];
+ if(len == 0) /* Illegal type so consume */
+ return n;
+ if(n < len)
+ return 0;
+ return len;
+ case Twrite: /* Fmt: TGGFFOOOOOOOOCC */
+ len = Twritehdr; /* T = type, G = tag, F = fid */
+ off = Twritecnt; /* O = offset, C = count */
+ break;
+ case Rread: /* Fmt: TGGFFCC */
+ len = Rreadhdr;
+ off = Rreadcnt;
+ break;
+ }
+ if(n < off+2)
+ return 0;
+
+ len += d[off]|(d[off+1]<<8);
+ if(n < len)
+ return 0;
+
+ return len;
+}
+
+int
+pushfcall(int fd)
+{
+ int r, n, l, pfd[2];
+ uchar *p, buf[MAXRPC];
+
+ if(pipe(pfd) < 0){
+ fprint(2, "pipe: %r\n");
+ exits("pipe");
+ }
+
+ /* Downstream is just a copy process */
+ switch(rfork(RFPROC|RFFDG|RFMEM)){
+ case 0:
+ close(pfd[1]);
+ echo(pfd[0], fd);
+ fprint(2, "echo finished\n");
+ exits("echo done");
+ case -1:
+ fprint(2, "fcall fork failed: %r\n");
+ exits("fork");
+ }
+
+ switch(rfork(RFPROC|RFFDG|RFMEM)){
+ default:
+ close(pfd[0]);
+ return pfd[1];
+ case 0:
+ close(pfd[1]);
+ break;
+ case -1:
+ fprint(2, "fcall fork failed: %r\n");
+ exits("fork");
+ }
+
+ /* Dispatch only full RPC's to the mount driver */
+ l = MAXRPC;
+ p = buf;
+ for(;;) {
+ n = read(fd, p, l);
+ if(n < 0)
+ break;
+ p += n;
+ l -= n;
+
+ for(;;) {
+ r = mntrpclen(buf, p - buf);
+ if(r == 0)
+ break;
+
+ if(write(pfd[0], buf, r) < 0)
+ break;
+
+ n = (p - buf) - r;
+ memmove(buf, buf+r, n);
+ p = buf+n;
+ l = MAXRPC - n;
+ }
+ }
+ abort();
+ return 0;
+}
M port/chan.c => port/chan.c +0 -1
@@ 361,7 361,6 @@ cunmount(Chan *mnt, Chan *mounted)
mountfree(f);
if(m->mount == nil) {
*l = m->hash;
- wunlock(&pg->ns);
cclose(m->from);
wunlock(&m->lock);
putmhead(m);
M port/devsdp.c => port/devsdp.c +8 -8
@@ 99,8 99,6 @@ struct OneWay
int (*auth)(OneWay*, uchar *buf, int len);
void *compstate;
- ulong compseq;
- ulong compwindow;
int (*comp)(Conv*, int subtype, ulong seq, Block **);
};
@@ 1310,8 1308,6 @@ print("pad too big\n");
c->lstats.inBadComp++;
return nil;
}
- c->in.compseq = c->in.seq;
- c->in.compwindow = c->in.window;
c->lstats.inDataBytes += BLEN(b);
if(control)
break;
@@ 2238,13 2234,17 @@ thwackcomp(Conv *c, int, ulong seq, Block **bp)
{
Block *b, *bb;
int nn;
+ ulong ackseq;
+ uchar mask;
// add ack info
b = padblock(*bp, 4);
- b->rp[0] = (c->in.compwindow>>1) & 0xff;
- b->rp[1] = c->in.compseq>>16;
- b->rp[2] = c->in.compseq>>8;
- b->rp[3] = c->in.compseq;
+
+ ackseq = unthwackstate(c->in.compstate, &mask);
+ b->rp[0] = mask;
+ b->rp[1] = ackseq>>16;
+ b->rp[2] = ackseq>>8;
+ b->rp[3] = ackseq;
bb = allocb(BLEN(b));
nn = thwack(c->out.compstate, bb->wp, b->rp, BLEN(b), seq, c->lstats.outCompStats);
M port/thwack.h => port/thwack.h +1 -0
@@ 65,3 65,4 @@ void unthwackinit(Unthwack*);
int thwack(Thwack*, uchar *dst, uchar *src, int nsrc, ulong seq, ulong stats[ThwStats]);
void thwackack(Thwack*, ulong seq, ulong mask);
int unthwack(Unthwack*, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq);
+ulong unthwackstate(Unthwack *ut, uchar *mask);
M port/unthwack.c => port/unthwack.c +68 -25
@@ 59,39 59,86 @@ unthwackinit(Unthwack *ut)
ut->blocks[i].data = ut->data[i];
}
-int
-unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
+ulong
+unthwackstate(Unthwack *ut, uchar *mask)
{
- UnthwBlock blocks[CompBlocks], *b, *eblocks;
- uchar *s, *d, *dmax, *smax, lit;
- ulong cmask, cseq, bseq, utbits, lithist;
- int i, off, len, bits, slot, tslot, use, code, utnbits, overbits;
+ ulong bseq, seq;
+ int slot, m;
- if(nsrc < 4 || nsrc > ThwMaxBlock)
- return -1;
+ seq = ~0UL;
+ m = 0;
+ slot = ut->slot;
+ for(;;){
+ slot--;
+ if(slot < 0)
+ slot += DWinBlocks;
+ if(slot == ut->slot)
+ break;
+ if(ut->blocks[slot].maxoff == 0)
+ continue;
+ bseq = ut->blocks[slot].seq;
+ if(seq == ~0UL)
+ seq = bseq;
+ else if(seq - bseq > MaxSeqMask)
+ break;
+ else
+ m |= 1 << (seq - bseq - 1);
+ }
+ *mask = m;
+ return seq;
+}
+
+/*
+ * insert this block in it's correct sequence number order.
+ * replace the oldest block, which is always pointed to by ut->slot.
+ * the encoder doesn't use a history at wraparound,
+ * so don't worry about that case.
+ */
+static int
+unthwackinsert(Unthwack *ut, int len, ulong seq)
+{
+ uchar *d;
+ int slot, tslot;
- /*
- * insert this block in it's correct sequence number order.
- * replace the oldest block, which is always pointed to by ut->slot.
- * the encoder doesn't use a history at wraparound,
- * so don't worry about that case.
- */
tslot = ut->slot;
for(;;){
slot = tslot - 1;
if(slot < 0)
slot += DWinBlocks;
- if(ut->blocks[slot].seq <= seq)
+ if(ut->blocks[slot].seq <= seq || ut->blocks[slot].maxoff == 0)
break;
d = ut->blocks[tslot].data;
ut->blocks[tslot] = ut->blocks[slot];
ut->blocks[slot].data = d;
tslot = slot;
}
- b = blocks;
ut->blocks[tslot].seq = seq;
- ut->blocks[tslot].maxoff = 0;
- *b = ut->blocks[tslot];
+ ut->blocks[tslot].maxoff = len;
+
+ ut->slot++;
+ if(ut->slot >= DWinBlocks)
+ ut->slot = 0;
+
+ ut->blocks[ut->slot].seq = ~0UL;
+ ut->blocks[ut->slot].maxoff = 0;
+
+ return tslot;
+}
+
+int
+unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
+{
+ UnthwBlock blocks[CompBlocks], *b, *eblocks;
+ uchar *s, *d, *dmax, *smax, lit;
+ ulong cmask, cseq, bseq, utbits;
+ int i, off, len, bits, slot, use, code, utnbits, overbits, lithist;
+
+ if(nsrc < 4 || nsrc > ThwMaxBlock)
+ return -1;
+
+ slot = ut->slot;
+ b = blocks;
+ *b = ut->blocks[slot];
d = b->data;
dmax = d + ndst;
@@ 101,7 148,6 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
cseq = seq - src[0];
cmask = src[1];
b++;
- slot = tslot;
while(cseq != seq && b < blocks + CompBlocks){
slot--;
if(slot < 0)
@@ 125,8 171,8 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
}
eblocks = b;
if(cseq != seq){
- print("blocks not in decompression window: cseq=%ld seq=%ld cmask=%lx nb=%ld\n", cseq, seq, cmask, eblocks - blocks);
- return -1;
+ print("blocks dropped: seq=%ld cseq=%ld %d cmask=%#lx %#x\n", seq, cseq, src[0], cmask, src[1]);
+ return -2;
}
smax = src + nsrc;
@@ 244,11 290,8 @@ unthwack(Unthwack *ut, uchar *dst, int ndst, uchar *src, int nsrc, ulong seq)
len = d - blocks->data;
memmove(dst, blocks->data, len);
- ut->blocks[tslot].maxoff = len;
- ut->slot++;
- if(ut->slot >= DWinBlocks)
- ut->slot = 0;
+ unthwackinsert(ut, len, seq);
return len;
}