503 lines
9.9 KiB
C
503 lines
9.9 KiB
C
#pragma lib "libventi.a"
|
|
#pragma src "/sys/src/libventi"
|
|
|
|
|
|
/* XXX should be own library? */
|
|
/*
|
|
* Packets
|
|
*/
|
|
enum
|
|
{
|
|
MaxFragSize = 9*1024
|
|
};
|
|
|
|
typedef struct Packet Packet;
|
|
#pragma incomplete Packet
|
|
|
|
Packet* packetalloc(void);
|
|
void packetappend(Packet*, uchar *buf, int n);
|
|
uint packetasize(Packet*);
|
|
int packetcmp(Packet*, Packet*);
|
|
int packetcompact(Packet*);
|
|
void packetconcat(Packet*, Packet*);
|
|
int packetconsume(Packet*, uchar *buf, int n);
|
|
int packetcopy(Packet*, uchar *buf, int offset, int n);
|
|
Packet* packetdup(Packet*, int offset, int n);
|
|
Packet* packetforeign(uchar *buf, int n, void (*free)(void *a), void *a);
|
|
int packetfragments(Packet*, IOchunk*, int nio, int offset);
|
|
void packetfree(Packet*);
|
|
uchar* packetheader(Packet*, int n);
|
|
uchar* packetpeek(Packet*, uchar *buf, int offset, int n);
|
|
void packetprefix(Packet*, uchar *buf, int n);
|
|
void packetsha1(Packet*, uchar sha1[20]);
|
|
uint packetsize(Packet*);
|
|
Packet* packetsplit(Packet*, int n);
|
|
void packetstats(void);
|
|
uchar* packettrailer(Packet*, int n);
|
|
int packettrim(Packet*, int offset, int n);
|
|
|
|
/* XXX should be own library? */
|
|
/*
|
|
* Logging
|
|
*/
|
|
typedef struct VtLog VtLog;
|
|
typedef struct VtLogChunk VtLogChunk;
|
|
|
|
struct VtLog
|
|
{
|
|
VtLog *next; /* in hash table */
|
|
char *name;
|
|
VtLogChunk *chunk;
|
|
uint nchunk;
|
|
VtLogChunk *w;
|
|
QLock lk;
|
|
int ref;
|
|
};
|
|
|
|
struct VtLogChunk
|
|
{
|
|
char *p;
|
|
char *ep;
|
|
char *wp;
|
|
};
|
|
|
|
VtLog* vtlogopen(char *name, uint size);
|
|
void vtlogprint(VtLog *log, char *fmt, ...);
|
|
void vtlog(char *name, char *fmt, ...);
|
|
void vtlogclose(VtLog*);
|
|
void vtlogremove(char *name);
|
|
char** vtlognames(int*);
|
|
void vtlogdump(int fd, VtLog*);
|
|
|
|
/* XXX begin actual venti.h */
|
|
|
|
typedef struct VtFcall VtFcall;
|
|
typedef struct VtConn VtConn;
|
|
typedef struct VtEntry VtEntry;
|
|
typedef struct VtRoot VtRoot;
|
|
|
|
/*
|
|
* Fundamental constants.
|
|
*/
|
|
enum
|
|
{
|
|
VtScoreSize = 20,
|
|
VtMaxStringSize = 1024,
|
|
VtMaxLumpSize = 56*1024,
|
|
VtPointerDepth = 7
|
|
};
|
|
#define VtMaxFileSize ((1ULL<<48)-1)
|
|
|
|
|
|
/*
|
|
* Strings in packets.
|
|
*/
|
|
int vtputstring(Packet*, char*);
|
|
int vtgetstring(Packet*, char**);
|
|
|
|
/*
|
|
* Block types.
|
|
*
|
|
* The initial Venti protocol had a much
|
|
* less regular list of block types.
|
|
* VtToDiskType converts from new to old.
|
|
*/
|
|
enum
|
|
{
|
|
VtDataType = 0<<3,
|
|
/* VtDataType+1, ... */
|
|
VtDirType = 1<<3,
|
|
/* VtDirType+1, ... */
|
|
VtRootType = 2<<3,
|
|
VtMaxType,
|
|
VtCorruptType = 0xFF,
|
|
|
|
VtTypeDepthMask = 7,
|
|
VtTypeBaseMask = ~VtTypeDepthMask
|
|
};
|
|
|
|
/* convert to/from on-disk type numbers */
|
|
uint vttodisktype(uint);
|
|
uint vtfromdisktype(uint);
|
|
|
|
/*
|
|
* VtEntry describes a Venti stream
|
|
*
|
|
* The _ enums are only used on the wire.
|
|
* They are not present in the VtEntry structure
|
|
* and should not be used by client programs.
|
|
* (The info is in the type field.)
|
|
*/
|
|
enum
|
|
{
|
|
VtEntryActive = 1<<0, /* entry is in use */
|
|
_VtEntryDir = 1<<1, /* a directory */
|
|
_VtEntryDepthShift = 2, /* shift for pointer depth */
|
|
_VtEntryDepthMask = 7<<2, /* mask for pointer depth */
|
|
VtEntryLocal = 1<<5, /* for local storage only */
|
|
VtEntryNoArchive = 1<<6 /* for local storage only */
|
|
};
|
|
enum
|
|
{
|
|
VtEntrySize = 40
|
|
};
|
|
struct VtEntry
|
|
{
|
|
ulong gen; /* generation number */
|
|
ushort psize; /* pointer block size */
|
|
ushort dsize; /* data block size */
|
|
uchar type;
|
|
uchar flags;
|
|
uvlong size;
|
|
uchar score[VtScoreSize];
|
|
};
|
|
|
|
void vtentrypack(VtEntry*, uchar*, int index);
|
|
int vtentryunpack(VtEntry*, uchar*, int index);
|
|
|
|
struct VtRoot
|
|
{
|
|
char name[128];
|
|
char type[128];
|
|
uchar score[VtScoreSize]; /* to a Dir block */
|
|
ushort blocksize; /* maximum block size */
|
|
uchar prev[VtScoreSize]; /* last root block */
|
|
};
|
|
|
|
enum
|
|
{
|
|
VtRootSize = 300,
|
|
VtRootVersion = 2
|
|
};
|
|
|
|
void vtrootpack(VtRoot*, uchar*);
|
|
int vtrootunpack(VtRoot*, uchar*);
|
|
|
|
/*
|
|
* score of zero length block
|
|
*/
|
|
extern uchar vtzeroscore[VtScoreSize];
|
|
|
|
/*
|
|
* zero extend and truncate blocks
|
|
*/
|
|
void vtzeroextend(int type, uchar *buf, uint n, uint nn);
|
|
uint vtzerotruncate(int type, uchar *buf, uint n);
|
|
|
|
/*
|
|
* parse score: mungs s
|
|
*/
|
|
int vtparsescore(char *s, char **prefix, uchar[VtScoreSize]);
|
|
|
|
/*
|
|
* formatting
|
|
* other than noted, these formats all ignore
|
|
* the width and precision arguments, and all flags
|
|
*
|
|
* V a venti score
|
|
*/
|
|
#pragma varargck type "V" uchar*
|
|
#pragma varargck type "F" VtFcall*
|
|
#pragma varargck type "T" void
|
|
#pragma varargck type "lT" void
|
|
|
|
int vtscorefmt(Fmt*);
|
|
|
|
/*
|
|
* error-checking malloc et al.
|
|
*/
|
|
void vtfree(void *);
|
|
void* vtmalloc(int);
|
|
void* vtmallocz(int);
|
|
void* vtrealloc(void *p, int);
|
|
void* vtbrk(int n);
|
|
char* vtstrdup(char *);
|
|
|
|
/*
|
|
* Venti protocol
|
|
*/
|
|
|
|
/*
|
|
* Crypto strengths
|
|
*/
|
|
enum
|
|
{
|
|
VtCryptoStrengthNone,
|
|
VtCryptoStrengthAuth,
|
|
VtCryptoStrengthWeak,
|
|
VtCryptoStrengthStrong
|
|
};
|
|
|
|
/*
|
|
* Crypto suites
|
|
*/
|
|
enum
|
|
{
|
|
VtCryptoNone,
|
|
VtCryptoSSL3,
|
|
VtCryptoTLS1,
|
|
VtCryptoMax
|
|
};
|
|
|
|
/*
|
|
* Codecs
|
|
*/
|
|
enum
|
|
{
|
|
VtCodecNone,
|
|
VtCodecDeflate,
|
|
VtCodecThwack,
|
|
VtCodecMax
|
|
};
|
|
|
|
enum
|
|
{
|
|
VtRerror = 1,
|
|
VtTping = 2,
|
|
VtRping,
|
|
VtThello = 4,
|
|
VtRhello,
|
|
VtTgoodbye = 6,
|
|
VtRgoodbye, /* not used */
|
|
VtTauth0 = 8,
|
|
VtRauth0,
|
|
VtTauth1 = 10,
|
|
VtRauth1,
|
|
VtTread = 12,
|
|
VtRread,
|
|
VtTwrite = 14,
|
|
VtRwrite,
|
|
VtTsync = 16,
|
|
VtRsync,
|
|
|
|
VtTmax
|
|
};
|
|
|
|
struct VtFcall
|
|
{
|
|
uchar msgtype;
|
|
uchar tag;
|
|
|
|
char *error; /* Rerror */
|
|
|
|
char *version; /* Thello */
|
|
char *uid; /* Thello */
|
|
uchar strength; /* Thello */
|
|
uchar *crypto; /* Thello */
|
|
uint ncrypto; /* Thello */
|
|
uchar *codec; /* Thello */
|
|
uint ncodec; /* Thello */
|
|
char *sid; /* Rhello */
|
|
uchar rcrypto; /* Rhello */
|
|
uchar rcodec; /* Rhello */
|
|
uchar *auth; /* TauthX, RauthX */
|
|
uint nauth; /* TauthX, RauthX */
|
|
uchar score[VtScoreSize]; /* Tread, Rwrite */
|
|
uchar blocktype; /* Tread, Twrite */
|
|
ushort count; /* Tread */
|
|
Packet *data; /* Rread, Twrite */
|
|
};
|
|
|
|
Packet* vtfcallpack(VtFcall*);
|
|
int vtfcallunpack(VtFcall*, Packet*);
|
|
void vtfcallclear(VtFcall*);
|
|
int vtfcallfmt(Fmt*);
|
|
|
|
enum
|
|
{
|
|
VtStateAlloc,
|
|
VtStateConnected,
|
|
VtStateClosed
|
|
};
|
|
|
|
struct VtConn
|
|
{
|
|
QLock lk;
|
|
QLock inlk;
|
|
QLock outlk;
|
|
int debug;
|
|
int infd;
|
|
int outfd;
|
|
int muxer;
|
|
void *writeq;
|
|
void *readq;
|
|
int state;
|
|
void *wait[256];
|
|
uint ntag;
|
|
uint nsleep;
|
|
Packet *part;
|
|
Rendez tagrend;
|
|
Rendez rpcfork;
|
|
char *version;
|
|
char *uid;
|
|
char *sid;
|
|
char addr[256]; /* address of other side */
|
|
};
|
|
|
|
VtConn* vtconn(int infd, int outfd);
|
|
int vtreconn(VtConn*, int, int);
|
|
VtConn* vtdial(char*);
|
|
int vtredial(VtConn*, char*);
|
|
void vtfreeconn(VtConn*);
|
|
int vtsend(VtConn*, Packet*);
|
|
Packet* vtrecv(VtConn*);
|
|
int vtversion(VtConn* z);
|
|
void vtdebug(VtConn* z, char*, ...);
|
|
void vthangup(VtConn* z);
|
|
int vtgoodbye(VtConn* z);
|
|
|
|
/* #pragma varargck argpos vtdebug 2 */
|
|
|
|
/* server */
|
|
typedef struct VtSrv VtSrv;
|
|
#pragma incomplete VtSrv
|
|
typedef struct VtReq VtReq;
|
|
struct VtReq
|
|
{
|
|
VtFcall tx;
|
|
VtFcall rx;
|
|
/* private */
|
|
VtSrv *srv;
|
|
void *sc;
|
|
};
|
|
|
|
int vtsrvhello(VtConn*);
|
|
VtSrv* vtlisten(char *addr);
|
|
VtReq* vtgetreq(VtSrv*);
|
|
void vtrespond(VtReq*);
|
|
|
|
/* client */
|
|
Packet* vtrpc(VtConn*, Packet*);
|
|
Packet* _vtrpc(VtConn*, Packet*, VtFcall*);
|
|
void vtrecvproc(void*); /* VtConn */
|
|
void vtsendproc(void*); /* VtConn */
|
|
|
|
int vtconnect(VtConn*);
|
|
int vthello(VtConn*);
|
|
int vtread(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);
|
|
int vtwrite(VtConn*, uchar score[VtScoreSize], uint type, uchar *buf, int n);
|
|
Packet* vtreadpacket(VtConn*, uchar score[VtScoreSize], uint type, int n);
|
|
int vtwritepacket(VtConn*, uchar score[VtScoreSize], uint type, Packet *p);
|
|
int vtsync(VtConn*);
|
|
int vtping(VtConn*);
|
|
|
|
/* sha1 */
|
|
void vtsha1(uchar score[VtScoreSize], uchar*, int);
|
|
int vtsha1check(uchar score[VtScoreSize], uchar*, int);
|
|
|
|
/*
|
|
* Data blocks and block cache.
|
|
*/
|
|
enum
|
|
{
|
|
NilBlock = ~0
|
|
};
|
|
|
|
typedef struct VtBlock VtBlock;
|
|
typedef struct VtCache VtCache;
|
|
#pragma incomplete VtCache
|
|
|
|
struct VtBlock
|
|
{
|
|
VtCache *c;
|
|
QLock lk;
|
|
|
|
uchar *data;
|
|
uchar score[VtScoreSize];
|
|
uchar type; /* BtXXX */
|
|
|
|
/* internal to cache */
|
|
int nlock;
|
|
int iostate;
|
|
int ref;
|
|
u32int heap;
|
|
VtBlock *next;
|
|
VtBlock **prev;
|
|
u32int used;
|
|
u32int used2;
|
|
u32int addr;
|
|
uintptr pc;
|
|
};
|
|
|
|
u32int vtglobaltolocal(uchar[VtScoreSize]);
|
|
void vtlocaltoglobal(u32int, uchar[VtScoreSize]);
|
|
|
|
VtCache*vtcachealloc(VtConn*, int blocksize, ulong nblocks);
|
|
void vtcachefree(VtCache*);
|
|
VtBlock*vtcachelocal(VtCache*, u32int addr, int type);
|
|
VtBlock*vtcacheglobal(VtCache*, uchar[VtScoreSize], int type);
|
|
VtBlock*vtcacheallocblock(VtCache*, int type);
|
|
void vtcachesetwrite(VtCache*,
|
|
int(*)(VtConn*, uchar[VtScoreSize], uint, uchar*, int));
|
|
void vtblockput(VtBlock*);
|
|
u32int vtcacheblocksize(VtCache*);
|
|
int vtblockwrite(VtBlock*);
|
|
VtBlock*vtblockcopy(VtBlock*);
|
|
void vtblockduplock(VtBlock*);
|
|
|
|
extern int vtcachencopy, vtcachenread, vtcachenwrite;
|
|
extern int vttracelevel;
|
|
|
|
/*
|
|
* Hash tree file tree.
|
|
*/
|
|
typedef struct VtFile VtFile;
|
|
struct VtFile
|
|
{
|
|
QLock lk;
|
|
int ref;
|
|
int local;
|
|
VtBlock *b; /* block containing this file */
|
|
uchar score[VtScoreSize]; /* score of block containing this file */
|
|
|
|
/* immutable */
|
|
VtCache *c;
|
|
int mode;
|
|
u32int gen;
|
|
int dsize;
|
|
int psize;
|
|
int dir;
|
|
VtFile *parent;
|
|
int epb; /* entries per block in parent */
|
|
u32int offset; /* entry offset in parent */
|
|
};
|
|
|
|
enum
|
|
{
|
|
VtOREAD,
|
|
VtOWRITE,
|
|
VtORDWR
|
|
};
|
|
|
|
VtBlock*vtfileblock(VtFile*, u32int, int mode);
|
|
int vtfileblockscore(VtFile*, u32int, uchar[VtScoreSize]);
|
|
void vtfileclose(VtFile*);
|
|
VtFile* _vtfilecreate(VtFile*, int offset, int psize, int dsize, int dir);
|
|
VtFile* vtfilecreate(VtFile*, int psize, int dsize, int dir);
|
|
VtFile* vtfilecreateroot(VtCache*, int psize, int dsize, int type);
|
|
int vtfileflush(VtFile*);
|
|
int vtfileflushbefore(VtFile*, u64int);
|
|
u32int vtfilegetdirsize(VtFile*);
|
|
int vtfilegetentry(VtFile*, VtEntry*);
|
|
uvlong vtfilegetsize(VtFile*);
|
|
void vtfileincref(VtFile*);
|
|
int vtfilelock2(VtFile*, VtFile*, int);
|
|
int vtfilelock(VtFile*, int);
|
|
VtFile* vtfileopen(VtFile*, u32int, int);
|
|
VtFile* vtfileopenroot(VtCache*, VtEntry*);
|
|
long vtfileread(VtFile*, void*, long, vlong);
|
|
int vtfileremove(VtFile*);
|
|
int vtfilesetdirsize(VtFile*, u32int);
|
|
int vtfilesetentry(VtFile*, VtEntry*);
|
|
int vtfilesetsize(VtFile*, u64int);
|
|
int vtfiletruncate(VtFile*);
|
|
void vtfileunlock(VtFile*);
|
|
long vtfilewrite(VtFile*, void*, long, vlong);
|
|
|
|
int vttimefmt(Fmt*);
|
|
|
|
extern int chattyventi;
|
|
extern int ventidoublechecksha1;
|
|
extern int ventilogging;
|
|
|
|
extern char *VtServerLog;
|