From 5e76df283f055ca6a3e4c1a2290859677e09d77e Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 21 Jul 2025 22:44:57 +0200 Subject: [PATCH] Mon 21 Jul 22:43:21 CEST 2025 --- js/dos/dns_srv_common.js | 639 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 639 insertions(+) create mode 100644 js/dos/dns_srv_common.js diff --git a/js/dos/dns_srv_common.js b/js/dos/dns_srv_common.js new file mode 100644 index 0000000..ce6862f --- /dev/null +++ b/js/dos/dns_srv_common.js @@ -0,0 +1,639 @@ +/** + ** ================================== + ** OOOO OOOO OOOO O O OOOO + ** O O O O O O O O O + ** O O O O O O O O O + ** OOOO OOOO OOOO O OOO OOOO + ** O O O O O O O O O + ** O O O O O O O O O + ** OOOO OOOO OOOO OOOO O O OOOO + ** ================================== + ** BSSLAB, Dr. Stefan Bosse http://www.bsslab.de + ** + ** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED + ** BY THE AUTHOR. + ** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED, + ** MODIFIED, OR OTHERWISE USED IN A CONTEXT + ** OUTSIDE OF THE SOFTWARE SYSTEM. + ** + ** $AUTHORS: Stefan Bosse + ** $INITIAL: (C) 2006-2016 BSSLAB + ** $CREATED: 5/27/15 by sbosse. + ** $VERSION: 1.1.2 + ** + ** $INFO: + ** + ** DOS: DNS Server Interface Commmon + ** + ** $ENDOFINFO + */ +"use strict"; +var Sch = Require('dos/scheduler'); +var Net = Require('dos/network'); +var Buf = Require('dos/buf'); +var Dns = Require('dos/dns'); +var Io = Require('com/io'); +var Cs = Require('dos/capset'); +var Comp = Require('com/compat'); +var Array = Comp.array; +var assert = Comp.assert; +var div = Comp.div; + +/**************************** + DNS Host File System + AFS +***************************/ + +/* + ** Cache parameters + */ +var DEF_INODE_ENTRIES = 500; +var DEF_DIR_ENTRIES = 200; +/** + ** Age periodically the data cache and remove timed out + ** cache objects [sec]. + */ +var CACHE_GC_TIME = 10; + +/** + ** Directory has a lifetime between MAXLIVE and 0. + ** Zero lifetime means: destroy the directory after an age request. + */ +var DNS_MAX_LIVE = 8; + +var DEF_BLOCK_SIZE = 512; +var DEF_MAGIC_SIZE = 32; + +/* + ** The right bit for each column. In dead, only the first + ** DNS_MAXCOLUMNS array elements are used. + */ +var dns_col_bits = [0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80]; + +/** + * + * @type {{DNSMODE_ONECOPY: number, DNSMODE_TWOCOPY: number}} + */ +var Dns_mode = { + DNSMODE_ONECOPY: 1, // Default file server number = 0 + DNSMODE_TWOCOPY: 2 // Duplicated file server mode +}; + +/** + * + * @param c_inode_buffers Number of i-node cache buffers + * @param c_inode_size Size of one i-node cache buffer [blocks] + * @param c_dir_buffers Number of directory cache buffers + * @param c_dir_size Size of one directory buffer [blocks] + * @constructor + */ +var dns_cache_parameter = function (c_inode_buffers,c_inode_size,c_dir_buffers,c_dir_size) { + this.c_inode_buffers=c_inode_buffers; + this.c_inode_size=c_inode_size; + this.c_dir_buffers=c_dir_buffers; + this.c_dir_size=c_dir_size; +}; + +/** + * + * @param c_inode_buffers Number of i-node cache buffers + * @param c_inode_size Size of one i-node cache buffer [blocks] + * @param c_dir_buffers Number of directory cache buffers + * @param c_dir_size Size of one directory buffer [blocks] + * @returns {dns_cache_parameter} + */ +var Dns_cache_parameter = function (c_inode_buffers,c_inode_size,c_dir_buffers,c_dir_size) { + var obj = new dns_cache_parameter(c_inode_buffers,c_inode_size,c_dir_buffers,c_dir_size); + Object.preventExtensions(obj); + return obj; +}; + +/* + ** Disk Magic Label + */ + +var MAGIC_STR = "AMOEBA::DNS::INODE::032"; + +/* + ** SERVER + * ====== + ** Disk layout + ** + ** Directory Table Partition: + ** + ** ------------------------- + ** 512 bytes: + ** 32 bytes : magic header + ** 480 bytes : super structure + ** ------------------------- + ** Directory (inode) table + ** + ** + ** ------------------------- + ** Live table + ** ------------------------- + ** + ** + ** The directory table contains the capability set of a directory (aka. + ** directory object number to capability set mapping). + */ + +/** + * + * @param i_objnum + * @param {capability []} i_caps + * @param i_size + * @param {(Afs_file_state.FF_invalid|*)} i_state + */ +var dns_inode = function (i_objnum, i_caps, i_size, i_state) { + this.i_objnum = i_objnum; // int: Directory object number + this.i_caps = i_caps; // capability array: referenced objects + this.i_size = i_size; // int: size of referenced object if any + this.i_state = i_state; // int: used or not +}; + +var DNS_INODE_SIZE = 2*4+2+2*Net.CAP_SIZE; +var DEF_INODE_SIZE = DNS_INODE_SIZE; +/* + ** The filesystem server informations we need to store the directory files + ** and to tell clients about the default fileserver. We can use up + ** to two file servers. + */ + +/** + * + * @type {{FS_down: number, FS_up: number, FS_unknown: number}} + */ +var Fs_state = { + FS_down:0, + FS_up:1, + FS_unknown:2 +}; + + +/** + * + * @param {capability []} fs_cap + * @param {fs_state []} fs_state + * @param {number} fs_default + * @param {(Dns_mode.DNSMODE_ONECOPY|*)} fs_mode + * @constructor + */ +var fs_server = function (fs_cap,fs_state,fs_default,fs_mode) { + this.fs_cap=fs_cap; // capability array; (* FS server ports *) + this.fs_state=fs_state; // fs_state array; (* FS server state *) + this.fs_default=fs_default; // int; (* Cuurent default *) + this.fs_mode=fs_mode; // dns_mode; +}; + +/** + * + * @param {capability []} fs_cap + * @param {fs_state []} fs_state + * @param {number} fs_default + * @param {(Dns_mode.DNSMODE_ONECOPY|*)} fs_mode + * @returns {fs_server} + * + */ +function Fs_server(fs_cap,fs_state,fs_default,fs_mode) { + var obj = new fs_server(fs_cap,fs_state,fs_default,fs_mode); + Object.preventExtensions(obj); + return obj; +} + +/* + ** The main DNS structure: the all known super structure with basic + ** information about the directory system. + */ + + +/** + * + * @param {string} dns_name + * @param {number} dns_block_size + * @param {port} dns_getport + * @param {port} dns_putport + * @param {port} dns_checkfield + * @param {number} dns_ncols + * @param {string []} dns_colnames + * @param {number []} dns_generic_colmask + * @param {fs_server} dns_fs + * @constructor + * @typedef {{dns_name,dns_blocksize,dns_ndirs,dns_nused,dns_freeobjnumds,dns_nextfree,dns_getport,dns_putport,dns_checkfield, + * dns_ncols,dns_colnames:string [],dns_generic_colmask: number [],dns_fs:fs_server,dns_lock:lock}} dns_super~obj + * @see dns_super~obj + */ +var dns_super = function (dns_name, dns_block_size, dns_getport, dns_putport, dns_checkfield, dns_ncols, dns_colnames, dns_generic_colmask, dns_fs) { + this.dns_name = dns_name||''; // string: The server name + this.dns_ndirs = 0; // int: Number of total table entries + this.dns_nused = 0; // int: Number of used table entries + this.dns_freeobjnums = []; // int array: Free slots list + this.dns_nextfree = 1; // int: Next free slot + + this.dns_block_size = dns_block_size||0; + + this.dns_getport = dns_getport; // port: Private getport + this.dns_putport = dns_putport; // port: Public putport + this.dns_checkfield = dns_checkfield; // port: Private checkfield + + this.dns_ncols = dns_ncols||0; // int: Number of columns + this.dns_colnames = dns_colnames||[]; // string array: Column names + this.dns_generic_colmask = dns_generic_colmask||[]; // rights_bits array: Column mask + + + this.dns_fs = dns_fs; // AFS file server capability [2]; all directories are saved there + this.dns_lock = Sch.Lock(); + +}; + +/** + * @typedef {{lock,unlock,try_lock,print}} afs_super~meth + */ + +/** Lock super structure [BLOCKING] + * + */ +dns_super.prototype.lock = function () { + // assert((!this.dns_lock.is_locked())||('dns_super is already locked!')); + this.dns_lock.acquire(); +}; +/** + * + */ +dns_super.prototype.try_lock = function () { + return this.dns_lock.try_acquire(); +}; + +/** + * + */ +dns_super.prototype.try_lock = function () { + return this.dns_lock.try_acquire(); +}; + +/** + * + */ +dns_super.prototype.unlock = function () { + this.dns_lock.release(); +}; +dns_super.prototype.print = function () { + var str=''; + str='SUPER BLOCK:\n'; + str=str+' LABEL = '+this.dns_name+'\n'; + str=str+' BLSIZE = '+this.dns_block_size+'\n'; + str=str+' DIRS = '+this.dns_ndirs+'\n'; + str=str+' USED = '+this.dns_nused+'\n'; + str=str+' FREE = '+this.dns_freeobjnums.length+'\n'; + str=str+' NEXTFREE = '+this.dns_nextfree+'\n'; + str=str+' GETPORT = '+Net.Print.port(this.dns_getport)+'\n'; + str=str+' PUTPORT = '+Net.Print.port(this.dns_putport)+'\n'; + str=str+' CHECKFI = '+Net.Print.port(this.dns_checkfield)+'\n'; + return str; + +}; + +/** + * + * @param i_objnum + * @param {capability []} i_caps + * @param i_size + * @param {(Afs_file_state.FF_invalid|*)} i_state + * @returns {dns_inode} + */ +function Dns_inode(i_objnum,i_caps,i_size,i_state) { + var obj = new dns_inode(i_objnum,i_caps,i_size,i_state); + Object.preventExtensions(obj); + return obj; +} + + +/** + * + * @param dns_name + * @param {number} dns_blocksize + * @param dns_getport + * @param dns_putport + * @param dns_checkfield + * @param dns_ncols + * @param dns_colnames + * @param dns_generic_colmask + * @param dns_file + * @returns {dns_super} + */ +function Dns_super(dns_name,dns_block_size,dns_getport,dns_putport,dns_checkfield,dns_ncols,dns_colnames,dns_generic_colmask,dns_file) { + var obj = new dns_super(dns_name,dns_block_size,dns_getport,dns_putport,dns_checkfield,dns_ncols,dns_colnames,dns_generic_colmask,dns_file); + Object.preventExtensions(obj); + return obj; +} + +/** + * + * @param buf + * @param ncols + * @param row + */ +function buf_put_row(buf,ncols,row) { + Buf.buf_put_string(buf,row.dr_name); + Buf.buf_put_int32(buf,row.dr_time); + for(var i=0;i Net.DNS_MAXCOLUMNS) { + Io.warn ('DNS: Warning: ncols='+ncols+' rowname='+row.dr_name); + } + var rights = []; + for (var i=0; i< ncols; i++) { + var rg = Dns.buf_get_rights(buf); + rights.push(rg); + } + row.dr_columns=rights; + row.dr_capset = Cs.buf_get_capset(buf); + return row; +} + +function buf_put_dir(buf,dir) { + var i; + Buf.buf_put_int32(buf,dir.dd_objnum); + Buf.buf_put_int32(buf,dir.dd_ncols); + Buf.buf_put_int32(buf,dir.dd_nrows); + for (i in dir.dd_colnames) { + var colname=dir.dd_colnames[i]; + Buf.buf_put_string(buf,colname); + } + Buf.buf_put_port(buf,dir.dd_random); + for (i in dir.dd_rows) { + var row=dir.dd_rows[i]; + buf_put_row(buf,dir.dd_ncols,row); + } + Buf.buf_put_int32(buf,dir.dd_time); +} + +function buf_get_dir(buf,dir) { + var i; + if (dir==undefined) dir=Dns_dir(); + dir.dd_objnum=Buf.buf_get_int32(buf); + dir.dd_ncols=Buf.buf_get_int32(buf); + dir.dd_nrows=Buf.buf_get_int32(buf); + var colnames=[]; + for(i=0;i a new directory AFS object must be created! + */ + + DD_modified: 3, + /* + ** Read only directory (standard case) + */ + DD_locked: 4 +}; + +/***************** + DNS Server Common +********************/ + +/** + * + * @param {string} dr_name + * @param {number} dr_time + * @param {number []} dr_columns + * @param {capset} dr_capset + * @constructor + * @typedef {{dr_name:string, dr_time:number, dr_columns:number [], dr_capset:capset}} dns_row~obj + * @see dns_row~obj + */ +var dns_row = function (dr_name, dr_time, dr_columns, dr_capset) { + this.dr_name = dr_name; // string: The row name + this.dr_time = dr_time; // integer: Time stamp + this.dr_columns = dr_columns; // rights_bits array: The rights mask + this.dr_capset = dr_capset; // capset: Row capability set +}; + +/** + * + * @param {string} dr_name + * @param {number} dr_time + * @param {* []} dr_columns + * @param {capset} dr_capset + * @returns {dns_row} + */ +function Dns_row(dr_name, dr_time, dr_columns, dr_capset) { + var obj = new dns_row(dr_name, dr_time, dr_columns, dr_capset); + Object.preventExtensions(obj); + return obj; +} + +/** + * + * @param {number} dd_objnum + * @param {number} dd_ncols + * @param {number} dd_nrows + * @param {string []} dd_colnames + * @param {port} dd_random + * @param {dns_row []} dd_rows + * @param {(Dns_dir_state.DD_invalid|*)} dd_state + * @param {number} dd_time + * @param {number} dd_live + * @constructor + * @typedef {{dd_objnum, dd_ncols, dd_nrows, dd_colnames: string [], dd_random: port, dd_rows:dns_Row [], + * dd_state:(Dns_dir_state.DD_invalid|*), dd_time, dd_live, dd_lock: lock}} dns_dir~obj + * @see dns_dir~obj + * @see dns_dir~meth + */ + +var dns_dir = function (dd_objnum, dd_ncols, dd_nrows, dd_colnames, dd_random, dd_rows, dd_state, dd_time, dd_live) { + this.dd_objnum = dd_objnum; // int: The directory index number + this.dd_ncols = dd_ncols; // int: Number of columns + this.dd_nrows = dd_nrows; // int: Number of rows in this dir + this.dd_colnames = dd_colnames; // string array: The column names + this.dd_random = dd_random; // port: Random check number + this.dd_rows = dd_rows||[]; // dns_row array: All the rows + this.dd_state = dd_state||Dns_dir_state.DD_invalid; // dns_dir_state: Status of the directory + this.dd_time = dd_time||0; // int: Time stamp + this.dd_live = dd_live||0; // int; Live time [0..MAXLIVE] + this.dd_lock = Sch.Lock(); +}; +/** + * + * @param {number} dd_objnum + * @param {number} dd_ncols + * @param {number} dd_nrows + * @param {string []} dd_colnames + * @param {port} dd_random + * @param {dns_row []} dd_rows + * @param {(Dns_dir_state.DD_invalid|*)} dd_state + * @param {number} dd_time + * @param {number} dd_live + * @returns {dns_dir} + */ +function Dns_dir(dd_objnum, dd_ncols, dd_nrows, dd_colnames, dd_random, dd_rows, dd_state, dd_time, dd_live) { + var obj = new dns_dir(dd_objnum, dd_ncols, dd_nrows, dd_colnames, dd_random, dd_rows, dd_state, dd_time, dd_live); + Object.preventExtensions(obj); + return obj; +} + +/** + * @typedef {{ + * lock:dns_dir.lock, + * unlock:dns_dir.unlock + * }} dns_dir~meth + */ +/** Lock directory - can block + * + */ +dns_dir.prototype.lock = function () { + this.dd_lock.acquire(); +}; + + +dns_dir.prototype.try_lock = function () { + return this.dd_lock.try_acquire(); +}; + +/** Unlock directory + * + */ +dns_dir.prototype.unlock = function () { + this.dd_lock.release(); +}; + +dns_dir.prototype.init = function (dd_colnames,dd_state,dd_time,dd_live) { + this.dd_colnames=dd_colnames; + this.dd_ncols=dd_colnames.length; + this.dd_rows=[]; + this.dd_random = Net.uniqport(); + this.dd_state=dd_state||Dns_dir_state.DD_invalid; + this.dd_time=dd_time||0; + this.dd_live=dd_live||0; + this.dd_lock.init(); +}; + +/** Calculate the size of a directory structure. + * + * @returns {number} + */ +dns_dir.prototype.size = function () { + var self=this; + var size=0; + size=4*Buf.SIZEOF_INT32; // dd_objnum,dd_ncols,dd_nrows,dd_time + Array.iter(self.dd_colnames,function (col) { + size=size+col.length+1; + }); + size=size+Buf.PORT_SIZE; + Array.iter(self.dd_rows, function (row) { + size=size+Buf.SIZEOF_INT32+row.dr_name.length+1+Cs.CAPSET_SIZE+Array.length(row.dr_columns)*Dns.RIGHTS_SIZE; + }); + return size; +}; + + +/** DNS Server Common + * + * @type {{CACHE_GC_TIME: number, DEF_BLOCK_SIZE: number, DEF_INODE_ENTRIES: number, DEF_INODE_SIZE: number, DEF_DIR_ENTRIES: number, DEF_DIR_BUFSIZE: number, DEF_MAGIC_SIZE: number, DNS_MAX_LIVE: number, DNS_INODE_SIZE: number, MAGIC_STR: string, Dns_dir_state: {DD_invalid: number, DD_unlocked: number, DD_modified: number, DD_locked: number}, Dns_mode: {DNSMODE_ONECOPY: number, DNSMODE_TWOCOPY: number}, Dns_row: Dns_row, Dns_dir: Dns_dir, Dns_cache_parameter: Function, Dns_inode: Dns_inode, Dns_super: Dns_super, Fs_server: Fs_server, Fs_state: {FS_down: number, FS_up: number, FS_unknown: number}, buf_put_row: buf_put_row, buf_get_row: buf_get_row, buf_put_dir: buf_put_dir, buf_get_dir: buf_get_dir, buf_put_inode: buf_put_inode, buf_get_inode: buf_get_inode, off_of_inode: off_of_inode}} + */ +module.exports = { + CACHE_GC_TIME : CACHE_GC_TIME, + DEF_BLOCK_SIZE : DEF_BLOCK_SIZE, + DEF_INODE_ENTRIES : DEF_INODE_ENTRIES, + DEF_INODE_SIZE : DEF_INODE_SIZE, + DEF_DIR_ENTRIES :DEF_DIR_ENTRIES, + DEF_MAGIC_SIZE: DEF_MAGIC_SIZE, + DNS_MAX_LIVE : DNS_MAX_LIVE, + DNS_INODE_SIZE : DNS_INODE_SIZE, + MAGIC_STR : MAGIC_STR, + + dns_col_bits:dns_col_bits, + + Dns_dir_state:Dns_dir_state, + Dns_mode: Dns_mode, + + Dns_row: Dns_row, + Dns_dir: Dns_dir, + + Dns_cache_parameter : Dns_cache_parameter, + Dns_inode : Dns_inode, + Dns_super : Dns_super, + Fs_server : Fs_server, + Fs_state : Fs_state, + buf_put_row : buf_put_row, + buf_get_row : buf_get_row, + buf_put_dir : buf_put_dir, + buf_get_dir : buf_get_dir, + buf_put_inode : buf_put_inode, + buf_get_inode : buf_get_inode, + off_of_inode : off_of_inode +};