idz: Port userdb/ onto common/

This commit is contained in:
Tau
2020-09-01 01:10:31 +00:00
committed by Tau
parent 2dfeeaa8bd
commit 941f858b15
5 changed files with 67 additions and 214 deletions
+43 -77
View File
@@ -1,5 +1,4 @@
import logger from "debug";
import { Transform } from "stream";
import { checkTeamName } from "./checkTeamName";
import { createProfile } from "./createProfile";
@@ -49,6 +48,8 @@ import { updateTeamPoints } from "./updateTeamPoints";
import { updateUiReport } from "./updateUiReport";
import { updateUserLog } from "./updateUserLog";
import { lockProfileExtend } from "./lockProfileExtend";
import { BLOCK_SIZE } from "../../common";
import { ByteStream } from "../../../util/stream";
const debug = logger("app:idz:userdb:decoder");
@@ -119,88 +120,53 @@ for (const fn of funcList) {
msgLengths.set(fn.msgCode, fn.msgLen);
}
function readHeader(buf: Buffer) {
return {
blah: "blah",
};
}
async function readRequest(stm: ByteStream): Promise<Request | undefined> {
const head = await stm.read(BLOCK_SIZE);
export class Decoder extends Transform {
state: Buffer;
constructor() {
super({
readableObjectMode: true,
writableObjectMode: true,
});
this.state = Buffer.alloc(0);
if (head.length === 0) {
// Connection closed
return undefined;
}
_transform(chunk: Buffer, encoding, callback) {
this.state = Buffer.concat([this.state, chunk]);
const msgCode = head.readUInt16LE(0x0000);
const msgLen = msgLengths.get(msgCode);
// Read header
if (msgLen === undefined) {
throw new Error(`Message ${msgCode.toString(16)}: Unknown command code`);
}
if (this.state.length < 0x04) {
return callback(null);
const tail = await stm.read(msgLen - BLOCK_SIZE);
const msg = Buffer.concat([head, tail]);
if (msg.length < msgLen) {
throw new Error(`Message ${msgCode.toString(16)}: Truncated read`);
}
if (debug.enabled) {
debug("Raw: %s", msg.toString("hex"));
}
const reader = readerFns.get(msgCode);
if (reader === undefined) {
throw new Error(`Message ${msgCode.toString(16)}: No read handler`);
}
const payload = reader(msg);
debug("Payload: %j", payload);
return payload;
}
export default async function* readRequestStream(stm: ByteStream) {
while (true) {
const req = await readRequest(stm);
if (req === undefined) {
return;
}
const magic = this.state.readUInt32LE(0);
if (magic !== 0x01020304) {
return callback(
new Error(
"Invalid magic number, cryptographic processing probably incorrect."
)
);
}
if (this.state.length < 0x30) {
return callback(null);
}
const header = readHeader(this.state);
if (this.state.length < 0x32) {
return callback(null);
}
const msgCode = this.state.readUInt16LE(0x30);
const msgLen = msgLengths.get(msgCode);
if (msgLen === undefined) {
return callback(
new Error(
`Unknown command code ${msgCode.toString(16)}, cannot continue`
)
);
}
if (this.state.length < 0x30 + msgLen) {
return callback(null);
}
const reqBuf = this.state.slice(0, 0x30 + msgLen);
const payloadBuf = reqBuf.slice(0x30);
if (debug.enabled) {
debug("Raw: %s", reqBuf.toString("hex"));
debug("Header: %j", header);
}
const reader = readerFns.get(msgCode);
if (reader === undefined) {
return callback(
new Error(`No reader for command code ${msgCode.toString(16)}`)
);
}
const payload = reader(payloadBuf);
debug("Payload: %j", payload);
return callback(null, payload);
yield req;
}
}