remove unused liboventi

This commit is contained in:
cinap_lenrek 2016-04-13 01:09:45 +02:00
parent ffb0199247
commit a5268a5413
23 changed files with 0 additions and 4289 deletions

View file

@ -1,271 +0,0 @@
#pragma lib "liboventi.a"
#pragma src "/sys/src/liboventi"
typedef struct VtSession VtSession;
typedef struct VtSha1 VtSha1;
typedef struct Packet Packet;
typedef struct VtLock VtLock;
typedef struct VtRendez VtRendez;
typedef struct VtRoot VtRoot;
typedef struct VtEntry VtEntry;
typedef struct VtServerVtbl VtServerVtbl;
#pragma incomplete VtSession
#pragma incomplete VtSha1
#pragma incomplete Packet
#pragma incomplete VtLock
#pragma incomplete VtRendez
enum {
VtScoreSize = 20, /* Venti */
VtMaxLumpSize = 56*1024,
VtPointerDepth = 7,
VtEntrySize = 40,
VtRootSize = 300,
VtMaxStringSize = 1000,
VtAuthSize = 1024, /* size of auth group - in bits - must be multiple of 8 */
MaxFragSize = 9*1024,
VtMaxFileSize = (1ULL<<48) - 1,
VtRootVersion = 2,
};
/* crypto strengths */
enum {
VtCryptoStrengthNone,
VtCryptoStrengthAuth,
VtCryptoStrengthWeak,
VtCryptoStrengthStrong,
};
/* crypto suites */
enum {
VtCryptoNone,
VtCryptoSSL3,
VtCryptoTLS1,
VtCryptoMax
};
/* codecs */
enum {
VtCodecNone,
VtCodecDeflate,
VtCodecThwack,
VtCodecMax
};
/* Lump Types */
enum {
VtErrType, /* illegal */
VtRootType,
VtDirType,
VtPointerType0,
VtPointerType1,
VtPointerType2,
VtPointerType3,
VtPointerType4,
VtPointerType5,
VtPointerType6,
VtPointerType7, /* not used */
VtPointerType8, /* not used */
VtPointerType9, /* not used */
VtDataType,
VtMaxType
};
/* Dir Entry flags */
enum {
VtEntryActive = (1<<0), /* entry is in use */
VtEntryDir = (1<<1), /* a directory */
VtEntryDepthShift = 2, /* shift for pointer depth */
VtEntryDepthMask = (0x7<<2), /* mask for pointer depth */
VtEntryLocal = (1<<5), /* used for local storage: should not be set for Venti blocks */
VtEntryNoArchive = (1<<6), /* used for local storage: should not be set for Venti blocks */
};
struct VtRoot {
ushort version;
char name[128];
char type[128];
uchar score[VtScoreSize]; /* to a Dir block */
ushort blockSize; /* maximum block size */
uchar prev[VtScoreSize]; /* last root block */
};
struct VtEntry {
ulong gen; /* generation number */
ushort psize; /* pointer block size */
ushort dsize; /* data block size */
uchar depth; /* unpacked from flags */
uchar flags;
uvlong size;
uchar score[VtScoreSize];
};
struct VtServerVtbl {
Packet *(*read)(VtSession*, uchar score[VtScoreSize], int type, int n);
int (*write)(VtSession*, uchar score[VtScoreSize], int type, Packet *p);
void (*closing)(VtSession*, int clean);
void (*sync)(VtSession*);
};
/* versions */
enum {
/* experimental versions */
VtVersion01 = 1,
VtVersion02,
};
/* score of zero length block */
extern uchar vtZeroScore[VtScoreSize];
/* both sides */
void vtAttach(void);
void vtDetach(void);
void vtClose(VtSession *s);
void vtFree(VtSession *s);
char *vtGetUid(VtSession *s);
char *vtGetSid(VtSession *s);
int vtSetDebug(VtSession *s, int);
int vtGetDebug(VtSession *s);
int vtSetFd(VtSession *s, int fd);
int vtGetFd(VtSession *s);
int vtConnect(VtSession *s, char *password);
int vtSetCryptoStrength(VtSession *s, int);
int vtGetCryptoStrength(VtSession *s);
int vtSetCompression(VtSession *s, int);
int vtGetCompression(VtSession *s);
int vtGetCrypto(VtSession *s);
int vtGetCodec(VtSession *s);
char *vtGetVersion(VtSession *s);
char *vtGetError(void);
int vtErrFmt(Fmt *fmt);
void vtDebug(VtSession*, char *, ...);
void vtDebugMesg(VtSession *z, Packet *p, char *s);
/* internal */
VtSession *vtAlloc(void);
void vtReset(VtSession*);
int vtAddString(Packet*, char*);
int vtGetString(Packet*, char**);
int vtSendPacket(VtSession*, Packet*);
Packet *vtRecvPacket(VtSession*);
void vtDisconnect(VtSession*, int);
int vtHello(VtSession*);
/* client side */
VtSession *vtClientAlloc(void);
VtSession *vtDial(char *server, int canfail);
int vtRedial(VtSession*, char *server);
VtSession *vtStdioServer(char *server);
int vtPing(VtSession *s);
int vtSetUid(VtSession*, char *uid);
int vtRead(VtSession*, uchar score[VtScoreSize], int type, uchar *buf, int n);
int vtWrite(VtSession*, uchar score[VtScoreSize], int type, uchar *buf, int n);
Packet *vtReadPacket(VtSession*, uchar score[VtScoreSize], int type, int n);
int vtWritePacket(VtSession*, uchar score[VtScoreSize], int type, Packet *p);
int vtSync(VtSession *s);
int vtZeroExtend(int type, uchar *buf, int n, int nn);
int vtZeroTruncate(int type, uchar *buf, int n);
int vtParseScore(char*, uint, uchar[VtScoreSize]);
void vtRootPack(VtRoot*, uchar*);
int vtRootUnpack(VtRoot*, uchar*);
void vtEntryPack(VtEntry*, uchar*, int index);
int vtEntryUnpack(VtEntry*, uchar*, int index);
/* server side */
VtSession *vtServerAlloc(VtServerVtbl*);
int vtSetSid(VtSession *s, char *sid);
int vtExport(VtSession *s);
/* sha1 */
VtSha1* vtSha1Alloc(void);
void vtSha1Free(VtSha1*);
void vtSha1Init(VtSha1*);
void vtSha1Update(VtSha1*, uchar *, int n);
void vtSha1Final(VtSha1*, uchar sha1[VtScoreSize]);
void vtSha1(uchar score[VtScoreSize], uchar *, int);
int vtSha1Check(uchar score[VtScoreSize], uchar *, int);
int vtScoreFmt(Fmt *fmt);
/* Packet */
Packet *packetAlloc(void);
void packetFree(Packet*);
Packet *packetForeign(uchar *buf, int n, void (*free)(void *a), void *a);
Packet *packetDup(Packet*, int offset, int n);
Packet *packetSplit(Packet*, int n);
int packetConsume(Packet*, uchar *buf, int n);
int packetTrim(Packet*, int offset, int n);
uchar *packetHeader(Packet*, int n);
uchar *packetTrailer(Packet*, int n);
int packetPrefix(Packet*, uchar *buf, int n);
int packetAppend(Packet*, uchar *buf, int n);
int packetConcat(Packet*, Packet*);
uchar *packetPeek(Packet*, uchar *buf, int offset, int n);
int packetCopy(Packet*, uchar *buf, int offset, int n);
int packetFragments(Packet*, IOchunk*, int nio, int offset);
int packetSize(Packet*);
int packetAllocatedSize(Packet*);
void packetSha1(Packet*, uchar sha1[VtScoreSize]);
int packetCompact(Packet*);
int packetCmp(Packet*, Packet*);
void packetStats(void);
/* portability stuff - should be a seperate library */
void vtMemFree(void *);
void *vtMemAlloc(int);
void *vtMemAllocZ(int);
void *vtMemRealloc(void *p, int);
void *vtMemBrk(int n);
char *vtStrDup(char *);
void vtFatal(char *, ...);
char *vtGetError(void);
char *vtSetError(char *, ...);
char *vtOSError(void);
/* locking/threads */
int vtThread(void (*f)(void*), void *rock);
void vtThreadSetName(char*);
VtLock *vtLockAlloc(void);
/* void vtLockInit(VtLock**); */
void vtLock(VtLock*);
int vtCanLock(VtLock*);
void vtRLock(VtLock*);
int vtCanRLock(VtLock*);
void vtUnlock(VtLock*);
void vtRUnlock(VtLock*);
void vtLockFree(VtLock*);
VtRendez *vtRendezAlloc(VtLock*);
void vtRendezFree(VtRendez*);
int vtSleep(VtRendez*);
int vtWakeup(VtRendez*);
int vtWakeupAll(VtRendez*);
/* fd functions - really network (socket) functions */
void vtFdClose(int);
int vtFdRead(int, uchar*, int);
int vtFdReadFully(int, uchar*, int);
int vtFdWrite(int, uchar*, int);
/*
* formatting
* other than noted, these formats all ignore
* the width and precision arguments, and all flags
*
* V a venti score
* R venti error
*/
#pragma varargck type "V" uchar*
#pragma varargck type "R" void
#pragma varargck argpos vtSetError 1

View file

@ -1,346 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
#include "session.h"
static char EProtocolBotch[] = "venti protocol botch";
static char ELumpSize[] = "illegal lump size";
static char ENotConnected[] = "not connected to venti server";
static Packet *vtRPC(VtSession *z, int op, Packet *p);
VtSession *
vtClientAlloc(void)
{
VtSession *z = vtAlloc();
return z;
}
VtSession *
vtDial(char *host, int canfail)
{
VtSession *z;
int fd;
char *na;
char e[ERRMAX];
if(host == nil)
host = getenv("venti");
if(host == nil)
host = "$venti";
if (host == nil) {
if (!canfail)
werrstr("no venti host set");
na = "";
fd = -1;
} else {
na = netmkaddr(host, 0, "venti");
fd = dial(na, 0, 0, 0);
}
if(fd < 0){
rerrstr(e, sizeof e);
if(!canfail){
vtSetError("venti dialstring %s: %s", na, e);
return nil;
}
}
z = vtClientAlloc();
if(fd < 0)
strcpy(z->fderror, e);
vtSetFd(z, fd);
return z;
}
int
vtRedial(VtSession *z, char *host)
{
int fd;
char *na;
if(host == nil)
host = getenv("venti");
if(host == nil)
host = "$venti";
na = netmkaddr(host, 0, "venti");
fd = dial(na, 0, 0, 0);
if(fd < 0){
vtOSError();
return 0;
}
vtReset(z);
vtSetFd(z, fd);
return 1;
}
VtSession *
vtStdioServer(char *server)
{
int pfd[2];
VtSession *z;
if(server == nil)
return nil;
if(access(server, AEXEC) < 0) {
vtOSError();
return nil;
}
if(pipe(pfd) < 0) {
vtOSError();
return nil;
}
switch(fork()) {
case -1:
close(pfd[0]);
close(pfd[1]);
vtOSError();
return nil;
case 0:
close(pfd[0]);
dup(pfd[1], 0);
dup(pfd[1], 1);
execl(server, "ventiserver", "-i", nil);
exits("exec failed");
}
close(pfd[1]);
z = vtClientAlloc();
vtSetFd(z, pfd[0]);
return z;
}
int
vtPing(VtSession *z)
{
Packet *p = packetAlloc();
p = vtRPC(z, VtQPing, p);
if(p == nil)
return 0;
packetFree(p);
return 1;
}
int
vtHello(VtSession *z)
{
Packet *p;
uchar buf[10];
char *sid;
int crypto, codec;
sid = nil;
p = packetAlloc();
if(!vtAddString(p, vtGetVersion(z)))
goto Err;
if(!vtAddString(p, vtGetUid(z)))
goto Err;
buf[0] = vtGetCryptoStrength(z);
buf[1] = 0;
buf[2] = 0;
packetAppend(p, buf, 3);
p = vtRPC(z, VtQHello, p);
if(p == nil)
return 0;
if(!vtGetString(p, &sid))
goto Err;
if(!packetConsume(p, buf, 2))
goto Err;
if(packetSize(p) != 0) {
vtSetError(EProtocolBotch);
goto Err;
}
crypto = buf[0];
codec = buf[1];
USED(crypto);
USED(codec);
packetFree(p);
vtLock(z->lk);
z->sid = sid;
z->auth.state = VtAuthOK;
vtSha1Free(z->inHash);
z->inHash = nil;
vtSha1Free(z->outHash);
z->outHash = nil;
vtUnlock(z->lk);
return 1;
Err:
packetFree(p);
vtMemFree(sid);
return 0;
}
int
vtSync(VtSession *z)
{
Packet *p = packetAlloc();
p = vtRPC(z, VtQSync, p);
if(p == nil)
return 0;
if(packetSize(p) != 0){
vtSetError(EProtocolBotch);
goto Err;
}
packetFree(p);
return 1;
Err:
packetFree(p);
return 0;
}
int
vtWrite(VtSession *z, uchar score[VtScoreSize], int type, uchar *buf, int n)
{
Packet *p = packetAlloc();
packetAppend(p, buf, n);
return vtWritePacket(z, score, type, p);
}
int
vtWritePacket(VtSession *z, uchar score[VtScoreSize], int type, Packet *p)
{
int n = packetSize(p);
uchar *hdr;
if(n > VtMaxLumpSize || n < 0) {
vtSetError(ELumpSize);
goto Err;
}
if(n == 0) {
memmove(score, vtZeroScore, VtScoreSize);
return 1;
}
hdr = packetHeader(p, 4);
hdr[0] = type;
hdr[1] = 0; /* pad */
hdr[2] = 0; /* pad */
hdr[3] = 0; /* pad */
p = vtRPC(z, VtQWrite, p);
if(p == nil)
return 0;
if(!packetConsume(p, score, VtScoreSize))
goto Err;
if(packetSize(p) != 0) {
vtSetError(EProtocolBotch);
goto Err;
}
packetFree(p);
return 1;
Err:
packetFree(p);
return 0;
}
int
vtRead(VtSession *z, uchar score[VtScoreSize], int type, uchar *buf, int n)
{
Packet *p;
p = vtReadPacket(z, score, type, n);
if(p == nil)
return -1;
n = packetSize(p);
packetCopy(p, buf, 0, n);
packetFree(p);
return n;
}
Packet *
vtReadPacket(VtSession *z, uchar score[VtScoreSize], int type, int n)
{
Packet *p;
uchar buf[10];
if(n < 0 || n > VtMaxLumpSize) {
vtSetError(ELumpSize);
return nil;
}
p = packetAlloc();
if(memcmp(score, vtZeroScore, VtScoreSize) == 0)
return p;
packetAppend(p, score, VtScoreSize);
buf[0] = type;
buf[1] = 0; /* pad */
buf[2] = n >> 8;
buf[3] = n;
packetAppend(p, buf, 4);
return vtRPC(z, VtQRead, p);
}
static Packet *
vtRPC(VtSession *z, int op, Packet *p)
{
uchar *hdr, buf[2];
char *err;
if(z == nil){
vtSetError(ENotConnected);
return nil;
}
/*
* single threaded for the momment
*/
vtLock(z->lk);
if(z->cstate != VtStateConnected){
vtSetError(ENotConnected);
goto Err;
}
hdr = packetHeader(p, 2);
hdr[0] = op; /* op */
hdr[1] = 0; /* tid */
vtDebug(z, "client send: ");
vtDebugMesg(z, p, "\n");
if(!vtSendPacket(z, p)) {
p = nil;
goto Err;
}
p = vtRecvPacket(z);
if(p == nil)
goto Err;
vtDebug(z, "client recv: ");
vtDebugMesg(z, p, "\n");
if(!packetConsume(p, buf, 2))
goto Err;
if(buf[0] == VtRError) {
if(!vtGetString(p, &err)) {
vtSetError(EProtocolBotch);
goto Err;
}
vtSetError(err);
vtMemFree(err);
packetFree(p);
vtUnlock(z->lk);
return nil;
}
if(buf[0] != op+1 || buf[1] != 0) {
vtSetError(EProtocolBotch);
goto Err;
}
vtUnlock(z->lk);
return p;
Err:
vtDebug(z, "vtRPC failed: %s\n", vtGetError());
if(p != nil)
packetFree(p);
vtUnlock(z->lk);
vtDisconnect(z, 1);
return nil;
}

View file

@ -1,78 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
#include "session.h"
void vtDumpSome(Packet*);
void
vtDebug(VtSession *s, char *fmt, ...)
{
va_list arg;
if(!s->debug)
return;
va_start(arg, fmt);
vfprint(2, fmt, arg);
va_end(arg);
}
void
vtDebugMesg(VtSession *z, Packet *p, char *s)
{
int op;
int tid;
int n;
uchar buf[100], *b;
if(!z->debug)
return;
n = packetSize(p);
if(n < 2) {
fprint(2, "runt packet%s", s);
return;
}
b = packetPeek(p, buf, 0, 2);
op = b[0];
tid = b[1];
fprint(2, "%c%d[%d] %d", ((op&1)==0)?'R':'Q', op, tid, n);
vtDumpSome(p);
fprint(2, "%s", s);
}
void
vtDumpSome(Packet *pkt)
{
int printable;
int i, n;
char buf[200], *q, *eq;
uchar data[32], *p;
n = packetSize(pkt);
printable = 1;
q = buf;
eq = buf + sizeof(buf);
q = seprint(q, eq, "(%d) '", n);
if(n > sizeof(data))
n = sizeof(data);
p = packetPeek(pkt, data, 0, n);
for(i=0; i<n && printable; i++)
if((p[i]<32 && p[i] !='\n' && p[i] !='\t') || p[i]>127)
printable = 0;
if(printable) {
for(i=0; i<n; i++)
q = seprint(q, eq, "%c", p[i]);
} else {
for(i=0; i<n; i++) {
if(i>0 && i%4==0)
q = seprint(q, eq, " ");
q = seprint(q, eq, "%.2X", p[i]);
}
}
seprint(q, eq, "'");
fprint(2, "%s", buf);
}

View file

@ -1,12 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
int
vtErrFmt(Fmt *f)
{
char *s;
s = vtGetError();
return fmtstrcpy(f, s);
}

View file

@ -1,16 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
void
vtFatal(char *fmt, ...)
{
va_list arg;
va_start(arg, fmt);
fprint(2, "fatal error: ");
vfprint(2, fmt, arg);
fprint(2, "\n");
va_end(arg);
exits("vtFatal");
}

View file

@ -1,46 +0,0 @@
</$objtype/mkfile
LIB=/$objtype/lib/liboventi.a
SYS=plan9
OFILES=\
client.$O\
debug.$O\
errfmt.$O\
fatal.$O\
pack.$O\
packet.$O\
parsescore.$O\
readfully.$O\
rpc.$O\
scorefmt.$O\
server.$O\
strdup.$O\
zero.$O\
$SYS-io.$O\
$SYS-sha1.$O\
$SYS-thread.$O\
HFILES=\
packet.h\
session.h\
UPDATE=\
mkfile\
$HFILES\
${OFILES:%.$O=%.c}\
${LIB:/$objtype/%=/386/%}\
CFLAGS=$CFLAGS
</sys/src/cmd/mksyslib
$O.vttest: vttest.$O $OFILES
$LD $LDFLAGS -o $target $prereq
acid: $HFILES packet.c
$CC $INC -a packet.c > acid || rm acid
test: $O.vttest
$O.vttest

View file

@ -1,147 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
/*
* integer conversion routines
*/
#define U8GET(p) ((p)[0])
#define U16GET(p) (((p)[0]<<8)|(p)[1])
#define U32GET(p) ((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
#define U48GET(p) (((vlong)U16GET(p)<<32)|(vlong)U32GET((p)+2))
#define U64GET(p) (((vlong)U32GET(p)<<32)|(vlong)U32GET((p)+4))
#define U8PUT(p,v) (p)[0]=(v)
#define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v)
#define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v)
#define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
#define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
static int
checkSize(int n)
{
if(n < 256 || n > VtMaxLumpSize) {
vtSetError("bad block size");
return 0;
}
return 1;
}
void
vtRootPack(VtRoot *r, uchar *p)
{
uchar *op = p;
U16PUT(p, r->version);
p += 2;
memmove(p, r->name, sizeof(r->name));
p += sizeof(r->name);
memmove(p, r->type, sizeof(r->type));
p += sizeof(r->type);
memmove(p, r->score, VtScoreSize);
p += VtScoreSize;
U16PUT(p, r->blockSize);
p += 2;
memmove(p, r->prev, VtScoreSize);
p += VtScoreSize;
assert(p-op == VtRootSize);
}
int
vtRootUnpack(VtRoot *r, uchar *p)
{
uchar *op = p;
memset(r, 0, sizeof(*r));
r->version = U16GET(p);
if(r->version != VtRootVersion) {
vtSetError("unknown root version");
return 0;
}
p += 2;
memmove(r->name, p, sizeof(r->name));
r->name[sizeof(r->name)-1] = 0;
p += sizeof(r->name);
memmove(r->type, p, sizeof(r->type));
r->type[sizeof(r->type)-1] = 0;
p += sizeof(r->type);
memmove(r->score, p, VtScoreSize);
p += VtScoreSize;
r->blockSize = U16GET(p);
if(!checkSize(r->blockSize))
return 0;
p += 2;
memmove(r->prev, p, VtScoreSize);
p += VtScoreSize;
assert(p-op == VtRootSize);
return 1;
}
void
vtEntryPack(VtEntry *e, uchar *p, int index)
{
ulong t32;
int flags;
uchar *op;
p += index * VtEntrySize;
op = p;
U32PUT(p, e->gen);
p += 4;
U16PUT(p, e->psize);
p += 2;
U16PUT(p, e->dsize);
p += 2;
flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask);
U8PUT(p, flags);
p++;
memset(p, 0, 5);
p += 5;
U48PUT(p, e->size, t32);
p += 6;
memmove(p, e->score, VtScoreSize);
p += VtScoreSize;
assert(p-op == VtEntrySize);
}
int
vtEntryUnpack(VtEntry *e, uchar *p, int index)
{
uchar *op;
p += index * VtEntrySize;
op = p;
e->gen = U32GET(p);
p += 4;
e->psize = U16GET(p);
p += 2;
e->dsize = U16GET(p);
p += 2;
e->flags = U8GET(p);
e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
e->flags &= ~VtEntryDepthMask;
p++;
p += 5;
e->size = U48GET(p);
p += 6;
memmove(e->score, p, VtScoreSize);
p += VtScoreSize;
assert(p-op == VtEntrySize);
if(!(e->flags & VtEntryActive))
return 1;
if(!checkSize(e->psize) || !checkSize(e->dsize))
return 0;
return 1;
}

View file

@ -1,848 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
#include "packet.h"
static Frag *fragAlloc(Packet*, int n, int pos, Frag *next);
static Frag *fragDup(Packet*, Frag*);
static void fragFree(Frag*);
static Mem *memAlloc(int, int);
static void memFree(Mem*);
static int memHead(Mem *m, uchar *rp, int n);
static int memTail(Mem *m, uchar *wp, int n);
static char EPacketSize[] = "bad packet size";
static char EPacketOffset[] = "bad packet offset";
static char EBadSize[] = "bad size";
static struct {
Lock lk;
Packet *packet;
int npacket;
Frag *frag;
int nfrag;
Mem *bigMem;
int nbigMem;
Mem *smallMem;
int nsmallMem;
} freeList;
#define FRAGSIZE(f) ((f)->wp - (f)->rp)
#define FRAGASIZE(f) ((f)->mem->ep - (f)->mem->bp)
#define NOTFREE(p) assert((p)->size>=0)
Packet *
packetAlloc(void)
{
Packet *p;
lock(&freeList.lk);
p = freeList.packet;
if(p != nil)
freeList.packet = p->next;
else
freeList.npacket++;
unlock(&freeList.lk);
if(p == nil)
p = vtMemBrk(sizeof(Packet));
else
assert(p->size == -1);
p->size = 0;
p->asize = 0;
p->first = nil;
p->last = nil;
p->next = nil;
return p;
}
void
packetFree(Packet *p)
{
Frag *f, *ff;
if(0)fprint(2, "packetFree %p\n", p);
NOTFREE(p);
p->size = -1;
for(f=p->first; f!=nil; f=ff) {
ff = f->next;
fragFree(f);
}
p->first = nil;
p->last = nil;
lock(&freeList.lk);
p->next = freeList.packet;
freeList.packet = p;
unlock(&freeList.lk);
}
Packet *
packetDup(Packet *p, int offset, int n)
{
Frag *f, *ff;
Packet *pp;
NOTFREE(p);
if(offset < 0 || n < 0 || offset+n > p->size) {
vtSetError(EBadSize);
return nil;
}
pp = packetAlloc();
if(n == 0)
return pp;
pp->size = n;
/* skip offset */
for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
offset -= FRAGSIZE(f);
/* first frag */
ff = fragDup(pp, f);
ff->rp += offset;
pp->first = ff;
n -= FRAGSIZE(ff);
pp->asize += FRAGASIZE(ff);
/* the remaining */
while(n > 0) {
f = f->next;
ff->next = fragDup(pp, f);
ff = ff->next;
n -= FRAGSIZE(ff);
pp->asize += FRAGASIZE(ff);
}
/* fix up last frag: note n <= 0 */
ff->wp += n;
ff->next = nil;
pp->last = ff;
return pp;
}
Packet *
packetSplit(Packet *p, int n)
{
Packet *pp;
Frag *f, *ff;
NOTFREE(p);
if(n < 0 || n > p->size) {
vtSetError(EPacketSize);
return nil;
}
pp = packetAlloc();
if(n == 0)
return pp;
pp->size = n;
p->size -= n;
ff = nil;
for(f=p->first; n > 0 && n >= FRAGSIZE(f); f=f->next) {
n -= FRAGSIZE(f);
p->asize -= FRAGASIZE(f);
pp->asize += FRAGASIZE(f);
ff = f;
}
/* split shared frag */
if(n > 0) {
ff = f;
f = fragDup(pp, ff);
pp->asize += FRAGASIZE(ff);
ff->next = nil;
ff->wp = ff->rp + n;
f->rp += n;
}
pp->first = p->first;
pp->last = ff;
p->first = f;
return pp;
}
int
packetConsume(Packet *p, uchar *buf, int n)
{
NOTFREE(p);
if(buf && !packetCopy(p, buf, 0, n))
return 0;
return packetTrim(p, n, p->size-n);
}
int
packetTrim(Packet *p, int offset, int n)
{
Frag *f, *ff;
NOTFREE(p);
if(offset < 0 || offset > p->size) {
vtSetError(EPacketOffset);
return 0;
}
if(n < 0 || offset + n > p->size) {
vtSetError(EPacketOffset);
return 0;
}
p->size = n;
/* easy case */
if(n == 0) {
for(f=p->first; f != nil; f=ff) {
ff = f->next;
fragFree(f);
}
p->first = p->last = nil;
p->asize = 0;
return 1;
}
/* free before offset */
for(f=p->first; offset >= FRAGSIZE(f); f=ff) {
p->asize -= FRAGASIZE(f);
offset -= FRAGSIZE(f);
ff = f->next;
fragFree(f);
}
/* adjust frag */
f->rp += offset;
p->first = f;
/* skip middle */
for(; n > 0 && n > FRAGSIZE(f); f=f->next)
n -= FRAGSIZE(f);
/* adjust end */
f->wp = f->rp + n;
p->last = f;
ff = f->next;
f->next = nil;
/* free after */
for(f=ff; f != nil; f=ff) {
p->asize -= FRAGASIZE(f);
ff = f->next;
fragFree(f);
}
return 1;
}
uchar *
packetHeader(Packet *p, int n)
{
Frag *f;
Mem *m;
NOTFREE(p);
if(n <= 0 || n > MaxFragSize) {
vtSetError(EPacketSize);
return 0;
}
p->size += n;
/* try and fix in current frag */
f = p->first;
if(f != nil) {
m = f->mem;
if(n <= f->rp - m->bp)
if(m->ref == 1 || memHead(m, f->rp, n)) {
f->rp -= n;
return f->rp;
}
}
/* add frag to front */
f = fragAlloc(p, n, PEnd, p->first);
p->asize += FRAGASIZE(f);
if(p->first == nil)
p->last = f;
p->first = f;
return f->rp;
}
uchar *
packetTrailer(Packet *p, int n)
{
Mem *m;
Frag *f;
NOTFREE(p);
if(n <= 0 || n > MaxFragSize) {
vtSetError(EPacketSize);
return 0;
}
p->size += n;
/* try and fix in current frag */
if(p->first != nil) {
f = p->last;
m = f->mem;
if(n <= m->ep - f->wp)
if(m->ref == 1 || memTail(m, f->wp, n)) {
f->wp += n;
return f->wp - n;
}
}
/* add frag to end */
f = fragAlloc(p, n, (p->first == nil)?PMiddle:PFront, nil);
p->asize += FRAGASIZE(f);
if(p->first == nil)
p->first = f;
else
p->last->next = f;
p->last = f;
return f->rp;
}
int
packetPrefix(Packet *p, uchar *buf, int n)
{
Frag *f;
int nn;
Mem *m;
NOTFREE(p);
if(n <= 0)
return 1;
p->size += n;
/* try and fix in current frag */
f = p->first;
if(f != nil) {
m = f->mem;
nn = f->rp - m->bp;
if(nn > n)
nn = n;
if(m->ref == 1 || memHead(m, f->rp, nn)) {
f->rp -= nn;
n -= nn;
memmove(f->rp, buf+n, nn);
}
}
while(n > 0) {
nn = n;
if(nn > MaxFragSize)
nn = MaxFragSize;
f = fragAlloc(p, nn, PEnd, p->first);
p->asize += FRAGASIZE(f);
if(p->first == nil)
p->last = f;
p->first = f;
n -= nn;
memmove(f->rp, buf+n, nn);
}
return 1;
}
int
packetAppend(Packet *p, uchar *buf, int n)
{
Frag *f;
int nn;
Mem *m;
NOTFREE(p);
if(n <= 0)
return 1;
p->size += n;
/* try and fix in current frag */
if(p->first != nil) {
f = p->last;
m = f->mem;
nn = m->ep - f->wp;
if(nn > n)
nn = n;
if(m->ref == 1 || memTail(m, f->wp, nn)) {
memmove(f->wp, buf, nn);
f->wp += nn;
buf += nn;
n -= nn;
}
}
while(n > 0) {
nn = n;
if(nn > MaxFragSize)
nn = MaxFragSize;
f = fragAlloc(p, nn, (p->first == nil)?PMiddle:PFront, nil);
p->asize += FRAGASIZE(f);
if(p->first == nil)
p->first = f;
else
p->last->next = f;
p->last = f;
memmove(f->rp, buf, nn);
buf += nn;
n -= nn;
}
return 1;
}
int
packetConcat(Packet *p, Packet *pp)
{
NOTFREE(p);
NOTFREE(pp);
if(pp->size == 0)
return 1;
p->size += pp->size;
p->asize += pp->asize;
if(p->first != nil)
p->last->next = pp->first;
else
p->first = pp->first;
p->last = pp->last;
pp->size = 0;
pp->asize = 0;
pp->first = nil;
pp->last = nil;
return 1;
}
uchar *
packetPeek(Packet *p, uchar *buf, int offset, int n)
{
Frag *f;
int nn;
uchar *b;
NOTFREE(p);
if(n == 0)
return buf;
if(offset < 0 || offset >= p->size) {
vtSetError(EPacketOffset);
return 0;
}
if(n < 0 || offset + n > p->size) {
vtSetError(EPacketSize);
return 0;
}
/* skip up to offset */
for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
offset -= FRAGSIZE(f);
/* easy case */
if(offset + n <= FRAGSIZE(f))
return f->rp + offset;
for(b=buf; n>0; n -= nn) {
nn = FRAGSIZE(f) - offset;
if(nn > n)
nn = n;
memmove(b, f->rp+offset, nn);
offset = 0;
f = f->next;
b += nn;
}
return buf;
}
int
packetCopy(Packet *p, uchar *buf, int offset, int n)
{
uchar *b;
NOTFREE(p);
b = packetPeek(p, buf, offset, n);
if(b == nil)
return 0;
if(b != buf)
memmove(buf, b, n);
return 1;
}
int
packetFragments(Packet *p, IOchunk *io, int nio, int offset)
{
Frag *f;
int size;
IOchunk *eio;
NOTFREE(p);
if(p->size == 0 || nio <= 0)
return 0;
if(offset < 0 || offset > p->size) {
vtSetError(EPacketOffset);
return -1;
}
for(f=p->first; offset >= FRAGSIZE(f); f=f->next)
offset -= FRAGSIZE(f);
size = 0;
eio = io + nio;
for(; f != nil && io < eio; f=f->next) {
io->addr = f->rp + offset;
io->len = f->wp - (f->rp + offset);
offset = 0;
size += io->len;
io++;
}
return size;
}
void
packetStats(void)
{
Packet *p;
Frag *f;
Mem *m;
int np, nf, nsm, nbm;
lock(&freeList.lk);
np = 0;
for(p=freeList.packet; p; p=p->next)
np++;
nf = 0;
for(f=freeList.frag; f; f=f->next)
nf++;
nsm = 0;
for(m=freeList.smallMem; m; m=m->next)
nsm++;
nbm = 0;
for(m=freeList.bigMem; m; m=m->next)
nbm++;
fprint(2, "packet: %d/%d frag: %d/%d small mem: %d/%d big mem: %d/%d\n",
np, freeList.npacket,
nf, freeList.nfrag,
nsm, freeList.nsmallMem,
nbm, freeList.nbigMem);
unlock(&freeList.lk);
}
int
packetSize(Packet *p)
{
NOTFREE(p);
if(0) {
Frag *f;
int size = 0;
for(f=p->first; f; f=f->next)
size += FRAGSIZE(f);
if(size != p->size)
fprint(2, "packetSize %d %d\n", size, p->size);
assert(size == p->size);
}
return p->size;
}
int
packetAllocatedSize(Packet *p)
{
NOTFREE(p);
if(0) {
Frag *f;
int asize = 0;
for(f=p->first; f; f=f->next)
asize += FRAGASIZE(f);
if(asize != p->asize)
fprint(2, "packetAllocatedSize %d %d\n", asize, p->asize);
assert(asize == p->asize);
}
return p->asize;
}
void
packetSha1(Packet *p, uchar sha1[VtScoreSize])
{
Frag *f;
VtSha1 *s;
int size;
NOTFREE(p);
s = vtSha1Alloc();
size = p->size;
for(f=p->first; f; f=f->next) {
vtSha1Update(s, f->rp, FRAGSIZE(f));
size -= FRAGSIZE(f);
}
assert(size == 0);
vtSha1Final(s, sha1);
vtSha1Free(s);
}
int
packetCmp(Packet *pkt0, Packet *pkt1)
{
Frag *f0, *f1;
int n0, n1, x;
NOTFREE(pkt0);
NOTFREE(pkt1);
f0 = pkt0->first;
f1 = pkt1->first;
if(f0 == nil)
return (f1 == nil)?0:-1;
if(f1 == nil)
return 1;
n0 = FRAGSIZE(f0);
n1 = FRAGSIZE(f1);
for(;;) {
if(n0 < n1) {
x = memcmp(f0->wp - n0, f1->wp - n1, n0);
if(x != 0)
return x;
n1 -= n0;
f0 = f0->next;
if(f0 == nil)
return -1;
n0 = FRAGSIZE(f0);
} else if (n0 > n1) {
x = memcmp(f0->wp - n0, f1->wp - n1, n1);
if(x != 0)
return x;
n0 -= n1;
f1 = f1->next;
if(f1 == nil)
return 1;
n1 = FRAGSIZE(f1);
} else { /* n0 == n1 */
x = memcmp(f0->wp - n0, f1->wp - n1, n0);
if(x != 0)
return x;
f0 = f0->next;
f1 = f1->next;
if(f0 == nil)
return (f1 == nil)?0:-1;
if(f1 == nil)
return 1;
n0 = FRAGSIZE(f0);
n1 = FRAGSIZE(f1);
}
}
}
static Frag *
fragAlloc(Packet *p, int n, int pos, Frag *next)
{
Frag *f, *ef;
Mem *m;
/* look for local frag */
f = &p->local[0];
ef = &p->local[NLocalFrag];
for(;f<ef; f++) {
if(f->state == FragLocalFree) {
f->state = FragLocalAlloc;
goto Found;
}
}
lock(&freeList.lk);
f = freeList.frag;
if(f != nil)
freeList.frag = f->next;
else
freeList.nfrag++;
unlock(&freeList.lk);
if(f == nil) {
f = vtMemBrk(sizeof(Frag));
f->state = FragGlobal;
}
Found:
if(n == 0)
return f;
if(pos == PEnd && next == nil)
pos = PMiddle;
m = memAlloc(n, pos);
f->mem = m;
f->rp = m->rp;
f->wp = m->wp;
f->next = next;
return f;
}
static Frag *
fragDup(Packet *p, Frag *f)
{
Frag *ff;
Mem *m;
m = f->mem;
/*
* m->rp && m->wp can be out of date when ref == 1
* also, potentially reclaims space from previous frags
*/
if(m->ref == 1) {
m->rp = f->rp;
m->wp = f->wp;
}
ff = fragAlloc(p, 0, 0, nil);
*ff = *f;
lock(&m->lk);
m->ref++;
unlock(&m->lk);
return ff;
}
static void
fragFree(Frag *f)
{
memFree(f->mem);
if(f->state == FragLocalAlloc) {
f->state = FragLocalFree;
return;
}
lock(&freeList.lk);
f->next = freeList.frag;
freeList.frag = f;
unlock(&freeList.lk);
}
static Mem *
memAlloc(int n, int pos)
{
Mem *m;
int nn;
if(n < 0 || n > MaxFragSize) {
vtSetError(EPacketSize);
return 0;
}
if(n <= SmallMemSize) {
lock(&freeList.lk);
m = freeList.smallMem;
if(m != nil)
freeList.smallMem = m->next;
else
freeList.nsmallMem++;
unlock(&freeList.lk);
nn = SmallMemSize;
} else {
lock(&freeList.lk);
m = freeList.bigMem;
if(m != nil)
freeList.bigMem = m->next;
else
freeList.nbigMem++;
unlock(&freeList.lk);
nn = BigMemSize;
}
if(m == nil) {
m = vtMemBrk(sizeof(Mem));
m->bp = vtMemBrk(nn);
m->ep = m->bp + nn;
}
assert(m->ref == 0);
m->ref = 1;
switch(pos) {
default:
assert(0);
case PFront:
m->rp = m->bp;
break;
case PMiddle:
/* leave a little bit at end */
m->rp = m->ep - n - 32;
break;
case PEnd:
m->rp = m->ep - n;
break;
}
/* check we did not blow it */
if(m->rp < m->bp)
m->rp = m->bp;
m->wp = m->rp + n;
assert(m->rp >= m->bp && m->wp <= m->ep);
return m;
}
static void
memFree(Mem *m)
{
lock(&m->lk);
m->ref--;
if(m->ref > 0) {
unlock(&m->lk);
return;
}
unlock(&m->lk);
assert(m->ref == 0);
switch(m->ep - m->bp) {
default:
assert(0);
case SmallMemSize:
lock(&freeList.lk);
m->next = freeList.smallMem;
freeList.smallMem = m;
unlock(&freeList.lk);
break;
case BigMemSize:
lock(&freeList.lk);
m->next = freeList.bigMem;
freeList.bigMem = m;
unlock(&freeList.lk);
break;
}
}
static int
memHead(Mem *m, uchar *rp, int n)
{
lock(&m->lk);
if(m->rp != rp) {
unlock(&m->lk);
return 0;
}
m->rp -= n;
unlock(&m->lk);
return 1;
}
static int
memTail(Mem *m, uchar *wp, int n)
{
lock(&m->lk);
if(m->wp != wp) {
unlock(&m->lk);
return 0;
}
m->wp += n;
unlock(&m->lk);
return 1;
}

View file

@ -1,56 +0,0 @@
typedef struct Packet Packet;
typedef struct Mem Mem;
typedef struct Frag Frag;
enum {
BigMemSize = MaxFragSize,
SmallMemSize = BigMemSize/8,
NLocalFrag = 2,
};
/* position to carve out of a Mem */
enum {
PFront,
PMiddle,
PEnd,
};
struct Mem
{
Lock lk;
int ref;
uchar *bp;
uchar *ep;
uchar *rp;
uchar *wp;
Mem *next;
};
enum {
FragLocalFree,
FragLocalAlloc,
FragGlobal,
};
struct Frag
{
int state;
Mem *mem;
uchar *rp;
uchar *wp;
Frag *next;
};
struct Packet
{
int size;
int asize; /* allocated memmory - always greater than size */
Packet *next;
Frag *first;
Frag *last;
Frag local[NLocalFrag];
};

View file

@ -1,31 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
int
vtParseScore(char *buf, uint n, uchar score[VtScoreSize])
{
int i, c;
memset(score, 0, VtScoreSize);
if(n != VtScoreSize*2)
return 0;
for(i=0; i<VtScoreSize*2; i++){
if(buf[i] >= '0' && buf[i] <= '9')
c = buf[i] - '0';
else if(buf[i] >= 'a' && buf[i] <= 'f')
c = buf[i] - 'a' + 10;
else if(buf[i] >= 'A' && buf[i] <= 'F')
c = buf[i] - 'A' + 10;
else
return 0;
if((i & 1) == 0)
c <<= 4;
score[i>>1] |= c;
}
return 1;
}

View file

@ -1,146 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
enum {
IdealAlignment = 32,
ChunkSize = 128*1024,
};
void
vtMemFree(void *p)
{
if(p == 0)
return;
free(p);
}
void *
vtMemAlloc(int size)
{
void *p;
p = malloc(size);
if(p == 0)
vtFatal("vtMemAlloc: out of memory");
setmalloctag(p, getcallerpc(&size));
return p;
}
void *
vtMemAllocZ(int size)
{
void *p = vtMemAlloc(size);
memset(p, 0, size);
setmalloctag(p, getcallerpc(&size));
return p;
}
void *
vtMemRealloc(void *p, int size)
{
if(p == nil)
return vtMemAlloc(size);
p = realloc(p, size);
if(p == 0)
vtFatal("vtRealloc: out of memory");
setrealloctag(p, getcallerpc(&size));
return p;
}
void *
vtMemBrk(int n)
{
static Lock lk;
static uchar *buf;
static int nbuf;
static int nchunk;
int align, pad;
void *p;
if(n >= IdealAlignment)
align = IdealAlignment;
else if(n > 8)
align = 8;
else
align = 4;
lock(&lk);
pad = (align - (uintptr)buf) & (align-1);
if(n + pad > nbuf) {
buf = vtMemAllocZ(ChunkSize);
setmalloctag(buf, getcallerpc(&n));
nbuf = ChunkSize;
pad = (align - (uintptr)buf) & (align-1);
nchunk++;
}
assert(n + pad <= nbuf);
p = buf + pad;
buf += pad + n;
nbuf -= pad + n;
unlock(&lk);
return p;
}
void
vtThreadSetName(char *name)
{
int fd;
char buf[32];
sprint(buf, "/proc/%d/args", getpid());
if((fd = open(buf, OWRITE)) >= 0){
write(fd, name, strlen(name));
close(fd);
}
}
int
vtFdRead(int fd, uchar *buf, int n)
{
n = read(fd, buf, n);
if(n < 0) {
vtOSError();
return -1;
}
if(n == 0) {
vtSetError("unexpected EOF");
return 0;
}
return n;
}
int
vtFdWrite(int fd, uchar *buf, int n)
{
int nn;
nn = write(fd, buf, n);
if(nn < 0) {
vtOSError();
return 0;
}
if(n != nn) {
vtSetError("truncated write");
return 0;
}
return 1;
}
void
vtFdClose(int fd)
{
close(fd);
}
char *
vtOSError(void)
{
return vtSetError("%r");
}

View file

@ -1,78 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
#include <libsec.h>
static void encode(uchar*, u32int*, ulong);
extern void vtSha1Block(u32int *s, uchar *p, ulong len);
struct VtSha1
{
DigestState *s;
};
VtSha1 *
vtSha1Alloc(void)
{
VtSha1 *s;
s = vtMemAlloc(sizeof(VtSha1));
vtSha1Init(s);
return s;
}
void
vtSha1Free(VtSha1 *s)
{
if(s == nil)
return;
if(s->s != nil)
free(s->s);
vtMemFree(s);
}
void
vtSha1Init(VtSha1 *s)
{
s->s = nil;
}
void
vtSha1Update(VtSha1 *s, uchar *p, int len)
{
s->s = sha1(p, len, nil, s->s);
}
void
vtSha1Final(VtSha1 *s, uchar *digest)
{
sha1(nil, 0, digest, s->s);
s->s = nil;
}
void
vtSha1(uchar sha1[VtScoreSize], uchar *p, int n)
{
VtSha1 s;
vtSha1Init(&s);
vtSha1Update(&s, p, n);
vtSha1Final(&s, sha1);
}
int
vtSha1Check(uchar score[VtScoreSize], uchar *p, int n)
{
VtSha1 s;
uchar score2[VtScoreSize];
vtSha1Init(&s);
vtSha1Update(&s, p, n);
vtSha1Final(&s, score2);
if(memcmp(score, score2, VtScoreSize) != 0) {
vtSetError("vtSha1Check failed");
return 0;
}
return 1;
}

View file

@ -1,531 +0,0 @@
sizeof_1_ = 8;
aggr _1_
{
'U' 0 lo;
'U' 4 hi;
};
defn
_1_(addr) {
complex _1_ addr;
print(" lo ", addr.lo, "\n");
print(" hi ", addr.hi, "\n");
};
sizeofFPdbleword = 8;
aggr FPdbleword
{
'F' 0 x;
{
'U' 0 lo;
'U' 4 hi;
};
};
defn
FPdbleword(addr) {
complex FPdbleword addr;
print(" x ", addr.x, "\n");
print("_1_ {\n");
_1_(addr+0);
print("}\n");
};
UTFmax = 3;
Runesync = 128;
Runeself = 128;
Runeerror = 65533;
sizeofFmt = 48;
aggr Fmt
{
'b' 0 runes;
'X' 4 start;
'X' 8 to;
'X' 12 stop;
'X' 16 flush;
'X' 20 farg;
'D' 24 nfmt;
'X' 28 args;
'D' 32 r;
'D' 36 width;
'D' 40 prec;
'U' 44 flags;
};
defn
Fmt(addr) {
complex Fmt addr;
print(" runes ", addr.runes, "\n");
print(" start ", addr.start\X, "\n");
print(" to ", addr.to\X, "\n");
print(" stop ", addr.stop\X, "\n");
print(" flush ", addr.flush\X, "\n");
print(" farg ", addr.farg\X, "\n");
print(" nfmt ", addr.nfmt, "\n");
print(" args ", addr.args\X, "\n");
print(" r ", addr.r, "\n");
print(" width ", addr.width, "\n");
print(" prec ", addr.prec, "\n");
print(" flags ", addr.flags, "\n");
};
FmtWidth = 1;
FmtLeft = 2;
FmtPrec = 4;
FmtSharp = 8;
FmtSpace = 16;
FmtSign = 32;
FmtZero = 64;
FmtUnsigned = 128;
FmtShort = 256;
FmtLong = 512;
FmtVLong = 1024;
FmtComma = 2048;
FmtByte = 4096;
FmtFlag = 8192;
sizeofTm = 40;
aggr Tm
{
'D' 0 sec;
'D' 4 min;
'D' 8 hour;
'D' 12 mday;
'D' 16 mon;
'D' 20 year;
'D' 24 wday;
'D' 28 yday;
'a' 32 zone;
'D' 36 tzoff;
};
defn
Tm(addr) {
complex Tm addr;
print(" sec ", addr.sec, "\n");
print(" min ", addr.min, "\n");
print(" hour ", addr.hour, "\n");
print(" mday ", addr.mday, "\n");
print(" mon ", addr.mon, "\n");
print(" year ", addr.year, "\n");
print(" wday ", addr.wday, "\n");
print(" yday ", addr.yday, "\n");
print(" zone ", addr.zone, "\n");
print(" tzoff ", addr.tzoff, "\n");
};
PNPROC = 1;
PNGROUP = 2;
Profoff = 0;
Profuser = 1;
Profkernel = 2;
Proftime = 3;
Profsample = 4;
sizeofLock = 4;
aggr Lock
{
'D' 0 val;
};
defn
Lock(addr) {
complex Lock addr;
print(" val ", addr.val, "\n");
};
sizeofQLp = 12;
aggr QLp
{
'D' 0 inuse;
'A' QLp 4 next;
'C' 8 state;
};
defn
QLp(addr) {
complex QLp addr;
print(" inuse ", addr.inuse, "\n");
print(" next ", addr.next\X, "\n");
print(" state ", addr.state, "\n");
};
sizeofQLock = 16;
aggr QLock
{
Lock 0 lock;
'D' 4 locked;
'A' QLp 8 $head;
'A' QLp 12 $tail;
};
defn
QLock(addr) {
complex QLock addr;
print("Lock lock {\n");
Lock(addr.lock);
print("}\n");
print(" locked ", addr.locked, "\n");
print(" $head ", addr.$head\X, "\n");
print(" $tail ", addr.$tail\X, "\n");
};
sizeofRWLock = 20;
aggr RWLock
{
Lock 0 lock;
'D' 4 readers;
'D' 8 writer;
'A' QLp 12 $head;
'A' QLp 16 $tail;
};
defn
RWLock(addr) {
complex RWLock addr;
print("Lock lock {\n");
Lock(addr.lock);
print("}\n");
print(" readers ", addr.readers, "\n");
print(" writer ", addr.writer, "\n");
print(" $head ", addr.$head\X, "\n");
print(" $tail ", addr.$tail\X, "\n");
};
sizeofRendez = 12;
aggr Rendez
{
'A' QLock 0 l;
'A' QLp 4 $head;
'A' QLp 8 $tail;
};
defn
Rendez(addr) {
complex Rendez addr;
print(" l ", addr.l\X, "\n");
print(" $head ", addr.$head\X, "\n");
print(" $tail ", addr.$tail\X, "\n");
};
sizeofNetConnInfo = 36;
aggr NetConnInfo
{
'X' 0 dir;
'X' 4 root;
'X' 8 spec;
'X' 12 lsys;
'X' 16 lserv;
'X' 20 rsys;
'X' 24 rserv;
'X' 28 laddr;
'X' 32 raddr;
};
defn
NetConnInfo(addr) {
complex NetConnInfo addr;
print(" dir ", addr.dir\X, "\n");
print(" root ", addr.root\X, "\n");
print(" spec ", addr.spec\X, "\n");
print(" lsys ", addr.lsys\X, "\n");
print(" lserv ", addr.lserv\X, "\n");
print(" rsys ", addr.rsys\X, "\n");
print(" rserv ", addr.rserv\X, "\n");
print(" laddr ", addr.laddr\X, "\n");
print(" raddr ", addr.raddr\X, "\n");
};
RFNAMEG = 1;
RFENVG = 2;
RFFDG = 4;
RFNOTEG = 8;
RFPROC = 16;
RFMEM = 32;
RFNOWAIT = 64;
RFCNAMEG = 1024;
RFCENVG = 2048;
RFCFDG = 4096;
RFREND = 8192;
RFNOMNT = 16384;
sizeofQid = 16;
aggr Qid
{
'W' 0 path;
'U' 8 vers;
'b' 12 type;
};
defn
Qid(addr) {
complex Qid addr;
print(" path ", addr.path, "\n");
print(" vers ", addr.vers, "\n");
print(" type ", addr.type, "\n");
};
sizeofDir = 60;
aggr Dir
{
'u' 0 type;
'U' 4 dev;
Qid 8 qid;
'U' 24 mode;
'U' 28 atime;
'U' 32 mtime;
'V' 36 length;
'X' 44 name;
'X' 48 uid;
'X' 52 gid;
'X' 56 muid;
};
defn
Dir(addr) {
complex Dir addr;
print(" type ", addr.type, "\n");
print(" dev ", addr.dev, "\n");
print("Qid qid {\n");
Qid(addr.qid);
print("}\n");
print(" mode ", addr.mode, "\n");
print(" atime ", addr.atime, "\n");
print(" mtime ", addr.mtime, "\n");
print(" length ", addr.length, "\n");
print(" name ", addr.name\X, "\n");
print(" uid ", addr.uid\X, "\n");
print(" gid ", addr.gid\X, "\n");
print(" muid ", addr.muid\X, "\n");
};
sizeofWaitmsg = 20;
aggr Waitmsg
{
'D' 0 pid;
'a' 4 time;
'X' 16 msg;
};
defn
Waitmsg(addr) {
complex Waitmsg addr;
print(" pid ", addr.pid, "\n");
print(" time ", addr.time, "\n");
print(" msg ", addr.msg\X, "\n");
};
sizeofIOchunk = 8;
aggr IOchunk
{
'X' 0 addr;
'U' 4 len;
};
defn
IOchunk(addr) {
complex IOchunk addr;
print(" addr ", addr.addr\X, "\n");
print(" len ", addr.len, "\n");
};
VtScoreSize = 20;
VtMaxLumpSize = 57344;
VtPointerDepth = 7;
VtEntrySize = 40;
VtRootSize = 300;
VtMaxStringSize = 1000;
VtAuthSize = 1024;
MaxFragSize = 9216;
VtMaxFileSize = 281474976710655;
VtRootVersion = 2;
VtCryptoStrengthNone = 0;
VtCryptoStrengthAuth = 1;
VtCryptoStrengthWeak = 2;
VtCryptoStrengthStrong = 3;
VtCryptoNone = 0;
VtCryptoSSL3 = 1;
VtCryptoTLS1 = 2;
VtCryptoMax = 3;
VtCodecNone = 0;
VtCodecDeflate = 1;
VtCodecThwack = 2;
VtCodecMax = 3;
VtErrType = 0;
VtRootType = 1;
VtDirType = 2;
VtPointerType0 = 3;
VtPointerType1 = 4;
VtPointerType2 = 5;
VtPointerType3 = 6;
VtPointerType4 = 7;
VtPointerType5 = 8;
VtPointerType6 = 9;
VtPointerType7 = 10;
VtPointerType8 = 11;
VtPointerType9 = 12;
VtDataType = 13;
VtMaxType = 14;
VtEntryActive = 1;
VtEntryDir = 2;
VtEntryDepthShift = 2;
VtEntryDepthMask = 28;
VtEntryLocal = 32;
VtEntryNoArchive = 64;
sizeofVtRoot = 300;
aggr VtRoot
{
'u' 0 version;
'a' 2 name;
'a' 130 type;
'a' 258 score;
'u' 278 blockSize;
'a' 280 prev;
};
defn
VtRoot(addr) {
complex VtRoot addr;
print(" version ", addr.version, "\n");
print(" name ", addr.name, "\n");
print(" type ", addr.type, "\n");
print(" score ", addr.score, "\n");
print(" blockSize ", addr.blockSize, "\n");
print(" prev ", addr.prev, "\n");
};
sizeofVtEntry = 40;
aggr VtEntry
{
'U' 0 gen;
'u' 4 psize;
'u' 6 dsize;
'b' 8 depth;
'b' 9 flags;
'W' 12 size;
'a' 20 score;
};
defn
VtEntry(addr) {
complex VtEntry addr;
print(" gen ", addr.gen, "\n");
print(" psize ", addr.psize, "\n");
print(" dsize ", addr.dsize, "\n");
print(" depth ", addr.depth, "\n");
print(" flags ", addr.flags, "\n");
print(" size ", addr.size, "\n");
print(" score ", addr.score, "\n");
};
sizeofVtServerVtbl = 16;
aggr VtServerVtbl
{
'X' 0 read;
'X' 4 write;
'X' 8 closing;
'X' 12 sync;
};
defn
VtServerVtbl(addr) {
complex VtServerVtbl addr;
print(" read ", addr.read\X, "\n");
print(" write ", addr.write\X, "\n");
print(" closing ", addr.closing\X, "\n");
print(" sync ", addr.sync\X, "\n");
};
VtVersion01 = 1;
VtVersion02 = 2;
QueuingW = 0;
QueuingR = 1;
sizeofThread = 20;
aggr Thread
{
'D' 0 pid;
'D' 4 ref;
'X' 8 error;
'D' 12 state;
'A' Thread 16 next;
};
defn
Thread(addr) {
complex Thread addr;
print(" pid ", addr.pid, "\n");
print(" ref ", addr.ref, "\n");
print(" error ", addr.error\X, "\n");
print(" state ", addr.state, "\n");
print(" next ", addr.next\X, "\n");
};
sizeofVtLock = 20;
aggr VtLock
{
Lock 0 lk;
'A' Thread 4 writer;
'D' 8 readers;
'A' Thread 12 qfirst;
'A' Thread 16 qlast;
};
defn
VtLock(addr) {
complex VtLock addr;
print("Lock lk {\n");
Lock(addr.lk);
print("}\n");
print(" writer ", addr.writer\X, "\n");
print(" readers ", addr.readers, "\n");
print(" qfirst ", addr.qfirst\X, "\n");
print(" qlast ", addr.qlast\X, "\n");
};
sizeofVtRendez = 12;
aggr VtRendez
{
'A' VtLock 0 lk;
'A' Thread 4 wfirst;
'A' Thread 8 wlast;
};
defn
VtRendez(addr) {
complex VtRendez addr;
print(" lk ", addr.lk\X, "\n");
print(" wfirst ", addr.wfirst\X, "\n");
print(" wlast ", addr.wlast\X, "\n");
};
ERROR = 0;
complex Thread vtRock;
complex Thread vtAttach:p;
complex Lock lk$4;
complex Thread vtDetach:p;
complex Thread vtSetError:p;
complex Lock lk$12;
complex VtLock vtLockFree:p;
complex VtLock vtRendezAlloc:p;
complex VtRendez vtRendezAlloc:q;
complex VtRendez vtRendezFree:q;
complex VtLock vtCanLock:p;
complex Thread vtCanLock:t;
complex VtLock vtLock:p;
complex Thread vtLock:t;
complex VtLock vtCanRLock:p;
complex VtLock vtRLock:p;
complex Thread vtRLock:t;
complex VtLock vtUnlock:p;
complex Thread vtUnlock:t;
complex Thread vtUnlock:tt;
complex VtLock vtRUnlock:p;
complex Thread vtRUnlock:t;
complex VtRendez vtSleep:q;
complex Thread vtSleep:s;
complex Thread vtSleep:t;
complex Thread vtSleep:tt;
complex VtLock vtSleep:p;
complex VtRendez vtWakeup:q;
complex Thread vtWakeup:t;
complex VtLock vtWakeup:p;
complex VtRendez vtWakeupAll:q;
complex Thread threadSleep:t;
complex Thread threadWakeup:t;

View file

@ -1,468 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
enum
{
QueuingW, /* queuing for write lock */
QueuingR, /* queuing for read lock */
};
typedef struct Thread Thread;
struct Thread {
int pid;
int ref;
char *error;
int state;
Thread *next;
};
struct VtLock {
Lock lk;
Thread *writer; /* thread writering write lock */
int readers; /* number writering read lock */
Thread *qfirst;
Thread *qlast;
};
struct VtRendez {
VtLock *lk;
Thread *wfirst;
Thread *wlast;
};
enum {
ERROR = 0,
};
static Thread **vtRock;
static void vtThreadInit(void);
static void threadSleep(Thread*);
static void threadWakeup(Thread*);
int
vtThread(void (*f)(void*), void *rock)
{
int tid;
tid = rfork(RFNOWAIT|RFMEM|RFPROC);
switch(tid){
case -1:
vtOSError();
return -1;
case 0:
break;
default:
return tid;
}
vtAttach();
(*f)(rock);
vtDetach();
_exits(0);
return 0;
}
static Thread *
threadLookup(void)
{
return *vtRock;
}
void
vtAttach(void)
{
int pid;
Thread *p;
static int init;
static Lock lk;
lock(&lk);
if(!init) {
rfork(RFREND);
vtThreadInit();
init = 1;
}
unlock(&lk);
pid = getpid();
p = *vtRock;
if(p != nil && p->pid == pid) {
p->ref++;
return;
}
p = vtMemAllocZ(sizeof(Thread));
p->ref = 1;
p->pid = pid;
*vtRock = p;
}
void
vtDetach(void)
{
Thread *p;
p = *vtRock;
assert(p != nil);
p->ref--;
if(p->ref == 0) {
vtMemFree(p->error);
vtMemFree(p);
*vtRock = nil;
}
}
char *
vtGetError(void)
{
char *s;
if(ERROR)
fprint(2, "vtGetError: %s\n", threadLookup()->error);
s = threadLookup()->error;
if(s == nil)
return "unknown error";
return s;
}
char*
vtSetError(char* fmt, ...)
{
Thread *p;
char *s;
va_list args;
p = threadLookup();
va_start(args, fmt);
s = vsmprint(fmt, args);
vtMemFree(p->error);
p->error = s;
va_end(args);
if(ERROR)
fprint(2, "vtSetError: %s\n", p->error);
werrstr("%s", p->error);
return p->error;
}
static void
vtThreadInit(void)
{
static Lock lk;
lock(&lk);
if(vtRock != nil) {
unlock(&lk);
return;
}
vtRock = privalloc();
if(vtRock == nil)
vtFatal("can't allocate thread-private storage");
unlock(&lk);
}
VtLock*
vtLockAlloc(void)
{
return vtMemAllocZ(sizeof(VtLock));
}
/*
* RSC: I think the test is backward. Let's see who uses it.
*
void
vtLockInit(VtLock **p)
{
static Lock lk;
lock(&lk);
if(*p != nil)
*p = vtLockAlloc();
unlock(&lk);
}
*/
void
vtLockFree(VtLock *p)
{
if(p == nil)
return;
assert(p->writer == nil);
assert(p->readers == 0);
assert(p->qfirst == nil);
vtMemFree(p);
}
VtRendez*
vtRendezAlloc(VtLock *p)
{
VtRendez *q;
q = vtMemAllocZ(sizeof(VtRendez));
q->lk = p;
setmalloctag(q, getcallerpc(&p));
return q;
}
void
vtRendezFree(VtRendez *q)
{
if(q == nil)
return;
assert(q->wfirst == nil);
vtMemFree(q);
}
int
vtCanLock(VtLock *p)
{
Thread *t;
lock(&p->lk);
t = *vtRock;
if(p->writer == nil && p->readers == 0) {
p->writer = t;
unlock(&p->lk);
return 1;
}
unlock(&p->lk);
return 0;
}
void
vtLock(VtLock *p)
{
Thread *t;
lock(&p->lk);
t = *vtRock;
if(p->writer == nil && p->readers == 0) {
p->writer = t;
unlock(&p->lk);
return;
}
/*
* venti currently contains code that assume locks can be passed between threads :-(
* assert(p->writer != t);
*/
if(p->qfirst == nil)
p->qfirst = t;
else
p->qlast->next = t;
p->qlast = t;
t->next = nil;
t->state = QueuingW;
unlock(&p->lk);
threadSleep(t);
assert(p->writer == t && p->readers == 0);
}
int
vtCanRLock(VtLock *p)
{
lock(&p->lk);
if(p->writer == nil && p->qfirst == nil) {
p->readers++;
unlock(&p->lk);
return 1;
}
unlock(&p->lk);
return 0;
}
void
vtRLock(VtLock *p)
{
Thread *t;
lock(&p->lk);
t = *vtRock;
if(p->writer == nil && p->qfirst == nil) {
p->readers++;
unlock(&p->lk);
return;
}
/*
* venti currently contains code that assumes locks can be passed between threads
* assert(p->writer != t);
*/
if(p->qfirst == nil)
p->qfirst = t;
else
p->qlast->next = t;
p->qlast = t;
t->next = nil;
t->state = QueuingR;
unlock(&p->lk);
threadSleep(t);
assert(p->writer == nil && p->readers > 0);
}
void
vtUnlock(VtLock *p)
{
Thread *t, *tt;
lock(&p->lk);
/*
* venti currently has code that assumes lock can be passed between threads :-)
* assert(p->writer == *vtRock);
*/
assert(p->writer != nil);
assert(p->readers == 0);
t = p->qfirst;
if(t == nil) {
p->writer = nil;
unlock(&p->lk);
return;
}
if(t->state == QueuingW) {
p->qfirst = t->next;
p->writer = t;
unlock(&p->lk);
threadWakeup(t);
return;
}
p->writer = nil;
while(t != nil && t->state == QueuingR) {
tt = t;
t = t->next;
p->readers++;
threadWakeup(tt);
}
p->qfirst = t;
unlock(&p->lk);
}
void
vtRUnlock(VtLock *p)
{
Thread *t;
lock(&p->lk);
assert(p->writer == nil && p->readers > 0);
p->readers--;
t = p->qfirst;
if(p->readers > 0 || t == nil) {
unlock(&p->lk);
return;
}
assert(t->state == QueuingW);
p->qfirst = t->next;
p->writer = t;
unlock(&p->lk);
threadWakeup(t);
}
int
vtSleep(VtRendez *q)
{
Thread *s, *t, *tt;
VtLock *p;
p = q->lk;
lock(&p->lk);
s = *vtRock;
/*
* venti currently contains code that assume locks can be passed between threads :-(
* assert(p->writer != s);
*/
assert(p->writer != nil);
assert(p->readers == 0);
t = p->qfirst;
if(t == nil) {
p->writer = nil;
} else if(t->state == QueuingW) {
p->qfirst = t->next;
p->writer = t;
threadWakeup(t);
} else {
p->writer = nil;
while(t != nil && t->state == QueuingR) {
tt = t;
t = t->next;
p->readers++;
threadWakeup(tt);
}
}
if(q->wfirst == nil)
q->wfirst = s;
else
q->wlast->next = s;
q->wlast = s;
s->next = nil;
unlock(&p->lk);
threadSleep(s);
assert(p->writer == s);
return 1;
}
int
vtWakeup(VtRendez *q)
{
Thread *t;
VtLock *p;
/*
* take off wait and put on front of queue
* put on front so guys that have been waiting will not get starved
*/
p = q->lk;
lock(&p->lk);
/*
* venti currently has code that assumes lock can be passed between threads :-)
* assert(p->writer == *vtRock);
*/
assert(p->writer != nil);
t = q->wfirst;
if(t == nil) {
unlock(&p->lk);
return 0;
}
q->wfirst = t->next;
if(p->qfirst == nil)
p->qlast = t;
t->next = p->qfirst;
p->qfirst = t;
t->state = QueuingW;
unlock(&p->lk);
return 1;
}
int
vtWakeupAll(VtRendez *q)
{
int i;
for(i=0; vtWakeup(q); i++)
;
return i;
}
static void
threadSleep(Thread *t)
{
if(rendezvous(t, (void*)0x22bbdfd6) != (void*)0x44391f14)
sysfatal("threadSleep: rendezvous failed: %r");
}
static void
threadWakeup(Thread *t)
{
if(rendezvous(t, (void*)0x44391f14) != (void*)0x22bbdfd6)
sysfatal("threadWakeup: rendezvous failed: %r");
}

View file

@ -1,19 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
#include "session.h"
int
vtFdReadFully(int fd, uchar *p, int n)
{
int nn;
while(n > 0) {
nn = vtFdRead(fd, p, n);
if(nn <= 0)
return 0;
n -= nn;
p += nn;
}
return 1;
}

View file

@ -1,471 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
#include "session.h"
struct {
int version;
char *s;
} vtVersions[] = {
VtVersion02, "02",
0, 0,
};
static char EBigString[] = "string too long";
static char EBigPacket[] = "packet too long";
static char ENullString[] = "missing string";
static char EBadVersion[] = "bad format in version string";
static Packet *vtRPC(VtSession *z, int op, Packet *p);
VtSession *
vtAlloc(void)
{
VtSession *z;
z = vtMemAllocZ(sizeof(VtSession));
z->lk = vtLockAlloc();
// z->inHash = vtSha1Alloc();
z->inLock = vtLockAlloc();
z->part = packetAlloc();
// z->outHash = vtSha1Alloc();
z->outLock = vtLockAlloc();
z->fd = -1;
z->uid = vtStrDup("anonymous");
z->sid = vtStrDup("anonymous");
return z;
}
void
vtReset(VtSession *z)
{
vtLock(z->lk);
z->cstate = VtStateAlloc;
if(z->fd >= 0){
vtFdClose(z->fd);
z->fd = -1;
}
vtUnlock(z->lk);
}
int
vtConnected(VtSession *z)
{
return z->cstate == VtStateConnected;
}
void
vtDisconnect(VtSession *z, int error)
{
Packet *p;
uchar *b;
vtDebug(z, "vtDisconnect\n");
vtLock(z->lk);
if(z->cstate == VtStateConnected && !error && z->vtbl == nil) {
/* clean shutdown */
p = packetAlloc();
b = packetHeader(p, 2);
b[0] = VtQGoodbye;
b[1] = 0;
vtSendPacket(z, p);
}
if(z->fd >= 0)
vtFdClose(z->fd);
z->fd = -1;
z->cstate = VtStateClosed;
vtUnlock(z->lk);
}
void
vtClose(VtSession *z)
{
vtDisconnect(z, 0);
}
void
vtFree(VtSession *z)
{
if(z == nil)
return;
vtLockFree(z->lk);
vtSha1Free(z->inHash);
vtLockFree(z->inLock);
packetFree(z->part);
vtSha1Free(z->outHash);
vtLockFree(z->outLock);
vtMemFree(z->uid);
vtMemFree(z->sid);
vtMemFree(z->vtbl);
memset(z, 0, sizeof(VtSession));
z->fd = -1;
vtMemFree(z);
}
char *
vtGetUid(VtSession *s)
{
return s->uid;
}
char *
vtGetSid(VtSession *z)
{
return z->sid;
}
int
vtSetDebug(VtSession *z, int debug)
{
int old;
vtLock(z->lk);
old = z->debug;
z->debug = debug;
vtUnlock(z->lk);
return old;
}
int
vtSetFd(VtSession *z, int fd)
{
vtLock(z->lk);
if(z->cstate != VtStateAlloc) {
vtSetError("bad state");
vtUnlock(z->lk);
return 0;
}
if(z->fd >= 0)
vtFdClose(z->fd);
z->fd = fd;
vtUnlock(z->lk);
return 1;
}
int
vtGetFd(VtSession *z)
{
return z->fd;
}
int
vtSetCryptoStrength(VtSession *z, int c)
{
if(z->cstate != VtStateAlloc) {
vtSetError("bad state");
return 0;
}
if(c != VtCryptoStrengthNone) {
vtSetError("not supported yet");
return 0;
}
return 1;
}
int
vtGetCryptoStrength(VtSession *s)
{
return s->cryptoStrength;
}
int
vtSetCompression(VtSession *z, int fd)
{
vtLock(z->lk);
if(z->cstate != VtStateAlloc) {
vtSetError("bad state");
vtUnlock(z->lk);
return 0;
}
z->fd = fd;
vtUnlock(z->lk);
return 1;
}
int
vtGetCompression(VtSession *s)
{
return s->compression;
}
int
vtGetCrypto(VtSession *s)
{
return s->crypto;
}
int
vtGetCodec(VtSession *s)
{
return s->codec;
}
char *
vtGetVersion(VtSession *z)
{
int v, i;
v = z->version;
if(v == 0)
return "unknown";
for(i=0; vtVersions[i].version; i++)
if(vtVersions[i].version == v)
return vtVersions[i].s;
assert(0);
return 0;
}
/* hold z->inLock */
static int
vtVersionRead(VtSession *z, char *prefix, int *ret)
{
char c;
char buf[VtMaxStringSize];
char *q, *p, *pp;
int i;
q = prefix;
p = buf;
for(;;) {
if(p >= buf + sizeof(buf)) {
vtSetError(EBadVersion);
return 0;
}
if(!vtFdReadFully(z->fd, (uchar*)&c, 1))
return 0;
if(z->inHash)
vtSha1Update(z->inHash, (uchar*)&c, 1);
if(c == '\n') {
*p = 0;
break;
}
if(c < ' ' || *q && c != *q) {
vtSetError(EBadVersion);
return 0;
}
*p++ = c;
if(*q)
q++;
}
vtDebug(z, "version string in: %s\n", buf);
p = buf + strlen(prefix);
for(;;) {
for(pp=p; *pp && *pp != ':' && *pp != '-'; pp++)
;
for(i=0; vtVersions[i].version; i++) {
if(strlen(vtVersions[i].s) != pp-p)
continue;
if(memcmp(vtVersions[i].s, p, pp-p) == 0) {
*ret = vtVersions[i].version;
return 1;
}
}
p = pp;
if(*p != ':')
return 0;
p++;
}
}
Packet*
vtRecvPacket(VtSession *z)
{
uchar buf[10], *b;
int n;
Packet *p;
int size, len;
if(z->cstate != VtStateConnected) {
vtSetError("session not connected");
return 0;
}
vtLock(z->inLock);
p = z->part;
/* get enough for head size */
size = packetSize(p);
while(size < 2) {
b = packetTrailer(p, MaxFragSize);
assert(b != nil);
n = vtFdRead(z->fd, b, MaxFragSize);
if(n <= 0)
goto Err;
size += n;
packetTrim(p, 0, size);
}
if(!packetConsume(p, buf, 2))
goto Err;
len = (buf[0] << 8) | buf[1];
size -= 2;
while(size < len) {
n = len - size;
if(n > MaxFragSize)
n = MaxFragSize;
b = packetTrailer(p, n);
if(!vtFdReadFully(z->fd, b, n))
goto Err;
size += n;
}
p = packetSplit(p, len);
vtUnlock(z->inLock);
return p;
Err:
vtUnlock(z->inLock);
return nil;
}
int
vtSendPacket(VtSession *z, Packet *p)
{
IOchunk ioc;
int n;
uchar buf[2];
/* add framing */
n = packetSize(p);
if(n >= (1<<16)) {
vtSetError(EBigPacket);
packetFree(p);
return 0;
}
buf[0] = n>>8;
buf[1] = n;
packetPrefix(p, buf, 2);
for(;;) {
n = packetFragments(p, &ioc, 1, 0);
if(n == 0)
break;
if(!vtFdWrite(z->fd, ioc.addr, ioc.len)) {
packetFree(p);
return 0;
}
packetConsume(p, nil, n);
}
packetFree(p);
return 1;
}
int
vtGetString(Packet *p, char **ret)
{
uchar buf[2];
int n;
char *s;
if(!packetConsume(p, buf, 2))
return 0;
n = (buf[0]<<8) + buf[1];
if(n > VtMaxStringSize) {
vtSetError(EBigString);
return 0;
}
s = vtMemAlloc(n+1);
setmalloctag(s, getcallerpc(&p));
if(!packetConsume(p, (uchar*)s, n)) {
vtMemFree(s);
return 0;
}
s[n] = 0;
*ret = s;
return 1;
}
int
vtAddString(Packet *p, char *s)
{
uchar buf[2];
int n;
if(s == nil) {
vtSetError(ENullString);
return 0;
}
n = strlen(s);
if(n > VtMaxStringSize) {
vtSetError(EBigString);
return 0;
}
buf[0] = n>>8;
buf[1] = n;
packetAppend(p, buf, 2);
packetAppend(p, (uchar*)s, n);
return 1;
}
int
vtConnect(VtSession *z, char *password)
{
char buf[VtMaxStringSize], *p, *ep, *prefix;
int i;
USED(password);
vtLock(z->lk);
if(z->cstate != VtStateAlloc) {
vtSetError("bad session state");
vtUnlock(z->lk);
return 0;
}
if(z->fd < 0){
vtSetError("%s", z->fderror);
vtUnlock(z->lk);
return 0;
}
/* be a little anal */
vtLock(z->inLock);
vtLock(z->outLock);
prefix = "venti-";
p = buf;
ep = buf + sizeof(buf);
p = seprint(p, ep, "%s", prefix);
p += strlen(p);
for(i=0; vtVersions[i].version; i++) {
if(i != 0)
*p++ = ':';
p = seprint(p, ep, "%s", vtVersions[i].s);
}
p = seprint(p, ep, "-libventi\n");
assert(p-buf < sizeof(buf));
if(z->outHash)
vtSha1Update(z->outHash, (uchar*)buf, p-buf);
if(!vtFdWrite(z->fd, (uchar*)buf, p-buf))
goto Err;
vtDebug(z, "version string out: %s", buf);
if(!vtVersionRead(z, prefix, &z->version))
goto Err;
vtDebug(z, "version = %d: %s\n", z->version, vtGetVersion(z));
vtUnlock(z->inLock);
vtUnlock(z->outLock);
z->cstate = VtStateConnected;
vtUnlock(z->lk);
if(z->vtbl)
return 1;
if(!vtHello(z))
goto Err;
return 1;
Err:
if(z->fd >= 0)
vtFdClose(z->fd);
z->fd = -1;
vtUnlock(z->inLock);
vtUnlock(z->outLock);
z->cstate = VtStateClosed;
vtUnlock(z->lk);
return 0;
}

View file

@ -1,20 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
int
vtScoreFmt(Fmt *f)
{
uchar *v;
int i;
v = va_arg(f->args, uchar*);
if(v == nil){
fmtprint(f, "*");
}else{
for(i = 0; i < VtScoreSize; i++)
fmtprint(f, "%2.2ux", v[i]);
}
return 0;
}

View file

@ -1,265 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
#include "session.h"
static char EAuthState[] = "bad authentication state";
static char ENotServer[] = "not a server session";
static char EVersion[] = "incorrect version number";
static char EProtocolBotch[] = "venti protocol botch";
VtSession *
vtServerAlloc(VtServerVtbl *vtbl)
{
VtSession *z = vtAlloc();
z->vtbl = vtMemAlloc(sizeof(VtServerVtbl));
setmalloctag(z->vtbl, getcallerpc(&vtbl));
*z->vtbl = *vtbl;
return z;
}
static int
srvHello(VtSession *z, char *version, char *uid, int , uchar *, int , uchar *, int )
{
vtLock(z->lk);
if(z->auth.state != VtAuthHello) {
vtSetError(EAuthState);
goto Err;
}
if(strcmp(version, vtGetVersion(z)) != 0) {
vtSetError(EVersion);
goto Err;
}
vtMemFree(z->uid);
z->uid = vtStrDup(uid);
z->auth.state = VtAuthOK;
vtUnlock(z->lk);
return 1;
Err:
z->auth.state = VtAuthFailed;
vtUnlock(z->lk);
return 0;
}
static int
dispatchHello(VtSession *z, Packet **pkt)
{
char *version, *uid;
uchar *crypto, *codec;
uchar buf[10];
int ncrypto, ncodec, cryptoStrength;
int ret;
Packet *p;
p = *pkt;
version = nil;
uid = nil;
crypto = nil;
codec = nil;
ret = 0;
if(!vtGetString(p, &version))
goto Err;
if(!vtGetString(p, &uid))
goto Err;
if(!packetConsume(p, buf, 2))
goto Err;
cryptoStrength = buf[0];
ncrypto = buf[1];
crypto = vtMemAlloc(ncrypto);
if(!packetConsume(p, crypto, ncrypto))
goto Err;
if(!packetConsume(p, buf, 1))
goto Err;
ncodec = buf[0];
codec = vtMemAlloc(ncodec);
if(!packetConsume(p, codec, ncodec))
goto Err;
if(packetSize(p) != 0) {
vtSetError(EProtocolBotch);
goto Err;
}
if(!srvHello(z, version, uid, cryptoStrength, crypto, ncrypto, codec, ncodec)) {
packetFree(p);
*pkt = nil;
} else {
if(!vtAddString(p, vtGetSid(z)))
goto Err;
buf[0] = vtGetCrypto(z);
buf[1] = vtGetCodec(z);
packetAppend(p, buf, 2);
}
ret = 1;
Err:
vtMemFree(version);
vtMemFree(uid);
vtMemFree(crypto);
vtMemFree(codec);
return ret;
}
static int
dispatchRead(VtSession *z, Packet **pkt)
{
Packet *p;
int type, n;
uchar score[VtScoreSize], buf[4];
p = *pkt;
if(!packetConsume(p, score, VtScoreSize))
return 0;
if(!packetConsume(p, buf, 4))
return 0;
type = buf[0];
n = (buf[2]<<8) | buf[3];
if(packetSize(p) != 0) {
vtSetError(EProtocolBotch);
return 0;
}
packetFree(p);
*pkt = (*z->vtbl->read)(z, score, type, n);
return 1;
}
static int
dispatchWrite(VtSession *z, Packet **pkt)
{
Packet *p;
int type;
uchar score[VtScoreSize], buf[4];
p = *pkt;
if(!packetConsume(p, buf, 4))
return 0;
type = buf[0];
if(!(z->vtbl->write)(z, score, type, p)) {
*pkt = 0;
} else {
*pkt = packetAlloc();
packetAppend(*pkt, score, VtScoreSize);
}
return 1;
}
static int
dispatchSync(VtSession *z, Packet **pkt)
{
(z->vtbl->sync)(z);
if(packetSize(*pkt) != 0) {
vtSetError(EProtocolBotch);
return 0;
}
return 1;
}
int
vtExport(VtSession *z)
{
Packet *p;
uchar buf[10], *hdr;
int op, tid, clean;
if(z->vtbl == nil) {
vtSetError(ENotServer);
return 0;
}
/* fork off slave */
switch(rfork(RFNOWAIT|RFMEM|RFPROC)){
case -1:
vtOSError();
return 0;
case 0:
break;
default:
return 1;
}
p = nil;
clean = 0;
vtAttach();
if(!vtConnect(z, nil))
goto Exit;
vtDebug(z, "server connected!\n");
if(0) vtSetDebug(z, 1);
for(;;) {
p = vtRecvPacket(z);
if(p == nil) {
break;
}
vtDebug(z, "server recv: ");
vtDebugMesg(z, p, "\n");
if(!packetConsume(p, buf, 2)) {
vtSetError(EProtocolBotch);
break;
}
op = buf[0];
tid = buf[1];
switch(op) {
default:
vtSetError(EProtocolBotch);
goto Exit;
case VtQPing:
break;
case VtQGoodbye:
clean = 1;
goto Exit;
case VtQHello:
if(!dispatchHello(z, &p))
goto Exit;
break;
case VtQRead:
if(!dispatchRead(z, &p))
goto Exit;
break;
case VtQWrite:
if(!dispatchWrite(z, &p))
goto Exit;
break;
case VtQSync:
if(!dispatchSync(z, &p))
goto Exit;
break;
}
if(p != nil) {
hdr = packetHeader(p, 2);
hdr[0] = op+1;
hdr[1] = tid;
} else {
p = packetAlloc();
hdr = packetHeader(p, 2);
hdr[0] = VtRError;
hdr[1] = tid;
if(!vtAddString(p, vtGetError()))
goto Exit;
}
vtDebug(z, "server send: ");
vtDebugMesg(z, p, "\n");
if(!vtSendPacket(z, p)) {
p = nil;
goto Exit;
}
}
Exit:
if(p != nil)
packetFree(p);
if(z->vtbl->closing)
z->vtbl->closing(z, clean);
vtClose(z);
vtFree(z);
vtDetach();
exits(0);
return 0; /* never gets here */
}

View file

@ -1,74 +0,0 @@
typedef struct VtAuth VtAuth;
/* op codes */
enum {
VtRError = 1,
VtQPing,
VtRPing,
VtQHello,
VtRHello,
VtQGoodbye,
VtRGoodbye, /* not used */
VtQAuth0,
VtRAuth0,
VtQAuth1,
VtRAuth1,
VtQRead,
VtRRead,
VtQWrite,
VtRWrite,
VtQSync,
VtRSync,
VtMaxOp
};
/* connection state */
enum {
VtStateAlloc,
VtStateConnected,
VtStateClosed,
};
/* auth state */
enum {
VtAuthHello,
VtAuth0,
VtAuth1,
VtAuthOK,
VtAuthFailed,
};
struct VtAuth {
int state;
uchar client[VtScoreSize];
uchar sever[VtScoreSize];
};
struct VtSession {
VtLock *lk;
VtServerVtbl *vtbl; /* == nil means client side */
int cstate; /* connection state */
int fd;
char fderror[ERRMAX];
VtAuth auth;
VtSha1 *inHash;
VtLock *inLock;
Packet *part; /* partial packet */
VtSha1 *outHash;
VtLock *outLock;
int debug;
int version;
int ref;
char *uid;
char *sid;
int cryptoStrength;
int compression;
int crypto;
int codec;
};

View file

@ -1,19 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
char*
vtStrDup(char *s)
{
int n;
char *ss;
if(s == nil)
return nil;
n = strlen(s) + 1;
ss = vtMemAlloc(n);
memmove(ss, s, n);
setmalloctag(ss, getcallerpc(&s));
return ss;
}

View file

@ -1,267 +0,0 @@
protocol version id
both client and server send '\n' terminated ascii of the form
venti-<versions>-<software>
<software> = is a software id which is ignored but may be useful for debugging
If the server and client have the same version number then this
version is used. Otherwise backup to the greatest common
major version number, e.g. 1.00 2.00 etc. If no version in
common then abort. The idea is both client and server should
support a continusous range of major versions. The minor version
numbers are used for development purposes.
After protocol negotiation switch to binary format
all numbers sent big endian
strings are sent with 2 byte length without nulls and in utf-8 max size of 1K
RPC protocol
header
op[1] byte op
tid[2] transation id
client manages the tid space. Until session is established tid must equal 0.
i.e. only one outstanding op.
CipherStrength
None,
Auth,
Weak,
Strong
CipherAlgorithms
None
SSL3
TLS1
CompressionAlgorithms
None
Deflate
Thwack?
BlockTypes
Root
Pointer
Data
==============================================
TPing
RPing
RError
error: string
THello
version:string; know to be supported by both
uid: string
uhash[20] use for cipher boot strapping
cipherstrength[1]
ncipher[1];
cipher[ncipher];
ncompressor[1];
compressor[ncompressor];
RHello
sid: string
shash[20]; use for cipher bott strapping
cipher[1];
compressor[1];
use srp style authentication
g=2
N is safe prime 1024 bits - find a good prime!
x = H("venti" H(sid) H(uid) H(password))
v = g^x
a = random
b = random
B = (v + g^b)
A = g^a
u = first four bytes of H(B)
S = (B - g^x) ^ (a + u*x) = (A * v^u) ^ b
K = H(S)
M1 = H(H(versions) H(THello) H(RHello) A B K)
M2 = H(A M1 K)
TAuth0
A[128]
RAuth0
B[128]
TAuth1
M1[20]
RAuth1
M2[20]
push cipher
push compression
TWrite
length[2] max 56*1024
type[1]
data[length]
RWrite
hash[20]
TRead
hash[20]
type[1]
length[2]
RRead
length[2]
data[length]
============================================================
simplified access when trusting the server
reduces network bandwidth since pointer blocks are not
sent to the client - can also enable permission checking
RReadRoot
root[20]
TReadRoot
name: string
type: string
blocksize[2]
nblock[8]
time[4]
uid: string;
gid: string
RReadData
root[20]
block[8]
length[2]
TReadData
length[2]
collision[1]
data[length]
==============================================
maybe some clients should be required to navigate to block via root nodes.
This would enable permission checking via access to the root node.
RTagOpen
tag[2]
root[20]
TTagOpen
QTagRead
tag[2]
type[1]
length[2]
RTagRead
length[2]
data[length]
QTagWalkRead
tag[2]
ntag[2] can reuse a tag to do an implict clunk
index[2]
type[1]
length[2]
RTagWalkRead
length[2]
data[length]
RTagClunk
tag[2]
TTagClunk
============================
Types of blocks
Data
Root
name[128]
type[128]
score[20] - DirBlock
Pointer
score[20]* the number of hashes can be less than fanout when the
tree is not full
DirBlock
DirEntry[32]*
DirEntry
pointersize[2] - pointer block size
datasize[2] - data blocks size
flag[1] directory
size[7] in bytes - determines pointer depth - intermidate truncated block count as full
score[20] root of pointer blocks or data block
============================
mode flags
(1<<0) ModeOtherExec
(1<<1) ModeOtherWrite
(1<<2) ModeOtherRead
(1<<3) ModeGroupExec
(1<<4) ModeGroupWrite
(1<<5) ModeGroupRead
(1<<6) ModeOwnerExec
(1<<7) ModeOwnerWrite
(1<<8) ModeOwnerRead
(1<<9) ModeSticky
(1<<10) ModeSetUid
(1<<11) ModeSetGid
(1<<12) ModeAppend
(1<<13) ModeExclusive
(1<<14) ModeLink
(1<<15) ModeDir - duplicates dir entry
(1<<16) ModeHidden
(1<<17) ModeSystem
(1<<18) ModeArchive
(1<<19) ModeTemporary
(1<<18) ModeCompressed
(1<<19) ModeEncrypted
extraType
2 Plan9
version[4]
muid: string
3 NT Time
createTime[8];
modifyTime[8];
accessTime[8]
MetaEntry
name: string /* must be first */
direntry[4]
id[8]
uid: string
gui: string
mtime[4]
ctime[4]
atime[4]
mode[4]
extratype;
extrasize[2]
extra:[nextra]
MetaEntry Block
magic[4]
size[2]
free[2] - used to determine if work compacting
maxindex[2] - size of index table in bytes
nindex[2]
index[2*nindex]
per OS directory entries?
inode...

View file

@ -1,79 +0,0 @@
#include <u.h>
#include <libc.h>
#include <oventi.h>
/* score of a zero length block */
uchar vtZeroScore[VtScoreSize] = {
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
};
int
vtZeroExtend(int type, uchar *buf, int n, int nn)
{
uchar *p, *ep;
switch(type) {
default:
memset(buf+n, 0, nn-n);
break;
case VtPointerType0:
case VtPointerType1:
case VtPointerType2:
case VtPointerType3:
case VtPointerType4:
case VtPointerType5:
case VtPointerType6:
case VtPointerType7:
case VtPointerType8:
case VtPointerType9:
p = buf + (n/VtScoreSize)*VtScoreSize;
ep = buf + (nn/VtScoreSize)*VtScoreSize;
while(p < ep) {
memmove(p, vtZeroScore, VtScoreSize);
p += VtScoreSize;
}
memset(p, 0, buf+nn-p);
break;
}
return 1;
}
int
vtZeroTruncate(int type, uchar *buf, int n)
{
uchar *p;
switch(type) {
default:
for(p = buf + n; p > buf; p--) {
if(p[-1] != 0)
break;
}
return p - buf;
case VtRootType:
if(n < VtRootSize)
return n;
return VtRootSize;
case VtPointerType0:
case VtPointerType1:
case VtPointerType2:
case VtPointerType3:
case VtPointerType4:
case VtPointerType5:
case VtPointerType6:
case VtPointerType7:
case VtPointerType8:
case VtPointerType9:
/* ignore slop at end of block */
p = buf + (n/VtScoreSize)*VtScoreSize;
while(p > buf) {
if(memcmp(p - VtScoreSize, vtZeroScore, VtScoreSize) != 0)
break;
p -= VtScoreSize;
}
return p - buf;
}
}

View file

@ -28,7 +28,6 @@ LIBS=\
libmemlayer\
libmp\
libndb\
liboventi\
libplumb\
libregexp\
libscribble\