Skip to content

Commit

Permalink
New Connection IDs
Browse files Browse the repository at this point in the history
Encrypted, Routable, Actionable, Long, load balancer friendly, Server & Client Connection Ids
Short unencrypted client and server connection IDs
  • Loading branch information
Universal Web committed May 26, 2023
1 parent 6892d2c commit d2ef75a
Show file tree
Hide file tree
Showing 17 changed files with 326 additions and 171 deletions.
2 changes: 1 addition & 1 deletion serverApp/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const appServer = await createServer({
// Where to load app resources from
resourceDirectory: `${currentPath(import.meta)}resources/`,
// Server ID used for load balancing and attaching to the end of connection IDs
id: 0,
// id: Buffer.from('alpha'),
// on connect message to respond with when a connection is established
onConnectMessage: `Welcome to the Universal Web.`,
// Port to listen on for connections
Expand Down
2 changes: 1 addition & 1 deletion udsp/ask.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class Ask {
const chunks = [];
const packetLength = body.length;
for (let index = 0; index < packetLength;index += chunkSize) {
const chunk = body.slice(index, index + chunkSize);
const chunk = body.subarray(index, index + chunkSize);
chunks.push(chunk);
}
return chunks;
Expand Down
2 changes: 1 addition & 1 deletion udsp/ask_new.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class Ask {
const chunks = [];
const packetLength = body.length;
for (let index = 0; index < packetLength;index += chunkSize) {
const chunk = body.slice(index, index + chunkSize);
const chunk = body.subarray(index, index + chunkSize);
chunks.push(chunk);
}
return chunks;
Expand Down
9 changes: 4 additions & 5 deletions udsp/client/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@ export async function connect(message = {}) {
console.log('-------CLIENT CONNECTING-------\n');
const thisClient = this;
// opn stands for open meaning connect to a server
message.intro = 'Hello World!';
message.intro = 'Hello Server!';
const result = await thisClient.request('opn', message);
console.log(result);
const {
body,
state,
time,
cid
sid
} = result;
if (state === 1 && cid) {
if (state === 1 && sid) {
connected(body);
thisClient.state = 1;
thisClient.cid = cid;
thisClient.id = cid;
thisClient.serverId = sid;
thisClient.lastPacketTime = Date.now();
thisClient.lastPacketGivenTime = time;
const bodyDecoded = decode(body);
Expand Down
22 changes: 13 additions & 9 deletions udsp/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import dgram from 'dgram';
// Default utility imports
import { success, configure, info } from '#logs';
import {
createSessionKey, clientSession, keypair, randomId, toBase64, emptyNonce, sessionKeys
createSessionKey, clientSession, keypair, toBase64, emptyNonce, sessionKeys,
createConnectionIdKey, encodeConnectionId, randomConnectionId
} from '#crypto';
import { pluckBuffer } from '#pluckBuffer';
import { getCertificate } from '#certificate';
Expand All @@ -38,9 +39,6 @@ import { onListening } from './listening.js';
import { currentPath } from '#directory';
// UNIVERSAL WEB Client Class
export class Client {
type = 'client';
description = `The Universal Web's UDSP client module to initiate connections to a UDSP Server.`;
descriptor = 'UDSP_CLIENT';
constructor(configuration) {
const thisClient = this;
console.log('-------CLIENT INITIALIZING-------\n', configuration);
Expand Down Expand Up @@ -69,7 +67,9 @@ export class Client {
this.emit = emit.bind(this);
this.onListening = onListening.bind(this);
this.onMessage = onMessage.bind(this);
thisClient.id = randomId();
thisClient.baseId = randomConnectionId();
thisClient.id = encodeConnectionId(thisClient.baseId, thisClient.connectionIdKey);
thisClient.idString = toBase64(thisClient.baseId);
thisClient.clientId = thisClient.id;
success(`clientId:`, toBase64(this.id));
success(`Creating Shared Keys`);
Expand Down Expand Up @@ -105,10 +105,10 @@ export class Client {
console.log(receiveKey, transmitKey);
const serviceKey = toBase64(destinationSignature);
const profileKey = toBase64(profileSignature);
success(`serviceKey:`, serviceKey);
success(`profileKey:`, profileKey);
// Needs to be more complex if forcing no connection with the same credentials
const connectionKey = `${serviceKey}${profileKey}`;
this.connectionKey = connectionKey;
Client.connections.set(connectionKey, thisClient);
Client.connections.set(thisClient.idString, thisClient);
thisClient.server.on('message', thisClient.onMessage.bind(thisClient));
thisClient.server.on('listening', thisClient.onListening);
return this;
Expand All @@ -125,8 +125,12 @@ export class Client {
thisClient.transmitKey = newSessionKeys.transmitKey;
thisClient.receiveKey = newSessionKeys.receiveKey;
thisClient.lastReKey = Date.now();
success(`client reKeyed -> ID: ${thisClient.connectionKey}`);
success(`client reKeyed -> ID: ${thisClient.idString}`);
}
type = 'client';
description = `The Universal Web's UDSP client module to initiate connections to a UDSP Server.`;
descriptor = 'UDSP_CLIENT';
connectionIdKey = createConnectionIdKey();
nonce = emptyNonce();
maxMTU = 1000;
encoding = 'binary';
Expand Down
6 changes: 4 additions & 2 deletions udsp/client/onPacket.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ export async function onMessage(packetEncoded) {
const {
receiveKey,
nonce,
keypair
keypair,
connectionIdKey
} = this;
msgReceived('Message Received');
const config = {
client: this,
receiveKey,
nonce,
packetEncoded,
isClient: true
isClient: true,
connectionIdKey
};
const headers = decodePacketHeaders(config);
const packet = await decodePacket(config);
Expand Down
8 changes: 5 additions & 3 deletions udsp/client/send.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,25 @@ export async function send(config) {
server,
serverId,
state,
transmitKey
transmitKey,
connectionIdKey
} = client;
const packet = await encodePacket({
client,
destination,
ephemeralPublic,
footer,
headers,
id,
id: serverId || id,
isClient: true,
keypair,
message,
nonce,
options,
profile,
state,
transmitKey
transmitKey,
connectionIdKey
});
msgSent(`Packet Size ${packet.length}`, message);
return promise((accept, reject) => {
Expand Down
13 changes: 10 additions & 3 deletions udsp/decodePacket.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
import { decode, } from 'msgpackr';
import { assign, } from 'Acid';
import {
encrypt, nonceBox, toBase64, hashSign, decrypt, boxUnseal, sessionKeys
encrypt, nonceBox, toBase64, hashSign, decrypt, boxUnseal, sessionKeys, getConnectionIdData
} from '#crypto';
import { createClient } from './server/clients/index.js';
export function decodePacketHeaders(config) {
Expand All @@ -16,7 +16,8 @@ export function decodePacketHeaders(config) {
packetEncoded,
server,
source,
state
state,
connectionIdKey
} = config;
const client = config.client;
info(`Packet Encoded Size ${packetEncoded.length}`);
Expand All @@ -29,10 +30,17 @@ export function decodePacketHeaders(config) {
if (!headers) {
return failed(`No headers -> Invalid Packet`);
}
info(`clientId: ${toBase64(headers.id)}`);
if (headers.key) {
success(`Public Key is given -> Processing as create client`);
} else {
success(`No Public Key is given -> Processing as a message`);
headers.id = getConnectionIdData(headers.id, connectionIdKey);
if (headers.id) {
success('Server Connection ID Decrypted');
} else {
return failed(`No ID -> Invalid Packet`);
}
console.log(headers);
}
config.headers = headers;
Expand Down Expand Up @@ -73,7 +81,6 @@ export async function decodePacket(config, result) {
if (message.body) {
success('body PAYLOAD', message.body.length);
}
info(`clientId: ${toBase64(headers.id)}`);
info(`Transmit Key ${toBase64(receiveKey)}`);
info(`Nonce Size: ${headers.nonce.length} ${toBase64(headers.nonce)}`);
const packetSize = packet.length;
Expand Down
3 changes: 2 additions & 1 deletion udsp/encodePacket.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import {
encrypt,
nonceBox,
randomize,
toBase64,
hashSignDetached,
boxSeal,
Expand All @@ -38,7 +39,7 @@ export async function encodePacket(data) {
destination,
isClient
} = data;
const nonce = nonceBox(nonceBuffer);
const nonce = randomize(nonceBuffer);
if (id) {
headers.id = id;
} else {
Expand Down
15 changes: 12 additions & 3 deletions udsp/reply.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,16 @@ export class Reply {
}
return chunks;
}
sendChunked(packet, incomingDataEncoding) {
async chunkBuffer(body) {
const chunks = [];
const packetLength = body.length;
for (let index = 0; index < packetLength;index += chunkSize) {
const chunk = body.subarray(index, index + chunkSize);
chunks.push(chunk);
}
return chunks;
}
buildReplyPackets(packet, incomingDataEncoding) {
const thisReply = this;
if (packet.body && packet.body.length > 700) {
const chunks = thisReply.chunk(packet.body);
Expand Down Expand Up @@ -137,10 +146,10 @@ export class Reply {
msgSent('REPLY.SEND', response);
if (response.body) {
if (incomingDataEncodingTypesChunked.test(incomingDataEncoding)) {
this.sendChunked(response, incomingDataEncoding);
this.buildReplyPackets(response, incomingDataEncoding);
} else if (incomingDataEncoding === 'struct' || incomingDataEncoding === 'json') {
response.body = encode(response.body);
this.sendChunked(response, incomingDataEncoding);
this.buildReplyPackets(response, incomingDataEncoding);
}
}
thisReply.replyAll();
Expand Down
12 changes: 6 additions & 6 deletions udsp/server/actions/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ export async function opn(reply) {
const client = reply.client();
const server = reply.server();
const response = reply.response;
info(`Client ID${client.id}`, `Stream ID${response.sid}`);
info(`Server ID${client.idString}`, `Client ID${client.clientIdString}`, `Stream ID${response.sid}`);
response.head = {};
response.body = {};
response.body = {
sid: server.id
};
client.newKey = true;
if (cacheMaxAge) {
response.head.cacheMaxAge = cacheMaxAge;
Expand All @@ -42,9 +44,7 @@ export async function opn(reply) {
// connection status - backwards compatibility
response.state = 1;
// Server connection id
response.cid = client.id;
response.sid = server.id;
client.reKey = keypair();
response.body.reKey = boxSeal(client.reKey.publicKey, client.publicKey);
// client.reKey = keypair();
// response.body.reKey = boxSeal(client.reKey.publicKey, client.publicKey);
reply.send('struct');
}
4 changes: 2 additions & 2 deletions udsp/server/clients/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ export class Client {
port,
nonce,
transmitKey,
id,
clientId,
state,
} = client;
this.packetConfig = {
address,
port,
nonce,
transmitKey,
id,
id: clientId,
state,
};
}
Expand Down
Loading

0 comments on commit d2ef75a

Please sign in to comment.